System Heal

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
JASS:
/*
 
    Heal v2.0.0
        by kingking
    
    - Library that transforms healing into a breeze, allowing full control on healing.
    
    CreateHealType()-> HealType
    ~ Generate a heal type.
    
    HealUnit(unit a, unit b,real,HealType)
    ~ Heal the unit + fire event.
    ~ Unit a -> Healer
    ~ Unit b -> Target
    
    RegisterHealEvent(trigger,integer)
    ~ trigger - Trigger to be registered, integer - priority
    
    UnregisterHealEvent(trigger)
    ~ trigger - Trigger to be registered
    
    RegisterHealUnitEvent(trigger,unit,integer)
    ~ trigger - Trigger to be registered, unit - healer, integer - priority
    ~ Fires if the unit heals anything.
    
    UnregisterHealUnitEvent(trigger,unit)
    ~ trigger - Trigger to be registered, unit - healer
    
    RegisterUnitHealedEvent(trigger,unit,integer)
    ~ trigger - Trigger to be registered, unit - healed, integer - priority
    ~ Fires if the unit is healed by anything.
    
    UnregisterUnitHealedEvent(trigger,unit)
    ~ trigger - Trigger to be registered, unit - healed
    
    GetHealAmount() -> real
    ~ Get the amount of healing at the moment.
    
    SetHealAmount(real)
    ~ Update the amount of healing.
    
    GetHealType()-> HealType
    ~ Get the type of healing.
    
    GetHealer() -> unit
    ~ Get healer.
    
    GetHealedUnit()-> unit
    ~ Get healed unit.
    
    Requires : A vJass complier
*/
library Heal
    
    struct HealType extends array
    endstruct
    
    globals
        HealType HEAL_TYPE_NORMAL=1
        private integer HealTypeCount=1
        private real Final=0.0
        private unit Healer=null
        private unit Target=null
        private HealType CurrHealType=1
        private key GenericCallback
        private key HealUnitCallback
        private key UnitHealedCallback
        private integer array TrigType
        private unit array HealedUnitList
        private unit array HealerList
        private trigger array Trig
        private integer array Next
        private integer array Prev
        private integer array Priority
        private integer array IndexStack
        private integer IndexStackMax=0
        private integer IndexMax=0
    endglobals
    
    function CreateHealType takes nothing returns HealType
        set HealTypeCount=HealTypeCount+1
        return HealTypeCount
    endfunction
    
    function GetHealer takes nothing returns unit
        return Healer
    endfunction
    
    function GetHealedUnit takes nothing returns unit
        return Target
    endfunction
    
    function GetHealType takes nothing returns HealType
        return CurrHealType
    endfunction
    
    function GetHealAmount takes nothing returns real
        return Final
    endfunction
    
    function SetHealAmount takes real r returns nothing
        set Final=r
    endfunction
    
    private function FireEvent takes unit healer, unit target, real amount, HealType htype returns nothing
        local unit oldhealer=Healer
        local unit oldtarget=Target
        local real oldamount=Final
        local HealType oldhealtype=CurrHealType
        local integer i=Next[0]
        local boolean ToFire
        set Healer=healer
        set Target=target
        set Final=amount
        set CurrHealType=htype
        loop
        exitwhen i==0
            set ToFire=false
            if TrigType<i>==GenericCallback then
                set ToFire=true
            elseif TrigType<i>==HealUnitCallback and HealerList<i>==healer then
                set ToFire=true
            elseif TrigType<i>==UnitHealedCallback and HealedUnitList<i>==target then
                set ToFire=true
            endif
            if ToFire==true and IsTriggerEnabled(Trig<i>) and TriggerEvaluate(Trig<i>) then
                call TriggerExecute(Trig<i>)
            endif
            set i=Next<i>
        endloop
        if Final&gt;amount then
            call SetWidgetLife(target,GetWidgetLife(target)+(Final-amount))
        elseif Final&lt;amount and Final&gt;=0.0 then
            call SetWidgetLife(target,GetWidgetLife(target)-(amount-Final))
        endif
        set Healer=oldhealer
        set Target=oldtarget
        set Final=oldamount
        set CurrHealType=oldhealtype
        set oldhealer=null
        set oldtarget=null
    endfunction
    
    function HealUnit takes unit healer, unit target, real amount, HealType htype returns nothing
        local real result
        if GetWidgetLife(target)&gt;.405 then
            set result=GetWidgetLife(target)+amount
            call SetWidgetLife(target,result)
            call FireEvent(healer,target,amount,htype)
        endif
    endfunction
    
    function RegisterHealEvent takes trigger trig, integer prio returns nothing
        local integer head
        local integer i
        local boolean isAdded
        if trig!=null then
            if IndexStackMax==0 then
                set IndexMax=IndexMax+1
                set i=IndexMax
            else
                set i=IndexStack[IndexStackMax]
                set IndexStackMax=IndexStackMax-1
            endif
            set Trig<i>=trig
            set Priority<i>=prio
            set TrigType<i>=GenericCallback
            set isAdded=false
            set head=Next[0]
            loop
                if prio&gt;Priority[head] then
                    set Next[Prev[head]]=i
                    set Prev<i>=Prev[head]
                    set Next<i>=head
                    set Prev[head]=i
                    set isAdded=true
                    set head=Prev[0]
                endif
                set head=Next[head]
            exitwhen head==0
            endloop
            if isAdded==false then
                set Next[Prev[head]]=i
                set Prev<i>=Prev[head]
                set Next<i>=head
                set Prev[head]=i
            endif
        endif
    endfunction
    
    function UnregisterHealEvent takes trigger trig returns nothing
        local integer i=Next[0]
        loop
        exitwhen i==0
            if Trig<i>==trig and TrigType<i>==GenericCallback then
                set Next[Prev<i>]=Next<i>
                set Prev[Next<i>]=Prev<i>
                set IndexStackMax=IndexStackMax+1                
                set IndexStack[IndexStackMax]=i
                return
            endif
            set i=Next<i>
        endloop
    endfunction
    
    function RegisterHealUnitEvent takes trigger trig, unit u, integer prio returns nothing
        local integer head
        local integer i
        local boolean isAdded
        if trig!=null then
            if IndexStackMax==0 then
                set IndexMax=IndexMax+1
                set i=IndexMax
            else
                set i=IndexStack[IndexStackMax]
                set IndexStackMax=IndexStackMax-1
            endif
            set Trig<i>=trig
            set Priority<i>=prio
            set TrigType<i>=HealUnitCallback
            set HealerList<i>=u
            set isAdded=false
            set head=Next[0]
            loop
                if prio&gt;Priority[head] then
                    set Next[Prev[head]]=i
                    set Prev<i>=Prev[head]
                    set Next<i>=head
                    set Prev[head]=i
                    set isAdded=true
                    set head=Prev[0]
                    set isAdded=true
                endif
                set head=Next[head]
            exitwhen head==0
            endloop
            if isAdded==false then
                set Next[Prev[head]]=i
                set Prev<i>=Prev[head]
                set Next<i>=head
                set Prev[head]=i
            endif
        endif
    endfunction
    
    function UnregisterHealUnitEvent takes trigger trig, unit u returns nothing
        local integer i=Next[0]
        loop
        exitwhen i==0
            if Trig<i>==trig and HealerList<i>==u then
                set Next[Prev<i>]=Next<i>
                set Prev[Next<i>]=Prev<i>
                set HealerList<i>=null
                set IndexStackMax=IndexStackMax+1                
                set IndexStack[IndexStackMax]=i
                return
            endif
            set i=Next<i>
        endloop
    endfunction
    
    function RegisterUnitHealedEvent takes trigger trig, unit u, integer prio returns nothing
        local integer head
        local integer i
        local boolean isAdded
        if trig!=null then
            if IndexStackMax==0 then
                set IndexMax=IndexMax+1
                set i=IndexMax
            else
                set i=IndexStack[IndexStackMax]
                set IndexStackMax=IndexStackMax-1
            endif
            set Trig<i>=trig
            set Priority<i>=prio
            set TrigType<i>=UnitHealedCallback
            set HealedUnitList<i>=u
            set isAdded=false
            set head=Next[0]
            loop
                if prio&gt;Priority[head] then
                    set Next[Prev[head]]=i
                    set Prev<i>=Prev[head]
                    set Next<i>=head
                    set Prev[head]=i
                    set isAdded=true
                    set head=Prev[0]
                    set isAdded=true
                endif
                set head=Next[head]
            exitwhen head==0
            endloop
            if isAdded==false then
                set Next[Prev[head]]=i
                set Prev<i>=Prev[head]
                set Next<i>=head
                set Prev[head]=i
            endif
        endif
    endfunction
    
    function UnregisterUnitHealedEvent takes trigger trig, unit u returns nothing
        local integer i=Next[0]
        loop
        exitwhen i==0
            if Trig<i>==trig and HealedUnitList<i>==u then
                set Next[Prev<i>]=Next<i>
                set Prev[Next<i>]=Prev<i>
                set HealedUnitList<i>=null
                set IndexStackMax=IndexStackMax+1                
                set IndexStack[IndexStackMax]=i
                return
            endif
            set i=Next<i>
        endloop
    endfunction
    
endlibrary
</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>


Heal
v1.0.0 - Release
v1.0.1 - Changed Healable from a boolean into an integer stack.
v1.0.2 - Changed Healable to Heal_Block/Heal_BlockAll.
v1.0.3 - Fixed bug that caused the system ignore the amount of healing.
v1.0.4 - Added heal type, it is useful for spell making.
v1.0.5 - Fixed heal type's bug. Changed Heal_GetTriggerUnit() to Heal_Target().
v1.0.6 - Removed useless parameter in Heal_BlockAll(). Fixed block healing code.
v1.0.7 - Moved initializer into module to fix bug (Heal_RegisterEvent did not work in struct initializers) which is caused by jasshelper.
v1.0.8 - Removed stack, replaced with local variables. A little efficiency gain in getting source/target/amount/type and adding block. Removed the usage of UnitAlive to avoid problem from map optimizer.
v2.0.0 - Rewrote whole library from scratch. Added prioritized event firing, ability to register heal events for particular unit, and modify amount of healing. Heal can never be done so easily before this!
 

Attachments

  • Heal.w3x
    31.9 KB · Views: 625

Sickle

New Member
Reaction score
13
You have gone way overboard. You took a simple function that should maybe be attached to an event and turned it into a mess.

Make it cleaner. Make it faster. Make it sane.

Edit:

This is the kind of thing I want to see.
JASS:
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\\
//:: Heal                                                                           ::\\
//::                                                                                ::\\
//:: by your friendly neighborhood Sickle.                                          ::\\
//::                                                                                ::\\
//:: What?                                                                          ::\\
//::   1. Heal lets you heal units using a certain function.                        ::\\
//::   2. It is recommended that all healing in your map be done with this function.::\\
//::                                                                                ::\\
//:: Why?                                                                           ::\\
//::   1. Heal fires an event when a unit is healed.                                ::\\
//::   2. It provides a clean, standard healing function.                           ::\\
//::   3. Why should I need another reason?                                         ::\\
//::                                                                                ::\\
//:: How?                                                                           ::\\
//::   These functions are available to you.                                        ::\\
//::                                                                                ::\\
//::     Heal(unit toHeal, real amount) returns nothing                             ::\\
//::       This function heals the unit for the given amount and fires an event.    ::\\
//::                                                                                ::\\
//::     GetHealedUnit(nothing) returns unit                                        ::\\
//::       This function returns the unit healed in the event.                      ::\\
//::                                                                                ::\\
//::     GetHealAmount(nothing) returns real                                        ::\\
//::       This function returns how much a unit was healed for.                    ::\\
//::                                                                                ::\\
//::     TriggerRegisterHealEvent(trigger whichTrigger) returns nothing             ::\\
//::       This function causes the trigger to fire when a unit is healed via Heal. ::\\
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\\

library Heal requires Event

globals
    private unit u = null
    private Event e
    private real r = 0
endglobals

function TriggerRegisterHealEvent takes trigger t returns nothing
    call e.register(t)
endfunction

function GetHealedUnit takes nothing returns unit
    return u
endfunction

function GetHealAmount takes nothing returns real
    return r
endfunction

native UnitAlive takes unit id returns boolean

function Heal takes unit lu, real lr returns nothing
    if not UnitAlive(lu) then
       return
    endif
    set r = lr
    set u = lu
    call SetWidgetLife(lu, GetWidgetLife(lu) + lr)
    call e.fire()
    set r = 0
    set u = null
endfunction

private struct Sickle extends array
static method onInit takes nothing returns nothing
    set e = Event.create()
endmethod
endstruct

endlibrary


Edit II: Maybe, just maybe, this.
JASS:
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\\
//:: Heal                                                                           ::\\
//::                                                                                ::\\
//:: by your friendly neighborhood Sickle.                                          ::\\
//::                                                                                ::\\
//:: What?                                                                          ::\\
//::   1. Heal lets you heal units using a certain function.                        ::\\
//::   2. It is recommended that all healing in your map be done with this function.::\\
//::                                                                                ::\\
//:: Why?                                                                           ::\\
//::   1. Heal fires an event when a unit is healed.                                ::\\
//::   2. It provides a clean, standard healing function.                           ::\\
//::   3. Why should I need another reason?                                         ::\\
//::                                                                                ::\\
//:: How?                                                                           ::\\
//::   These functions are available to you.                                        ::\\
//::                                                                                ::\\
//::     Heal(unit toHeal, real amount) returns nothing                             ::\\
//::       This function heals the unit for the given amount and fires an event.    ::\\
//::                                                                                ::\\
//::     HealEx(unit healer, unit toHeal, real amount) returns nothing              ::\\
//::       This function heals the unit for the given amount and fires an event.    ::\\
//::                                                                                ::\\
//::     GetHealedUnit(nothing) returns unit                                        ::\\
//::       This function returns the unit healed in the event.                      ::\\
//::                                                                                ::\\
//::     GetHealer(nothing) returns unit                                            ::\\
//::       This function returns the healer (if any) in the event.                  ::\\
//::                                                                                ::\\
//::     GetHealAmount(nothing) returns real                                        ::\\
//::       This function returns how much a unit was healed for.                    ::\\
//::                                                                                ::\\
//::     TriggerRegisterHealEvent(trigger whichTrigger) returns nothing             ::\\
//::       This function causes the trigger to fire when a unit is healed via Heal. ::\\
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\\

library Heal requires Event

globals
    private unit u = null
    private unit h = null
    private Event e
    private real r = 0
endglobals

function TriggerRegisterHealEvent takes trigger t returns nothing
    call e.register(t)
endfunction

function GetHealedUnit takes nothing returns unit
    return u
endfunction

function GetHealAmount takes nothing returns real
    return r
endfunction

function GetHealer takes nothing returns unit
    return h
endfunction

native UnitAlive takes unit id returns boolean

function Heal takes unit lu, real lr returns nothing
    if not UnitAlive(lu) then
       return
    endif
    set r = lr
    set u = lu
    call SetWidgetLife(lu, GetWidgetLife(lu) + lr)
    call e.fire()
    set r = 0
    set u = null
endfunction

function HealEx takes unit lh, unit lu, real lr returns nothing
    if not UnitAlive(lu) then
       return
    endif
    set r = lr
    set u = lu
    set h = lh
    call SetWidgetLife(lu, GetWidgetLife(lu) + lr)
    call e.fire()
    set r = 0
    set u = null
    set lh = null
endfunction

private struct Sickle extends array
static method onInit takes nothing returns nothing
    set e = Event.create()
endmethod
endstruct

endlibrary
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
He is going to use his version of Heal to crush your map by making the functionality of GetWidgetLife > .405 fails. :p
 

Sickle

New Member
Reaction score
13
Here. Let me fix that then. Import this and find and replace GetWidgetLife(u) > .405 with IsUnitAlive(u). Alternatively, I updated my script.

JASS:
library IsUnitAlive

native UnitAlive takes unit id returns boolean

function IsUnitAlive takes unit u returns boolean
    return UnitAlive(u)
endfunction

function IsUnitDead takes unit u returns boolean
    return not UnitAlive(u)
endfunction

endlibrary
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
JASS:
library HealCrusher initializer Init requires Heal
    
    private function Cond takes nothing returns boolean
        call Heal(GetHealedUnit(),100.)
        return false
    endfunction
    
    private function Init takes nothing returns nothing
          local trigger trig = CreateTrigger()
          call TriggerRegisterHealEvent(trig)
          call TriggerAddCondition(trig,Condition(function Cond))
    endfunction
endlibrary

Put this library into a map.
Make a healing spell with your library, then cast it. See what happen.

JASS:
library HealCrusher initializer Init requires Heal
    
    private function Cond takes nothing returns boolean
        call HealUnit(Heal_GetSource(),Heal_GetTriggerUnit(),100.)
        return false
    endfunction
    
    private function Init takes nothing returns nothing
          local trigger trig = CreateTrigger()
          call Heal_RegisterEvent(trig)
          call TriggerAddCondition(trig,Condition(function Cond))
    endfunction
endlibrary

Use this with my library. Test the spell. Compare them.
 

Sickle

New Member
Reaction score
13
Whoop dee doo. Yours works recursively. Somewhat.

I could achieve what your system does with a single check. But that would be stupid. Recursive healing is madness.
 

Sickle

New Member
Reaction score
13
Yes. I know.

His is recursively defined. Somewhat.

I could add a single check and mine is fixed.
 

Viikuna

No Marlo no game.
Reaction score
265
Somethign like this is indeed useful, since it makes it easy to create for example some buff types that make unit unhealable or something, or some thingies that incerease healing done or whatever.

But its so simple, that it might be easier for user to make it himself. Dont really know.
 

Weep

Godspeed to the sound of the pounding
Reaction score
401
// Questions : UnitDamageTarget does healing
// effect when negative damage amount is used
// as arguement. Why we need to use this?
//
// Truth : UnitDamageTarget works but it is not
// detectable by EVENT_UNIT_DAMAGED.

Uh, what? Negative target damage only works with spell-type damage (otherwise is 0) and can be detected by EVENT_UNIT_DAMAGED just fine.
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
Uh, what? Negative target damage only works with spell-type damage (otherwise is 0) and can be detected by EVENT_UNIT_DAMAGED just fine.
Oh, ya. Forget to update it, it works just fine.

However, some damage detection systems do GetEventDamage() > 0. filtration before executing triggers.
 

Jesus4Lyf

Good Idea™
Reaction score
397
However, some damage detection systems does GetEventDamage() > 0. filtration before executing triggers.
Post in the threads of such systems and complain. I don't think we have any at TheHelper.
JASS:
Heal_Enable(unit, flag)

Heal_Bock(amount) makes much more sense, because it can be totally conditional.
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
Heal_Bock(amount) makes much more sense, because it can be totally conditional.
Okay. :)
 

Advice D.

New Member
Reaction score
11
Just a few things I noticed:
JASS:
//  Heal_Unit(healer, target, amount)
Should be "HealUnit"?
JASS:
            if life == maxlife then
                return false//If target has full hp, no healing is done.
            else
                set amount = maxlife - life //if current hp + amount &gt; max hp, set amount to max hp - current hp.
                call SetWidgetLife(target,life + amount)
            endif
This ends up fully healing regardless of the amount used in the function call. Add a hp check, perhaps?
EDIT: Just tested it without the maxlife-life line and it worked fine. Is there any reason for it to be in at all?
 

XeNiM666

I lurk for pizza
Reaction score
138
Hmmm. Nice system. Just what I needed for a spell... XD

May I suggest a "Heal over time" function?
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
@Advice D.
Should be "HealUnit"?
That was a typo. >< My bad.

This ends up fully healing regardless of the amount used in the function call. Add a hp check, perhaps?
EDIT: Just tested it without the maxlife-life line and it worked fine. Is there any reason for it to be in at all?

I will look into it. :p

@XeNiM666
3 flavors here for you to choose. :)

JASS:
/////////////////////////////////////////////////////////////
//
//                  Timed Healing (Blue)
//                        v1.0.0
//  
//                  An add-on for Heal.
//
//     It enables &quot;healing over time&quot; can be done easily.
//
//  Functions provided :
//  TimedHealUnit(healer,target,amount,period,duration,effect)
//
//  Info :
//  Blue   : Uses KT2
//  Red    : Uses T32 (For speed freaks)
//  Purple : Uses TimerUtils (For those who does not like KT2)
//
//  Blue and Purple flavor are able to deal with any period.
//  Red flavor is only able to heal every .03125 (T32&#039;s period)
//////////////////////////////////////////////////////////////
library_once TimedHealing requires Heal, KT

    private struct Data
        unit healer
        unit target
        real amount
        real tick
        effect eff
        
        method onDestroy takes nothing returns nothing
            call DestroyEffect(.eff)
            set .eff = null
        endmethod
        
    endstruct
    
    private function Handler takes nothing returns boolean
        local Data d = KT_GetData()
        if d.tick &gt; 0 then
            set d.tick = d.tick - 1
            if HealUnit(d.healer,d.target,d.amount) == false then
                call d.destroy()
                return true
            endif
            return false
        endif
        call d.destroy()
        return true
    endfunction

    function TimedHealUnit takes unit healer, unit target, real totalAmount, real period, real duration, effect eff returns nothing
        local Data d = Data.create()
        set d.healer = healer
        set d.target = target
        set d.tick = R2I(duration / period)
        set d.amount = totalAmount / period
        set d.eff = eff
        call KT_Add(function Handler,d,period)
    endfunction
endlibrary


JASS:
/////////////////////////////////////////////////////////////
//
//                  Timed Healing (Red)
//                        v1.0.0
//  
//                  An add-on for Heal.
//
//     It enables &quot;healing over time&quot; can be done easily.
//
//  Functions provided :
//  TimedHealUnit(healer,target,amount,period,duration,effect)
//
//  Info :
//  Blue   : Uses KT2
//  Red    : Uses T32 (For speed freaks)
//  Purple : Uses TimerUtils (For those who does not like KT2)
//
//  Blue and Purple flavor are able to deal with any period.
//  Red flavor is only able to heal every .03125 (T32&#039;s period)
//////////////////////////////////////////////////////////////
library_once TimedHealing requires Heal, T32

    private struct Data
        unit healer
        unit target
        real amount
        real tick
        effect eff
        
        method onDestroy takes nothing returns nothing
            call DestroyEffect(.eff)
            set .eff = null
        endmethod
        
        method periodic takes nothing returns nothing
            if .tick &gt;= T32_Tick then
                if HealUnit(.healer,.target,.amount) == false then
                    call .destroy()
                    call .stopPeriodic()
                endif
            else
                call .destroy()
                call .stopPeriodic()
            endif
        endmethod
        
        implement T32x
        
        static method add takes unit healer, unit target, real totalAmount, real duration, effect eff returns nothing
            local thistype this  = thistype.create()
            set .healer = healer
            set .target = target
            set .tick = T32_Tick + R2I(duration / T32_PERIOD)
            set .amount = totalAmount / T32_PERIOD
            set .eff = eff
            call .startPeriodic()
        endmethod
    endstruct

    function TimedHealUnit takes unit healer, unit target, real totalAmount, real duration, effect eff returns nothing
        call Data.add(healer,target,totalAmount,duration,eff)
    endfunction
endlibrary


JASS:
/////////////////////////////////////////////////////////////
//
//                  Timed Healing (Purple)
//                        v1.0.0
//  
//                  An add-on for Heal.
//
//     It enables &quot;healing over time&quot; can be done easily.
//
//  Functions provided :
//  TimedHealUnit(healer,target,amount,period,duration,effect)
//
//  Info :
//  Blue   : Uses KT2
//  Red    : Uses T32 (For speed freaks)
//  Purple : Uses TimerUtils (For those who does not like KT2)
//
//  Blue and Purple flavor are able to deal with any period.
//  Red flavor is only able to heal every .03125 (T32&#039;s period)
//////////////////////////////////////////////////////////////
library_once TimedHealing requires Heal, TimerUtils

    private struct Data
        unit healer
        unit target
        real amount
        real tick
        effect eff
        timer t
        
        method onDestroy takes nothing returns nothing
            call ReleaseTimer(.t)
            call DestroyEffect(.eff)
            set .eff = null
        endmethod
        
    endstruct
    
    private function Handler takes nothing returns boolean
        local Data d = GetTimerData(GetExpiredTimer())
        if d.tick &gt; 0 then
            set d.tick = d.tick - 1
            if HealUnit(d.healer,d.target,d.amount) == false then
                call d.destroy()
            endif
            return false
        endif
        call d.destroy()
        return true
    endfunction

    function TimedHealUnit takes unit healer, unit target, real totalAmount, real period, real duration, effect eff returns nothing
        local Data d = Data.create()
        set d.healer = healer
        set d.target = target
        set d.tick = R2I(duration / period)
        set d.amount = totalAmount / period
        set d.eff = eff
        set d.t = NewTimer()
        call SetTimerData(d.t,d)
        call TimerStart(d.t,period,true,function Handler)
    endfunction
endlibrary


Update :
v1.0.3 released. Credits to Advice D. for finding out the bug.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      • Ghan
        Administrator - Servers are fun

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top