Modül Sistem Dizilimine Giriş Dersi

Users who are viewing this thread

Merhaba, yabancı forumda gördüğüm ve kodlamayla ilgili çok güzel ve açıklayıcı bilgiler içeren bir başlığı ,hem forumda kodlama öğrenmeye hevesli insanlara yardımcı olmak, hem de çevirirken kendim de öğrenirim diye çevirip buraya koyuyorum, yazılar uzun, umarım işinize yarar.
Orijinal Konu(Caba`drin): An Introduction to Module System Syntax and Usage

Mount and Blade(Warband)’ı modlamaya yönelik, modül sisteme giriş niteliğinde ve kullanmaya başlamak için çok yararlı başlıklar ve kılavuzlar var, fakat benim amacım modül sistemin çekirdeğini oluşturan işlemler ve söz diziminin temel noktalarına yönelik bir kılavuz oluşturmak.


Temeller
Modül sistemde kullanılabilecek geçerli bütün komutların ve işlemlerin bulunduğu liste header_operations.py dosyası içerisinde bulunabilir. Genelde yanlarında # işaretleriyle birlikte ipuçları içeren yorumlar bulunur, fakat asıl olarak her operasyonda(işlem) hangi argümanların içerilmesi gerektiğini gösterir. Modül sistem içinde her işlem aşağıda bulunan şekilde düzenlenir:
1. Parantez içine alınır: (operasyon)
2. Hemen ardından virgül gelir: (operasyon),
3. Operasyon içinde bulunan argumanlar birbirinden virgülle ayrılır: (operasyon, argüman, argüman)

Ek olarak, header_operations dosyası listelenen her operasyona bir sayısal kod verir. Örnek olarak, call_script = 1. Oyun hata verdiğinde, hatalar SCRIPT ERROR ON OPCODE ##:.... şeklinde gözükür. OPCODE numarası, header_operations içerisindeki operasyonun numarasını verir. Yan, hata OPCODE1 şeklindeyse, hatadaki kodun satırı call_script’i kullanmıştır.

Çeşitli modül dosyalarının içerisinde bulunan maddeler indekslenmiştir, sırasal sayı değeri dosya içinde bulunan sıralamalarına göre bulunur. Bu indeksler 0’la başlar ve 1 eklenerek devam eder. Böylece troops, items, triggers, scenes, vb, .txt dosyası halindeyken indeks değerleriyle refere edilirler. Eğer “trigger 0”da bir hata kodu görürseniz, bu dosyadaki ilk trigger’dır, ve satır 4teyse, trigger’daki 5. operasyona bakmanız gerekir.


Değişkenler

Yerel değişkenler - ": variable " -:sad:iki nokta üst üste) ile başlayan değişkenler, yerel değişkenlerdir. Bu değişkenler sadece belirtildikleri kod bloğunda(tuple) yer alır ve diğer kod bloklarında refere edilemezler. Öncelikle değişkenler kendileri daha önceden bir değer taşıyabilecekleri için bunlara 0 ya da başka bir değer verilmelidir. Alıntı(denden) işaretiyle kapatılırlar. Örn: “:agent_id”
Genel değişkenler - "$variable" - $(soru işareti) ile başlayan değişkenler, genel değişkenlerdir. Herhangi bir modül_x’in içerisinde refere edilebilirler. Varsayılan değerleri 0’dır. . Alıntı(denden) işaretiyle kapatılırlar. Örn: "$g_talk_troop"

Registerlar(kayıt) - reg(#) yada reg# - motorun geçici bilgileri saklamak için kullandığı değişkenlerdir. Genel değişken sayılırlar, fakat birkaç farklı kod tarafından erişilebilirler, ve sonrasında başka bir kod tarafından kullanılmak üzere bırakılırlar. Header_commons içerisinde reg0’dan reg65’e kadar kayıtlar vardır.
Stringler(dizilim) - s# - tamsayılar yerine belli dizilimleri kullanan özel değişkenlerdir. Module_strings içerisinde belirtilmeyen(quick strings) stringler @ işaretiyle başlar. Header_common içerisinde s0’dan s67’ye kadar tanımlanmışlardır.


Positions(pozisyonlar) - pos# -  Yukardaki iki değişkenin aksine, pozisyon lar birden fazla bilgiyi depolarlar, her pozisyon X, Y, Z koordinatlarını ve ayrıca X, Y, Z eksenlerinde rotasyonu belirler. Header_commons’da pos0’dan pos64’e kadar pozisyon tanımlanmıştır, pos64’ten itibaren belirsiz bir miktar pozisyon kuşatma kuleleri(belfry) tarafından kullanılır.
Constants(sabitler) - constant – module_constant  içerisinde belirlenmiş sabitlerdir, kendilerine verilen sabit sayı değerleri taşırlar ve module_constant içerisinde değişiklik yaparak değiştirilemezler. Herhangi bir module_x dosyasından ve herhangi bir tuple’dan çağırılabilirler. Constantlar “” işareti içine alınmazlar.

Yerel ve genel değişkenler, ve registerlar(kayıt) operasyon içerisinde (assign, <variable_name>, <variable_value>), şeklinde gösterilirler. Varieble value(değişken değeri) bölümü başka bir variable name(değişken ismi) de olabilir. Stringler ve pozisyonların kendi özel operasyonları vardır, header_operations’da gösterildiği üzere.


Module System Ön ekleri
 
Modül sistem içerisinde(örn; module_mission_templates), bir koda veya diğer modül dosyalarında bulunan bilgilere kodun önüne, ön ek(prefix) koyarak çağırılabilir.
  • module_animations: "anim_"
  • module_factions: "fac_"
  • module_info_pages: "ip_"
  • module_items: "itm_"
  • module_map_icons: "icon_"
  • module_game_menus: "menu_"
  • module_meshes: "mesh_"
  • module_mission_templates: "mst_"
  • module_particle_systems: "psys_"
  • module_parties: "p_"
  • module_party_templates: "pt_"
  • module_pstfx_params: "pfx_"
  • module_presentations: "prsnt_"
  • module_quests: "qst_"
  • module_scene_props: "spr_"
  • module_scenes: "scn_"
  • module_scripts: "script_"
  • module_skills: "skl_"
  • module_sounds: "snd_"
  • module_strings: "str_"
  • module_tableau_materials: "tableau_"
  • module_troops: "trp_"

Module_Scripts, Parametreler, Argumentlar, vs.

Çoğu module_x dosyası kendi içerisindeki kodlardan oluşur. _skills, _troops, _items vs gibi dosyalar oyundaki belli başlı unsurları tanımlar. module_game_menus oyundaki bütün menüleri, ayarları vs. kapsar. Presentationlar bütün sunum-çizim verilerini kapsar. Fakat module_scripts bir sürü modül dosyalarından çağırılabilir, oyun kodunun içerisinde “genel” fonksiyonları sağlar. (call_script, "script_scriptname", <optional_aruments>), a Goto:, Jump, fonksiyonlarını kullanabilirsiniz.
Bu işlemi anlaşılır kılmak için, call script operasyonları bilgiyi hali hazırdaki koddan genel değişkenler kullanmadan script’e getirmek için kullanılır. Bu argümanlar ya da parametreler halihazırdaki kod parçasındaki yerel değişkenler olabilir. Module_scripts içindeki kodlar, script içerisinde yerel değişken olarak aktarılan parametreleri depolayarak kullanılmaya başlar. Scriptler bilgiyi çağırıldıkları şekilde aynen geri gönderemezler, bunu yapmak için registerlar kullanılır. Bir kodu çağırırken, script bittiğinden, bu registerlar, kolaylık olsun diye yerel değişkenler içine kaydedilir.

Örnek:
Code:
//...statements(ifadeler)...//
(assign, ":local_variable_1", 10),
(assign, ":local_variable_2", 5),

(call_script, "script_örnek_script", ":local_variable_1", ":local_variable_2"),

(assign, ":local_variable_3", reg0), #local_variable_3 = 15

//...daha fazla bir şeyler, local_variable_3 ü kullanan...//
Code:
  # script_örnek_script
  # Input: variable_1, variable_2
  # Output: Sum in reg0
  ("örnek_script", [
     (store_script_param, ":num1", 1), #şimdi num1 10
     (store_script_param, ":num2", 2), #şimdi num2 5 

     (store_add, ":sum", ":num1", ":num2"),

     (assign, reg0, ":sum"),
  ]),


Terminoloji
Troops(askerler) module_troops içerisinde isimlendirilmiş askerleri refere ederken kullanılır,  "trp_player" oyuncunun kendisidir,  "trp_npc##" yoldaşlarımıza verilen referans, "trp_knight_#_##" lordlara verilen referans,  ve "trp_swadian_footman" vs, vs. Daha fazla jenerik askerlede, her partideki çoklu örnekler yaratmak için module_troops içerisindeki girişler kullanılır "template".

Alternatif olarak, agent’lar bir scene’de(savaş haritası, taverna vb) bulunan, özel karakterlere sayılarla referans verir. Agent’lar module_troops’taki template’lerden çağırılır, oyuncu(player), NPCler, lordlar kendilerine özeldir, fakat genel askerler için tek bir trop template’inden çoklu agentlar yaratılabilir. Her agent scene içinde özel bir sayıya sahiptir, scene sona erdiğinde agent biter, agent id’si anlamsız kalır.
“Party” dünya haritası üzerinde gezen herhangi bir gruptur, oyuncunun grubu, haydutlar veya NPC lordları, veya kale/köy/şehir olabilir. Değişik tipteki partiler ilk party slotu(yuva) "slot_party_type"da kategorilere ayrılır(ya da party slot 0 olabilir, aşağıya göz atın), her tip parti için bir tamsayı atanmıştır. Bu tipler module_constant içinde tanımlanmıştır ve spt_*(slot_party_type’nin kısaltılmışı) ile başlar. Spt_* için birkaç örnek değer spt_kingdom_hero_party (NPC lordları) ve spt_castle (...kaleler) gösterilebilir.

Her parti kodda refere edilirken bir ID numarasına sahiptir. Örnek olarak, oyuncu party’si "p_main_party"dir ve indeks değeri ya da Party ID’si 0’dır. Bazı partiler sabit veya statik ID numaralarına sahiptir, oyuncu partisinde ve bütün kale/şehir,kasabalarda olduğu gibi. Sabit ID’ye sahip olanlar module_parties içinde verilmiştir. Modül dosyalarını çalıştırdığınızda ID_parties.py dosyasından ID numaralarına bakabilirsiniz.(ID=identity-kimlik)

module_parties içinde verilmemiş kalan diğer partiler, party_template’e göre oyun tarafından dinamik olarak yaratılırlar.(agent-troop arasındaki fark gibi). Bu partiler module_party_templates içinde yer alır ve hepsi "pt_*" önekiyle refere edilir. Bu template asker çeşitlerinin listesini ve  oyunda olacak olan template’in asker sayısını içerir.(oyun 2 değer arasındaki değerlerde rasgele bir  sayı verir). Bir party template’i oyun sırasında <spawn_party> komutuyla yaratılabilir. Bu yeni partiye bir ID numarası verilir ve bir slot_party_type, vb değeriyle sınıflandırılır. Party templateleri varolan partiler içinde kullanılabilir, böylece varolan bir partiye template ekleyerek asker takviyesi yapılabilir.
 
Slotlar, bir obje tarafından değişkenleri dizmek için gereken yollardır(party, troop, agent, team, faction, scene, item, player, scene prop, yada party template).  Her party, troop, agent, item vs. belli sayıda "slots" (variables) atanmış olur. Bu değişkenler her objenin versiyonu için genel bir isimlendirmesi "slot_item_SLOTNAME"(burada items için)dir, kullanışlı olmasına karşın her obje için kendine özel bilgi içerir. Bir sabit “constant”, olarak gözükmesine karşın, oyun motorunun dizilmiş değişkenlerin(slotlar) isimlerini module_constants içinde sayılara çevirir. Örn: (slot_item_base_price = 53). Bu oyun motorunun 53. değişkene atanmış item’ın taban fiyatına baktığı anlamına gelir.

Yani, slot kullanan operasyonlara baktığınızda, (item_get_slot, ":base_price", ":item_id", slot_item_base_price gibi), hangi item’ın taban fiyatınını almak istediğinizi belirtmeniz gerekir. Fakat mesela değişken dizilmiş olduğundan, try_for_*  loop’una(döngü) iliştirip birçok ":item_id" içindeki her item’ın taban fiyatını çıkartabilirsiniz.

Belli bir item’in fiyatına item_get_slot operasyonunu kullanarak ulaşabilirsiniz, item_set_slot ile değiştirebilirsiniz, ve item_slot_eq ile eşitliği test edebilirsiniz, vs.

C-benzeri programlama dili biliyorsanız, slotlar şu şekilde çalışır:sad:spouse=eş)
slot_troop_spouse
spouse[troop1] = spousename
spouse[troop2] = spousename
spouse[trp_player] = spousename
motor troop_variable_30[troop1], troop_variable30[trp_player] vb olarak okur, since slot_troop_spouse sabitler içinde slot 30 olarak tanımlandığından.

slot_item_base_price
baseprice[item1] = priceA
baseprice[item2] = priceB
baseprice[item3] = priceC
motor bunu da item_variable_53[item1], item_variable_53[item2] vb olarak okunur, sabitler içinde 53 olarak tanımlandığından

*_set_slot operation ile tanımlanmadan önce bütün slotların değeri 0’dır.



Kontrol ve Koşullu Operasyonlar ve Dizilim(Control and Conditional Operations and Syntax)
Genel olarak, oyun motorunu bütün kondisyonel(koşullu) operasyonları “eğer-if” olarak ve bunu izleyen bütün kodları da “o zaman -then” olarak, “eğer-o zaman” ilişkisi içinde değerlendirdiğini belirtmek gerekir. Motor kodları okurken, koşullu bir operasyon başarısızlığa uğrarsa oyun durur, ve kalan kodları okumaz.

Eğer-o zaman(yada) ifadelerini izole edip hatalara izin vermesini ve kalan kodların okunması için (try_begin), (else_try), ve (try_end)’i kullanan “try block”(deneme blokları) kullanılması koşultır. Aşağıda ayrıntılı incelenmiştir.
(eq,<value>,<value>),  Value 1 = Value 2 eşit mi?
(gt,<value>,<value>),  Value 1 > Value 2 büyük mü?
(ge,<value>,<value>),  Value 1 >= Value 2 büyük/eşit mi?
(lt,<value>,<value>),  Value 1 < Value 2 küçük mü?
(le,<value>,<value>),  Value 1 <= Value 2 küçük/eşit mi?
(neq,<value>,<value>), Value 1 != Value 2 faktöriyel eşit mi?
(is_between,<value>,<lower_bound>,<upper_bound>), Lower <= Value < Upper alt ve üst sınırlar arasında mı?

Ayrıca "_is_" içeren her operasyon bir doğru-yanlış koşulının arandığını gösterir. Örnek olarak,
(agent_is_alive,<agent_id>), agent ID’si verilenin canlı olup olmadığına bakar. Eğer soru olumluysa, kod devam eder. Yanlışsa durur.

Bir D/Y testinde adece “yanlış”ı çek etmesini istiyorsanız(doğru olup olmadığına bakmadan), şunu kullanın:

(neg|<operation>),

Önceki örneğe benzer olarak, (neg|agent_is_alive,<agent_id>) kodun devam etmesi için sadece ID’si verilen agent’ın ölü olup olmadığına bakacaktır.(canlı DEĞİL)
(try_begin),
(try_end),
(else_try),
(try_for_range,<destination>,<lower_bound>,<upper_bound>),
(try_for_range_backwards,<destination>,<lower_bound>,<upper_bound>),
(try_for_parties,<destination>),
(try_for_agents,<destination>),

Destination(varış yeri) bir döngü içinde tekrarlanan değişkendir.
Yineleme alt sınırda başlayacak ve üst sınır-1’e kadar devam edecektir.
Yukarda değindiğimiz gibi, motor her koşullu operasyonu “if-then” olarak “if” olursa devamındaki kodun “then” olarak devam etmesini sağlar, AND(ve) bağlacı birçok string’i çoklu koşullu operasyonla bağlayarak gerçekleştirilir.
Örnek olarak, eğer bir agent’ın canlı VE at VE düşman olmasını istiyorsanız, kod şu şekilde olmalıdır:
(agent_is_alive,<agent_id>),
(neg|agent_is_human,<agent_id>),
(neg|agent_is_ally,<agent_id>),

Bir koşul(condition) VEYA başka bir koşul olması isteniyorsa,
(this_or_next|<operation>),
kullanılır.
Bu mantığa göre birçok defa bu şekilde kullanılabilir.
Örnek, bir değişkenin 1 VEYA 5 olması isteniyorsa:
(this_or_next|eq, ":test_variable", 1),
(eq, ":test_variable", 5),
 
Bütün koşullu operasyonlar, altlarından bulunan bütün kod satırlarına etkilediğinden dolayı, kod parçalarını ayırmak için bir yol gerekiyor, böylece koşullu operasyon yalnızca bir parçaya etki edicek ve kodun kalanı hata olsa bile devam edecek.
Bunu yapmak için, "try block" kullanılmalı, yani (try_begin) ve (try_end)  arasına yazılmış kod. Tipik bir if-then ifadesi olarak gözükebilir, ilk koddan sonra gelen (try_begin) koşulları yerine getirmesi gereken “if” yerine, onu takip eden "End If" veya  (try_end) satırları da “then” olarak düşünebilirsiniz. Bütün if-thenlerde, (else_try), “else if”-eğer olmazsa- ifadesinde olur. Eğer herhangi bir noktada (else_try)’dan önce kondisyon hata verirse, motor onun yerine geçecek bir (else_try)’ı arar.


Örnek:
Code:
#Yukarda herhangi bir kod
(try_begin),
    (eq, 1, 1), #Doğru, diğer satıra geç
	(gt, 2, 5), #yanlış, else try’a git
	#bağlı operasyonlar
(else_try),
    (eq, 0, 1), #yanlış diğer else try’a git
	# bağlı operasyonlar
(else_try),
    (eq, ":favorite_lance", ":jousting"), # belki?
	(assign, ":prisoners", 100),
(try_end),
#Kod favorite lance=jousting ve prisoners was set to 100’dan herhangi birine göre devam ediyor
M&B Modül system’i For-Next döngüsü için değişik çözümler sunar. En basit (try_for_range, ":iterator", <lower bound>, <upper bound>) kullanmak, bütün operasyonları döngüye sokmak ve (try_end) ile bitirmektir, "Next iterator" ya da benzeri bir şey kullanmaktansa.

Döngü alt sınırda başlayacak ve tam sayı basamaklardan üst-sınıra kadar devam edecektir, atandığı yere giderken değişkenler üstünden sayılacaktır, yukarıdaki “:iterator” örneğinde olduğu gibi. ":iterator", try_for_range block’u izleyen kod tarafından kullanılmalıdır, fakat eğer tam sayı-basamaklarının üst sınır-1’e olan yinelemelerini geçemezse. Eğer ":iterator" değişkeni izleyen kod tarafından kullanılmazsa, ":unused" değişkeni mutlaka onun yerine konulmalıdır.

Örnek:
Code:
(try_for_range, ":i", 0, 10),
    (store_add, ":count", ":i", 1),
	(assign, reg0, ":count"),
	(display_message, "@{reg0}"),
(try_end),
#Bu kod ekranda 1den 10a kadar sayıların sayıldığı bir mesaj gösterecektir.

Bunların yanı sıra (try_for_range_backwards, ":iterator", <lower bound>, <upper bound>) vardır, burada yineleme üst sınır-1’den başlayacak ve alt sınıra kadar sayılacaktır. header_operations’da yazan alt sınır ve üst sınırın yer değiştirmesi gerektiğini yorumunu dikkate almayınız, yanlış yazılmış. Bu söylediğimiz bir şeyi listenin indeksini bozmadan listeden kaldırmaya yarar(örn;bir parti içerisindeki üyeler).

Dikkat etmeniz gereken, hem alt sınır hem de üst sınırların “düz bir sayı” olması gerekmediğidir, kodun içinde daha önce verilmiş herhangi bir değişken de olabilir. Örnekler aşağıdadır.

İki spesifik (try_for_*) daha vardır: (try_for_agents, <agent_id>) ve (try_for_parties, <party_id>). Bunlar sırayla scene’deki bütün ajanları ve oyundaki bütün partiler arasında döngü yaratır. Yinelenen(iterator) Agent’ın(ya da party’nin) ID numarasıdır ve yerel değişkenler içinde depolanmalıdır.

Örnek:
Code:
(get_player_agent_no, ":player"),
(agent_get_team, ":playerteam", ":player"),
(try_for_agents, ":agent"), # bütün agentlar içinde yinelenir.
    (agent_is_alive, ":agent"), # şu anki agent’ın canlı olup olmadığına bakar
    (agent_is_human, ":agent"), #eğer canlıysa, insan olup olmadığına bakar(at değil)
    (agent_is_non_player, ":agent"), #eğer canlı ve insansa, agent’ın oyuncu olmadığına bakar    (agent_get_team, ":team", ":agent"), #eğer canlı, insansa ve oyuncu değilse, takımına bakar
    (eq, ":team", ":playerteam"), #canlı, insan, oyuncu-olmayan, agent’ın oyuncunun takımında olup olmadığına bakar 
	#buraya bu canlı,insan, oyuncu-olmayan, oyuncunun takımında olan agent’ı kullanan operasyonlar geliyor 
(try_end), #diğer agent’a geç
Çoğu zaman bütün agent’lar arasında bir agent’ı bulmak için döngü kullanmak isterseniz, ya da başka bir şeyler(itemlar gibi) arasında bir silahı bulmak istersiniz, fakat bulduğunuzda geri kalan diğerleri arasında döngüyü yinelemeye gerek yoktur. Bunun için döngü kırılması kullanılır. M&B Module System’in böyle bir özellik için özel bir operasyonu yoktur, fakat birkaç basit numarayla bir döngüyü kırabilirsiniz. Bu numara modül sistemde hangi döngü çeşidini(try_for_*) kullandığınıza göre değişir.

İlk yöntem: Döngünün sonunu değiştirmek
-Bir try_for_range döngüsünü kırmak
Bir try_for_range döngüsünü, üst değeri değiştirip alt değerle eşit olmasını sağlayarak kolaylıkla sağlayabilirsiniz. Böylecek, oyun motoru döngünün bir sonraki aşamaya atlamaya çalıştığında son yinelemeye geldiğini düşünüp bitirecektir. Döngü, kodu tekrarlamadan sona erecektir.
Bunu yapmak için, üst sınır döngünün içinde daha önceden tanımlanmış bir değişken olmalı, ayrıca veri kaybı olmadan değiştirilebilen bir değişken olmalı- bunun için yeni bir değişken yaratın ya da gerekirse bir tane kopyasını oluşturun. Bir kod yeteri kadar tekrarda uygulandığında, bir şey bulununca, vs., değişkeni döngünün sonunda alt değere eşit olacak şekilde ayarlayın(ya onu değişkenle aynı değere, ya da döngünün başladığı sabit değere atayın)

Örnek:
Code:
#Büyükçe bir döngünün(try_for_agents) içinde 
    (assign, ":end", "itm_glaive"),  # döngünün üst sınırını ayarlar
    (try_for_range, ":item", "itm_jousting_lance",":end"), #oyundaki bütün jousting lance’ler içinde döngü oluşturur
        (agent_has_item_equipped, ":agent", ":item"), #agent’ın eşyalarında lance olup olmadığına bakar
        (agent_set_wielded_item, ":agent", ":item"), #eğer kargı eşyalardaysa, elinde tutup tutmadığına bakar
        (assign, ":end", "itm_jousting_lance"), #döngü kırıcı-üst sınırla alt sınır aynı değerlere sahip, böylece kargılar içinde yineleme durur
    (try_end),
# try_for_agents loop’u devam ediyor
-Bir try_for_range_backwards döngüsünü kırmak
Yukardakiyle aynı yöntem kullanılır. Bu sefer, döngünün sonu, alt sınırdır, yani değişecek olan değişken alt sınır olmalıdır, ve üst sınırla aynı olacak şekilde değiştirilmelidir.


Örnek:
Code:
#Yukardaki kod ":troop" değişkenine bir değer atamış olsun
	(assign, ":array_begin", 0), # döngünün alt sınırını belirler
	(try_for_range_backwards, ":i", ":array_begin", 10), #0’dan 10 a kadar döngü
		(party_slot_eq, "p_main_party_backup", ":i", 0), #oyuncunun partisinin, party slot’unun 0’a eşit olup olmadığına bak 
		(party_set_slot, "p_main_party_backup", ":i", ":troop"), #eğer öyleyse, bu slot’a verilen troop değişkeninin değerini ata
		(assign, ":array_begin", 10), #Loop breaker – alt değerin üst değerle aynı olmasını sağla, diğer slotlara göz atma 
	(try_end),
İkinci yöntem: Koşul testi kullanarak
-Bir try_for_agents veya _parties döngüsü kırmak
try_for_agents ve try_for_parties döngülerinde, döngünün üst sınırını değiştirmek mümkün değildir. Onun yerine,kodun başında bir koşul testi(genel olarak eşitlik) gerçekleştirerek döngü kırılır. Yani koşul doğru olduğu sürece, döngünün içinde kod devam eder. Koşul yanlış olduğu anda, döngü devam eder, fakat döngünün içindeki hiçbirşey çalışmaz, ilk koşul yerine getirilmediği için döngü kısa sürede sona erer.
Bunu yapmak için, döngünün öncesinde bir değişken ayarlanmalıdır(en kolayı değeri 0 olan bir değişken oluşturmaktır). Sonrasında, döngünün içinde,bu değeri test eden bir koşullu operasyon konulmalıdır. Bir kere çalışmasını istediğiniz kod bloğundan sonra değişkene, değeri döngü tekrarlandığında koşulun yerine getirilmeyeceği bir değere çevirin.

Örnek:
Code:
#Yukardaki kod pos1’e bir değer vermiş olsun	
	(assign, ":break_loop", 0), #değişkene, döngüyü kırmak için test değeri verir
	(try_for_agents, ":agent"), #bütün agentlar içinde döngü 
	    (eq, ":break_loop", 0), #döngü kırıcını doğruluğunu kontrol eder
	    (agent_is_alive, ":agent"), #eğer öyleyse,devam edip,agentın canlı olmadığına bakar 
	    (agent_is_non_player, ":agent"), #canlıysa, oyuncu olmadığına bakar
		(agent_is_human, ":agent"), #canlı, oyuncu değil, 
		(agent_get_position, pos0, ":agent"), #canlı,insan, oyuncu-değil ise, bulunduğu pozisyonu alır ve pos0’a kaydeder 
		(get_distance_between_positions_in_meters, ":distance_to_target_pos", pos0, pos1), #pos0’dan pos1’e olan uzaklığa bak ve yerel değişkene kaydet
		(lt, ":distance_to_target_pos", 10), #agentımızın pos1’e 10 metre yakınlıkta bulunup bulunmadığına bak 
		(assign, ":agent_at_target", ":agent"), #öyleyse, agent’ın ID’sini yerel değişken "agent_at_target"a kaydet
		(assign, ":break_loop", 1), #Agent döngü kırıcı – test koşulunu değiştir ki eşitlik testi bir sonraki denemede yanlış çıksın
	(try_end),
#Bu döngü, canlı, insan, oyuncu-olmayan agent, pos1’e 10 metre uzaklıkta olduğu anda kırılacaktır 
#Agent bulunduğunda, devam eden kodlar bununla ilgili çalışacaktır



Diğer Başlıklar
Mission Templates(aynı zamanda module_triggersda) içinde bulunan bir trigger(tetikleyici) aşağıdaki şekli alır:
İlk kısım: bir trigger’ın hangi aralıklarla(saniye olarak yada "ti_on_agent_hit" gibi hard-code olarak) çek edildiğine bakar
İkinci kısım: erteleme, saniye olarak yine, ilk koşul bloğunun yerine getirilmesinden sonuç bloğuna geçişe kadar olan zamanı kapsar. "ti_on_agent_hit" gibi bir hard-code kelime/olay kullanıyorsanız bu kısım çalışmaz.
Üçüncü kısım: koşul yerine getirilip kodun sonuçları ortaya çıktıktan sonra trigger’ın tekrar çek edilmesi gereken süreyi verir, yine saniye olarak.
dördüncü kısım: koşullar bloğu, her zaman trigger çağırıldığında gerçekleşir.
beşinci kısım: sonuçlar bloğu, sadece koşul bloğu gerçekleştiğinde yerine getirilir, ve gerçekleşmesi için erteleme zamanının geçmesi gerekir.

Uygulamada şuna benzer:
Code:
 (10, 2, 60,
   [
    (eq, 1, 1),
   ],
   [
    (val_add, "$global_variable", 10),
   ]),
Burada ilk kısım 10 saniyedir, yani trigger her 10 saniyede kontrol edilir. Erteleme 2 saniyedir, yani koşullar yerine getirilmişse, sonuç bloğu 2 saniye sonra gerçekleşir. Tekrar gerçekleşme süresi 60 saniyedir, yani koşul bloğu yerine getirildikten 60 saniye sonra trigger tekrar kontrol edilir.
Koşul bloğu basit olarak 1=1 olan bir eşitlik testi şeklinde, yani her zaman gerçekleşir, böylece sonuç blokları trigger kontrol edildikten 2 saniye sonra gerçekleşir.
The conditions block is a simple equality test 1==1, that will always pass, so the consequences block will always fire 2 seconds after the trigger is checked. Sonuç bloğu bir genel değişkeni(global variable) alır ve 10 artırır.



Referans olacak diğer konular
Aşağıda verilen bağlantılar konuyla ilgili yardımcı olabilecek diğer başlıklardır, kolaylık olsun topladım.(çevrilmedi)



Başlık yapım aşamasındadır, önerilere, düzeltmeler vs. açığım. Teşekkürler.
 
Merhaba üstadlar, bu mod geliştirme işinden hiç anlamam ama son derece istekliyim, bu konuda bana yardımcı olabilecek kimse varsa lütfen bana yazsınlar, size minnettar olurum, şimdiden teşekkürler, hoşçakalın
 
yalnız ben de sadece çevirdim, arada Türkçeleşmeyen bazı kelimeler var, daha çok programcılık dilinde, eğer biraz ingilizceniz varsa orijinal konusundan da referans alarak kodlama öğrenmeye çalışabilirsiniz.
 
Nefdulin said:
C++ bundan kolay be abi

http://ftp.gnu.org/gnu/coreutils/coreutils-8.20.tar.xz  bu da saf C kodu, silme pointer ve hala bana modül sisteminden kolay geliyor :smile:

modül sisteminin sıkıntısı, normalde pythonda built-in olarak gelen özelliklerin encapsulate edilmiş olması. ki bu durum da python bilgisi olmayanların rahat edebilmesi için. bir nevi C ile yazılmış bir dil olan Python kullanılarak başka bir dil yazılmış yani (inception :smile: )
 
Asp.net, c#, Visual Basic, Borland delphi, Java Script bu dilleri adım gibi biliyorum ama bundan bişey anlamadım ben yahu neden acep :???:
 
MassiveStroke said:
Abi bana Wfastaki gibi askerlere nasıl komutlar verebilirim mesela 2 li sıra olurştur komutunu warbanda aktermak isiyorum
Burası soru yerimi şimdi ?
 
Back
Top Bottom