HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

How to use Cohadar's Damage Detection?

05-25-2008, 09:54 AM#1
Hatebreeder
Hey there,
Can someone post me an example Trigger, which uses Cohadar's Damage Detection System?
I can't seem to use it properly...
05-25-2008, 10:18 AM#2
cohadar
Collapse JASS:
//==============================================================================
library ManaShield initializer Init uses ORBEngine, ABCT, Skill

globals
    private integer AID_DEAD_FIXER = 'AFix'
endglobals

//==============================================================================
private struct Zero
    unit u
    real finalhp
    boolean fix
endstruct

//==============================================================================
private function ZeroHandler takes nothing returns boolean
    //local timer t = GetExpiredTimer()
    //local Zero Z = ClearTimerStructC(t) // ABC
    local Zero Z = ABCT_GetData() // ABC

    if Z.fix then
        call UnitRemoveAbility(Z.u, AID_DEAD_FIXER)
    endif
    call SetUnitState(Z.u ,UNIT_STATE_LIFE, Z.finalhp)

    call Z.destroy()
    //call ReleaseTimer(t) // Recycler
    return true
endfunction

//==============================================================================
// This function will "block" a certain amount of damage done to the unit
// Needs to be used in the EVENT_UNIT_DAMAGED event.
// This function was made by: Shadow1500
//==============================================================================
private function DamageModify takes unit whichUnit, real dmg, real dmgnew returns nothing
    //local timer t
    local Zero Z
    local real life = GetWidgetLife(whichUnit)
    local real maxlife = GetUnitState(whichUnit, UNIT_STATE_MAX_LIFE)
    local boolean usetimer = false
    local real dmgback = dmg-dmgnew
    local real finalhp = life-dmgnew
    if dmgback<=0.0 then
        call SetWidgetLife(whichUnit, RMaxBJ(1.0, life+dmgback))
        return
    endif
    if dmg > maxlife then
        call UnitAddAbility( whichUnit,AID_DEAD_FIXER)
        set maxlife = 1000+maxlife
        set usetimer = true
    endif
    if ( life+dmgback > maxlife ) then
        call SetUnitState(whichUnit ,UNIT_STATE_LIFE, maxlife )
        set usetimer = true
    else
        call SetUnitState(whichUnit ,UNIT_STATE_LIFE, life+dmgback )
    endif
    if usetimer then
        set Z = Zero.create()
        set Z.u = whichUnit
        set Z.fix = true        
        set Z.finalhp = finalhp
        
        //set t = NewTimer() // Recycler
        //call SetTimerStructC(t, Z)
        //call TimerStart(t, 0, false, function ZeroHandler)
        call ABCT_Zero(function ZeroHandler, Z)
    endif
endfunction

//==============================================================================
//  Protect the magi ffs
//==============================================================================
private function Actions takes nothing returns nothing
    local unit victim = GetTriggerUnit()
    local real damage = GetEventDamage()
    local real mana = GetUnitState(victim, UNIT_STATE_MANA)
    
    if damage >= mana then
        call SetUnitState(victim, UNIT_STATE_MANA, 0)
        call DamageModify(victim, damage, damage-mana)
    else
        call SetUnitState(victim, UNIT_STATE_MANA, mana-damage)
        call DamageModify(victim, damage, 0)
    endif
    
    set victim = null
endfunction


//==============================================================================
private function Init takes nothing returns nothing
    call ORBEngine_RegisterOrbShield(function Actions, Skill_MANASHIELD, "Manashield")
endfunction

endlibrary
05-25-2008, 07:34 PM#3
grim001
That DamageModify function is so old and flawed.
05-25-2008, 09:45 PM#4
cohadar
I did not want to think of the subject so I used other peoples code.
It works fine for me (tested)

I firmly believe in code reuse, also in don't fix if not broken wisdom.
05-26-2008, 05:01 AM#5
grim001
It will fail if the unit is at very low health, or if you are dealing with very large amounts of damage, or if you try to modify damage more than once on the same unit at the same instant. There's also a high chance it will mess with GetKillingUnit() functioning correctly. I recently solved all those problems with DamageMod which you can find the systems section.
05-26-2008, 07:26 AM#6
cohadar
Ok tnx I will have a look at it.
05-26-2008, 07:51 AM#7
TheDamien
Quote:
Originally Posted by grim001
It will fail if the unit is at very low health, or if you are dealing with very large amounts of damage, or if you try to modify damage more than once on the same unit at the same instant. There's also a high chance it will mess with GetKillingUnit() functioning correctly. I recently solved all those problems with DamageMod which you can find the systems section.

Why does it mess up GetKillingUnit()?
05-26-2008, 08:09 AM#8
grim001
If you use it in a way that winds up increasing the damage dealt rather than reducing it, the killing blow will most likely come from SetUnitState in the callback.
05-26-2008, 08:12 AM#9
TheDamien
Hmm, that seems fairly apparent in hindsight.