Tuesday, 2018-10-16, 6:58 AM Welcome Pengunjung


Indonesian Modding

Main | Sign Up | Login | RSS
[ New messages · Members · Forum rules · Search · RSS ]
  • Page 1 of 1
  • 1
Forum moderator: Rheiko  
Forum » Dunia Modding Warcraft III » Warcraft III Tutorial » Indeks Dinamik [Dynamic Indexing] (Metode Indeks Dinamik untuk Spell dan Sistem)
Indeks Dinamik [Dynamic Indexing]
RheikoDate: Tuesday, 2014-01-07, 9:10 PM | Message # 1
Co-Admin
Group: Administrators
Messages: 42
Awards: 2
Reputation: 12
Status: Offline
Contents
    IntroductionMUIDynamic IndexingComparisonCredits


Introduction

Dynamic indexing adalah teknik yang digunakan untuk memastikan spell atau kodemu dapat digunakan lebih dari satu kali tanpa gangguan. Pada pertama, ini sangat menakutkan untuk dilihat. Tutorial ini bertujuan untuk menunjukkannya dengan lebih mudah: memudahkan yang rumit.

Sebelum kita mulai Dynamic Indexing, kamu harus mengerti tujuannya. Tujuan utama adalah mencapai MUI, tujuan semua pembuat spell yang tidak gagal harus berharap untuk didapat.

MUI
MUI adalah singkatan dari Multiple Unit Instanceability. Yang tujuan satu-satunya: membuat spell dapat digunakan oleh lebih dari 1 unit (tanpa kejadian yang tidak diinginkan).

Apa masalah-masalah MUI yang saya bicarakan? Ya, Mari membuat spell mudah yang mengirim health point setiap 0.1 detik.



Terlihat cukup mudah. Kamu akan memulai sebuah timer saat spell mulai melakukan loop/putaran setiap 0.1 detik.
Dalam putaran tersebut, kamu akan melakukan damage pada target untuk 2 hit points, dan memberikan 2 hit points kepada Caster:

Code
Siphon Life Cast
         Events
         Unit - A unit Starts the effect of an ability
         Conditions
         (Ability being cast) Equal to Siphon Life
         Actions
         Set SL_Caster = (Triggering unit)
         Set SL_Target = (Target unit of ability being cast)
         Set SL_Counter = 0
         Trigger - Turn on Siphon Life Loop <gen>


Code
Siphon Life Loop
         Events
         Time - Every 0.10 seconds of game time
         Conditions
         Actions
         Unit - Cause SL_Caster to damage SL_Target, dealing 2 damage of attack type Spells and damage type Normal
         Unit - Set life of SL_Caster to ((Life of SL_Caster) + 2.00)
         Set SL_Counter = (SL_Counter + 0.10)
         If (All Conditions are True) then do (Then Actions) else do (Else actions)
         If - Conditions
         SL_Counter Greater than or equal to 3.00
         Then - Actions
         Trigger - Turn off (This trigger)
         Else - Actions


Ini akan bekerja (abaikan fakta bahwa ini tidak mengecek jika unit telah mati).


(Lingkaran disebelah kanan bawah menunjukkan berapa lama waktu telah berlalu)

Tapi apa yang kamu pikirkan jika ada caster lain datang?



Sekarang caster pertama tidak akan mendapat HP lagi, dan monster hanya menerima 2 damage per detik daripada 4
(2 + 2). Kenapa? Lihat pada trigger diatas. Saat spell digunakan, SL_Caster diatur menggunakan casting
unit. Karena variable hanya bisa menunjukkan satu hal setiap kali, caster asli (hijau) tertimpa.
tidak hanya itu, tapi targetnya juga tertimpa, dan SL_Counter direset ke 0.

Ini menunjukkan kenapa kita perlu MUI. Tanpa itu, monster tidak mengalami rasa sakit sebanyak yang seharusnya.

Dynamic Indexing
Ada banyak cara untuk mencapai MUI. Dynamic indexing adalah salah satunya. Itu melibatkan array dan satu index setiap spell cast.

Hal pertama yang harus dilakukan adalah mengetahui variable apa yang kamu perlukan untuk disimpan. Pada kali ini, kita perlu menyimpan:
Caster: unit
Target: unit
Counter: real
Kenapa? Karena variable-variable tersebut kita gunakan di periodic loop. Simpan variable yang hanya kamu perlukan untuk diakses
selama periodic. Jika kamu hanya butuh data saat spell digunakan pada pertama kali, kamu tidak perlu menyimpannya.

Daripada membuat variable tunggal, kita akan mengubahnya menjadi array:


Sekarang, tujuan dari dynamic indexing adalah untuk memiliki satu index untuk setiap spell cast. Di periodic trigger,
kamu akan memutar melewati setiap spell cast yang aktif (diketahui sebagai instansi dari spell). Instansi biasanya menunjukkan pada satu spell cast, dan itu akan diasosiasikan dengan index yang digunakan. Instansi pertama dari sebuah spell akan memiliki index yaitu 1, yang kedua akan memiliki index yaitu 2. Saat kita bicara tentang multi-instanceability, kita sebenarnya mengatakan bahwa spell harus bekerja dengan penggunaan spell lebih dari satu kali pada saat bersamaan.

Sebagai contoh, jika kamu memiliki 3 instansi spell, itu akan terlihat seperti ini:



Saat kamu memutar melewati setiap instansi, kamu akan memiliki caster dan target yang berbeda untuk dihadapi. inilah beberapa kode semu:

Code
For each (SL_Loop_Integer) from 1 to 3, do (Actions)
       Loop - Actions
       Unit - Cause SL_Caster[SL_Loop_Integer] to damage SL_Target[SL_Loop_Integer], dealing 2 damage of attack type Spells and damage type Normal
       Unit - Set life of SL_Caster[SL_Loop_Integer] to ((Life of SL_Caster[SL_Loop_Integer]) + 2.00)
       Set SL_Counter[SL_Loop_Integer] = (SL_Counter[SL_Loop_Integer] + 0.10)


Perhatikan bahwa setiap kali putaran mengulang, itu menunjukkan pada instansi baru. Saat SL_Loop_Integer adalah 1,
itu akan menunjukkan pada instansi pertama (lihat gambaar diatas). Saat SL_Loop_Integer adalah 2, itu akan menunjukkan pada instansi kedua. Sama untuk yang ketiga.

Sekarang, kode tersebut adalah spesifik. Itu berputar melewati 3 instansi saja. Tapi bagaimana jika kita mau 5? atau 10? atau hanya 1?
Tujuan utama dari dynamic indexing adalah untuk membuat bentuk umum yang dapat bekerja dalam situasi apapun. Bagaimana kita melakukannya?
Mudah, kita hanya akan membuat variable dengan tipe integer untuk melacak setiap instansi:

SL_Index (Name) - Integer (Type) - 0 (Initial Value)

Jadi bagaimana kita melakukannya? Ya, pertama kita harus khawatir tentang alokasi. Alokasi adalah sebuah proses untuk mendapatkan index baru dan mendaftarkan variable yang kita butuhkan. Karena kita punya urutan dari 1, 2, 3, dll.. kita hanya perlu untuk menambah index setiap kali sebuah spell digunakan.

Anggap saja kita mengikuti skenario. Spell tersebut digunakan oleh dark ranger kepada hawk, blood mage kepada pit lord,
firelord kepada skeleton, dan sea witch kepada clockwerk goblin:



Gambar diatas akan menunjukkan bagaimana itu seharusnya terlihat pada alokasi. Saat spell digunakan oleh dark ranger, index seharusnya menjadi 1. SL_Caster[1] seharusnya adalah dark ranger. SL_Target[1] seharusnya adalah hawk. SL_Counter[1] seharusnya adalah 0.0. Dan seterusnya dengan index yang lain. Ini triggernya:

Code
Siphon Life Cast
      Events
      Unit - A unit Starts the effect of an ability
      Conditions
      (Ability being cast) Equal to Siphon Life
      Actions
      Set SL_Index = SL_Index + 1
      Set SL_Caster[SL_Index] = (Triggering unit)
      Set SL_Target[SL_Index] = (Target unit of ability being cast)
      Set SL_Counter[SL_Index] = 0
      If (All Conditions are True) then do (Then Actions) else do (Else actions)
      If - Conditions
      SL_Index Equal to 1
      Then - Actions
      Trigger - Turn on Siphon Life Loop <gen>
      Else - Actions


Ini akan bekerja. SL_Index akan bertambah 1 dari setiap instansi, dan array akan diatur untuk instansi tertentu. Untuk Index 1, caster akan menjadi dark ranger, target akan menjadi hawk, dan counter akan menjadi 0. Sama untuk setiap instansi, seperti yang ditunjukkan oleh gambar diatas.

Bagaimana dengan loop/putaran yang sebenarnya? Sama saja seperti yang kita lakukan di atas, tetapi daripada memutar ke 3,
kita hanya akan memutar pada SL_Index. Kenapa? Kalu kamu pikir-pikir, SL_Index sebenarnya terus melacak jumlah dari instansi setiap spell. Saat spell pertama digunakan, index diatur ke 1. Saat yang kedua digunakan, index adalah 2. Saat yang keempat digunakan, index adalah 4. dll.

Untuk garis terakhir, itu akan menghidupkan putaran periodic/periodic loop saat instansi pertama dibuat. Kamu mungkin bertanya-tanya kenapa?
Saya tidak menghidupkannya dari pertama–jangan khawatir tentang itu. Itu akan menjadi penting nanti. Sekarang kita akan melanjutkan pada looping/putaran.

(Trigger ini harus dalam keadaan off dari pertama)

Code
Siphon Life Loop
      Events
      Time - Every 0.10 seconds of game time
      Conditions
      Actions
      For each (SL_Loop_Integer) from 1 to SL_Index, do (Actions)
      Loop - Actions
      Unit - Cause SL_Caster[SL_Loop_Integer] to damage SL_Target[SL_Loop_Integer], dealing 2 damage of attack type Spells and damage type Normal
      Unit - Set life of SL_Caster[SL_Loop_Integer] to ((Life of SL_Caster[SL_Loop_Integer]) + 2.00)
      Set SL_Counter[SL_Loop_Integer] = (SL_Counter[SL_Loop_Integer] + 0.10)
      If (All Conditions are True) then do (Then Actions) else do (Else actions)
      If - Conditions
      SL_Counter[SL_Loop_Integer] Greater than or equal to 3.00
      Then - Actions
      Else - Actions


Ayo analisis trigger tadi. SL_Loop_Integer hanya variable integer yang digunakan untuk looping/putaran, daripada (Integer A). Itu berputar sampai SL_Index, sebenarnya melewati setiap instansi sampai yang terakhir.
SL_Caster[SL_Loop_Integer] akan menjadi caster untuk instansi tersebut. Sama untuk variable yang lain.
Trigger itu akan berputar melewati instansi dan melakukan action untuk setiap instansi spell.

Kamu mungkin bertanya-tanya kenapa aku membiarkan "Then" action kosong. Apa yang kita lakukan saat spell telah selesai?
Kita harus deallocate instansinya. Sebaliknya, spell akan terus berjalan pada instansi yang selesai tanpa gunanya. Itu juga akan memastikan bahwa SL_Index tidak akan bertambah terus dan terus (max array index adalah 8191).
Jadi bagaimana kita melakukannya? Kita akan menimpa instansi-untuk-dihapus dengan instansi terakhir, dan kemudian kita atur loop/putarannya dan SL_Index kembali ke-1 (jadi itu akan menjalankan instansi tersebut). Inilah bagaimana akan terlihat:



Seperti yang kamu lihat, blood mage menyelesaikan spellnya (untuk sekarang). Jadi sekarang sea witch harus menggantikan tempatnya. Tujuan kita: buat sea witch memiliki index 2 (menimpa blood mage). kemudian mengurangi index
dan mengulanginya (SL_Loop_Index) dengan 1. Seperti inilah bagaimana itu akan terlihat:

Code
Siphon Life Loop
     Events
     Time - Every 0.10 seconds of game time
     Conditions
     Actions
     For each (SL_Loop_Integer) from 1 to SL_Index, do (Actions)
     Loop - Actions
     Unit - Cause SL_Caster[SL_Loop_Integer] to damage SL_Target[SL_Loop_Integer], dealing 2 damage of attack type Spells and damage type Normal
     Unit - Set life of SL_Caster[SL_Loop_Integer] to ((Life of SL_Caster[SL_Loop_Integer]) + 2.00)
     Set SL_Counter[SL_Loop_Integer] = (SL_Counter[SL_Loop_Integer] + 0.10)
     If (All Conditions are True) then do (Then Actions) else do (Else actions)
     If - Conditions
     SL_Counter[SL_Loop_Integer] Greater than or equal to 3.00
     Then - Actions
     Set SL_Caster[SL_Loop_Integer] = SL_Caster[SL_Index]
     Set SL_Target[SL_Loop_Integer] = SL_Target[SL_Index]
     Set SL_Counter[SL_Loop_Integer] = SL_Counter[SL_Index]
     Set SL_Index = (SL_Index - 1)
     Set SL_Loop_Integer = (SL_Loop_Integer - 1)
     Else - Actions


Secara visual, inilah bagaimana itu akan terlihat saat menimpa instansi milik blood mage:



Begitulah. Tapi bagaimana tentang mengurangi index dan loop integer? Kenapa kita melakukannya?
Baiklah, ini bagaimana itu seharusnya terlihat setelah kita menimpa instansi kedua:



Sekarang kita sudah menimpa slot kedua, kita harus mengurangi SL_Index karena kita tidak membutuhkan instansi ke-4.
SL_Index = SL_Index - 1, Yang berarti: 4 - 1 = 3. Ini bagaimana itu akan terlihat:



Sekarang masalah instansi ke-2 telah selesai! Sea witch tidak akan pernah mendapat giliran! Berarti, kita harus mengatur
SL_Loop_Integer kembali agar instansi Sea witch dapat berjalan:



Akhirnya, Kita selesai! Spell akan bekerja dengan benar. Jika kamu menggunakan spell lain, Index akan mengambil
slot ke-4, yang tidak memiliki masalah. Sekarang spell bekerja, tapi adalah satu hal lagi yang dapat kita lakukan untuk efisiensi.
Jika tidak ada instansi aktif, kita harus mematikan trigger. Sebaliknya itu akan berputar tanpa habis. Inilah trigger terakhir:



Selesai!

Perbandingan
Banyak orang bertanya bagaimana dynamic indexing dibandingkan dengan metode lainnya. Hal yang terpenting untuk
diingat bahwa ini hanya berbeda nanodetik dan dapat bervariasi dari situasi ke situasi, tapi secara umum:
    Alokasi sering lebih cepat daripada menyimpan semua item di hashtable. (array set vs. hash set)Pengulangan lebih cepat daripada hashtable/putaran unit-group (array load vs. hash load)Dealokasi bervariasi. Hashtables bisa kadang-kadang lebih cepat saat dealokasi karena dealokasi dynamic indexing sedang OnVersus struct linked list, alokasi lebih cepat. Pengulangan secara relatif sama.Dealokasi hampir selalu lebih lamban.

Ingat bahwa ini hanya perbandingan dari metode-metode, masih banyak faktor lain yang dapat mengubah kecepatan.

Credits

    Hanky - memopulerkan metode ini dengan ini.Sellenisko - Banshee Queen model. :DGhostwolf - Model viewer.Classic BattleNet - Beberapa Gambar.WoW - Model Babi.


SPECIAL THANKS
TO
PurgeandFire


Bukti


Message edited by Rheiko - Wednesday, 2014-01-08, 5:26 PM
 
ILHDate: Friday, 2014-01-10, 4:40 PM | Message # 2
Indomodder Super Legendaris
Group: Moderator Resources
Messages: 8
Awards: 0
Reputation: 4
Status: Offline
Ah, tutorial yang bagus biggrin +rep

EDIT: OT: MUI=Melon United International xD


Message edited by ILH - Friday, 2014-01-10, 4:54 PM
 
RheikoDate: Friday, 2014-01-10, 6:11 PM | Message # 3
Co-Admin
Group: Administrators
Messages: 42
Awards: 2
Reputation: 12
Status: Offline
Terima kasih smile

lol, bagus sebagai lelucon :v
 
Daffa_MageDate: Wednesday, 2014-02-19, 2:25 PM | Message # 4
Grand Leader
Group: Administrators
Messages: 76
Awards: 1
Reputation: 6
Status: Offline
Tutorial yang bagus, kalau boleh jujur, ane tidak pake ini dari dulu sampel sekarang, ane pake UI milik Bribe (Unit Indexer).
 
Forum » Dunia Modding Warcraft III » Warcraft III Tutorial » Indeks Dinamik [Dynamic Indexing] (Metode Indeks Dinamik untuk Spell dan Sistem)
  • Page 1 of 1
  • 1
Search: