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

UTS - Unit on Tower System v1.3 GUI/MUI

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
Usable in tower defense sort of maps.

Unit on Tower system: Creates a dummy natural unit that faces the direction your tower is attacking and plays attack animation, and changed their height using crow form. When tower dies it gets killed too. Now your tower wont look too static if you use unit models on them. Also include feature to make unit enter tower as of v1.3

As long as dummy unit is set to hover and not fly, he will look right even on hills.

v1.1 configuration is easier
v1.2 implemented deindexing thanks to wrda for showing me how
v1.3 now units can garrison the scout tower to create the corresponding tower type, and that tower ungarrison to downgrade itself back to scout tower and create the same unit type. If the unit ungarrison his health percentage will be equal to the tower due to bad working environment :D and when the unit health is low he "heals" himself when the tower is in good condition :p

You can simply remove the scout tower's ability to upgrade to i.e. sniper tower if you want to exclusively use the garrison system.
There are 2 abilities both are using the channel spell, garrison spell must be manually added (object editor) to the unit of your choosing while ungarrison is automatically given (via trigger) to the tower type when they appear in the map.
If for some reason you want some special towers to unable to ungarrison, then you may delete the add ability line in start trigger and manually add the spell to a tower type.

Instructions (Readme) on how to install is included in the map

  • UTS INI config
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- ------------------Set to false if no longer testing------------------------- --------
      • Set Debug_Mode = True
      • -------- ------------------------------------------- --------
      • Set UTS_Tower_Type[1] = Sniper Tower
      • Set UTS_Dummy_Type[1] = Sniper Tower (Dummy)
      • Set UTS_Dummy_FlyingHeight[1] = 150.00
      • Set UTS_Unit_Type[1] = Rifleman
      • -------- ------------------------------------------- --------
      • Set UTS_Tower_Type[2] = Mortar Tower
      • Set UTS_Dummy_Type[2] = Mortar Tower (Dummy)
      • Set UTS_Dummy_FlyingHeight[2] = 150.00
      • Set UTS_Unit_Type[2] = Mortar Team
      • -------- ------------------------------------------- --------
      • Set UTS_Tower_Type[3] = Archer Tower (No scout tower model)
      • Set UTS_Dummy_Type[3] = Archer Tower Dummy
      • Set UTS_Dummy_FlyingHeight[3] = 0.00
      • Set UTS_Unit_Type[3] = Archer
      • -------- ------------------------------------------- --------
      • Set UTS_Tower_Type[4] = Warlock Tower
      • Set UTS_Dummy_Type[4] = Warlock Tower (Dummy)
      • Set UTS_Dummy_FlyingHeight[4] = 120.00
      • Set UTS_Unit_Type[4] = Fel Orc Warlock
      • -------- ------------------------------------------- --------
      • -------- Adjust this number to the max amount of tower types you plan to use --------
      • Set UTS_Total_Towers = 4
      • -------- ------------------------------------------- --------
      • Set UTS_Spell_Type[1] = Enter Scout Tower
      • Set UTS_Spell_Type[2] = Ungarrison
      • Set UTS_Scout_Tower = Scout Tower
      • -------- ------------------------------------------- --------
  • UTS Start
    • Events
      • Unit - A unit Finishes an upgrade
      • Unit - A unit enters (Playable map area)
    • Conditions
      • ((Triggering unit) is A structure) Equal to True
    • Actions
      • For each (Integer UTS_ThisTower) from 1 to UTS_Total_Towers, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Unit-type of (Triggering unit)) Equal to UTS_Tower_Type[UTS_ThisTower]
            • Then - Actions
              • Set UTS_Index = (UTS_Index + 1)
              • -------- ------------------------------------------------------------ --------
              • Set UTS_Caster[UTS_Index] = (Triggering unit)
              • Set UTS_Caster_Loc = (Position of UTS_Caster[UTS_Index])
              • -------- ------------------------------------------------------------ --------
              • Unit - Add Ungarrison to UTS_Caster[UTS_Index]
              • -------- ------------------------------------------------------------ --------
              • Unit - Create 1 UTS_Dummy_Type[UTS_ThisTower] for Neutral Passive at UTS_Caster_Loc facing Default building facing degrees
              • Set UTS_Setheight = UTS_Dummy_FlyingHeight[UTS_ThisTower]
              • -------- ------------------------------------------------------------ --------
              • Set UTS_Dummy[UTS_Index] = (Last created unit)
              • -------- ------------------------------------------------------------ --------
              • Unit - Turn collision for UTS_Dummy[UTS_Index] Off
              • Unit - Move UTS_Dummy[UTS_Index] instantly to UTS_Caster_Loc
              • Unit - Change color of UTS_Dummy[UTS_Index] to (Color of (Owner of UTS_Caster[UTS_Index]))
              • Unit - Add Crow Form to UTS_Dummy[UTS_Index]
              • Animation - Change UTS_Dummy[UTS_Index] flying height to UTS_Setheight at 0.00
              • Unit - Make UTS_Dummy[UTS_Index] Explode on death
              • -------- ------------------------------------------------------------ --------
              • Custom script: call RemoveLocation(udg_UTS_Caster_Loc)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • UTS_Index Equal to 1
                • Then - Actions
                  • Trigger - Turn on UTS Attack <gen>
                  • Trigger - Turn on UTS Death <gen>
                • Else - Actions
            • Else - Actions
  • UTS Attack
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • ((Attacking unit) is A structure) Equal to True
    • Actions
      • For each (Integer UTS_Loop) from 1 to UTS_Index, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Attacking unit) Equal to UTS_Caster[UTS_Loop]
            • Then - Actions
              • Unit - Make UTS_Dummy[UTS_Loop] face (Triggering unit) over 0.10 seconds
              • Animation - Play UTS_Dummy[UTS_Loop]'s attack animation
              • Animation - Queue UTS_Dummy[UTS_Loop]'s stand animation
            • Else - Actions
  • UTS Death
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Triggering unit) is A structure) Equal to True
    • Actions
      • For each (Integer UTS_Loop2) from 1 to UTS_Index, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • UTS_Caster[UTS_Loop2] Equal to (Triggering unit)
            • Then - Actions
              • Animation - Change UTS_Dummy[UTS_Loop2] flying height to 0.00 at 0.00
              • -------- ---------- --------
              • Trigger - Turn off (This trigger)
              • Unit - Kill UTS_Dummy[UTS_Loop2]
              • Trigger - Turn on (This trigger)
              • -------- ---------- --------
              • Set UTS_Dummy[UTS_Loop2] = UTS_Dummy[UTS_Index]
              • Set UTS_Caster[UTS_Loop2] = UTS_Caster[UTS_Index]
              • Set UTS_Index = (UTS_Index - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • UTS_Index Equal to 0
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                  • Trigger - Turn off UTS Attack <gen>
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • Debug_Mode Equal to True
                    • Then - Actions
                      • Game - Display to (All players) the text: (String(UTS_Index))
                    • Else - Actions
                • Else - Actions
              • Custom script: exitwhen true
            • Else - Actions

  • UTS Garrison
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to UTS_Spell_Type[1]
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Target unit of ability being cast)) Equal to UTS_Scout_Tower
        • Then - Actions
          • For each (Integer UTS_Garrison_Integer) from 1 to UTS_Total_Towers, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Unit-type of (Triggering unit)) Equal to UTS_Unit_Type[UTS_Garrison_Integer]
                • Then - Actions
                  • Unit - Replace (Target unit of ability being cast) with a UTS_Tower_Type[UTS_Garrison_Integer] using The old unit's relative life and mana
                  • Unit - Remove (Triggering unit) from the game
                • Else - Actions
        • Else - Actions
          • Set Temp_loc = (Position of (Triggering unit))
          • Floating Text - Create floating text that reads I can't enter that. at Temp_loc with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
          • Floating Text - Change (Last created floating text): Disable permanence
          • Floating Text - Change the lifespan of (Last created floating text) to 2.00 seconds
          • Floating Text - Change the fading age of (Last created floating text) to 1.00 seconds
          • Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
          • Custom script: call RemoveLocation(udg_Temp_loc)
  • UTS Ungarrison
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to UTS_Spell_Type[2]
    • Actions
      • For each (Integer UTS_Ungarrison_Integer) from 1 to UTS_Total_Towers, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Unit-type of (Triggering unit)) Equal to UTS_Tower_Type[UTS_Ungarrison_Integer]
            • Then - Actions
              • For each (Integer UTS_Loop3) from 1 to UTS_Index, do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Triggering unit) Equal to UTS_Caster[UTS_Loop3]
                    • Then - Actions
                      • Set Temp_loc = ((Position of UTS_Caster[UTS_Loop3]) offset by (Collision Size of (Triggering unit)) towards (Random angle) degrees)
                      • -------- ---------------------------------------------------------------- --------
                      • Unit - Replace (Triggering unit) with a UTS_Scout_Tower using The old unit's relative life and mana
                      • Unit - Create 1 UTS_Unit_Type[UTS_Ungarrison_Integer] for (Owner of UTS_Caster[UTS_Loop3]) at Temp_loc facing Default building facing degrees
                      • Unit - Set life of (Last created unit) to (Percentage life of UTS_Caster[UTS_Loop3])%
                      • -------- ---------------------------------------------------------------- --------
                      • Custom script: call RemoveLocation(udg_Temp_loc)
                      • -------- ---------------------------------------------------------------- --------
                      • Trigger - Turn off (This trigger)
                      • Unit - Remove UTS_Dummy[UTS_Loop3] from the game
                      • Trigger - Turn on (This trigger)
                      • -------- ---------------------------------------------------------------- --------
                      • Set UTS_Dummy[UTS_Loop3] = UTS_Dummy[UTS_Index]
                      • Set UTS_Caster[UTS_Loop3] = UTS_Caster[UTS_Index]
                      • Set UTS_Index = (UTS_Index - 1)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • Debug_Mode Equal to True
                        • Then - Actions
                          • Game - Display to (All players) the text: (String(UTS_Index))
                        • Else - Actions
                      • Custom script: exitwhen true
                    • Else - Actions
            • Else - Actions
Previews
Contents

Unit on Tower v1.3 (Map)

Reviews
Wrda
Your UTS Start trigger after the description is outdated (in the map it's totally fine). UTS_Caster_Loc doesn't need to be an array, but it doesn't hurt anything so that's fine. It's a modest system, with potential to be expanded. Can take...

Wrda

Spell Reviewer
Level 28
Joined
Nov 18, 2012
Messages
2,011
Your Tower Cast trigger isn't acceptable, if a user wants to use way more towers, he will have to touch that trigger despite not being the configurable trigger. Use a loop to figure out which tower type entered the game/finished upgrade, and only then you create a new instance (the Tower_Index = Tower_Index + 1 part). Dummy flying height value should be an array variable configured in Tower INI trigger, where the indexes correspond to the tower type. Tower_Mui variable isn't needed at all, use Tower_Index for it instead. Tower_Dummy_FlyingHeight doesn't need to be an array.
In Tower Loop, once again, remove those "or multiple" conditions and check the unit type with a loop, so essentially you'd have 2 loops. You can use
  • Custom script: exitwhen true
to exit the loop early (do it on the outmost loop, not the inner one! Also use another integer variable such as Tower_Loop2).

Same thing for the Tower Death trigger. In addition, the deindexing is failing, the unit with the max index won't be looped over. See Visualize: Dynamic Indexing to understand what I'm talking about.
It would be better if you had a prefix such as UTS_Mui than Tower_Mui (Unit Tower System - can be another name), it's a quite common word and possible to clash with other eventual spells/system the user has. I don't see the usefulness of having a debug part. Seems like only a creator of the system would need.

This system could be expanded further one day, such as removing these "finished upgrade/unit enters the map" and have a trigger to register the units the user want to attach to the tower by having variables acting as parameters. Then users could have units go "inside" towers, and able to go out.
Right now it has some issues, and is somewhat simple.


PS: In the example the warlock tower has rock spires model.
 

Wrda

Spell Reviewer
Level 28
Joined
Nov 18, 2012
Messages
2,011
  • UTS Attack
    • Events
      • Unit - A unit Is attacked
    • Conditions
    • Actions
      • For each (Integer UTS_Loop) from 1 to UTS_Mui, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • UTS_Index Equal to 0
            • Then - Actions
              • Custom script: exitwhen true
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Attacking unit) Equal to UTS_Caster[UTS_Loop]
            • Then - Actions
              • Set VariableSet UTS_Victim[UTS_Loop] = (Triggering unit)
              • Unit - Make UTS_Dummy[UTS_Loop] face UTS_Victim[UTS_Loop] over 0.10 seconds
              • Animation - Play UTS_Dummy[UTS_Loop]'s attack animation
              • Animation - Queue UTS_Dummy[UTS_Loop]'s stand animation
            • Else - Actions
When UTS_Index is 0, the trigger gets disabled, so you no longer need to check that and "exitwhen true". I said that because before you needed to check the valid tower types and then the unit in question.
edit2: I removed UTS_Mui and used UTS_Index, but reverted back to using UTS_MUI because the deindexing failed when I used UTS_Index. Im sure I did something wrong lol
Yes, because then the max index was decreased by 1, while there's still the unit at max index + 1 that you lost reference to :p
That's why on the deindexing one has to "swap" the current index with the max index, before lowering it.
Besides, the death trigger is called again when Unit - Kill UTS_Dummy[UTS_Loop2] happens. It stops execution at that point, and then fires the trigger, finishing running it, and then returning to the previous point and continue. So UTS_Loop2 gets overwritten and screws up. Need to turn off the trigger before killing the dummy, and then turn it on.
So it should be like this:
  • UTS Death
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • For each (Integer UTS_Loop2) from 1 to UTS_Index, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • UTS_Caster[UTS_Loop2] Equal to (Triggering unit)
            • Then - Actions
              • Animation - Change UTS_Dummy[UTS_Loop2] flying height to 0.00 at 0.00
              • Trigger - Turn off (This trigger)
              • Unit - Kill UTS_Dummy[UTS_Loop2]
              • Trigger - Turn on (This trigger)
              • Set VariableSet UTS_Caster[UTS_Loop2] = UTS_Caster[UTS_Index]
              • Set VariableSet UTS_Dummy[UTS_Loop2] = UTS_Dummy[UTS_Index]
              • Set VariableSet UTS_Index = (UTS_Index - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • UTS_Index Equal to 0
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                  • Trigger - Turn off UTS Attack <gen>
                • Else - Actions
              • Custom script: exitwhen true
            • Else - Actions
Now you can replace UTS_Mui with UTS_Index everywhere ;)
UTS_Caster_Loc doesn't need to be an array at all, since you're not using on multiple triggers, same with UTS_Victim, can just use the triggering unit directly in this last case. Seems to me that you no longer need UTS_Loop2 too, only reason to use that is if there were nested loops (UTS_Loop2 loop inside a UTS_Loop loop).
 
Level 6
Joined
Jun 18, 2024
Messages
28
thats it thank you :thumbs_up: and the suggestion that unit should be able to get in the tower is a good idea. I will try implementing that soon

edit: implemented the idea it turned out nicely I think

edit2: I accidentally removed my previous post LOL I just wanted to delete the map file
 
Last edited:
Top