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

Threat System

Status
Not open for further replies.
Level 1
Joined
Nov 13, 2015
Messages
2
Hi, Is there any threat systems that are in GUI? Threat system is like "a unit deals the most damage on the enemy unit will make that enemy unit attacks that unit".
 
Level 3
Joined
Sep 21, 2013
Messages
36
oh, thank you. It seems hard for me to understand but I will figure it out.
Ok, here is explanation: In first trigger "Ini0" we create hashtable because we need to store data in double-dimensional array way. We pick hashtable because usual array of real values isn't enough complicated - it can provide only one index while hashtable offers you two indexes, they can be understood as tree-structure.

Next trigger is "Ini". There we just create any units and buildings for test purposes. I cannot preinsert units on "Map initialization" into the map because the normal way of appearing units in the game is when they sold or trained or created via triggers or etc. in game-time.
So the next trigger "Threat Roles giving" is waiting for appearing of units/buildings in the map via event-listening of
Code:
Unit - A unit enters (Playable map area)
and then it manages who is ThreatOwner (an unit which will attack selectively according to a threat-level) and who is Attacker (an unit which is supposed to be controlled by the player and ordered to attack the ThreatOwner), and fills the corresponding unit arrays with that units. Also, here is damage event "a unit takes damage" attaching to the "Damage_calc", so by this we can track when someone (Triggering unit in the trigger "Damage_calc") is taking damage and who is damaging (Damage Source-unit in the trigger) it, and amount of damage done (Damage Taken).

Next trig is "Damage calc" and this is the core of the mechanism. It starts with limited by ThreatOwner_index (it's represents a quantity of ThreatOwners in the map) loop with iterator A and inside that loop here is another one limited by Attacker_index with iterator B. So as we see further there are three if-blocks appears: two of them are under all loops. First if-block is searching for the pair of ThreatOwner and Attacker, then when all conditions are true - operation of addition happens and then here is saving of sum of damage done inside the hashtable at right indexes (they represent exact address to the sum of damage done by Attacker with index B to ThreatOwner[A]).
Code:
Set CurrentDamage = ((Load (Integer A) of (Integer B) from DoubledArray) + (Damage taken))
Hashtable - Save CurrentDamage as (Integer A) of (Integer B) in DoubledArray

Then time comes for second if-block where we define which of the sums of damage done to ThreatOwner[A] is bigger than others. There is mechanism of it: at the start of loop with iterator B (second loop) we have nullified values of variables:
Code:
Set ThreatIndex = 0
Set CurrentThreat = 0.00
then we checking via conditions
Code:
(Triggering unit) Equal to ThreatOwner[(Integer A)]
CurrentThreat Less than (Load (Integer A) of (Integer B) from DoubledArray)
that "is that who taking damage is certain tower that taking damage right now?"-check because we only want to change threat-defined attack for tower that getting damage now and not to change other towers attack-orders (this is why we have condition of "ThreatIndex != 0" in third if-block, because default value (at the start of second loop) of ThreatIndex is 0 and it will not change exactly because of that condition
Code:
(Triggering unit) Equal to ThreatOwner[(Integer A)]
and that's why other towers order will not be touched).
So next thing to mention is condition which defines who of Attackers have max threat and this if-block since it's in second loop - it will check (or "goes through") all of each Attacker's sums of damage done to that tower with index A. It also reseting ThreatIndex to index B only when damage sum is higher than current value of CurrentThreat (CurrentThreat variable changes during the loop, so after each successful compare via conditions the CurentThreat-variable become higher). So at the end we have ThreatIndex which addresses us to Attacker with highest threat.

The third if-block is under the first loop: condition "ThreatIndex != 0" is already explained. So here we issuing order to attack Attacker with index "ThreatIndex". That's all.

This script is unfinished, but core-mechanism is done and performing well. Thing that should be in is indexes' cleaner which listens to an event of dying building (since buildings is our predetermined ThreatOwner) and clean itself, that's freeing the space inside unit array called "ThreatOwner".
You need that feature only if you want to manage a huge amounts of ThreatOwners in the map, because array lengths are finite.
 
Last edited:

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
A true threat system is really hard to implement. Technically the best target is the one which has the potential to deal the most damage, allowing pre-emptive targeting (no need to take the damage to know). However if that is the case one can abuse the logic by getting the unit to kite damage while lower damage heroes deal the damage. Let us not forget that healers and supports might be higher kill priority than damage dealers, especially if they have revive abilities so damage alone is bad for determining targets.

As such the actual implementation needs to start by making a pre-emptive guess as to who is the highest threat. Then one needs to adjust it based on what happens. If the highest threat person is evading then retarget. If too many high threat people are attacking then consider running and regrouping since you cannot win.
 
Status
Not open for further replies.
Top