• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Solved] MUI Array set-up?

Status
Not open for further replies.
Level 7
Joined
May 11, 2010
Messages
278
I know how to do MUI hashtable set-ups with data relating to a specific unit. How can i do something similar with arrays?

Basically, I'm planning to create a spell system that reads a number of data entries (like damage, range, impact delay etc.) specified in a trigger. It then takes this data and checks if the target is in range, applies damage etc.

As I said, i know how to link this data to a unit and create a system using hashtables, but I'd like to use arrays instead (for faster execution, and learning purposes). And it needs to be MUI. It also needs to be able to handle multiple spell casts started before the end of the previous spell.

If it's really stupid to do this using arrays, I'll use hashtables instead. Any constructive criticism of what i'm planning is welcome.

  • Actions
    • Events
    • Conditions
    • Actions
      • Set Damage = 0.00
      • -------- The damage the attack will deal. --------
      • Set Range = MeleeRange
      • -------- How far away the target can be and still be hit. --------
      • Set ProjectileAbility = False
      • -------- Set to true if the ability fires a projectile. --------
      • Set PoiseDamage = 0
      • -------- How much the enemy's poise will be reduced. When enemy poise reaches 0, the enemy will be stunned. --------
      • Set Animation = attack
      • -------- The animation the caster will play. --------
      • Set DamageDelay = 0.50
      • -------- The delay before damage is applied. --------
      • -------- If this is set to 0, it will deal damage the instant the ability is activated. --------
      • -------- Try to match this with the impact of the animation. --------
      • Set Target = TargetofPlayer[(Player number of (Owner of (Triggering unit)))]
      • -------- The target the attack will be aimed at. --------
      • Set Caster = (Triggering unit)
      • -------- The unit that casts the ability. --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ProjectileAbility Equal to False
        • Then - Actions
          • Trigger - Run MeleeAbility <gen> (ignoring conditions)
        • Else - Actions
          • Trigger - Run ProjectileAbility <gen> (ignoring conditions)
      • -------- Runs the triggers. Don't touch this. --------
      • -------- Does the ability have any extra effects? --------
      • -------- Add a "Run trigger" for a trigger with those effects here. --------
 
Level 28
Joined
Sep 26, 2009
Messages
2,520
I'm not sure what you intend to do with your trigger, but using arrays basically means that you save the caster or target (depends on your type of spell) into array with index "n + 1" where "n" is the current index.
You keep track of "n" for each spell separately; also, every time you save new unit into array, you also save "n" as "n+1" to keep "n" updated.
This "n" integer basically keeps track of how many units you have saved in your variable (it's just integer number).

You will also need another variables - like real for damage, integer for instance count of the spell, etc. - all arrays.

Finally, all arrays related to that caster will be saved under same index number - "n"

You also need to remove casters who finished that spell and recycle all casters, so you won't hit limit and increase efficiency
 
Level 7
Joined
May 11, 2010
Messages
278
After taking a quick look at all the links, i decided to take a closer look at "Dynamic Indexing Template" that Maker linked. I don't really understand everything.
The following is from the "Dynamic Loops" folder of the map.

  • Actions
    • -------- Increase the index size --------
    • Set EXAMPLE_Index_Size = (EXAMPLE_Index_Size + 1)
    • -------- Dynamic Index --------
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • EXAMPLE_Index_Size Greater than EXAMPLE_Index_maxSize
      • Then - Actions
        • Set EXAMPLE_Index[EXAMPLE_Index_Size] = EXAMPLE_Index_Size
        • Set EXAMPLE_Index_maxSize = EXAMPLE_Index_Size
      • Else - Actions
    • -------- Dynamic Index End --------
    • -------- IMPORTANT SYSTEM PART END --------
If i've understood this correctly, each time this trigger fires, Index_Size is increased by 1. Then, Index[Index_Size] is set to Index_Size. Lastly, Index_maxSize is set to Index_Size.
In short, each time this trigger fires, Index_Size and Index_maxSize is increased by one, and "Index[y] = Index_Size" has "y" increased by one, and set to the new size of Index_Size.

So far so good?
I understood as much as this will cause the index to constantly grow, and therefore the recycling part is very important.

The next trigger is a looping trigger.
  • Actions
    • For each (Integer EXAMPLE_LOOP) from 1 to EXAMPLE_Index_Size, do (Actions)
      • Loop - Actions
        • Set TempInt = EXAMPLE_Index[EXAMPLE_LOOP]
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • EXAMPLE_DUR[TempInt] Greater than 0.00
            • Then - Actions
              • Set EXAMPLE_DUR[TempInt] = (EXAMPLE_DUR[TempInt] - 0.03)
            • Else - Actions
              • -------- IMPORTANT SYSTEM PART START --------
              • -------- RecycleIndex --------
              • Set EXAMPLE_Index[EXAMPLE_LOOP] = EXAMPLE_Index[EXAMPLE_Index_Size]
              • Set EXAMPLE_Index[EXAMPLE_Index_Size] = TempInt
              • Set EXAMPLE_Index_Size = (EXAMPLE_Index_Size - 1)
              • Set EXAMPLE_LOOP = (EXAMPLE_LOOP - 1)
              • -------- Turn the trigger again off if the index_size is below 0... --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • EXAMPLE_Index_Size Equal to 0
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                  • Skip remaining actions
                • Else - Actions
              • -------- IMPORTANT SYSTEM PART END --------
This is where things get messy. Let's say that Index_Size is 10 due to multiple executions of the trigger (sounds plausible to me).

During the first loop, TempInt is set to Index[LOOP] (Index[1]). In the first trigger, Index[1] was set to 1. (Before recycling begins, Index[x] will always be = x, will it not?)
So TempInt is 1 for the first loop. Let's say that DUR[1] is 0, as such the "Else" part triggers.
This is what confuses me:
Index[LOOP] (Index[1] in this case) is set to Index[Index_Size] (Index[10] in this case). This causes Index[1] to get the value 10. (So is Index[10] supposed to use Index[1] instead, because it's value is now stored in Index[1]?)
Then, Index[Index_Size] (in this case Index[10]) is set to TempInt (in this case, 1) (this is needed because...? I mean, if Index[10] will be unused until redefined, why set its value to 1?)
Index_Size is set to Index_Size-1, causing Index_Size's value to become 9. (But then, what happens to Index[10]? Will it be left out of the loop?)
LOOP is set to LOOP-1, causing LOOP's value to become... 0? Wait, what the actual is happening here?

If any of you can help me figure this out, I'd appreciate it greatly.
 
im not sure y the indexing is done that way.
here is how it should be done.

u use a maxIndex which is an integer.
in the cast trigger u set maxIndex = maxIndex + 1
then store whatever u need in arrays with the maxIndex integer as the index.
for example:
  • Set unitTarget[maxIndex] = target unit of ability being cast
  • Set unitCaster[maxIndex] = triggering unit
i set the unit to the target and the caster to triggering unit.
then in the looping trigger u do
  • For each integer tempInt from 1 to maxIndex
to deindex you do this
  • Set unitCaster[tempInt] = unitCaster[maxIndex]
  • Set unitCaster[maxIndex] = no unit
  • Set unitTarget[tempInt] = unitTarget[maxIndex]
  • Set unitTarget[maxIndex] = no unit
  • Set maxIndex = maxIndex - 1
  • Set tempInt = tempInt - 1
in the cast trigger u have to do a check against the maxIndex to see if it is equal to 1 or 0 depending on were u place it in ur trigger. This is used to start the loop trigger.
u also need one in the loop trigger to turn it off when all of the instances of the spell are done. This is done so u stop the trigger from running when it isnt necessary.
 
Level 7
Joined
May 11, 2010
Messages
278
@deathismyfriend: that does not look MUI to me. what happens when two or three instances of the trigger runs at the same time? won't that way of deindexing cause the third instance to be terminated when the first expires?

@Maker: Thanks! I understand a lot better now. As usual, Maker is invaluable ^^
 
it is fully MUI.

the way it works is it moves the last index to the index that was just removed. then it reduces the maxIndex.

basically lets have 5 instances of the spell running.

1 / 2 / 3 / 4 / 5

lets remove number 2

1 / x / 3 / 4 / 5

now we have a gap.
we then move index 5 to 2

1 / 5 / 3 / 4 / x

now we reduce so our max index is now 4

i explain exactly what happens step by step in my tutorial it should be able to help u a lot.
 
Status
Not open for further replies.
Top