HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Damage Detection Simplicity

03-22-2008, 02:16 AM#1
Hydrolisk
Currently, I want a way to detect damage on "all units." What I've got so far is putting every unit into a unit group and then setting that as a unit variable. However, whenever I use a trigger using "all units," the trigger never activates. Using GUI, I can see no "Damaged Unit;" could this be a problem?

And also, is this leakless? If so, how can I prevent leaks?
03-22-2008, 02:28 AM#2
moyack
Basically you need to have a system which detects when a new unit enters to the map, create a new trigger with the respective event EVENT_UNIT_DAMAGED, and then add to those triggers an action so they can do something to the damaged units.

As is this would leak events and triggers (something unavoidable), but any optimization could be done if you define more specifically how is your map and such.
03-22-2008, 02:49 AM#3
Hydrolisk
(Following one of the systems in the Resources section, I wouldn't need to go through all this trouble, although I'd rather try myself and learn something in the process.)
-
The current map I'm working on (but will quickly cease production and move onto something else) uses the following triggers.
Trigger:
All Units Group
Collapse Events
Unit - A unit enters (Playable map area)
Conditions
Collapse Actions
Set allunits_ug = (Units in (Playable map area))
Collapse Unit Group - Pick every unit in allunits_ug and do (Actions)
Collapse Loop - Actions
Set allunits_u = (Picked unit)
Custom script: call DestroyGroup( udg_allunits_ug )
and
Trigger:
Ability Initialization
Collapse Events
Time - Elapsed game time is 10.00 seconds
Conditions
Collapse Actions
Trigger - Add to Warriors Monument Aura <gen> the event (Unit - allunits_u Takes damage)
Trigger - Add to Charge Detect Attack <gen> the event (Unit - allunits_u Takes damage)
Trigger - Add to Courage and Bravery <gen> the event (Unit - allunits_u Takes damage)
and (the .90 is for testing; doesn't work )
Trigger:
Courage and Bravery
Events
Collapse Conditions
(Level of Courage and Bravery for (Triggering unit)) Not equal to 0
Collapse Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
(Random real number between 0.00 and 1.00) Less than or equal to 0.90
Collapse Then - Actions
Unit - Set life of (Triggering unit) to ((Life of (Triggering unit)) + ((Damage taken) x 2.00))
Special Effect - Create a special effect attached to the chest of (Triggering unit) using Abilities\Spells\Orc\HealingWave\HealingWaveTarget.mdl
Set candb_fx = (Last created special effect)
Wait 2.00 seconds
Special Effect - Destroy (Last created special effect)
Else - Actions
and
That's it.
-
My map (and new one) will only need a super simple DD method; I'm planning on using dummy units for detecting ability damage and normal units will do normal fighting damage (easy to check, I believe).
-
What are these leaks, in detail? (I already know what leaks are, but could you explain in more detail these 2 specific ones?)
-
Feel free to comment on the triggers at hand; I need the info.
03-22-2008, 08:18 AM#4
Pyrogasm
What are you even trying to do? In no way can I see what you posted working. The only thing I can see that doing is adding that EVENT_UNIT_DAMAGED event to the trigger for one (and only one) random unit on the map (whichever unit was the last unit in allunits_ug at 10.00 seconds elapsed gametime).

Adding events to triggers doesn't work the way you think it does.


As for the "leaks": it's the memory allocated for new events added to a trigger and/or memory allocated for TriggerActions and the triggers themselves.
03-22-2008, 04:08 PM#5
Hydrolisk
I see.

How would I detect damage for any unit on the map then? (I've heard about dynamic triggers and vJASS, although frankly, I have no clue what either one is.)
03-22-2008, 11:46 PM#6
Gorman
Trigger:
All Units Group
Collapse Events
Unit - A unit enters (Playable map area)
Conditions
Collapse Actions
Set allunits_ug = (Units in (Playable map area))
Wait 10.00 seconds
Collapse Unit Group - Pick every unit in allunits_ug and do (Actions)
Collapse Loop - Actions
Trigger - Add to Warriors Monument Aura <gen> the event (Unit - Picked unit Takes damage)
Trigger - Add to Charge Detect Attack <gen> the event (Unit - Picked unit Takes damage)
Trigger - Add to Courage and Bravery <gen> the event (Unit - Picked unit Takes damage)
Custom script: call DestroyGroup( udg_allunits_ug )

Although the fact that u didnt do that in the first place makes me thing that u cant do that, but meh

Also, why dont u just have one damage detection trigger, add some conditions to it to see what spell gets used, then make it runn the approptiate trigger. I think that why is better because you are adding only a third of the amount of events
03-23-2008, 12:16 AM#7
moyack
Quote:
Originally Posted by Hydrolisk
I see.

How would I detect damage for any unit on the map then? (I've heard about dynamic triggers and vJASS, although frankly, I have no clue what either one is.)
The thing is: there are several ways to detect the damage, but the simplicity and efficiency will depend only on the things that you want to do with that detection. If you give to us a good explanation about what do you want to do with that detection, we will be able to give you a good (and more adequate) idea about how to implement it.
03-23-2008, 07:22 PM#8
Hydrolisk
Well, I want to use detection to be able to replace "Unit is attacked" (as it can be easily abused), EX: If an archer shot an arrow at a guy 1200 away, the archer's 15% chance to cast Chain Lightning won't fire as soon as the archer attacks, rather, when the archer's arrow hits; and so that I can produce better effects with spells, EX: instead of stunning my target before a projectile even hits, I can stun the target when it takes damage by the projectile (and then make flashy effects if required).
03-25-2008, 07:33 AM#9
chobibo
Try looking at emjlr3's on attack template, I think it does what you want. It kinda works like a " generic a unit is damaged event ".
*Note that there is no Generic unit damage event.
03-25-2008, 09:02 AM#10
Malf
You want an attack detection not a damage detection in your case.
03-25-2008, 12:51 PM#11
Anitarf
Quote:
Originally Posted by Malf
You want an attack detection not a damage detection in your case.
They're mostly the same, though, I mean, to detect attack hits you need to first detect damage, that's not such a big problem, we have a unit takes damage event, the only problem is that it's only a specific unit event, so to detect damage for any unit, you need to have a specific unit event for every unit.

The easiest way to do that is to have a single "damage detection" trigger and whenever a unit enters playable map area, add a unit takes damage event for that unit to that trigger. The problem with that is that you can't clean up events without destroying the whole trigger, so once units leave the game the event for them will stay in your trigger. Now, I'm not even sure if that's a performance issue at all, but generaly proper damage detection systems avoid this by making a new trigger for every unit and destroying that trigger when the unit dies.

Once you do this, you have an equivalent of a generic unit takes damage event trigger. Now, the second part of the challenge is telling apart attack damage from spell damage. One way is to deal all your spell damage with triggers and before you deal it, set a global boolean variable to true, so when the damage detection trigger runs it checks that boolean to see if the damage was caused by a trigger or by another source (in this case, the only source left are attacks), and immediately sets the boolean to false. Another way is to give all units a passive ability that leaves a buff behind when they attack, like slow poison for example. Then, in the damage detect trigger, check if the unit has the buff, if it does then the damage was caused by an attack, then remove the buff. A third method would be to keep track of who's attacking whom and who's casting spells on whom and when damage is dealt, check if the damage source's last action was an attack or a spell cast (might work incorrectly with projectile spells and attacks that take some time to reach the target).
03-28-2008, 08:33 PM#12
Hydrolisk
I suppose I can't detect whenever a unit enters the map and store it in an array (and then every once in a while, clear the arrays of all dead units)? And how would I make a trigger that makes other triggers? It's cool how far the community's modding capabilities have advanced.
03-30-2008, 09:14 AM#13
Pyrogasm
You could store every unit on the map in an array... but I don't know where that'd get you. What exactly do you mean by clearing arrays periodically?

Triggers making other triggers is quite simple; all it requires are a few custom scripts:
Trigger:
Collapse My Actions Trigger
Events
Collapse Conditions
Something equal to SomethingElse
Collapse Actions
Game - Display to (All Players) the text Foo!
Collapse My Adding Events Trigger
Collapse Events
Unit - A Unit enters (Playable Map Area)
Conditions
Collapse Actions
Custom script: local trigger T = CreateTrigger()
Custom script: call TriggerRegisterUnitEvent(T, GetTriggerUnit(), EVENT_UNIT_DAMAGED)
Custom script: call TriggerAddCondition(T, Condition(function Trig_My_Actions_Trigger_Conditions))
Custom script: call TriggerAddAction(T, function Trig_My_Actions_Trigger_Actions)
Custom script: set T = null
You should be able to see how the function names line up and stuff.
05-14-2008, 05:40 PM#14
Mystic Prophet
Hmm this post seems a couple months old, but I came across it in one of my searches and it still seems unanswered so...

This is what I used for my crude system. not sure how efficient it is, but it works.
Trigger:
Unit enters map
Collapse Events
Unit - A unit enters (Entire map)
Conditions
Collapse Actions
-------- A --------
Trigger - Add to Acid Bomb <gen> the event (Unit - (Entering unit) Takes damage)

Trigger:
Acid Bomb
Events
Collapse Conditions
(Damage taken) Equal to 0.31
Collapse Actions
Unit Group - Add (Triggering unit) to Group_Damage[(Player number of (Owner of (Damage source)))]
Unit Group - Pick every unit in Group_Damage[(Player number of (Owner of (Damage source)))] and do (Unit - Cause (Damage source) to damage (Picked unit), dealing ((Real((Intelligence of (Damage source) (Include bonuses)))) x (0.33 x (Real((Level of Acid Bomb for (Damage source)))))) damage of attack type Spells and damage type Normal)
Unit Group - Pick every unit in Group_Damage[(Player number of (Owner of (Damage source)))] and do (Unit Group - Remove (Picked unit) from Group_Damage[(Player number of (Owner of (Damage source)))])
Unit Group - Destroy unit group (Last created unit group)

There's also a triggering replacing any preplaced units in the map, so that every unit "enters the map" at some point.

EDITED: the WEU event was obsolete and not used (as it didnt work anyway). that trigger was disabled in the map. it should work as shown here.
05-14-2008, 05:45 PM#15
Vexorian
You are using WEU's "Any unit takes damage" ...