• Check out the results of the Techtree Contest #19!
  • Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

[GUI] CreepBlockSystem - Creep Respawning

This bundle is marked as pending. It has not been reviewed by a staff member yet.
  • Like
Reactions: Izzetin
Creep Block System:
Creep Respawning
by Master Zul'khan

(Made by World Editor 1.27b; works on below, but unsure if it works on new patchs!)

description:
This is a Creep Respawn system enhanced with Unit Indexer, using unit-groups named Creep Blocks to properly maintain spawning and roaming of creeps inside Respawn Regions.
FEATURES:
- Regions can collide together, without creeps confusing their respawn regions.
- Roaming creeps return to their own regions, no matter if carried over borders.
- Random creep spawn with different unit-types for each Creep Block.
- Generates creeps itself if you just create respawn regions with respawn triggers, and leave the creep setup free.
AVAILABLE OPTIONS:
- Unique Player Color: Spawns creeps with specific team color according to unit (food cost) in object editor.
- Respawn Faction: You can set the player owner of creeps in a unit-group for each region. e.g. Neutral Hostile or Neutral Passive.
- Difficulty Settings: Set spawn units for different difficulties. Making higher creeps as the game progresses.
ADDITIONAL BONUS!
- Drop Tables:
- Customizable item drop table for each Unit-type.
- Includes item qualities.
- Includes item drop chance.
NOTES:
- This is easy to implement.
- This system is leakless and bug-free.
- This system does NOT use hashtables or jass.
- This system is fully MUI can be used for all Player owned units. (Add Event: A unit owned by (Player) Dies for trigger.)
== TRIGGERS: ==
  • Creeps Setup
    • Events
      • Game - UnitIndexEvent becomes Equal to 3.00
    • Conditions
    • Actions
      • -------- // Creep Blocks // --------
      • -------- Block Family = 1 = --------
      • Set CreepBlock[1] = (Units in RespawnRegion 01 Makrura <gen>)
      • -------- = Respawn Duration = 1 = --------
      • Set Respawn_Duration[1] = 15.00
      • Unit Group - Pick every unit in CreepBlock[1] and do (Set CreepBlockID[(Custom value of (Picked unit))] = 1)
      • -------- Block Family = 2 = --------
      • Set CreepBlock[2] = (Units in RespawnRegion 02 Makrura <gen>)
      • -------- = Respawn Duration = 2 = --------
      • Set Respawn_Duration[2] = 15.00
      • Unit Group - Pick every unit in CreepBlock[2] and do (Set CreepBlockID[(Custom value of (Picked unit))] = 2)
      • -------- Block Family = 3 = --------
      • Set CreepBlock[3] = (Units in RespawnRegion 03 Makrura <gen>)
      • -------- = Respawn Duration = 3 = --------
      • Set Respawn_Duration[3] = 15.00
      • Unit Group - Pick every unit in CreepBlock[3] and do (Set CreepBlockID[(Custom value of (Picked unit))] = 3)
      • -------- // Repawn Timers // --------
      • Countdown Timer - Start Respawn_Timer[1] as a Repeating timer that will expire in 15.00 seconds
      • Wait 2.00 game-time seconds
      • Countdown Timer - Start Respawn_Timer[2] as a Repeating timer that will expire in 15.00 seconds
      • Wait 2.00 game-time seconds
      • Countdown Timer - Start Respawn_Timer[3] as a Repeating timer that will expire in 15.00 seconds
      • Wait 2.00 game-time seconds
      • Countdown Timer - Start Respawn_Timer[4] as a Repeating timer that will expire in 15.00 seconds
      • Wait 2.00 game-time seconds
      • Countdown Timer - Start Respawn_Timer[5] as a Repeating timer that will expire in 15.00 seconds
      • Wait 2.00 game-time seconds
      • Countdown Timer - Start Respawn_Timer[6] as a Repeating timer that will expire in 15.00 seconds
      • Wait 2.00 game-time seconds
      • Countdown Timer - Start Respawn_Timer[7] as a Repeating timer that will expire in 15.00 seconds
      • Wait 2.00 game-time seconds
      • Countdown Timer - Start Respawn_Timer[8] as a Repeating timer that will expire in 15.00 seconds
      • -------- Out! --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DebugEnabled Equal to True
        • Then - Actions
          • -------- Debug Message: Respawn timers are initialized. --------
          • Game - Display to (All players) for 3.00 seconds the text: ==== |cff32cd32res...
          • Trigger - Turn on Select <gen>
        • Else - Actions
      • Custom script: call DestroyTrigger(GetTriggeringTrigger())
== Spawn & Roam ==
  • Creep Respawn
    • Events
    • Conditions
    • Actions
      • -------- Check If Player Isn't Nearby --------
      • Set TempPoint[0] = (Random point in Respawn_Block)
      • Set TempPoint[1] = (Position of Hero)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Distance between TempPoint[0] and TempPoint[1]) Greater than 800.00
        • Then - Actions
          • -------- ==== --------
          • -------- Respawn Part. --------
          • -------- ==== --------
          • -------- Spawn Unit --------
          • Unit - Create 1 Respawn_Type[(Random integer number between 1 and 3)] for Respawn_Faction at TempPoint[0] facing (Random angle) degrees
          • Set CreepTriggering = (Last created unit)
          • -------- Set Creep Block ID of Unit --------
          • Set CreepBlockID[(Custom value of CreepTriggering)] = Respawn_Index
          • -------- Add Unit to Creep Block --------
          • Unit Group - Add CreepTriggering to CreepBlock[Respawn_Index]
          • -------- Set Team Color & Disable Supply Usage (Optional) --------
          • Unit - Change color of CreepTriggering to (Color of (Player((Supply used by CreepTriggering))))
          • Unit - Disable supply usage for CreepTriggering
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • DebugEnabled Equal to True
            • Then - Actions
              • -------- Debug Message: Respawn unit Index --------
              • Game - Display to (All players) for 10.00 seconds the text: ==== New Unit Respa...
              • Game - Display to (All players) for 10.00 seconds the text: (|cff32cd32a new unit is spawned: |r + ((Name of CreepTriggering) + (|cff32cd32 in Creep Block |r + ((String(CreepBlockID[(Custom value of CreepTriggering)])) + (|cff32cd32 with unit index: |r + (String((Custom value of CreepTriggering))))))))
              • Special Effect - Create a special effect attached to the origin of CreepTriggering using Abilities\Spells\Undead\AnimateDead\AnimateDeadTarget.mdl
              • Trigger - Run Display <gen> (ignoring conditions)
            • Else - Actions
        • Else - Actions
      • Custom script: call RemoveLocation(udg_TempPoint[0])
      • Custom script: call RemoveLocation(udg_TempPoint[1])
  • Creep Despawn
    • Events
    • Conditions
      • (Random real number between 0.00 and 100.00) Less than 8.00
    • Actions
      • Set CreepTriggering = (Random unit from CreepBlock[Respawn_Index])
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of CreepTriggering) Not equal to Frog
        • Then - Actions
          • -------- ==== --------
          • -------- Despawning --------
          • -------- ==== --------
          • -------- Check If Player Isn't Nearby --------
          • Set TempPoint[0] = (Position of CreepTriggering)
          • Set TempPoint[1] = (Position of Hero)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance between TempPoint[0] and TempPoint[1]) Greater than 2000.00
            • Then - Actions
              • -------- Remove Unit from Creep Block --------
              • Unit Group - Remove CreepTriggering from CreepBlock[Respawn_Index]
              • -------- Creep Block ID: Clear Index --------
              • Set CreepBlockID[(Custom value of CreepTriggering)] = 0
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • DebugEnabled Equal to True
                • Then - Actions
                  • -------- Debug Message: Despawn unit Index --------
                  • Game - Display to (All players) for 10.00 seconds the text: ==== Random Unit De...
                  • Game - Display to (All players) for 10.00 seconds the text: (|cff32cd32a unit is despawned: |r + ((Name of CreepTriggering) + (|cff32cd32 from Creep Block |r + ((String(Respawn_Index)) + (|cff32cd32 with unit index: |r + (String((Custom value of CreepTriggering))))))))
                • Else - Actions
              • -------- Despawn Unit --------
              • Unit - Remove CreepTriggering from the game
            • Else - Actions
          • Custom script: call RemoveLocation(udg_TempPoint[0])
          • Custom script: call RemoveLocation(udg_TempPoint[1])
        • Else - Actions
  • Creep Roam
    • Events
    • Conditions
    • Actions
      • Unit Group - Pick every unit in CreepBlock[Respawn_Index] and do (Actions)
        • Loop - Actions
          • -------- - Options: --------
          • -------- You can use the Disabled condition below if you're using a general Roam Chance for all units. --------
          • -------- Low Roam Rate: 20.0 --------
          • -------- Moderate Roam Rate: 30.0 --------
          • -------- Very High Roam Rate: 50.0 --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Random real number between 0.00 and 100.00) Less than Respawn_RoamChance
              • (Random real number between 0.00 and 100.00) Less than 20.00
            • Then - Actions
              • Set TempPoint[0] = (Random point in Respawn_Block)
              • Unit - Order (Picked unit) to Attack-Move To TempPoint[0]
              • Custom script: call RemoveLocation(udg_TempPoint[0])
            • Else - Actions
  • Creep Dies
    • Events
      • Unit - A unit owned by Neutral Hostile Dies
      • Unit - A unit owned by Neutral Passive Dies
    • Conditions
      • CreepBlockID[(Custom value of (Triggering unit))] Not equal to 0
    • Actions
      • -------- Setting the needed variables --------
      • Set CreepTriggering = (Triggering unit)
      • Set CreepType = (Unit-type of CreepTriggering)
      • Set TempPoint[0] = (Center of (Playable map area))
      • -------- Get Unit UDex --------
      • Set Respawn_Index = (Custom value of CreepTriggering)
      • -------- ==== --------
      • -------- Creep Dies Part. --------
      • -------- ==== --------
      • Unit Group - Remove CreepTriggering from CreepBlock[CreepBlockID[Respawn_Index]]
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DebugEnabled Equal to True
        • Then - Actions
          • -------- Debug Message: Triggering unit --------
          • Game - Display to (All players) for 10.00 seconds the text: ==== A Unit Dies
          • Game - Display to (All players) for 10.00 seconds the text: (|cff32cd32triggering unit: |r + (Name of CreepTriggering))
          • -------- Debug Message: Triggering unit index --------
          • Game - Display to (All players) for 10.00 seconds the text: (|cff32cd32triggering unit index: |r + (String(Respawn_Index)))
          • -------- Debug Message: Triggering unit is removed from creep block --------
          • If ((CreepTriggering is in CreepBlock[CreepBlockID[Respawn_Index]]) Equal to False) then do (Game - Display to (All players) for 10.00 seconds the text: (|cff32cd32Triggering unit is removed from Creep Block: |r + (String(CreepBlockID[Respawn_Index])))) else do (Do nothing)
          • Trigger - Run Display <gen> (ignoring conditions)
        • Else - Actions
      • -------- Set Dying Unit to Creep Graveyard --------
      • Set CreepGraveyard[Respawn_Index] = CreepTriggering
      • -------- ==== --------
      • Set UnitIndexerEnabled = False
      • -------- ==== --------
      • -------- Dummy Unit Part. --------
      • -------- ==== --------
      • -------- Create Dummy Unit for Dead Creep --------
      • Unit - Create 1 Frog for Neutral Extra at TempPoint[0] facing Default building facing degrees
      • Custom script: call RemoveLocation(udg_TempPoint[0])
      • Set UDexUnits[Respawn_Index] = (Last created unit)
      • -------- ==== --------
      • Set UnitIndexerEnabled = True
      • -------- Add Dummy to Creep Block --------
      • Unit Group - Add (Last created unit) to CreepBlock[CreepBlockID[Respawn_Index]]
      • Unit - Set the custom value of (Last created unit) to Respawn_Index
      • Unit - Hide (Last created unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DebugEnabled Equal to True
        • Then - Actions
          • -------- Debug Message: Dummy unit created --------
          • Game - Display to (All players) for 10.00 seconds the text: ==== Dummy Unit Cre...
          • Game - Display to (All players) for 10.00 seconds the text: (|cff32cd32a dummy unit created for: |r + ((Name of CreepTriggering) + (|cff32cd32 in Creep Block: |r + (String(CreepBlockID[Respawn_Index])))))
          • -------- Debug Message: Dummy unit index --------
          • If (((Last created unit) is in CreepBlock[CreepBlockID[Respawn_Index]]) Equal to True) then do (Game - Display to (All players) for 10.00 seconds the text: (|cff32cd32dummy unit index: |r + (String((Custom value of (Last created unit)))))) else do (Do nothing)
        • Else - Actions
      • -------- Add a Timer to Dummy Unit --------
      • -------- - Options: --------
      • -------- You can use the Disabled line below if you're using a generic Respawn Duration for all units. --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Respawn_Duration[CreepBlockID[Respawn_Index]] Greater than 0.00
        • Then - Actions
          • -------- Group Respawn Timer --------
          • Unit - Add a Respawn_Duration[CreepBlockID[Respawn_Index]] second Water Elemental expiration timer to (Last created unit)
        • Else - Actions
          • -------- Common Respawn Timer (You can change value, below:) --------
          • Unit - Add a 15.00 second Water Elemental expiration timer to (Last created unit)
      • -------- ///// --------
      • Unit - Add a 200.00 second Water Elemental expiration timer to (Last created unit)
      • -------- ///// --------
      • -------- Fire Unit Dies event for Drop Tables --------
      • Set CreepDropEvent = 1.00
      • -------- ----------------------------- --------
      • Set CreepDropEvent = 0.00
      • -------- ----------------------------- --------
  • Creep Cleanup
    • Events
      • Unit - A unit owned by Neutral Extra Dies
    • Conditions
      • CreepBlockID[(Custom value of (Triggering unit))] Not equal to 0
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DebugEnabled Equal to True
        • Then - Actions
          • -------- Debug Message: Dummy unit timer expires --------
          • Game - Display to (All players) for 10.00 seconds the text: ==== A Respawn Dela...
        • Else - Actions
      • -------- Get Unit UDex --------
      • Set Respawn_Index = (Custom value of (Triggering unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DebugEnabled Equal to True
        • Then - Actions
          • -------- Debug Message: Dummy unit index --------
          • Game - Display to (All players) for 10.00 seconds the text: (|cff32cd32removed unit index: |r + (String(Respawn_Index)))
          • Game - Display to (All players) for 10.00 seconds the text: (|cff32cd32name of the removed unit: |r + (Name of CreepGraveyard[Respawn_Index]))
          • -------- Debug Message: Cleaned Creep Block --------
          • Game - Display to (All players) for 10.00 seconds the text: (|cff32cd32removed from Creep Block: |r + (String(CreepBlockID[Respawn_Index])))
        • Else - Actions
      • -------- Remove Unit Corpse in Creep Graveyard --------
      • Unit - Remove CreepGraveyard[Respawn_Index] from the game
      • -------- Remove Dummy Unit from Creep Block --------
      • Unit Group - Remove (Triggering unit) from CreepBlock[CreepBlockID[Respawn_Index]]
      • -------- Creep Block ID: Clear Index --------
      • Set CreepBlockID[Respawn_Index] = 0
  • Creep Reses by Resurrect
    • Events
      • Unit - A unit Spawns a summoned unit
    • Conditions
      • CreepBlockID[(Custom value of (Summoned unit))] Not equal to 0
    • Actions
      • Set CreepTriggering = (Summoned unit)
      • -------- Get Unit UDex --------
      • Set Respawn_Index = (Custom value of CreepTriggering)
      • -------- Check: Is Summoned Unit 'Resurrected' or 'Animate Dead'? --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (CreepTriggering has buff Animate Dead) Equal to False
        • Then - Actions
          • -------- Is Resurrected: --------
          • -------- Add Summoned Unit to Creep Block --------
          • Unit Group - Add CreepTriggering to CreepBlock[CreepBlockID[Respawn_Index]]
          • -------- Remove Dummy Unit from Creep Block --------
          • Unit Group - Remove UDexUnits[Respawn_Index] from CreepBlock[CreepBlockID[Respawn_Index]]
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • DebugEnabled Equal to True
            • Then - Actions
              • -------- Debug Message: Summoned unit index --------
              • Game - Display to (All players) for 10.00 seconds the text: ==== Dead Unit Rese...
              • Game - Display to (All players) for 10.00 seconds the text: (|cff32cd32resed unit index: |r + (String(Respawn_Index)))
              • -------- Debug Message: Summoned unit added to Creep Block --------
              • Game - Display to (All players) for 10.00 seconds the text: (|cff32cd32added Creep Block: |r + (String(CreepBlockID[Respawn_Index])))
              • -------- Debug Message: Dummy unit is cleaned --------
              • If ((UDexUnits[Respawn_Index] is in CreepBlock[CreepBlockID[Respawn_Index]]) Equal to False) then do (Game - Display to (All players) for 10.00 seconds the text: (|cff32cd32Dummy unit is cleaned from Creep Block: |r + (String(CreepBlockID[Respawn_Index])))) else do (Do nothing)
            • Else - Actions
          • -------- Remove Dummy Unit --------
          • Unit - Remove UDexUnits[Respawn_Index] from the game
          • -------- UDexUnit: Reserve for Creep Unit --------
          • Set UDexUnits[Respawn_Index] = CreepTriggering
        • Else - Actions
          • -------- Is Animate Dead: --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • DebugEnabled Equal to True
            • Then - Actions
              • -------- Debug Message: Spawned unit is Animated --------
              • Game - Display to (All players) for 10.00 seconds the text: |cff32cd32Spawned u...
            • Else - Actions
          • -------- Notice: index of creep units animate dead will be zero. --------
          • -------- Clean Unit Index --------
          • Unit - Set the custom value of CreepTriggering to 0
      • -------- Creep Graveyard: Remove Unit from array --------
      • Set CreepGraveyard[Respawn_Index] = No unit
== Respawn Blocks ==
This is where respawn triggers are created.
  • RespawnCreep Block01
    • Events
      • Time - Respawn_Timer[1] expires
    • Conditions
    • Actions
      • Set Respawn_Index = 1
      • Set Respawn_Block = RespawnRegion 01 Makrura <gen>
      • Set Respawn_RoamChance = 20.00
      • Trigger - Run Creep Roam <gen> (checking conditions)
      • -------- Set Number of Units in Creep Block --------
      • Set Loop = (3 - (Number of units in CreepBlock[Respawn_Index]))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Loop Not equal to 0
        • Then - Actions
          • -------- Respawn Unit --------
          • Set Respawn_Faction = Neutral Hostile
          • Set Respawn_Type[1] = Makrura Pooldweller
          • Set Respawn_Type[2] = Makrura Pooldweller
          • Set Respawn_Type[3] = Makrura Tidecaller
          • For each (Integer A) from 1 to Loop, do (Trigger - Run Creep Respawn <gen> (ignoring conditions))
        • Else - Actions
      • Trigger - Run Creep Despawn <gen> (checking conditions)
  • Drop Roll
    • Events
    • Conditions
    • Actions
      • Set Roll = (Random integer number between 1 and 100)
      • -------- Check Common --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Roll Less than or equal to DropChance_Common
        • Then - Actions
          • Item - Create DropLoot_Common at DropPoint
        • Else - Actions
          • Set Roll = (Roll - DropChance_Common)
          • -------- Check Rare --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Roll Less than or equal to DropChance_Rare
            • Then - Actions
              • Item - Create DropLoot_Rare at DropPoint
            • Else - Actions
              • -------- Drop Nothing --------
      • Custom script: call RemoveLocation(udg_DropPoint)
== Drop Tables ==
This is where drop tables are created.
  • DropTable Makrura Pooldweller
    • Events
      • Game - CreepDropEvent becomes Equal to 1.00
    • Conditions
      • CreepType Equal to Makrura Pooldweller
    • Actions
      • -------- Drop Item --------
      • Set DropPoint = (Position of CreepTriggering)
      • Set DropLoot_Common = Healing Salve
      • Set DropChance_Common = 12
      • Set DropLoot_Rare = Potion of Healing
      • Set DropChance_Rare = 8
      • Trigger - Run Drop Roll <gen> (checking conditions)
Requires:
Unit Indexer (Included in map.)

• If you're using an owner changing ability, like charm.
You should eventually remove the tamed creep from: CreepBlock [CreepBlockID [Index of Unit] ] and clear value of: CreepBlockID [Index of Unit] , to prevent roaming and allow the respawning of unit.
v1.0 --> Initial release.

CONCLUSION
This is a creep respawn system built upon Rexxar's campaign respawn system, enhanced with Bribe's Unit Indexer. I use this in my under development wow campaign.
--------------------------------------------------------------------------------------------------------------------------------
:thumbs_up: ...Enjoy, mon! and, please credit me in return.
Keywords:
respawn, creeps, rpg, system, gui, orpg, respawning, creep block, roam, wander, simple, easy
Contents

Creep Block Respawning (Map)

First question - did you inspired yourself with the system inside Founding the Durotar campaign (Rexxar campaign)?
Cause from description, it looks similar. Yet I didn't tested yours, yet.
Ah, thanks for the question. - I meant to say I studied the system of Rexxar campaign. This uses a similiar method of spawning and roaming from Founding of Durotar.
 
Very useful System i really like it!
I tested it but i have a Question.
When fighting the ''Roaming'' Units in their Region they start roaming away at some point thats kinda weird.
(Sorry if i misunderstood something)
 
Last edited:
Ah, yes! I think Those pesky roaming units are meant to be unpredictable sometimes, Izzetin. But how did you manage to test them?

Did you filter out your own units from respawn region?

This kinda problem usually is because of wander ability. But we don't use that here.



This must be an intentional problem,
Which the reason is relative to one of below:
1) Which version are you testing it on?
2) They return to their origin point when outside of guard range.

I'll test it myself tonight, and then responde to your question...
 
Very useful System i really like it!
I tested it but i have a Question.
When fighting the ''Roaming'' Units in their Region they start roaming away at some point thats kinda weird.
(Sorry if i misunderstood something)

Hi, dude.
I had a little test run and found both the problem and solution. Actually, this isn't a problem of my system. But rather an intentional behavior.

You can test it with adding an special effect to roaming units.
And, you'll see that doesn't relate to roaming behavior.

The exact issue is:
  • They return to their original creation point when outside of guard distance.
They're programmed to return to their position after certain parameters.
But, those roaming units do not back up from fight. They won't run away unless outside of their Guard Distance.
But they do return to attack if hit, unlike wander units.

Here's the solution:
This issue can be prevented by setting their Guard Distance further in Constants.

anyway, Thank you! You've noticed something I overlooked...
 
Back
Top