Improving Creep Respawn/Loot System

Level 21
Joined
Mar 16, 2008
Messages
955
There are 15 creep camps that unlock a loot chest when all of them are dead. Problem is when the camp respawns, I can't figure out how to check if that camp is dead. So for the respawns we just make the chest vulnerable and ignore the "kill the entire camp" mechanic to get loot. Is there an easy way to fix this? To make sure the respawns also need to be killed.

The first round of loot is handled by GUI loot tables. and the respawn is handled by trigger. But I can't think of a good way to make the chests vulnerable once the camps are dead. Not really sure how to check where the creep camp units are in the array.

  • Destroy Doodad 1
    • Events
      • Unit - Rock Golem 1269 <gen> Dies
      • Unit - Rock Golem 1271 <gen> Dies
      • Unit - Rock Golem 1270 <gen> Dies
      • Unit - Mud Golem 0947 <gen> Dies
      • Unit - Mud Golem 0885 <gen> Dies
      • Unit - Mud Golem 0909 <gen> Dies
    • Conditions
      • (Rock Golem 1269 <gen> is dead) Equal to True
      • (Rock Golem 1271 <gen> is dead) Equal to True
      • (Rock Golem 1270 <gen> is dead) Equal to True
      • (Mud Golem 0947 <gen> is dead) Equal to True
      • (Mud Golem 0885 <gen> is dead) Equal to True
      • (Mud Golem 0909 <gen> is dead) Equal to True
    • Actions
      • Set VariableSet temp_loot_pt = (Position of |cff009900Uncommon Treasure|r (variation 1) 1203 <gen>)
      • Unit - Remove Invulnerable (treasure) from |cff009900Uncommon Treasure|r (variation 1) 1203 <gen>
      • Special Effect - Create a special effect at temp_loot_pt using Objects\Spawnmodels\Other\ToonBoom\ToonBoom.mdl
      • Special Effect - Destroy (Last created special effect)
      • Custom script: call RemoveLocation(udg_temp_loot_pt)
      • Trigger - Turn off (This trigger)
  • loot respawn init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set VariableSet loot_spawn_types[1] = Blood Stained Dagger
      • Set VariableSet loot_spawn_types[2] = Fallen Death Knight's Blade
      • Set VariableSet loot_spawn_types[3] = Fallen Knight's Helmet
      • Set VariableSet loot_spawn_types[4] = Fallen Paladin's War Gavel
      • Set VariableSet loot_spawn_types[5] = Fel Steel Shoulder Plates
      • Set VariableSet loot_spawn_types[6] = Gilded Chestguard
      • Set VariableSet loot_spawn_types[7] = Imbued Royal Knight's Regalia
      • Set VariableSet loot_spawn_types[8] = Iron Cuisses
      • Set VariableSet loot_spawn_types[9] = Iron Gauntlets
      • Set VariableSet loot_spawn_types[10] = Iron Shoulder Plates
      • Set VariableSet loot_spawn_types[11] = Knight's Belt
      • Set VariableSet loot_spawn_types[12] = Pandaren Amulet
      • Set VariableSet loot_spawn_types[13] = Ruby Ring
      • Set VariableSet loot_spawn_types[14] = Shadow Bow
      • Set VariableSet loot_spawn_types[15] = Vas Fictile Axe
      • Set VariableSet loot_spawn_types[16] = Verbena Bonariensis
      • Set VariableSet loot_spawn_types[17] = Warhorse Bridal
      • Set VariableSet loot_spawn_types[18] = Gold Coins
      • Set VariableSet loot_spawn_types[19] = Gold Coins
  • treasure dies
    • Events
      • Unit - |cff009900Uncommon Treasure|r (variation 1) 1203 <gen> Dies
      • Unit - |cff009900Uncommon Treasure|r (variation 1) 1204 <gen> Dies
      • Unit - |cff009900Uncommon Treasure|r (variation 1) 1205 <gen> Dies
      • Unit - |cff009900Uncommon Treasure|r (variation 1) 1206 <gen> Dies
      • Unit - |cff009900Uncommon Treasure|r (variation 1) 1207 <gen> Dies
      • Unit - |cff009900Uncommon Treasure|r (variation 1) 1631 <gen> Dies
      • Unit - |cff009900Uncommon Treasure|r (variation 1) 1635 <gen> Dies
      • Unit - |cff009900Uncommon Treasure|r (variation 1) 1636 <gen> Dies
      • Unit - |cff009900Uncommon Treasure|r (variation 2) 1562 <gen> Dies
      • Unit - |cff009900Uncommon Treasure|r (variation 2) 1608 <gen> Dies
      • Unit - |cff009900Uncommon Treasure|r (variation 2) 1623 <gen> Dies
      • Unit - |cff009900Uncommon Treasure|r (variation 2) 1630 <gen> Dies
      • Unit - |cff009900Uncommon Treasure|r (variation 2) 1632 <gen> Dies
      • Unit - |cff009900Uncommon Treasure|r (variation 2) 1633 <gen> Dies
      • Unit - |cff009900Uncommon Treasure|r (variation 2) 1634 <gen> Dies
    • Conditions
    • Actions
      • Set VariableSet original_treasure_counter = (original_treasure_counter + 1)
      • Unit - Remove (Dying unit) from the game
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • original_treasure_counter Equal to 15
        • Then - Actions
          • Trigger - Turn on loot chest dies <gen>
          • Trigger - Turn off (This trigger)
        • Else - Actions
  • loot chest dies
    • Events
      • Unit - A unit owned by Neutral Hostile Dies
    • Conditions
      • (Level of Mark of Loot Chest (class) for (Dying unit)) Equal to 1
    • Actions
      • Set VariableSet loot_spawn_pt = (Position of (Dying unit))
      • Unit - Remove (Dying unit) from the game
      • Set VariableSet loot_ran_num = (Random integer number between 1 and 25)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • loot_ran_num Equal to 25
        • Then - Actions
          • Set VariableSet loot_ran_num = (Random integer number between 1 and 4)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • loot_ran_num Equal to 1
              • (C'thun (Old God) 2423 <gen> is alive) Equal to True
            • Then - Actions
              • Item - Create Old God Rune: C'thuun at loot_spawn_pt
              • Custom script: call RemoveLocation(udg_loot_spawn_pt)
              • Skip remaining actions
            • Else - Actions
              • Set VariableSet loot_ran_num = (Random integer number between 1 and 19)
              • Item - Create loot_spawn_types[loot_ran_num] at loot_spawn_pt
              • Custom script: call RemoveLocation(udg_loot_spawn_pt)
              • Skip remaining actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • loot_ran_num Equal to 2
              • (Yogg-Saron (Old God) 2424 <gen> is alive) Equal to True
            • Then - Actions
              • Item - Create Old God Rune: Yogg-saron at loot_spawn_pt
              • Custom script: call RemoveLocation(udg_loot_spawn_pt)
              • Skip remaining actions
            • Else - Actions
              • Set VariableSet loot_ran_num = (Random integer number between 1 and 19)
              • Item - Create loot_spawn_types[loot_ran_num] at loot_spawn_pt
              • Custom script: call RemoveLocation(udg_loot_spawn_pt)
              • Skip remaining actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • loot_ran_num Equal to 3
              • (N'zoth (Old God) 2425 <gen> is alive) Equal to True
            • Then - Actions
              • Item - Create Old God Rune: N'zoth at loot_spawn_pt
              • Custom script: call RemoveLocation(udg_loot_spawn_pt)
              • Skip remaining actions
            • Else - Actions
              • Set VariableSet loot_ran_num = (Random integer number between 1 and 19)
              • Item - Create loot_spawn_types[loot_ran_num] at loot_spawn_pt
              • Custom script: call RemoveLocation(udg_loot_spawn_pt)
              • Skip remaining actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • loot_ran_num Equal to 4
              • (Algalon the Observer (Old God) 2426 <gen> is alive) Equal to True
            • Then - Actions
              • Item - Create Prison Portal Rune: Algalon at loot_spawn_pt
              • Custom script: call RemoveLocation(udg_loot_spawn_pt)
              • Skip remaining actions
            • Else - Actions
              • Set VariableSet loot_ran_num = (Random integer number between 1 and 19)
              • Item - Create loot_spawn_types[loot_ran_num] at loot_spawn_pt
              • Custom script: call RemoveLocation(udg_loot_spawn_pt)
              • Skip remaining actions
        • Else - Actions
          • Set VariableSet loot_ran_num = (Random integer number between 1 and 19)
          • Item - Create loot_spawn_types[loot_ran_num] at loot_spawn_pt
          • Custom script: call RemoveLocation(udg_loot_spawn_pt)
  • New Respawn Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units in Main Map Region <gen> owned by Neutral Hostile) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Level of Mark of No Rez Creep (class) for (Picked unit)) Not equal to 1
            • Then - Actions
              • -------- increment counter --------
              • Set VariableSet creep_counter = (creep_counter + 1)
              • -------- unit --------
              • Set VariableSet creep_array[creep_counter] = (Picked unit)
              • -------- point of unit --------
              • Set VariableSet creep_point[creep_counter] = (Position of (Picked unit))
              • -------- unit facing --------
              • Set VariableSet creep_real[creep_counter] = (Facing of (Picked unit))
              • -------- unit type --------
              • Set VariableSet creep_type[creep_counter] = (Unit-type of (Picked unit))
            • Else - Actions
  • New Respawn Creep
    • Events
      • Game - The in-game time of day becomes Equal to 6.06
    • Conditions
      • (day_counter mod 2) Equal to 0
    • Actions
      • For each (Integer creep_A_interger) from 1 to creep_counter, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (creep_array[creep_A_interger] is dead) Equal to True
            • Then - Actions
              • Unit - Create 1 creep_type[creep_A_interger] for Neutral Hostile at creep_point[creep_A_interger] facing creep_real[creep_A_interger] degrees
              • Set VariableSet creep_array[creep_A_interger] = (Last created unit)
              • Special Effect - Create a special effect at creep_point[creep_A_interger] using Abilities\Spells\Orc\FeralSpirit\feralspiritdone.mdl
              • Special Effect - Destroy (Last created special effect)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Level of Mark of Loot Chest (class) for creep_array[creep_A_interger]) Equal to 1
                • Then - Actions
                  • Unit Group - Add creep_array[creep_A_interger] to Creep_Treasure_Unit_Grp
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • original_treasure_counter Less than 15
                    • Then - Actions
                      • Unit - Remove creep_array[creep_A_interger] from the game
                    • Else - Actions
                • Else - Actions
            • Else - Actions
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
Use Unit Group arrays to track multiple groups of Units. Use a Unit Indexer or a Hashtable to link each Unit to their Unit Group. Then whenever a unit dies you can check to see if it is linked to a group and go from there. If it has a group then remove it from that group, check if that group is empty and proceed to your respawn logic if necessary. This is clean and highly efficient.

Here's a simple Unit Indexer example:

Link and Add units to their Unit Group when they're created or at the start of the map if they're pre-placed (Elapsed time 0.01s):
  • Actions
    • Unit - Create 1 Creep...
    • Set Variable CV = (Custom value of (Last created unit))
    • Set Variable Group_Number = 3
    • Set Variable Creep_Group_Number[CV] = Group_Number
    • Unit Group - Add (Last created unit) to Creep_Groups[Group_Number]
Get and Remove units from their Unit Group when they die:
  • Events
    • Unit - A unit Dies
  • Conditions
    • Creep_Group_Number[(Custom value of (Triggering unit))] Greater than 0
  • Actions
    • Set Variable CV = (Custom value of (Triggering unit))
    • Set Variable Group_Number = Creep_Group_Number[CV]
    • Unit Group - Remove (Triggering unit) from Creep_Groups[Group_Number]
    • If all conditions are true then do (Actions)
      • If - Conditions
        • (Creep_Groups[Group_Number] is empty) Equal to True
      • Then - Actions
        • -------- All of the units in the group have died --------
      • Else - Actions
        • -------- At least one unit is still alive --------
Important:

1) Unit Group arrays need to be initialized before becoming usable, so make sure that you set the Size inside of the Variable Editor to a large enough number. For example, setting it to 100 would allow you to use an Index range of [0] to [100]. In other words, you can have 100 different Unit Groups.

2) Most Unit Indexers will recycle the custom values of dead units. This could be problematic for a respawn system since you don't want your dead unit's custom values to change and lose track of their data. That means switching to a Hashtable could be necessary. The logic would remain mostly the same, just replace all instances of Creep_Group_Number[] with a saved Integer value inside of a Hashtable.

3) Removed units won't fire the Event "A unit Dies", you should be aware of this! If you must Remove a creep then you can kill it first to run the Event:
  • Actions
    • Unit - Kill (Triggering unit)
    • Unit - Remove (Triggering unit) from the game
 
Last edited:
Level 21
Joined
Mar 16, 2008
Messages
955
Thank you I think I'll use this system. However I'm confused how I can reference certain units in the index if they are pre placed. How do I tell the indexer exactly which 5 units should be in a certain group?
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
They're preplaced so you already have a direct reference to each of them.
  • Unit Group - Add Footman 0003 to ...
  • Unit Group - Add Footman 0004 to ...
  • Unit Group - Add Footman 0005 to ...
You could also use Regions if that'd be easier, like have a Region covering each "Creep Camp", then you can use the Pick Every Unit In Region action to help simplify things.
 
Last edited:
Top