• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Death Coil with Extra Percentage Heal/Damage

Level 13
Joined
Sep 11, 2013
Messages
475
Greetings!

How can I made Death Coil to give 3% extra percentage damage of max hp of the enemy beside the Death Coil normal damage?
If the target blink or teleport before death coil reach his position, the death coil must dissapear/miss.

ideally the spell will be like this..

Target allowed - AIR / ALLIED / GROUND / STRUCTURE
LVL 1 --- 25 damage + 3% damage of max hp of the enemy
LVL 2 --- 50 damage + 3% damage of max hp of the enemy
LVL 3 --- 75 damage + 3% damage of max hp of the enemy
LVL 4 --- 100 damage + 3% damage of max hp of the enemy

Optionally - I prefer that the Death Coil must heal the allies with the same damage per level + 3% of ally max hp (if the target will be an ally)

I have no idea how to create this spell. :peasant-sad:

The help will be appreaciated!
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,901
You can have a unique Dummy unit cast Death Coil instead of your Hero. Then use a Damage Event to detect when a unit takes damage from this spell:
  • Events
    • Unit - A unit Takes damage
  • Conditions
    • (Unit-type of (Damage source)) Equal to Death Coil Dummy
  • Actions
    • ...
This assumes that a Damage Event runs when an Ally is hit by Death Coil. I'm pretty sure that it will...

Then in the Actions you would use an If Then Else to determine if the (Damage Target) is an Ally or Enemy, and modify the Heal/Damage depending on the outcome. The math for calculating the bonus amount is pretty simple, just multiply the target's Max Life by 0.03.
  • Set Variable BonusAmount = (Max life of (Damage Target) x 0.03)
However, the issue with this design is that your Dummy unit will be the source of the damage and get the kill credit, not your hero. This could cause issues for your other triggers that rely on "A unit Dies" or "A unit Takes damage", if you have any.

For example, if you had an Ability Power system for scaling Hero spell damage, or a reward system for when a Hero gets a kill, both could fail because it's the Dummy unit casting Death Coil and not the Hero. In other words, if your trigger's Conditions expect a Hero then they won't work.

Alternatively, you could trigger everything yourself using this:
An example of it in use:
 
Last edited:
Level 13
Joined
Sep 11, 2013
Messages
475
You can have a unique Dummy unit cast Death Coil instead of your Hero. Then use a Damage Event to detect when a unit takes damage from this spell:
  • Events
    • Unit - A unit Takes damage
  • Conditions
    • (Unit-type of (Damage source)) Equal to Death Coil Dummy
  • Actions
    • ...
This assumes that a Damage Event runs when an Ally is hit by Death Coil. I'm pretty sure that it will...

Then in the Actions you would use an If Then Else to determine if the (Damage Target) is an Ally or Enemy, and modify the Heal/Damage depending on the outcome. The math for calculating the bonus amount is pretty simple, just multiply the target's Max Life by 0.03.
  • Set Variable BonusAmount = (Max life of (Damage Target) x 0.03)
However, the issue with this design is that your Dummy unit will be the source of the damage and get the kill credit, not your hero. This could cause issues for your other triggers that rely on "A unit Dies" or "A unit Takes damage", if you have any.

For example, if you had an Ability Power system for scaling Hero spell damage, or a reward system for when a Hero gets a kill, both could fail because it's the Dummy unit casting Death Coil and not the Hero. In other words, if your trigger's Conditions expect a Hero then they won't work.

Alternatively, you could trigger everything yourself using this:
An example of it in use:
Hi Uncle and thanks for the answer!

I don't really understand how this should be created.. For the moment, the dummy can take the credit for the kill as long as the hero will receive the xp when is near the kill and as long as the player will receive the bounty (gold) for kill.

So.. What I did..
  • Death Coil
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Death Coil - Channel
    • Actions
      • Game - Display to (All players) the text: work
      • Set VariableSet DeathCoilPoint1 = (Position of (Casting unit))
      • Set VariableSet DeathCoilPoint2 = (DeathCoilPoint1 offset by 135.00 towards (Facing of (Casting unit)) degrees.)
      • Unit - Create 1 Death Coil Dummy for (Owner of (Casting unit)) at DeathCoilPoint2 facing (Facing of (Casting unit)) degrees
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Unit - Add Death Coil XXX to (Last created unit)
      • Unit - Set level of Death Coil XXX for (Last created unit) to (Level of Death Coil - Channel for (Triggering unit))
      • Unit - Order (Last created unit) to Undead Death Knight - Death Coil (Target unit of ability being cast)
      • Custom script: call RemoveLocation(udg_DeathCoilPoint1)
      • Custom script: call RemoveLocation(udg_DeathCoilPoint2)
  • DeathCoilDamage
    • Events
      • Unit - A unit Takes damage
    • Conditions
      • (Unit-type of (Damage source)) Equal to Death Coil Dummy
    • Actions
      • Game - Display to (All players) the text: work2
      • Set VariableSet DeathCoilReal = ((Max life of (Damage Target)) x 0.50)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Damage Target) belongs to an ally of (Owner of (Damage source)).) Equal to True
        • Then - Actions
          • Unit - Cause (Damage source) to damage (Damage Target), dealing (-1.00 x DeathCoilReal) damage of attack type Spells and damage type Normal
        • Else - Actions
          • Unit - Cause (Damage source) to damage (Damage Target), dealing DeathCoilReal damage of attack type Spells and damage type Normal
The second trigger is definitely broken because the damage will go to infinite loop and will crash the game, but I don't know how to fix that since the spell is not a normal attack.. :peasant-confused:
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,901
You don't have to cause more damage, you can directly modify the damage that was dealt. Also, you don't need two Points for the Dummy unit and you don't need to change it's facing angle. Dummy units can cast spells instantly without having to turn.
  • Death Coil
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Death Coil - Channel
    • Actions
      • Game - Display to (All players) the text: work
      • Set VariableSet DeathCoilPoint = (Position of (Triggering unit))
      • Unit - Create 1 Death Coil Dummy for (Owner of (Triggering unit)) at DeathCoilPoint facing default building degrees
      • Custom script: call RemoveLocation(udg_DeathCoilPoint)
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Unit - Add Death Coil XXX to (Last created unit)
      • Unit - Set level of Death Coil XXX for (Last created unit) to (Level of (Ability being cast) for (Triggering unit))
      • Unit - Order (Last created unit) to Undead Death Knight - Death Coil (Target unit of ability being cast)
  • DeathCoilDamage
    • Events
      • Unit - A unit Takes damage
    • Conditions
      • (Unit-type of (Damage source)) Equal to Death Coil Dummy
    • Actions
      • Game - Display to (All players) the text: work2
      • Set VariableSet DeathCoilReal = ((Max life of (Damage Target)) x 0.50)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Damage Target) belongs to an ally of (Owner of (Damage source)).) Equal to True
        • Then - Actions
          • Event Response - Set Damage of Unit Damaged Event to ((Damage taken) - DeathCoilReal)
        • Else - Actions
          • Event Response - Set Damage of Unit Damaged Event to ((Damage taken) + DeathCoilReal)
Your Dummy unit should have these EXACT settings:
1) Copy and paste the Locust.
2) Set it's Model, Shadow, Attacks Enabled, and Movement Type to NONE.
3) Set it's Base Speed to 0.
4) Optionally import and use the Vexorian Dummy model to get access to Attachment Points.
5) Optionally adjust the Art fields to prevent weird rotations. I forget the names but stuff like Interpolation and Launch settings.
 
Last edited:
Level 13
Joined
Sep 11, 2013
Messages
475
You don't have to cause more damage, you can directly modify the damage that was dealt.
I didn't know that.:peasant-smile:

Also, you don't need two Points for the Dummy unit and you don't need to change it's facing angle. Dummy units can cast spells instantly without having to turn.
I know that, but I did that because my custom model need to create the death coil effect in front of him, not inside his chest.

So.. Problems..

1. Death Coil will not work on allies if they're full hp, but the dummy spell will still cast the spell.. How can I stop dummy spell to cast the spell if the allied units are already full hp. I don't know how to create such a trigger..

2.The damage trigger in percentage seems to work on the enemy, but will not heal the allied units in percentage.. I think A unit takes damage event do not work on allies with death coil.. Any solution?
 

Attachments

  • Death Coil Problems.w3m
    21.2 KB · Views: 3

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,901
Looks like you'll need to use the alternative solution I suggested. It's much better anyway, you can do a lot of cool stuff with custom missiles and you'll avoid most if not all of the issues the Dummy solution has.

For the base ability, you'll want to use Death Coil for it's special targeting rules, but make sure that it doesn't actually inflict any damage/heal.
 
Level 13
Joined
Sep 11, 2013
Messages
475
Looks like you'll need to use the alternative solution I suggested. It's much better anyway, you can do a lot of cool stuff with custom missiles and you'll avoid most if not all of the issues the Dummy solution has.

For the base ability, you'll want to use Death Coil for it's special targeting rules, but make sure that it doesn't actually inflict any damage/heal.
Great! I used Death Coil as a base ability and the first problem is now solved. :peasant-smile:

Last problem..
So, from what I understand, it is impossible to make Death Coil to heal the allies in percentage with "A unit takes damage" event..
And the only solution is with your alternative solution that is way too complicated for me to understand..
Well, at least the damage percentage work perfect and the spell can remain like this.:peasant-thumbs-up-cheers:

Thank you very much for your help!
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,901
alternative solution that is way too complicated for me to understand..
It's surprisingly simple.

Like any good system, all you need to do is copy and paste the folder that contains all of the system's triggers into your own map. Then from that point on you can use the system, but of course you first need to learn how do so. This has been made very clear by the author in their demo map, with plenty of examples to learn from.

I've even provided some "noob friendly" examples in this thread. Again, you can simply copy and paste my triggers into your own map. From there it's really just a matter of adjusting the Events/Conditions/Actions to fit your needs -> Launching a missile in response to casting Death Coil.

To really break down how simple it is:
Step 1) Download and open my example map from that thread (Battleship Missile System 1).
Step 2) Copy the Missile System folder and paste it into your own map.
Step 3) Copy my example folder and paste it into your own map. You can delete these examples later.
Step 4) After reading my examples and getting a better understanding, try creating your own trigger. Better yet, I'll just show you how...

Here's an example of using the system to create your Death Coil spell. Note how I copy and pasted those Missile actions straight from the other map:
  • Death Coil Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Death Coil (Hero - Fake)
    • Actions
      • -------- Missile Properties: --------
      • Set VariableSet MissileSource = (Casting unit)
      • Set VariableSet MissileTarget = (Target unit of ability being cast)
      • Set VariableSet MissileOwner = (Owner of MissileSource)
      • Set VariableSet MissileModel = Abilities\Weapons\FireBallMissile\FireBallMissile.mdl
      • Set VariableSet MissileCollision = 75.00
      • Set VariableSet MissileStartZ = 60.00
      • Set VariableSet MissileFinishZ = 60.00
      • Set VariableSet MissileSpeed = 900.00
      • Set VariableSet MissileStart = (Position of MissileSource)
      • -------- Arc should be between 0.00 and 80.00: --------
      • Set VariableSet MissileArc = 15.00
      • -------- Missile Events: --------
      • Set VariableSet Missile_onFinish = Death Coil Impact <gen>
      • -------- Launch Missile: --------
      • Trigger - Run MissileCreate <gen> (ignoring conditions)
  • Death Coil Impact
    • Events
    • Conditions
    • Actions
      • Set VariableSet DeathCoilReal = (Max life of MissileTarget x 0.50)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (MissileTarget belongs to an ally of MissileOwner) Equal to True
        • Then - Actions
          • Unit - Cause MissileSource to damage MissileTarget, dealing (-1.00 x DeathCoilReal) damage of attack type Spells and damage type Normal
        • Else - Actions
          • Unit - Cause MissileSource to damage MissileTarget, dealing DeathCoilReal damage of attack type Spells and damage type Normal
^ I was even able to copy your damage Actions from earlier and adjust them to use the system. Easy!

You can customize the Missile variables in the first trigger as much as you'd like. For example, you'll want to change the MissileModel from FireBall.mdl to the DeathCoil.mdl. It's similar to working on a Missile in the Object Editor, in fact it offers even more control.

Note how the Missile variables you set in the first trigger (Cast) carry over to the second trigger (Impact).
MissileSource = (Casting unit), MissileTarget = (Target unit of ability being cast). MissileOwner = (Owner of Casting unit)
 
Last edited:
Level 13
Joined
Sep 11, 2013
Messages
475
It's surprisingly simple.

Like any good system, all you need to do is copy and paste the folder that contains all of the system's triggers into your own map. Then from that point on you can use the system, but of course you first need to learn how do so. This has been made very clear by the author in their demo map, with plenty of examples to learn from.

I've even provided some "noob friendly" examples in this thread. Again, you can simply copy and paste my triggers into your own map. From there it's really just a matter of adjusting the Events/Conditions/Actions to fit your needs -> Launching a missile in response to casting Death Coil.

To really break down how simple it is:
Step 1) Download and open my example map from that thread (Battleship Missile System 1).
Step 2) Copy the Missile System folder and paste it into your own map.
Step 3) Copy my example folder and paste it into your own map. You can delete these examples later.
Step 4) After reading my examples and getting a better understanding, try creating your own trigger. Better yet, I'll just show you how...

Here's an example of using the system to create your Death Coil spell. Note how I copy and pasted those Missile actions straight from the other map:
  • Death Coil Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Death Coil (Hero - Fake)
    • Actions
      • -------- Missile Properties: --------
      • Set VariableSet MissileSource = (Casting unit)
      • Set VariableSet MissileTarget = (Target unit of ability being cast)
      • Set VariableSet MissileOwner = (Owner of MissileSource)
      • Set VariableSet MissileModel = Abilities\Weapons\FireBallMissile\FireBallMissile.mdl
      • Set VariableSet MissileCollision = 75.00
      • Set VariableSet MissileStartZ = 60.00
      • Set VariableSet MissileFinishZ = 60.00
      • Set VariableSet MissileSpeed = 900.00
      • -------- Arc should be between 0.00 and 80.00: --------
      • Set VariableSet MissileArc = 15.00
      • -------- Missile Events: --------
      • Set VariableSet Missile_onFinish = Death Coil Impact <gen>
      • -------- Launch Missile: --------
      • Trigger - Run MissileCreate <gen> (ignoring conditions)
  • Death Coil Impact
    • Events
    • Conditions
    • Actions
      • Set VariableSet DeathCoilReal = (Max life of MissileTarget x 0.50)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (MissileTarget belongs to an ally of MissileOwner) Equal to True
        • Then - Actions
          • Unit - Cause MissileSource to damage MissileTarget, dealing (-1.00 x DeathCoilReal) damage of attack type Spells and damage type Normal
        • Else - Actions
          • Unit - Cause MissileSource to damage MissileTarget, dealing DeathCoilReal damage of attack type Spells and damage type Normal
^ I was even able to copy your damage Actions from earlier and adjust them to use the system. Easy!

You can customize the Missile variables in the first trigger as much as you'd like. For example, you'll want to change the MissileModel from FireBall.mdl to the DeathCoil.mdl. It's similar to working on a Missile in the Object Editor, in fact it offers even more control.

Note how the Missile variables you set in the first trigger (Cast) carry over to the second trigger (Impact).
MissileSource = (Casting unit), MissileTarget = (Target unit of ability being cast). MissileOwner = (Owner of Casting unit)
I tried to follow your example, but did not work and very weird bugs has appear with my missile..
The missile disspear and do not heal or damage anymore.. :peasant-sad:
 

Attachments

  • Death Coil - MISSLE SYSTEM.w3m
    82 KB · Views: 3

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,901
You're still referencing (Damage target), should be MissileTarget:
  • Set VariableSet DeathCoilReal = ((Max life of (Damage Target)) x 0.50)
I also forgot an important Missile variable:
  • Set VariableSet MissileStart = (Position of MissileSource)
 

Attachments

  • Death Coil - MISSLE SYSTEM fix.w3m
    80 KB · Views: 2
Last edited:
Level 13
Joined
Sep 11, 2013
Messages
475
You're still referencing (Damage target), should be MissileTarget:
  • Set VariableSet DeathCoilReal = ((Max life of (Damage Target)) x 0.50)
I also forgot an important Missile variable:
  • Set VariableSet MissileStart = (Position of MissileSource)
Seems to work great, but I found 2 more problems..

1. How can I create the missle in front of the hero (135 bonus range in front of hero)? like my old trigger.

2. With this system it is impossible to dodge the missile with blink and I wish to be able to dodge the missile if I blink. It is possible?
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,901
Seems to work great, but I found 2 more problems..

1. How can I create the missle in front of the hero (135 bonus range in front of hero)? like my old trigger.

2. With this system it is impossible to dodge the missle with blink and I wish to be able to dodge the missle if I blink. It is possible?
#1) MissileStart is where the Missile is created, so just do what you were doing originally:
  • Set Variable TempPoint1 = (Position of MissileSource)
  • Set Variable TempPoint2 = (Position of MissileTarget)
  • Set Variable MissileStart = (TempPoint1 offset by 135.00 towards (Angle between TempPoint1 and TempPoint2) degrees)
#2 is somewhat complicated, but it's technically possible.
You can create another trigger which periodically checks the state of MissileTarget and destroys the Missile if they become "illegal":
  • Death Coil Periodic
    • Events
    • Conditions
    • Actions
      • If all conditions are true then do actions
        • If - Conditions
          • Has_Blinked_Recently[(Custom value of MissileTarget)] Greater than 0
        • Then - Actions
          • Set Variable MissileDestroy = True
        • Else - Actions
  • Events
    • Unit - A unit Starts the effect of an ability
  • Conditions
    • Or - Multiple conditions
      • (Ability being cast) Equal to Blink
  • Actions
    • Set Variable Has_Blinked_Recently[(Custom value of (Triggering unit)] = Has_Blinked_Recently[(Custom value of (Triggering unit)] + 1
    • Wait 0.10 game-time seconds
    • Set Variable Has_Blinked_Recently[(Custom value of (Triggering unit)] = Has_Blinked_Recently[(Custom value of (Triggering unit)] - 1
^ Both of these triggers require a Unit Indexer, which I believe you already have in your map?

You also need to register Death Coil Periodic as the Missile's "onPeriod" trigger:
  • Set Variable Missile_onPeriod = Death Coil Periodic <gen>
So you would Set that along with setting Missile_onFinish.

Some of these variable names might be slightly off, I'm going off of memory. Also, you may want to add multiple Conditions to Death Coil Periodic to check if the MissileTarget is Hidden or Dead or anything else that could make it an "illegal" target.
 
Last edited:
Level 13
Joined
Sep 11, 2013
Messages
475
#1) MissileStart is where the Missile is created, so just do what you were doing originally:
  • Set Variable TempPoint1 = (Position of MissileSource)
  • Set Variable TempPoint2 = (Position of MissileTarget)
  • Set Variable MissileStart = (TempPoint1 offset by 135.00 towards (Angle between TempPoint1 and TempPoint2) degrees)
#2 is somewhat complicated, but it's technically possible.
You can create another trigger which periodically checks the state of MissileTarget and destroys the Missile if they become "illegal":
  • Death Coil Periodic
    • Events
    • Conditions
    • Actions
      • If all conditions are true then do actions
        • If - Conditions
          • Has_Blinked_Recently[(Custom value of MissileTarget)] Greater than 0
        • Then - Actions
          • Set Variable MissileDestroy = True
        • Else - Actions
  • Events
    • Unit - A unit Starts the effect of an ability
  • Conditions
    • Or - Multiple conditions
      • (Ability being cast) Equal to Blink
  • Actions
    • Set Variable Has_Blinked_Recently[(Custom value of (Triggering unit)] = Has_Blinked_Recently[(Custom value of (Triggering unit)] + 1
    • Wait 0.10 game-time seconds
    • Set Variable Has_Blinked_Recently[(Custom value of (Triggering unit)] = Has_Blinked_Recently[(Custom value of (Triggering unit)] - 1
^ This requires a Unit Indexer, which I believe you already have in your map?

You also need to register Death Coil Periodic as the Missile's "onPeriodic" trigger:
  • Set Variable Missile_onPeriodic = Death Coil Periodic <gen>
Do that along with setting Missile_onFinish.

Some of these variable names might be slightly off, I'm going off of memory.
Thank you very much for your help ! Now I have many options from where to choose what I need for this spell. :peasant-thumbs-up:
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,901
Thank you very much for your help ! Now I have many options from where to choose what I need for this spell.
No problem.

Note that the Has_Blinked_Recently solution is far from perfect. For instance, if a unit Blinks and then is immediately targeted by a new Death Coil, that new Death Coil would be destroyed since Has_Blinked_Recently will still be > 0. So there's a small window for error after Blinking. It's possible to fix this issue using an alternate method, but I just don't know how to do it (at least easily). Something like adding the Missiles to a MissileGroup, which are then all destroyed at the exact moment that MissileTarget casts Blink.

But if you only have one Death Coil caster then it shouldn't ever be an issue.
 
Level 13
Joined
Sep 11, 2013
Messages
475
No problem.

Note that the Has_Blinked_Recently solution is far from perfect. For instance, if a unit Blinks and then is immediately targeted by a new Death Coil, that new Death Coil would be destroyed since Has_Blinked_Recently will still be > 0. So there's a small window for error after Blinking. It's definitely possible to fix this issue using an alternate method, but I just don't know how to do it (easily). Something like adding the Missiles to a MissileGroup, which are then all destroyed at the exact moment that MissileTarget casts Blink.

But if you only have one Death Coil caster than it shouldn't be an issue you ever encounter.
No need to worry, I think I'll just let the spell impossible to dodge as a feature of the spell. :peasant-thinking:
 

Dr Super Good

Spell Reviewer
Level 65
Joined
Jan 18, 2005
Messages
27,290
You don't have to cause more damage
Yes you do? Since otherwise the damage will have an incorrect damage source. Ultimately the damage must come from the caster, not a dummy unit, since otherwise it could bug out or break systems in a map.

Wait 0.10 game-time seconds
This is below the precision of that action assuming standard implementation (not Lua override). It may be better to use a regular wait action with 0.1 since that is how wait game-time is implemented. If you want to wait 0.1 seconds of game time, a timer would be needed.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,901
Yes you do? Since otherwise the damage will have an incorrect damage source. Ultimately the damage must come from the caster, not a dummy unit, since otherwise it could bug out or break systems in a map.
I would argue that you do not. It's not a requirement, it's just ideal. There's cases where this causes no issue since not every map relies on "special" Damage changing effects or Kill credit effects. Often times the Kill credit goes to the (Owner of (Killing unit)) which still works for the Dummy unit. I would also point out that any map that relies on Dummy units is probably dealing with 10's if not 100's of Dummy related bugs, but modders generally don't care as long as their map "works".

But I explained all of this in my original post.

This is below the precision of that action assuming standard implementation
A Wait 0.10 game-time is less than a 0.03 second Periodic Interval? I thought that the polled Waits were even longer than normal Waits, and don't Waits need to be synced online? Regardless, I know that the Wait solution is bad, which I explained to Ativ.
 
Last edited:

Dr Super Good

Spell Reviewer
Level 65
Joined
Jan 18, 2005
Messages
27,290
A Wait 0.10 game-time is less than a 0.03 second Periodic Interval?
Unless it has been changed with reforged, the wait game-time action internally calls TriggerSleepAction (regular wait action). TriggerSleepAction from black box observations seemed to be network synchronised real time, with the minimum delay depending on network latency (shorter in single player, longer in multiplayer) and game speed (less game time at slower speeds, more game time at faster speeds).

It also leaks a handle reference, but that is another issue.

Code:
function PolledWait takes real duration returns nothing
    local timer t
    local real  timeRemaining

    if (duration &gt; 0) then
        set t = CreateTimer()
        call TimerStart(t, duration, false, null)
        loop
            set timeRemaining = TimerGetRemaining(t)
            exitwhen timeRemaining &lt;= 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 &gt; 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

I know that with Lua there is a hacky proxy solution that allows one to replace functions like PolledWait with timer based thread suspension. These then have perfectly accurate timing and combined with local variables enables StarCraft II style trigger solutions, assuming there are no desync issues.
 
Level 21
Joined
Mar 16, 2008
Messages
979
Uncle previously provided me with a much simpler system that I've been editing to make lots of different spells scale:

  • Cast Death Coil
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to Death Coil (Q)
    • Actions
      • Set VariableSet death_c_level = (Level of (Ability being cast) for (Casting unit))
      • Set VariableSet death_c_amount = (death_c_base[death_c_level] + (0.50 x (Life of (Casting unit))))
      • Ability - Set Ability: (Unit: (Casting unit)'s Ability with Ability Code: Death Coil (Q) (Death Knight))'s Real Level Field: Amount Healed/Damaged ('Udc1') of Level: (death_c_level - 1) to death_c_amount
You need to make sure the "Udc1" matches the correct damage field for the spell you are scaling in Object Editor by toggling raw code values with ctrl+D.
1747199706434.png

Ctrl+D to see what code you want to edit:
1747199734816.png
You can simply edit this trigger to meet you specifications
  • Set VariableSet death_c_amount = (death_c_base[death_c_level] + (0.03 x (Life of (Target unit of ability being cast))))
and of course you need to set the base damage array:
  • Set Death Coil Vars
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set VariableSet death_c_base[1] = 200.00
      • Set VariableSet death_c_base[2] = 400.00
      • Set VariableSet death_c_base[3] = 600.00
      • Set VariableSet death_c_base[4] = 615.00
      • Set VariableSet death_c_base[5] = 630.00
      • Set VariableSet death_c_base[6] = 645.00
      • Set VariableSet death_c_base[7] = 660.00
      • Set VariableSet death_c_base[8] = 675.00
      • Set VariableSet death_c_base[9] = 690.00
      • Set VariableSet death_c_base[10] = 710.00
      • Set VariableSet death_c_base[11] = 720.00
      • Set VariableSet death_c_base[12] = 730.00
      • Set VariableSet death_c_base[13] = 740.00
      • Set VariableSet death_c_base[14] = 750.00
      • Set VariableSet death_c_base[15] = 760.00
This is just an example from my map but I think it should be easy to edit from here to match what you requested in your original post.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,901
Uncle previously provided me with a much simpler system that I've been editing to make lots of different spells scale:
That's a great idea for this type of effect, I completely forgot about this option, thanks for bringing it up.

The only issue I can think of:
Death Coil uses a Missile which means that it's impact is delayed, but you're snapshotting the damage/heal values beforehand. So any changes to the target's Max Life during the "Missile flight" will not be accounted for.

That being said, I imagine a lot of mapmakers would gladly make this compromise if it meant a simple trigger that doesn't have to utilize all sorts of weird tricks and imported systems. In a lot of cases it won't matter.
 
Last edited:
Level 4
Joined
Jul 24, 2015
Messages
32
I would do it like this:
1)A trigger where on cast, spawn a dummy missile unit(invul unit with locust and Death Coil model) that store the value of caster, target, heal/damage value then start loop trigger 2)
2) A looping trigger that move the coil and check the distance, then dealing the heal\dmg when close enough, clear the values and close the trigger
3) has a tigger that when target cast blink or teleport, force ending on trigger 2) (Or you can add the distance check in 2), where if unit is over xx distance the trigger stops)

I am away from my pc for some hours I can't post the trigger outta me head now but hope that helps
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,901
I would do it like this:
1)A trigger where on cast, spawn a dummy missile unit(invul unit with locust and Death Coil model) that store the value of caster, target, heal/damage value then start loop trigger 2)
2) A looping trigger that move the coil and check the distance, then dealing the heal\dmg when close enough, clear the values and close the trigger
3) has a tigger that when target cast blink or teleport, force ending on trigger 2) (Or you can add the distance check in 2), where if unit is over xx distance the trigger stops)

I am away from my pc for some hours I can't post the trigger outta me head now but hope that helps
That's what the Relativistic Missile system does, except you no longer need Dummy units since Special Effects can do the same thing with less overhead. This is only possible on 1.31+.
 
Level 4
Joined
Jul 24, 2015
Messages
32
Hello again, here's the map, I tried to get it as close as I can.

  • Death Coil
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Death Coil
    • Actions
      • Set DC_Count = (DC_Count + 1)
      • Set DC_CountMax = (DC_CountMax + 1)
      • Set DC_Caster[DC_CountMax] = (Casting unit)
      • Set DC_Target[DC_CountMax] = (Target unit of ability being cast)
      • Set DC_Point[DC_CountMax] = (Position of (Casting unit))
      • Set DC_speed[DC_CountMax] = 1.00
      • Set DC_TargetPoint[DC_CountMax] = (Position of DC_Target[DC_CountMax])
      • Unit - Create 1 Death Coil for (Owner of DC_Caster[DC_CountMax]) at DC_Point[DC_CountMax] facing DC_TargetPoint[DC_CountMax]
      • Set DC_EffectUnit[DC_CountMax] = (Last created unit)
      • Set DC_Damage[DC_CountMax] = ((Real((Level of Death Coil for DC_Caster[DC_CountMax]))) x 25.00)
      • Unit Group - Add DC_Target[DC_CountMax] to DC_Group
      • Trigger - Turn on Death Coil Loop <gen>
      • Custom script: call RemoveLocation (udg_DC_Point[udg_DC_CountMax])
  • Death Coil Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
      • DC_CountMax Greater than 0
    • Actions
      • For each (Integer DC_Integer) from 1 to DC_CountMax, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • DC_Caster[DC_Integer] Not equal to No unit
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (DC_Target[DC_Integer] is in DC_Group) Equal to True
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (DC_Target[DC_Integer] is alive) Equal to True
                    • Then - Actions
                      • Set DC_Point[DC_Integer] = (Position of DC_EffectUnit[DC_Integer])
                      • Set DC_TargetPoint[DC_Integer] = (Position of DC_Target[DC_Integer])
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Distance between DC_Point[DC_Integer] and DC_TargetPoint[DC_Integer]) Greater than or equal to 30.00
                        • Then - Actions
                          • Set DC_speed[DC_Integer] = (DC_speed[DC_Integer] + 1.00)
                          • Set DC_Point[DC_Integer] = (DC_Point[DC_Integer] offset by DC_speed[DC_Integer] towards (Angle from DC_Point[DC_Integer] to DC_TargetPoint[DC_Integer]) degrees)
                          • Unit - Move DC_EffectUnit[DC_Integer] instantly to DC_Point[DC_Integer], facing DC_TargetPoint[DC_Integer]
                          • Custom script: call RemoveLocation(udg_DC_Point[udg_DC_Integer])
                          • Custom script: call RemoveLocation(udg_DC_TargetPoint[udg_DC_Integer])
                        • Else - Actions
                          • Special Effect - Create a special effect attached to the chest of DC_Target[DC_Integer] using Abilities\Spells\Undead\DeathCoil\DeathCoilSpecialArt.mdl
                          • Special Effect - Destroy (Last created special effect)
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (DC_Target[DC_Integer] belongs to an ally of (Owner of DC_Caster[DC_Integer])) Equal to True
                            • Then - Actions
                              • Unit - Set life of DC_Target[DC_Integer] to (((Life of DC_Target[DC_Integer]) + DC_Damage[DC_Integer]) + ((Max life of DC_Target[DC_Integer]) x 0.03))
                            • Else - Actions
                              • Unit - Cause DC_Caster[DC_Integer] to damage DC_Target[DC_Integer], dealing (DC_Damage[DC_Integer] + ((Max life of DC_Target[DC_Integer]) x 0.03)) damage of attack type Spells and damage type Magic
                          • Unit - Remove DC_EffectUnit[DC_Integer] from the game
                          • Set DC_Caster[DC_Integer] = No unit
                          • Set DC_Target[DC_Integer] = No unit
                          • Custom script: call RemoveLocation(udg_DC_Point[udg_DC_Integer])
                          • Custom script: call RemoveLocation(udg_DC_TargetPoint[udg_DC_Integer])
                          • Set DC_Count = (DC_Count - 1)
                    • Else - Actions
                      • Unit - Remove DC_EffectUnit[DC_Integer] from the game
                      • Set DC_Caster[DC_Integer] = No unit
                      • Set DC_Target[DC_Integer] = No unit
                      • Custom script: call RemoveLocation(udg_DC_Point[udg_DC_Integer])
                      • Custom script: call RemoveLocation(udg_DC_TargetPoint[udg_DC_Integer])
                      • Set DC_Count = (DC_Count - 1)
                • Else - Actions
                  • Unit - Remove DC_EffectUnit[DC_Integer] from the game
                  • Set DC_Caster[DC_Integer] = No unit
                  • Set DC_Target[DC_Integer] = No unit
                  • Custom script: call RemoveLocation(udg_DC_Point[udg_DC_Integer])
                  • Custom script: call RemoveLocation(udg_DC_TargetPoint[udg_DC_Integer])
                  • Set DC_Count = (DC_Count - 1)
            • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DC_Count Less than or equal to 0
        • Then - Actions
          • Set DC_CountMax = 0
          • Trigger - Turn off (This trigger)
        • Else - Actions
  • Death Coil Cancel
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Ability being cast) Equal to Blink (Neutral)
          • (Ability being cast) Equal to Mass Teleport
    • Actions
      • Unit Group - Remove (Casting unit) from DC_Group
Might not be the best, but it works, any input is welcome.

Adjust coil's speed with DC_Speed variable or remove one in the loop to get it moving at constant speed.
 

Attachments

  • Death Coil.w3x
    21.2 KB · Views: 0
Top