HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Trying to heal a unit on damage

01-26-2009, 01:19 AM#1
Bobo_The_Kodo
If I shoot at the unit with a lot of units at once, eventually it will take damage for some reason ... Anyone know why ?

Collapse JASS:
library Heal uses TimerUtils
    
    private struct Data
        unit whichUnit
        real hp
        real maxhp
    endstruct
    
    private function MaxHealLoop takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local Data dat = GetTimerData( t )
        set dat.whichUnit:MaxLife = dat.maxhp
        call SetWidgetLife( dat.whichUnit, dat.hp )
        call dat.destroy()
        call ReleaseTimer( t )
    endfunction
    
    private function HealLoop takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local Data dat = GetTimerData( t )
        call SetWidgetLife( dat.whichUnit, GetWidgetLife( dat.whichUnit ) + dat.hp )
        call dat.destroy()
        call ReleaseTimer( t )
    endfunction
    
    function NegateDamage takes nothing returns nothing
        local unit whichUnit = GetDamagedUnit()
        local real damage = GetDamage()
        local real hp = GetWidgetLife( whichUnit )
        local real maxhp
        local timer t
        local Data dat
        call SetWidgetLife( whichUnit, 1000000 )
        set maxhp = GetWidgetLife( whichUnit )
        call SetWidgetLife( whichUnit, hp )
        if maxhp - hp >= damage then // Heals directly
            set hp = hp + damage
            call SetWidgetLife( whichUnit, hp )
        elseif damage > hp - 0.595 and damage > maxhp - hp then // Adds max hp
            set t = NewTimer()
            set dat = Data.create()
            set dat.whichUnit = whichUnit
            set dat.hp = hp
            set dat.maxhp = maxhp
            set whichUnit:MaxLife = whichUnit:MaxLife + 10000
            if GetWidgetLife( whichUnit ) < damage then
                call SetWidgetLife( whichUnit, maxhp + 10000 )
            endif
            call SetTimerData( t, dat )
            call TimerStart( t, 0., false, function MaxHealLoop )
        elseif maxhp - hp < damage then // Heals after 0. seconds
            set t = NewTimer()
            set dat = Data.create()
            set dat.whichUnit = whichUnit
            set dat.hp = damage
            call SetTimerData( t, dat )
            call TimerStart( t, 0., false, function HealLoop )
        endif
    endfunction

endlibrary
01-26-2009, 09:18 AM#2
Frozenhelfire
What event are you using to fire the trigger? You may want to use a damage detection system if you aren't already.
01-26-2009, 12:14 PM#3
DioD
You cant ajust max HP of units...
01-26-2009, 03:28 PM#4
Anitarf
Quote:
Originally Posted by DioD
You cant ajust max HP of units...
You can with unit properties...
01-26-2009, 03:41 PM#5
Bobo_The_Kodo
Ehhh.. I said it was working most of the time Frozen / DioD... I'm thinking about changing the maxhp - hp < damage to change their maxhp also, but that would be unnecessarily laggy-er if there is a way to fix how it currently is.
01-26-2009, 04:16 PM#6
Anitarf
Can you try figuring out more precisely in what kind of situation do they take damage and how much damage do they take?
01-26-2009, 04:54 PM#7
Bobo_The_Kodo
Well if i take like 5 guys with 0.05 second cooldown and order them to attack my guy, eventually he will have taken damage from one of them, so it must be case 3. Is it possible that the unit could be attacked in between the timer starting and expiring, because some frames you can see the life difference even with a 0 second timer.
01-26-2009, 05:39 PM#8
DioD
Anitarf

You cant ajust max HP of units WidgetLife.

And there special function "SetUnitMaxState" no "hardcoded systems" needed.
01-26-2009, 06:15 PM#9
Anitarf
Quote:
Originally Posted by Bobo_The_Kodo
Well if i take like 5 guys with 0.05 second cooldown and order them to attack my guy, eventually he will have taken damage from one of them, so it must be case 3. Is it possible that the unit could be attacked in between the timer starting and expiring, because some frames you can see the life difference even with a 0 second timer.
Hmm... could you perhaps repeat the test using my ADamage library? I have built-in checks to see if a timer is already running for a unit when it takes damage, so if this is indeed the problem it shouldn't happen with ADamage.
01-26-2009, 08:03 PM#10
Ammorth
I believe an event can fire between the expiration of a timer (even if the timer is a 0 second timer). I was working on an anti-greedisgood system, which would fire 2, 0 second timers, 1 for the PlayerState event (gainning resources) and the IssueHarvest event (the unit drops of resources and is ordered to harvest). The PlayerState always happened before the harvest event.

So, I would fire a 0 second timer on the resource event and then would set a boolean to true on the harvest event. If the boolean was true after the 0 second timer expired for the resource event, the unit deposited resources. I also used a 0 second timer to set the boolean back to false, that fired during the harvest event.

Code:
HARVEST EVENT
 | | 0 sec expires
        (all this happens within 0 seconds)
| | 0 sec expires
PLAYER STATE EVENT

Therefore, because I was able to have another 0 second timer start between a 0 second timer, the system worked. Otherwise, the boolean would never be set to true and it would always fail.
01-27-2009, 12:03 AM#11
Bobo_The_Kodo
Collapse JASS:
library Heal uses TimerUtils

    globals
        private constant integer SURVIVAL_ABILITY = 'A000'
    endglobals
    
    private struct Data
        unit whichUnit
        real hp
    endstruct
    
    private function HealLoop takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local Data dat = GetTimerData( t )
        call UnitRemoveAbility( dat.whichUnit, SURVIVAL_ABILITY )
        call SetWidgetLife( dat.whichUnit, dat.hp )
        call dat.destroy()
        call ReleaseTimer( t )
    endfunction
    
    function NegateDamage takes nothing returns nothing
        local unit whichUnit = GetDamagedUnit()
        local real damage = GetDamage()
        local real hp = GetWidgetLife( whichUnit )
        local real maxhp = GetUnitState( whichUnit, UNIT_STATE_MAX_LIFE )
        local timer t
        local Data dat
        if maxhp - hp >= damage then // Heals directly
            set hp = hp + damage
            call SetWidgetLife( whichUnit, hp )
        else // Adds max hp ability
            set t = NewTimer()
            set dat = Data.create()
            set dat.whichUnit = whichUnit
            set dat.hp = hp
            call UnitAddAbility( whichUnit, SURVIVAL_ABILITY )
            if GetWidgetLife( whichUnit ) < damage then
                call SetWidgetLife( whichUnit, maxhp + 10000 )
            endif
            call SetTimerData( t, dat )
            call TimerStart( t, 0., false, function HealLoop )
        endif
    endfunction

endlibrary

Decided to go with this, can it possibly bug ?
01-27-2009, 12:28 AM#12
Anitarf
Quote:
Originally Posted by Bobo_The_Kodo
Decided to go with this, can it possibly bug ?
I don't know, you tell us. Do you still get that bug?
01-27-2009, 03:31 AM#13
Bobo_The_Kodo
No that bug doesn't happen any more... But doesn't Item Life Bonus act oddly, and thats how it's used by the MaxState systems ?