• 🏆 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!
  • ✅ Time to vote for the top 3 models! The POLL for Hive's 6th HD Modeling Contest: Mechanical is now open! 📅 Poll close on July 16, 2024! 🔗 Cast your vote now!
  • ✅ The POLL for Hive's Texturing Contest #33 is OPEN! Vote for the TOP 3 SKINS! 🔗Click here to cast your vote!

Respawn System Fix

Status
Not open for further replies.
Level 2
Joined
Jun 5, 2012
Messages
19
Hello guys!

I am in dire need of assistance here. I have a respawn system that respawns a random easy difficulty creep is a weak creep dies, medium for a medium creep and so on.
The code is working fine but the creeps only respawn twice, not thrice or more. Also it doesnt work for some units. Can you find errors/room for efficieny?

P.S. Lets not go into timers. Waits would do.


  • Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set TempInt[0] = 5
      • -------- --------
      • -------- Easy Creeps --------
      • Set CreepsType[1] = Mur'gul Cliffrunner
      • Set CreepsType[2] = Mur'gul Blood-Gill
      • Set CreepsType[3] = Mur'gul Tidewarrior
      • Set CreepsType[4] = Spider Crab Shorecrawler
      • Set CreepsType[5] = Spider Crab Limbripper
      • Set CreepsType[6] = Stormreaver Hermit
      • Set CreepsType[7] = Skeletal Orc
      • -------- Medium Creeps --------
      • Set CreepsType[8] = Sea Elemental
      • Set CreepsType[9] = Sea Giant
      • Set CreepsType[10] = Makrura Deepseer
      • Set CreepsType[11] = Skeletal Orc Grunt
      • Set CreepsType[12] = Mur'gul Marauder
      • Set CreepsType[13] = Giant Sea Turtle
      • Set CreepsType[14] = Mur'gul Snarecaster
      • -------- Hard Creeps --------
      • Set CreepsType[15] = Revenant of the Depths
      • Set CreepsType[16] = Sea Giant Hunter
      • Set CreepsType[17] = Gargantuan Sea Turtle
      • Set CreepsType[18] = Stormreaver Warlock
      • Set CreepsType[19] = Enraged Jungle Stalker
      • Set CreepsType[20] = Mur'gul Marauder
      • -------- Boss --------
      • Set CreepsType[21] = Deeplord Revenant
      • Set CreepsType[22] = Sea Giant Behemoth
      • Set CreepsType[23] = Ancient Hydra
      • Set CreepsType[24] = Skeletal Orc Champion
      • Set CreepsType[25] = Dragon Turtle
      • -------- --------
      • Set CreepsStartValue[1] = 1
      • Set CreepsStartValue[2] = 8
      • Set CreepsStartValue[3] = 15
      • Set CreepsStartValue[4] = 21
      • For each (Integer A) from 1 to 4, do (Actions)
        • Loop - Actions
          • Set CreepsEndValue[(Integer A)] = (CreepsStartValue[(Integer A)] - 1)
          • Set TempPoint[0] = (Random point in Corpses Area <gen>)
          • Unit - Create a CreepsType[(Random integer number between 1 and 20)] corpse for Neutral Hostile at TempPoint[0]
      • For each (Integer A) from 1 to 7, do (Actions)
        • Loop - Actions
          • Custom script: set bj_wantDestroyGroup = true
          • Unit Group - Pick every unit in (Units owned by Neutral Hostile matching ((Unit-type of (Matching unit)) Equal to CreepsType[(Integer A)])) and do (Actions)
            • Loop - Actions
              • Unit Group - Add (Picked unit) to CreepsTypeGroup[1]
              • Set TempInt[0] = (TempInt[0] + 1)
              • Unit - Set the custom value of (Picked unit) to TempInt[0]
              • Set CreepsPointLoc[(Custom value of (Picked unit))] = (Position of (Picked unit))
      • For each (Integer A) from 8 to 14, do (Actions)
        • Loop - Actions
          • Custom script: set bj_wantDestroyGroup = true
          • Unit Group - Pick every unit in (Units owned by Neutral Hostile matching ((Unit-type of (Matching unit)) Equal to CreepsType[(Integer A)])) and do (Actions)
            • Loop - Actions
              • Unit Group - Add (Picked unit) to CreepsTypeGroup[2]
              • Set TempInt[0] = (TempInt[0] + 1)
              • Unit - Set the custom value of (Picked unit) to TempInt[0]
              • Set CreepsPointLoc[(Custom value of (Picked unit))] = (Position of (Picked unit))
      • For each (Integer A) from 15 to 20, do (Actions)
        • Loop - Actions
          • Custom script: set bj_wantDestroyGroup = true
          • Unit Group - Pick every unit in (Units owned by Neutral Hostile matching ((Unit-type of (Matching unit)) Equal to CreepsType[(Integer A)])) and do (Actions)
            • Loop - Actions
              • Unit Group - Add (Picked unit) to CreepsTypeGroup[3]
              • Set TempInt[0] = (TempInt[0] + 1)
              • Unit - Set the custom value of (Picked unit) to TempInt[0]
              • Set CreepsPointLoc[(Custom value of (Picked unit))] = (Position of (Picked unit))
      • For each (Integer A) from 21 to 25, do (Actions)
        • Loop - Actions
          • Custom script: set bj_wantDestroyGroup = true
          • Unit Group - Pick every unit in (Units owned by Neutral Hostile matching ((Unit-type of (Matching unit)) Equal to CreepsType[(Integer A)])) and do (Actions)
            • Loop - Actions
              • Unit Group - Add (Picked unit) to CreepsTypeGroup[4]
              • Set TempInt[0] = (TempInt[0] + 1)
              • Unit - Set the custom value of (Picked unit) to TempInt[0]
              • Set CreepsPointLoc[(Custom value of (Picked unit))] = (Position of (Picked unit))
      • Custom script: call RemoveLocation(udg_TempPoint[0])
  • Spawn System
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Triggering player) Equal to Neutral Hostile
    • Actions
      • Game - Display to (All players) the text: debug
      • For each (Integer A) from 1 to 4, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Triggering unit) is in CreepsTypeGroup[(Integer A)]) Equal to True
            • Then - Actions
              • Unit Group - Remove (Triggering unit) from CreepsTypeGroup[(Integer A)]
              • Set CreepsCVPass = (Custom value of (Triggering unit))
              • Set CreepsFacingUnit[CreepsCVPass] = (Facing of (Triggering unit))
              • Set CreepsRespawnInterval[CreepsCVPass] = (6.00 x (Real((Integer A))))
              • Set CreepsStartValue[CreepsCVPass] = CreepsStartValue[(Integer A)]
              • Set CreepsEndValue[CreepsCVPass] = CreepsEndValue[(Integer A)]
              • Wait CreepsRespawnInterval[CreepsCVPass] seconds
              • Unit - Create 1 CreepsType[(Random integer number between CreepsStartValue[CreepsCVPass] and CreepsEndValue[CreepsCVPass])] for Neutral Hostile at CreepsPointLoc[CreepsCVPass] facing CreepsFacingUnit[CreepsCVPass] degrees
              • Unit Group - Add (Last created unit) to CreepsTypeGroup[(Integer A)]
              • Special Effect - Create a special effect attached to the origin of (Last created unit) using Abilities\Spells\Human\MassTeleport\MassTeleportCaster.mdl
              • Special Effect - Destroy (Last created special effect)
            • Else - Actions
 
Level 5
Joined
Jun 16, 2004
Messages
108
Well I will start with a potential problem to your system.
  • For each (Integer A) from 1 to 4, do (Actions)
Starting with this, note that the "integer a" variable is global.
Here is a simple trigger:
  • Untitled Trigger 020
    • Events
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 10, do (Actions)
        • Loop - Actions
          • Wait 30.00 seconds
Converted to JASS:
JASS:
function Trig_Untitled_Trigger_020_Actions takes nothing returns nothing
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 10
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        call TriggerSleepAction( 30.00 )
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
endfunction

Note that the JASS loop exits the "1 to 10" loop when the "integer a" variable becomes 11.

So what happens in your system when one unit dies, and then another unit dies before the previous one resurrects? I imagine it would go something like this:
- Unit 1 dies (easy creep)
- Trigger for unit 1 gets to integer a value of 1
- CreepsCVPass gets set to the custom value of unit 1; other values set
- Trigger for unit 1 gets to the wait
- Trigger for unit 1 is waiting
- Unit 2 dies (medium creep)
- Trigger for unit 2 gets to integer a value of 2
- CreepsCVPass gets set to the custom value of unit 2; other values set
- Trigger for unit 2 gets to the wait
- Trigger for unit 2 is waiting
- Trigger for unit 1 finishes waiting
- Trigger for unit 1 creates another creep with the CreepsCVPass value of unit 2
- Trigger for unit 1 adds spawned unit to creep group 2 (integer a value = 2 currently due to unit 2 running second)
- Trigger for unit 1 continues looping and exits when integer a = 5
- Trigger for unit 2 creates another creep with the CreepsCVPass value of unit 2
- Trigger for unit 2 adds spawned unit to creep group 5 (integer a value = 5 currently due to the loop from unit 1 finishing)
- Trigger for unit 2 exits the integer a loop immediately (5 > 4)

Well that is just one simple scenario, but it showcases how the system can pretty easily have unexpected results, both due to integer a being global and CreepsCVPass being global. Even if both creeps are the same type, the second reviving creep would still be in creep group 5.

So basically, using a wait in an integer a / integer b loop is not safe if any other trigger in your map can use those loops during the wait. Similarly, relying on a global variable's value after a wait when that value can be changed by other triggers is also not safe.

Using some JASS would pretty easily get around this via using local variables. Alternatively, you might be able to loop on a custom integer array variable, where the index is the custom value of the unit. Well, you can go with whatever kind of solution you can think of.

On another note, you do not set the custom value for units that are spawned in the second trigger, and you do not set the CreepsPointLoc.


There might be other issues with the trigger, but I figure the above is manifesting itself in some way already.

If you like, here is a possible band-aid solution:
  • Spawn System
  • Events
    • Unit - A unit Dies
  • Conditions
    • (Triggering player) Equal to Neutral Hostile
  • Actions
    • Custom script: local integer old_ccp
    • Custom script: local integer old_astart
    • Custom script: local integer old_aend
    • Game - Display to (All players) the text: debug
    • For each (Integer A) from 1 to 4, do (Actions)
      • Loop - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • ((Triggering unit) is in CreepsTypeGroup[(Integer A)]) Equal to True
          • Then - Actions
            • Unit Group - Remove (Triggering unit) from CreepsTypeGroup[(Integer A)]
            • Set CreepsCVPass = (Custom value of (Triggering unit))
            • Set CreepsFacingUnit[CreepsCVPass] = (Facing of (Triggering unit))
            • Set CreepsRespawnInterval[CreepsCVPass] = (6.00 x (Real((Integer A))))
            • Set CreepsStartValue[CreepsCVPass] = CreepsStartValue[(Integer A)]
            • Set CreepsEndValue[CreepsCVPass] = CreepsEndValue[(Integer A)]
            • Custom script: set old_ccp = udg_CreepsCVPass
            • Custom script: set old_astart = bj_forLoopAIndex
            • Custom script: set old_aend = bj_forLoopAIndexEnd
            • Wait CreepsRespawnInterval[CreepsCVPass] seconds
            • Custom script: set udg_CreepsCVPass = old_ccp
            • Custom script: set bj_forLoopAIndex = old_astart
            • Custom script: set bj_forLoopAIndexEnd = old_aend
            • Unit - Create 1 CreepsType[(Random integer number between CreepsStartValue[CreepsCVPass] and CreepsEndValue[CreepsCVPass])] for Neutral Hostile at CreepsPointLoc[CreepsCVPass] facing CreepsFacingUnit[CreepsCVPass] degrees
            • Unit Group - Add (Last created unit) to CreepsTypeGroup[(Integer A)]
            • -------- still have to set the custom value and point here --------
            • Special Effect - Create a special effect attached to the origin of (Last created unit) using Abilities\Spells\Human\MassTeleport\MassTeleportCaster.mdl
            • Special Effect - Destroy (Last created special effect)
          • Else - Actions
 
Last edited:
Status
Not open for further replies.
Top