• 🏆 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!

Tracker Boomerang v1.0

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
  • Like
Reactions: deepstrasz
Tracker Boomerang v1.0 by WherewolfTherewolf
----------------------------------------------
Ok, have we all played either TLoZ Phantom Hourglass or TLoZ Spirit Tracks? If so then you will most likely remember the Boomerang (which of course is a normal item from the series) that allowed you to trace out its path before unleashing it on your unfortunate enemies. This spell is me trying to carry that item over to Warcraft III.

Tracker Boomerang
*Consists of 2 spells - the hero spell one which is what you use to trace the path and the one to throw the boomerang.
*Once you cast the first spell, you trace out the path of the boomerang. It creates a temporary unit that you order to move in the path you want the boomerang to go. The path that the tracer follows will be the same path the boomerang follows.
*Once you have your path traced out, and if your close enough to the start of your path (the bright colored circle of power) you cast the second spell to unleash the boomerang on your enemies which it then stuns.

*This spell is not only an offensive spell, this spell can be integrated into puzzles (as I have demonstrated with the switch elevator in the test map).


This spell is MPI but not MUI. The spell does use a Hash Table.


Thanks to Darkness-4ever for figuring out why this wasn't working before

  • Learn Tracker Boomerang
    • Events
      • Unit - A unit Learns a skill
    • Conditions
      • (Learned Hero Skill) Equal to Tracker Boomerang
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Throw Boomerang for (Learning Hero)) Equal to 0
        • Then - Actions
          • Unit - Add Throw Boomerang to (Learning Hero)
        • Else - Actions
  • Tracker Hash Variables and assorted Stuff
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set Tb_Hash = (Last created hashtable)
      • Set Tb_String[1] = *whap!*
      • Set Tb_String[2] = *shmack!*
      • Set Tb_String[3] = *thunk!*
      • Set Tb_String[4] = *thap!*
      • Set Tb_String[5] = *phump!*
  • Trace Path Start
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Tracker Boomerang
    • Actions
      • -------- Clean Up --------
      • Unit Group - Pick every unit in Tb_PathGroup[(Player number of (Owner of (Casting unit)))] and do (Actions)
        • Loop - Actions
          • Unit - Remove (Picked unit) from the game
      • Hashtable - Clear all child hashtables of child (Key (Owner of (Casting unit))) in Tb_Hash
      • Set Tb_PathInt[(Player number of (Owner of (Casting unit)))] = 0
      • -------- -------------------------------------- --------
      • Set P = (Position of (Casting unit))
      • -------- -------------------------------------- --------
      • Unit - Create 1 Tracer for (Owner of (Casting unit)) at P facing Default building facing degrees
      • Unit Group - Add (Last created unit) to Tb_TracerGroup
      • Selection - Clear selection for (Owner of (Casting unit))
      • Selection - Select (Last created unit) for (Owner of (Casting unit))
      • Unit - Set the custom value of (Last created unit) to (100 x (Level of Tracker Boomerang for (Casting unit)))
      • Unit - Create 1 Path Start for (Owner of (Last created unit)) at P facing Default building facing degrees
      • Set Tb_PathStart[(Player number of (Owner of (Casting unit)))] = (Last created unit)
      • Special Effect - Create a special effect attached to the overhead of (Last created unit) using UI\Feedback\RallyPoint\RallyPoint.mdl
      • Unit Group - Add (Last created unit) to Tb_PathGroup[(Player number of (Owner of (Casting unit)))]
      • -------- -------------------------------------- --------
      • Set Tb_Caster[(Player number of (Owner of (Casting unit)))] = (Casting unit)
      • Custom script: call RemoveLocation(udg_P)
      • Wait 0.10 seconds
      • Unit - Pause Tb_Caster[(Player number of (Owner of (Casting unit)))]
  • Trace Path
    • Events
      • Time - Every 0.05 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in Tb_TracerGroup and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Custom value of (Picked unit)) Not equal to (100 x (Level of Tracker Boomerang for Tb_Caster[(Player number of (Owner of (Picked unit)))]))
              • (Custom value of (Picked unit)) Greater than 0
            • Then - Actions
              • Set P = (Position of (Picked unit))
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Distance between Tb_ReferenceP[(Player number of (Owner of (Picked unit)))] and P) Less than or equal to 7.00
                • Then - Actions
                  • Unit - Set the custom value of (Picked unit) to ((Custom value of (Picked unit)) - 1)
                  • Custom script: call RemoveLocation( udg_Tb_ReferenceP[GetConvertedPlayerId(GetOwningPlayer(GetEnumUnit()))] )
                  • Set Tb_ReferenceP[(Player number of (Owner of (Picked unit)))] = (Position of (Picked unit))
                  • Skip remaining actions
                • Else - Actions
              • Custom script: call RemoveLocation( udg_P)
            • Else - Actions
          • Set Tb_ReferenceP[(Player number of (Owner of (Picked unit)))] = (Position of (Picked unit))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Custom value of (Picked unit)) Less than or equal to 1
            • Then - Actions
              • Unit Group - Remove (Picked unit) from Tb_TracerGroup
              • Set Tb_PathInt[(Player number of (Owner of (Picked unit)))] = (Tb_PathInt[(Player number of (Owner of (Picked unit)))] + 1)
              • Unit - Create 1 Path End for (Owner of (Picked unit)) at Tb_ReferenceP[(Player number of (Owner of (Picked unit)))] facing Default building facing degrees
              • Unit Group - Add (Last created unit) to Tb_PathGroup[(Player number of (Owner of (Picked unit)))]
              • Hashtable - Save Handle Of(Last created unit) as Tb_PathInt[(Player number of (Picked player))] of (Key (Owner of (Picked unit))) in Tb_Hash
              • Custom script: call RemoveLocation( udg_Tb_ReferenceP[GetConvertedPlayerId(GetOwningPlayer(GetEnumUnit()))] )
              • Unit - Remove (Picked unit) from the game
              • Unit - Unpause Tb_Caster[(Player number of (Owner of (Picked unit)))]
              • Selection - Select Tb_Caster[(Player number of (Owner of (Picked unit)))]
              • Skip remaining actions
            • Else - Actions
          • Set Tb_PathInt[(Player number of (Owner of (Picked unit)))] = (Tb_PathInt[(Player number of (Owner of (Picked unit)))] + 1)
          • Unit - Create 1 Path for (Owner of (Picked unit)) at Tb_ReferenceP[(Player number of (Owner of (Picked unit)))] facing Default building facing degrees
          • Unit Group - Add (Last created unit) to Tb_PathGroup[(Player number of (Owner of (Picked unit)))]
          • Hashtable - Save Handle Of(Last created unit) as Tb_PathInt[(Player number of (Owner of (Picked unit)))] of (Key (Owner of (Picked unit))) in Tb_Hash
          • Unit - Set the custom value of (Picked unit) to ((Custom value of (Picked unit)) - 1)
  • Throw Boomerang
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Throw Boomerang
    • Actions
      • Unit Group - Remove all units from Tb_AlreadyStunned[(Player number of (Owner of (Casting unit)))]
      • Set Tb_Caster[(Player number of (Owner of (Casting unit)))] = (Casting unit)
      • Set P = (Position of Tb_PathStart[(Player number of (Owner of (Casting unit)))])
      • Set P2 = (Position of (Casting unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Distance between P and P2) Less than or equal to 140.00
        • Then - Actions
          • Unit - Create 1 Boomerang for (Owner of (Casting unit)) at P facing Default building facing degrees
          • Unit Group - Add (Last created unit) to Tb_BoomerangGroup
          • Unit - Set the custom value of (Last created unit) to 1
        • Else - Actions
      • Custom script: call RemoveLocation(udg_P)
      • Custom script: call RemoveLocation(udg_P2)
  • Boomerang Path
    • Events
      • Time - Every 0.02 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in Tb_BoomerangGroup and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Custom value of (Picked unit)) Less than Tb_PathInt[(Player number of (Owner of (Picked unit)))]
            • Then - Actions
              • Unit - Set the custom value of (Picked unit) to ((Custom value of (Picked unit)) + 1)
              • Set P = (Position of (Load (Custom value of (Picked unit)) of (Key (Owner of (Picked unit))) in Tb_Hash))
              • Unit - Move (Picked unit) instantly to P
              • Custom script: call RemoveLocation(udg_P)
            • Else - Actions
              • Unit Group - Add (Picked unit) to Tb_BoomerangGroup2
              • Unit Group - Remove (Picked unit) from Tb_BoomerangGroup
  • Boomerang Return
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in Tb_BoomerangGroup2 and do (Actions)
        • Loop - Actions
          • Set P3 = (Position of Tb_Caster[(Player number of (Owner of (Picked unit)))])
          • Set P = (Position of (Picked unit))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance between P3 and P) Less than or equal to 90.00
            • Then - Actions
              • Unit - Remove (Picked unit) from the game
            • Else - Actions
              • Set P2 = (P offset by 30.00 towards (Angle from P to P3) degrees)
              • Unit - Move (Picked unit) instantly to P2
              • Custom script: call RemoveLocation(udg_P2)
          • Custom script: call RemoveLocation(udg_P)
          • Custom script: call RemoveLocation(udg_P3)
  • Boomerang Stun
    • Events
      • Time - Every 0.20 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in Tb_BoomerangGroup and do (Actions)
        • Loop - Actions
          • Set P = (Position of (Picked unit))
          • Set Tb_ReferenceUnit = (Picked unit)
          • Set Tb_StunGroup = (Units within 120.00 of P matching (((Owner of (Matching unit)) is an enemy of (Owner of Tb_ReferenceUnit)) Equal to True))
          • Unit Group - Pick every unit in Tb_StunGroup and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is alive) Equal to True
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • ((Picked unit) is in Tb_AlreadyStunned[(Player number of (Owner of Tb_ReferenceUnit))]) Equal to False
                    • Then - Actions
                      • Unit Group - Add (Picked unit) to Tb_AlreadyStunned[(Player number of (Owner of Tb_ReferenceUnit))]
                      • Set P2 = (Position of (Picked unit))
                      • Unit - Create 1 Boomerang Cast Dummy for (Owner of Tb_ReferenceUnit) at P facing Default building facing degrees
                      • Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
                      • Unit - Order (Last created unit) to Neutral - Firebolt (Picked unit)
                      • Sound - Play BoomerangHit <gen> at 100.00% volume, located at P2 with Z offset 0.00
                      • -------- Unnecassary Stuff --------
                      • Set Tb_RandomInt = (Random integer number between 1 and 5)
                      • Floating Text - Create floating text that reads Tb_String[Tb_RandomInt] at P2 with Z offset 0.00, using font size 10.00, color (100.00%, 0.00%, 0.00%), and 0.00% transparency
                      • Floating Text - Change the lifespan of (Last created floating text) to 5.00 seconds
                      • Floating Text - Change (Last created floating text): Disable permanence
                      • Floating Text - Change the fading age of (Last created floating text) to 4.00 seconds
                      • Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
                      • -------- ------------------------------------------ --------
                      • Custom script: call RemoveLocation(udg_P2)
                    • Else - Actions
                • Else - Actions
          • Custom script: call DestroyGroup( udg_Tb_StunGroup)
          • Custom script: call RemoveLocation(udg_P)
      • Unit Group - Pick every unit in Tb_BoomerangGroup2 and do (Actions)
        • Loop - Actions
          • Set P = (Position of (Picked unit))
          • Set Tb_ReferenceUnit = (Picked unit)
          • Set Tb_StunGroup = (Units within 120.00 of P matching (((Owner of (Matching unit)) is an enemy of (Owner of Tb_ReferenceUnit)) Equal to True))
          • Unit Group - Pick every unit in Tb_StunGroup and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is alive) Equal to True
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • ((Picked unit) is in Tb_AlreadyStunned[(Player number of (Owner of Tb_ReferenceUnit))]) Equal to False
                    • Then - Actions
                      • Unit Group - Add (Picked unit) to Tb_AlreadyStunned[(Player number of (Owner of Tb_ReferenceUnit))]
                      • Set P2 = (Position of (Picked unit))
                      • Unit - Create 1 Boomerang Cast Dummy for (Owner of Tb_ReferenceUnit) at P facing Default building facing degrees
                      • Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
                      • Unit - Order (Last created unit) to Neutral - Firebolt (Picked unit)
                      • Sound - Play BoomerangHit <gen> at 100.00% volume, located at P2 with Z offset 0.00
                      • -------- Unnecassary Stuff --------
                      • Set Tb_RandomInt = (Random integer number between 1 and 5)
                      • Floating Text - Create floating text that reads Tb_String[Tb_RandomInt] at P2 with Z offset 0.00, using font size 10.00, color (100.00%, 0.00%, 0.00%), and 0.00% transparency
                      • Floating Text - Change the lifespan of (Last created floating text) to 5.00 seconds
                      • Floating Text - Change (Last created floating text): Disable permanence
                      • Floating Text - Change the fading age of (Last created floating text) to 4.00 seconds
                      • Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
                      • -------- ------------------------------------------ --------
                      • Custom script: call RemoveLocation(udg_P2)
                    • Else - Actions
                • Else - Actions
          • Custom script: call DestroyGroup( udg_Tb_StunGroup)
          • Custom script: call RemoveLocation(udg_P)
  • End Path
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to End Path (Neutral Hostile 1)
    • Actions
      • Unit - Set the custom value of (Casting unit) to 1
Keywords:
Boomerang, Track, Trace, Path, Spell, Zelda, Link, Item, Weapon, Stun, Puzzle, Australia, Rang
Contents

Just another Warcraft III map (Map)

Reviews
14:22, 13th Nov 2015 BPower: No update done in years. Rejected. 17:22, 14th Feb 2010 The_Reborn_Devil: Very interesting and unique idea, but I'm afraid it must be fully MUI before it can be approved. Status: Rejected until updated...

Moderator

M

Moderator

14:22, 13th Nov 2015
BPower: No update done in years. Rejected.

17:22, 14th Feb 2010
The_Reborn_Devil:
Very interesting and unique idea, but I'm afraid it must be fully MUI before it can be approved.


Status: Rejected until updated
Rating: N/A

PM me or another mod once you've fixed this to get the spell reviewed again. Have a nice day!
 
Level 23
Joined
Nov 29, 2006
Messages
2,482
I believe it has to be fully multiinstanceable :O

Oh and you should totally use GetTriggeringUnit instead of castingUnit. See in your case, I do see a problem. When you use waits, CastingUnit will be overwritten (caee by case, if cast multiply times even by different players, but usually yes, broken stuff :>), thus destroying the entire spell. CastingUnit is a wrapped global, while GetTriggeringUnit is a local and will work though waits, if that would be necessary. Also, a normal wait is discarding players who could lag. Polled Wait will always function in those cases (and then again, you should try to avoid waits or polled waits as much as possible, since they are not accurate, and has some other negative attributes).

Thats all I can say now, I have some packing to do, since Im catching the train in a moment
 
Level 19
Joined
Feb 4, 2009
Messages
1,313
If you are using hashtables then there is no excuse for not being MUI.

hashtables are imba 2D-arrays
there is nothing you can't do with them :p

Juse use Key of (Unit) for storing the data.
or better use the key of the dummy
so you can cast it multiple times with the same unit without screwing things up

however the idea is very nice and I would like to see it improved (unpractical in real games though....the arrow is too slow and you should select it automatically for the casting player cause it is quite hard to do that)
 
please make this mui, b4 i go jump off the hive chat ._.

K, give me some time to redo it MUIable

unpractical in real games though....the arrow is too slow and you should select it automatically for the casting player cause it is quite hard to do that

Well it does do that, but you share unit control here (I put that in to test and make sure it worked right, I can remove that now) but yes it does actually select the aura. And the idea of this is a little unpractical for games like AoS's but this spell is a bit more geared towards things like Campaigns.


Oh and if anyone wants it I can trigger in some damage for the spell.



Edit:
MUIing this is going to be a pain - this may take a while
 
Last edited:
1: Not the appropriate place to ask that
2: MUI means that if every unit on the map had this spell, they could all cast it at once and it would work perfectly for each. Basically multiple units from multiple players can cast the same spell at the same exact time and it wouldn't conflict.
3: MPI used to be accepted (MUI isn't very practical for this spell so I didn't do it, but I guess I have to for it to be accepted) and it meant that multiple players could have a unit cast this spell at the exact same time and it wouldn't conflict, but not multiple units by the same player.
 
Level 23
Joined
Nov 29, 2006
Messages
2,482
Well in any sense of matter, aos-like spell could indeed become mpi only, but then again, what if you would reset your cooldown with an item or something, and cast it again? That is where mpi fails, as either it would be incorrectly designed to create a new instance of the spell for the unit, or just screw up entirely.

There's a difference on cases such as player systems, like alliance/camera/resource/cinema/arrowkeys or something like that. They are most likely always to be mpi cases.
 
Top