|  |  | @ -5,21 +5,15 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 |  |  |  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
			
		
	
		
		
			
				
					
					|  |  |  | //      Magicbane Emulator Project © 2013 - 2022
 |  |  |  | //      Magicbane Emulator Project © 2013 - 2022
 | 
			
		
	
		
		
			
				
					
					|  |  |  | //                www.magicbane.com
 |  |  |  | //                www.magicbane.com
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | package engine.ai; |  |  |  | package engine.ai; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.Enum; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.Enum.DispatchChannel; |  |  |  | import engine.Enum.DispatchChannel; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.ai.utilities.CombatUtilities; |  |  |  | import engine.ai.utilities.CombatUtilities; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.ai.utilities.MovementUtilities; |  |  |  | import engine.ai.utilities.MovementUtilities; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.gameManager.*; |  |  |  | import engine.gameManager.*; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.math.Vector3fImmutable; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.net.DispatchMessage; |  |  |  | import engine.net.DispatchMessage; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.net.client.msg.PerformActionMsg; |  |  |  | import engine.net.client.msg.PerformActionMsg; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.net.client.msg.PowerProjectileMsg; |  |  |  | import engine.net.client.msg.PowerProjectileMsg; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.net.client.msg.UpdateStateMsg; |  |  |  | import engine.net.client.msg.UpdateStateMsg; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.net.client.msg.chat.ChatSystemMsg; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.objects.*; |  |  |  | import engine.objects.*; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.powers.ActionsBase; |  |  |  | import engine.powers.ActionsBase; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.powers.PowersBase; |  |  |  | import engine.powers.PowersBase; | 
			
		
	
	
		
		
			
				
					|  |  | @ -61,8 +55,8 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |         Helpee(null, false, true, true, false, true), |  |  |  |         Helpee(null, false, true, true, false, true), | 
			
		
	
		
		
			
				
					
					|  |  |  |         HelpeeWimpy(null, true, false, true, false, false), |  |  |  |         HelpeeWimpy(null, true, false, true, false, false), | 
			
		
	
		
		
			
				
					
					|  |  |  |         None(null, false, false, false, false, false), |  |  |  |         None(null, false, false, false, false, false), | 
			
		
	
		
		
			
				
					
					|  |  |  |         GuardCaptain(null,false,true,true,true,false), |  |  |  |         GuardCaptain(null, false, true, true, true, false), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         GuardMinion(GuardCaptain,false,true,true,false,true); |  |  |  |         GuardMinion(GuardCaptain, false, true, true, false, true); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         private static HashMap<Integer, MobBehaviourType> _behaviourTypes = new HashMap<>(); |  |  |  |         private static HashMap<Integer, MobBehaviourType> _behaviourTypes = new HashMap<>(); | 
			
		
	
		
		
			
				
					
					|  |  |  |         public MobBehaviourType BehaviourHelperType; |  |  |  |         public MobBehaviourType BehaviourHelperType; | 
			
		
	
	
		
		
			
				
					|  |  | @ -374,8 +368,8 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (!MovementUtilities.updateMovementToCharacter(aiAgent, mob)) |  |  |  |         if (!MovementUtilities.updateMovementToCharacter(aiAgent, mob)) | 
			
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     private static void patrol(Mob mob){ |  |  |  |     private static void patrol(Mob mob) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         if(mob.isMoving() == true){ |  |  |  |         if (mob.isMoving() == true) { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             //early exit for a mob who is already moving to a patrol point
 |  |  |  |             //early exit for a mob who is already moving to a patrol point
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //while mob moving, update lastPatrolTime so that when they stop moving the 10 second timer can begin
 |  |  |  |             //while mob moving, update lastPatrolTime so that when they stop moving the 10 second timer can begin
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             mob.stopPatrolTime = System.currentTimeMillis(); |  |  |  |             mob.stopPatrolTime = System.currentTimeMillis(); | 
			
		
	
	
		
		
			
				
					|  |  | @ -383,7 +377,7 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         //wait between 10 and 15 seconds after reaching patrol point before moving
 |  |  |  |         //wait between 10 and 15 seconds after reaching patrol point before moving
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         int patrolDelay = ThreadLocalRandom.current().nextInt(10000) + 5000; |  |  |  |         int patrolDelay = ThreadLocalRandom.current().nextInt(10000) + 5000; | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(mob.stopPatrolTime + patrolDelay > System.currentTimeMillis()){ |  |  |  |         if (mob.stopPatrolTime + patrolDelay > System.currentTimeMillis()) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             //early exit while waiting to patrol again
 |  |  |  |             //early exit while waiting to patrol again
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
	
		
		
			
				
					|  |  | @ -397,7 +391,7 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |         //guard captains inherit barracks patrol points dynamically
 |  |  |  |         //guard captains inherit barracks patrol points dynamically
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (mob.contract != null && NPC.ISGuardCaptain(mob.contract.getContractID())) { |  |  |  |         if (mob.contract != null && NPC.ISGuardCaptain(mob.contract.getContractID())) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             Building barracks = mob.building; |  |  |  |             Building barracks = mob.building; | 
			
		
	
		
		
			
				
					
					|  |  |  |             if(barracks != null && barracks.patrolPoints != null && barracks.getPatrolPoints().isEmpty() == false) { |  |  |  |             if (barracks != null && barracks.patrolPoints != null && barracks.getPatrolPoints().isEmpty() == false) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 mob.patrolPoints = barracks.patrolPoints; |  |  |  |                 mob.patrolPoints = barracks.patrolPoints; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
	
		
		
			
				
					|  |  | @ -519,7 +513,7 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 callGotResponse = true; |  |  |  |                 callGotResponse = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(callGotResponse){ |  |  |  |         if (callGotResponse) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             //wait 60 seconds to call for help again
 |  |  |  |             //wait 60 seconds to call for help again
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             mob.nextCallForHelp = System.currentTimeMillis() + 60000; |  |  |  |             mob.nextCallForHelp = System.currentTimeMillis() + 60000; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
	
		
		
			
				
					|  |  | @ -533,7 +527,7 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |             //    return;
 |  |  |  |             //    return;
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //}
 |  |  |  |             //}
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //TEST CODE FOR BEHAVIOUR CHANGING START
 |  |  |  |             //TEST CODE FOR BEHAVIOUR CHANGING START
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if(mob.BehaviourType == null || mob.BehaviourType.ordinal() == MobBehaviourType.None.ordinal()){ |  |  |  |             if (mob.BehaviourType == null || mob.BehaviourType.ordinal() == MobBehaviourType.None.ordinal()) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 mob.BehaviourType = MobBehaviourType.Simple; |  |  |  |                 mob.BehaviourType = MobBehaviourType.Simple; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             //TEST CODE FOR BEHAVIOUR CHANGING END
 |  |  |  |             //TEST CODE FOR BEHAVIOUR CHANGING END
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -590,7 +584,7 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 continue; |  |  |  |                 continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             // No aggro for this race type
 |  |  |  |             // No aggro for this race type
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if(aiAgent.notEnemy.contains(loadedPlayer.getRace().getRaceType())) |  |  |  |             if (aiAgent.notEnemy.contains(loadedPlayer.getRace().getRaceType())) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 continue; |  |  |  |                 continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (MovementUtilities.inRangeToAggro(aiAgent, loadedPlayer)) { |  |  |  |             if (MovementUtilities.inRangeToAggro(aiAgent, loadedPlayer)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 aiAgent.setAggroTargetID(playerID); |  |  |  |                 aiAgent.setAggroTargetID(playerID); | 
			
		
	
	
		
		
			
				
					|  |  | @ -602,30 +596,25 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |     private static void CheckMobMovement(Mob mob) { |  |  |  |     private static void CheckMobMovement(Mob mob) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         mob.updateLocation(); |  |  |  |         mob.updateLocation(); | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (mob.isPet() == false && mob.isSummonedPet() == false && mob.isNecroPet() == false) { |  |  |  |         if (mob.isPet() == false && mob.isSummonedPet() == false && mob.isNecroPet() == false) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             patrol(mob); |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         } else{ |  |  |  |             if (mob.getCombatTarget() == null) { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 patrol(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 chaseTarget(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |             //pet logic
 |  |  |  |             //pet logic
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if(mob.playerAgroMap.containsKey(mob.getOwner().getObjectUUID()) == false){ |  |  |  |             if (mob.playerAgroMap.containsKey(mob.getOwner().getObjectUUID()) == false) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 //mob no longer has its owner loaded, translocate pet to owner
 |  |  |  |                 //mob no longer has its owner loaded, translocate pet to owner
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 MovementManager.translocate(mob,mob.getOwner().getLoc(),null); |  |  |  |                 MovementManager.translocate(mob, mob.getOwner().getLoc(), null); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (mob.getCombatTarget() == null || mob.combatTarget.isAlive() == false) { |  |  |  |             if (mob.getCombatTarget() == null || mob.combatTarget.isAlive() == false) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 //move back to owner
 |  |  |  |                 //move back to owner
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (CombatUtilities.inRange2D(mob, mob.getOwner(), 10) == false) { |  |  |  |                 if (CombatUtilities.inRange2D(mob, mob.getOwner(), 10) == false) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     mob.destination = mob.getOwner().getLoc(); |  |  |  |                     mob.destination = mob.getOwner().getLoc(); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     MovementUtilities.moveToLocation(mob, mob.destination, 5); |  |  |  |                     MovementUtilities.moveToLocation(mob, mob.destination, 5); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } else { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             } else { |  |  |  |                     chaseTarget(mob); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 //chase target
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 mob.updateMovementState(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (mob.getRange() > 15) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         mob.destination = mob.getCombatTarget().getLoc(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         MovementUtilities.moveToLocation(mob, mob.destination, 0); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } else { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         mob.destination = MovementUtilities.GetDestinationToCharacter(mob, (AbstractCharacter) mob.getCombatTarget()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         MovementUtilities.moveToLocation(mob, mob.destination, mob.getRange()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
	
		
		
			
				
					|  |  | @ -637,7 +626,7 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_WITH_LOOT) { |  |  |  |             if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_WITH_LOOT) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 aiAgent.despawn(); |  |  |  |                 aiAgent.despawn(); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 //update time of death after mob despawns so respawn time happens after mob despawns.
 |  |  |  |                 //update time of death after mob despawns so respawn time happens after mob despawns.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if(aiAgent.deathTime != 0) { |  |  |  |                 if (aiAgent.deathTime != 0) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                     aiAgent.setDeathTime(System.currentTimeMillis()); |  |  |  |                     aiAgent.setDeathTime(System.currentTimeMillis()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                 respawn(aiAgent); |  |  |  |                 respawn(aiAgent); | 
			
		
	
	
		
		
			
				
					|  |  | @ -650,7 +639,7 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) { |  |  |  |                 if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     aiAgent.despawn(); |  |  |  |                     aiAgent.despawn(); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     //update time of death after mob despawns so respawn time happens after mob despawns.
 |  |  |  |                     //update time of death after mob despawns so respawn time happens after mob despawns.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if(aiAgent.deathTime != 0) { |  |  |  |                     if (aiAgent.deathTime != 0) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                         aiAgent.setDeathTime(System.currentTimeMillis()); |  |  |  |                         aiAgent.setDeathTime(System.currentTimeMillis()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                     respawn(aiAgent); |  |  |  |                     respawn(aiAgent); | 
			
		
	
	
		
		
			
				
					|  |  | @ -660,7 +649,7 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER) { |  |  |  |                 if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     aiAgent.despawn(); |  |  |  |                     aiAgent.despawn(); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     //update time of death after mob despawns so respawn time happens after mob despawns.
 |  |  |  |                     //update time of death after mob despawns so respawn time happens after mob despawns.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if(aiAgent.deathTime != 0) { |  |  |  |                     if (aiAgent.deathTime != 0) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                         aiAgent.setDeathTime(System.currentTimeMillis()); |  |  |  |                         aiAgent.setDeathTime(System.currentTimeMillis()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                     respawn(aiAgent); |  |  |  |                     respawn(aiAgent); | 
			
		
	
	
		
		
			
				
					|  |  | @ -735,4 +724,16 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |             aiAgent.setCombatTarget(null); |  |  |  |             aiAgent.setCombatTarget(null); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     private static void chaseTarget(Mob mob) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         mob.updateMovementState(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (mob.getRange() > 15) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 mob.destination = mob.getCombatTarget().getLoc(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 MovementUtilities.moveToLocation(mob, mob.destination, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 mob.destination = MovementUtilities.GetDestinationToCharacter(mob, (AbstractCharacter) mob.getCombatTarget()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 MovementUtilities.moveToLocation(mob, mob.destination, mob.getRange()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } |