• 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.

[Trigger] Setting ability level to another ability's level

Level 12
Joined
Jul 5, 2014
Messages
551
I can't figure out the problem of the trigger. The permanent invisibility and mana regeneration both have 2 levels. The trigger adds them both when "one with the night" is activated, so it's only the "set level" which doesn't want to work. I've tried using the ID of the casting unit too but it didn't work either.

  • Shadowmeld
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to One With The Night
    • Actions
      • Unit - Add Permanent Invisibility (Custom) to (Casting unit)
      • Unit - Set level of Permanent Invisibility (Custom) for (Casting unit) to (Level of One With The Night for (Casting unit))
      • Unit - Add Custom Mana Regeneration to (Casting unit)
      • Unit - Set level of Custom Mana Regeneration for (Casting unit) to (Level of One With The Night for (Casting unit))
 
Level 30
Joined
Aug 29, 2012
Messages
1,382
Have you tried "starts the effect of an ability" as event? It's usually more accurate, although I don't know if that's the problem here

What I do know is that some abilities can't be leveled up via trigger, it's arbitrary and there's not really a way to know which except for trial and error. What ability was used as base for the mana regeneration? There are a lot of item abilities that fall in this category sadly

A workaround is simply to create distinct abilities for each level of the main spell
 
Level 12
Joined
Jul 5, 2014
Messages
551
Have you tried "starts the effect of an ability" as event? It's usually more accurate, although I don't know if that's the problem here

What I do know is that some abilities can't be leveled up via trigger, it's arbitrary and there's not really a way to know which except for trial and error. What ability was used as base for the mana regeneration? There are a lot of item abilities that fall in this category sadly

A workaround is simply to create distinct abilities for each level of the main spell
The invisibility is a unit ability. Mana reg is based on the sobi mask's ability.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
To clarify on what Chaosium said.

Item abilities have inconsistent behavior and a good portion cannot use Levels. However, you can add multiple copies of the same Item ability to stack the effect. On 1.31+ you can rely on the Set Ability Field actions to modify the values directly.

Also, remember that "Begins Casting" occurs regardless of whether the Unit successfully casts the ability. In other words, you can trigger this Event without any mana cost, cooldown, or ability effects occurring. Test this yourself by ordering your unit to Stop after triggering the Event. A unit's Art - Cast Point field in the Object Editor is what determines the amount of time spent before reaching the "Starts Effect" Event.
 
Level 12
Joined
Jul 5, 2014
Messages
551
Item abilities have inconsistent behavior and a good portion cannot use Levels. However, you can add multiple copies of them to stack the effect. On 1.31+ you can rely on the Set Ability Field actions to modify the values directly.

Also, remember that "Begins Casting" occurs regardless of whether the Unit successfully casts the ability. In other words, you can trigger this Event without any mana cost, cooldown, or ability effects occurring. Test this yourself by ordering your unit to Stop after triggering the Event.
This is an ability that works like shadowmeld. I'm not sure if it can be abused.
 
Level 12
Joined
Jul 5, 2014
Messages
551
What ability is it?

At the moment it'll add a new stack of Mana Regen each time you hit the hotkey.

I imagine you're going to undo these effects at some point. How will that work exactly?
It's a channel ability with maxed out follow through so it remains active almost indefinitely. I considered the abuse of hitting the button over and over but apparently, it interrupts the spell because the mana reg didn't increase and it went away when the ability was interrupted.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
It's a channel ability with maxed out follow through so it remains active almost indefinitely. I considered the abuse of hitting the button over and over but apparently, it interrupts the spell because the mana reg didn't increase and it went away when the ability was interrupted.
How are you removing the Mana Regen ability? It's much easier to be sure if we can see all of your triggers involved.
 
Level 12
Joined
Jul 5, 2014
Messages
551
How are you removing the Mana Regen ability? It's much easier to be sure if we can see all of your triggers involved.
Fair enough. Although I now switched from trying to leveling via trigger.

  • Shadowmeld
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to One With The Night
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of One With The Night for (Triggering unit)) Equal to 2
        • Then - Actions
          • Unit - Add Permanent Invisibility2 (Custom) to (Casting unit)
          • Unit - Add Custom Mana Regeneration2 to (Casting unit)
        • Else - Actions
          • Unit - Add Permanent Invisibility (Custom) to (Casting unit)
          • Unit - Add Custom Mana Regeneration to (Casting unit)
  • Shadowmeld Copy
    • Events
      • Unit - A unit Stops casting an ability
    • Conditions
      • (Ability being cast) Equal to One With The Night
    • Actions
      • Unit - Remove Permanent Invisibility (Custom) from (Casting unit)
      • Unit - Remove Custom Mana Regeneration from (Casting unit)
      • Unit - Remove Permanent Invisibility2 (Custom) from (Casting unit)
      • Unit - Remove Custom Mana Regeneration2 from (Casting unit)
  • Daytime
    • Events
      • Game - The in-game time of day becomes Greater than or equal to 6.00
      • Game - The in-game time of day becomes Less than or equal to 18.00
    • Conditions
    • Actions
      • Unit - Change ownership of Night time 0049 <gen> to Neutral Passive and Change color (the ability has a dummy ownership requirement for day/night change)
      • Unit - Remove Permanent Invisibility (Custom) from Hero
      • Unit - Remove Custom Mana Regeneration from Hero
      • Unit - Remove Permanent Invisibility2 (Custom) from Hero
      • Unit - Remove Custom Mana Regeneration2 from Hero
  • Nighttime
    • Events
      • Game - The in-game time of day becomes Greater than or equal to 18.00
      • Game - The in-game time of day becomes Less than or equal to 6.00
    • Conditions
    • Actions
      • Unit - Change ownership of Night time 0049 <gen> to Player 2 (Blue) and Change color
It's pretty simple and taking out the game-time can make this version of Shadowmeld work during the day too. The only downside I can't solve it interrupting when daytime comes. It no longer has associated bonuses, it's just ugly to see an inactive ability still having the green frame.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
That looks fine. Just order the Unit to Stop when daytime comes:
  • Unit - Order Hero to Stop
If multiple units have the ability then you can add them to a Unit Group on cast and loop over that instead.
  • Unit Group - Pick every unit in OWTN_Group and do (Actions)
    • Loop - Actions
      • Unit - Order (Picked unit) to Stop
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
That's exactly what I want to avoid. I don't want to player's actions unnecessarily interrupted with a stop the moment day comes.
They'll only be in the Unit Group if they're actually casting the ability. You remove them once they stop.

On Cast -> Add to group.
On Stop -> Remove from group.
On Daytime -> Order group to Stop.
 
Level 12
Joined
Jul 5, 2014
Messages
551
They'll only be in the Unit Group if they're actually casting the ability. You remove them once they stop.

On Cast -> Add to group.
On Stop -> Remove from group.
On Daytime -> Order group to Stop.
That's a single hero's ability but I guess that also needs a group to avoid stop when the ability isn't cast. Won't it drive the game nuts if the player keeps going in and out of the group with each click/interrupt?
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
That's a single hero's ability but I guess that also needs a group to avoid stop when the ability isn't cast.
If it's a single Hero then it's even easier. You have many variable types at your disposal:
  • Events
    • Unit - A unit Begins casting an ability
  • Conditions
    • It's your ability
  • Actions
    • Set Variable Hero_Is_Casting = True
    • Set Variable Hero_Is_Casting = 69
    • Set Variable Hero_Is_Casting = I'm a string that says something
    • Set Variable Hero_That_Is_Casting = (Casting unit)
  • Events
    • Unit - A unit Stops casting an ability
  • Conditions
    • It's your ability
  • Actions
    • Set Variable Hero_Is_Casting = False
    • Set Variable Hero_Is_Casting = 0
    • Set Variable Hero_Is_Casting = I now say something else
    • Set Variable Hero_That_Is_Casting = No unit
Obviously a String or an Integer variable wouldn't make much sense here but my point is that you have many options to choose from.

Then you simply check for your variable at Daytime:
  • Actions
    • If all conditions are true then do (Actions)
      • If - Conditions
        • Hero_Is_Casting Equal to True
      • Then - Actions
        • Unit - Order Hero_That_Is_Casting to Stop
      • Else - Actions
Won't it drive the game nuts if the player keeps going in and out of the group with each click/interrupt?
Not really, and it's not worth worrying about. Maybe we've scared you with all of our talk about efficiency but this isn't something you'd want to waste time thinking about.
 
Last edited:
Level 12
Joined
Jul 5, 2014
Messages
551
If it's a single Hero then it's even easier. You have many variable types at your disposal:
  • Events
    • Unit - A unit Begins casting an ability
  • Conditions
    • It's your ability
  • Actions
    • Set Variable Hero_Is_Casting = True
    • Set Variable Hero_Is_Casting = 69
    • Set Variable Hero_Is_Casting = I'm a string that says something
    • Set Variable Hero_That_Is_Casting = (Casting unit)
  • Events
    • Unit - A unit Stops casting an ability
  • Conditions
    • It's your ability
  • Actions
    • Set Variable Hero_Is_Casting = False
    • Set Variable Hero_Is_Casting = 0
    • Set Variable Hero_Is_Casting = I now say something else
    • Set Variable Hero_That_Is_Casting = No unit
Check for your variable at Daytime:
  • Actions
    • If all conditions are true then do (Actions)
      • If - Conditions
        • Hero_Is_Casting Equal to True
      • Then - Actions
        • Unit - Order Hero_That_Is_Casting to Stop
      • Else - Actions
Not really, and it's not worth worrying about. Maybe we've scared you with all of our talk about efficiency but this isn't something you'd want to waste time thinking about.
Wow, I somehow overlooked the boolean solution. That way I won't have to manually remove the abilities. It's not really your efficiency talk that makes me wary but quick changes that I don't know if the game can keep up with or ongoing periodic checks, like having the game check for things every 0.1 seconds for 3 hours.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
Wow, I somehow overlooked the boolean solution. That way I won't have to manually remove the abilities.
Better yet just use the Unit variable.
  • Events
    • Unit - A unit Begins casting an ability
  • Conditions
    • It's your ability
  • Actions
    • Set Variable Hero_That_Is_Casting = (Casting unit)
    • -------- Add abilities --------
  • Events
    • Unit - A unit Stops casting an ability
  • Conditions
    • It's your ability
  • Actions
    • -------- Remove abilities --------
    • Set Variable Hero_That_Is_Casting = No unit
Check for your variable at Daytime:
  • Events
    • It's daytime
  • Conditions
  • Actions
    • Unit - Order Hero_That_Is_Casting to Stop
Not too sure what you mean about not having to remove the abilities. You would still have to manually remove the abilities, just only in the "Stops casting" trigger.

It's not really your efficiency talk that makes me wary but quick changes that I don't know if the game can keep up with or ongoing periodic checks, like having the game check for things every 0.1 seconds for 3 hours.
I think we discussed this a few days ago. It's the contents of your triggers that are important. Running a trigger 10 times per second can be perfectly fine assuming that what you're doing inside of it doesn't have memory leaks and isn't an expensive process. If you're unsure about what's considered expensive, here's what I generally keep an eye on:

1) Creating new things is expensive. This means creating Units, Items, Special Effects, Points, Unit Groups, and Player Groups. For the last three you would be creating them when you Set them as something new.

2) Looping over a large Unit Group, say one with 50 units contained inside, and running many Loop - Actions. These Actions occur once per Unit, so the complexity is multiplied with each Unit. 50 units * 5 actions = 250 Actions * 10 instances per second = 2500 Actions per second. Of course the Actions themselves have impact depending on what they do.

3) Certain functions can be expensive. For example, a Distance check relies on square root which is known to be slow. Mind you computers are pretty fast these days so it's not like you need to avoid this function, just don't go crazy with it especially in a short time frame.

But I would generally only optimize when it's easy/convenient to do so and more importantly once you notice performance problems. Pre-optimizing can lead to slow development time and prevent you from finishing the map. It's better to have a less than ideal product which you can then go back and polish than no product at all.
 
Last edited:
Level 12
Joined
Jul 5, 2014
Messages
551
Better yet just use the Unit variable.
What makes it better than a boolean?

Not too sure what you mean about not having to remove the abilities. You would still have to manually remove the abilities, just only in the "Stops casting" trigger.
I had ability removal for daytime apart from the ability removal in the "stop casting" trigger. Now, the boolean doesn't let the player overstay their nighttime.

Certain functions can be expensive.
Periodic check is a function too. I really like using distance check (there's a whole segment where you cannot go too close to a player's units and it's measure how far are they from you. Group order is also a problem because they sometimes not always move to their intended location if someone gets in their way. Solving this with periodic "pick all units" sounds exactly an issue, although I'm not trying to control that many guys (in a single group).
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
What makes it better than a boolean?
We're now in micro-optimization territory, but as you can see by my example triggers you would no longer need the If Then Else that I suggested and you can avoid using Event Responses like (Casting unit). So it's an objectively cleaner and more efficient solution.

Periodic check is a function too. I really like using distance check (there's a whole segment where you cannot go too close to a player's units and it's measure how far are they from you. Group order is also a problem because they sometimes not always move to their intended location if someone gets in their way. Solving this with periodic "pick all units" sounds exactly an issue, although I'm not trying to control that many guys (in a single group).
I worked on a map similar to Castle Wars which hit upwards of 400 units on the screen at once, each getting periodic orders to Attack-Move to the opponent's side of the map. Each Player has a Unit Group containing all of their units which is maintained at all times. We have many Periodic Intervals, probably 20+ running at any given time. There's tons of custom spells that rely on them as well. There's a Damage Engine which runs complex logic whenever any damage is dealt, probably the biggest performance hit.

But even with all of that the performance is more than acceptable, I get well above 100 fps even on HD graphics. So there's a pretty large budget for expensive processes.
 
Level 12
Joined
Jul 5, 2014
Messages
551
We're now in micro-optimization territory, but as you can see by my example triggers you would no longer need the If Then Else that I suggested and you can avoid using Event Responses like (Casting unit). So it's an objectively cleaner and more efficient solution.


I worked on a map similar to Castle Wars which hit upwards of 400 units on the screen at once, each getting periodic orders to Attack-Move to the opponent's side of the map. Each Player has a Unit Group containing all of their units which is maintained at all times. We have many Periodic Intervals, probably 20+ running at any given time. There's tons of custom spells that rely on them as well. There's a Damage Engine which runs complex logic whenever any damage is dealt, probably the biggest performance hit.

But even with all of that the performance is more than acceptable, I get well above 100 fps even on HD graphics. So there's a pretty large budget for expensive processes.
That's good to know. Of course, it depends on one's PC. Makes me wonder if I really need them custom scripts to remove leaks. I'm guessing it's just "keep as clean as possible".
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
That's good to know. Of course, it depends on one's PC. Makes me wonder if I really need them custom scripts to remove leaks. I'm guessing it's just "keep as clean as possible".
The important thing to remember about memory leaks is that they're a growing problem. A leak is permanent. If your map has worsening performance over time it's almost guaranteed to be because of these leaks.

So let's say you have an expensive trigger that does NOT leak. Let's say the trigger is for a custom spell that fires 50 Missiles over the course of 5 seconds and those Missiles lower your FPS by 50 during that time. The important thing to note here is that once the trigger is finished you'll get that 50 FPS back and things will return to normal.

Now take that same trigger but let's say that you leak a Point whenever you create a Missile. Now you'll be creating 50 Point leaks every single time you cast the spell. You'll have 50 after the first cast, 100 after the second cast, and so on. So this is like death by a thousand cuts.
 
Last edited:
Level 12
Joined
Jul 5, 2014
Messages
551
The important thing to remember about memory leaks is that they're a growing problem. A leak is permanent. If your map has worsening performance over time it's almost guaranteed to be because of these leaks.

So let's say you have an expensive trigger that does NOT leak. Let's say the trigger is for a custom spell that fires 50 Missiles over the course of 5 seconds and those Missiles lower your FPS by 50 during that time. However, once the trigger is finished you'll get that 50 FPS back and things will return to normal.

Now take that same trigger but let's say that you leak a Point whenever you create a Missile. Now you'll be creating 50 Point leaks every single time you cast the spell. You'll have 50 after the first cast, 100 after the second cast, and so on. So this is like death by a thousand cuts.
Fair. Although with a multiple map campaign, the player may leaves before the cuts prove too much for the map. From what I've heard, leaks won't go to the next map.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
Fair. Although with a multiple map campaign, the player may leaves before the cuts prove too much for the map. From what I've heard, leaks won't go to the next map.
Yeah, the memory leaks won't transfer. So it all depends, a 60 minute campaign mission obviously suffers more from memory leaks than a 15 minute mission. The severity of the leaks matters as well which we've discussed before. Creating 1 leak whenever you cast an ability is completely negligible while creating 1 leak 60 times per second can really add up over time.
 
Top