1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still haven't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. Let your favorite entries duke it out in the 15th Techtree Contest Poll.
    Dismiss Notice
  5. Weave light to take you to your highest hopes - the 6th Special Effect Contest is here!
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Zwiebelchen's Threat System 2.7

Submitted by Zwiebelchen
This bundle is marked as approved. It works and satisfies the submission rules.
What is a threat system?
Basicly, it's a system that takes over Mob AI. The unit that dealt the most damage to the creep will be the one that gets attacked.
Although that is only half the truth, it should be enough to get the idea.

If you ever played World of Warcraft (as a mapper, you should have), chances are you know what a threat system does.
And this is an almost perfect replica of it.


Requirements:
- vJass preprocessor

What is different from this to other systems:
- First of all, this system is almost (if not completely) 100% fail-safe. It does checks on killed AND removed units and clears them automaticly.

- Second, it features a unique camp squad functionality, which ensures that units that are preplaced in camps will always attack and return together. If units return, they will be rendered invulnerable until they reach their original camp position again. If they can not reach their camping position within a certain duration, they will get instantly teleported back.
Like this, there is almost no more kiting or bug-abusing possible, as it was with other systems.

- Third: It does not block other Spellcasting systems. The system will only give orders to units, if the unit either has no order (i.e. auto-engage) or an "attack" order. If you want the unit to use a spell instead of attacking, you can do so whenever you want without having to fear interference of the system.
In fact, there is a special function provided so that people can create their own Spell-AI directly in a custom trigger

- Fourth: It provides a lot of useful functions and Getters (Like ApplyHealThreat or GetCombatState), to make triggering spells even more easy.

- Fifth: It is, by far, the fastest and most flexible threat system out there. I completely remastered the system from the last version and the entire script (except for certain enumerations that can not be avoided) is now O(1) complexity.


Version history:
2.7
- Fixed a bug that sometimes did not properly render units in-combat if pulled again right after returning to camp position

2.6
- Added a new function: ZTS_GetCombatTime, which returns the time an npc unit is currently in combat; returns 0 if the unit is currently out of combat or returning to camp position; does not work on player units

2.5
- Added a new boolean to the ZTS_AddThreatUnit command that determines wether the added unit shall be added to already fighting Creep Camps or only to non-fighting Creep Camps - this is interesting when you create encounters that summon units as you usually don't want those summoned units to create their own Creep Camp but want them to be added to the Boss' Creep Camp
- Fixed a small bug that sometimes caused linked Creep Camps

2.4
- Fixed a bug sometimes rendering units permanently invulnerable, when registering a unit in close range to currently retreating units

2.3
- Changed TriggerActions of dynamic triggers to TriggerConditions, to avoid nasty action leak
- Fixed GetThreatUnitAmount (did not return the correct value)

2.2b
- fixed a small logic bug with GetThreatUnitAmount and GetThreatUnitPosition

2.2
- Now uses "smart" order instead of "attack" to issue attack orders ... it turned out that the "smart" order returns false if the unit can not reach the target (for example when rooted) - weird, as it doesn't work for "attack" for some reason
- because of that, the AddRootAbility function and the Range Setter and Getters were removed, as they have become obsolete

2.1b
- fixed a small logical bug with GetCombatState sometimes returning a false positive

2.1
- rebuilt Update function to avoid some useless enumerations - depending on the number of PlayerUnits registered, the system should now be MULTIPLE TIMES faster - As a side effect, I could also remove some useless variables

2.0
- Initial release

Comments & Discussion:

Why hashtables instead of global arrays and structs?
- hashtables are not limited in terms of max size, unlike and array of structs with a unit array, which reaches the 8000 limit very fast ... this was basicly the most important point on that decision
- hashtables are more flexible and easier to use (Flush functions, etc.)
- hashtables were benchmarked to be only 60-80% slower than getting UnitUserData alone

Where is the sort function?
- version 2.0 and higher does not use sorting anymore; instead, when threat is applied to a unit, it uses an insertion method to keep the order of the list

What is new compared to pre 2.0 versions?
- Aside from the fact that the system now is a dozen times faster than before, I also improved the AI by using the "smart" instead of "attack" order. It turned out that - in a weird way - "smart" is indeed smarter than other orders, as it returns false if the unit can't reach the target (i.e. because of root)
- There is now a way to directly get an Order event by the threat system, to make creating spell-AI easier.

Does it matter how many units are registered to the system at the same time?
- In terms of speed, no; it only affects memory usage, but that should not have an impact on game performance at all, even with tousands of units registered - only the number of currently fighting units affects runtime

I still do not really understand how to use the system...
- just check the demo map and you'll get the idea

Keywords:
threat, aggro, wow, world of warcraft
Contents

Threat System v2.7 (Map)

Reviews
Moderator
17:56, 17th Jan 2010 TriggerHappy: Very good, and you know what my suggestions are. This can be approved in it's current state, though.
  1. Zwiebelchen

    Zwiebelchen

    Joined:
    Sep 17, 2009
    Messages:
    6,968
    Resources:
    12
    Models:
    5
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    JASS:
    4
    Resources:
    12
    If you got Newgen and installed the newest JASS-helper, make sure you follow the instructions properly:

    - Create a new trigger called ZTS
    - Convert it to custom text
    - replace everything inside this trigger with the script
    - Save the map and see if it compiles

    If you still encounter a problem even after following those steps, just send me the map and I will look over it and see what I can do.

    PS: Test map doesn't work in newgen. It's broken due to the outdated editor. Make sure to manually run the game and test the map.
     
  2. Sunchips

    Sunchips

    Joined:
    Jul 23, 2009
    Messages:
    870
    Resources:
    123
    Models:
    112
    Icons:
    4
    Packs:
    7
    Resources:
    123
    Uhm I tried saving it again and now somehow it magically works to start the map, even throught test map. Thx for the help tho.
     
  3. gorillabull

    gorillabull

    Joined:
    Jul 17, 2011
    Messages:
    1,368
    Resources:
    2
    Spells:
    2
    Resources:
    2
    woah epic system and its written almost purely in jass :goblin_yeah:
     
  4. Zwiebelchen

    Zwiebelchen

    Joined:
    Sep 17, 2009
    Messages:
    6,968
    Resources:
    12
    Models:
    5
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    JASS:
    4
    Resources:
    12
    Updated to 2.6, adding a new function ZTS_GetCombatTime, which returns the time an npc unit is currently in combat (update interval matches the update interval system constant due to performance reasons).

    This function is useful when triggering your own spell-AI.
    For example, you can use it to make your unit fire spells on random time intervals or create some kind of "enrage" type of spell that triggers after a certain time in combat.
     
  5. Vestra

    Vestra

    Joined:
    Oct 9, 2011
    Messages:
    1,446
    Resources:
    0
    Resources:
    0
    clearly a mechanic for the new gaias boss.
     
  6. Nosticus

    Nosticus

    Joined:
    Jan 10, 2012
    Messages:
    31
    Resources:
    0
    Resources:
    0
    Is there anyway to make an AOE "threat aura" with this? and also how would one go about making a unit gain more threat with a passive ability?
     
  7. Zwiebelchen

    Zwiebelchen

    Joined:
    Sep 17, 2009
    Messages:
    6,968
    Resources:
    12
    Models:
    5
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    JASS:
    4
    Resources:
    12
    Both is possible and easy to make.

    For the first, simply create a periodic trigger applying x threat to all units within range every y seconds (optionally, you can create a condition that checks for the debuff aswell).

    For the latter, simply use a damage detection engine and apply x threat for every point of damage dealt when the passive ability is on the unit. You can check the demo map for this one.
     
  8. Nosticus

    Nosticus

    Joined:
    Jan 10, 2012
    Messages:
    31
    Resources:
    0
    Resources:
    0
    Figured it out, Awesome thanks :D
     
  9. Nosticus

    Nosticus

    Joined:
    Jan 10, 2012
    Messages:
    31
    Resources:
    0
    Resources:
    0
    Actually nevermind T_T still doesn't work, does your system not work with Neutral hostile? I have a trigger set to call ZTS_ApplyHealThreat(GetEventDamageSource(),GetEventDamageSource(), 200, false, true) on attack and it no work :/
     
  10. Nosticus

    Nosticus

    Joined:
    Jan 10, 2012
    Messages:
    31
    Resources:
    0
    Resources:
    0
    Also another strange thing, is my trigger doesn't work on units that were in game at init, until they have died and are respawned by my system...mind = blown or are spawned by a trigger, which is weird because how are they added to threat table units after respawn or are they xD?
     
  11. Zwiebelchen

    Zwiebelchen

    Joined:
    Sep 17, 2009
    Messages:
    6,968
    Resources:
    12
    Models:
    5
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    JASS:
    4
    Resources:
    12
    All neutral hostile units need to be registered to the system. ApplyHealThreat only works on player units registered to the system.
    The system works fine with neutral hostile.

    This is because dead units get cleared from the system. You need to register those units again upon revival or when created.
     
  12. Nosticus

    Nosticus

    Joined:
    Jan 10, 2012
    Messages:
    31
    Resources:
    0
    Resources:
    0
    Ok, so I'm just going to post my triggers, since nothing else is working...
    Trigger 1: Init
    Events
    Map initialization
    Conditions
    Actions
    Player - Disable sleeping for all creeps
    -------- Add units to damage detection trigger --------
    Unit Group - Pick every unit in (Units owned by Neutral Hostile) and do (Trigger - Add to DamageDetect <gen> the event (Unit - (Picked unit) Takes damage))
    Unit Group - Pick every unit in (Units owned by Player 8 (Pink)) and do (Trigger - Add to DamageDetect <gen> the event (Unit - (Picked unit) Takes damage))
    -------- Setting up of all the participating units in the threat system --------
    -------- Units where AI shall be taken over by the script have to be registered with AddThreatUnit --------
    -------- Units that shall appear on ThreatUnit's threat lists have to be registered with AddPlayerUnit --------
    Unit Group - Pick every unit in (Units owned by Player 9 (Gray)) and do (Custom script: call ZTS_AddPlayerUnit( GetEnumUnit() ))
    Unit Group - Pick every unit in (Units owned by Player 11 (Dark Green)) and do (Custom script: call ZTS_AddPlayerUnit( GetEnumUnit() ))
    Unit Group - Pick every unit in (Units owned by Neutral Hostile) and do (Custom script: call ZTS_AddThreatUnit( GetEnumUnit(), false ))
    Unit Group - Pick every unit in (Units owned by Player 8 (Pink)) and do (Custom script: call ZTS_AddThreatUnit( GetEnumUnit(), false ))



    Trigger 2:DamageDetect
    Events
    Conditions
    Actions
    -------- A simple damage detection function used to add threat in amount of damage dealt --------
    Custom script: call ZTS_ModifyThreat(GetEventDamageSource(), GetTriggerUnit(), GetEventDamage(), true)


    Trigger 3:Will of the Archpaladin
    Events
    Game - DamageEvent becomes Equal to 1.00
    Conditions
    (Level of Will of the Archpaladin (Paladin) Evasion for DamageEventSource) Equal to 1
    Actions
    Custom script: call ZTS_ApplyHealThreat(GetEventDamageSource(),GetEventDamageSource(), 400, false, true)
    Game - Display to (All players) the text: Will of the Archpal...


    Ok, so why does your system not work for me? units that are already made before the game is launched do NOT work, until they are re-spawned then they do if they are player pink, not Neutral Hostile, which is opposite of what you are saying.
     
  13. Zwiebelchen

    Zwiebelchen

    Joined:
    Sep 17, 2009
    Messages:
    6,968
    Resources:
    12
    Models:
    5
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    JASS:
    4
    Resources:
    12
    From just your triggers, I can not find a mistake. Post more, as there is definitely no bug with the system (I have used it for years now without any issues)!

    Remember that the units owned by pink and neutral hostile will only react to gray and dark green units this way. The threat system will simply ignore all other players.
    Also remember that any units of gray and dark green MUST be registered again after revival/creation/recreation.
    Same goes for pink and neutral hostile.
     
  14. Vlad727

    Vlad727

    Joined:
    Oct 8, 2010
    Messages:
    132
    Resources:
    0
    Resources:
    0
    Heya Zwiebelchen,
    I was wondering the following things:

    1. If I make a skill that applies a buff to the caster, what type of script call do I need to generate threat for the caster (static amount) to all nearby enemies?

    2. Is it possible that edit the threat generation rate for specific hero's
    Like a tanking class generates 125% threat while others have 100%?
    This is just for their basic attacks.

    3. Is it possible to make an effect (exclamation mark) if the target changes target.
    so players have a visual warning if they pull a enemy.

    4. this is the script call you used for the basic heal testing skill
    • call ZTS_ApplyHealThreat( GetTriggerUnit(), GetSpellTargetUnit(), 100*GetUnitAbilityLevel(GetTriggerUnit(), GetSpellAbilityId()), true, true)

    I use stat based skills that do not lvl, so would it then be
    GetHeroAtributeStr ?
    if not what is the proper syntax?

    I really like the way your system functions, and I am sadly new to Jass and ruby, having only done the basic python isnt helping much.

    So could you assist me.
     
  15. Zwiebelchen

    Zwiebelchen

    Joined:
    Sep 17, 2009
    Messages:
    6,968
    Resources:
    12
    Models:
    5
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    JASS:
    4
    Resources:
    12
    You can simply enumerate all enemies within X range and then use ZTS_ModifyThreat on each one.

    You can also use the ZTS_ApplyHealThreat, however, this mechanic will split the threat over all units that are currently aggroed and is not based on range - it will use all currently aggroed units. Which means that if a spell creates 500 threat and there's 5 units around, all units will get a total of 100 threat applied.

    You probably want the first solution.

    Yes, just use a damage detection system and if the hero unit type is XYZ, apply 1.25 points of threat per damage instead of 1 point of threat per damage.

    You can basicly compare if the threat slot unit at slot 1 before and after applying threat is not the same. If it is, then do nothing, if it isn't, display the exclamation mark.

    I'd say write a small snippet for this, so you can use a one-liner when you need to apply threat.

    You can use GetHeroStr(GetTriggerUnit()).
     
  16. Vlad727

    Vlad727

    Joined:
    Oct 8, 2010
    Messages:
    132
    Resources:
    0
    Resources:
    0
    Thx man, this is exactly what I needed (^w^) thx again
     
  17. Sunchips

    Sunchips

    Joined:
    Jul 23, 2009
    Messages:
    870
    Resources:
    123
    Models:
    112
    Icons:
    4
    Packs:
    7
    Resources:
    123
    Edit: I fixed the problem I had.

    However I noticed something else. If I run away from a unit so that they start running back to their camp position and I then beat them to the destination so that they start attacking me right when they have returned they never count as out of combat and the threat system does no longer work for that unit. This means the unit will chase me indefinately but if I attack him he will then return to his camp position and once again count in the threat system. I can't find a logic reason to why this happens, does anyone know what might be the cause here?
     
    Last edited: Jan 7, 2015
  18. Zwiebelchen

    Zwiebelchen

    Joined:
    Sep 17, 2009
    Messages:
    6,968
    Resources:
    12
    Models:
    5
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    JASS:
    4
    Resources:
    12
    All I can say is that it can't be a bug with the actual system, as I have been using it for years and never had this problem. For reference, see the demo map. It works properly there.

    I think there is some other script interfering here. Is there a script running in your map that might unregister the units that leave combat? Remember: once added to the system, you don't need to remove those units again; there is no periodic trigger running for out-of-combat units, so no performance hit at all!
     
  19. Sunchips

    Sunchips

    Joined:
    Jul 23, 2009
    Messages:
    870
    Resources:
    123
    Models:
    112
    Icons:
    4
    Packs:
    7
    Resources:
    123
    Thanks for the reply. It does work like it should in the testmap like you said but I tried deleting all triggers in my map except the ZTS and one trigger to add the units to the threat list as showed in the picture.

    Even in this state this problem occurs in my map and I'm really not sure what I have set wrong :/
    I tried making a debug trigger to get the combatstate of a unit and show it over their head every 0.5 seconds. When the unit was standing in its camp position it was registered as out of combat as it should be. When I aggro the unit it says it's in combat as it should be. But when I get too far away he returns to his camping position and then if I aggro it right when it comes back it says the unit is still out of combat even though it is hitting my unit. But if I modify the threat of my unit towards the enemy unit it will be registered in combat.

    EDIT: I noticed this bug exists in your test map too. But it only occurs if I do not deal damage to the enemy unit and if the enemy unit is the only one in the camp.

    EDIT Again: I noticed this bug even exists in your map Gaias Retaliation. I tried aggroing a wolf without damaging it. I then lured it away so that it starts returning. I then beat it back to its camp location instantly aggroing it once it returned. I made sure to not deal any damage to it and then I could lure it away out of its return range. This is not a common occurence but I know one instance that may cause this: One player aggros a creep and runs away so it starts returning. Another player is following the first player but is so far behind that it aggros the creep just as it had returned from chasing player one. Now the second player is followed by the creep until it attacks the creep.

    Picture
    [​IMG]
     

    Attached Files:

    Last edited: Jan 8, 2015
  20. Zwiebelchen

    Zwiebelchen

    Joined:
    Sep 17, 2009
    Messages:
    6,968
    Resources:
    12
    Models:
    5
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    JASS:
    4
    Resources:
    12
    I'll investigate that. I have an idea what could be the cause for that... I think the event that usually makes the unit enter combat fires too early.

    --> unit returns and turns invulnerable; is still considered retreating and not truly out of combat
    --> unit gets unpaused
    --> player enters range again; WC3 AI issues an order to it
    --> event that renders unit in-combat fires, but doesn't do anything as it still hasn't properly left combat from the previous pull
    --> unit is officially out of combat again now after the initial pull, even though it's already attacking

    If that is indeed the problem, it's an easy fix; I'll upload a fixed version in several hours.