System HealCraft (Add-On for Heal)

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
JASS:
////////////////////////////////////////////////////////
//
//      -----------------
//      |   HealCraft   |   ~ v1.0.2 ~
//      -----------------
//                                       by kingking
//  ==================
//  What's HealCraft?
//  ==================
//  HealCraft simulates normal unit regeneration
//  and provides some handy functions like 
//  firing triggers when units' hp are gained.
//
//  ==================
//  Why use it?
//  ==================
//  Some users tried to use some kinds of snippet to 
//  block units' normal regeneration but it is not the
//  best solution. HealCraft is aimed to solve that.
//
//  =====================
//  Functions provided :
//  =====================
//  SetUnitTypeRegeneration(integer unitid,real amount)
//  -> unitid - Type of unit, like 'hfoo' for footmen
//  -> amount - Amount of regeneration per second
//
//  HealCraft_RegisterEvent(trigger)
//  HealCraft_UnregisterEvent(trigger)
//  -> Wrapper for unit hp regeneration event.
//  -> You can use Heal_RegisterEvent + NORMAL_HP_REGEN
//     constants too, they are same.
//  -> This is just for better readability.
//
//  HealCraft_EnableCallback(unit whichUnit, boolean flag)
//  -> Activate/Deactivate the regen event for unit.
//  -> It uses stack, you must decrease it 
//     to 0 if you want to disable the callback.
//  -> The event is disabled by default.
//
//  --------------------------------------
//  ~ Useful functions for callbacks.
//  --------------------------------------
//  Heal_GetTarget() -> unit
//  -> Simulates GetTriggerUnit for the event.
//
//  Heal_GetAmount() -> real
//  -> Return the amount of hp regenerated.
//
//  Heal_Block(real amount)
//  -> Block certain amount of regenerated hp.
//
//  Heal_BlockAll()
//  -> Block the hp regeneration of unit for
//     current instance.
//
//  ============
//  Constants :
//  ============
//  HEALS_PER_SECOND
//  -> How fast the unit will get hp regeneration.
//  -> Too high( >32 ) will cripple the performance if you 
//     have too many units on map.
//  
//  NORMAL_HP_REGEN
//  -> Heal type for healing event.
//
//  =============
//  Extra Info :
//  =============
//  ~ You must set the unit regeneration for all units
//    to 0.000 in Object Editor. (Apply this for unit
//    types that are used in your map, just leave
//    those are not used in your map. <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite1" alt=":)" title="Smile    :)" loading="lazy" data-shortname=":)" /> )
//  ~ You must set Hero Attributes - HP Regen. Bonus
//    per Strength Point to 0.00
//  ~ You must set the value of unit regeneration in
//    this library if you want hp regeneration for the 
//    unit.
//
//  ===========
//  Requires :
//  ===========
//  AIDS by Jesus4Lyf
//  Heal by kingking
//  Event by Jesus4Lyf
//  Jasshelper 0.A.2.B or newer
/////////////////////////////////////////////////////////
library HealCraft requires AIDS, Heal, Event
    
    globals
        public constant real HEALS_PER_SECOND = 32
    endglobals
    
    globals
        HealType NORMAL_HP_REGEN
        private Event OnHeal
        private hashtable hasht = InitHashtable()
    endglobals
    
    public function RegisterEvent takes trigger whichTrigger returns EventReg
        return OnHeal.register(whichTrigger)
    endfunction
    
    public function UnregisterEvent takes trigger whichTrigger returns nothing
        call OnHeal.unregister(whichTrigger)
    endfunction
    
    private keyword Data
    
    public function EnableCallback takes unit whichUnit, boolean flag returns nothing
        if flag == true then
            set Data[whichUnit].stackLevel = Data[whichUnit].stackLevel + 1
        elseif Data[whichUnit].stackLevel &gt; 0 then
            set Data[whichUnit].stackLevel = Data[whichUnit].stackLevel - 1
        endif
    endfunction
    
    function SetUnitTypeRegeneration takes integer whichId,real amount returns nothing
        call SaveReal(hasht,whichId,0,amount / HEALS_PER_SECOND)
    endfunction
    
    private struct EventWrapper extends array
        private static method Cond takes nothing returns boolean
            if Heal_GetType() == NORMAL_HP_REGEN then
                call OnHeal.fire()
            endif
            return false
        endmethod
        private static method onInit takes nothing returns nothing
            local trigger trig = CreateTrigger()
            set OnHeal = Event.create()
            call Heal_RegisterEvent(trig)
            call TriggerAddCondition(trig,Condition(function thistype.Cond))
        endmethod
    endstruct
    
    private struct Data extends array
        private thistype next
        private thistype prev
        integer stackLevel
        
        private method AIDS_onCreate takes nothing returns nothing
            set this.prev = thistype(0).prev
            set this.next = thistype(0)
            set thistype(0).prev.next = this
            set thistype(0).prev = this
            //Link
        endmethod
        
        private method AIDS_onDestroy takes nothing returns nothing
            set this.next.prev = this.prev
            set this.prev.next = this.next
            set this.stackLevel = 0
            //Unlink
        endmethod
        
        private static method periodicHandler takes nothing returns nothing
            local thistype this = 0
            loop
                set this = this.prev//Should be faster than array stack.
            exitwhen this == 0
                if this.stackLevel &gt; 0 then
                    call HealUnit(this.unit,this.unit,LoadReal(hasht,GetUnitTypeId(this.unit),0),NORMAL_HP_REGEN)
                else
                    if GetWidgetLife(this.unit) &gt; .405 then
                        call SetWidgetLife(this.unit,GetWidgetLife(this.unit) + LoadReal(hasht,GetUnitTypeId(this.unit),0))
                    endif
                endif
            endloop
        endmethod
        
        private static method AIDS_onInit takes nothing returns nothing
            set NORMAL_HP_REGEN = HealType.new()
            call TimerStart(CreateTimer(),1. / HEALS_PER_SECOND,true,function thistype.periodicHandler)
        endmethod
        //! runtextmacro AIDS()
    endstruct
    
endlibrary


HealCraft requires Event | Heal | AIDS


HealCraft
v1.0.0 - Release
v1.0.1 - Changed Jesus4Lyf's Hash to Table + My Hash algorithm, efficiency increased.
v1.0.2 - Does not use hash anymore, use hashtable attachment instead. Regen event is disabled by default. New function is added to let users to enable/disable regen event.
 
I really think firing an event on every regeneration tick for every unit is a terrible idea.

Think about the complexity. Let's say you have 2 triggers that fire on unit regen, and 10 units on the map. 32x2x10 gives you 640 trigger execs/evals per second. The value added? Minimal... Imagine the lag if you had more than 10 units (that's not uncommon) or more than 2 triggers. That's the reason I wanted this pulled from the Heal system thread - because this cannot be approved in its current state. It is detrimental to mappers. :)

You need to think more carefully about what you want achieved with this. Personally, I recommend enabling/disabling unit hp regeneration, and you could do this with a stack like the status effects in Status. But Status already also handles unit regen, so I'm not sure what the point of this system is.

What exactly are you trying to achieve?

PS. Your attaching to unit type ids can be drastically optimised by using either removing Table or removing Hash. If you remove both and use a hashtable directly to load/save a real, even better. :)
 
I really think firing an event on every regeneration tick for every unit is a terrible idea
Lower HEALS_PER_SECOND. You can get less lag. :)

v1.0.2 is released. I found a workaround to fix this issue. :p
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    And since almost all of my programming experience is with defunct shit now, I figure my best place is helping preserve legacy stuff. Which I don't know how to do necessarily, but I need some kind of a hobby and figuring out how older things worked is the only shit that really interests me. Well soldering and restoration is fun too, but no one is bringing me new stuff to fix and restore, so it's mostly old shit, and I LOVE OG Xbox so much. I want to make sure it can function as long as possible, until someone can effectively emulate it at least. I have like 15 I was going to fix over the winter and didn't get to.
    +1
  • Varine Varine:
    I also have a couple OG gameboys, but idk if I can do that without like, manufacturing new parts that no one makes anymore and I can't do that right now
  • tom_mai78101 tom_mai78101:
    Currently in the middle of getting the probate process going. We're doing the informal probate process.
    +3
  • Varine Varine:
    A probate is usually done with a will, yes? If so I am sorry for your loss
    +1
  • The Helper The Helper:
    Yeah Tom, me too sorry for your loss buddy my mom told me she finds out her olds friend died from Google searching them. She had not talked to one of her old friends in a year and found out she died from Google. Also another one in the same session. RIP all of them my sincere condolences Tom
    +1
  • Varine Varine:
    We have some elderly guests that regularly come hang out at the bar at the end of the night, and every once in a while we don't see someone for a few weeks and then someone shows up with their obituary.
  • Varine Varine:
    We usually let them do their memorials there in the morning if they want to and I'll make them some snacks and drinks. There was one guy named Tom that came in like every night and would sit by himself and get a bunch of soup and a glass of wine. idk why but he LOVED our fucking soup, like he would order a fucking quart of it at a time and would always get so sad when we stop doing it for the summer.
    +1
  • Varine Varine:
    But he also loved our calamari, which is another thing I hate but it sells super well so I can't change it. There was one day he came in and was asking me how to make it, because he tried to at home once in the off season when we stop running it and he really wanted it lol
  • Varine Varine:
    I think he's one of the only people I've made recipes for for free because he really wanted a broccoli cheddar, and it was like dude I don't have a recipe, it's just whatever I have, but here, this is how you do it
  • Varine Varine:
    I don't think he ever figured out how to do the calamari in a pan though, like idk how to do that either. He was afraid of the at home deep fryers though and it's like yeah, that's fair, I am too
  • Varine Varine:
    He was just such a sweet old man, we had two servers pregnant and they held a baby shower together, he was soooooo fucking excited to get to see a baby. Unfortunately he died a month or so before they were born
  • The Helper The Helper:
    So I decided to Google some people that I had not seen or heard from in a while and sure enough one of my old best friends, we had a falling out years ago but whatever, find out he died of Pancreatic Cancer in January. I have also lost a few of my closer acquaintances from growing up the last year. Getting old - people die - I kinda thought it was going to be this way a few years ago....
    +2
  • The Helper The Helper:
    Forum running super slow again
  • Ghan Ghan:
    Not really clear from the stats as to what is causing the slowness.
  • Ghan Ghan:
    We get a lot of guest traffic so it may just be the load is getting too high and not from any particular source.
  • Ghan Ghan:
    Looks like the server is maxed out on CPU.
  • Ghan Ghan:
    Oh it looks like a lot of the traffic is Silkroad Forums. That domain isn't protected by Cloudflare.
  • Ghan Ghan:
    But the old Silkroad site is still on its own server. I just had a test site set up on this server for it.
  • Ghan Ghan:
    I just disabled that test site. Let's see if that helps the load.
  • Ghan Ghan:
    Looks much better already.
  • The Helper The Helper:
    I had actually forgot about the Silkroad site. I had asked
  • The Helper The Helper:
    SD Ryoko about it and he said the couple of people left on there really like it, that was a few years ago, maybe I should check back
  • jonas jonas:
    I guess when you're getting old, and the last day of soup season draws near, you start wondering
  • jonas jonas:
    will I make it to the start of the next season? or was this the last time I'll ever have my favorite dish?
  • The Helper The Helper:
    I am doing my first Vibe Coding project. In installed the environment and tools according to instructions but it is all chat doing this for me at my direction. It is fun really and holy shit I might finish in 2 hours what it would have taken a day to in my Access and this would be an electron app complete new

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials
      Top