System Toggle HP Regen

the Immortal

I know, I know...
Reaction score
51
A hack-ish way to disable unit's life regeneration. Has its cons, and as such, I suppose, non-suitable for approval. But still worth the submission imo, as I haven't seen a better way to disable a unit's HP regeneration (actually haven't seen any).

Requires AIDS
Optionally uses Damage

API / Usage / Cons list and everything is in the script.

JASS:
library ToggleHPRegen initializer onInit requires AIDS optional Damage
    /*
      Overview:
        Allows toggling of unit's life regeneration / healing. 
        Uses kinda hack-ish method but works without problems from what I observed. 
        Optionally uses Damage to register for onDamage events.
        
      API:
        ToggleRegen(unit u, boolean disable)
            - disables or enables the unit's regeneration. 
        
        SetUnitLifeEx(unit whichUnit, real newLife)
            - sets whichUnit's life to newLife. Works when its regen is disabled
        
      How to import: 
         - Make sure you have a vJASS compiler (JassHelper) and then simply
         - Copy this script into any trigger object
         
      Inner workings:
        Mantains a stack with all units who have their regens disabled and re-sets 
        their life several times per second (default - 33) to a value. Thus regeneration 
        (and respectively any heal) gets disabled. That value also gets updated each 
        time the unit takes damage so it doesnt become immune to damage. 
        
      Cons:
         - life regeneration over ~100/sec gets visible at default PERIOD (0.03)
           FIX: use smaller period. 
           
         - Any heals also get disabled. Not sure if it counts as a 'con' though. 
           Still, the SetUnitLifeEx function is here for such heals. 
           Can also add a SetWidgetLife/SetUnitState hook if someone thinks it'd be useful
           
      Thx to:
         - J4L's nicey systems
         - Tyrande_Ma3x for original idea. 
    */
    
    globals
        //How often to update unit's HP
        //33 fps should be pretty enough for most maps
        private constant real PERIOD = 0.03
    endglobals
    
    //----------------------------------------------------------------------------------------
    
    private struct RegData extends array
        real HP
        boolean e
        integer num
        trigger trgOnDmg
        
        private method AIDS_onDestroy takes nothing returns nothing
            set e = false
        endmethod
        
        // Really just better/faster with AIDS_RegisterOnLeave(..)
        // but J4L said not to use it!! Q_Q
        //! runtextmacro AIDS()
    endstruct
    
    globals
        private trigger trgOnDamage = CreateTrigger()
        private timer timPeriodic = CreateTimer()
        private unit array ug
        private integer uc = 0
        private RegData rd
    endglobals
    
    private function onPeriod takes nothing returns nothing
        set rd = 0  //use as iterator. -1 var!
        loop
            exitwhen rd == uc
            call SetWidgetLife(ug[rd], RegData[ug[rd]].HP)
            set rd = rd + 1
        endloop
    endfunction
    
    private function onDamage takes nothing returns boolean
        set rd = RegData[GetTriggerUnit()]
        static if LIBRARY_Damage then
            if rd.e then
                set rd.HP = rd.HP - GetEventDamage()
                call SetWidgetLife(GetTriggerUnit(), rd.HP)   //fixes cheat death bug
            endif
        else    //no need for check since only units with disabled regen trigger this
            set rd.HP = rd.HP - GetEventDamage()
            call SetWidgetLife(GetTriggerUnit(), rd.HP)   //fixes cheat death bug
        endif
        return false
    endfunction
    
    function SetUnitLifeEx takes unit whichUnit, real newLife returns nothing
        set RegData[whichUnit].HP = newLife
        call SetWidgetLife(whichUnit, newLife)
    endfunction
    
    function ToggleRegen takes unit u, boolean stop returns nothing
        set rd = RegData<u>
        if rd.e == stop then
            return
        endif
        
        set rd.e = stop
        
        if stop == true then
            set rd.HP = GetWidgetLife(u)
            
            if uc == 0 then
                //ResumeTimer bugs? :/
                call TimerStart(timPeriodic, PERIOD, true, function onPeriod)
            endif
            
            set ug[uc] = u
            set rd.num = uc
            set uc = uc + 1
            
            static if not LIBRARY_Damage then
                if rd.trgOnDmg == null then
                    set rd.trgOnDmg = CreateTrigger()
                    call TriggerAddCondition(rd.trgOnDmg, Condition(function onDamage))
                    call TriggerRegisterUnitEvent(rd.trgOnDmg, u, EVENT_UNIT_DAMAGED)
                endif
            endif
        else
            
            set uc = uc - 1
            set RegData[ug[uc]].num = rd.num
            set ug[rd.num] = ug[uc]
            
            static if not LIBRARY_Damage then
                call DestroyTrigger(rd.trgOnDmg)
                set rd.trgOnDmg = null
            endif
            
            if uc == 0 then
                call PauseTimer(timPeriodic)
            endif
            
        endif
    endfunction
    
    private function onInit takes nothing returns nothing
        static if LIBRARY_Damage then
            call Damage_RegisterEvent(trgOnDamage)
        endif
        call TriggerAddCondition(trgOnDamage, Condition(function onDamage))
        call TimerStart(timPeriodic, PERIOD, true, function onPeriod)
        call PauseTimer(timPeriodic)
    endfunction
endlibrary</u>


Also, if someone is willing to take a look, I had to re-start the timer instead of resuming it as resuming actually runs the timer 2-3 times and then stops. Had the same issue in another project of mine.
Not that it matters performance-wise.


Oh, and yes, the test map sucks. I know.
 

Attachments

  • StopRegen.w3x
    43.1 KB · Views: 420

13lade619

is now a game developer :)
Reaction score
398

the Immortal

I know, I know...
Reaction score
51
You could. But it wouldn't be as precise and good as mine (even though the latter isn't perfect, as well, as I said).

Also from what I see your code will allow a unit to regen at 3/10 speed of its normal reg speed (which is a nice idea btw). But let's say it just disables it. You would also need AIDS. And internally my script does the same as T32 - one timer, one stack - it's just one dependency less. But mine also takes into account damage taken. Look, what if:

First, if a unit gets damaged after a regen tick but before timer tick (which IS possible)? Its life will be [Prev life] + [Regenerated value] - [Damage Taken]. Maybe not that much of a problem, but on a unit with lots of regen it may get noticed or imbalanced.

Then, the continuation. Unit with life locked to X takes X+1 damage (or, really, 1-10 damage more). But it has regenerated some health since the last lock (yeah, a 0.03125 seconds, but still a real possibility on a unit with larger regen rate). So the unit doesn't die until the next tick of the timer due to setting it's life to <0. But now it's counted as a suicide!

Very slim chances, but let's be on the safe side. What makes this script bigger than yours are also the function that can heal through disabled regen and the spaghettiness of the static if's that utilize Damage if it's present. Apart from that (and the damage detection) it does exactly the same.
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
The solution already exists, you don't need this library anyway unless this library provides better functionality than it. :)

Bug report : When ToggleRegen(unit,true) is called, any healing spells will fail for the unit. :S
 

the Immortal

I know, I know...
Reaction score
51
Wasn't aware of your solution, but from what I see it has a real different approach.
Your one triggers the entire regeneration and thus requires setup for every different unit-type. Not that it's bad, it's simply too much work for what mine does - disable HP regen.

And in such a meaning no, it is not 'better', it is just different:
As the fact that not everyone uses Damage for its damage-source-type detecting capabilities (which requires triggering all the damage), nor everyone uses FS inventories (which require importing all items' data in their scripts)... they need far too much setup. (or a good object data reading program ^.-).


My 2 cents on why it could prove useful.
(plus the fact I wanna use it for the Tower Contest)


PS. And, hey, you've added this library after I submitted mine! Darn competition! =O

PPS.
Cons:
- Any heals also get disabled. Not sure if it counts as a 'con' though.
Still, the SetUnitLifeEx function is here for such heals.
Can also add a SetWidgetLife/SetUnitState hook if someone thinks it'd be useful
Documented ;o Should I implement an optional hook?
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
PS. And, hey, you've added this library after I submitted mine! Darn competition! =O
I had the idea for it first, look at the last page. I posted the unit regeneration library long time ago. I planned to release it long time ago, including triggered regeneration abilities on item for units. :p

Your one triggers the entire regeneration and thus requires setup for every different unit-type. Not that it's bad, it's simply too much work for what mine does - disable HP regen.
Hmm, actually that's not much work on it. Just set 0.000 unit regeneration rate and trigger unit hp regeneration rate for the units needed, ignore the units that is not used.
 

Attachments

  • StopRegen.w3x
    39.1 KB · Views: 356

Viikuna

No Marlo no game.
Reaction score
265
Or just make some GSL script for getting those those initial values from object editor and writing them for you.

Anyways, this should be done with some bonus system, like UnitProperties, Bonusmod or Status. This system is not really needed.
 

the Immortal

I know, I know...
Reaction score
51
Still, as a small, snippet-like system, I think it should have its use.. somewhere.

The same way ordinary multi-page inventories exist despite of having Full Screen ones and whatnot - sometimes such a minimalistic approach is better in a given scenario.

Like in the current Tower Contest where that would just one of the side-effects of a tower. I can't use neither GSL nor HealCraft. Plus it'd be both an overkill and unfeasible granted a prerequisite is an easy importing. I needed it, I made it, decided it could be useful, and thus - posted it.

If you think it isn't - feel free to GY it.

//off for the rest of the upcoming night. Cheers!
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +1
  • V-SNES V-SNES:
    Happy Friday!
    +1

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top