Pumpkin Lord
Selamlar Modcular,
Uzun zamandır aklımda olan bir konuydu, sadece biraz daha kendimi geliştirip kendimi öyle sunmayı bekledim, fakat sanırım bu kadarı yeterli oldu. Bu konu ile amacım Türklere kod desteği sağlamak ve kodlama daki sorularını cevaplandırmak. Yazdığım çoğu işe de buradan ulaşmanız mümkün.
Soru sorarken yalvarırım aynı soruları tekrar ve tekrardan sormayın, "şu kod olsa MANYAK olur" gibi saçma sapan mesajlar yazmaktan çekinelim.
Oyuna ilk girdiğiniz karşınıza çıkan Ana menü'dür. Peki, burası ne kadar kişiselleştirilebilir? İşte cevap;
/Mount&Blade Warband/Textures/warrider_logo.dds, "Başlangıç Eğitimi"'nin üzerindeki logoyu temsil eder. Resim dosyasıdır.
/Mount&Blade Warband/Textures/main_menu_nord.dds, arkadaki büyük resmi temsil eder. Nord Savaşçıları ve sol taraftaki bütün alan tek bir resimdir.
*Yeni bir menü seçeneği eklenemez. Hardcodelanmıştır.
*Hareket eden resimler daha önce eklendi. Bilin, bu mümkün.
*Herhangi bir menü seçeneğini hakkında ayarlar yapmak için;
-Mod klasöründe "game_variables.txt" dosyası olacak.
-Açın.
-Arama yapın; "initial_".
-Arama yaptıktan sonra, direk bunları göreceksiniz,
Burada ki her bir paragraf bir seçeneği temsil ediyor. Peki, nedir anlamları?
_position_y, vertikal olarak yerini değiştirir. Yukarı aşağı...
_position_x, horizontal olarak yerini değiştirir. Sağ sol...
_text_size_x, horizontal olarak seçeneğin boyutunu ayarlar.
_text_size_y, vertikal olarak seçeneğin boyutunu ayarlar.
_text_flags_, pek bir bilgim yok.
_text_color_, seçeneğin rengini ayarlar. İnternetten "Hex Code Colors" gibi bir arama verirseniz, burada kullanabileceğiniz renk kodları bulabilirsiniz.
_highlight_text_color_, üstüne gelindiğinde seçeneği parlatacak olan renk.
*Numaralar ne kadar büyük olursa, boyutta o kadar büyük oluyor.
*Mesela, bir seçeneği yok etmek istiyorsanız;
-İstediğiniz seçeneğin size_y ve size_x 'lerini 0 yapın.
Selamlar,
Nice süredir konuya birşey paylaşmıyordum. Obvious sebeplerden dolayı böyle bir rehber hazırlama gereği duydum, anladığım ve gözlemlediğim kadarıyla (nihayet!) kodlama alanına ufak ufak ilerlemeler başlamış, belki onca seneden sonra farklı yüzler görmeye başlayabilecez modlama alanında. Bu rehber kodlama da aşina olup da bilmediğiniz veya hiç bilmediğiniz bazı terimleri öğretecek size. Özellikle kodlamada bu terimler vasıtasıyla öğreneceğiniz pek çok method ve sisteme farklı bakış açıları da çabası. Ve başlıyorum...
Module (Modül) - Daha popüler adıyla "Modifikasyon" veya kısa söylemiyle "Mod" ile aynı anlama gelir. Fakat yaptığımız işin teknik adı budur.
Scene (Sahne) - Zaten bilinen birşey. Sahne motorun tanımladığı bir ortamdır, bu ortamda pek çok objeler bulunur ve özellikle "agent" sisteminin kullanıldığı ve bu sistemle oynanabilen bir platforma dönüşür. Sahne kodlarıyla bu sahnenin içine "external" olarak konan objelerin yerini, cismini veya herhangi somut bilgisini saklayabilirken, .sco uzantılı dosyayla sahnenin kendisini saklayabilmekteyiz. Aslında işi yapan yine kod.
Agent (Canlı veya Aktör) - Agentlar Native'de aslında savaşlarda savaştığımız herşey. Mesela;
Dünya haritasında bir düşman partisine saldırırsınız: X
Parti lideri ile konuşma ekranı geçer: Y
Seçenek menüsü çıkar: Z
Savaşa girersiniz: V
X: Bir partydir. Pek çok troopun içinde olduğu.
Y: Lider bir troopdur.
Z: 2D bir meshdir. Presentations, meshes ile oluşturulmuş.
V: Ve işte...gördüğünüz bütün o trooplar size tanıdık geliyor değil mi? Görünüş olarak öyle ama değiller. Orada gördükleriniz birer aktör, yani agent. Oyun motoru agent ile troop arasındaki farklılığı çok net ortaya koymuştur. Troop bir ruh, agent ta o ruhu yaşatan fiziksel varlıklar. Aktörler. Bir sahnede gördüğünüz bütün Lordlar, krallar, düşman askerleri, sizin askerleriniz ve hatta sen bile birer aktörsünüz.
Agentlar troopların motor tarafından oluşturulmuş "sahne" ortamındaki temsilidir. Ve, trooplar ile aktörler aynı şey değillerdir.
Mesh (Materyal) - Bir mesh 2D'dir. 3D meshler obje kategorisine girer ve oyunda gördüğümüz herşey anlamına girer. Zırhlar, atlar, silahlar...vs hepsi 3D birer objedir. 3D objede bir meshtir aslında ama burası biraz karışık.
Burada bahsettiğim mesh, bir 2D tasarımdan ibarettir. En çok presentations.py ve tableau_materials.py'de kullanılır çünkü varoldukları yer orasıdır. Bir meshi oyuna aktarmak için onu ilk önce bir presentations ve tableau içine koymanız gerekir ve öyle kullanmanız gerekir. Mesela, bir şehre girdiğinizde arkadaki şehir resmi bir 2D meshtir, fakat şehir sahnesine girdiğinizde gördüğünüz bütün o binalar 3D objedir, yani 3D meshtir.
Script (Senaryo) - Script ile kod çok karıştırılan şeylerdir. Script, bir senaryodur yani pek çok koddan varolmuş birşeyi gerçekleştirmek için yaratılmıştır. Mesela, oyunun içindeki moral sistemi belli bir sistemi vardır. Bu sistemin içindeki "morali düşürme" veya "morali arttırma" yı yapan kodlar birer scripttir. Yani partinizde çok asker vardır, ve motor bunu verilen kondisyonlar içinde check eder, ve checkler doğru geri döndüğünde "moral düşürme" scriptini ateşler.
Peki o zaman, kod veya trigger ne? Kod, tek satır motora ne yapacağı tanıtılmış bir cümledir. (agent_set_position) dediğimde, o aktörün orada olması gerektiğini sağlar.
Trigger (Ateşleme) Trigger, kodlamada bir scriptin veya kodun neye göre ateşleneceğini sağladığınız yer. Bu devamlı bir loop şeklinde de olabilir, ya da belli birşey gerçekleşince de olabilir. Scriptten farkı, scriptin içinde bir ateşleme parametresi belirleyemezsiniz. Fakat triggerda zaman-bazlı veya action-bazlı belirleyebilirsiniz.
Parameter (Parametre/Kondisyonlar) Parametre trigger'ın içinde bulunan birşeydir. Bildiğimiz kodlama mantığı ile alakası yoktur, tamamen back-end çalışır. Hardcodedur, oynanamaz. Bir trigger'ın ateşlenmesi için gerekli action veya zamanı belirlersiniz.
Mission (Sahne kodlaması) Sahneyi çaktınız, değil mi? Motorun tanımlayabildiği bir ortam demiştik, tıpkı Dünya Haritası gibi. Peki bu sahnede olan herşeyi sağlayan kodlama sistemi ne diye merak etmiyormusunuz? İşte benim en çok kodlamasını sevdiğim yer burası. Savaşıyorsunuz, adam öldürünce onun öldüğünü belirttiğiniz ve ölme animasyonun oynadığı yer burası işte. Ve pek çok şekilde diğer kodlama sistemleriyle entegre etmek mümkün. (scene_props.py, scripts.py...) Canır canır yanan bir BOSS mu yaratmak istiyorsunuz, aktörün posizyonlarını ölçüp gerekli particleları verdiğiniz yer burası. Bir sahne mission olmadan sadece görüntüdür. İnteraktif hale geldiği yer missionla olur.
Loop (Tekrarlama) - Tekrarlama demektir. Bu ne demek, warband kodlamasında bunu "try_for" koduyla yapıyorsunuz. "try_for_agents" dediğinizde ve altına "agent_is_alive" kondisyonunu belirlediğinizde, bu loop sahnede varolan bütün canlı aktörleri bulana kadar döner ve elinize bütün bu canlı aktörlerin verisi ulaşır. Sonra bunları "agent_deliver_damage_to_agent" ile öldürürmüsünüz yoksa "agent_set_position ile kendinize mi çekersiniz? Size kalmış. Aktör sadece bir örnek tabii.
Devam edecek...
Zamanla yaptıkça burayı zenginleştirecem. Eğer sende bir kodcuysan, bana bu konuda yardım etmekte serbestsin. Ve öğrenmek isteyen arkadaşlar bu konu üzerinden istediği soruyu sorabilirler.
Saygı ve Sevgilerimle,
Uzun zamandır aklımda olan bir konuydu, sadece biraz daha kendimi geliştirip kendimi öyle sunmayı bekledim, fakat sanırım bu kadarı yeterli oldu. Bu konu ile amacım Türklere kod desteği sağlamak ve kodlama daki sorularını cevaplandırmak. Yazdığım çoğu işe de buradan ulaşmanız mümkün.
Soru sorarken yalvarırım aynı soruları tekrar ve tekrardan sormayın, "şu kod olsa MANYAK olur" gibi saçma sapan mesajlar yazmaktan çekinelim.
Çalışmalarım
Yeni deneyim, buyurun.
Mission_templates.py'ye bir trigger olarak ekleyeceksiniz. İstediğiniz missionlara da alttaki satırı uygun yere eklemeniz lazım.
Code:
ranged_pull = (
ti_on_agent_hit, 0, 0, [(is_between, reg0, "itm_heavy_throwing_axes_melee", "itm_torch"),
# (item_get_type, ":is_bow", reg0),
# (eq, ":is_bow", itp_type_bow),
# (eq, reg0, "itm_short_bow"),
],
[ #(display_message, "@IP: Arrow shot."),
(store_trigger_param_1, ":target"),
(store_trigger_param_2, ":source"),
(get_player_agent_no, ":me"),
(str_store_agent_name, s0, ":target"),
(agent_is_alive, ":source"),
(agent_get_position, pos1, ":target"),
(agent_get_position, pos2, ":source"),
(get_distance_between_positions, ":dist", pos1, pos2),
(assign, reg1, ":dist"),
(position_move_x, pos2, 50),
(eq, ":source", ":me"),
(try_begin),
(le, ":dist", 200),
(str_store_string, s1, "@Too close to pull! Distance: {reg1}"),
(else_try),
(ge, ":dist", 1000),
(str_store_string, s1, "@Too far to pull! Distance: {reg1}"),
(else_try),
(neg|agent_is_human, ":target"),
(str_store_string, s1, "@You cannot pull an animal! Distance: {reg1}"),
(else_try),
(agent_get_horse, ":has_horse", ":target"),
(neq, ":has_horse", -1),
(str_store_string, s1, "@You cannot pull horsemen! Distance: {reg1}"),
(else_try),
(agent_is_alive, ":target"),
(agent_set_position, ":target", pos2),
(str_store_string, s1, "@Pulled {s0}. Distance: {reg1}"),
(try_end),
(display_message, "@{s1}"),
])
Mission_templates.py'ye bir trigger olarak ekleyeceksiniz. İstediğiniz missionlara da alttaki satırı uygun yere eklemeniz lazım.
Code:
ranged_pull,
Double-post:
Küçük bir mission triggeri yazdım. Sistem savaşta öldürdüğünüz her lord veya kingle ve bağlı olduğu factionla ilişkinizi düşürüyor. Gerçekçilik adına.
Küçük bir mission triggeri yazdım. Sistem savaşta öldürdüğünüz her lord veya kingle ve bağlı olduğu factionla ilişkinizi düşürüyor. Gerçekçilik adına.
Code:
#Belendor - Every killing of a lord or king decreases your relationship with corresponding faction and person himself.
common_lord_trigger = (
ti_on_agent_killed_or_wounded, 0, 0, [],
[
(store_trigger_param_1, ":killed_agent"),
(store_trigger_param_2, ":killer_agent"),
(get_player_agent_no, ":player"),
(agent_is_active, ":killed_agent"),
(agent_is_active, ":killer_agent"),
(agent_is_alive, ":killer_agent"),
(agent_get_troop_id, ":killed_trp", ":killed_agent"),
(troop_is_hero, ":killed_trp"),
(eq, ":killer_agent", ":player"),
(store_random_in_range, ":lord_num", -5, -10),
(store_random_in_range, ":lord_fac_num", -2, -5),
(store_random_in_range, ":king_num", -3, -8),
(store_random_in_range, ":king_fac_num", -1, -3),
(try_begin),
(is_between, ":killed_trp", lords_begin, lords_end),
(assign, ":rep_to_dec", ":lord_num"),
(assign, ":fac_rep_to_dec", ":lord_fac_num"),
(else_try),
(is_between, ":killed_trp", kings_begin, kings_end),
(assign, ":rep_to_dec", ":king_num"),
(assign, ":fac_rep_to_dec", ":king_fac_num"),
(try_end),
(call_script, "script_change_player_relation_with_troop", ":killed_trp", ":fac_rep_to_dec"),
(store_troop_faction, ":killed_trp_fac", ":killed_trp"),
(call_script, "script_change_player_relation_with_faction_ex", ":killed_trp_fac", ":rep_to_dec"),
])
Yeni yazmayı bitirdiğim "yaralanma" kodum. MP ve SP için de çalışıyor olması lazım. Konsept olarak, bir oyuncu 25'den fazla hasar alırsa, her 5 saniyede bir kan kaybedecek ölene kadar. Erken konsept çalışması, sonra ilerletebilirim.
Code:
bleeding_0 = (
ti_on_agent_spawn, 0, 0, [],
[ (store_trigger_param_1, "$un_agent"),
(agent_set_slot, "$un_agent" ,slot_agent_bleeding, -1),
])
bleeding_1 = (
ti_on_agent_hit, 0, 0, [(agent_slot_eq, "$un_agent", slot_agent_bleeding, -1),],
[ (store_trigger_param_1, ":receiver"),
(store_trigger_param_2, ":dealer"),
(store_trigger_param_3, ":damage"),
(ge, ":damage", 25),
(str_clear, s1),
(assign, reg1, ":damage"),
(agent_get_player_id, ":player", ":receiver"),
(agent_is_alive, ":receiver"),
(agent_is_human, ":receiver"),
(agent_is_active, ":receiver"),
(player_is_active, ":player"),
(str_store_player_username, s1, ":player"),
(display_message, "@{s1} is now bleeding, amount of {reg1} damage inflicted!", 0xFF6AAA89),
(agent_set_slot, "$un_agent" ,slot_agent_bleeding, 1),
#(assign, ":receiver", "$un_agent"),
])
bleeding = (
5, 0, 0, [(agent_slot_eq, "$un_agent", slot_agent_bleeding, 1),],
[
(store_random_in_range, ":bleed_dmg", 4, 8),
(agent_is_alive, "$un_agent"),
(store_agent_hit_points, ":un_hp", "$un_agent"),
(val_sub, ":un_hp", ":bleed_dmg"),
(agent_set_hit_points, "$un_agent", ":un_hp"),
])
Singleplayer'da her zaman ne kadar vurduğumu görmek hoşuma gitmiştir, Multi'de de güzel bir özellik. Buyurun kodu;
Code:
damage_value = (
ti_on_agent_hit, 0, 0, [],
[ (store_trigger_param_1, ":receiver"),
(store_trigger_param_2, ":dealer"),
(store_trigger_param_3, ":damage"),
(assign, reg19, ":damage"),
(get_player_agent_no, ":player"),
(try_begin),
(eq, ":dealer", ":player"),
(display_message, "@Delivered {reg19} damage.", 0xFFAAFFAA),
(else_try),
(eq, ":receiver", ":player"),
(display_message, "@Received {reg19} damage.", 0xFF7A4800),
(try_end),
])
Deniz Savaşları, Ruthven tarafından yazılmıştır. Kodlarla arası iyi olmayanlar için, hazır Modul Sistemine ekledim.
**Bu çalışma bana ait değildir.**
**Bu çalışma bana ait değildir.**
Şehir Menüsünden Direk Konuşabilme
Game_menus.py'den "(jump_to_menu, "mnu_town_tournament")," diye aratın. Hemen onun altındaki "]),"'den sonra şu kodları ekleyin;
Kodu açıklamak gerekirse;
-"Meet with the Guild Master." , bu iki tırnak arasına ne yazarsan şehir menüsünde o yazı gözükecek ama işlev hep aynı kalır.
-(party_slot_eq,"$current_town",slot_party_type, spt_town), girilen party'nin bir şehir olduğunu kontrol eden operasyon.
-(call_script, "script_cf_enter_center_location_bandit_check"),, geceleri haydutlar için kontrol eder, tıpkı geceleri tavernaya girerken tuzağa düşürüldüğümüz gibi. Eğer, bu seçeneğe tıklarken geceleri haydutlara yakalanmamak istiyorsanız, bu dizini silebilirsiniz.
-(party_get_slot, ":conversation_troop", "$current_town", slot_town_elder), işte burası. Slot_town_elder burada bulunduğunuz şehirdeki Lonca Başkanı ile konuştuğunuzu belirtir. Bunu değiştirmenin şöyle yolları var;
Eğer değiştirmek isterseniz, tek yapmanız gereken;
Bunu mesela buna değiştirmek;
Game_menus.py'den "(jump_to_menu, "mnu_town_tournament")," diye aratın. Hemen onun altındaki "]),"'den sonra şu kodları ekleyin;
Code:
("meet_with_guild_master",
[
(party_slot_eq,"$current_town",slot_party_type, spt_town),
],
"Meet with the Guild Master.",
[
(try_begin),
(call_script, "script_cf_enter_center_location_bandit_check"),
(else_try),
(party_get_slot, ":conversation_troop", "$current_town", slot_town_elder),
(call_script, "script_setup_troop_meeting", ":conversation_troop", -1),
(try_end),
]),
Kodu açıklamak gerekirse;
-"Meet with the Guild Master." , bu iki tırnak arasına ne yazarsan şehir menüsünde o yazı gözükecek ama işlev hep aynı kalır.
-(party_slot_eq,"$current_town",slot_party_type, spt_town), girilen party'nin bir şehir olduğunu kontrol eden operasyon.
-(call_script, "script_cf_enter_center_location_bandit_check"),, geceleri haydutlar için kontrol eder, tıpkı geceleri tavernaya girerken tuzağa düşürüldüğümüz gibi. Eğer, bu seçeneğe tıklarken geceleri haydutlara yakalanmamak istiyorsanız, bu dizini silebilirsiniz.
-(party_get_slot, ":conversation_troop", "$current_town", slot_town_elder), işte burası. Slot_town_elder burada bulunduğunuz şehirdeki Lonca Başkanı ile konuştuğunuzu belirtir. Bunu değiştirmenin şöyle yolları var;
Code:
slot_town_tavernkeeper = Barmen.
slot_town_weaponsmith = Silah satıcısı.
slot_town_armorer = Zırh satıcısı.
slot_town_merchant = Hmm, esnaf da olabilir ya da ilk görevlerdeki quest troopları da. Test edin.
slot_town_horse_merchant= At tüccarı.
slot_town_elder = Lonca Başkanı. (Varsayılan)
Eğer değiştirmek isterseniz, tek yapmanız gereken;
Code:
(party_get_slot, ":conversation_troop", "$current_town", slot_town_elder),
Bunu mesela buna değiştirmek;
Code:
(party_get_slot, ":conversation_troop", "$current_town", slot_town_merchant),
Dünya Haritasında İstila Sistemi
İlk olarak "module_party_templates.py"'i bulun. Amacımız bir istila partisi yaratmak, sonra kodlarla bu partileri oyuna ekleyecez.
Bu kodu açıklamak gerekirse;
-"istilacı", party'nin idsi. Bütün script ve triggerlerde bu party'i kullanmak için lazım olan integer girdimiz.
-"İstilacılar", dünya haritasında partynin gözüken adı.
-"icon_khergit", header/ID/Module_map_icons.py'den de ulaşabileceğiniz geçerli map iconlardan herhangi birini party'nin kullanması için yazdığınız yer. Bu durumda, Khergit Lordlarınınkini kullanıyoruz.
-"fac_outlaws", hangi factiona bağlı olduğunu belirttiğin yer.
Ve;
Bu kodda görüldüğü üzere partyde yer alan trooplar. Bu durumda 10 ile 32 arasında rastgele sayılarda partyler spawnlanacak. Sayıyı istediğiniz gibi değiştirin, troopuda. Fakat yeni bir troop eklemek için, mesela bunun gibi olması lazım;
Neyse sonra, module_triggers.py'e gidin. Normalde böyle bir istilayı başka tür kondisyonlar sonucunda da başlatabilirsiniz, mesela bir görev verdikten sonra ya da bir item kazandıktan sonra, buradaki sistem. Her 365 günde bir bu partiyi yaratmak olacak.
Ve, module_triggers.py'de;
Bu satırların hemen altına, şu aşağıdaki kodları yapıştırın;
ti_once'u sıfır ile değiştirin eğer her yıl olmasını istiyorsanız. Buradaki sistemde sadece ilk 365.günde spawnlayacaktır.
Not:8765, 365 güne denk gelmektedir. Yani, 1 oyun gününü 24 saatten hesaplayacaksınız.
Kodu açıklamak gerekirse;
-"p_town_1", bu partynin hangi party etrafında spawnlanmasını belirttiğin yer. Bu durumda sanırsam Praven oluyor.
-"pt_istilacı", işte ilk başta bahsettiğim party_template'in ID'sinin önem arzettiği yer. Bunu istediğin partye değiştir, o party spawnlacak.
-"251", kaç tane partynin spawnlanacağı toplamda ve maksimum olarak.
-"4", bu biraz karışık. Açıklamak gerekirse, partylerin ne kadar sıklıkla ve spawnlandığında aynı anda kaç tane spawnlanacağını belirttiğin yer.
Evet, bu kadar. İstilanız hazır!
İlk olarak "module_party_templates.py"'i bulun. Amacımız bir istila partisi yaratmak, sonra kodlarla bu partileri oyuna ekleyecez.
Code:
("istilacı","İstilacılar",icon_khergit|carries_goods(2)|pf_show_faction,0,fac_outlaws,bandit_personality,[(trp_swadian_knight,10,32),]),
Bu kodu açıklamak gerekirse;
-"istilacı", party'nin idsi. Bütün script ve triggerlerde bu party'i kullanmak için lazım olan integer girdimiz.
-"İstilacılar", dünya haritasında partynin gözüken adı.
-"icon_khergit", header/ID/Module_map_icons.py'den de ulaşabileceğiniz geçerli map iconlardan herhangi birini party'nin kullanması için yazdığınız yer. Bu durumda, Khergit Lordlarınınkini kullanıyoruz.
-"fac_outlaws", hangi factiona bağlı olduğunu belirttiğin yer.
Ve;
Code:
[(trp_swadian_knight,10,32),]),
Bu kodda görüldüğü üzere partyde yer alan trooplar. Bu durumda 10 ile 32 arasında rastgele sayılarda partyler spawnlanacak. Sayıyı istediğiniz gibi değiştirin, troopuda. Fakat yeni bir troop eklemek için, mesela bunun gibi olması lazım;
Code:
[(trp_swadian_knight,10,32),(trp_swadian_infantry,5,15)]),
Neyse sonra, module_triggers.py'e gidin. Normalde böyle bir istilayı başka tür kondisyonlar sonucunda da başlatabilirsiniz, mesela bir görev verdikten sonra ya da bir item kazandıktan sonra, buradaki sistem. Her 365 günde bir bu partiyi yaratmak olacak.
Ve, module_triggers.py'de;
Code:
# Refresh Merchants
(0.0, 0, 168.0, [],
[
(call_script, "script_refresh_center_inventories"),
]),
Bu satırların hemen altına, şu aşağıdaki kodları yapıştırın;
Code:
(8765,0,ti_once,[],[
(set_spawn_radius, 4),
(try_for_range, ":i", 0, 251),
(spawn_around_party, "p_town_1", "pt_invaders"),
(val_add, ":i", 1), #bunu ekleyin ki, karşınıza "unused local variable" hatası çıkmasın gereksiz yere
(try_end),
]),
ti_once'u sıfır ile değiştirin eğer her yıl olmasını istiyorsanız. Buradaki sistemde sadece ilk 365.günde spawnlayacaktır.
Not:8765, 365 güne denk gelmektedir. Yani, 1 oyun gününü 24 saatten hesaplayacaksınız.
Kodu açıklamak gerekirse;
-"p_town_1", bu partynin hangi party etrafında spawnlanmasını belirttiğin yer. Bu durumda sanırsam Praven oluyor.
-"pt_istilacı", işte ilk başta bahsettiğim party_template'in ID'sinin önem arzettiği yer. Bunu istediğin partye değiştir, o party spawnlacak.
-"251", kaç tane partynin spawnlanacağı toplamda ve maksimum olarak.
-"4", bu biraz karışık. Açıklamak gerekirse, partylerin ne kadar sıklıkla ve spawnlandığında aynı anda kaç tane spawnlanacağını belirttiğin yer.
Evet, bu kadar. İstilanız hazır!
Silahlara Alevle Yanma Efekti Verme
Başka bir kodla karşınızdayım. Bu da yine yapılması kolay olanlardan, kodu AoM için yazmıştım. Çok genel bir kod olduğu için, çoğu kişinin işine yarayabileceğini düşündüm.
İlk olarak, bu kodu eklerken Morgh's Tools'u kullanmanızı aşırı şekilde öneririm.
-İlk olarak, Morgh'un toolunu indirdikten sonra onu açın. Modun dizinini ayarlayın ve sol taraftan "Item Editor"'e girin.
-Orada herhangi bir "silah"'a tıklayın, bunun bir silah olması iyi olur. Çünkü, zırhlarda çalışması için ekstra bir iş gerekir, ve bu kod çalışmaz silahtan başka bir nesnenin üstünde.
-Silah'a tıkladıktan sonra, programın aşağısında "Triggers" diye bir küçük bir pencere var, oraya;
Bunu ekleyin. Sonra "Update Item" ve "Save Changes"'e tıklayıp çıkın.
Sonuç olarak, silahınız bu kod sayesinde Alev alev yanıyor olacak.
Başka bir kodla karşınızdayım. Bu da yine yapılması kolay olanlardan, kodu AoM için yazmıştım. Çok genel bir kod olduğu için, çoğu kişinin işine yarayabileceğini düşündüm.
İlk olarak, bu kodu eklerken Morgh's Tools'u kullanmanızı aşırı şekilde öneririm.
-İlk olarak, Morgh'un toolunu indirdikten sonra onu açın. Modun dizinini ayarlayın ve sol taraftan "Item Editor"'e girin.
-Orada herhangi bir "silah"'a tıklayın, bunun bir silah olması iyi olur. Çünkü, zırhlarda çalışması için ekstra bir iş gerekir, ve bu kod çalışmaz silahtan başka bir nesnenin üstünde.
-Silah'a tıkladıktan sonra, programın aşağısında "Triggers" diye bir küçük bir pencere var, oraya;
Code:
[(ti_on_init_item,[(set_position_delta,0,60,0),(particle_system_add_new,"psys_torch_fire"),(particle_system_add_new,"psys_torch_smoke"),(set_current_color,150,130,70),(add_point_light,10,30),])]
Bunu ekleyin. Sonra "Update Item" ve "Save Changes"'e tıklayıp çıkın.
Sonuç olarak, silahınız bu kod sayesinde Alev alev yanıyor olacak.
Kalıcı Savaş Kodları
Bunu yapmanın birden fazla yolu var. Bu da bunlardan sadece bir tanesi, gayet kolay ve komplexlikten uzak bir kod. Tek yapmanız gereken;
-Module_triggers.py'e girip "Refresh Weapon Sellers" diye arama verip, orada böyle bir kod satırları göreceksiniz;
Onun hemen altına bu kodları ekleyin.
Mavi renkteki rakamı ne kadar yazarsanız o kadar süre ile bu trigger ateşlenecek. Bu kod hiçbir şekilde factionların AI'lerini düzenlemediği için, oyunda arada barış yapsalar bile, tam 1 saniye sonra yine düşmana dönecekler.
Kırmızı renkteki rakamlar;
-1 = Düşman
0 = Nötr
1 = Dost/Ticari/Söz
Yukarıdaki işleme göre istediğiniz factionu istediğiniz factiona düşman edebilirsiniz. Son "set_relation" operasyonunun altına koyun, son parantez ile ilk parantez içinde kalmalı.
Bunu yapmanın birden fazla yolu var. Bu da bunlardan sadece bir tanesi, gayet kolay ve komplexlikten uzak bir kod. Tek yapmanız gereken;
-Module_triggers.py'e girip "Refresh Weapon Sellers" diye arama verip, orada böyle bir kod satırları göreceksiniz;
Code:
# Refresh Weapon sellers
(0.0, 0, 168.0, [],
[
(call_script, "script_refresh_center_weaponsmiths"),
]),
Onun hemen altına bu kodları ekleyin.
Şimdi, bu kod oyuna başladığınız an itibari ile her 0.1 saniyede bir bu triggeri ateşliyor.# Alliances
(0.1, 0, 0.0, [],
[
(set_relation, "fac_kingdom_1", "fac_kingdom_2", -1),
(set_relation, "fac_kingdom_2", "fac_kingdom_1", -1),
]),
Mavi renkteki rakamı ne kadar yazarsanız o kadar süre ile bu trigger ateşlenecek. Bu kod hiçbir şekilde factionların AI'lerini düzenlemediği için, oyunda arada barış yapsalar bile, tam 1 saniye sonra yine düşmana dönecekler.
Kırmızı renkteki rakamlar;
-1 = Düşman
0 = Nötr
1 = Dost/Ticari/Söz
Code:
(set_relation, "fac_factionidsinikoyburaya", "fac_biröncekifactionundüşmanolmasınıistediğinfactionunidsideburayakoy", -1),
Yukarıdaki işleme göre istediğiniz factionu istediğiniz factiona düşman edebilirsiniz. Son "set_relation" operasyonunun altına koyun, son parantez ile ilk parantez içinde kalmalı.
İlk olarak eskiden Rigale moduna yazdığım ve bağışlamak amaçlı hazırlamış olduğun bu kod var elimde, bu kodun aynısını Caliph'in OSP konusunda da bulabilirsiniz. Fakat, orada oyuna nasıl eklenebileceğini anlatmamıştım, burada da detaylı bir şekilde üzerinden geçecem. Bu kodun bir kısmı Rigale modunun sahibi Cromcrom'a aittir, kullanırken ona da teşşekür etmeyi unutmayın.
Bu kod şu an Rigale modunda kullanılmaktadır. Sahibi ben ve Cromcrom'dur.
Bu kod basit olarak eğer Onurunuz belli bir seviyenin altındaysa ve yeterli paranız varsa her 24 saatte tanesi 20 dinar olan Bandit üniteleri almanıza yarıyor. Bunu yapabilmek için kamp menüsüne bakmanız yeterli ki sadece onurunuz o seviyeye düştüğü zaman.
Code, çalıştırabilmek için;
-İlk olarak, game_menus.py dosyasında "Choose an action:"'ı bulmanız lazım ve çok önemli altta gördüğünüz satırları atlamanız lazım;
Sonra, yukarıdaki kodları atladıktan sonra /Onlar zaten MS'nin içinde, yani kopyalamaya falan çalışmayın.\ , aşağıdaki satırları yukarıdaki son parantezden sonra yapıştırın.
Sonra, yine game_menus.py dosyasında "camp_no_prisoners" bulun ve yine, bu kodları ellemeden atlayın;
Ve, aşağıdaki kodları yapıştırın.
Bu kod şu an Rigale modunda kullanılmaktadır. Sahibi ben ve Cromcrom'dur.
Bu kod basit olarak eğer Onurunuz belli bir seviyenin altındaysa ve yeterli paranız varsa her 24 saatte tanesi 20 dinar olan Bandit üniteleri almanıza yarıyor. Bunu yapabilmek için kamp menüsüne bakmanız yeterli ki sadece onurunuz o seviyeye düştüğü zaman.
Code, çalıştırabilmek için;
-İlk olarak, game_menus.py dosyasında "Choose an action:"'ı bulmanız lazım ve çok önemli altta gördüğünüz satırları atlamanız lazım;
Code:
"none",
[
],
[
Sonra, yukarıdaki kodları atladıktan sonra /Onlar zaten MS'nin içinde, yani kopyalamaya falan çalışmayın.\ , aşağıdaki satırları yukarıdaki son parantezden sonra yapıştırın.
Code:
("camp_recruit_bandits",
[(troops_can_join, 1),
(store_current_hours, ":cur_time"),
(val_sub, ":cur_time", 24),
(gt, ":cur_time", "$g_bandit_recruit_last_time"),
(try_begin),
(gt, "$g_bandit_recruit_last_time", 0),
(assign, "$g_bandit_recruit_last_time", 0),
(try_end),
], "Some bandits show themselves in order to be recruited.",
[(jump_to_menu, "mnu_camp_recruit_bandits_2"),
],
),
Sonra, yine game_menus.py dosyasında "camp_no_prisoners" bulun ve yine, bu kodları ellemeden atlayın;
Code:
"You have no prisoners to recruit from.",
"none",
[],
[
("continue",[],"Continue...",
[(jump_to_menu, "mnu_camp"),
]
),
]
),
Ve, aşağıdaki kodları yapıştırın.
Code:
(
"camp_recruit_bandits_2",0,
"{s18}",
"none",
[(store_random_in_range, ":volunteer_amount", 5,16),
(assign,reg8,":volunteer_amount"),
(party_get_free_companions_capacity, ":free_capacity", "p_main_party"),
(store_troop_gold, ":gold", "trp_player"),
(store_div, ":gold_capacity", ":gold", 10),#10 denars per man
(assign, ":party_capacity", ":free_capacity"),
(val_min, ":party_capacity", ":gold_capacity"),
(try_begin),
(gt, ":party_capacity", 0),
(val_min, ":volunteer_amount", ":party_capacity"),
(try_end),
(assign, reg5, ":volunteer_amount"),
(assign, reg7, 0),
(try_begin),
(gt, ":volunteer_amount", ":gold_capacity"),
(assign, reg7, 1), #not enough money
(try_end),
(try_begin),
(eq, ":volunteer_amount", 0),
(str_store_string, s18, "@No one here seems to be willing to join your party."),
(else_try),
(store_random_in_range, ":final_gold_per_bandit",8,13),
(store_mul, reg6, ":volunteer_amount", ":final_gold_per_bandit"),#8 to 12 denars per man, calculated for the whole group
(str_store_troop_name_by_count, s3, "trp_bandit", ":volunteer_amount"),
(try_begin),
(eq, reg5, 1),
(str_store_string, s18, "@One {s3} volunteers to follow you."),
(else_try),
(str_store_string, s18, "@{reg5} {s3} volunteer to follow you."),
(try_end),
(set_background_mesh, "mesh_pic_recruits"),
(try_end),
],
[
("continue_not_enough_gold",
[
(eq, reg7, 1),
],
"I don't have enough money...",
[
(jump_to_menu,"mnu_camp_action"),
]),
("continue",
[
(eq, reg7, 0),
(eq, reg5, 0),
], #noone willing to join
"Continue...",
[
(jump_to_menu,"mnu_camp_action"),
]),
("recruit_them",
[
(eq, reg7, 0),
(gt, reg5, 0),
],
"Recruit them ({reg6} denars).",
[
(party_add_members, "p_main_party", "trp_bandit", reg8),
(troop_remove_gold, "trp_player", reg6),
(store_current_hours, "$g_bandit_recruit_last_time"),
(jump_to_menu,"mnu_camp_action"),
]),
("forget_it",
[
(eq, reg7, 0),
(gt, reg5, 0),
],
"Forget it.",
[
(jump_to_menu,"mnu_camp_action"),
]),
],
),
Rehberler
Scripts.py'de "party_get_ideal_size" ara, onun hemen aşağısında bu satırları bulacaksın.
Sarı renkteki rakam, ana rakam. Burada yazılan sayının büyüklüğü/küçüklüğü, katsayı oranını arttırır ve ona göre bir sayı verir. Tabii, diğer oranları da hesaba katarak bu sayı civarında bir asker limiti verir.
Kırmızı renkteki rakam, leadership başına verilen asker alabilme sayısı. Daha sonra bunun skillinin nasıl değiştirilebileceğini de anlatırım.
Yeşil renkteki rakam, kaç renown başına 1 tane daha ekstra troop komuta edebilme oranını belirliyor.
Turuncu renkteki rakam, herhangi bir orandan bağımsız olarak, kralların komuta edebildiği asker sayısına direk bonus asker veren sayı.
Mor renkteki rakam, yukarıdakinin marshallere olanı.
Kahverengi rengindeki rakam, eğer bir lordun kalesi varsa verilen asker sayısı, bu sayı herhangi bir oran veya hesaplamadan bağımsız olarak direk verilen sayı.
Mavi renkteki rakam, işte bütün bu yukarıdaki oranlara göre verilen sayının belli ortalamasının alındığı ve burada yazılan sayıya göre hesaplanıp, Lordların maksimum sayısına etki ediyor. Tabii buradaki husus, sayı ne kadar az olursa o kadar büyük bir asker sayısı elde edilir.
Bu kodların hepsi AI lordları için geçerlidir.
Onun dışında bu da benim kendi eklentim;
Bu herhangi bir köy elde tutulduğunda verilen ekstra asker sayısı.
ve
Bu da herhangi bir Şehir elde tutulduğunda geçerli.
("party_get_ideal_size",
[
(store_script_param_1, ":party_no"),
(assign, ":limit", 30),
(try_begin),
(party_slot_eq, ":party_no", slot_party_type, spt_kingdom_hero_party),
(party_stack_get_troop_id, ":party_leader", ":party_no", 0),
(store_faction_of_party, ":faction_id", ":party_no"),
(assign, ":limit", 10),
(store_skill_level, ":skill", "skl_leadership", ":party_leader"),
(store_attribute_level, ":charisma", ":party_leader", ca_charisma),
(val_mul, ":skill", 5),
(val_add, ":limit", ":skill"),
(val_add, ":limit", ":charisma"),
(troop_get_slot, ":troop_renown", ":party_leader", slot_troop_renown),
(store_div, ":renown_bonus", ":troop_renown", 25),
(val_add, ":limit", ":renown_bonus"),
(try_begin),
(faction_slot_eq, ":faction_id", slot_faction_leader, ":party_leader"),
(val_add, ":limit", 100),
(try_end),
(try_begin),
(faction_slot_eq, ":faction_id", slot_faction_marshall, ":party_leader"),
(val_add, ":limit", 20),
(try_end),
(try_for_range, ":cur_center", castles_begin, castles_end),
(party_slot_eq, ":cur_center", slot_town_lord, ":party_leader"),
(val_add, ":limit", 20),
(try_end),
(try_end),
(store_character_level, ":level", "trp_player"), #increase limits a little bit as the game progresses.
(store_add, ":level_factor", 80, ":level"),
(val_mul, ":limit", ":level_factor"),
(val_div, ":limit",80),
(assign, reg0, ":limit"),
]),
Sarı renkteki rakam, ana rakam. Burada yazılan sayının büyüklüğü/küçüklüğü, katsayı oranını arttırır ve ona göre bir sayı verir. Tabii, diğer oranları da hesaba katarak bu sayı civarında bir asker limiti verir.
Kırmızı renkteki rakam, leadership başına verilen asker alabilme sayısı. Daha sonra bunun skillinin nasıl değiştirilebileceğini de anlatırım.
Yeşil renkteki rakam, kaç renown başına 1 tane daha ekstra troop komuta edebilme oranını belirliyor.
Turuncu renkteki rakam, herhangi bir orandan bağımsız olarak, kralların komuta edebildiği asker sayısına direk bonus asker veren sayı.
Mor renkteki rakam, yukarıdakinin marshallere olanı.
Kahverengi rengindeki rakam, eğer bir lordun kalesi varsa verilen asker sayısı, bu sayı herhangi bir oran veya hesaplamadan bağımsız olarak direk verilen sayı.
Mavi renkteki rakam, işte bütün bu yukarıdaki oranlara göre verilen sayının belli ortalamasının alındığı ve burada yazılan sayıya göre hesaplanıp, Lordların maksimum sayısına etki ediyor. Tabii buradaki husus, sayı ne kadar az olursa o kadar büyük bir asker sayısı elde edilir.
Bu kodların hepsi AI lordları için geçerlidir.
Onun dışında bu da benim kendi eklentim;
(try_for_range, ":cur_center", villages_begin, willages_end),
(party_slot_eq, ":cur_center", slot_town_lord, ":party_leader"),
(val_add, ":limit", 10),
(try_end),
Bu herhangi bir köy elde tutulduğunda verilen ekstra asker sayısı.
ve
(try_for_range, ":cur_center", towns_begin, towns_end),
(party_slot_eq, ":cur_center", slot_town_lord, ":party_leader"),
(val_add, ":limit", 30),
(try_end),
Bu da herhangi bir Şehir elde tutulduğunda geçerli.
Ana Menü Hakkında
Oyuna ilk girdiğiniz karşınıza çıkan Ana menü'dür. Peki, burası ne kadar kişiselleştirilebilir? İşte cevap;
/Mount&Blade Warband/Textures/warrider_logo.dds, "Başlangıç Eğitimi"'nin üzerindeki logoyu temsil eder. Resim dosyasıdır.
/Mount&Blade Warband/Textures/main_menu_nord.dds, arkadaki büyük resmi temsil eder. Nord Savaşçıları ve sol taraftaki bütün alan tek bir resimdir.
*Yeni bir menü seçeneği eklenemez. Hardcodelanmıştır.
*Hareket eden resimler daha önce eklendi. Bilin, bu mümkün.
*Herhangi bir menü seçeneğini hakkında ayarlar yapmak için;
-Mod klasöründe "game_variables.txt" dosyası olacak.
-Açın.
-Arama yapın; "initial_".
-Arama yaptıktan sonra, direk bunları göreceksiniz,
Code:
#main menu (initial)
initial_tutorial_button_position_x = 0.05
initial_tutorial_button_position_y = 0.48
initial_tutorial_button_size_x = 0.185
initial_tutorial_button_size_y = 0.031
initial_tutorial_button_text_size_x = 0.022
initial_tutorial_button_text_size_y = 0.030
initial_tutorial_button_text_flags = 0x10
initial_tutorial_button_text_color = 0xFF110000
initial_tutorial_button_highlight_text_color = 0xFFFFDD00
initial_start_new_game_button_position_x = 0.05
initial_start_new_game_button_position_y = 0.44
initial_start_new_game_button_size_x = 0.185
initial_start_new_game_button_size_y = 0.031
initial_start_new_game_button_text_size_x = 0.022
initial_start_new_game_button_text_size_y = 0.030
initial_start_new_game_button_text_flags = 0x10
initial_start_new_game_button_text_color = 0xFF110000
initial_start_new_game_button_highlight_text_color = 0xFFFFDD00
initial_resume_game_button_position_x = 0.05
initial_resume_game_button_position_y = 0.40
initial_resume_game_button_size_x = 0.185
initial_resume_game_button_size_y = 0.031
initial_resume_game_button_text_size_x = 0.022
initial_resume_game_button_text_size_y = 0.030
initial_resume_game_button_text_flags = 0x10
initial_resume_game_button_text_color = 0xFF110000
initial_resume_game_button_highlight_text_color = 0xFFFFDD00
initial_multiplayer_button_position_x = 0.05
initial_multiplayer_button_position_y = 0.36
initial_multiplayer_button_size_x = 0.185
initial_multiplayer_button_size_y = 0.031
initial_multiplayer_button_text_size_x = 0.022
initial_multiplayer_button_text_size_y = 0.030
initial_multiplayer_button_text_flags = 0x10
initial_multiplayer_button_text_color = 0xFF110000
initial_multiplayer_button_highlight_text_color = 0xFFFFDD00
initial_custom_battle_button_position_x = 0.05
initial_custom_battle_button_position_y = 0.32
initial_custom_battle_button_size_x = 0.185
initial_custom_battle_button_size_y = 0.031
initial_custom_battle_button_text_size_x = 0.022
initial_custom_battle_button_text_size_y = 0.030
initial_custom_battle_button_text_flags = 0x10
initial_custom_battle_button_text_color = 0xFF110000
initial_custom_battle_button_highlight_text_color = 0xFFFFDD00
initial_options_button_position_x = 0.05
initial_options_button_position_y = 0.28
initial_options_button_size_x = 0.185
initial_options_button_size_y = 0.031
initial_options_button_text_size_x = 0.022
initial_options_button_text_size_y = 0.030
initial_options_button_text_flags = 0x10
initial_options_button_text_color = 0xFF110000
initial_options_button_highlight_text_color = 0xFFFFDD00
initial_credits_button_position_x = 0.05
initial_credits_button_position_y = 0.24
initial_credits_button_size_x = 0.185
initial_credits_button_size_y = 0.031
initial_credits_button_text_size_x = 0.022
initial_credits_button_text_size_y = 0.030
initial_credits_button_text_flags = 0x10
initial_credits_button_text_color = 0xFF110000
initial_credits_button_highlight_text_color = 0xFFFFDD00
initial_quit_button_position_x = 0.05
initial_quit_button_position_y = 0.20
initial_quit_button_size_x = 0.185
initial_quit_button_size_y = 0.025
initial_quit_button_text_size_x = 0.022
initial_quit_button_text_size_y = 0.030
initial_quit_button_text_flags = 0x10
initial_quit_button_text_color = 0xFF110000
initial_quit_button_highlight_text_color = 0xFFFFDD00
initial_game_logo_position_x = 0.045
initial_game_logo_position_y = 0.54
initial_game_logo_size_x = 0.2
initial_game_logo_size_y = 0.07
initial_version_info_position_x = 0.18
initial_version_info_position_y = 0.525
initial_version_info_text_size_x = 0.016
initial_version_info_text_size_y = 0.016
initial_version_info_text_flags = 0x200
initial_version_info_text_color = 0xFF110000
initial_version_info_highlight_text_color = 0xFFFFDD00
Burada ki her bir paragraf bir seçeneği temsil ediyor. Peki, nedir anlamları?
_position_y, vertikal olarak yerini değiştirir. Yukarı aşağı...
_position_x, horizontal olarak yerini değiştirir. Sağ sol...
_text_size_x, horizontal olarak seçeneğin boyutunu ayarlar.
_text_size_y, vertikal olarak seçeneğin boyutunu ayarlar.
_text_flags_, pek bir bilgim yok.
_text_color_, seçeneğin rengini ayarlar. İnternetten "Hex Code Colors" gibi bir arama verirseniz, burada kullanabileceğiniz renk kodları bulabilirsiniz.
_highlight_text_color_, üstüne gelindiğinde seçeneği parlatacak olan renk.
*Numaralar ne kadar büyük olursa, boyutta o kadar büyük oluyor.
*Mesela, bir seçeneği yok etmek istiyorsanız;
-İstediğiniz seçeneğin size_y ve size_x 'lerini 0 yapın.
-FIN-
Oyun Tarihini Değiştirme
Gayet basit bir işlem. Şöyle ki, ilk olarak "module_scripts.py" dosyasında "game_get_date_text" araması verin. Karşınıza bunun çıkması lazım; (Benim yaptığım aramada 4. bulgu doğruydu, yani arama yaptıktan sonra 3 kere daha CTRL+G yapın)
Gayet açık bir şekilde kırmızı renkli rakamı neye değiştirirseniz oyuna başladığınızda tarih bu olacak. Bir çok mod için güzel bir detay olabilir.
Onun dışında, bej renkli rakam, bir günde kaç oyun saati olduğunu değiştirmesi lazım. Test etmediğim için olmayabilir. Aynı teorim, yeşil renkli rakam içinde geçerlidir. Oyuna başladığınızda kaçıncı ayda başladığınızı değiştirmenize yaraması lazım.
Gayet basit bir işlem. Şöyle ki, ilk olarak "module_scripts.py" dosyasında "game_get_date_text" araması verin. Karşınıza bunun çıkması lazım; (Benim yaptığım aramada 4. bulgu doğruydu, yani arama yaptıktan sonra 3 kere daha CTRL+G yapın)
#script_game_get_date_text:
# This script is called from the game engine when the date needs to be displayed.
# INPUT: arg1 = number of days passed since the beginning of the game
# OUTPUT: result string = date
("game_get_date_text",
[
(store_script_param_2, ":num_hours"),
(store_div, ":num_days", ":num_hours", 24),
(store_add, ":cur_day", ":num_days", 23),
(assign, ":cur_month", 3),
(assign, ":cur_year", 1257),
(assign, ":try_range", 99999),
(try_for_range, ":unused", 0, ":try_range"),
Gayet açık bir şekilde kırmızı renkli rakamı neye değiştirirseniz oyuna başladığınızda tarih bu olacak. Bir çok mod için güzel bir detay olabilir.
Onun dışında, bej renkli rakam, bir günde kaç oyun saati olduğunu değiştirmesi lazım. Test etmediğim için olmayabilir. Aynı teorim, yeşil renkli rakam içinde geçerlidir. Oyuna başladığınızda kaçıncı ayda başladığınızı değiştirmenize yaraması lazım.
WB Kodlama Terimleri
Selamlar,
Nice süredir konuya birşey paylaşmıyordum. Obvious sebeplerden dolayı böyle bir rehber hazırlama gereği duydum, anladığım ve gözlemlediğim kadarıyla (nihayet!) kodlama alanına ufak ufak ilerlemeler başlamış, belki onca seneden sonra farklı yüzler görmeye başlayabilecez modlama alanında. Bu rehber kodlama da aşina olup da bilmediğiniz veya hiç bilmediğiniz bazı terimleri öğretecek size. Özellikle kodlamada bu terimler vasıtasıyla öğreneceğiniz pek çok method ve sisteme farklı bakış açıları da çabası. Ve başlıyorum...
Terimler
Module (Modül) - Daha popüler adıyla "Modifikasyon" veya kısa söylemiyle "Mod" ile aynı anlama gelir. Fakat yaptığımız işin teknik adı budur.
Scene (Sahne) - Zaten bilinen birşey. Sahne motorun tanımladığı bir ortamdır, bu ortamda pek çok objeler bulunur ve özellikle "agent" sisteminin kullanıldığı ve bu sistemle oynanabilen bir platforma dönüşür. Sahne kodlarıyla bu sahnenin içine "external" olarak konan objelerin yerini, cismini veya herhangi somut bilgisini saklayabilirken, .sco uzantılı dosyayla sahnenin kendisini saklayabilmekteyiz. Aslında işi yapan yine kod.
Agent (Canlı veya Aktör) - Agentlar Native'de aslında savaşlarda savaştığımız herşey. Mesela;
Dünya haritasında bir düşman partisine saldırırsınız: X
Parti lideri ile konuşma ekranı geçer: Y
Seçenek menüsü çıkar: Z
Savaşa girersiniz: V
X: Bir partydir. Pek çok troopun içinde olduğu.
Y: Lider bir troopdur.
Z: 2D bir meshdir. Presentations, meshes ile oluşturulmuş.
V: Ve işte...gördüğünüz bütün o trooplar size tanıdık geliyor değil mi? Görünüş olarak öyle ama değiller. Orada gördükleriniz birer aktör, yani agent. Oyun motoru agent ile troop arasındaki farklılığı çok net ortaya koymuştur. Troop bir ruh, agent ta o ruhu yaşatan fiziksel varlıklar. Aktörler. Bir sahnede gördüğünüz bütün Lordlar, krallar, düşman askerleri, sizin askerleriniz ve hatta sen bile birer aktörsünüz.
Agentlar troopların motor tarafından oluşturulmuş "sahne" ortamındaki temsilidir. Ve, trooplar ile aktörler aynı şey değillerdir.
Mesh (Materyal) - Bir mesh 2D'dir. 3D meshler obje kategorisine girer ve oyunda gördüğümüz herşey anlamına girer. Zırhlar, atlar, silahlar...vs hepsi 3D birer objedir. 3D objede bir meshtir aslında ama burası biraz karışık.
Burada bahsettiğim mesh, bir 2D tasarımdan ibarettir. En çok presentations.py ve tableau_materials.py'de kullanılır çünkü varoldukları yer orasıdır. Bir meshi oyuna aktarmak için onu ilk önce bir presentations ve tableau içine koymanız gerekir ve öyle kullanmanız gerekir. Mesela, bir şehre girdiğinizde arkadaki şehir resmi bir 2D meshtir, fakat şehir sahnesine girdiğinizde gördüğünüz bütün o binalar 3D objedir, yani 3D meshtir.
Script (Senaryo) - Script ile kod çok karıştırılan şeylerdir. Script, bir senaryodur yani pek çok koddan varolmuş birşeyi gerçekleştirmek için yaratılmıştır. Mesela, oyunun içindeki moral sistemi belli bir sistemi vardır. Bu sistemin içindeki "morali düşürme" veya "morali arttırma" yı yapan kodlar birer scripttir. Yani partinizde çok asker vardır, ve motor bunu verilen kondisyonlar içinde check eder, ve checkler doğru geri döndüğünde "moral düşürme" scriptini ateşler.
Peki o zaman, kod veya trigger ne? Kod, tek satır motora ne yapacağı tanıtılmış bir cümledir. (agent_set_position) dediğimde, o aktörün orada olması gerektiğini sağlar.
Trigger (Ateşleme) Trigger, kodlamada bir scriptin veya kodun neye göre ateşleneceğini sağladığınız yer. Bu devamlı bir loop şeklinde de olabilir, ya da belli birşey gerçekleşince de olabilir. Scriptten farkı, scriptin içinde bir ateşleme parametresi belirleyemezsiniz. Fakat triggerda zaman-bazlı veya action-bazlı belirleyebilirsiniz.
Parameter (Parametre/Kondisyonlar) Parametre trigger'ın içinde bulunan birşeydir. Bildiğimiz kodlama mantığı ile alakası yoktur, tamamen back-end çalışır. Hardcodedur, oynanamaz. Bir trigger'ın ateşlenmesi için gerekli action veya zamanı belirlersiniz.
Mission (Sahne kodlaması) Sahneyi çaktınız, değil mi? Motorun tanımlayabildiği bir ortam demiştik, tıpkı Dünya Haritası gibi. Peki bu sahnede olan herşeyi sağlayan kodlama sistemi ne diye merak etmiyormusunuz? İşte benim en çok kodlamasını sevdiğim yer burası. Savaşıyorsunuz, adam öldürünce onun öldüğünü belirttiğiniz ve ölme animasyonun oynadığı yer burası işte. Ve pek çok şekilde diğer kodlama sistemleriyle entegre etmek mümkün. (scene_props.py, scripts.py...) Canır canır yanan bir BOSS mu yaratmak istiyorsunuz, aktörün posizyonlarını ölçüp gerekli particleları verdiğiniz yer burası. Bir sahne mission olmadan sadece görüntüdür. İnteraktif hale geldiği yer missionla olur.
Loop (Tekrarlama) - Tekrarlama demektir. Bu ne demek, warband kodlamasında bunu "try_for" koduyla yapıyorsunuz. "try_for_agents" dediğinizde ve altına "agent_is_alive" kondisyonunu belirlediğinizde, bu loop sahnede varolan bütün canlı aktörleri bulana kadar döner ve elinize bütün bu canlı aktörlerin verisi ulaşır. Sonra bunları "agent_deliver_damage_to_agent" ile öldürürmüsünüz yoksa "agent_set_position ile kendinize mi çekersiniz? Size kalmış. Aktör sadece bir örnek tabii.
Devam edecek...
Zamanla yaptıkça burayı zenginleştirecem. Eğer sende bir kodcuysan, bana bu konuda yardım etmekte serbestsin. Ve öğrenmek isteyen arkadaşlar bu konu üzerinden istediği soruyu sorabilirler.
Saygı ve Sevgilerimle,