• 🏆 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!

Roar that heals the caster over time based on strength

Status
Not open for further replies.
Level 4
Joined
Feb 13, 2015
Messages
60
Hi, cant figurer it out myself so fought maybe you pros could. ;)
Like the title says, I want to make the spell Roar heal the caster over time based on his strenght. Multiple heros might cast it at the same time, just so you know.

Thanks on before hand.
 
Level 3
Joined
Sep 7, 2013
Messages
47
  • Events
    • Unit starts the effect of an ability
  • Conditions
    • (Ability being cast) is equal to Regenerative Roar
  • Actions
    • Set Roar_Duration = 10 //or any duration that you want
    • Set Heal_PerSecond = 5
      • Do Multiple ActionsFor each (Your_IntegerVar) from 1 to (Roar_Duration), do (Actions)
        • Loop - Actions
          • Unit - Set life of (Triggering unit) to (Life of (Triggering unit) + Heal_PerSecond)
          • Wait 0.5 seconds //you cannot have this value lower than 0.27 something. that is the wait limit
This is a special case wherein you can use loops with waits while maintaining MUI. Because 1. Triggering unit is still remembered even after using waits 2. Using Triggering unit instead of storing it to a variable maintains MUI

MUI is Multi- Instanceability meaning even if 2 heroes cast it at the same time there will be no problem
 
Level 12
Joined
Mar 24, 2011
Messages
1,082
Let me nitpick:
  • Set Heal_PerSecond = 5
This is not Heal Per Second, this is Heal Per Tick
You better do:
  • ----Configurables - Feel free to modify----
  • Set int_RoarDurationSeconds = 10
  • Set real_HealingPerSecond = 5
  • Set real_TickInterval = 0.5
  • ----Spell - do not modify----
  • Set real_TicksPerSecond = 1 / real_TickInterval
  • Set real_HealPerTick = real_HealingPerSecond/real_TicksPerSecond
  • Set int_RoarIntervalsCount = int_RoarDurationSeconds * (RealToInt(real_TicksPerSecond))
  • Do Multiple ActionsFor each (Your_IntegerVar) from 1 to (int_RoarIntervalCount), do (Actions)
    • Loop - Actions
    • Unit - Set life of (Triggering unit) to (Life of (Triggering unit) + HealPerTick)
    • Wait real_TickInterval seconds //you cannot have this value lower than 0.27 something. that is the wait limit
More nitpicking:
Roar is actualy an AoE spell, no ?
It should affect all units around the caster so:
  • Unit - Set life of (Triggering unit) to (Life of (Triggering unit) + HealPerTick)
This turns into >>>
  • Set TempPoint = Unit position of (Triggering unit)
  • Set TempUnitGroup = Units in RoarAoERange matching (units are not enemy and are alive and not building)
  • Pick all units in TempUnit Group
    • Loop
      • Unit - Set life of (Picked unit) to (Life of (Picked unit) + HealPerTick)
  • Custom script: Clear leaks
This spawns another configurable:
  • Set RoarAoERange = 500
All configurables can be moved to map initialization trigger as long as they are not temporal variables (I do not like the idea of having to set "constants" every time the spell is cast)
 
Level 3
Joined
Sep 7, 2013
Messages
47
Well I was in a bit rush when I wrote them so supposedly there will be errors. Let me correct them.

Let me nitpick:

This is not Heal Per Second, this is Heal Per Tick

I really do mean Heal Per Second because I think that is easier to understand and is more easily configurable than Heal Per Tick. I just forgot to set a Tick_Interval variable just like what you did (anyway your whole trigger is still better)

But let me correct myself again... This is NOT 100% MUI because variables inside the loop may change during the spell duration and thus may create problems.

Roar is actualy an AoE spell, no ?
It should affect all units around the caster so:
  • Unit - Set life of (Triggering unit) to (Life of (Triggering unit) + HealPerTick)
This turns into >>>
  • Set TempPoint = Unit position of (Triggering unit)
  • Set TempUnitGroup = Units in RoarAoERange matching (units are not enemy and are alive and not building)
  • Pick all units in TempUnit Group
    • Loop
      • Unit - Set life of (Picked unit) to (Life of (Picked unit) + HealPerTick)
  • Custom script: Clear leaks
This spawns another configurable:
  • Set RoarAoERange = 500

So, the caster will turn now into a walking healing ward, no?

All configurables can be moved to map initialization trigger as long as they are not temporal variables (I do not like the idea of having to set "constants" every time the spell is cast)

That will be a mess if only GUI. Imagine all the constants of the all the spells in your map clumped together in a single trigger...

Not to mention the Strength stat that should be a factor for the heal and the MUI that is hard to be achieved in gui. I guess the best way around this is to use locals (via CustomScripts or JASS)
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
NEVER EVER EVER EVER EVER EVER use waits INSIDE a LOOP.
Just so you will never ever ever EVER forget it.

To make a new discussion between us 3 :D
Let's head on.

Waits continue to run while the game is paused.
You can start a 60 seconds wait, alt+tab (the game is paused), wait a minute in real time, go back to WC3 and you will see that the wait has ended as soon as you unpause it.

That is why you want to use Wait Timers.
  • Wait 2.00 seconds
  • Wait 2.00 game-time seconds
JASS:
//This is the first.
native TriggerSleepAction takes real timeout returns nothing

//This is the second.
function PolledWait takes real duration returns nothing
    local timer t
    local real  timeRemaining

    if (duration > 0) then
        set t = CreateTimer()
        call TimerStart(t, duration, false, null)
        loop
            set timeRemaining = TimerGetRemaining(t)
            exitwhen timeRemaining <= 0

            // If we have a bit of time left, skip past 10% of the remaining
            // duration instead of checking every interval, to minimize the
            // polling on long waits.
            if (timeRemaining > bj_POLLED_WAIT_SKIP_THRESHOLD) then
                call TriggerSleepAction(0.1 * timeRemaining)
            else
                call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
            endif
        endloop
        call DestroyTimer(t)
    endif
endfunction
You can see that there is definately difference between those.

But that is not the reason why you may not use them in loops.
The reason is that they are inaccurate.
When you wait '2' seconds, you actuall wait between 2.04 and 2.19 seconds.
In a loop that difference increases dramatically.

What you want to do is more like a damage over time... but then a heal.
Just wait a few minutes.

EDIT:
Does this kind of fits your needs?

(Yes I use a heal of 10 every 0.5 seconds for 5 seconds.
It is calculated at the bottom of the Roar Cast trigger.
You can change that to whatever you want.)
 

Attachments

  • Roar.w3x
    50.4 KB · Views: 49
Level 12
Joined
Mar 24, 2011
Messages
1,082
@Mirage_tempest I know that you ment healing per second, just you didn't do healing per second (nitpicking :) )

Not to mention the Strength stat that should be a factor for the heal and the MUI that is hard to be achieved in gui. I guess the best way around this is to use locals (via CustomScripts or JASS)

Oh, I forgot that part of the question :D On the other hand... (Even more nitpicking :D ) You forgot that part of the question. I will leave you now because I have to do my own things...
 
Level 25
Joined
May 11, 2007
Messages
4,651
Since everyone are making their own version of the spell, so do I!
LordDz proudly presents..

THE LAZY WAY OF DOING IT!

THEME SONG! (Listen to it or this will not work)

Open up the object editor, click on the abilites tab, press ctrl + f and type in Rejuvenation.
Create your own spell of it.

Set the amount of levels of the spell to the maximium strength a hero can have in your map, say 100.
Right-Click on the Hitpoints gained on lvl1 and use "Autofill levels". Set the base value to say 20 and the Constant Factor to how much a strength point should heal.

Go to the trigger editor.
  • YOURE GONNA HERE ME ROAR
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to AND HEAR ME ROAR (Roar Ability)
    • Actions
      • Set CasterUnit = (Triggering unit)
      • Set CasterPlayer = (Owner of CasterUnit)
      • Set tempPoint1 = (Position of CasterUnit)
      • Unit - Create 1 Dummy STR Healer (Already has the spell) for CasterPlayer at tempPoint1 facing 0.00 degrees
      • Set DummyUnit = (Last created unit)
      • Unit - Set level of HEAL STRENGTH OF POWER (Healing Ability) for DummyUnit to (Strength of CasterUnit (Include bonuses))
      • Unit - Add a 2.00 second Water Elemental expiration timer to DummyUnit
      • Unit - Order DummyUnit to Night Elf Druid Of The Claw - Rejuvenation CasterUnit
      • Custom script: call RemoveLocation(udg_tempPoint1)
 

Attachments

  • dzhelps_Roar.w3x
    32.4 KB · Views: 42
Last edited:
Level 3
Joined
Sep 7, 2013
Messages
47
Oh, I forgot that part of the question :D On the other hand... (Even more nitpicking :D ) You forgot that part of the question. I will leave you now because I have to do my own things...

No, I didn't forget it. It is just because I realized the whole trigger thing is not MUI that's why I mention about the Strength factor.
I mean.. you can freely do this
  • Set HealPerTick = (get hero str + base heal)
if you didn't intend your spell to be MUI.

By the way Wietlol nailed it. I think this is harder if it were to use hashtables
 
Level 25
Joined
May 11, 2007
Messages
4,651
An algorithm like that wouldn't make sense for the spell other than trying to show off triggering skills :p
(I made mine just for the hell of it)

A spell should be kept simple for the user to understand and use.

Also, random Pogo song because.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
My triggers are simple to understand are they?
They just give you a massive amount of opportunities too.

The Roar Cast:
When a unit has cast roar -> Make an EOT on (triggering unit) by (triggering unit) with buff (Roar Buff) for (5) seconds with an interval of (0.5) seconds with special effect (rejuvenation)
And apply a real as custom value indexed to 0.

The Roar Interval:
When Roar's Interval is fired -> Heal unit for the custom value of the Roar.
Simple.
 
Level 3
Joined
Sep 7, 2013
Messages
47
It would be better to create a advanced trigger version of it than to create an ability with many levels. For every ability level = 1 ability, The thing would greatly affect loading times.

And to think that the "Roar" we are discussing about already have a regenerative feature (As i have an ability like that in the map i am working)

And it is working properly :D
 

Attachments

  • Untitled.jpg
    Untitled.jpg
    169.4 KB · Views: 51
Level 24
Joined
Aug 1, 2013
Messages
4,657
Wietlol, I just wanted to create my own version, your trigger works fine.
I know that... you mentioned that before.
I don't want to be nitpicking but it looks a bit more like trolling.
Even though it is a good thing to show how dummy units can do magic tricks... It didn't really exceed the current top suggestion.

So that is why it looks like trolling rather than helping. Especially from someone with that (high) reputation.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
I might be wrong but waits inside of loops doesn't work, right? How will you exit the loop if there's a wait in it?
They work in actions and standard loop flow control. They do not work in iteration loops such as used on forces and groups. They execute how one would expect with the wait being applied when ever the program reaches that line of execution. Recall that loops happen sequentially each iteration at a time.
 
Status
Not open for further replies.
Top