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

unit respawn trigger

Status
Not open for further replies.
Level 3
Joined
Jan 6, 2021
Messages
24
hi, so i made a trigger for respawns but i cant get it to work as i intended. my goal with this is when a unit dies it checks for it then wait X sec and respawn the units, but after one death they respawn and keeps respawning every 20 sec, and i guess it has with (soldier 0032) ignore the spelling in the trigger.

im trying to make stuff work and do it myself too learn abit more about this, so this trigger could be cleaner iguess.
unknown.png
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,542
So you're making some fundamental mistakes here.

This "Wait until" action is generally avoided and in this case doesn't work the way you think it does:
  • Wait until (Dying unit) Equal to tier 1 soldier 0032 <gen>...
tier 1 soldier 0032 <gen> can only ever die once, assuming it's not a Hero. Even if you use a spell like Resurrection or Animate Dead, the units that are "revived" are actually brand new units that have no relation to the old unit. Heroes are special in that they can be revived.

With that in mind, running the trigger again (checking conditions) means that you're basically running a trigger like this:
  • Events
  • Conditions
    • (Dying unit) Equal to tier 1 soldier 0032 <gen>
  • Actions
    • Wait until...
    • etc...
Issues here:
There's no Event of a unit dying therefore there is no (Dying unit). Event Responses are set in response to an Event.
tier 1 soldier 0032 <gen> has already died and therefore this Condition will NEVER be possible again. This trigger will never get past the Conditions.
Wait until (Dying unit) Equal to tier 1 soldier 0032 <gen> is impossible, like I said before this unit has already died, it can't die again.

Here's a solution. Although, I'm not sure if I fully understand what you're trying to achieve:
  • Events
    • Unit - tier 1 soldier 0032 <gen> dies
  • Conditions
  • Actions
    • Wait 20.00 seconds
    • Unit - Create 3 tier 1 soldier for Neutral Hostile...
    • Trigger - Run (This trigger) (ignoring conditions)
So when this specific soldier dies the trigger will begin repeating at an interval of 20.00 seconds, creating 3 new tier 1 soldiers each time. Note how I'm using a Specific Unit event here as opposed to a Player Unit event. This removes the need for the Unit condition. The "Wait until" action was never necessary to begin with so I got rid of that as well. I'm also using "Run trigger (ignoring conditions)" since I don't have any Conditions to check.

Here's how to post your triggers on Hive:
 
Last edited:
Level 3
Joined
Jan 6, 2021
Messages
24
well thanks alot you made me learn something :), but im not sure this will fix what i am thinking of doing. i think Angel arena had what i am looking for, its like you go around killing mobs and after a time they respawn but i dont want them to keep stacking so my problem is that i need a condition that checks if there is living units in that area/region!
i would like to have something like
"check if units are alive in region 000 and If units are alive in region 000 check again" not sure if there is a condition or a action that can do this but it feels like a simple thing right?
 
Level 39
Joined
Feb 27, 2007
Messages
5,013
The easiest
"check if units are alive in region 000 and If units are alive in region 000 check again
If I attack the enemies and then pull them out of the region but don't kill them, a duplicate set will be spawned where they originally were. You can't check if all units in a region are dead because units that aren't in the region won't be checked. The easiest solution is to give every unit that should be respawned either a dummy flag ability that does nothing or a unit-type classification (like Ancient or Suicidal) that is otherwise unused in your map. Then you check for units with that ability or unit-type classification when registering all the respawns

  • Events
    • Time - Elapsed game time is 0.50 seconds
  • Conditions
  • Actions
    • Set RS_Delay = 90.00 //90 second delay before a unit respawns
    • Set RS_Count = 0
    • Custom script: set bj_wantDestroyGroup = true //cleans a group leak in the line below this one
    • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
      • Loop - Actions
        • If (All conditions are true) then do (Then actions) else do (Else actions)
          • If - Conditions
            • (Level of FLAG ABILITY for (Picked Unit)) greater than 0
            • -------- or the classification check --------
          • Then - Actions
            • Set RS_Count = RS_Count + 1
            • Set RS_Unit[RS_Count] = (Picked Unit)
            • Set RS_UnitType[RS_Count] = (Unit-type of RS_Unit[RS_Count])
            • Set RS_Pos[RS_Count] = (Position of RS_Unit[RS_Count])
            • Set RS_Facing[RS_Count] = (Facing angle of RS_Unit[RS_Count])
            • Set RS_Owner[RS_Count] = (Owner of RS_Unit[RS_Count])
          • Else - Actions
  • Events
    • Unit - A unit dies
  • Conditions
    • (Level of FLAG ABILITY for (Triggering Unit)) greater than 0
    • -------- or check unit-type classification --------
  • Actions
    • -------- create an integer variable in the variable editor; we will shadow it here locally (so it works like a local variable, which are normally inaccessible in GUI, in order to be able to use a wait and avoid needing to attach data to a timer --------
    • -------- change the line below this one to match the name of your local integer variable (BUT KEEP THE udg_ PREFIX); in this example it is called TempInt --------
    • Custom script: local integer udg_TempInt = 0
    • Set TempUnit = (Triggering Unit)
    • For each (Integer A) from 1 to RS_Count do (Actions)
      • Loop - Actions
        • If (All conditions are true) then do (Then actions) else do (Else actions)
          • If - Conditions
            • RSUnit[(Integer A)] equal to TempUnit
          • Then - Actions
            • Set TempInt = (Integer A)
            • Custom script: exitwhen true //this leaves the loop early
          • Else - Actions
    • If (All conditions are true) then do (Then actions) else do (Else actions)
      • If - Conditions
        • TempInt greater than 0 //if it is >0 then we found a match
      • Then - Actions
        • Wait - RS_Delay game-time seconds
        • Unit - Create 1 RS_UnitType[TempInt] for RS_Owner[TempInt] at RS_Pos[TempInt] facing RS_Facing[TempInt] degrees
        • Set RS_Unit[TempInt] = (Last created unit)
      • Else - Actions
You could make respawn time variable as well. If you want respawns to happen in waves that's a little bit more effort, but not much.
 
Level 3
Joined
Jan 6, 2021
Messages
24
The easiest

If I attack the enemies and then pull them out of the region but don't kill them, a duplicate set will be spawned where they originally were. You can't check if all units in a region are dead because units that aren't in the region won't be checked. The easiest solution is to give every unit that should be respawned either a dummy flag ability that does nothing or a unit-type classification (like Ancient or Suicidal) that is otherwise unused in your map. Then you check for units with that ability or unit-type classification when registering all the respawns

  • Events
    • Time - Elapsed game time is 0.50 seconds
  • Conditions
  • Actions
    • Set RS_Delay = 90.00 //90 second delay before a unit respawns
    • Set RS_Count = 0
    • Custom script: set bj_wantDestroyGroup = true //cleans a group leak in the line below this one
    • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
      • Loop - Actions
        • If (All conditions are true) then do (Then actions) else do (Else actions)
          • If - Conditions
            • (Level of FLAG ABILITY for (Picked Unit)) greater than 0
            • -------- or the classification check --------
          • Then - Actions
            • Set RS_Count = RS_Count + 1
            • Set RS_Unit[RS_Count] = (Picked Unit)
            • Set RS_UnitType[RS_Count] = (Unit-type of RS_Unit[RS_Count])
            • Set RS_Pos[RS_Count] = (Position of RS_Unit[RS_Count])
            • Set RS_Facing[RS_Count] = (Facing angle of RS_Unit[RS_Count])
            • Set RS_Owner[RS_Count] = (Owner of RS_Unit[RS_Count])
          • Else - Actions
  • Events
    • Unit - A unit dies
  • Conditions
    • (Level of FLAG ABILITY for (Triggering Unit)) greater than 0
    • -------- or check unit-type classification --------
  • Actions
    • -------- create an integer variable in the variable editor; we will shadow it here locally (so it works like a local variable, which are normally inaccessible in GUI, in order to be able to use a wait and avoid needing to attach data to a timer --------
    • -------- change the line below this one to match the name of your local integer variable (BUT KEEP THE udg_ PREFIX); in this example it is called TempInt --------
    • Custom script: local integer udg_TempInt = 0
    • Set TempUnit = (Triggering Unit)
    • For each (Integer A) from 1 to RS_Count do (Actions)
      • Loop - Actions
        • If (All conditions are true) then do (Then actions) else do (Else actions)
          • If - Conditions
            • RSUnit[(Integer A)] equal to TempUnit
          • Then - Actions
            • Set TempInt = (Integer A)
            • Custom script: exitwhen true //this leaves the loop early
          • Else - Actions
    • If (All conditions are true) then do (Then actions) else do (Else actions)
      • If - Conditions
        • TempInt greater than 0 //if it is >0 then we found a match
      • Then - Actions
        • Wait - RS_Delay game-time seconds
        • Unit - Create 1 RS_UnitType[TempInt] for RS_Owner[TempInt] at RS_Pos[TempInt] facing RS_Facing[TempInt] degrees
        • Set RS_Unit[TempInt] = (Last created unit)
      • Else - Actions
You could make respawn time variable as well. If you want respawns to happen in waves that's a little bit more effort, but not much.
okey thanks, code looks complicated but i think i understand it kinda, can i just copy this code and change some stuff? i guess i need to make some variables and the dummy though. so the dummy is like a custom ability that does noting but as long there is units in region with this ability they will not respawn right?
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,542
If you provide more details about how the system should work that would help a lot. Every little detail you can think of because there's a lot of ways you can make a respawn system and saying "like the system in X map" isn't really that helpful if we haven't played the map.

That being said, I attached a system I made based on what I thought you might want.

How the system works:
You provide Regions which contain your Creeps. The system then creates a Hashtable which tracks Neutral Hostile units inside of these Regions.
It does this by storing data in the Hashtable using the Region (Rect) as the Parent key and storing the unit data at the Child keys.
The total number of Creeps in a region at initialization time is saved at Child key -1.
The current number of living Creeps in a Region is saved at Child key 0.
The Creep unit-types is saved at Child keys 1+.
The Creeps also have a link to the Region they belong to which is saved using their Handle as the Parent key and 0 as the Child key.
This allows us to detect the Region that a dying Creep belongs to. It also acts as a filter since we know that units missing this link aren't part of the system.

If you want a delay before the Creeps respawn then you can use the Creep Respawn Unit Dies Delayed trigger instead of the default one.
  • -------- SET DELAY HERE: --------
  • Wait 4.00 game-time seconds
I attached a second map (2) which simplifies things slightly and uses a periodic trigger for respawning.
 

Attachments

  • Creep Respawn System 1.w3m
    22 KB · Views: 8
  • Creep Respawn System 2.w3m
    19.9 KB · Views: 13
Last edited:
Level 18
Joined
Mar 16, 2008
Messages
721
also make the decay time longer in gameplay constants if you want a longer respawn time.

Here is a simpler version of Pyro's system if the others seem too complicated:

  • Creep Respawn Initial Start
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set VariableSet Creeps = (Units owned by Neutral Hostile.)
      • Unit Group - Pick every unit in Creeps and do (Actions)
        • Loop - Actions
          • Set VariableSet I = (I + 1)
          • Unit - Set the custom value of (Picked unit) to I
          • Set VariableSet Angle[I] = (Facing of (Picked unit))
          • Set VariableSet Position = (Position of (Picked unit))
          • Set VariableSet X[I] = (X of Position)
          • Set VariableSet Y[I] = (Y of Position)
          • Custom script: call RemoveLocation(udg_Position)
      • Set VariableSet I = 0
      • Set VariableSet Position = (Center of (Entire map)) [you want this incase there's a problem it will respawn units here]
  • Creep Respawn Loop
    • Events
      • Unit - A unit owned by Neutral Hostile Dies
    • Conditions
    • Actions
      • Set VariableSet I = (I + 1)
      • Set VariableSet Creep[I] = (Dying unit)
      • Wait 595.00 seconds
      • Set VariableSet J = (J + 1)
      • Unit - Create 1 (Unit-type of Creep[J]) for Neutral Hostile at (Position offset by (X[(Custom value of Creep[J])], Y[(Custom value of Creep[J])])) facing Angle[(Custom value of Creep[J])] degrees
      • Unit - Set the custom value of (Last created unit) to (Custom value of Creep[J])
(credit: [Solved] - [Need Help!] - Creep Respawning System)
 
Status
Not open for further replies.
Top