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

Can someone tell me why my map lags

Status
Not open for further replies.
Level 2
Joined
Dec 20, 2022
Messages
11
Been making this map for a little bit, have played it all the way through a few times. Recently though I noticed it started to have a framerate drop or something at around lvl 8 and lvl 12. Weird thing is, is sometimes it's not as bad, and sometimes it'll go away at around lvl 10, only to come back at around lvl 14. I Used to have 6 computers on the map as well and it still worked.

Tried removing one of the computers, deleted a bunch of units and doodads, and tried to make sure I cleared all the leaks, although I'm very new to this so idk if I did it correctly, yet still lags/stutters/has a weird framerate drop. Could really use some help! Thanks.
 

Attachments

  • Siege.w3m
    642.5 KB · Views: 4

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,570
I see a lot of Unit Group and Point leaks throughout the triggers. All of your Creep Respawn triggers for example leak a Unit Group in their Conditions and a Point during unit creation.

Solutions can be found here:
 
Level 2
Joined
Dec 20, 2022
Messages
11
should I create new variables, not sure what I use for groups really(unit variable then set as array? or unit-group variable?), but some for points (all the creep respawn regions) and then during the Melee initialization trigger, set the point variables to where they should be. Then after they respawn call the remove point function?
 
Level 2
Joined
Dec 20, 2022
Messages
11
I've already read about them a lot.... how do you think I figured out how to remove locations? Idk what I'm doing really that's why I asked for help implementing them, not learning about them. I've been trying to fix it for a while, but came up with no luck. That's why I made an account here, to ask for help, to show me where exactly I'm messing up and what exactly to do.

You can tell from my map triggers, that I've read about memory leaks, how else would I know how to remove locations.
Uncle gave me some great advice, especially by pointing me directly at the creep reswpans.
But I don't understand how to implement a point leak clear, in the condition, if that's what I'm checking for (the point).
Also I don't see how I have unit groups that leak, when I make 1 unit?

Also If I never knew anything about leaks, why would I make the suggestions for this:
"should I create new variables, not sure what I use for groups really(unit variable then set as array? or unit-group variable?), but some for points (all the creep respawn regions) and then during the Melee initialization trigger, set the point variables to where they should be. Then after they respawn call the remove point function?"

Uncle at least straight forward in telling me where I messed up, but again, I'm not exactly sure what to exactly do, even though I HAVE read the memory leak stuff.

Not looking for you to fix my entire map. Just be like "oh in your creep respawn triggers you leak unit groups and locations"
You should make your triggers look like this: (then give me 1 example of wtf to do, then I go implement that the 100+ times I need to)
EG
blah
done.
 
Level 2
Joined
Dec 20, 2022
Messages
11
I don't really need explanations, or definitions, about leaks. I've read everything I could online. Including the threads you guys' have posted, multiple time's. I understand that when I do certain things it leaks memory or whatever, causing the game to slow down more and more, the more the leaks happen. It can happen with units, unit groups, lightning effects, special effects, and points. I know what they are. I don't need more info on them.
Stuff to get rid of them: bjWantDestroygroup, destroy last created spcial effect, remove LightingVariableName, call removeLocation, etc. I've already done some of these on my map. I don't know where else I could fix things. Maybe within the special effects of my "Nuke" spell, for the locations, and the creep respawn system. But again, idk how to implement what uncle said to do, when the condition is what I need. Very confused.
Thanks though.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,570
I don't really need explanations, or definitions, about leaks. I've read everything I could online. Including the threads you guys' have posted, multiple time's. I understand that when I do certain things it leaks memory or whatever, causing the game to slow down more and more, the more the leaks happen. It can happen with units, unit groups, lightning effects, special effects, and points. I know what they are. I don't need more info on them.
Stuff to get rid of them: bjWantDestroygroup, destroy last created spcial effect, remove LightingVariableName, call removeLocation, etc. I've already done some of these on my map. I don't know where else I could fix things. Maybe within the special effects of my "Nuke" spell, for the locations, and the creep respawn system. But again, idk how to implement what uncle said to do, when the condition is what I need. Very confused.
Thanks though.
So using that Unit Group condition leak as an example, you would need to move the Condition to the Actions of the trigger since that's the only place that you can deal with Memory Leaks.

This can be done with an If Then Else statement:
  • Events
    • Your Event Happens
  • Conditions
    • We're now checking for the Unit Group condition in the Actions
  • Actions
    • Set Variable TempUnitGroup = (Units matching some condition...)
    • If (Number of units in TempUnitGroup) Greater than 0 then do stuff...
    • Custom script: call DestroyGroup(udg_TempUnitGroup)
I'm writing this from memory hence the weirdness, but this is basically what it should look like.

Another leak I noticed was when you were using Point with Polar Offset. In your case you were close with your solution since you did use a Point variable + Remove it, but with this function you actually need two Point variables. One that represents the original Point, and another that represents the new Point that is created at the offset position:
  • Set Variable PointA = (Center of map)
  • Set Variable PointB = (PointA offset by 100 units towards 90 degrees)
  • Unit - Create 1 Footman at PointB...
  • Custom script: call RemoveLocation(udg_PointA)
  • Custom script: call RemoveLocation(udg_PointB)
If you see these functions being referenced in your Conditions/Actions (and not by a variable being Set to them) then it's safe to assume they leak:
Units In...
Units matching...
Players matching...
Position Of...
Center Of...
Target Point Of...
Rally-Point As Point

There's probably some more but those are the main culprits that I can think of right now. Most leaks will either be Points or Unit Groups, since a good portion of the functions (Conditions/Actions) interact with those in some way.
 
Last edited:
Level 2
Joined
Dec 20, 2022
Messages
11
  • creepRespawn1
    • Events
      • Time - Every 100.00 seconds of game time
    • Conditions
    • Actions
      • Set VariableSet CR1 = (Center of creepSpawnTest <gen>)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in (Units in creepSpawnTest Copy <gen>)) Equal to 0
        • Then - Actions
          • Unit - Create 1 Dire Wolf for Neutral Hostile at CR1 facing Default building facing degrees
          • Custom script: call RemoveLocation(udg_CR1)
        • Else - Actions
          • Custom script: call RemoveLocation(udg_CR1)
Would this work? Do I really need to create a unit group for the 1 dire wolf?
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,570
The Unit Group has nothing to do with the Dire Wolf, the Unit Group is created here:
  • (Number of units in (Units in creepSpawnTest Copy <gen>)
In order for the game to know how many units are in a Region, it must first store all of the units in said Region into a Unit Group. So the game creates a temporary Unit Group to store them (even if none are found). Then it this case because you're asking for the number of units in it, it counts the number of units in said Unit Group and spits out an Integer number between 0 (no units found) and X (total number of units in the region). The problem is that this Unit Group never gets destroyed during this whole process, which is what creates the memory leak.

It's your job to intervene and manually fix the memory leak yourself. The trigger should look like this:
  • creepRespawn1
    • Events
      • Time - Every 100.00 seconds of game time
    • Conditions
    • Actions
      • Set Variable TempUnitGroup = (Units in creepSpawnTest Copy <gen>)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in TempUnitGroup) Equal to 0
        • Then - Actions
          • Set VariableSet CR1 = (Center of creepSpawnTest <gen>)
          • Unit - Create 1 Dire Wolf for Neutral Hostile at CR1 facing Default building facing degrees
          • Custom script: call RemoveLocation(udg_CR1)
        • Else - Actions
      • Custom script: call DestroyGroup(udg_TempUnitGroup)
Note how I simplified the Point removal to one Action and only create it when needed.

Also, if you find yourself creating a lot of these respawn triggers you could create a system to manage it better. For example, all of your respawns that happen "Every 100.00 seconds" could be contained inside of a single trigger. Not necessary but something to keep in mind if you plan on making a fairly large map.

Another thing to note is that Dead units can be Added to a Unit Group if their Corpse hasn't fully decayed yet. Keep that in mind for your map because a dead Dire Wolf may very well prevent future Dire Wolves from spawning, at least unit it fully decays and the game Removes it from existence.
 
Last edited:
Level 2
Joined
Dec 20, 2022
Messages
11
Thank you!
Does the dead unit being added to a group cause lag? I'm not too worried about the thing not spawning here and there.

Also I swear I remember reading somewhere that preplaced regions didn't leak. I'm guessing that's only kinda true? is it only for creating units at those places, but not checking if there's any there?
 
Level 39
Joined
Feb 27, 2007
Messages
5,024
Also I swear I remember reading somewhere that preplaced regions didn't leak.
The region isn't "leaking", some other object that is created is not being cleaned up when you're done with it. For example, it creates a point object when you do something like "Center of REGION 001 <gen>", which then becomes a memory leak if you never remove the point or (by storing it in a variable) keep a reference to it to reuse later. Similarly, "Units in REGION 001 <gen>" is a unit group object that gets created and subsequently leaks.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,570
Thank you!
Does the dead unit being added to a group cause lag? I'm not too worried about the thing not spawning here and there.

Also I swear I remember reading somewhere that preplaced regions didn't leak. I'm guessing that's only kinda true? is it only for creating units at those places, but not checking if there's any there?
The Unit Group gets destroyed immediately after being used so there's no worry about lag or something like that.

And the solution is simple, just add filters to your Unit Group:
  • Set Variable TempUnitGroup = (Units in X region matching ((Matching unit) is Alive) Equal to True)
Now the Unit Group only contains living units.


Understanding the logic behind what's happening will help make this memory leak stuff click. Understand that all of your triggers in GUI get converted to Jass code, which does a whole lot more behind the scenes, like creating Points and Unit Groups which wind up becoming potential memory leaks. They're potential because you can still manually deal with them by using the Set/Destroy method. Learning a bit of Jass will help make this all clear since you can see exactly what's happening in your functions.

So to clarify what I said before:

In order for the game to know how many units are in a Region it has to go through a whole process:

First a Unit Group is needed to store these units, so one is created:
vJASS:
local group TempUnitGroup = CreateGroup()
So the game creates a brand new Unit Group to store the Units in before any are even found.
Then it proceeds to check for Units inside of the given Region and Adds them to the Unit Group:
vJASS:
call GroupAddUnit(TempUnitGroup, TheUnitFound)
Then it counts the number of Units inside the Unit Group and returns the Integer value to the user.
This value is used in your question -> Is the number of units in my region Equal to 0?
If this Condition is True then the trigger proceeds to the Actions, otherwise, it either stops the trigger short or proceeds to the Else - Actions (in an If Then Else).

The problem here is that the Unit Group it created at the start of the process never gets destroyed. That is what creates the memory leak.

(Note that this is not the exact process but it gets the point across)

And again:
Units In...
Units matching...
Players matching...
Position Of...
Center Of...
Target Point Of...
Rally-Point As Point

If you see those words outside of a Variable being Set, you're creating a memory leak. There may be some rare exceptions but don't worry about those yet.
 
Last edited:
Level 2
Joined
Dec 20, 2022
Messages
11
I tried doing the stuff you said, but still lags around the same time. Not sure what to do. I know I have some leaks in the nuke spell, but even when playing on the character that doesn't use it, I still experience the same thing. Seems like adding all the variables, and then removing them, did nothing.
 

Attachments

  • Siege.w3m
    652.5 KB · Views: 3

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,570
If it's sudden lag then I doubt it'd be because of a memory leak, that would be more gradual unless you suddenly create 1000+ leaks all at once (very unlikely). You should figure out what changes around that time. Is a new unit introduced to the map? Maybe that unit's model is causing issues. Can you think of anything like that?

Anyway, just glancing at the map again I can see a lot of wrong practices:
  • stampede
    • Events
      • Unit - A unit Begins channeling an ability
    • Conditions
      • (Ability being cast) Equal to Stampede
    • Actions
      • Animation - Play (Casting unit)'s attack animation
      • Set VariableSet stamCasterHero = (Triggering unit)
      • Set VariableSet stamMouseLocation = (Mouse Position for Triggered Mouse Event)
      • Set VariableSet stampIDK = (Unit: (Triggering unit)'s Ability with Ability Code: (Ability being cast))
      • Unit - Create 1 dummy for (Triggering player) at (Position of (Triggering unit)) facing Default building facing degrees
      • Set VariableSet stamCaster = (Last created unit)
      • Unit - Add StampedeForDummy to (Last created unit)
      • Unit - Add a 10.00 second Generic expiration timer to (Last created unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Stampede for (Triggering unit)) Equal to 3
        • Then - Actions
          • Unit - Set level of StampedeForDummy for (Last created unit) to 3
          • Unit - Order (Last created unit) to Neutral Beastmaster - Stampede stamMouseLocation
          • Custom script: call RemoveLocation(udg_stamMouseLocation)
        • Else - Actions
          • Custom script: call RemoveLocation(udg_stamMouseLocation)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Stampede for (Triggering unit)) Equal to 2
        • Then - Actions
          • Unit - Set level of StampedeForDummy for (Last created unit) to 2
          • Unit - Order (Last created unit) to Neutral Beastmaster - Stampede stamMouseLocation
          • Custom script: call RemoveLocation(udg_stamMouseLocation)
        • Else - Actions
          • Custom script: call RemoveLocation(udg_stamMouseLocation)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Stampede for (Triggering unit)) Equal to 1
        • Then - Actions
          • Unit - Set level of StampedeForDummy for (Last created unit) to 1
          • Unit - Order (Last created unit) to Neutral Beastmaster - Stampede stamMouseLocation
          • Custom script: call RemoveLocation(udg_stamMouseLocation)
        • Else - Actions
          • Custom script: call RemoveLocation(udg_stamMouseLocation)
      • Custom script: call RemoveLocation(udg_stamMouseLocation)
Don't Remove stamMouseLocation multiple times, simply Remove it once at the end. Currently you're removing it ~four times in a row.

I see you doing this in the NeverAlone trigger as well as many others. You don't have to Remove a location immediately after using it once. You can re-use it throughout the trigger multiple times:
  • Set Variable MyPoint = (Target point of ability being cast)
  • Unit - Create 1 Dummy at MyPoint
  • Special Effect - Create a Special Effect at MyPoint
  • Item - Create 1 Boots of Speed at MyPoint
  • Custom script: call RemoveLocation(udg_MyPoint)
The pattern is simple: Set once / Use as many times as you need to / Remove once.

This Omnislash trigger has a lot of problems and isn't MUI (may not be an issue). The For Loop + Wait is just asking for issues since you're using (Integer A) which is a global variable. Shared global variables should NOT be used with Waits:
  • Omnislash
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Omnislash
    • Actions
      • Set VariableSet o = (Triggering unit)
      • Set VariableSet t = (Target unit of ability being cast)
      • Set VariableSet tl = (Position of t)
      • If ((Level of Omnislash for o) Equal to 1) then do (Set VariableSet loops = 8) else do (Do nothing)
      • If ((Level of Omnislash for o) Equal to 2) then do (Set VariableSet loops = 13) else do (Do nothing)
      • If ((Level of Omnislash for o) Equal to 3) then do (Set VariableSet loops = 18) else do (Do nothing)
      • Unit - Make o Invulnerable
      • Animation - Change o's vertex coloring to (100.00%, 100.00%, 100.00%) with 50.00% transparency
      • Selection - Remove o from selection
      • Unit - Move o instantly to tl
      • Custom script: call RemoveLocation(udg_tl)
      • Animation - Play o's attack animation
      • Unit - Cause o to damage t, dealing (Random real number between 200.00 and 300.00) damage of attack type Hero and damage type Normal
      • Special Effect - Create a special effect attached to the chest of o using Abilities\Spells\NightElf\Blink\BlinkCaster.mdl
      • Special Effect - Destroy (Last created special effect)
      • For each (Integer A) from 1 to loops, do (Actions)
        • Loop - Actions
          • Wait 0.30 seconds
          • Set VariableSet o_current_loc = (Position of o)
          • Set VariableSet EG[1] = (Units within 750.00 of o_current_loc matching ((((Matching unit) is A structure) Not equal to True) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an enemy of (Owner of o).) Equal to True) and ((((Matching unit) is sleeping
          • Set VariableSet EG[2] = (Random 1 units from EG[1])
          • Custom script: call RemoveLocation(udg_o_current_loc)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Number of units in EG[1]) Greater than 0
            • Then - Actions
              • Unit Group - Pick every unit in EG[2] and do (Actions)
                • Loop - Actions
                  • Set VariableSet p = (Picked unit)
                  • Set VariableSet pl = (Position of p)
                  • Selection - Remove o from selection
                  • Unit - Move o instantly to pl
                  • Custom script: call RemoveLocation(udg_pl)
                  • Animation - Play o's attack animation
                  • Unit - Cause o to damage p, dealing (Random real number between 200.00 and 300.00) damage of attack type Hero and damage type Normal
                  • Special Effect - Create a special effect attached to the chest of o using Abilities\Spells\NightElf\Blink\BlinkCaster.mdl
                  • Special Effect - Destroy (Last created special effect)
                  • Custom script: call DestroyGroup(udg_EG[1])
                  • Custom script: call DestroyGroup(udg_EG[2])
            • Else - Actions
              • Custom script: call DestroyGroup(udg_EG[1])
              • Custom script: call DestroyGroup(udg_EG[2])
              • Selection - Add o to selection for (Owner of o)
              • Animation - Change o's vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency
              • Unit - Make o Vulnerable
      • Selection - Add o to selection for (Owner of o)
      • Animation - Change o's vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency
      • Unit - Make o Vulnerable
      • Unit - For Unit (Triggering unit), start cooldown of ability Omnislash " over "180.00 seconds.
If another trigger which uses (Integer A) were to run during the Omnislash trigger it would create a clash since they would both be fighting for the usage of Integer A. This is the nature of a global variable, it's shared between all of your triggers. Changing it's value means EVERYTHING that is referencing it now has that new value. A local variable on the other hand is different in that a new instance of itself is generated each time it's Set. Unfortunately, GUI doesn't have easy access to local variables as you can only access them through Custom Script. Alternatively, and what most GUI users do, is use Indexing methods like Dynamic Indexing to manage spells like Omnislash. Dynamic Indexing will allow you to take advantage of Arrays in order to have multiple Omnislashes running at once all with their own unique sets of data despite using the same Variables (they use different [indexes] of said variables).
 
Last edited:
Level 2
Joined
Dec 20, 2022
Messages
11
Yeah it does seem kinda sudden, but its very slight. Like I'll be completely fine up until around 6-9ish hero level wise, then it'll start to cause the screen "stuttering" or lag I'm talking about. But I played it last night and did a full round completely fine.

Ah yeah I still need to learn a lot about hashtables, and that stuff... Not sure If I really wanna put in all the time to understand that after finals haha. But should I just call the remove locations, like in never alone and stampede, at the very end of the triggers? that's like outside of all the loops and branches?

Also I ran into a problem with my siphon life spell, it works consistently when I test it, but in that round I did last night, it would like only sap life once or twice and heal the caster once or twice, not the full duration "tic" like a normal dot spell.
 
Level 2
Joined
Dec 20, 2022
Messages
11
Actually nvm about the siphon life spell, think I figured it out, was subtracting my counter inside the pick each unit loop. Appreciate all the help though guys, thanks a ton. Seems like my map works most of the time, not sure why I will occasionally get stuttering, but it's much better than before.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,570
It could just be your PC then. Your map is still pretty damn lightweight with barely any triggers so it'd be odd for there to be performance issues without a massive red flag leak, which I didn't see.

And regarding Never Alone and Stampede, like I said before, you Set the Point variable ONCE, Use it as many times as you need to, then Remove it ONCE.
To clarify, I mean ONCE per trigger.

The reason you'd want to Set the Point variable again in the same trigger is if you needed to assign it a different position than it had before. The keyword being different, meaning it has different coordinates. This is perfectly fine to do, just remember to Remove it before Setting it again.

Understand that a Point variable is simply a container for x/y/z coordinates which are used to interact with the game's grid. When you tell a Unit to move to the (Center of playable map area) you're actually telling it to move to x:0, y:0 (the center coordinates of the game grid). The Z coordinate would depend on the cliff height that is found at the center. So for example when you use the Cliff tool to increase or decrease cliff height, you're increasing the Z coordinate at the position of those cliffs by either +128.00 or -128.00 units.

To get a better understanding, look at the bottom left corner of the World Editor and you can see your mouse's current x/y/z coordinates. It even says "Point:" which helps get across the idea that a Point is just a container of coordinates.

So it's important to remember that Point variables are simply a way to alleviate you from the hassle of needing to supply x/y/z coordinates whenever you want to Create or Move something somewhere. When you code in Jass/Lua you actually have the option to use these coordinates directly and can completely avoid using Points if you'd like.

Combine this information with the understanding that sometimes (depending on what it does) your GUI conditions/actions are actually creating and leaking Points, and you'll be able to determine when and where to Set/Remove Points.
 
Last edited:
Level 20
Joined
Feb 27, 2019
Messages
593
This trigger leaks a dummy unit each time Raiden with Lightning Fast Reflexes level 1-3 attacks another unit because there is no generic expiration timer added to the dummy for those levels.
  • Lightning Fast Reflexes
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • (((Attacking unit) is A Hero) Equal to True) and ((Level of Lightning Fast Reflexes for (Attacking unit)) Greater than or equal to 1)
    • Actions
      • Set VariableSet LFRLoc = (Position of (Attacking unit))
      • Unit - Create 1 dummy for (Owner of (Attacking unit)) at LFRLoc facing Default building facing degrees
      • Unit - Add Chain Lightning for dummy to (Last created unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Lightning Fast Reflexes for (Attacking unit)) Equal to 4
        • Then - Actions
          • Set VariableSet chanceLFR = (Random integer number between 1 and 100)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • chanceLFR Less than or equal to 30
            • Then - Actions
              • Unit - Set level of Chain Lightning for dummy for (Last created unit) to 1
              • Unit - Order (Last created unit) to Orc Far Seer - Chain Lightning (Attacked unit)
              • Unit - Add a 3.00 second Generic expiration timer to (Last created unit)
              • Special Effect - Create a special effect attached to the chest of (Attacking unit) using Abilities\Spells\Orc\FeralSpirit\feralspiritdone.mdl
              • Special Effect - Destroy (Last created special effect)
            • Else - Actions
              • Do nothing
        • Else - Actions
          • Do nothing
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Lightning Fast Reflexes for (Attacking unit)) Equal to 3
        • Then - Actions
          • Set VariableSet chanceLFR = (Random integer number between 1 and 100)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • chanceLFR Less than or equal to 20
            • Then - Actions
              • Unit - Set level of Chain Lightning for dummy for (Last created unit) to 1
              • Unit - Order (Last created unit) to Orc Far Seer - Chain Lightning (Triggering unit)
              • Special Effect - Create a special effect attached to the chest of (Attacking unit) using Abilities\Spells\Orc\FeralSpirit\feralspiritdone.mdl
              • Special Effect - Destroy (Last created special effect)
            • Else - Actions
              • Do nothing
        • Else - Actions
          • Do nothing
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Lightning Fast Reflexes for (Attacking unit)) Equal to 2
        • Then - Actions
          • Set VariableSet chanceLFR = (Random integer number between 1 and 100)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • chanceLFR Less than or equal to 15
            • Then - Actions
              • Unit - Set level of Chain Lightning for dummy for (Last created unit) to 1
              • Unit - Order (Last created unit) to Orc Far Seer - Chain Lightning (Triggering unit)
              • Special Effect - Create a special effect attached to the chest of (Attacking unit) using Abilities\Spells\Orc\FeralSpirit\feralspiritdone.mdl
              • Special Effect - Destroy (Last created special effect)
            • Else - Actions
              • Do nothing
        • Else - Actions
          • Do nothing
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Lightning Fast Reflexes for (Attacking unit)) Equal to 1
        • Then - Actions
          • Set VariableSet chanceLFR = (Random integer number between 1 and 100)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • chanceLFR Less than or equal to 10
            • Then - Actions
              • Unit - Set level of Chain Lightning for dummy for (Last created unit) to 1
              • Unit - Order (Last created unit) to Orc Far Seer - Chain Lightning (Triggering unit)
              • Special Effect - Create a special effect attached to the chest of (Attacking unit) using Abilities\Spells\Orc\FeralSpirit\feralspiritdone.mdl
              • Special Effect - Destroy (Last created special effect)
            • Else - Actions
              • Do nothing
        • Else - Actions
          • Do nothing
      • Custom script: call RemoveLocation(udg_LFRLoc)
 
Status
Not open for further replies.
Top