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: 633

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
400
// 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
  • The Helper The Helper:
    Actually I was just playing with having some kind of mention of the food forum and recipes on the main page to test and see if it would engage some of those people to post something. It is just weird to get so much traffic and no engagement
  • The Helper The Helper:
    So what it really is me trying to implement some kind of better site navigation not change the whole theme of the site
  • Varine Varine:
    How can you tell the difference between real traffic and indexing or AI generation bots?
  • The Helper The Helper:
    The bots will show up as users online in the forum software but they do not show up in my stats tracking. I am sure there are bots in the stats but the way alot of the bots treat the site do not show up on the stats
  • Varine Varine:
    I want to build a filtration system for my 3d printer, and that shit is so much more complicated than I thought it would be
  • Varine Varine:
    Apparently ABS emits styrene particulates which can be like .2 micrometers, which idk if the VOC detectors I have can even catch that
  • Varine Varine:
    Anyway I need to get some of those sensors and two air pressure sensors installed before an after the filters, which I need to figure out how to calculate the necessary pressure for and I have yet to find anything that tells me how to actually do that, just the cfm ratings
  • Varine Varine:
    And then I have to set up an arduino board to read those sensors, which I also don't know very much about but I have a whole bunch of crash course things for that
  • Varine Varine:
    These sensors are also a lot more than I thought they would be. Like 5 to 10 each, idk why but I assumed they would be like 2 dollars
  • Varine Varine:
    Another issue I'm learning is that a lot of the air quality sensors don't work at very high ambient temperatures. I'm planning on heating this enclosure to like 60C or so, and that's the upper limit of their functionality
  • Varine Varine:
    Although I don't know if I need to actually actively heat it or just let the plate and hotend bring the ambient temp to whatever it will, but even then I need to figure out an exfiltration for hot air. I think I kind of know what to do but it's still fucking confusing
  • The Helper The Helper:
    Maybe you could find some of that information from AC tech - like how they detect freon and such
  • Varine Varine:
    That's mostly what I've been looking at
  • Varine Varine:
    I don't think I'm dealing with quite the same pressures though, at the very least its a significantly smaller system. For the time being I'm just going to put together a quick scrubby box though and hope it works good enough to not make my house toxic
  • Varine Varine:
    I mean I don't use this enough to pose any significant danger I don't think, but I would still rather not be throwing styrene all over the air
  • The Helper The Helper:
    New dessert added to recipes Southern Pecan Praline Cake https://www.thehelper.net/threads/recipe-southern-pecan-praline-cake.193555/
  • The Helper The Helper:
    Another bot invasion 493 members online most of them bots that do not show up on stats
  • Varine Varine:
    I'm looking at a solid 378 guests, but 3 members. Of which two are me and VSNES. The third is unlisted, which makes me think its a ghost.
    +1
  • The Helper The Helper:
    Some members choose invisibility mode
    +1
  • The Helper The Helper:
    I bitch about Xenforo sometimes but it really is full featured you just have to really know what you are doing to get the most out of it.
  • The Helper The Helper:
    It is just not easy to fix styles and customize but it definitely can be done
  • The Helper The Helper:
    I do know this - xenforo dropped the ball by not keeping the vbulletin reputation comments as a feature. The loss of the Reputation comments data when we switched to Xenforo really was the death knell for the site when it came to all the users that left. I know I missed it so much and I got way less interested in the site when that feature was gone and I run the site.
  • Blackveiled Blackveiled:
    People love rep, lol

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top