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

How to detect code damage?

Status
Not open for further replies.
Level 11
Joined
Oct 11, 2012
Messages
711
Hi guys. I know there are resources such as DDS to detect code damage, but I just want to know how it is done. A modified ability of runed bracers can be used to differentiate physical and magic damages, but how to detect code damage? What's the trick of it? Thanks a lot. :)
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
it cant, it only detects damage that is dealt with the special function UnitDamageTargetEx, which is basically used when you want to deal damage inside the onDamage trigger

it is possible to do so, but it would require hooks
 
Level 11
Joined
Oct 11, 2012
Messages
711
Set a var to a value b4 dealing dmg. On damage event, check for the var. Don't forget to reset.

Thank again, CakeMaster. :) +Rep if I can

it cant, it only detects damage that is dealt with the special function UnitDamageTargetEx, which is basically used when you want to deal damage inside the onDamage trigger

it is possible to do so, but it would require hooks

Can "UnitDamageTarget" be detected?
 
Last edited by a moderator:

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
The JASS virtual machine compiler (well it just optimizes the program structure, all name resolution is still interpreted at run time) that runs during map initialization will detect if the map script file (war3map.j) is damaged due to a file error.

If you mean "script to detect trigger generated damage on units, destructible or items" then this clearly is not helpful.

For units a damage detection system can work by using a custom damage function which acts as a wrapper for the native damage function but also sends signals to the map damage detection system to inform it that a trigger is dealing damage.

As far as I know it is not possible to detect damage to items and destructibles using triggers in a meaningful and efficient way in the first place.
 
Level 11
Joined
Oct 11, 2012
Messages
711
Only with hooks, which require vJass

Ok, I know some vJass. BTW, you said that
it only detects damage that is dealt with the special function UnitDamageTargetEx, which is basically used when you want to deal damage inside the onDamage trigger

Then how does it detect it? I cant figured it out. :(

but also sends signals to the map damage detection system to inform it that a trigger is dealing damage.
Thanks for the reply. But how does it send the signal?

Does something like the following works?
JASS:
globals
    boolean code_damage = false
endglobals

function HamgDoingDamage takes nothing returns nothing
    ......
    set code_damage = true
    call UnitDamageTarget(gg_unit_Hamg_0111,u,.........)
    .....
endfunction

......
function onDamage takes nothing returns nothing
    if code_damage == true then
        call BJDebugMsg("Code Damage")
        set code_damage = false
    else
        call BJDebugMsg("Other Types of Damage")
    endif
endfunction

function test takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterUnitEvent( t, gg_unit_Hamg_0111, EVENT_UNIT_DAMAGED )
    call TriggerAddCondition(t, function onDamage)
endfunction
 
Last edited:

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
Thanks for the reply. But how does it send the signal?
Well the simplest would be a global boolean. Before any script does damage you set the boolean true. The DDS handler code can then know the damage came from a trigger by checking if this boolean is true. It may or may not be possible to set it false straight after dealing the damage in the same thread, depends if the damage response event pre-empts threads that deal damage during the damage call. Otherwise you would need to set it false after the hanlder runs.

Does something like the following works?
No because code is a key word representing a type. Using it as a variable name will generate a syntax error.
 
Level 11
Joined
Oct 11, 2012
Messages
711
Well the simplest would be a global boolean. Before any script does damage you set the boolean true. The DDS handler code can then know the damage came from a trigger by checking if this boolean is true. It may or may not be possible to set it false straight after dealing the damage in the same thread, depends if the damage response event pre-empts threads that deal damage during the damage call. Otherwise you would need to set it false after the hanlder runs.


No because code is a key word representing a type. Using it as a variable name will generate a syntax error.
Thanks, I have fixed that.

Yeah, that should work.
Thanks, PnF! :) What if two units deal damage at the same time? For example, A deals physical damage and B deals code damage at the same time, would that mess up the onDamage function? Or is each damage event a separate event(always runs in an order and not at the same time)?
 
Code in wc3 is always ordered. Those two damage instances are treated as separate events.

Let's say you damage a unit. It'll pause the current process, skip over to the damage event, complete the damage triggers, and then return to the original thread. So it'll work fine as long as you set the boolean back to false. For example, let's say you have this code:
JASS:
function SomeDamage takes nothing returns nothing
    ......
    call BJDebugMsg("Start")
    call UnitDamageTarget(u,gg_unit_Hamg_0111,.........)
    call BJDebugMsg("In Between")
    call UnitDamageTarget(u,gg_unit_Hamg_0111,.........)
    call BJDebugMsg("Finished")
    .....
endfunction

......
function onDamage takes nothing returns nothing
    call BJDebugMsg("Damage")
endfunction

function test takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterUnitEvent( t, gg_unit_Hamg_0111, EVENT_UNIT_DAMAGED )
    call TriggerAddCondition(t, function onDamage)
endfunction

What do you think will be displayed? If you run it in Warcraft 3, it'll display:

Start
Damage
In Between
Damage
Finish

Hopefully that shows why the code will work just fine, even with two damage instances at the "same" time.
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
If mixed dmg equals to calling UnitDamageTarget 2 times, then yes, those are separate events and this should be properly detected via DDS.

There is always an option to use custom events with priority queue to ensure events with highest priority run before those, which have lower value.

However, this is more complicated and you should not bother with such solution at this time. Just don't forget to set your variable (boolean as I see) correctly on each damage call so you avoid uncorrect damage event handling.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
If mixed dmg equals to calling UnitDamageTarget 2 times, then yes, those are separate events and this should be properly detected via DDS.

There is always an option to use custom events with priority queue to ensure events with highest priority run before those, which have lower value.

However, this is more complicated and you should not bother with such solution at this time. Just don't forget to set your variable (boolean as I see) correctly on each damage call so you avoid uncorrect damage event handling.

I didnt read the last few posts, but is there need for priority in this question? I see nothing that asks for priorities, and even with priority queue you cant detect code damage, so this seems irrelevant to me

What if two units deal damage at the same time?

Simple, as PnF mentioned, they cant. You can make 1 unit deal 2 damage instances at the "same" time(any buff-applying spell, including spells like stormbolt), but that is most likely also not "at the very same time", but rather "one after another straight off"
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
@edo494 lol. First and last sentence says it all, whats your point?

I mentioned priority in case, obviously, there are situations when you need to queue event firing - it is mostly related to custom events. And obviously, its not the case when we talk about two separate UnitDamageTarget calls one after another :)
And if you haven't noticed:
If mixed dmg equals to calling UnitDamageTarget 2 times, then yes, those are separate events and this should be properly detected via DDS.
 
Level 11
Joined
Oct 11, 2012
Messages
711
Code in wc3 is always ordered. Those two damage instances are treated as separate events.

Let's say you damage a unit. It'll pause the current process, skip over to the damage event, complete the damage triggers, and then return to the original thread. So it'll work fine as long as you set the boolean back to false. For example, let's say you have this code:
JASS:
function SomeDamage takes nothing returns nothing
    ......
    call BJDebugMsg("Start")
    call UnitDamageTarget(u,gg_unit_Hamg_0111,.........)
    call BJDebugMsg("In Between")
    call UnitDamageTarget(u,gg_unit_Hamg_0111,.........)
    call BJDebugMsg("Finished")
    .....
endfunction

......
function onDamage takes nothing returns nothing
    call BJDebugMsg("Damage")
endfunction

function test takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterUnitEvent( t, gg_unit_Hamg_0111, EVENT_UNIT_DAMAGED )
    call TriggerAddCondition(t, function onDamage)
endfunction

What do you think will be displayed? If you run it in Warcraft 3, it'll display:

Start
Damage
In Between
Damage
Finish

Hopefully that shows why the code will work just fine, even with two damage instances at the "same" time.

Thanks PnF, that's crystal clear. I always like your explanation and example. :)

Also, gratitude to Banner and edo494.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
What do you think will be displayed? If you run it in Warcraft 3, it'll display:

Start
Damage
In Between
Damage
Finish
In that case it is super easy. Simply set a boolean before dealing triggered damage (make it true) and clear it after the damage call returns (make it false). If the boolean is true in the damage detection system handler then the damage was done by script, otherwise it was done by a natural game source (part of game engine).
 
A miracle system has came into our wc3 universe. http://www.hiveworkshop.com/forums/...-1-a-231846/?prev=search=physical&d=list&r=20

Look into that to clear up any more questions you have, I am sure that will answer. Sadly I am also lacking into this field of knowledge so I don't have much to say myself, I only know spell and physical. Code is likely done through a private line/function of some sort so it doesn't get pulled into one of the other two.
 
Status
Not open for further replies.
Top