• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Heal Event for GUI, version 1.1.1.1

This system allows you to detect when a unit is healed, and for how much, if the heal is greater than HEAL_THRESHOLD (by default, it's set for 5.00).

Uses minimal custom script (pretty sure just 2 lines to check for Locust) so it should be a lot easier to understand than some of my other systems. To achieve this, I split each task into its own trigger, so - when importing - you'll want to copy the Heal Event trigger category for simplicity.

Game - HealEvent Becomes Equal to 1.00 - the event to use to detect a heal
Game - HealEvent Becomes Equal to 0.50 - the event to use to detect regeneration.
heal_amount - the amount healed
heal_target - the unit who was healed
heal_source - the source of the healing can be detected if you first triggered the heal using the Heal Unit <gen> trigger.

To heal a unit using this system, do the following:

Set NextHealSource = the one doing the healing
Set NextHealTarget = the unit being healed
Set NextHealAmount = the amount to be healed
Trigger - Run Heal Unit <gen> (ignoring conditions)

Requirement: GUI Unit Indexer

Optional Requirements: Damage Engine 3.5 and GUI Unit Event


  • Heal Configuration
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Configurable --------
      • Set HEAL_THRESHOLD = 5.00
      • Set HEAL_CHECK_INTERVAL = 0.05
      • -------- With these current values, a unit with 100 HP regen/sec. could constantly fire off the heal event. --------
      • -------- --------
      • Countdown Timer - Start heal_timer as a Repeating timer that will expire in HEAL_CHECK_INTERVAL seconds
      • -------- --------
      • Set REGEN_STRENGTH_VALUE = 0.05
      • Set REGEN_THRESHOLD = 5.00
      • Set REGEN_EVENT_INTERVAL = 1.00
  • Heal Unit
    • Events
    • Conditions
    • Actions
      • Custom script: local integer id = udg_heal_integer
      • Custom script: local real amount = udg_heal_amount
      • Custom script: local unit source
      • Set heal_target = NextHealTarget
      • Set heal_integer = (Custom value of heal_target)
      • Set heal_life = (Life of heal_target)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • heal_check Equal to True
        • Then - Actions
          • Set heal_check = False
          • Set heal_amount = ((heal_life - ((heal_regen[heal_integer] x (Elapsed time for heal_timer)) / HEAL_CHECK_INTERVAL)) - heal_lastLife[heal_integer])
          • -------- A potential heal still has to exceed HEAL_THRESHOLD --------
          • Set heal_diff = HEAL_THRESHOLD
        • Else - Actions
          • Unit - Set life of heal_target to ((Life of heal_target) + NextHealAmount)
          • Set heal_amount = ((Life of heal_target) - heal_life)
          • -------- If the heal ended up being less than 1.00, ignore the event --------
          • Set heal_diff = 1.00
      • -------- Don't run the event if there was little to nothing to heal --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • heal_amount Greater than or equal to heal_diff
        • Then - Actions
          • -------- Don't let the event for this heal run more than once --------
          • Set heal_lastLife[heal_integer] = (heal_lastLife[heal_integer] + heal_amount)
          • -------- Set the source, if one was assigned --------
          • Custom script: set source = udg_heal_source
          • Set heal_source = NextHealSource
          • -------- Fire the event --------
          • Set HealEvent = 0.00
          • Set HealEvent = 1.00
          • Set HealEvent = 0.00
          • -------- Reset the source, if a previous one was assigned --------
          • Custom script: set udg_heal_source = source
          • Custom script: set source = null
        • Else - Actions
      • -------- Reset variables to their previous states --------
      • Custom script: set udg_heal_amount = amount
      • Custom script: set udg_heal_integer = id
      • Set heal_target = UDexUnits[heal_integer]
      • Set NextHealAmount = 0.00
      • Set NextHealSource = No unit
      • Set NextHealTarget = No unit
  • Heal Check Loop
    • Events
      • Time - heal_timer expires
    • Conditions
    • Actions
      • Set heal_exitwhen = (heal_count - 1)
      • For each (Integer heal_integer) from 0 to heal_exitwhen, do (Actions)
        • Loop - Actions
          • Set heal_integer = heal_indices[heal_integer]
          • -------- --------
          • Set heal_target = UDexUnits[heal_integer]
          • Set heal_life = (Life of heal_target)
          • Set heal_diff = (heal_life - heal_lastLife[heal_integer])
          • Set heal_lastLife[heal_integer] = heal_life
          • -------- --------
          • Set heal_amount = (heal_diff - (Max(0.00, heal_regen[heal_integer])))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • heal_amount Greater than or equal to HEAL_THRESHOLD
            • Then - Actions
              • Set HealEvent = 1.00
              • Set HealEvent = 0.00
            • Else - Actions
              • Set heal_regen[heal_integer] = ((heal_regen[heal_integer] + heal_diff) x 0.50)
              • -------- The next section was added in version 1.1.0.0 to introduce regeneration events. --------
              • Set regen_buildup[heal_integer] = (regen_buildup[heal_integer] + heal_diff)
              • Set regen_timeleft[heal_integer] = (regen_timeleft[heal_integer] - HEAL_CHECK_INTERVAL)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • regen_timeleft[heal_integer] Less than or equal to 0.00
                • Then - Actions
                  • -------- Reset the regen event clock --------
                  • Set regen_timeleft[heal_integer] = REGEN_EVENT_INTERVAL
                  • -------- Analyze the amount regenerated in the past REGEN_CHECK_INTERVAL --------
                  • Set heal_amount = regen_buildup[heal_integer]
                  • Set regen_buildup[heal_integer] = 0.00
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (heal_target is A Hero) Equal to True
                    • Then - Actions
                      • -------- Don't spam the event due to regeneration caused by hero attributes --------
                      • Set heal_diff = (heal_amount - ((Real((Strength of heal_target (Include bonuses)))) x REGEN_STRENGTH_VALUE))
                    • Else - Actions
                      • Set heal_diff = heal_amount
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • heal_diff Greater than or equal to REGEN_THRESHOLD
                    • Then - Actions
                      • Set HealEvent = 0.50
                      • Set HealEvent = 0.00
                    • Else - Actions
                • Else - Actions
          • -------- --------
          • Set heal_integer = heal_indexRef[heal_integer]
  • Heal Adjust On Damage
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • Set NextHealTarget = DamageEventTarget
      • Set heal_check = True
      • Trigger - Run Heal Unit <gen> (ignoring conditions)
  • Heal Adjust After Damage
    • Events
      • Game - AfterDamageEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DamageEventAmount Greater than 0.00
        • Then - Actions
          • Set TempInteger = (Custom value of DamageEventTarget)
          • Set heal_lastLife[TempInteger] = ((Life of DamageEventTarget) - (heal_regen[TempInteger] x ((Elapsed time for heal_timer) / HEAL_CHECK_INTERVAL)))
        • Else - Actions
          • Set NextHealTarget = DamageEventTarget
          • Set heal_check = True
          • Trigger - Run Heal Unit <gen> (ignoring conditions)
  • Heal Add Unit
    • Events
      • Game - UnitIndexEvent becomes Equal to 1.00
      • Game - DeathEvent becomes Equal to 2.00
    • Conditions
      • heal_inSys[UDex] Equal to False
      • (UDexUnits[UDex] is Mechanical) Equal to False
      • (Default movement speed of UDexUnits[UDex]) Not equal to 0.00
    • Actions
      • Custom script: if GetUnitAbilityLevel(udg_UDexUnits[udg_UDex], 'Aloc') > 0 then
      • Skip remaining actions
      • Custom script: endif
      • Set heal_inSys[UDex] = True
      • Set heal_indices[heal_count] = UDex
      • Set heal_indexRef[UDex] = heal_count
      • Set heal_lastLife[UDex] = (Life of UDexUnits[UDex])
      • Set regen_timeleft[UDex] = REGEN_EVENT_INTERVAL
      • Set regen_buildup[UDex] = 0.00
      • Set heal_count = (heal_count + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • heal_count Equal to 1
        • Then - Actions
          • Trigger - Turn on Heal Check Loop <gen>
        • Else - Actions
  • Heal Remove Unit
    • Events
      • Game - DeathEvent becomes Equal to 0.50
      • Game - DeathEvent becomes Equal to 1.00
      • Game - DeathEvent becomes Equal to 3.00
      • Game - UnitIndexEvent becomes Equal to 2.00
    • Conditions
      • heal_inSys[UDex] Equal to True
    • Actions
      • Set heal_inSys[UDex] = False
      • Set heal_count = (heal_count - 1)
      • Set heal_indices[heal_indexRef[UDex]] = heal_indices[heal_count]
      • Set heal_indexRef[heal_indices[heal_count]] = heal_indexRef[UDex]
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • heal_count Equal to 0
        • Then - Actions
          • Trigger - Turn off Heal Check Loop <gen>
        • Else - Actions


Keywords:
heal, healing, heal event, EVENT_PLAYER_UNIT_HEALED
Contents

Just another Warcraft III map (Map)

Reviews
17:20, 17th Oct 2015 This resource has been Approved by BPower. Criticism: Very useful, when you need to detect heal events in your map. As expected very good and polished GUI coding.

Moderator

M

Moderator

17:20, 17th Oct 2015

This resource has been Approved by BPower.

Criticism:
Very useful, when you need to detect heal events in your map.
As expected very good and polished GUI coding.
 
Level 5
Joined
Aug 20, 2015
Messages
133
after a quick test i have a question - this event reacts oonly on active heal spells, not to aura effect or heal via Roar or Inner Fire spells?
 
Level 13
Joined
Jun 20, 2014
Messages
479
Maybe u can use it on some weird passive that grants a buff or something when then unit gets healed or some stage mechanics that will be triggered when a unit in your party gets healed. This is good.

edit: @ssbbssc2 it detects the heal when a unit gains a certain amout of health over a period of time.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Update to 1.0.1.0:

- Changed heal threshold to 5.00.
- Turns off the Heal Check Loop when there are no units in the system.
- Now does not add mechanical units and structures to the system.

Demo map changes:

- Updated the text tags to round off instead of just rounding down.
- Added Alchemist and Crypt Lord to show off their healing abilities. To demo Locust Swarm effectively, pull back the mortar teams so they don't auto-attack and then send the Crypt Lord to the North-East corner of the map to take some damage before using Locust Swarm.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
This system treats those as regeneration. In the Heal Event thread, I outlined that those will be not possible to get an event for without triggers. What I can do is add an additional component to the system so that if - over a period of 1 second - the unit has regenerated beyond a certain threshold it could fire a "RegenEvent". The variable which tracks regeneration already exists: heal_regen[(Custom value of unit)] / HEAL_CHECK_INTERVAL will get you the amount of regen per second.

The problem with balancing it is a hero/boss with a lot of built-in regen will mess it up. Here's a link to the original discussion for anyone who hasn't seen it, yet: http://www.hiveworkshop.com/forums/lab-715/healevent-270489/

So, what I'll do is add a trigger which runs every 1.00 seconds. Loops through all active indices. If the unit is regenerating more than HEAL_THRESHOLD per second, it will run HealEvent Equal to 0.50. This will fire for high-natural regen units, but there's no way for the system to know enough about that regen to make a difference - it can only estimate.
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
v1.1.0.0 - Added support to detect regeneration above REGEN_THRESHOLD per REGEN_CHECK_INTERVAL.

Demo Map updated with items such as scroll of regeneration and the heal text tag is now more interesting.

Clarified that DamageEngine and UnitEvent are optional and not necessary requirements. GUI Unit Indexer is the only requirement.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
In the JASS forum, there exists 2 approved resources by Magtheridon96 which overlap with some of the features of this system:

http://www.hiveworkshop.com/forums/jass-resources-412/system-getunitregeneration-203453/

http://www.hiveworkshop.com/forums/jass-resources-412/system-heal-203662/

Unfortunately, neither resource auto-detects healing ("Heal" allows you to heal a unit over time which this does not implement). Aside from that, this system incorporates the functions of those 2 systems.

There is this resource on wc3c which, still, only allows you to trigger heals: http://www.wc3c.net/showthread.php?t=104638

There is this resource on TheHelper which allows you to set a unit's regeneration (I think, it's a pretty simple resource that doesn't seem to interact with non-triggered regeneration): http://www.thehelper.net/threads/healcraft-add-on-for-heal.134996/. Lastly, the same author also made another resource for healing, but - again - just for triggering healing: http://www.thehelper.net/threads/heal.127720/

So, I guess no one made a resource to detect natural WC3 healing until now. Better late than never?
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Changed the default Heal Add Unit filter to check if the default movement speed of the unit is not equal to 0 instead of checking if it's a structure. This prevents wards from being added to the system.

Also updated the demo map to subtract 32.00 from the text tag's X position which centers it with the unit instead of having it off to the right.
 
Level 6
Joined
Oct 31, 2015
Messages
95
this probably might be necroposting but i will post anyway because i liked this system :D
I would like to report a bug when Metamorphosis ends making the system detect an infinite number of heals :p
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Well the demon hunter regenerates wildly while metamorphosized, so I think what I should add to this is an additional threshold which can be assigned per unit-type for cases like this. It will require a hashtable to index the individual threshold to a unit type.

Alternatively, you could just remove the 0.50 heal event from that trigger which displays regen. It's unimportant as it fires once per second as opposed to heals which fire just about exactly when the heal takes effect.
 
Level 6
Joined
Oct 31, 2015
Messages
95
Every time I cast metamorphosis the system also seems to increase the healing. The results of the tests I've made with a lvl 6 normal Demon Hunter:
1º Cast: first shows +500 hp from the skill bonus. When ends detects infinites +250.
2º Cast: shows the +500 hp. When ends detects infinites +375.
3º Cast +500 hp then infinites +438... (I believe it never ends)

I've also tested with a 0 bonus hp Metamorphosis and a Bear Form skill. When the Druid return to his normal form the infinite heals are displayed (Bear has greater hp than druid just as the normal metamorphosed demon hunter) but the demon hunter (with the 0 hp bonus skill) does not display the healing bug anymore.
Seems to bug when the new unit have different hp from the normal one.
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
I found the problem, but I won't be able to update this for a while.

To fix the problem, below the condition in the loop trigger, "heal_amount Greater than or equal to HEAL_THRESHOLD", add the real comparison, "heal_regen[heal_integer] Greater than 0.00".

This will completely fix the problem.

Please update to the newest Heal Event. I have fixed a critical issue where if a unit loses more than HEAL_THRESHOLD life either due to negative regeneration or a lower-HP transform that it would cause an infinite heal loop on that unit.

I had been subtracting the heal_regen amount to negate any regeneration, but it then treats negative regeneration as healing so I had to do a Max(0, regen) to get that bug resolved.
 
Level 7
Joined
Aug 11, 2010
Messages
269
Another fantastic system. And just what I was looking for to compliment your damage system (Funnily enough something I asked in the comments about)

I do have a question, is it possible to disable regeneration and/or multiply healing before it happens using this system?
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
The system cannot catch regen or healing below REGEN_THRESHOLD or HEAL_THRESHOLD. Aside from that, you can add an event response (heal_event equal to 0.50 for regen or 1.00 for heal) then modify the unit's HP manually higher or lower. If you want to increase the fluidity of regen in the unit's hit points display, you can lower the REGEN_EVENT_INTERVAL (you'll want to lower the REGEN_THRESHOLD to scale).
 
Level 7
Joined
Aug 11, 2010
Messages
269
The system cannot catch regen or healing below REGEN_THRESHOLD or HEAL_THRESHOLD. Aside from that, you can add an event response (heal_event equal to 0.50 for regen or 1.00 for heal) then modify the unit's HP manually higher or lower. If you want to increase the fluidity of regen in the unit's hit points display, you can lower the REGEN_EVENT_INTERVAL (you'll want to lower the REGEN_THRESHOLD to scale).

Gotcha. Thanks for the response. If I lower the REGEN_THRESHOLD, won't that make it so that the heal text appears for non-ability regeneration, though?
 
Level 13
Joined
Jul 15, 2007
Messages
763
I finally got round to using this, and whilst it doesn't track healing sources by itself, it's fairly easy to update any of your existing healing spells to use this system. It seems to work very well, though i have yet to see how well it works in a full, long game setting.

One thing that's a bit weird is maximum HP gains are treated as healing, when really the current hit point increase (or "healing") is a side-effect of an increase in max hit-points. It makes showing actual, proper healing from floating text a bit more complicated (example: summon a unit and give it ten 100-HP tomes, it will be "healed" for 1000 which is misleading).
 
Level 5
Joined
Apr 10, 2011
Messages
56
I am using your Unit Indexer and Damage System 4.0.
I can't seem to get this to work. I thought your system was super simple that I had to write 3 vars and call a trigger, but it is not working like I expected it to.
Any help would be appreciated. I need to heal_source to get a stored value to buff the heal.

Code:
Heals
    Events
        Unit - A unit Starts the effect of an ability
    Conditions
        (Ability being cast) Equal to Heal ( Mine )
    Actions
        Set NextHealSource = (Triggering unit)
        Set NextHealTarget = (Targeted unit)
        Set NextHealAmount = (myStatMagic[(Custom value of (Triggering unit))] + 10.00)
        Trigger - Run Heal Unit <gen> (ignoring conditions)

Heal (Mine) is meant to just be a dummy ability that triggers your Heal Unit code from your test map. Thanks
 
Last edited by a moderator:
Level 5
Joined
Apr 10, 2011
Messages
56
To give more details. I have a spell that has a base heal of 10. And it is supposed to get augmented by the Heal Source's "Magic Stat" (just some integer stored in array) and add it to the base. Let's say it's Magic is 190 and the base is 10. I want to heal for 200. This allows the unit with a higher "Magic Stat" to heal more than someone with a lower "Magic Stat". However, the "Heal" ability might be breaking the system.
 
Last edited by a moderator:
Top