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

Detect damage type

Status
Not open for further replies.
Before we start, I'm using Bribe's Damage Engine and Unit Indexer.

I basically need to store what type of damage was dealt to a unit (only triggered damage is relevant). So I can apply custom resistance, special effects, ect. My current idea is basically using a dummy damage function, that stores the damage-type, but otherwise just functions like "UnitDamageTarge". Got any ideas?

An example is that I have units using "explosive barrels", and they basically need to explode on attack / spell hit, whenever fire damage is dealt to them. Since all spells is triggered, and attacks never actually deal fire damage (in my case anyhow), I just need to detect which damage type is dealt via triggers when dealing trigger damage.
 
Level 39
Joined
Feb 27, 2007
Messages
5,023
AFAIK DamageEngine can't differentiate between Code damage and Attack damage. It's able to tell if something was a spell by using reverse runed bracers, but I don't see anything in its code that would allow you to catch UnitDamageTarget events. You could add a simple check for yourself by making your own global boolean variable, but you're going to have to make sure you never forget to reset it to "false" after dealing damage:
  • -------- Something like this --------
  • Set DamageIsCode = true
  • Unit - Cause X to damage Y for D damage
  • Set DamageIsCode = false
  • -------- Or this --------
  • Set DamageIsCode = true
  • Unit Group - Pick every unit in G and do (Actions)
    • Loop - Actions
      • Unit - Cause X to damage Y for D damage
  • Set DamageIsCode = false
  • -------- --------
  • -------- Then you just do --------
  • Events
    • EventVariable becomes equal to WhateverIsNecessaryForYourTrigger
  • Conditions
    • DamageIsCode = true
  • Actions
    • -------- Kowabunga! --------
Or you could write your own wrappers for UnitDamageTarget/catch them with vJASS hooks. Or use PDD, which does have a check for IS_DAMAGE_CODE.
 
Level 39
Joined
Feb 27, 2007
Messages
5,023
The only way you could get that is through a hook. The game doesn't store that information once it uses it for damage calculation (which happens before even the first DE event fires), so once you leave the function that called UnitDamageTarget there's no way to get AttackType/DamageType/WeaponType. In fact you can't even have an DT or WT variable in GUI, so you'd have to do some finagling to even be able to check the DamageType in a trigger condition or if-block.

Hook wise:
JASS:
scope GetDamageInfo
    globals
        attacktype Recent_AttackType
        damagetype Recent_DamageType
        weapontype Recent_WeaponType
    endglobals
  
    private function DT_Hook takes unit whichUnit, widget target, real amount, boolean attack, boolean ranged, attacktype attackType, damagetype damageType, weapontype weaponType returns nothing
        //maybe has to have same return type too??
        set Recent_AttackType = attackType
        set Recent_DamageType = damageType
        set Recent_WeaponType = weaponType
    endfunction
  
    private function DP_Hook takes unit whichUnit, real delay, real radius, real x, real y, real amount, boolean attack, boolean ranged, attacktype attackType, damagetype damageType, weapontype weaponType returns nothing
        //maybe has to have same return type too??
        set Recent_AttackType = attackType
        set Recent_DamageType = damageType
        set Recent_WeaponType = weaponType
    endfunction
  
    hook UnitDamageTarget DT_Hook
    hook UnitDamagePoint DP_Hook
endscope
Then just refer to Recent_DamageType as necessary and hope that no UnitDamageTarget/Point calls were made between events to mess you up.
 
So, something like this:

JASS:
function TriggerExplosives takes nothing returns nothing
    local unit target = udg_DamageEventTarget
    local location loc = GetUnitLoc(udg_DamageEventTarget)
 
    if (GetUnitAbilityLevel(target, 'A002') > 0 and Recent_DamageType == DAMAGE_TYPE_FIRE) then //<------------ Like that?

        call SetUnitExploded(target, true)
        call KillUnit(target)
        set bj_lastCreatedEffect = AddSpecialEffectLoc("NewGroundEX.mdx", loc)
    endif
 
    //cleanup
    set loc = null
    set target = null
endfunction

//===========================================================================
function InitTrig_Ab_Eplosi_death_Copy takes nothing returns nothing
    set gg_trg_Ab_Eplosi_death_Copy = CreateTrigger(  )
    call TriggerRegisterVariableEvent( SomeTrigger, "udg_DamageEvent", EQUAL, 1.00 )
    call TriggerAddAction( TriggerExplosives, function Trig_Ab_Eplosi_death_Copy_Actions )
endfunction
 
Status
Not open for further replies.
Top