[Spell] Integer array not recognized - solution without hashtable?

Level 11
Joined
May 16, 2020
Messages
655
Hi guys,

I want to recreate DotA's Meat Hook ability in MUI, and if possible NOT using a hashtable for it.

Ideally the spell should be build along this structure:
Visualize: Dynamic Indexing

However, this part of the code causes problems, as the game doesn't recognize "arrays pof the array" (when two abilities are cast, the chains of the first spell are not destroyed):
  • Set VariableSet MH_Chain[MH_Counter[MH_Integer]] = (Last created special effect)
Is it possible to fix this without hashtables?

***

  • Meat Hook
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Meat Hook
    • Actions
      • Set VariableSet MH_Index = (MH_Index + 1)
      • Set VariableSet MH_Caster[MH_Index] = (Triggering unit)
      • Set VariableSet MH_Damage[MH_Index] = (80.00 + (70.00 x (Real((Level of Meat Hook for MH_Caster[MH_Index])))))
      • Set VariableSet MH_Counter[MH_Index] = 0
      • Set VariableSet MH_Distance[MH_Index] = 0.00
      • Set VariableSet MH_Boolean[MH_Index] = False
      • Set VariableSet MH_UnitHooked[MH_Index] = No unit
      • -------- --------
      • Set VariableSet MH_PointTemp[1] = (Position of MH_Caster[MH_Index])
      • Set VariableSet MH_PointTemp[2] = (Target point of ability being cast)
      • Set VariableSet MH_Angle[MH_Index] = (Angle from MH_PointTemp[1] to MH_PointTemp[2])
      • Set VariableSet MH_Point[MH_Index] = (MH_PointTemp[1] offset by 50.00 towards MH_Angle[MH_Index] degrees.)
      • -------- --------
      • Special Effect - Create a special effect at MH_Point[MH_Index] using war3mapImported\HookHead.mdl
      • Set VariableSet MH_Missile[MH_Index] = (Last created special effect)
      • Special Effect - Set Scale of MH_Missile[MH_Index] to 1.10
      • Special Effect - Set Yaw of MH_Missile[MH_Index] to: (Radians(MH_Angle[MH_Index]))
      • Special Effect - Set Height of MH_Missile[MH_Index] to: 30.00
      • -------- --------
      • Custom script: call RemoveLocation(udg_MH_PointTemp[1])
      • Custom script: call RemoveLocation(udg_MH_PointTemp[2])
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • MH_Index Equal to 1
        • Then - Actions
          • Countdown Timer - Start MH_Timer as a Repeating timer that will expire in 0.03 seconds
          • Trigger - Turn on Meat Hook Loop <gen>
        • Else - Actions
  • Meat Hook Loop
    • Events
      • Time - MH_Timer expires
    • Conditions
    • Actions
      • For each (Integer MH_Integer) from 1 to MH_Index, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • MH_Boolean[MH_Integer] Equal to False
            • Then - Actions
              • Set VariableSet MH_Counter[MH_Integer] = (MH_Counter[MH_Integer] + 1)
              • -------- --------
              • Set VariableSet MH_PointTemp[1] = (MH_Point[MH_Integer] offset by MH_Distance[MH_Integer] towards MH_Angle[MH_Integer] degrees.)
              • Special Effect - Create a special effect at MH_PointTemp[1] using war3mapImported\HookChain.mdl
              • Set VariableSet MH_Chain[MH_Counter[MH_Integer]] = (Last created special effect)
              • Special Effect - Set Scale of MH_Chain[MH_Counter[MH_Integer]] to 1.30
              • Special Effect - Set Yaw of MH_Chain[MH_Counter[MH_Integer]] to: (Radians(MH_Angle[MH_Integer]))
              • Special Effect - Set Height of MH_Chain[MH_Counter[MH_Integer]] to: 35.00
              • -------- --------
              • Set VariableSet MH_Distance[MH_Integer] = (MH_Distance[MH_Integer] + 43.50)
              • Set VariableSet MH_PointTemp[2] = (MH_Point[MH_Integer] offset by MH_Distance[MH_Integer] towards MH_Angle[MH_Integer] degrees.)
              • Special Effect - Set Position of MH_Missile[MH_Integer] to x: (X of MH_PointTemp[2]), y: (Y of MH_PointTemp[2]), z: 15.00
              • -------- --------
              • Custom script: set bj_wantDestroyGroup = true
              • Unit Group - Pick every unit in (Units within 100.00 of MH_PointTemp[2].) and do (Actions)
                • Loop - Actions
                  • Set VariableSet MH_UnitTemp = (Picked unit)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (MH_UnitTemp is alive) Equal to True
                      • (MH_UnitTemp is A structure) Equal to False
                      • (MH_UnitTemp is An Ancient) Equal to False
                      • MH_UnitTemp Not equal to MH_Caster[MH_Integer]
                      • MH_Boolean[MH_Integer] Equal to False
                    • Then - Actions
                      • Set VariableSet MH_Boolean[MH_Integer] = True
                      • Set VariableSet MH_UnitHooked[MH_Integer] = MH_UnitTemp
                      • Unit - Turn collision for MH_UnitTemp Off.
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (MH_UnitTemp belongs to an enemy of (Owner of MH_Caster[MH_Integer]).) Equal to True
                        • Then - Actions
                          • Special Effect - Create a special effect attached to the origin of MH_UnitTemp using Objects\Spawnmodels\Human\HumanBlood\BloodElfSpellThiefBlood.mdl
                          • Special Effect - Destroy (Last created special effect)
                          • Unit - Cause MH_Caster[MH_Integer] to damage MH_UnitTemp, dealing MH_Damage[MH_Integer] damage of attack type Chaos and damage type Universal
                          • Unit - Pause MH_UnitTemp
                          • Unit - Create 1 Vision Dummy (500/500 Flying Vision) for (Owner of MH_Caster[MH_Integer]) at MH_PointTemp[2] facing Default building facing degrees
                          • Unit - Add a 4.00 second Generic expiration timer to (Last created unit)
                        • Else - Actions
                    • Else - Actions
              • Custom script: call RemoveLocation (udg_MH_PointTemp[1])
              • Custom script: call RemoveLocation (udg_MH_PointTemp[2])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • MH_Counter[MH_Integer] Greater than or equal to 29
                • Then - Actions
                  • Set VariableSet MH_Boolean[MH_Integer] = True
                • Else - Actions
            • Else - Actions
              • -------- --------
              • -------- PULL BACK CHAIN --------
              • -------- --------
              • Special Effect - Destroy MH_Chain[MH_Counter[MH_Integer]]
              • Set VariableSet MH_Distance[MH_Integer] = (MH_Distance[MH_Integer] - 43.50)
              • Set VariableSet MH_PointTemp[1] = (MH_Point[MH_Integer] offset by MH_Distance[MH_Integer] towards MH_Angle[MH_Integer] degrees.)
              • Special Effect - Set Position of MH_Missile[MH_Integer] to x: (X of MH_PointTemp[1]), y: (Y of MH_PointTemp[1]), z: 15.00
              • Unit - Move MH_UnitHooked[MH_Integer] instantly to MH_PointTemp[1]
              • -------- --------
              • Set VariableSet MH_Counter[MH_Integer] = (MH_Counter[MH_Integer] - 1)
              • -------- --------
              • Custom script: call RemoveLocation (udg_MH_PointTemp[1])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • MH_Counter[MH_Integer] Equal to 0
                • Then - Actions
                  • Unit - Turn collision for MH_UnitHooked[MH_Integer] On.
                  • Unit - Unpause MH_UnitHooked[MH_Integer]
                  • Special Effect - Destroy MH_Missile[MH_Integer]
                  • -------- --------
                  • Set VariableSet MH_Caster[MH_Integer] = MH_Caster[MH_Index]
                  • Set VariableSet MH_Damage[MH_Integer] = MH_Damage[MH_Index]
                  • Set VariableSet MH_Counter[MH_Integer] = MH_Counter[MH_Index]
                  • Set VariableSet MH_Distance[MH_Integer] = MH_Distance[MH_Index]
                  • Set VariableSet MH_Boolean[MH_Integer] = MH_Boolean[MH_Index]
                  • Set VariableSet MH_UnitHooked[MH_Integer] = MH_UnitHooked[MH_Index]
                  • Set VariableSet MH_Point[MH_Integer] = MH_Point[MH_Index]
                  • Set VariableSet MH_Angle[MH_Integer] = MH_Angle[MH_Index]
                  • Set VariableSet MH_Missile[MH_Integer] = MH_Missile[MH_Index]
                  • -------- --------
                  • Set VariableSet MH_Index = (MH_Index - 1)
                  • Set VariableSet MH_Integer = (MH_Integer - 1)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • MH_Index Equal to 0
                    • Then - Actions
                      • Countdown Timer - Pause MH_Timer
                      • Trigger - Turn off (This trigger)
                    • Else - Actions
                • Else - Actions
 
Level 18
Joined
Jun 26, 2020
Messages
1,454
That is because in the variable MH_Chain[MH_Counter[MH_Integer]] can be overwriten because if you have 2 casters you can have
MH_Counter[1]="some integer"
MH_Counter[2]="the same integer"
In that moment MH_Chain will be overwriten, so in this case you need 2 indexes like "MH_Chain[m][n]", but that is no possible in world editor, so yes or yes you need hashtables, because is the only way to have 2 indexes. just doing "Save Handle of (Last created special effect) as MH_Counter[MH_Integer] of MH_Integer in <Your hashtable>".

Edit: Thinking well, there is a way to do this without using hashtables, but is a little tricky, I will tell you when I have time.
 
Last edited:
Level 18
Joined
Jun 26, 2020
Messages
1,454
Ok, to do this you have to store the effect in a variable you know it won't be overwriten, like trying to emulate using 2 indexes, what I say is using a index with 3 digits (or more, depending the number of casters) like "abc" where a=MH_Integer and bc=MH_Counter[MH_Integer] so you have to do:
  • Special Effect - Create a special effect at MH_PointTemp[1] using war3mapImported\HookChain.mdl
  • Set VariableSet MH_Chain[100*MH_Integer+MH_Counter[MH_Integer]] = (Last created special effect)
  • -------- Then --------
  • Special Effect - Destroy MH_Chain[100*MH_Integer+MH_Counter[MH_Integer]]
You don't have to worry if you don't exceed the max number of an array that is 8191.
 

Uncle

Warcraft Moderator
Level 42
Joined
Aug 10, 2018
Messages
4,191
Array size limit is 32764 in later versions.

Why no Hashtables?
 
What you want is creating a list-like data structure for each instance. Something like explained here: [Trigger] - Why dynamic indexing is flawed and people should use linked list instead

It would be less efficient, but you also can just create a second dynamic indexing structure, only for the effects. What will be indexed is the effect itself of course, but also the reference to the Caster Index. And like you index in the cast trigger, you would index the effects inside the loop, just there, where you create the effects. It would look like:

  • Special Effect - Create a special effect ...
  • Set MH_Effect_MaxIndex = Set MH_Effect_MaxIndex + 1
  • Set MH_Effect_CasterIndex[MH_Effect_MaxIndex] = MH_Integer
  • Set MH_Effect_SpecialEffect[MH_Effect_MaxIndex] = (Last created special effect)
So all effect instances for one specifc cast instance share the same CasterIndex value.
When destroying your chain spell, you have to loop through all effect instances and destroy/deindex all instances with that have:
  • MH_Effect_CasterIndex[MH_Effect_MaxIndex] Equals MH_Integer
 
Level 18
Joined
Jun 26, 2020
Messages
1,454
Maker explains that order of instanciation matters. In a linked list the order is fixed, but in dynamic indexing the order gets mixed up when it's up to deindexing. So deindexing leads to wrong/different order of instances, and later instanciated instance might get higher priority in processing, as they run before others and have chance to kill units etc more early than others.
 
Level 18
Joined
Jun 26, 2020
Messages
1,454
@IcemanBo the order in every instance doesn't matter (only if the indexed datas have correlation with other indexed datas or you add an index in middle of the distance, but why somebody will do the first? an teh second is impossible with dynamic indexing at least the actions include add an index, but again, why somebody will do that?) because it supouse in every instant the actions happens "at the same time".
In his example of the missiles "Imagine if projectile A and B are launched. Projectile C is launched 0.01 seconds after projectile A and B. They all have the same speed and trajectory. They are all flying and then projectile A hits a barrel and is destroyed, so is the barrel. Now projectile C is moved by the indexing to take the index of projectile A and is the next projectile to be moved. What happens is projectile C can now hit targets before projectile B, even though projectile C was created and lauched after projectile B." there is no way the rocket C will hit a target before the projectile B even if C is moved before than B, because:
  • if C is launched 0.01 after A and B then if C now is moved before B so if every run of the trigger is 0.01 C at most will be at the same distance of the target as B when is C is moved, then B is moved and B is now again closer to the target than C again and will pass to the next distance.
  • If C hits the target in the next move so the projectile B was already hit the target in the previous instance is impossible that it is not so.
If you don't believe me just imagine a chess table, you have 3 peons (A,B,C) and C is a block before A and B, so in every instance you move them 1 block ahead in order (you know, first A, then B, then C), so the peon A get eliminated and now the peon C takes A's turn and lost its original turn, do you believe C will reach the last block before B?
 
Last edited:
Yo're make assumptions of position and time frame in both of your points. Timeout, for example can also be 0.03, or something else, and C might appear after B, but still under difference of 0.03, and then would be falsely processed before B. Also starting positions might be not same, and missiles might hit target differently. It's not a major problem, but the discrepancy is there.
 
Level 18
Joined
Jun 26, 2020
Messages
1,454
@IcemanBo In reality I shouldn't say an specific time of the instances because in reality doesn't matter the time of the instances, because no matter how many time pass when C was added, it won't be considered until the next instance, and
Also starting positions might be very different, and missiles might hit target differently.
If there can be another starting conditions so what is the problem with the order of the actions? why matter if C ends before B if it understandably can happen?, the claim of Maker will have sense only if C hits the target before B only if the unique difference of the starting conditions of B and C was C launches 0.01 after B.
 
Level 18
Joined
Jun 26, 2020
Messages
1,454
It is a problem, because C can be added later by time, comes chronologically after B, but still might get priorization in processing over B. :eek:
Explain.
Edit: Ok, I got it, if the process already start if the instant don't end, C will have to wait it to start acting, is that? If the answer is yes so I don't get why the problem is the order of the actions and not what I just said.

Edit2: Ok, Now I really got it, I didn't understand because Maker didn't explain well, an example, if the time of the instance was 1.00 second the A starts so the trigger runs, then after 0.1 second B start but it have to wait the instance end to will be recognized and then 0.2 second later start C so B is before C but them will have to wait the next instance to get recognized but B will act before C.
So then A got eliminated and now C for being the last takes A's place so now C is before B, so if B and C have the same target or the same goal and do the same actions, even if B start before C, now C is who will do things before B.

But well at the end this only matter if the time of the instance is not too small or we are very exquisite with the difference of times and B and C start before the instance end and have the same initial conditions (and that is virtually imposible, much if the time of the instance is too small), but if you wanna take this in consideration so don't use GUI and use hashtables and Jass Timers because the Maker's solution is not efficient because we have to re-index every data after the eliminated.

Maker said it:"Yeah, imagine if there were 1000 instances and the first one expires. You would reindex 999 instances with your method, where as with a linked list for example you would only relink 1 instance with another. If you were working as a programmer an suggested such a solution, you would find yourself unemployed in no time".
 
Last edited:
Level 11
Joined
May 16, 2020
Messages
655
Thanks for the answers all!

From the conversation I gather that using a hashtable would be the most efficient solution... I just don't like hashtables because I don't really understand how to use them (and generally don't understand their pros- and cons). But If that is the best solution I will use it.

The following still has an error though:

  • Meat Hook Loop
    • Events
      • Time - MH_Timer expires
    • Conditions
    • Actions
      • For each (Integer MH_Integer) from 1 to MH_Index, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • MH_Boolean[MH_Integer] Equal to False
            • Then - Actions
              • Set VariableSet MH_Counter[MH_Integer] = (MH_Counter[MH_Integer] + 1)
              • -------- --------
              • Set VariableSet MH_PointTemp[1] = (MH_Point[MH_Integer] offset by MH_Distance[MH_Integer] towards MH_Angle[MH_Integer] degrees.)
              • Special Effect - Create a special effect at MH_PointTemp[1] using war3mapImported\HookChain.mdl
              • Set VariableSet MH_Chain[MH_Integer] = (Last created special effect)
              • Special Effect - Set Scale of MH_Chain[MH_Integer] to 1.30
              • Special Effect - Set Yaw of MH_Chain[MH_Integer] to: (Radians(MH_Angle[MH_Integer]))
              • Special Effect - Set Height of MH_Chain[MH_Integer] to: 35.00
              • Hashtable - Save Handle OfMH_Chain[MH_Integer] as MH_Counter[MH_Integer] of MH_Integer in MH_Table.
              • -------- --------
              • Set VariableSet MH_Distance[MH_Integer] = (MH_Distance[MH_Integer] + 43.50)
              • Set VariableSet MH_PointTemp[2] = (MH_Point[MH_Integer] offset by MH_Distance[MH_Integer] towards MH_Angle[MH_Integer] degrees.)
              • Special Effect - Set Position of MH_Missile[MH_Integer] to x: (X of MH_PointTemp[2]), y: (Y of MH_PointTemp[2]), z: 15.00
              • -------- --------
              • Custom script: set bj_wantDestroyGroup = true
              • Unit Group - Pick every unit in (Units within 100.00 of MH_PointTemp[2].) and do (Actions)
                • Loop - Actions
                  • Set VariableSet MH_UnitTemp = (Picked unit)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (MH_UnitTemp is alive) Equal to True
                      • (MH_UnitTemp is A structure) Equal to False
                      • (MH_UnitTemp is An Ancient) Equal to False
                      • MH_UnitTemp Not equal to MH_Caster[MH_Integer]
                      • MH_Boolean[MH_Integer] Equal to False
                    • Then - Actions
                      • Set VariableSet MH_Boolean[MH_Integer] = True
                      • Set VariableSet MH_UnitHooked[MH_Integer] = MH_UnitTemp
                      • Unit - Turn collision for MH_UnitTemp Off.
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (MH_UnitTemp belongs to an enemy of (Owner of MH_Caster[MH_Integer]).) Equal to True
                        • Then - Actions
                          • Special Effect - Create a special effect attached to the origin of MH_UnitTemp using Objects\Spawnmodels\Human\HumanBlood\BloodElfSpellThiefBlood.mdl
                          • Special Effect - Destroy (Last created special effect)
                          • Unit - Cause MH_Caster[MH_Integer] to damage MH_UnitTemp, dealing MH_Damage[MH_Integer] damage of attack type Chaos and damage type Universal
                          • Unit - Pause MH_UnitTemp
                          • Unit - Create 1 Vision Dummy (500/500 Flying Vision) for (Owner of MH_Caster[MH_Integer]) at MH_PointTemp[2] facing Default building facing degrees
                          • Unit - Add a 4.00 second Generic expiration timer to (Last created unit)
                        • Else - Actions
                    • Else - Actions
              • Custom script: call RemoveLocation (udg_MH_PointTemp[1])
              • Custom script: call RemoveLocation (udg_MH_PointTemp[2])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • MH_Counter[MH_Integer] Greater than or equal to 29
                • Then - Actions
                  • Set VariableSet MH_Boolean[MH_Integer] = True
                • Else - Actions
            • Else - Actions
              • -------- --------
              • -------- PULL BACK CHAIN --------
              • -------- --------
              • Special Effect - Destroy (Load MH_Counter[MH_Integer] of MH_Integer in MH_Table.)
              • Set VariableSet MH_Distance[MH_Integer] = (MH_Distance[MH_Integer] - 43.50)
              • Set VariableSet MH_PointTemp[1] = (MH_Point[MH_Integer] offset by MH_Distance[MH_Integer] towards MH_Angle[MH_Integer] degrees.)
              • Special Effect - Set Position of MH_Missile[MH_Integer] to x: (X of MH_PointTemp[1]), y: (Y of MH_PointTemp[1]), z: 15.00
              • Unit - Move MH_UnitHooked[MH_Integer] instantly to MH_PointTemp[1]
              • -------- --------
              • Set VariableSet MH_Counter[MH_Integer] = (MH_Counter[MH_Integer] - 1)
              • -------- --------
              • Custom script: call RemoveLocation (udg_MH_PointTemp[1])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • MH_Counter[MH_Integer] Equal to 0
                • Then - Actions
                  • Unit - Turn collision for MH_UnitHooked[MH_Integer] On.
                  • Unit - Unpause MH_UnitHooked[MH_Integer]
                  • Special Effect - Destroy MH_Missile[MH_Integer]
                  • -------- --------
                  • Set VariableSet MH_Caster[MH_Integer] = MH_Caster[MH_Index]
                  • Set VariableSet MH_Damage[MH_Integer] = MH_Damage[MH_Index]
                  • Set VariableSet MH_Counter[MH_Integer] = MH_Counter[MH_Index]
                  • Set VariableSet MH_Distance[MH_Integer] = MH_Distance[MH_Index]
                  • Set VariableSet MH_Boolean[MH_Integer] = MH_Boolean[MH_Index]
                  • Set VariableSet MH_UnitHooked[MH_Integer] = MH_UnitHooked[MH_Index]
                  • Set VariableSet MH_Point[MH_Integer] = MH_Point[MH_Index]
                  • Set VariableSet MH_Angle[MH_Integer] = MH_Angle[MH_Index]
                  • Set VariableSet MH_Missile[MH_Integer] = MH_Missile[MH_Index]
                  • -------- --------
                  • Set VariableSet MH_Index = (MH_Index - 1)
                  • Set VariableSet MH_Integer = (MH_Integer - 1)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • MH_Index Equal to 0
                    • Then - Actions
                      • Countdown Timer - Pause MH_Timer
                      • Trigger - Turn off (This trigger)
                    • Else - Actions
                • Else - Actions
When pulling the chain back, not all segments get detroyed. I assume the problem is somewhere in the last part of the code, which re-aligns the MH_Counter...?

  • -------- --------
  • Set VariableSet MH_Caster[MH_Integer] = MH_Caster[MH_Index]
  • Set VariableSet MH_Damage[MH_Integer] = MH_Damage[MH_Index]
  • Set VariableSet MH_Counter[MH_Integer] = MH_Counter[MH_Index]
  • Set VariableSet MH_Distance[MH_Integer] = MH_Distance[MH_Index]
  • Set VariableSet MH_Boolean[MH_Integer] = MH_Boolean[MH_Index]
  • Set VariableSet MH_UnitHooked[MH_Integer] = MH_UnitHooked[MH_Index]
  • Set VariableSet MH_Point[MH_Integer] = MH_Point[MH_Index]
  • Set VariableSet MH_Angle[MH_Integer] = MH_Angle[MH_Index]
  • Set VariableSet MH_Missile[MH_Integer] = MH_Missile[MH_Index]
  • -------- --------
  • Set VariableSet MH_Index = (MH_Index - 1)
  • Set VariableSet MH_Integer = (MH_Integer - 1)
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • MH_Index Equal to 0
    • Then - Actions
      • Countdown Timer - Pause MH_Timer
      • Trigger - Turn off (This trigger)
    • Else - Actions
  • Else - Actions
 
Last edited:
because the Maker's solution is not efficient because we have to re-index every data after the eliminated.
Maker's method is doubly linked list, where only two nodes get re-connected afer an instance finished. It's more leight-weight than the dynamic indexer deindexing part, because it does not care about the amount of instance members.

@Ugabunda you create many of effects, but destroy only one. You would need a loop from 1-MH_Counter[MH_Integer], going through all effects for one instance.
 
Level 11
Joined
May 16, 2020
Messages
655
Sorry, updated the trigger to show everything. I do reduce the integer with:

MH_Counter[MH_integer] = MH_Counter[MH_integer] - 1

But this still leaves some chains when the 2 abilities are used at the same time, specifically when the transition from Index 2 > Index 1 happens.
 
Last edited:
Level 18
Joined
Jun 26, 2020
Messages
1,454
Maker's method is doubly linked list, where only two nodes get re-connected afer an instance finished. It's more leight-weight than the dynamic indexer deindexing part, because it does not care about the amount of instance members.
To connect 2 nodes you must desconect some of them to another node, so then you have to reconnect them again but you have to desconect it of the next node, and so repeating with the others, the rest of nodes aren't a chain you can move all togheter.

@Ugabunda That is beacause you have to re-index every variable of the chains when one ends, you have to add
  • For each (Integer MH_Integer2) from 1 to MH_Counter[MH_Index], do (Actions)
    • Loop - Actions
      • Hashtable - Save Handle Of(Load MH_Counter[MH_Integer2] of MH_Index in MH_Table) as MH_Counter[MH_Integer2] of MH_Integer in MH_Table.
Plus, I recommend have this outside the loop
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • MH_Index Equal to 0
    • Then - Actions
      • Countdown Timer - Pause MH_Timer
      • Trigger - Turn off (This trigger)
    • Else - Actions
 
Last edited:
@HerlySQR repeating something for all nodes is not needed. You might want to read the concept more closely.

A--B--C--D--E

^Imagine these are the nodes. The concept of the doubly linked list is that each node saves data to its previous and its next node. (first and last node might be special, but it's not important)
Now a node gets destroyed, for example Node B... The only thing that to happen is that A's "next" node is now C instead of B, and C's "previous" node is now A instead of B. Only 2 re-assignments.

In comparison in dynamic indexing, each member of the instance needs its own re-assignment.
 
Level 18
Joined
Jun 26, 2020
Messages
1,454
@HerlySQR repeating something for all nodes is not needed. You might want to read the concept more closely.

A--B--C--D--E

^Imagine these are the nodes. The concept of the doubly linked list is that each node saves data to its previous and its next node. (first and last node might be special, but it's not important)
Now a node gets destroyed, for example Node B... The only thing that to happen is that A's "next" node is now C instead of B, and C's "previous" node is now A instead of B. Only 2 re-assignments.

In comparison in dynamic indexing, each member of the instance needs its own re-assignment.
Ok I got it, creating a function that change the n value of a series, makes sense, and I can think more efficient ways to do that than the Maker's method, but that have the minus of if a lot of units are using the spell and the loop never off or is is on for a lot of time then you are creating a lot of unused data, but that is improbable in most of cases.
 
Level 11
Joined
May 16, 2020
Messages
655
Sorry what is that MG_Integer2? Do I need to create a second integer?

I use only 1 integer currently and with this it doesn't work:

  • For each (Integer MH_Integer) from 1 to MH_Counter[MH_Index], do (Actions)
    • Loop - Actions
      • Hashtable - Save Handle Of(Load MH_Counter[MH_Integer] of MH_Index in MH_Table.) as MH_Counter[MH_Integer] of MH_Integer in MH_Table.
 
Level 18
Joined
Jun 26, 2020
Messages
1,454
Sorry what is that MG_Integer2? Do I need to create a second integer?

I use only 1 integer currently and with this it doesn't work:

  • For each (Integer MH_Integer) from 1 to MH_Counter[MH_Index], do (Actions)
    • Loop - Actions
      • Hashtable - Save Handle Of(Load MH_Counter[MH_Integer] of MH_Index in MH_Table.) as MH_Counter[MH_Integer] of MH_Integer in MH_Table.
Yes, you need to create a second integer, and I wrote it bad, it must be like this:
  • For each (Integer MH_Integer2) from 1 to MH_Counter[MH_Index], do (Actions)
    • Loop - Actions
      • Hashtable - Save Handle Of(Load MH_Integer2 of MH_Index in MH_Table) as MH_Integer2 of MH_Integer in MH_Table.
 
Ok I got it, creating a function that change the n value of a series, makes sense, and I can think more efficient ways to do that than the Maker's method, but that have the minus of if a lot of units are using the spell and the loop never off or is is on for a lot of time then you are creating a lot of unused data, but that is improbable in most of cases.
In Maker's method there's no workload outsourced to a function to change 'n' values of some series. It's literally only 2 re-assignment of one next and one prev integer..., which is already highly efficient.
 
Level 18
Joined
Jun 26, 2020
Messages
1,454
In Maker's method there's no workload outsourced to a function to change 'n' values of some series. It's literally only 2 re-assignment of one next and one prev integer..., which is already highly efficient.
Yes, I noticed that when I try understand it, but is too complicated to do understand it, this method is only necessary if you have a lot of data per time (maybe this case), if not, you add a lot of steps to a simple method.

@Ugabunda you're welcome, and yes they can also be reference leaks in the hashtable, because it is keeping saving data, so you have to clear it adding this to the For:
  • For each (Integer MH_Integer2) from 1 to MH_Counter[MH_Index], do (Actions)
    • Loop - Actions
      • Hashtable - Save Handle Of(Load MH_Integer2 of MH_Index in MH_Table) as MH_Integer2 of MH_Integer in MH_Table.
      • Custom script: call RemoveSavedHandle(udg_MH_Table,udg_MH_Index,udg_MH_Integer2)
But, I don't think this is necessary because you will reuse this cells of the hashtable everytime you cast the spell.
 
Last edited:
Top