threat, aggro, system, world of warcraft, boss fight, boss encounter, tank, boss, fight, encounter
Type:
System
Category:
GUI / Triggers
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
Rating - 2.00 (1 vote)
(Hover and click)
Moderator Comments
Not Rated
21:14, 26th Jul 2012
Magtheridon96:
Comments
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:
Trigger actions
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.
All resources require INGAME screenshot.
I think this has been stated a lot of times so far.
__________________
Apheraz Lucent and -Grendel will forever live in my memory, two extraordinary persons taken away from our world before their time.
And so i dedicate my signature to them, a small sign of memory that will forever remain on my profile, for as long as it exists.
I am sad it's all i can do for them now and i hope i never did something to bring them anything but joy in their life.
World is a cruel place, but it was a better place with both of you in it. Miss you both.
The screenshot for this system looks threatening enough, suits its name in an epic way.
Seriously, put a decent screenshot, if it's a system at least show the system is in action.
Well I'll be the first to comment on the triggering:
Triggers
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])
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
UnitIndexer
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 MUI Triggers with Waits 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?
This can easily be abused for the fact that not all units are reachable, some could be behind walls. So the units attacking would easily get stuck trying to attack an unreachable target.
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.
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.
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...
Quote:
Originally Posted by CoLd Bon3
Well, you should also create a way to give different amounts of thread for different abilities.
Shouldn't the threat go to 0 after some time or when another target is picked? Cause if this gets imported in a longer map, the threat numbers could go really high.