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

[Trigger] How to seperate enemy waves?

Status
Not open for further replies.
Level 8
Joined
Jun 13, 2010
Messages
344
Hey,

I am trying to make a defensive map, where there will be coming waves 1 by 1. The next wave will not come before the existing wave has been slain.

I know the error in this trigger, but I can't find the solution to fix it. When the last enemy of the wave is slain, both trigger 2 and trigger 3 will activate.

Trigger 2 and trigger 3 is constructed the same way, but with a condition requiring the variable:
  • Invade_Wave_Integer Equal to 2

  • Invaders Wave 1
    • Events
      • Time - Elapsed game time is 2.00 seconds
    • Conditions
    • Actions
      • Set Invade_Count = 0
      • Set Invade_Wave_Integer = (Invade_Wave_Integer + 1)
      • Countdown Timer - Start A_Timer as a One-shot timer that will expire in (Real(Wave_Timer)) seconds
      • Countdown Timer - Create a timer window for A_Timer with title (Wave + ((String(Invade_Wave_Integer)) + :))
      • Set A_Timer_Window = (Last created timer window)
      • Wait (Real(Wave_Timer)) seconds
      • Countdown Timer - Destroy A_Timer_Window
      • Game - Display to (All players) the text: (Wave + ((String(Invade_Wave_Integer)) + has spawned!))
      • -------- Spawns --------
      • Unit - Create 1 Ghoul for Player 12 (Brown) at Invade_Point facing Default building facing degrees
      • -------- --------
      • Unit Group - Pick every unit in (Units in Invade_Spawn) and do (Actions)
        • Loop - Actions
          • Set A_Unit = (Picked unit)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Owner of A_Unit) Equal to Player 12 (Brown)
              • (A_Unit is A structure) Not equal to True
              • (A_Unit is dead) Not equal to True
            • Then - Actions
              • Unit Group - Add A_Unit to Invade_Group
              • Set Invade_Count = (Invade_Count + 1)
            • Else - Actions
  • Invaders Wave 2
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Owner of (Triggering unit)) Equal to Player 12 (Brown)
      • ((Triggering unit) is A structure) Not equal to True
      • ((Triggering unit) is in Invade_Group) Equal to True
      • Invade_Wave_Integer Equal to 1
    • Actions
      • Set A_Unit = (Triggering unit)
      • Set Invade_Count = (Invade_Count - 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Invade_Count Less than or equal to 0
        • Then - Actions
          • Set Invade_Wave_Integer = (Invade_Wave_Integer + 1)
          • Countdown Timer - Start A_Timer as a One-shot timer that will expire in (Real(Wave_Timer)) seconds
          • Countdown Timer - Create a timer window for A_Timer with title (Wave + ((String(Invade_Wave_Integer)) + :))
          • Set A_Timer_Window = (Last created timer window)
          • Wait (Real(Wave_Timer)) seconds
          • Game - Display to (All players) the text: (Wave + ((String(Invade_Wave_Integer)) + has spawned!))
          • Countdown Timer - Destroy A_Timer_Window
          • -------- Spawns --------
          • Unit - Create 2 Ghoul for Player 12 (Brown) at Invade_Point facing Default building facing degrees
          • -------- --------
          • Unit Group - Pick every unit in (Units in Invade_Spawn) and do (Actions)
            • Loop - Actions
              • Set A_Unit = (Picked unit)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Owner of A_Unit) Equal to Player 12 (Brown)
                  • (A_Unit is A structure) Not equal to True
                  • (A_Unit is dead) Not equal to True
                • Then - Actions
                  • Unit Group - Add A_Unit to Invade_Group
                  • Set Invade_Count = (Invade_Count + 1)
                • Else - Actions
        • Else - Actions
 
Level 8
Joined
Jun 13, 2010
Messages
344
Try using When the UNITS dies >>> Turn on [Example Trigger]
Make the trigger you dont want to be enabled Initially [OFF] and not on
so when you want it to be on You put a trigger [On] in the last Created/finished Trigger

Hope it helps.

Ye I should have noted that in the thread.

I tried that, problem is, if I turn on the say Wave 3 trigger as the wave 2 trigger ends, the wave 3 trigger won't fire due to the unit has already died before the wave 3 trigger was turned on.
 
Level 6
Joined
Oct 9, 2017
Messages
116
Ye I should have noted that in the thread.

I tried that, problem is, if I turn on the say Wave 3 trigger as the wave 2 trigger ends, the wave 3 trigger won't fire due to the unit has already died before the wave 3 trigger was turned on.
Newgen WE May cause problems like copying things without permission
Now back to the problem
I suggest you make a trigger when units owned by player 12 Dies
Remove it completely from the game
then the Trigger will create new ones,
 
Level 18
Joined
Nov 21, 2012
Messages
835
The next wave will not come before the existing wave has been slain.
use this instead of "unit dies" trigger:
  • WaitTrigger
    • Events
    • Conditions
    • Actions
      • Wait until ((Number of units in Invade_Spawn) Equal to 0), checking every 1.00 seconds
      • Trigger - Run SpawnTrigger <gen> (checking conditions)
instead of:
  • Unit - Create 1 Ghoul for Player 12 (Brown) at Invade_Point facing Default building facing degrees
you can use 2 variables: for unit-type and integer for quantity

edit
and after spawn add group directly to your InvadeGroup ;)
  • Untitled Trigger 002
    • Events
    • Conditions
    • Actions
      • Unit - Create 1 Footman for Player 1 (Red) at (Center of (Playable map area)) facing Default building facing degrees
      • Unit Group - Add all units of (Last created unit group) to Invade_Group
 
Last edited:
Level 13
Joined
Oct 12, 2016
Messages
769
^ ZiBithe's method is one effective way to detect if all units are dead before launching the next wave.

For determining each wave, you can do this through an integer counter like so:
  • Enemy Waves
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Owner of (Triggering unit)) Equal to Player 12 (Brown)
      • (Number of units in SpawnGroup) Equal to 0
    • Actions
      • Set WaveLevel = (WaveLevel + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • WaveLevel Equal to 1
        • Then - Actions
          • Unit - Create 1 Footman for Player 12 (Brown) at SpawnPoint facing (Random angle) degrees
          • Unit Group - Add (Last created unit) to SpawnGroup
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • WaveLevel Equal to 2
            • Then - Actions
              • Unit - Create 1 Knight for Player 12 (Brown) at SpawnPoint facing (Random angle) degrees
              • Unit Group - Add (Last created unit) to SpawnGroup
            • Else - Actions
Make sure you set your variables like "SpawnPoint" and run your "Enemy Waves" trigger while ignoring conditions at some point like Map Initialization or whatever:
  • Map Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set SpawnPoint = (Center of Respawn <gen>)
      • Trigger - Run Enemy Waves <gen> (ignoring conditions)
 
Level 8
Joined
Jun 13, 2010
Messages
344
use this instead of "unit dies" trigger:
  • base.gif
    WaitTrigger
    • join.gif
      events.gif
      Events
    • join.gif
      cond.gif
      Conditions
    • joinbottomminus.gif
      actions.gif
      Actions
      • empty.gif
        join.gif
        zzz.gif
        Wait until ((Number of units in Invade_Spawn) Equal to 0), checking every 1.00 seconds
      • empty.gif
        joinbottom.gif
        page.gif
        Trigger - Run SpawnTrigger <gen> (checking conditions)

Seems very simple and nice, but I can't make it work somehow... -.-
instead of:
  • unit.gif
    Unit - Create 1 Ghoul for Player 12 (Brown) at Invade_Point facing Default building facing degrees
you can use 2 variables: for unit-type and integer for quantity

What would that be good for? Just curious thoughts. :)

For determining each wave, you can do this through an integer counter like so:

Oh ye, that is the issue. By having each wave in the same trigger, I will prevent having multiple event activations. Why didn't I think of that, lol.

page.gif
Trigger - Run Enemy Waves <gen> (ignoring conditions)

Why this? :)
To the Map initialization point, I did this:
  • Initialization Spawn
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set Invade_Spawn = Invaders Village Spawn <gen>
      • Set Invade_Point = (Center of Invade_Spawn)
 
Level 18
Joined
Nov 21, 2012
Messages
835
you need variables (unit-typw and integer) to make thing more-auto
like this:
  • SnowYellSettings
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set InvadeUnitType[1] = Ghoul
      • Set InvadeQuantity[1] = 1
      • Set InvadeUnitType[2] = Ghoul
      • Set InvadeQuantity[2] = 2
      • Set InvadeUnitType[3] = Ghoul
      • Set InvadeQuantity[3] = 3
      • Set InvadeUnitType[4] = Necromancer
      • Set InvadeQuantity[4] = 1
      • Set InvadeUnitType[5] = Necromancer
      • Set InvadeQuantity[5] = 2
  • //etc...
  • SnowYelStartTimer
    • Events
      • Time - Elapsed game time is 2.00 seconds
    • Conditions
    • Actions
      • Set InvadeCount = (InvadeCount + 1)
      • Countdown Timer - Start InvadeTimer as a One-shot timer that will expire in 30.00 seconds
      • Countdown Timer - Create a timer window for InvadeTimer with title Time
      • Set InvadeTimerWindow = (Last created timer window)
  • SnowYellTimerExp
    • Events
      • Time - InvadeTimer expires
    • Conditions
    • Actions
      • Countdown Timer - Destroy InvadeTimerWindow
      • Game - Display to (All players) the text: wave
      • Unit - Create InvadeQuantity[InvadeCount] InvadeUnitType[InvadeCount] for Player 12 (Brown) at InvadePoint facing Default building facing degrees
      • Unit Group - Add all units of (Last created unit group) to InvadeGroup
      • Wait until ((Number of units in InvadeGroup) Equal to 0), checking every 1.00 seconds
      • Trigger - Run SnowYelStartTimer <gen> (ignoring conditions)
;)
 
Level 8
Joined
Jun 13, 2010
Messages
344
you need variables (unit-typw and integer) to make thing more-auto
like this:
  • base.gif
    SnowYellSettings
    • joinminus.gif
      events.gif
      Events
      • line.gif
        joinbottom.gif
        folder.gif
        Map initialization
    • join.gif
      cond.gif
      Conditions
    • joinbottomminus.gif
      actions.gif
      Actions
      • empty.gif
        join.gif
        set.gif
        Set InvadeUnitType[1] = Ghoul
      • empty.gif
        join.gif
        set.gif
        Set InvadeQuantity[1] = 1

More auto like in being able to make just 1 trigger and not have to make too much work for each wave, or what are your thoughts with this?

unitgroup.gif
Unit Group - Add all units of (Last created unit group) to InvadeGroup

Does this leak, or what unit group is referred to?
 
Level 13
Joined
Oct 12, 2016
Messages
769
Why this?
That's just for my example. If the wave trigger runs when something dies, you'll need to force that one trigger to run to start things (ignoring the conditions)

Does this leak, or what unit group is referred to?
Since "InvadeGroup" is a preset group, there is no need to destroy it. Therefore, it doesn't create leaks if it is reused.

HOWEVER, (Last created unit group) DOES leak. It's a unit group that's created and not destroyed, so it kind of continues to exist.
 
Level 8
Joined
Jun 13, 2010
Messages
344
HOWEVER, (Last created unit group) DOES leak. It's a unit group that's created and not destroyed, so it kind of continues to exist.

Ye it was that group I was aiming for. :/
How can I prevent that? Make another trigger than registeres units entering the spawn region equal to player 12 and add them to group by default?

That's just for my example. If the wave trigger runs when something dies, you'll need to force that one trigger to run to start things (ignoring the conditions)

I think I have made it work though. I have taken a couple of stuff from both of you and ZiBitheWand3r3r.
I will share it when I have made it fully work and free for leaks for others to see if needed. :)
 
Level 18
Joined
Nov 21, 2012
Messages
835
I gave you fully working solution, but its up to you what you prefer.
bj_lastCreatedGroup does not leak, it is reused by, and connected to GUI action "Create X Units and Loc" (like bj_lastCreatedUnit which refers to excactly last unit created)

variables UnitType "InvadeUnitType" and Integer "InvadeQuantity" means that at 1st wave 1 Ghoul will be created, 2nd wave: 2 Ghouls, 3rd wave: 3 Ghouls, 4th wave 1 Necromancer, 5th wave 2 Necromancers. So you can use simple action
"Unit - Create InvadeQuantity[InvadeCount] InvadeUnitType[InvadeCount] for Player 12 (Brown) at InvadePoint facing Default building facing degrees"
after you increase InvadeCount by 1.
 
Level 8
Joined
Jun 13, 2010
Messages
344
I gave you fully working solution, but its up to you what you prefer.
bj_lastCreatedGroup does not leak, it is reused by, and connected to GUI action "Create X Units and Loc" (like bj_lastCreatedUnit which refers to excactly last unit created)

variables UnitType "InvadeUnitType" and Integer "InvadeQuantity" means that at 1st wave 1 Ghoul will be created, 2nd wave: 2 Ghouls, 3rd wave: 3 Ghouls, 4th wave 1 Necromancer, 5th wave 2 Necromancers. So you can use simple action
"Unit - Create InvadeQuantity[InvadeCount] InvadeUnitType[InvadeCount] for Player 12 (Brown) at InvadePoint facing Default building facing degrees"
after you increase InvadeCount by 1.

I am using your variable suggestions. They will also be proving worthy for ingame configuration and such, so that will be most useful.

  • -------- +1 Dead Archer for every 5 waves --------
  • Set Invade_TypeQuantityReal[1] = (Invade_TypeQuantityReal[1] + 0.20)
I will be doing it this way to balance the waves even further.

I actually used all of your suggestions, but took in Wark's suggestion with the unit dies trigger and made the balancing system through that:

  • Invader Waves
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Owner of (Triggering unit)) Equal to Player 12 (Brown)
    • Actions
      • Set A_Unit = (Triggering unit)
      • Unit Group - Remove A_Unit from Invade_Group
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in Invade_Group) Equal to 0
        • Then - Actions
          • Game - Display to (All players) the text: (Wave + ((String(Invade_WaveInteger)) + was fought back...))
          • Set Invade_WaveInteger = (Invade_WaveInteger + 1)
          • Countdown Timer - Start Invade_Timer as a One-shot timer that will expire in (Real(Invade_TimerWait)) seconds
          • Countdown Timer - Create a timer window for Invade_Timer with title (Wave + ((String(Invade_WaveInteger)) + :))
          • Set Invade_TimerWindow = (Last created timer window)
          • -------- Calculating Wave Quantity --------
          • -------- +1 Dead Archer for every 5 waves --------
          • Set Invade_TypeQuantityReal[1] = (Invade_TypeQuantityReal[1] + 0.20)
          • -------- +1 Ghoul for every 4 waves --------
          • Set Invade_TypeQuantityReal[2] = (Invade_TypeQuantityReal[2] + 0.25)
          • -------- +1 Risen Soldier for every 3 waves --------
          • Set Invade_TypeQuantityReal[3] = (Invade_TypeQuantityReal[3] + 0.33)
          • -------- +1 Skeletal Brute for every 5 waves --------
          • Set Invade_TypeQuantityReal[4] = (Invade_TypeQuantityReal[4] + 0.20)
          • -------- +1 Zombie for every 3 waves --------
          • Set Invade_TypeQuantityReal[5] = (Invade_TypeQuantityReal[5] + 0.33)
        • Else - Actions

My other triggers so far:

  • Invader Map Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set Invade_Type[1] = Dead Archer
      • Set Invade_Type[2] = Ghoul
      • Set Invade_Type[3] = Risen Soldier
      • Set Invade_Type[4] = Skeletal Brute
      • Set Invade_Type[5] = Zombie
      • Set Invade_Type[6] = Fallen Mage
      • Set Invade_TypeQuantityReal[1] = 0.00
      • Set Invade_TypeQuantityReal[2] = 1.00
      • Set Invade_TypeQuantityReal[3] = 4.00
      • Set Invade_TypeQuantityReal[4] = 0.00
      • Set Invade_TypeQuantityReal[5] = 3.00
      • Set Invade_TypeQuantityReal[6] = 0.00
  • Invader Timer Start
    • Events
      • Time - Elapsed game time is 2.00 seconds
    • Conditions
    • Actions
      • Set Invade_WaveInteger = 1
      • Set Invade_TimerWait = 2
      • Countdown Timer - Start Invade_Timer as a One-shot timer that will expire in (Real(Invade_TimerWait)) seconds
      • Countdown Timer - Create a timer window for Invade_Timer with title (Wave + ((String(Invade_WaveInteger)) + :))
      • Set Invade_TimerWindow = (Last created timer window)
  • Invader Timer
    • Events
      • Time - Invade_Timer expires
    • Conditions
    • Actions
      • Countdown Timer - Destroy Invade_TimerWindow
      • Game - Display to (All players) the text: (Wave + ((String(Invade_WaveInteger)) + has spawned!))
      • -------- Dead Archer --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Invade_TypeQuantityReal[1] Greater than or equal to 1.00
        • Then - Actions
          • Unit - Create (Integer(Invade_TypeQuantityReal[1])) Invade_Type[1] for Player 12 (Brown) at Invade_Point facing Default building facing degrees
          • Unit Group - Add all units of (Last created unit group) to Invade_Group
        • Else - Actions
      • -------- Ghoul --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Invade_TypeQuantityReal[2] Greater than or equal to 1.00
        • Then - Actions
          • Unit - Create (Integer(Invade_TypeQuantityReal[2])) Invade_Type[2] for Player 12 (Brown) at Invade_Point facing Default building facing degrees
          • Unit Group - Add all units of (Last created unit group) to Invade_Group
        • Else - Actions
      • -------- Risen Soldier --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Invade_TypeQuantityReal[3] Greater than or equal to 1.00
        • Then - Actions
          • Unit - Create (Integer(Invade_TypeQuantityReal[3])) Invade_Type[3] for Player 12 (Brown) at Invade_Point facing Default building facing degrees
          • Unit Group - Add all units of (Last created unit group) to Invade_Group
        • Else - Actions
      • -------- Skeletal Brute --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Invade_TypeQuantityReal[4] Greater than or equal to 1.00
        • Then - Actions
          • Unit - Create (Integer(Invade_TypeQuantityReal[4])) Invade_Type[4] for Player 12 (Brown) at Invade_Point facing Default building facing degrees
          • Unit Group - Add all units of (Last created unit group) to Invade_Group
        • Else - Actions
      • -------- Zombie --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Invade_TypeQuantityReal[5] Greater than or equal to 1.00
        • Then - Actions
          • Unit - Create (Integer(Invade_TypeQuantityReal[5])) Invade_Type[5] for Player 12 (Brown) at Invade_Point facing Default building facing degrees
          • Unit Group - Add all units of (Last created unit group) to Invade_Group
        • Else - Actions
 
Level 18
Joined
Nov 21, 2012
Messages
835
I suggested to you to not use "unit dies" event trigger, but I didnt ask if you're using for your creeps: "Does decay" flag in OE or not. Since unit are removed from unit group when removed from the game then - if you use "does't decay" you dont need "unit dies" trigger as unit after "Art death time" is removed from unit group. Otherwise you need "unit dies" trigger.

You are very inventive for this " +1 Dead Archer for every 5 waves" idea ;)
However there's simpler way to do that:
abandom this variable "Invade_TypeQuantityReal[x]"
use integer comparison:
modulus = dividend - ((dividend / divisor) * divisor)
"dividend" is your Invade_WaveInteger

to send additional unit every 5 wave:
set modulus = Invade_WaveInteger - ((Invade_WaveInteger / 5) * 5)
if modulus==0 then
your action
endif
so at waves: 5, 10, 15, 20, 25 etc... your action will run

to send additional unit every 7 wave:
set modulus = Invade_WaveInteger - ((Invade_WaveInteger / 7) * 7)
if modulus==0 then
your action
endif
so at waves: 7, 14, 21, 28, 35 etc... your action will run

edit
just realized that there's gui action for this:
  • Untitled Trigger 003
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Invade_WaveInteger mod 5) Equal to 0
        • Then - Actions
          • -------- this will run for 5, 10, 15, 20, etc... waves --------
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Invade_WaveInteger mod 7) Equal to 0
        • Then - Actions
          • -------- this will run for 7, 14, 21, 28, 35, etc... waves --------
        • Else - Actions
 
Last edited:
Level 8
Joined
Jun 13, 2010
Messages
344
I suggested to you to not use "unit dies" event trigger, but I didnt ask if you're using for your creeps: "Does decay" flag in OE or not. Since unit are removed from unit group when removed from the game then - if you use "does't decay" you dont need "unit dies" trigger as unit after "Art death time" is removed from unit group. Otherwise you need "unit dies" trigger.

I will look at this some time. I am taking a short break from the editor so it will not get boring, while I find ideas for the map. :)
 
Status
Not open for further replies.
Top