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

Simple Threat System v1.2

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
This is a system I made for my boss fight maps.

It's function is, to give every units within a preset unit group a threat value, that will makes every hostile unit to attack only the units with the highest threat value, within their check range. This system works similar to World of Warcraft's Threat System and are inspired by it.

This is just the core of the system, if you want to adds/increase/decrease threat value on certain units, you can do so through editing "TS_G_Value[Custom Value of Unit]". Several examples of gaining or losing threat is included.

Requirements:
- Bribe's Unit Indexer (Included)


Credits:
-Bribe for it's Unit Indexer(From his Damage Engine)
-Defskull for helping me in some script difficult
-Tank-Commander for his comments
-CoLd Bon3 for the idea of different displays
-Magtheridon96 for spotting a leak

Changelog:
v1 - Initial Rush Release
v1.1 - Fixed the Script a bit
- Uploaded a in-game Screenshoot
- All unnecessary imports, scripts are removed
- Made more things configurable(Thanks to Tank-Commander)
v1.2 - Included '-chgdisplay' command, to alter the threat display
- Some fixes made to smooth up the system a bit

Keywords:
threat, aggro, system, world of warcraft, boss fight, boss encounter, tank, boss, fight, encounter
Contents

Just another Warcraft III map (Map)

Reviews
12th Dec 2015 IcemanBo: Too long as NeedsFix. Rejected. 21:14, 26th Jul 2012 Magtheridon96: In the init trigger, wouldn't it be better to set your system's group to the units on the map that are heroes instead of picking all the heroes and...

Moderator

M

Moderator

12th Dec 2015
IcemanBo: Too long as NeedsFix. Rejected.

21:14, 26th Jul 2012
Magtheridon96:

  • In the init trigger, wouldn't it be better to set your system's group to the units on the map that are heroes instead of picking all the heroes and adding them to the group? ;p
  • You could store things like (Last created floating text) into variables to improve performance
  • In the looping trigger, you're doing two group enumerations on the same group one directly after the other. You should merge them to one. Group enumerations can be very costly sometimes. Just place the code of the second one directly after the code of the first one.
  • I would suggest making it easier for the user to control threat.
    Right now, modifying the variable is very ugly :/
    Either change the name or add some functionality like this:
    • Set AddThreatUnit = Some unit
    • Set AddThreatValue = 30
    • Trigger - Execute AddThreat <gen> (ignoring conditions)
    • Set SetThreatUnit = Some unit
    • Set SetThreatValue = 0
    • Trigger - Execute SetThreat <gen> (ignoring conditions)
    Of course, you may only need one of them since you can set threat by adding -currentThreat, or you can add threat by setting the threat to currentThread + setValue.
 
Well I'll be the first to comment on the triggering:


  • Threat System Inilt
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Unit Group - Pick every unit in Heroes and do (Actions)
        • Loop - Actions
          • Set TS_G_tempInt1 = (Custom value of (Picked unit))
          • Floating Text - Create floating text that reads (String(TS_G_Value[TS_G_tempInt1])) at (Position of (Picked unit)) with Z offset 0.00, using font size 8.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
          • Set TS_G_FT[TS_G_tempInt1] = (Last created floating text)
      • Trigger - Turn on Threat System FT Loop <gen>
  • Threat System Focus
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Set TS_G_TempInt[0] = 0
      • Set TS_G_ThreatHolder1 = TS_G_ThreatHolder
      • Unit Group - Pick every unit in Heroes and do (Actions)
        • Loop - Actions
          • Set TS_G_TempInt[0] = (TS_G_TempInt[0] + 1)
          • Set TS_G_Unit[TS_G_TempInt[0]] = (Picked unit)
          • Set TS_G_TempInt1[TS_G_TempInt[0]] = TS_G_Value[(Custom value of TS_G_Unit[TS_G_TempInt[0]])]
          • For each (Integer B) from 1 to TS_G_TempInt[0], do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • TS_G_TempInt1[(Integer B)] Greater than or equal to TS_G_TempIntGreatest
                • Then - Actions
                  • Set TS_G_TempIntGreatest = TS_G_TempInt1[(Integer B)]
                  • Set TS_G_ThreatHolder = TS_G_Unit[(Integer B)]
                • Else - Actions
      • Set TS_G_TempPos[0] = (Position of TS_G_ThreatHolder)
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 800.00 of TS_G_TempPos[0]) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) belongs to an enemy of (Owner of TS_G_ThreatHolder)) Equal to True
            • Then - Actions
              • Unit - Order (Picked unit) to Attack TS_G_ThreatHolder
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • TS_G_ThreatHolder Not equal to TS_G_ThreatHolder1
                • Then - Actions
                  • Set TS_G_TempPos[1] = (Position of (Picked unit))
                  • Floating Text - Create floating text that reads Change Target! at TS_G_TempPos[1] with Z offset 0.00, using font size 8.00, color (100.00%, 0.00%, 0.00%), and 0.00% transparency
                  • Floating Text - Change (Last created floating text): Disable permanence
                  • Floating Text - Set the velocity of (Last created floating text) to 25.00 towards 90.00 degrees
                  • Floating Text - Change the fading age of (Last created floating text) to 2.15 seconds
                  • Floating Text - Change the lifespan of (Last created floating text) to 3.00 seconds
                  • Custom script: call RemoveLocation(udg_TS_G_TempPos[1])
                • Else - Actions
            • Else - Actions
          • Custom script: call RemoveLocation(udg_TS_G_TempPos[0])
  • Threat System FT Loop
    • Events
      • Time - Every 0.06 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in Heroes and do (Actions)
        • Loop - Actions
          • Set TS_G_tempInt1 = (Custom value of (Picked unit))
          • Floating Text - Change the position of TS_G_FT[TS_G_tempInt1] to (Picked unit) with Z offset 0.00
          • Floating Text - Change text of TS_G_FT[TS_G_tempInt1] to (String(TS_G_Value[TS_G_tempInt1])) using font size 8.00

  • Unit Indexer
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Custom script: call ExecuteFunc("InitializeUnitIndexer")
      • Custom script: endfunction
      • Custom script: function IndexUnit takes nothing returns boolean
      • Custom script: local integer pdex = udg_UDex
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • UnitIndexerEnabled Equal to True
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • UDexRecycle Equal to 0
            • Then - Actions
              • Set UDex = (UDexGen + 1)
              • Set UDexGen = UDex
            • Else - Actions
              • Set UDex = UDexRecycle
              • Set UDexRecycle = UDexNext[UDex]
          • Set UDexUnits[UDex] = (Matching unit)
          • Unit - Set the custom value of UDexUnits[UDex] to UDex
          • Set UDexPrev[UDexNext[0]] = UDex
          • Set UDexNext[UDex] = UDexNext[0]
          • Set UDexNext[0] = UDex
          • Set UnitIndexEvent = 0.00
          • Set UnitIndexEvent = 1.00
          • Set UnitIndexEvent = 0.00
          • Custom script: set udg_UDex = pdex
        • Else - Actions
      • Custom script: return false
      • Custom script: endfunction
      • Custom script: function IndexNewUnit takes nothing returns boolean
      • Custom script: local integer pdex = udg_UDex
      • Custom script: local integer ndex
      • Set UDexWasted = (UDexWasted + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • UDexWasted Equal to 15
        • Then - Actions
          • Set UDexWasted = 0
          • Set UDex = UDexNext[0]
          • Custom script: loop
          • Custom script: exitwhen udg_UDex == 0
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Custom value of UDexUnits[UDex]) Equal to 0
            • Then - Actions
              • Custom script: set ndex = udg_UDexNext[udg_UDex]
              • Custom script: set udg_UDexNext[udg_UDexPrev[udg_UDex]] = ndex
              • Custom script: set udg_UDexPrev[ndex] = udg_UDexPrev[udg_UDex]
              • Set UDexPrev[UDex] = 0
              • Set UnitIndexEvent = 2.00
              • Set UnitIndexEvent = 0.00
              • Set UDexUnits[UDex] = No unit
              • Set UDexNext[UDex] = UDexRecycle
              • Set UDexRecycle = UDex
              • Custom script: set udg_UDex = ndex
            • Else - Actions
              • Set UDex = UDexNext[UDex]
          • Custom script: endloop
          • Custom script: set udg_UDex = pdex
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Custom value of (Matching unit)) Equal to 0
        • Then - Actions
          • Custom script: call IndexUnit()
        • Else - Actions
      • Custom script: return false
      • Custom script: endfunction
      • Custom script: function InitializeUnitIndexer takes nothing returns nothing
      • Custom script: local integer i = 0
      • Custom script: local region re = CreateRegion()
      • Custom script: local rect r = GetWorldBounds()
      • Set UnitIndexerEnabled = True
      • Custom script: call RegionAddRect(re, r)
      • Custom script: call TriggerRegisterEnterRegion(CreateTrigger(), re, Filter(function IndexNewUnit))
      • Custom script: call RemoveRect(r)
      • Custom script: set re = null
      • Custom script: set r = null
      • Custom script: loop
      • Custom script: call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, Player(i), Filter(function IndexUnit))
      • Custom script: set i = i + 1
      • Custom script: exitwhen i == 16
      • Custom script: endloop
      • Set UnitIndexEvent = 3.00
      • Set UnitIndexEvent = 0.00


I'm assuming UnitIndex is not your work (since it's not done in the same style as everything else/where it should be) So I won't comment on that in particular.

While simple a lot of things in this could be configurable, for example

Font Size
Alert Range
Floating text start Z offset
etc.

Additionally you only need one loop trigger not two, consulting the "Delayed MUI Spells Without Waits" section of http://www.hiveworkshop.com/forums/trigger-gui-editor-tutorials-279/mui-triggers-waits-218354/ you can achieve this by setting the delay variable (as explained in there) to a number which will create the exact same gap between the running instances (assuming you reset the counter each time)

If you keep them split up you could turn off your loop triggers when they are not in use (which should be done anyway tbf) when there's no floating text or units to apply floating text to. and then turn it back on when a unit.

Additional notes:

Why all the custom imports? I mean there's a lot in this for no real reason
Why all the custom units? which never get used?

Also when I tested it, it didn't even actually work?
 
Level 14
Joined
Aug 8, 2010
Messages
1,022
Am, i am lazy to look at the code, so i will just give some suggestions.
It is kinda stupid for those numbers to be whatever they want. Make the minimum thread 0% and the max 100%. When a unit reaches 100% thread, the previous 100% thread unit should immediately get 10-20 thread lower (for example) because the units will change targets all the time (if 2 or more units manage to get to 100% thread). And, you order the new 100% thread target to get attacked. Targets that have lower than 100% thread should reduce thread over time (because if there is a new 100% thread unit, and the previous is left to 80%, it will hit 1 time and it will be again at 100% thread, that's why there should be over time reduction, only of the units below 100% thread tough). And if a unit with lower than 100% thread manages to get to 100% despite the thread reduction over time, the cycle begins again.

Spells should also give thread. For example, i casted Holy Light at a target and from 140 thread i dropped to 36. Exactly the opposite should happen. Healers must be focused. Well, you should also create a way to give different amounts of thread for different abilities. But that is not very needed.

EDIT : Another two things i saw. First, the system orders all units to target a high-thread unit, no matter what team the ordered units are, enemies or friends. Well, it's good this way, but it would be better if you can switch this option on and off in the trigger. Secondly, there should be an option INGAME that makes you choose weather or not your hero gets ordered by the thread trigger. It will be annoying if you wanna kill one unit but a second one has more thread...

Those are just suggestions. I think that this system will be a real BANGARANG if you make the changes i listed.

Good job!!! Keep up the good work! I like it! :]
 
Level 33
Joined
Mar 27, 2008
Messages
8,035
Those are just suggestions. I think that this system will be a real BANGARANG if you make the changes i listed.
Skrillex fans alert ;p

But I do agree on spells also should give threat (not thread), either an increase of threat or decrease of threat.

Hey, why healer should be focused ?
It's not fair :(

I think when it cast Healing-based spell or support-type, it will have a decrease of threat because they are not the unit that is supposed to tank, though sometimes they are a tanker, depends on the spells/situations.
 
Level 14
Joined
Aug 8, 2010
Messages
1,022
I am not a huge fan of Skrillex... i just listen to his songs, along with other Dubstep and D'n'B songs... never mind, this is off-topic.

Thanks for telling me it's threaT, not threaD.

The healer should be focused because he can heal everyone, including himself, so basically, all units can NOT die. The only way is to kill the healer. However, tanks should be tanks...
Well, you should also create a way to give different amounts of thread for different abilities.
This is the solution.
 
Level 10
Joined
Mar 19, 2010
Messages
622
The threat generations in the map is merely examples, it just shows how the threat generation works, as well a some idea for people to look at it.

@CoLd Bon3: The suggestions is nice, I'll see what I can do.

Why the healer is focused? It's just an example.

@Magtheridon96: The generation are just examples. Thanks for the suggestion, I'll improve it :D
 
Top