• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Anubis Statues

Status
Not open for further replies.
Level 8
Joined
Jul 18, 2010
Messages
332
These anubis statues of mine are obviously statues in the game that will fire lasers for every 15 secs. You can destroy them which will give them a 30 sec delay instead of 15 secs. The only problem is they will infinitely use the laser without the 15 or 30 secs. Like after they use it they will use it again and again and again. Here are the triggers


  • Unit - Create 1 Anubis Statue for Neutral Hostile at riflemanpoint_Copy_3 facing 180.00 degrees
  • Hashtable - Save 15 as 5 of (Key (Last created unit)) in aoehashtable
  • Unit Group - Add (Last created unit) to statues
  • Unit - Create 1 Anubis Statue for Neutral Hostile at riflemanpoint_Copy_2 facing 0.00 degrees
  • Hashtable - Save 15 as 5 of (Key (Last created unit)) in aoehashtable
  • Unit Group - Add (Last created unit) to statues
  • Unit - Create 1 Anubis Statue for Neutral Hostile at riflemanpoint_Copy_8 facing 0.00 degrees
  • Hashtable - Save 15 as 5 of (Key (Last created unit)) in aoehashtable
  • Unit Group - Add (Last created unit) to statues
  • Unit - Create 1 Anubis Statue for Neutral Hostile at riflemanpoint_Copy_9 facing 180.00 degrees
  • Hashtable - Save 15 as 5 of (Key (Last created unit)) in aoehashtable
  • Unit Group - Add (Last created unit) to statues
  • Hashtable - Save 15 as 5 of (Key (Last created unit)) in aoehashtable
  • Unit Group - Add (Last created unit) to statues



I think I should just use timers for this one, I don't even know why I did it like this.
  • seth pyramid statues
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in statues and do (Actions)
        • Loop - Actions
          • Set aoetime = (Load 5 of (Key (Picked unit)) from aoehashtable)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Load 5 of (Key (Picked unit)) from aoehashtable) Greater than 0.00
            • Then - Actions
              • Hashtable - Save (aoetime - 1.00) as 5 of (Key (Picked unit)) in aoehashtable
            • Else - Actions
              • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in aoehashtable
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Load 5 of (Key (Picked unit)) from aoehashtable) Equal to 0.00
            • Then - Actions
              • Unit - Add Anubis Statue to (Picked unit)
              • Unit - Order (Picked unit) to Special Rexxar - Battle Roar
              • Unit Group - Remove (Picked unit) from statues
            • Else - Actions



  • aoe spell 13
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Ability being cast) Equal to Anubis Statue
    • Actions
      • Set aoeunit = (Triggering unit)
      • Hashtable - Save Handle Ofaoeunit as 2 of (Key (Triggering unit)) in aoehashtable
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Ability being cast) Equal to Anubis Statue
        • Then - Actions
          • Set aoetime = 1.50
          • Sound - Play MonsoonLightningHit <gen> at 100.00% volume, attached to (Triggering unit)
          • Hashtable - Save aoetime as 1 of (Key (Triggering unit)) in aoehashtable
          • Hashtable - Save Handle Of(Position of (Triggering unit)) as 3 of (Key (Triggering unit)) in aoehashtable
          • Hashtable - Save Handle Of((Load 3 of (Key (Triggering unit)) in aoehashtable) offset by 150.00 towards (Facing of (Triggering unit)) degrees) as 4 of (Key (Triggering unit)) in aoehashtable
          • Special Effect - Create a special effect attached to the overhead of (Triggering unit) using Abilities\Spells\Orc\FeralSpirit\feralspirittarget.mdl
          • Special Effect - Destroy (Last created special effect)
          • Special Effect - Create a special effect attached to the overhead of (Triggering unit) using Abilities\Spells\Orc\FeralSpirit\feralspirittarget.mdl
          • Special Effect - Destroy (Last created special effect)
          • Unit - Create 1 Plasma Laser for (Owner of (Triggering unit)) at (Load 4 of (Key (Triggering unit)) in aoehashtable) facing (Facing of (Triggering unit)) degrees
          • Animation - Change (Last created unit)'s size to (200.00%, 200.00%, 200.00%) of its original size
          • Animation - Change (Last created unit)'s vertex coloring to (100.00%, 16.50%, 16.50%) with 0.00% transparency
          • Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
        • Else - Actions
  • aoe spell Copy 13
    • Events
      • Time - Every 0.18 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in aoegroup_Copy_13 and do (Actions)
        • Loop - Actions
          • Set aoetime = (Load 1 of (Key (Picked unit)) from aoehashtable)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Load 1 of (Key (Picked unit)) from aoehashtable) Greater than 0.00
            • Then - Actions
              • Hashtable - Save (aoetime - 0.18) as 1 of (Key (Picked unit)) in aoehashtable
            • Else - Actions
              • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in aoehashtable
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Load 1 of (Key (Picked unit)) from aoehashtable) Less than or equal to 0.00
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Unit-type of (Picked unit)) Equal to Anubis Statue
                • Then - Actions
                  • Hashtable - Save 15 as 5 of (Key (Picked unit)) in aoehashtable
                  • Unit - Remove Anubis Statue from (Picked unit)
                  • Unit Group - Add (Picked unit) to statues
                  • Trigger - Turn on seth pyramid statues <gen>
                  • Unit - Create 1 Plasma Laser for (Owner of (Picked unit)) at (Load 4 of (Key (Picked unit)) in aoehashtable) facing (Facing of (Picked unit)) degrees
                  • Animation - Change (Last created unit)'s size to (600.00%, 600.00%, 600.00%) of its original size
                  • Animation - Change (Last created unit)'s vertex coloring to (100.00%, 16.50%, 16.50%) with 0.00% transparency
                  • Animation - Change (Last created unit)'s animation speed to 40.00% of its original speed
                  • Unit - Add a 3.00 second Generic expiration timer to (Last created unit)
                  • Unit - Create 1 scream for (Owner of (Picked unit)) at (Load 3 of (Key (Picked unit)) in aoehashtable) facing (Facing of (Picked unit)) degrees
                  • Animation - Change (Last created unit)'s vertex coloring to (100.00%, 16.50%, 16.50%) with 0.00% transparency
                  • Animation - Change (Last created unit)'s size to (225.00%, 100.00%, 100.00%) of its original size
                  • Animation - Change (Last created unit)'s animation speed to 40.00% of its original speed
                  • Unit - Add a 3.00 second Generic expiration timer to (Last created unit)
                  • Unit - Create 1 scream for (Owner of (Picked unit)) at (Load 3 of (Key (Picked unit)) in aoehashtable) facing (Facing of (Picked unit)) degrees
                  • Animation - Change (Last created unit)'s vertex coloring to (100.00%, 16.50%, 16.50%) with 0.00% transparency
                  • Animation - Change (Last created unit)'s size to (200.00%, 100.00%, 100.00%) of its original size
                  • Animation - Change (Last created unit)'s animation speed to 40.00% of its original speed
                  • Unit - Add a 3.00 second Generic expiration timer to (Last created unit)
                  • Unit - Create 1 scream for (Owner of (Picked unit)) at (Load 3 of (Key (Picked unit)) in aoehashtable) facing (Facing of (Picked unit)) degrees
                  • Animation - Change (Last created unit)'s vertex coloring to (100.00%, 16.50%, 16.50%) with 0.00% transparency
                  • Animation - Change (Last created unit)'s size to (175.00%, 100.00%, 100.00%) of its original size
                  • Animation - Change (Last created unit)'s animation speed to 40.00% of its original speed
                  • Unit - Add a 3.00 second Generic expiration timer to (Last created unit)
                  • Set aoepoint_Copy = ((Load 4 of (Key (Picked unit)) in aoehashtable) offset by 200.00 towards (Facing of (Picked unit)) degrees)
                  • Sound - Play LightningBolt <gen> at 100.00% volume, located at aoepoint_Copy with Z offset 0.00
                  • Set aoetargetgroup = (Units within 270.00 of aoepoint_Copy matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an ally of (Owner of aoeunit)) Equal to False) and ((((Matching unit) is dead)
                  • Unit Group - Pick every unit in aoetargetgroup and do (Actions)
                    • Loop - Actions
                      • Unit - Cause aoeunit to damage (Picked unit), dealing 100000.00 damage of attack type Chaos and damage type Normal
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • ((Picked unit) has buff Slow) Equal to False
                        • Then - Actions
                          • Unit - Create 1 Plasma Laser Dummy for (Owner of aoeunit) at aoepoint_Copy facing Default building facing degrees
                          • Unit - Add a 0.50 second Generic expiration timer to (Last created unit)
                          • Unit - Order (Last created unit) to Human Sorceress - Slow (Picked unit)
                        • Else - Actions
                  • Custom script: call RemoveLocation (udg_aoepoint_Copy)
                  • Custom script: call DestroyGroup(udg_aoetargetgroup)
                  • Set aoepoint_Copy = ((Load 4 of (Key (Picked unit)) in aoehashtable) offset by 400.00 towards (Facing of (Picked unit)) degrees)
                  • Sound - Play LightningBolt <gen> at 100.00% volume, located at aoepoint_Copy with Z offset 0.00
                  • Set aoetargetgroup = (Units within 270.00 of aoepoint_Copy matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an ally of (Owner of aoeunit)) Equal to False) and ((((Matching unit) is dead)
                  • Unit Group - Pick every unit in aoetargetgroup and do (Actions)
                    • Loop - Actions
                      • Unit - Cause aoeunit to damage (Picked unit), dealing 100000.00 damage of attack type Chaos and damage type Normal
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • ((Picked unit) has buff Slow) Equal to False
                        • Then - Actions
                          • Unit - Create 1 Plasma Laser Dummy for (Owner of aoeunit) at aoepoint_Copy facing Default building facing degrees
                          • Unit - Add a 0.50 second Generic expiration timer to (Last created unit)
                          • Unit - Order (Last created unit) to Human Sorceress - Slow (Picked unit)
                        • Else - Actions
                  • Custom script: call RemoveLocation (udg_aoepoint_Copy)
                  • Custom script: call DestroyGroup(udg_aoetargetgroup)
                  • Set aoepoint_Copy = ((Load 4 of (Key (Picked unit)) in aoehashtable) offset by 600.00 towards (Facing of (Picked unit)) degrees)
                  • Sound - Play LightningBolt <gen> at 100.00% volume, located at aoepoint_Copy with Z offset 0.00
                  • Set aoetargetgroup = (Units within 270.00 of aoepoint_Copy matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an ally of (Owner of aoeunit)) Equal to False) and ((((Matching unit) is dead)
                  • Unit Group - Pick every unit in aoetargetgroup and do (Actions)
                    • Loop - Actions
                      • Unit - Cause aoeunit to damage (Picked unit), dealing 100000.00 damage of attack type Chaos and damage type Normal
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • ((Picked unit) has buff Slow) Equal to False
                        • Then - Actions
                          • Unit - Create 1 Plasma Laser Dummy for (Owner of aoeunit) at aoepoint_Copy facing Default building facing degrees
                          • Unit - Add a 0.50 second Generic expiration timer to (Last created unit)
                          • Unit - Order (Last created unit) to Human Sorceress - Slow (Picked unit)
                        • Else - Actions
                  • Custom script: call RemoveLocation (udg_aoepoint_Copy)
                  • Custom script: call DestroyGroup(udg_aoetargetgroup)
                  • Set aoepoint_Copy = ((Load 4 of (Key (Picked unit)) in aoehashtable) offset by 800.00 towards (Facing of (Picked unit)) degrees)
                  • Sound - Play LightningBolt <gen> at 100.00% volume, located at aoepoint_Copy with Z offset 0.00
                  • Set aoetargetgroup = (Units within 270.00 of aoepoint_Copy matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an ally of (Owner of aoeunit)) Equal to False) and ((((Matching unit) is dead)
                  • Unit Group - Pick every unit in aoetargetgroup and do (Actions)
                    • Loop - Actions
                      • Unit - Cause aoeunit to damage (Picked unit), dealing 100000.00 damage of attack type Chaos and damage type Normal
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • ((Picked unit) has buff Slow) Equal to False
                        • Then - Actions
                          • Unit - Create 1 Plasma Laser Dummy for (Owner of aoeunit) at aoepoint_Copy facing Default building facing degrees
                          • Unit - Add a 0.50 second Generic expiration timer to (Last created unit)
                          • Unit - Order (Last created unit) to Human Sorceress - Slow (Picked unit)
                        • Else - Actions
                  • Custom script: call RemoveLocation (udg_aoepoint_Copy)
                  • Custom script: call DestroyGroup(udg_aoetargetgroup)
                  • Set aoepoint_Copy = ((Load 4 of (Key (Picked unit)) in aoehashtable) offset by 1000.00 towards (Facing of (Picked unit)) degrees)
                  • Sound - Play LightningBolt <gen> at 100.00% volume, located at aoepoint_Copy with Z offset 0.00
                  • Set aoetargetgroup = (Units within 270.00 of aoepoint_Copy matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an ally of (Owner of aoeunit)) Equal to False) and ((((Matching unit) is dead)
                  • Unit Group - Pick every unit in aoetargetgroup and do (Actions)
                    • Loop - Actions
                      • Unit - Cause aoeunit to damage (Picked unit), dealing 100000.00 damage of attack type Chaos and damage type Normal
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • ((Picked unit) has buff Slow) Equal to False
                        • Then - Actions
                          • Unit - Create 1 Plasma Laser Dummy for (Owner of aoeunit) at aoepoint_Copy facing Default building facing degrees
                          • Unit - Add a 0.50 second Generic expiration timer to (Last created unit)
                          • Unit - Order (Last created unit) to Human Sorceress - Slow (Picked unit)
                        • Else - Actions
                  • Custom script: call RemoveLocation (udg_aoepoint_Copy)
                  • Custom script: call DestroyGroup(udg_aoetargetgroup)
                  • Set aoepoint_Copy = ((Load 4 of (Key (Picked unit)) in aoehashtable) offset by 1200.00 towards (Facing of (Picked unit)) degrees)
                  • Sound - Play LightningBolt <gen> at 100.00% volume, located at aoepoint_Copy with Z offset 0.00
                  • Set aoetargetgroup = (Units within 270.00 of aoepoint_Copy matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an ally of (Owner of aoeunit)) Equal to False) and ((((Matching unit) is dead)
                  • Unit Group - Pick every unit in aoetargetgroup and do (Actions)
                    • Loop - Actions
                      • Unit - Cause aoeunit to damage (Picked unit), dealing 100000.00 damage of attack type Chaos and damage type Normal
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • ((Picked unit) has buff Slow) Equal to False
                        • Then - Actions
                          • Unit - Create 1 Plasma Laser Dummy for (Owner of aoeunit) at aoepoint_Copy facing Default building facing degrees
                          • Unit - Add a 0.50 second Generic expiration timer to (Last created unit)
                          • Unit - Order (Last created unit) to Human Sorceress - Slow (Picked unit)
                        • Else - Actions
                  • Custom script: call RemoveLocation (udg_aoepoint_Copy)
                  • Custom script: call DestroyGroup(udg_aoetargetgroup)
                  • Set aoepoint_Copy = ((Load 4 of (Key (Picked unit)) in aoehashtable) offset by 1400.00 towards (Facing of (Picked unit)) degrees)
                  • Sound - Play LightningBolt <gen> at 100.00% volume, located at aoepoint_Copy with Z offset 0.00
                  • Set aoetargetgroup = (Units within 270.00 of aoepoint_Copy matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an ally of (Owner of aoeunit)) Equal to False) and ((((Matching unit) is dead)
                  • Unit Group - Pick every unit in aoetargetgroup and do (Actions)
                    • Loop - Actions
                      • Unit - Cause aoeunit to damage (Picked unit), dealing 100000.00 damage of attack type Chaos and damage type Normal
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • ((Picked unit) has buff Slow) Equal to False
                        • Then - Actions
                          • Unit - Create 1 Plasma Laser Dummy for (Owner of aoeunit) at aoepoint_Copy facing Default building facing degrees
                          • Unit - Add a 0.50 second Generic expiration timer to (Last created unit)
                          • Unit - Order (Last created unit) to Human Sorceress - Slow (Picked unit)
                        • Else - Actions
                  • Custom script: call RemoveLocation (udg_aoepoint_Copy)
                  • Custom script: call DestroyGroup(udg_aoetargetgroup)
                  • Set aoepoint_Copy = ((Load 4 of (Key (Picked unit)) in aoehashtable) offset by 1600.00 towards (Facing of (Picked unit)) degrees)
                  • Sound - Play LightningBolt <gen> at 100.00% volume, located at aoepoint_Copy with Z offset 0.00
                  • Set aoetargetgroup = (Units within 270.00 of aoepoint_Copy matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an ally of (Owner of aoeunit)) Equal to False) and ((((Matching unit) is dead)
                  • Unit Group - Pick every unit in aoetargetgroup and do (Actions)
                    • Loop - Actions
                      • Unit - Cause aoeunit to damage (Picked unit), dealing 100000.00 damage of attack type Chaos and damage type Normal
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • ((Picked unit) has buff Slow) Equal to False
                        • Then - Actions
                          • Unit - Create 1 Plasma Laser Dummy for (Owner of aoeunit) at aoepoint_Copy facing Default building facing degrees
                          • Unit - Add a 0.50 second Generic expiration timer to (Last created unit)
                          • Unit - Order (Last created unit) to Human Sorceress - Slow (Picked unit)
                        • Else - Actions
                  • Custom script: call RemoveLocation (udg_aoepoint_Copy)
                  • Custom script: call DestroyGroup(udg_aoetargetgroup)
                • Else - Actions
            • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in aoegroup_Copy_13) Equal to 0
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
          • Do nothing
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
¿Why don't you just add Phoenix Fire to the statues with 15 seconds attack cooldown?

These triggers seems pretty heavy . Too many stuff being done at really fast periodic rate.

Maybe you should describe us the original idea you wanted so maybe we can find another (better) way to achieve it.
 
Level 8
Joined
Jul 18, 2010
Messages
332
Sorry about that, I was kinda in a hurry when I was doing this one so I was just copying other triggers that look similar to this one.

What does phoenix fire do exactly that will help me with this one.

I already told the plan at the top.

The first trigger is the making of the statues.
The second trigger is their timer on when they are going to use the spell
The third and fourth trigger is the spell which isn't really laggy or anything it's just that they end up casting the spell over and over again.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Phoenix Fire is an skill that shoots automatically to a random target. You can configure the missile model, the damage, the range, the attack speed, etc. Just set the attack speed to 15 and you're done.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
get rid of the do nothing. u really need to post the whole triggers when ur asking ppl to help.
y this
  • Time - Every 0.18 seconds of game time
that is such an odd time.
use integers to do ur counting. reals are inaccurate.
so change this
  • Hashtable - Save (aoetime - 0.18) as 1 of (Key (Picked unit)) in aoehashtable
u should switch these triggers over and use an indexing system. Hashtables are slower unless u have enough things to fill an array.

if u need to learn how to index, there is a chapter in my tutorial that will help u with it. http://www.hiveworkshop.com/forums/tutorial-submission-283/things-gui-user-should-know-233242/
basically it works by storing units and increasing a max index. then in another trigger u loop through all the indexes and do the damage / whatever u want to do.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
get rid of the do nothing. u really need to post the whole triggers when ur asking ppl to help.
y this
  • Time - Every 0.18 seconds of game time
that is such an odd time.
use integers to do ur counting. reals are inaccurate.
so change this
  • Hashtable - Save (aoetime - 0.18) as 1 of (Key (Picked unit)) in aoehashtable
u should switch these triggers over and use an indexing system. Hashtables are slower unless u have enough things to fill an array.
Don't recommend indexing when he is already using a hashtable. Using hashtables is totally fine and the better solution, as it's cleaner and much more readable than indexing.
Also, hashtables are faster than GUI indexing.
Indexing would just make the stuff unneccessary complicated and harder to read.

@TO:
Change the Condition in your second trigger to "equal or less than 0.00".
Using equal with reals is a bad practice, as reals might never reach that number due to rounding errors and inaccuracy.

I think the problem with your units using the laser constantly is, that in your trigger aoe spell Copy 13, you never remove the unit grom the "aoe-group_Copy_13".
Also, the second condition (value <= 0.00) will always be true, even if there is no stored value for that unit and the trigger will also never turn itself off.
Remember: If you load a real from a flushed hashtable, it will return 0.00, so your condition should also be changed to value <= 0.01 - or you add a second condition "Hashtable has stored value".
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
bribe or nes did a test to find out that hashtables are up to 4 - 8x slower than using an array. when an array is completely filled hashtables are still about 1.5x slower.
Slower than array reads alone, yes, but indexing comes with overhead for incrementing indexes, getting the units index, etc.
Getting a hashtable value is only about 70-80% slower than getting UnitUserData alone.

Also, I'd like the source of that test, because my memory tells me that those numbers are made up and much lower.


Also, it makes no sense to optimize GUI triggers with unneccessary speed quirks, especially when it's just making stuff more complicated. Using hashtables is fine and encouraged to EVERY GUIer. Even I use them over array indexing, as simplicity beats speed in things like this (well okay, technically I use array indexing, as I got systems doing that for me, but when it comes to timer attachment, I always use hashtables).

And we are talking about periodic ForGroup loops here, with copy and pasting the same parenthesis over and over again, just to make it run multiple times... do you really think speed matters here?
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
speed matters everywhere lol.
No it doesn't. Some speed quirks are just horrible practice.

Also i dont suggest that ppl use indexing like GetUnitUserData.
Which is a failure on its own. GetUnitUserData is the fastest way to use indexing and the only thing were indexing actually makes sense.

I show them how to do it in my tutorial. It really isnt hard to understand how to index. it is simple.
Indexing based on the instances of the spell is a horrible and slow practice that is in no way faster than using hashtables, as it creates a lot of overhead due to incrementing counters, recycling indexes, etc.. Don't just make this stuff up if you have no clue what you are doing.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
No it doesn't. Some speed quirks are just horrible practice.


Which is a failure on its own. GetUnitUserData is the fastest way to use indexing and the only thing were indexing actually makes sense.


Indexing based on the instances of the spell is a horrible and slow practice that is in no way faster than using hashtables, as it creates a lot of overhead due to incrementing counters, recycling indexes, etc.. Don't just make this stuff up if you have no clue what you are doing.


Speed is always good.
GetUnitUserData is very fast but hashtables are still slower. Are they slower than actual indexing im not entirely sure never tested it.

As for this statement.
Don't just make this stuff up if you have no clue what you are doing.
All i have to say is no reason to be rude lol. Your always saying everyone has no clue what there doing. Honestly i dont care what u have to say half the time, its not constructive criticism.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
Speed is always good.
GetUnitUserData is very fast but hashtables are still slower. Are they slower than actual indexing im not entirely sure never tested it.
If you are not sure about it, don't tell people to fix something that is not broken. It's simple as that.

And even if indexing would be faster (which it isn't, as hashtables are still fast as hell and create no overhead due to index recycling), the impact on the trigger is basicly non existent.
The triggers f***ing create units, special effects, cycle through loops... the speed increase of replacing a hashtable read with an array read would be like 0.00000001% here. You know how much slower a unit creation is compared to an integer operation or a variable read? Like A THOUSAND TIMES!
Optimizing variable reads ONLY makes sense when used in complicated maths operations and scripts or when the amount of variable reads actually matters in comparison to the amount of agent operations.
Note that this is almost NEVER the case for spells.


As for this statement.
All i have to say is no reason to be rude lol. Your always saying everyone has no clue what there doing. Honestly i dont care what u have to say half the time, its not constructive criticism.
It's not constructive criticism any more, as it became way too annoying long time ago.
You always spread your (often limited) knowledge around and sell it as the ultimate truth. You correct stuff that is not even broken. You just seem to not understand that people use different styles of coding and that there is more than just one solution in most cases.

if you want to help, do it! But please stop fixing stuff that is not broken at all! And please - for christ's sake - stop making stuff any more complicated than it actually is just for a minor speed increase.
Because people do not care, as long as the trigger does not work.
They just want to know what is wrong, so they can fix it and move on. They don't want the trigger to be 1% faster. It's just ridicolous.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
Like I said before the changes I suggest are in the TOs option. As for limit knowledge no reason to insult lol. Speed is still important everywhere. I do use hashtables also, but not when I can index. The trigger he posted is broken I suggested ways to fix and make it more efficient. If u have a problem with that that's ur problem.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
Like I said before the changes I suggest are in the TOs option. As for limit knowledge no reason to insult lol. Speed is still important everywhere. I do use hashtables also, but not when I can index. The trigger he posted is broken I suggested ways to fix and make it more efficient. If u have a problem with that that's ur problem.
Yeah okay, I will stop this now. No reason to beat a dead horse any longer or hijacking this thread.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
@deathismyfriend
I would just say that Unit Indexer may be faster at the moment of "using it" with units and stuff, but remember it's also "indexing" the units.

When widgets enters Wc3 map they are automatically indexed by Wc3 by the widgetId to handle with Hashtables. UnitIndexer re-indexes them to handle them with variables (making the Wc3 system still use memory, but useless). Also, it periodically uses memory to index the units, clean stuff, and so on; hashtables and widget id doesn't.

So, if you add up the Unit Indexer System to the usage of the system itself and it's limitations, you may find yourself with tons of Global Variable Arrays, a system that indexes units, and your own systems that uses the Unit Indexer. Sum al that, and you get something pretty similar to Hashtable usage, wich doesn't require any trigger or system, and has no limitations, and it's already built in the Wc3.

@colinjames12
Have you already tried Phoenix Fire ability?
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
They do have an index limit but ull never hit it lol.

As for the group loop.
To deal damage every second u have to load the damage that was indexed to be dealt. which means using each units Key to load that value. You also would need to use a counter which would be stored in a hashtable linked to each unit. To do all this u need to loop through all the units that need to get damaged. How else would u do that ?
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
mmm... Have you ever noticed you can use Unit ID / 1000000 and UnitID * 1000000 to handle units with arrays instead of having to use the whole ID with a Hashtable?

You can also use mod, or root, or log, or any other math function to make reference to a specific unit.

- Set Unit[Index] = "GetHandleId(Unit) / 10000000"
- Kill (GetHandleId(Unit) * 10000000"
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
You can turn the handle Id into anything you want. It's the barcode of everything in Wc3.

You can "SaveUnitHandle" wich turns a unit into a Integer, and "LoadUnitHandle" turns an integer into a Unit.

And there's no need to loop through unused indexes. Why would you? Bribe's indexer uses the unit custom value. This "idea" uses the unit ID with a simple math operation to access anything, not just units.

Also; with a good programming order, you can use a simple hashtable for the whole game, instead of a bunch of global arrays.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
You can turn the handle Id into anything you want. It's the barcode of everything in Wc3.

You can "SaveUnitHandle" wich turns a unit into a Integer, and "LoadUnitHandle" turns an integer into a Unit.

And there's no need to loop through unused indexes. Why would you? Bribe's indexer uses the unit custom value. This "idea" uses the unit ID with a simple math operation to access anything, not just units.

Also; with a good programming order, you can use a simple hashtable for the whole game, instead of a bunch of global arrays.

i know this. Did u also notice that using it this way is the same thing as indexing lol.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
I always knew xD But it may prove to be usefull for something and someone.

I still like using a single Hashtable for the whole map instead of tons of global arrays + index system.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
They do have an index limit but ull never hit it lol.
There is no index limit. The "index limit", you talk about is the integer max and min size.

As for the group loop.
To deal damage every second u have to load the damage that was indexed to be dealt. which means using each units Key to load that value. You also would need to use a counter which would be stored in a hashtable linked to each unit. To do all this u need to loop through all the units that need to get damaged. How else would u do that ?
You would still need group loops even with indexed arrays if you want it MUI, as GUI arrays can't be two dimensional (at least not with additional maths that would make array indexing even slower compared to hashtables) as you need to have a unit array for each instance of the spell.
And if it doesn't have to be MUI, then there's no reason to use indexing at all, as you could just use unindexed globals then.

Also there's nothing wrong with ForGroup loops, so no reason not to use them.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
There is no index limit. The "index limit", you talk about is the integer max and min size.

Yes that was wat i was tlking about. Like i said it is a limit but ull never hit it.

You would still need group loops even with indexed arrays if you want it MUI, as GUI arrays can't be two dimensional (at least not with additional maths that would make array indexing even slower compared to hashtables) and you need to have a unit array for each instance of the spell.
And if it doesn't have to be MUI, then there's no reason to use indexing at all, as you could just use unindexed globals then.

Also there's nothing wrong with ForGroup loops, so no reason not to use them.

Only time u need a group loop when indexing is for an Aoe damage effect.
Yes u need to have a unit array for each spell with indexing. That is a downside.
If its not MUI then no u dont need indexing but u also dont need hashtables for non MUI spells.
I didnt say there was anything wrong with a group loop. I just dont use them unless needed. You always need them when using hashtable. When u do an Aoe spell with indexing u need 1 group loop each Aoe damage interval. With hashtable u need one group loop w Aoe interval and one group to loop through all of the units using the hashtable.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
Only time u need a group loop when indexing is for an Aoe damage effect.
If it's not an AoE damage effect, I wouldn't need a group loop with hashtables either.

I didnt say there was anything wrong with a group loop. I just dont use them unless needed. You always need them when using hashtable.
No you don't. Only for AoE damage effects. It's absolutely the same for both indexed and hashtable spells. In fact, hashtables allow for two dimensional unit arrays by default, so you wouldn't even need that group loop. The only way to achieve the same with indexed arrays is by using maths to simulate a two dimensional array, which reduces speed due to additional maths operations.

When u do an Aoe spell with indexing u need 1 group loop each Aoe damage interval. With hashtable u need one group loop w Aoe interval and one group to loop through all of the units using the hashtable.
No you don't. It's exactly the same.

Arrays are one dimensional. In order to create two dimensional indexing, you'd need maths operations. Or you could just use hashtables in the first place, which are two dimensional by default.
If you use a hashtable for a one dimensional spell, it's exactly the same for both arrays and hashtables. The only difference is, that arrays require additional overhead through index recycling. There's no need for a group loop in one-dimensional spells in either of the cases.
The group loop for two-dimensional spells is needed in both cases.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
For me, Hashtable + Unit group > Unit Indexer + Loop + Tons of variables for each ability/system.

Unit indexer ? i dont use the unit indexer.
Loop is the same as a group loop lol. Might be faster or slower not sure.
Tons of variables ? This i just dont understand.
With indexing u need a Max index integer. and a tempInt. The rest is the variables that keep track of damage / whatever which u would need to save them into a hashtable to do damage and everything. So were do tons of variables come into play ?

@Zwiebelchen
What do u mean u dont need a group loop when using hashtables ?

And when making any spell using indexing u dont need a two dimensional indexing. Ive never came across one.
Also what do u mean by u dont need a tempGroup to do Aoe damage at the interval lol. U pick units in range then deal damage so u need a group loop.
When the unit needs to be removed from the hashtable u also need to clear the child / parents keys for that unit. So thats pretty much the same as de-indexing lol
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
@Zwiebelchen
What do u mean u dont need a group loop when using hashtables ?
As you can have actual two dimensional unit arrays, you can actually just loop through the second-order unit array instead of doing a ForGroup. You can't do that with one dimensional indexing.

And when making any spell using indexing u dont need a two dimensional indexing. Ive never came across one.
Every spell hitting more than just one unit over time requires two dimensional indexing or a group loop.

Also what do u mean by u dont need a tempGroup to do Aoe damage at the interval lol. U pick units in range then deal damage so u need a group loop.
Why would you pick the units again every time? For an AoE-Debuff-DoT spell, you just store the group picked once and just cycle through it every time!
If you want a stationary AoE-Attack like Rain of Fire, it's actually a one dimensional spell, not a two dimensional spell. Enuming units in range would be required either way then.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
As you can have actual two dimensional unit arrays, you can actually just loop through the second-order unit array instead of doing a ForGroup. You can't do that with one dimensional indexing.

What do u mean by loop through the second order unit array ?
Also if u loop using a hashtable and loop through a indexed spell and hashtables are slower to begin with how does this make them faster ?

Every spell hitting more than just one unit over time requires two dimensional indexing or a group loop.

A DOT spell doesnt require two dimensional indexing lol. Unless im thinking of two dimensional indexing wrong. All u need is a counter on the index of the unit then when counter hits the number deal damage to the unit.

Why would you pick the units again every time? For an AoE-Debuff-DoT spell, you just store the group picked once and just cycle through it every time!
If you want a stationary AoE-Attack like Rain of Fire, it's actually a one dimensional spell, not a two dimensional spell. Enuming units in range would be required either way then.

Im tlking about an Aoe damage were the units can move out of the Aoe effect area. You would need to do a group loop both ways.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
What do u mean by loop through the second order unit array ?
Also if u loop using a hashtable and loop through a indexed spell and hashtables are slower to begin with how does this make them faster ?
We are not talking about the same thing. You continue to talk about one dimensional spells, I talk about two dimensional spells.
For one dimensional spells, there's no looping in both cases.

A DOT spell doesnt require two dimensional indexing lol. Unless im thinking of two dimensional indexing wrong. All u need is a counter on the index of the unit then when counter hits the number deal damage to the unit.
Then how do you determine the damaging unit or the amount of damage dealt by that unit? Again, We are talking about AoE effects here.
All you can do with indexing is summing up the total damage per interval and then deal that damage regardless of the casting unit.
As soon as you want the casting unit to deal that damage, you need two dimensional arrays.

Im tlking about an Aoe damage were the units can move out of the Aoe effect area. You would need to do a group loop both ways.
Yes. That's what I was talking about.

Let's say you have a spell that deals AoE damage and debuffs all units hit with a DoT, dealing damage per second for 10 seconds.
How do you do that with indexing without a group loop?
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
We are not talking about the same thing. You continue to talk about one dimensional spells, I talk about two dimensional spells.
For one dimensional spells, there's no looping in both cases.

And again not sure what u mean by two dimensional spells lol.
Im tlking about a DOT type of spell.

Then how do you determine the damaging unit or the amount of damage dealt by that unit? Again, We are talking about AoE effects here.
All you can do with indexing is summing up the total damage per interval and then deal that damage regardless of the casting unit.
As soon as you want the casting unit to deal that damage, you need two dimensional arrays.

I store the amount of damage i want the caster to deal into a real variable. How is it a 2 dimensional array. If u have an array with a caster, an array with the target unit. Then an array to store damage to deal. An array to tell when the spell ends. And an array to count up to the interval of time. ? They are still single arrays. you index all that into a index then de-index it when that spell instance is over...If u still dont understand what im doing. Then look at my tutorial in the indexing chapter. Thats how i index all of my spells.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
I store the amount of damage i want the caster to deal into a real variable. How is it a 2 dimensional array. If u have an array with a caster, an array with the target unit. Then an array to store damage to deal. An array to tell when the spell ends. And an array to count up to the interval of time. ? They are still single arrays. you index all that into a index then de-index it when that spell instance is over...If u still dont understand what im doing. Then look at my tutorial in the indexing chapter. Thats how i index all of my spells.
What if the spell hits more than one unit? You need to have a group array then and cycle through the members of the group.

So what you would do in your periodic trigger would be:
- loop through the indexes
- for each index, loop through the stored group
- deal damage

What I would do with hashtables:
- have ONE SINGLE global group, containing all targets doted
- loop through that group
- lookup the handle ID of that unit, get the caster and damage dealt and deal that damage

You can clearly tell the second is the easier solution.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
if its a moving Aoe then u have to use groups for both. If its Aoe were all units are lets say poisoned. then u make a tempGroup and index all those units in the Casting trigger. Then its a normal loop.

I dont use multiple groups when doing a spell.
Just look at the example I posted.

Also, you don't neccessarily need a group in the hashtable case.
You can also just use a unit array instead of the group, as you can always just access all data by handle Id.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
I see the way u did it. im saying i wouldnt do it that way tho.

Like i said i dont use group arrays unless absolutely necessary.

Instead of using a group like that u store each unit and index it in the casting trigger. That way it breaks it down as if its a normal spell.
What if you want stacking debuffs?
You'd need a group array then.

EDIT:
I see what you did there. Actually, I got to admit that's a pretty clever way to do it (never thought of actually indexing the units, not the spell instances), as it allows indexing the same unit multiple times.
Okay, I'm convinced, indexing is a good idea in this case.

The only flaw this method has is that debuffs that overwrite each other require looping through all the indexed units in order to find if the unit is already indexed to clear it up (that's actually a pretty huge drawback compared to GetHandleId(unit) based indexing). Also, triggered dispel abilities would also require search loops.

So it's safe to say that there's two optimal solutions depending on what you want to do:
- global group with hashtables indexed by GetHandleId(unit) for non-stacking or dispellable debuffs.
- unit array with indexing for stacking debuffs.

However, nothing beats a hashtable that uses GetHandleId(timer) as a parent in speed and accuracy. But as timers are not accessable in GUI, it's fine to use indexing instead.
 
Last edited:
Level 29
Joined
Oct 24, 2012
Messages
6,543
What if you want stacking debuffs?
You'd need a group array then.

EDIT:
I see what you did there. Actually, I got to admit that's a pretty clever way to do it, as it allows indexing the same unit multiple times.
Okay, I'm convinced, indexing is a good idea in this case.

Thanks for that. I always thought it would be faster that way.

However, nothing beats a hashtable that uses GetHandleId(timer) as a parent. But as timers are not accessable in GUI, it's fine to use indexing instead.

I honestly never made any vJass spells yet lol. Ive just learned about the stuff with spells by helping ppl fix theres. Ive made 1 spell for myself lol.
I have used GetHandleId a lot tho for timers and some other things.
Are hashtables really that much faster when using GetHandleId() compared to using indexing ? I havent really seen any spells that use hashtables. I wish someone would make 2 identical spells. One based on hashtables and one based on indexing. Make them as efficient as possible and find out the speed difference lol. Im betting its very minimal but it would still be nice to know.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
I honestly never made any vJass spells yet lol. Ive just learned about the stuff with spells by helping ppl fix theres. Ive made 1 spell for myself lol.
I have used GetHandleId a lot tho for timers and some other things.
Are hashtables really that much faster when using GetHandleId() compared to using indexing ? I havent really seen any spells that use hashtables. I wish someone would make 2 identical spells. One based on hashtables and one based on indexing. Make them as efficient as possible and find out the speed difference lol. Im betting its very minimal but it would still be nice to know.
It's basicly just that:

You create a timer, store all data needed into GetHandleId(timer), run the timer and let it fire an execute function that reads GetHandleId(GetExpiredTimer()).

No cross-referencing, no indexing, no Modulo functions to find out wether "it's time to damage". Also, it avoids the all the slow trigger thing as timers directly call a function.

Plus, you avoid having to make one periodic timer event and masses of arrays for each spell.
Timer attachment eats indexing of all kinds for breakfast.

EDIT: Let's not hijack this thread any further. TO seems to be gone anyway.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
It's basicly just that:

You create a timer, store all data needed into GetHandleId(timer), run the timer and let it fire an execute function that reads GetHandleId(GetExpiredTimer()).

No cross-referencing, no indexing, no Modulo functions to find out wether "it's time to damage". Also, it avoids the all the slow trigger thing as timers directly call a function.

Plus, you avoid having to make one periodic timer event and masses of arrays for each spell.
Timer attachment eats indexing of all kinds for breakfast.

EDIT: Let's not hijack this thread any further. TO seems to be gone anyway.

Ooo ok I do that already lol. Also ya this is my last post on here. I guess we did hijack the thread a little lol.

@TO
Sry for the thread hijack if u still need help just post on here
 
Level 8
Joined
Jul 18, 2010
Messages
332
You two are acting too immature, and I can't help but notice that this has happened in two of my threads already. But that's okay.

Btw, regarding my problem, it's solved now, like my problem with the enabling and disabling invulnerability of units, my triggers here are stupid. I switch to using timers for this too now.

I found that when you use an ability, remove it and add it again, it will still undergo its cooldown. So what I did is just reset ability cooldowns and now the problem is solved.

And I also feel that hashtables are better that's why I resorted to using that. I understand much better and I can manipulate it much better. I just need to know how to use it better though.
 
Status
Not open for further replies.
Top