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

I maybe have a leak in spawning units

Status
Not open for further replies.
Level 2
Joined
Aug 6, 2012
Messages
27
Hey guys I recently created a custom map that allows our heroes to attack against the monsters.

I create 2 regions, one where the monsters spawn and one for our castle.And I want the monsters to go and destroy the castle.


  • Untitled Trigger 001
    • Events
      • Time - Elapsed game time is 120.00 seconds
    • Conditions
    • Actions
      • Player - Add 500 to Player 3 (Teal) Current gold
      • Player - Add 500 to Player 1 (Red) Current gold
      • Game - Display to (All players) the text: Next wave begins...
      • Wait 2.00 seconds
      • Game - Display to (All players) the text: You have just got 500 gold.
      • Unit - Create 10 Crypt Fiend for Player 2 (Blue) at (Center of Region 000 <gen>) facing (Player 1 (Red) start location)
      • Unit Group - Order (Units in Region 000 <gen>) to Attack-Move To (Center of Region 001 <gen>)
      • Wait 6.00 seconds
      • Unit - Create 1 Crypt Fiend for Player 2 (Blue) at (Center of Region 000 <gen>) facing (Player 1 (Red) start location)
      • Unit Group - Order (Units in Region 000 <gen>) to Attack-Move To (Center of Region 001 <gen>)
(player 2 is the enemy; Region 000 <gen> is the spawning location; Region 001 <gen> is our hero's castle)

Each way I use the same structure of strigger as above, but after some waves, some monsters in previous wave do not go and attack.they go back to the spawning point and stand, so they only go and attack in the next way:vw_wtf:

Can anyone tell me why and help me? thanks in advance!
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
You certainly do have leaks, but I don't think that means what you think it means.
Leaks don't really cause a trigger (or objects) to bug. Leaks cause the game to run slower than it normally would.

Try using this action right after you spawned the units:
  • AI - Ignore (Last created unit)'s guard position
(You will have to do this for all units by the way, this only works for 1 last created unit).

Something like this:
  • Set tempLoc1 = (Center of Region 000 <gen>)
  • Set tempLoc2 = (Center of Region 001 <gen>)
  • For each (Integer A) from 1 to 10, do (Actions)
    • Loop - Actions
      • Unit - Create 1 Crypt Fiend for Player 2 (Blue) at tempLoc1 facing 90.00 degrees
      • AI - Ignore (Last created unit)'s guard position
      • Unit - Order (Last created unit) to Attack-Move To tempLoc2
  • Custom script: call RemoveLocation( udg_tempLoc1 )
  • Custom script: call RemoveLocation( udg_tempLoc2 )
The point variables and custom scripts are to remove the actual leaks.
 
Last edited:
Level 28
Joined
Jan 26, 2007
Messages
4,789
Edit: the way of my friend ap0calypse is correct here but I have to edit it a bit, because it's:

  • Custom script: call RemoveLocation( udg_tempLoc1 )
  • Custom script: call RemoveLocation( udg_tempLoc2 )
If you use a small r instead of a capital R, you will get a script error.
Lol, thanks for that :D (typo'd the first one and copy/pasted it, stupid me ^^).
 
Level 2
Joined
Aug 6, 2012
Messages
27
It means that each wave I have a strigger like this:

  • Untitled Trigger 001
    • Events
      • Time - Elapsed game time is 120.00 seconds
    • Conditions
    • Actions
      • Player - Add 500 to Player 3 (Teal) Current gold
      • Player - Add 500 to Player 1 (Red) Current gold
      • Game - Display to (All players) the text: Next wave begins...
      • Wait 2.00 seconds
      • Game - Display to (All players) the text: You have just got 500 gold.
      • Set tempLoc1 = (Center of Region 000 <gen>)
      • Set tempLoc2 = (Center of Region 001 <gen>)
    • For each (Integer A) from 1 to 10, do (Actions)
      • Loop - Actions
        • Unit - Create 1 Crypt Fiend for Player 2 (Blue) at tempLoc1 facing 90.00 degrees
        • AI - Ignore (Last created unit)'s guard position
        • Unit - Order (Last created unit) to Attack-Move To tempLoc2
    • Custom script: call removeLocation( udg_tempLoc1 )
    • Custom script: call removeLocation( udg_tempLoc2 )
it is right?
 
This could be this way although probs more inefficient(got bored lol).:q
  • Untitled Trigger 001
    • Events
      • Time - Elapsed game time is 120.00 seconds
    • Conditions
    • Actions
      • Player - Add 500 to Player 3 (Teal) Current gold
      • Player - Add 500 to Player 1 (Red) Current gold
      • Game - Display to (All players) the text: Next wave begins...
      • Wait 2.00 seconds
      • Game - Display to (All players) the text: You have just got 500 gold.
      • Set tempLoc_1 = (Center of Region 000 <gen>)
      • Set tempLoc_2 = (Center of Region 001 <gen>)
      • Unit - Create 10 Crypt Fiend for Player 2 (Blue) at tempLoc_1 facing 90.00 degrees
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Last created unit group) and do (Actions)
        • Loop - Actions
          • AI - Ignore (Picked unit)'s guard position
          • Unit - Order (Picked unit) to Attack-Move To tempLoc_2
      • Custom script: call RemoveLocation(udg_tempLoc_1)
      • Custom script: call RemoveLocation(udg_tempLoc_2)
although you also did ap0calipses mistake. xD
Also I would like to know if using 'last created units' leaks?
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
It means that each wave I have a strigger like this:

  • Untitled Trigger 001
    • Events
      • Time - Elapsed game time is 120.00 seconds
    • Conditions
    • Actions
      • Player - Add 500 to Player 3 (Teal) Current gold
      • Player - Add 500 to Player 1 (Red) Current gold
      • Game - Display to (All players) the text: Next wave begins...
      • Wait 2.00 seconds
      • Game - Display to (All players) the text: You have just got 500 gold.
      • Set tempLoc1 = (Center of Region 000 <gen>)
      • Set tempLoc2 = (Center of Region 001 <gen>)
    • For each (Integer A) from 1 to 10, do (Actions)
      • Loop - Actions
        • Unit - Create 1 Crypt Fiend for Player 2 (Blue) at tempLoc1 facing 90.00 degrees
        • AI - Ignore (Last created unit)'s guard position
        • Unit - Order (Last created unit) to Attack-Move To tempLoc2
    • Custom script: call removeLocation( udg_tempLoc1 )
    • Custom script: call removeLocation( udg_tempLoc2 )
it is right?

Kind-of. Read Dr. Boom's comment: I made a small mistake myself :p Except for that tiny mistake, the trigger is correct.
By the way: there are multiple ways to compress a huge amount of waves into 2 triggers (or 3, depending on your style). It is recommended that you do not use 1 trigger/wave.
You can also change the "90.00 degrees" to anything you want (but DO NOT use a point! So "Player starting location" is not good, use an actual angle).

Edit: just now saw the question DeathChef asked...
Also I would like to know if using 'last created units' leaks?
It does.
The part of the code you need to know is:
JASS:
set bj_groupLastCreatedDest = CreateGroup()
// [...]
return bj_groupLastCreatedDest
The "CreateGroup()" there means it creates one, yet never destroys it :D

Which is actually funny, because "bj_lastCreatedGroup" exists, yet Blizz doesn't return that one. It creates a new group and copies the last created group.
 
Level 2
Joined
Aug 6, 2012
Messages
27
Kind-of. Read Dr. Boom's comment: I made a small mistake myself :p Except for that tiny mistake, the trigger is correct.

By the way: there are multiple ways to compress a huge amount of waves into 2 triggers (or 3, depending on your style). It is recommended that you do not use 1 trigger/wave.
You can also change the "90.00 degrees" to anything you want (but DO NOT use a point! So "Player starting location" is not good, use an actual angle).


can you give me some suggestions of conpressing waves into only 2,3 striggers?
 
Level 16
Joined
May 1, 2008
Messages
1,605
Are you guys talking about a huge spawn system? Well then you only need 2 triggers..
the init trigger and the spawn trigger - not more not less (not less in GUI)
But for spawn systems you really should learn how to use vJass, because it has no leaks and no variables, which makes it tons better =D
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Are you guys talking about a huge spawn system? Well then you only need 2 triggers..
the init trigger and the spawn trigger - not more not less (not less in GUI)
But for spawn systems you really should learn how to use vJass, because it has no leaks and no variables, which makes it tons better =D
It is perfectly acceptable to need 3 triggers for the spawn system (if that is your style).
Usually the third trigger would be the init spawn (all units are dead, initialize spawn).
Maybe even a fourth trigger for the timer to make it less messy (this can come in handy if the units spawn 1 by 1).

By the way: vJass does have variables :wink:


can you give me some suggestions of conpressing waves into only 2,3 striggers?
My pleasure.

So the first thing you need to do is create a ton of variables. Everything you want to know about your wave should be a variable (with an array).
Then you can set those up in some kind of init-trigger.

  • Setting up Creeps
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- waveCreepType[X] = Creep type of each level --------
      • -------- waveGoldLevel[X] = Gold gained after defeating a level --------
      • -------- waveWaveType[X] = The type of the wave (air/normal/immune/...) --------
      • -------- waveCreepAmount[X] = The amount of units that spawn per level --------
      • -------- Level 1 --------
      • Set tempInt = (tempInt + 1)
      • Set waveCreepType[tempInt] = Peasant
      • Set waveGoldLevel[tempInt] = 1
      • Set waveWaveType[tempInt] = Dummy
      • Set waveCreepAmount[tempInt] = 20
      • -------- Level 2 --------
      • Set tempInt = (tempInt + 1)
      • Set waveCreepType[tempInt] = Footman
      • Set waveGoldLevel[tempInt] = 3
      • Set waveWaveType[tempInt] = Normal
      • Set waveCreepAmount[tempInt] = 15
      • -------- [...] --------
      • -------- Copy/paste "Wave 1" and set the variables to whatever you like --------
You can add armor type, gold/kill (if you have a custom bounty system), the interval between each creep (if they spawn 1 by 1), ...
Just add anything you like :)

It is also very nice to add this:
  • Set spawnLoc[1] = (Center of SpawnRed <gen>)
  • Set spawnLoc[2] = (Center of SpawnBlue <gen>)
  • Set endLoc[1] = (Center of EndRed <gen>)
  • Set endLoc[2] = (Center of EndBlue <gen>)
At the end of that trigger (do this for all players).
That way we don't have to use custom scripts anymore.


Now for the spawning.
You need 1 more variable. I usually call it "currentLevel" (integer variable).
Increase currentLevel by 1 everytime a level is done.

Then you can spawn creeps like this:
  • Player Group - Pick every player in playingPlayers and do (Actions)
    • Loop - Actions
      • For each (Integer A) from 1 to waveCreepAmount[currentLevel], do (Actions)
        • Loop - Actions
          • Unit - Create 1 waveCreepType[currentLevel] for Player 12 (Brown) at spawnLoc[(Player number of (Picked player))] facing Default building facing degrees
          • AI - Ignore (Last created unit)'s guard position
          • Unit - Order (Last created unit) to Attack-Move To endLoc[(Player number of (Picked player))]
Where "playingPlayers" is the player group that contains all human players with as slot status "playing" (so there is no spawn for unused/left players).

You can link this up with a timer (if all creeps are dead, start timer that expires in X seconds) and activate the trigger above when the timer ends.
And there you go, all wave-triggers have been combined into a few triggers that will automatically do all work for you :)
 
Level 16
Joined
May 1, 2008
Messages
1,605
Moin moin =)

Okay first of all !READ! it's no battle between ap0calypse and me, but since he said how many triggers and variables you maybe need for a spawn system, he just turned my mind on I started to think about it myself and I come to this solution:

1 Trigger - 2 Variables - (shit)-GUI
(Well since this guy just wanna simple spawn system, it's possible like this, else I'm not sure!)

  • SpawnSystem
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Custom script: local unit u
      • Set SpawnLevel = (SpawnLevel + 1)
      • For each (Integer A) from 1 to 5, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SpawnUnit[(Integer A)] Equal to No unit-type
            • Then - Actions
              • Set SpawnUnit[1] = Peasant
              • Set SpawnUnit[2] = Footman
              • Set SpawnUnit[3] = Knight
              • Set SpawnUnit[4] = Rifleman
              • Set SpawnUnit[5] = Mortar Team
              • -------- --------
              • Set SpawnAmount[1] = 10
              • Set SpawnAmount[2] = 20
              • Set SpawnAmount[3] = 5
              • Set SpawnAmount[4] = 13
              • Set SpawnAmount[5] = 9
            • Else - Actions
      • Wait 10.00 seconds
      • For each (Integer A) from 1 to 2, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Integer A) Equal to 1
            • Then - Actions
              • For each (Integer B) from 1 to SpawnAmount[SpawnLevel], do (Actions)
                • Loop - Actions
                  • Custom script: set u = CreateUnit(Player(1),udg_SpawnUnit[udg_SpawnLevel],GetRectCenterX(gg_rct_SpawnRect1),GetRectCenterY(gg_rct_SpawnRect1),0.)
                  • Custom script: call RemoveGuardPosition(u)
                  • Custom script: call IssuePointOrder(u,"attack",GetRectCenterX(gg_rct_MoveRect),GetRectCenterY(gg_rct_MoveRect))
                  • Custom script: set u = null
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Integer A) Equal to 2
                • Then - Actions
                  • For each (Integer B) from 1 to SpawnAmount[SpawnLevel], do (Actions)
                    • Loop - Actions
                      • Custom script: set u = CreateUnit(Player(1),udg_SpawnUnit[udg_SpawnLevel],GetRectCenterX(gg_rct_SpawnRect2),GetRectCenterY(gg_rct_SpawnRect2),0.)
                      • Custom script: call RemoveGuardPosition(u)
                      • Custom script: call IssuePointOrder(u,"attack",GetRectCenterX(gg_rct_MoveRect),GetRectCenterY(gg_rct_MoveRect))
                      • Custom script: set u = null
                • Else - Actions
      • Wait 10.00 seconds
      • Trigger - Run SpawnSystem <gen> (ignoring conditions)
Greetings and Peace
Dr. Boom
 
Status
Not open for further replies.
Top