|  |  |  | @ -18,17 +18,16 @@ import engine.mobileAI.Threads.MobAIThread;@@ -18,17 +18,16 @@ import engine.mobileAI.Threads.MobAIThread; | 
			
		
	
		
			
				
					|  |  |  |  | import engine.mobileAI.utilities.CombatUtilities; | 
			
		
	
		
			
				
					|  |  |  |  | import engine.mobileAI.utilities.MovementUtilities; | 
			
		
	
		
			
				
					|  |  |  |  | import engine.net.DispatchMessage; | 
			
		
	
		
			
				
					|  |  |  |  | import engine.net.client.msg.PerformActionMsg; | 
			
		
	
		
			
				
					|  |  |  |  | import engine.net.client.msg.PowerProjectileMsg; | 
			
		
	
		
			
				
					|  |  |  |  | import engine.net.client.msg.UpdateStateMsg; | 
			
		
	
		
			
				
					|  |  |  |  | import engine.objects.*; | 
			
		
	
		
			
				
					|  |  |  |  | import engine.powers.ActionsBase; | 
			
		
	
		
			
				
					|  |  |  |  | import engine.powers.PowersBase; | 
			
		
	
		
			
				
					|  |  |  |  | import engine.server.MBServerStatics; | 
			
		
	
		
			
				
					|  |  |  |  | import org.pmw.tinylog.Logger; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.ArrayList; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.HashSet; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.Map.Entry; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.Objects; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.concurrent.ConcurrentHashMap; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.concurrent.ThreadLocalRandom; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -54,18 +53,6 @@ public class MobAI {@@ -54,18 +53,6 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |                     return; | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (mob.isPlayerGuard() == false && MobCast(mob)) { | 
			
		
	
		
			
				
					|  |  |  |  |                     mob.updateLocation(); | 
			
		
	
		
			
				
					|  |  |  |  |                     return; | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (mob.isPlayerGuard() == true && GuardCast(mob)) { | 
			
		
	
		
			
				
					|  |  |  |  |                     mob.updateLocation(); | 
			
		
	
		
			
				
					|  |  |  |  |                     return; | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (!CombatUtilities.inRangeToAttack(mob, target)) | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
	
		
			
				
					|  |  |  | @ -85,8 +72,6 @@ public class MobAI {@@ -85,8 +72,6 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |                     break; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             mob.updateLocation(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         } catch (Exception e) { | 
			
		
	
		
			
				
					|  |  |  |  |             Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage()); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
	
		
			
				
					|  |  |  | @ -148,7 +133,7 @@ public class MobAI {@@ -148,7 +133,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (target.getPet() != null) | 
			
		
	
		
			
				
					|  |  |  |  |                 if (target.getPet().getCombatTarget() == null && target.getPet().assist == true) | 
			
		
	
		
			
				
					|  |  |  |  |                 if (target.getPet().getCombatTarget() == null && target.getPet().assist) | 
			
		
	
		
			
				
					|  |  |  |  |                     target.getPet().setCombatTarget(mob); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         } catch (Exception e) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -251,7 +236,7 @@ public class MobAI {@@ -251,7 +236,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |             if(target.isAlive()) | 
			
		
	
		
			
				
					|  |  |  |  |                 target.setCombatTarget(mob); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if(target.isPet() && target.isAlive() == false && target.guardCaptain.isAlive() == true){ | 
			
		
	
		
			
				
					|  |  |  |  |             if(target.isPet() && !target.isAlive() && target.guardCaptain.isAlive()){ | 
			
		
	
		
			
				
					|  |  |  |  |                 mob.setCombatTarget(target.guardCaptain); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             if(mob.isPet()){ | 
			
		
	
	
		
			
				
					|  |  |  | @ -272,7 +257,7 @@ public class MobAI {@@ -272,7 +257,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             //early exit while waiting to patrol again
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.stopPatrolTime + (patrolDelay * 1000) > System.currentTimeMillis()) | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.stopPatrolTime + (patrolDelay * 1000L) > System.currentTimeMillis()) | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             //guard captains inherit barracks patrol points dynamically
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -302,7 +287,7 @@ public class MobAI {@@ -302,7 +287,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     //make sure mob is out of combat stance
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (minion.getKey().despawned == false) { | 
			
		
	
		
			
				
					|  |  |  |  |                     if (!minion.getKey().despawned) { | 
			
		
	
		
			
				
					|  |  |  |  |                         if (MovementUtilities.canMove(minion.getKey())) { | 
			
		
	
		
			
				
					|  |  |  |  |                             Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3); | 
			
		
	
		
			
				
					|  |  |  |  |                             minion.getKey().updateLocation(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -315,253 +300,6 @@ public class MobAI {@@ -315,253 +300,6 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public static boolean canCast(Mob mob) { | 
			
		
	
		
			
				
					|  |  |  |  |         return false; | 
			
		
	
		
			
				
					|  |  |  |  |         //try {
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             // Performs validation to determine if a
 | 
			
		
	
		
			
				
					|  |  |  |  |             // mobile in the proper state to cast.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             //if (mob == null)
 | 
			
		
	
		
			
				
					|  |  |  |  |             //    return false;
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             //if(mob.isPlayerGuard == true){
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             ///    int contractID;
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             //    if (mob.behaviourType.equals(Enum.MobBehaviourType.GuardMinion))
 | 
			
		
	
		
			
				
					|  |  |  |  |             //        contractID = mob.guardCaptain.contract.getContractID();
 | 
			
		
	
		
			
				
					|  |  |  |  |             //    else
 | 
			
		
	
		
			
				
					|  |  |  |  |             //        contractID = mob.contract.getContractID();
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             //    if(Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false)
 | 
			
		
	
		
			
				
					|  |  |  |  |              //       return false;
 | 
			
		
	
		
			
				
					|  |  |  |  |             //}
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             //if (mob.mobPowers.isEmpty())
 | 
			
		
	
		
			
				
					|  |  |  |  |             //    return false;
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |            //if (!mob.canSee((PlayerCharacter) mob.getCombatTarget())) {
 | 
			
		
	
		
			
				
					|  |  |  |  |             //    mob.setCombatTarget(null);
 | 
			
		
	
		
			
				
					|  |  |  |  |             //    return false;
 | 
			
		
	
		
			
				
					|  |  |  |  |            // }
 | 
			
		
	
		
			
				
					|  |  |  |  |            // if (mob.nextCastTime == 0)
 | 
			
		
	
		
			
				
					|  |  |  |  |             //    mob.nextCastTime = System.currentTimeMillis();
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |            // return mob.nextCastTime >= System.currentTimeMillis();
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         //} catch (Exception e) {
 | 
			
		
	
		
			
				
					|  |  |  |  |        //     Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: canCast" + " " + e.getMessage());
 | 
			
		
	
		
			
				
					|  |  |  |  |         //}
 | 
			
		
	
		
			
				
					|  |  |  |  |         //return false;
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public static boolean MobCast(Mob mob) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         try { | 
			
		
	
		
			
				
					|  |  |  |  |             // Method picks a random spell from a mobile's list of powers
 | 
			
		
	
		
			
				
					|  |  |  |  |             // and casts it on the current target (or itself).  Validation
 | 
			
		
	
		
			
				
					|  |  |  |  |             // (including empty lists) is done previously within canCast();
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             ArrayList<Integer> powerTokens; | 
			
		
	
		
			
				
					|  |  |  |  |             ArrayList<Integer> purgeTokens; | 
			
		
	
		
			
				
					|  |  |  |  |             AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.behaviourType.callsForHelp) | 
			
		
	
		
			
				
					|  |  |  |  |                 MobCallForHelp(mob); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             // Generate a list of tokens from the mob powers for this mobile.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             powerTokens = new ArrayList<>(mob.mobPowers.keySet()); | 
			
		
	
		
			
				
					|  |  |  |  |             purgeTokens = new ArrayList<>(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             // If player has this effect on them currently then remove
 | 
			
		
	
		
			
				
					|  |  |  |  |             // this token from our list.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             for (int powerToken : powerTokens) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 PowersBase powerBase = PowersManager.getPowerByToken(powerToken); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 for (ActionsBase actionBase : powerBase.getActions()) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     String stackType = actionBase.stackType; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (target.getEffects() != null && target.getEffects().containsKey(stackType)) | 
			
		
	
		
			
				
					|  |  |  |  |                         purgeTokens.add(powerToken); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             powerTokens.removeAll(purgeTokens); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             // Sanity check
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (powerTokens.isEmpty()) | 
			
		
	
		
			
				
					|  |  |  |  |                 return false; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             // Pick random spell from our list of powers
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             int powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); | 
			
		
	
		
			
				
					|  |  |  |  |             int powerRank = mob.mobPowers.get(powerToken); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             PowersBase mobPower = PowersManager.getPowerByToken(powerToken); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             //check for hit-roll
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mobPower.requiresHitRoll) | 
			
		
	
		
			
				
					|  |  |  |  |                 if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget())) | 
			
		
	
		
			
				
					|  |  |  |  |                     return false; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             // Cast the spell
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 PerformActionMsg msg; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (!mobPower.isHarmful() || mobPower.targetSelf) { | 
			
		
	
		
			
				
					|  |  |  |  |                     PowersManager.useMobPower(mob, mob, mobPower, powerRank); | 
			
		
	
		
			
				
					|  |  |  |  |                     msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob); | 
			
		
	
		
			
				
					|  |  |  |  |                 } else { | 
			
		
	
		
			
				
					|  |  |  |  |                     PowersManager.useMobPower(mob, target, mobPower, powerRank); | 
			
		
	
		
			
				
					|  |  |  |  |                     msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 msg.setUnknown04(2); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 PowersManager.finishUseMobPower(msg, mob, 0, 0); | 
			
		
	
		
			
				
					|  |  |  |  |                 long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 mob.nextCastTime = System.currentTimeMillis() + randomCooldown; | 
			
		
	
		
			
				
					|  |  |  |  |                 return true; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } catch (Exception e) { | 
			
		
	
		
			
				
					|  |  |  |  |             Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage()); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         return false; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public static boolean GuardCast(Mob mob) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         try { | 
			
		
	
		
			
				
					|  |  |  |  |             // Method picks a random spell from a mobile's list of powers
 | 
			
		
	
		
			
				
					|  |  |  |  |             // and casts it on the current target (or itself).  Validation
 | 
			
		
	
		
			
				
					|  |  |  |  |             // (including empty lists) is done previously within canCast();
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             ArrayList<Integer> powerTokens; | 
			
		
	
		
			
				
					|  |  |  |  |             ArrayList<Integer> purgeTokens; | 
			
		
	
		
			
				
					|  |  |  |  |             AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.behaviourType.callsForHelp) | 
			
		
	
		
			
				
					|  |  |  |  |                 MobCallForHelp(mob); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             // Generate a list of tokens from the mob powers for this mobile.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             powerTokens = new ArrayList<>(mob.mobPowers.keySet()); | 
			
		
	
		
			
				
					|  |  |  |  |             purgeTokens = new ArrayList<>(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             // If player has this effect on them currently then remove
 | 
			
		
	
		
			
				
					|  |  |  |  |             // this token from our list.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             for (int powerToken : powerTokens) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 PowersBase powerBase = PowersManager.getPowerByToken(powerToken); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 for (ActionsBase actionBase : powerBase.getActions()) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     String stackType = actionBase.stackType; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (target.getEffects() != null && target.getEffects().containsKey(stackType)) | 
			
		
	
		
			
				
					|  |  |  |  |                         purgeTokens.add(powerToken); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             powerTokens.removeAll(purgeTokens); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             // Sanity check
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (powerTokens.isEmpty()) | 
			
		
	
		
			
				
					|  |  |  |  |                 return false; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             int powerToken = 0; | 
			
		
	
		
			
				
					|  |  |  |  |             int nukeRoll = ThreadLocalRandom.current().nextInt(1,100); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (nukeRoll < 55) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 //use direct damage spell
 | 
			
		
	
		
			
				
					|  |  |  |  |                 powerToken = powerTokens.get(powerTokens.size() - 1); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             } else { | 
			
		
	
		
			
				
					|  |  |  |  |                 //use random spell
 | 
			
		
	
		
			
				
					|  |  |  |  |                 powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             int powerRank = 1; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             switch(mob.getRank()){ | 
			
		
	
		
			
				
					|  |  |  |  |                 case 1: | 
			
		
	
		
			
				
					|  |  |  |  |                     powerRank = 10; | 
			
		
	
		
			
				
					|  |  |  |  |                     break; | 
			
		
	
		
			
				
					|  |  |  |  |                 case 2: | 
			
		
	
		
			
				
					|  |  |  |  |                     powerRank = 15; | 
			
		
	
		
			
				
					|  |  |  |  |                     break; | 
			
		
	
		
			
				
					|  |  |  |  |                 case 3: | 
			
		
	
		
			
				
					|  |  |  |  |                     powerRank = 20; | 
			
		
	
		
			
				
					|  |  |  |  |                     break; | 
			
		
	
		
			
				
					|  |  |  |  |                 case 4: | 
			
		
	
		
			
				
					|  |  |  |  |                     powerRank = 25; | 
			
		
	
		
			
				
					|  |  |  |  |                     break; | 
			
		
	
		
			
				
					|  |  |  |  |                 case 5: | 
			
		
	
		
			
				
					|  |  |  |  |                     powerRank = 30; | 
			
		
	
		
			
				
					|  |  |  |  |                     break; | 
			
		
	
		
			
				
					|  |  |  |  |                 case 6: | 
			
		
	
		
			
				
					|  |  |  |  |                     powerRank = 35; | 
			
		
	
		
			
				
					|  |  |  |  |                     break; | 
			
		
	
		
			
				
					|  |  |  |  |                 case 7: | 
			
		
	
		
			
				
					|  |  |  |  |                     powerRank = 40; | 
			
		
	
		
			
				
					|  |  |  |  |                     break; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             PowersBase mobPower = PowersManager.getPowerByToken(powerToken); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             //check for hit-roll
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mobPower.requiresHitRoll) | 
			
		
	
		
			
				
					|  |  |  |  |                 if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget())) | 
			
		
	
		
			
				
					|  |  |  |  |                     return false; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             // Cast the spell
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 PerformActionMsg msg; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (!mobPower.isHarmful() || mobPower.targetSelf) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (mobPower.category.equals("DISPEL")) { | 
			
		
	
		
			
				
					|  |  |  |  |                         PowersManager.useMobPower(mob, target, mobPower, powerRank); | 
			
		
	
		
			
				
					|  |  |  |  |                         msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); | 
			
		
	
		
			
				
					|  |  |  |  |                     } else { | 
			
		
	
		
			
				
					|  |  |  |  |                         PowersManager.useMobPower(mob, mob, mobPower, powerRank); | 
			
		
	
		
			
				
					|  |  |  |  |                         msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob); | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  |                 } else { | 
			
		
	
		
			
				
					|  |  |  |  |                     PowersManager.useMobPower(mob, target, mobPower, powerRank); | 
			
		
	
		
			
				
					|  |  |  |  |                     msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 msg.setUnknown04(2); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 PowersManager.finishUseMobPower(msg, mob, 0, 0); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY); | 
			
		
	
		
			
				
					|  |  |  |  |                 mob.nextCastTime = System.currentTimeMillis() + randomCooldown; | 
			
		
	
		
			
				
					|  |  |  |  |                 return true; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } catch (Exception e) { | 
			
		
	
		
			
				
					|  |  |  |  |             Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage()); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |         return false; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public static void MobCallForHelp(Mob mob) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         try { | 
			
		
	
	
		
			
				
					|  |  |  | @ -606,7 +344,7 @@ public class MobAI {@@ -606,7 +344,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob == null) | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.getTimestamps().containsKey("lastExecution") == false) | 
			
		
	
		
			
				
					|  |  |  |  |             if (!mob.getTimestamps().containsKey("lastExecution")) | 
			
		
	
		
			
				
					|  |  |  |  |                 mob.getTimestamps().put("lastExecution", System.currentTimeMillis()); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (System.currentTimeMillis() < mob.getTimeStamp("lastExecution")) | 
			
		
	
	
		
			
				
					|  |  |  | @ -626,11 +364,11 @@ public class MobAI {@@ -626,11 +364,11 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.despawned && mob.isPlayerGuard) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (mob.behaviourType.equals(Enum.MobBehaviourType.GuardMinion)) { | 
			
		
	
		
			
				
					|  |  |  |  |                     if (mob.guardCaptain.isAlive() == false || ((Mob) mob.guardCaptain).despawned == true) { | 
			
		
	
		
			
				
					|  |  |  |  |                     if (!mob.guardCaptain.isAlive() || ((Mob) mob.guardCaptain).despawned) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                         //minions don't respawn while guard captain is dead
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                         if (mob.isAlive() == false) { | 
			
		
	
		
			
				
					|  |  |  |  |                         if (!mob.isAlive()) { | 
			
		
	
		
			
				
					|  |  |  |  |                             mob.deathTime = System.currentTimeMillis(); | 
			
		
	
		
			
				
					|  |  |  |  |                             return; | 
			
		
	
		
			
				
					|  |  |  |  |                         } | 
			
		
	
	
		
			
				
					|  |  |  | @ -642,7 +380,7 @@ public class MobAI {@@ -642,7 +380,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 //check to send mob home for player guards to prevent exploit of dragging guards away and then teleporting
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (mob.behaviourType.equals(Enum.MobBehaviourType.Pet1) == false) | 
			
		
	
		
			
				
					|  |  |  |  |                 if (!mob.behaviourType.equals(Enum.MobBehaviourType.Pet1)) | 
			
		
	
		
			
				
					|  |  |  |  |                     CheckToSendMobHome(mob); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
	
		
			
				
					|  |  |  | @ -662,7 +400,7 @@ public class MobAI {@@ -662,7 +400,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |                 HashSet<AbstractWorldObject> players = WorldGrid.getObjectsInRangePartial(mob.loc, mob.getAggroRange(), MBServerStatics.MASK_PLAYER); | 
			
		
	
		
			
				
					|  |  |  |  |                 if(players.size() > 0){ | 
			
		
	
		
			
				
					|  |  |  |  |                     for(AbstractWorldObject player : players){ | 
			
		
	
		
			
				
					|  |  |  |  |                         if(mob.playerAgroMap.containsKey(player.getObjectUUID()) == false) { | 
			
		
	
		
			
				
					|  |  |  |  |                         if(!mob.playerAgroMap.containsKey(player.getObjectUUID())) { | 
			
		
	
		
			
				
					|  |  |  |  |                             PlayerCharacter pc = (PlayerCharacter) player; | 
			
		
	
		
			
				
					|  |  |  |  |                             mob.playerAgroMap.put(pc.getObjectUUID(), 0.0f); | 
			
		
	
		
			
				
					|  |  |  |  |                         } | 
			
		
	
	
		
			
				
					|  |  |  | @ -674,12 +412,12 @@ public class MobAI {@@ -674,12 +412,12 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.behaviourType.equals(Enum.MobBehaviourType.Pet1) == false) | 
			
		
	
		
			
				
					|  |  |  |  |             if (!mob.behaviourType.equals(Enum.MobBehaviourType.Pet1)) | 
			
		
	
		
			
				
					|  |  |  |  |                 CheckToSendMobHome(mob); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.getCombatTarget() != null) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (mob.getCombatTarget().isAlive() == false) { | 
			
		
	
		
			
				
					|  |  |  |  |                 if (!mob.getCombatTarget().isAlive()) { | 
			
		
	
		
			
				
					|  |  |  |  |                     mob.setCombatTarget(null); | 
			
		
	
		
			
				
					|  |  |  |  |                     return; | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
	
		
			
				
					|  |  |  | @ -688,18 +426,35 @@ public class MobAI {@@ -688,18 +426,35 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     PlayerCharacter target = (PlayerCharacter) mob.getCombatTarget(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (mob.playerAgroMap.containsKey(target.getObjectUUID()) == false) { | 
			
		
	
		
			
				
					|  |  |  |  |                     if (!mob.playerAgroMap.containsKey(target.getObjectUUID())) { | 
			
		
	
		
			
				
					|  |  |  |  |                         mob.setCombatTarget(null); | 
			
		
	
		
			
				
					|  |  |  |  |                         return; | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (mob.canSee((PlayerCharacter) mob.getCombatTarget()) == false) { | 
			
		
	
		
			
				
					|  |  |  |  |                     if (!mob.canSee((PlayerCharacter) mob.getCombatTarget())) { | 
			
		
	
		
			
				
					|  |  |  |  |                         mob.setCombatTarget(null); | 
			
		
	
		
			
				
					|  |  |  |  |                         return; | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.isMoving()) { | 
			
		
	
		
			
				
					|  |  |  |  |                 mob.updateLocation(); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             boolean combatState = mob.isCombat(); | 
			
		
	
		
			
				
					|  |  |  |  |             mob.setCombat(mob.combatTarget != null); | 
			
		
	
		
			
				
					|  |  |  |  |             if(combatState != mob.isCombat()){ | 
			
		
	
		
			
				
					|  |  |  |  |                 //send message to update combat state
 | 
			
		
	
		
			
				
					|  |  |  |  |                 UpdateStateMsg rwss = new UpdateStateMsg(); | 
			
		
	
		
			
				
					|  |  |  |  |                 rwss.setPlayer(mob); | 
			
		
	
		
			
				
					|  |  |  |  |                 DispatchMessage.sendToAllInRange(mob, rwss); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             boolean walking = mob.isWalk(); | 
			
		
	
		
			
				
					|  |  |  |  |             mob.setWalkMode(mob.combatTarget == null); | 
			
		
	
		
			
				
					|  |  |  |  |             if(walking != mob.isWalk()){ | 
			
		
	
		
			
				
					|  |  |  |  |                 //send message to update run/walk state
 | 
			
		
	
		
			
				
					|  |  |  |  |                 MovementManager.sendRWSSMsg(mob); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             switch (mob.behaviourType) { | 
			
		
	
		
			
				
					|  |  |  |  |                 case GuardCaptain: | 
			
		
	
	
		
			
				
					|  |  |  | @ -738,22 +493,21 @@ public class MobAI {@@ -738,22 +493,21 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |             if(!pets) { | 
			
		
	
		
			
				
					|  |  |  |  |                 ConcurrentHashMap<Integer, Float> loadedPlayers = aiAgent.playerAgroMap; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 for (Entry playerEntry : loadedPlayers.entrySet()) { | 
			
		
	
		
			
				
					|  |  |  |  |                 for (Integer playerEntry : loadedPlayers.keySet()) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     int playerID = (int) playerEntry.getKey(); | 
			
		
	
		
			
				
					|  |  |  |  |                     PlayerCharacter loadedPlayer = PlayerCharacter.getFromCache(playerID); | 
			
		
	
		
			
				
					|  |  |  |  |                     PlayerCharacter loadedPlayer = PlayerCharacter.getFromCache(playerEntry); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     //Player is null, let's remove them from the list.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (loadedPlayer == null) { | 
			
		
	
		
			
				
					|  |  |  |  |                         loadedPlayers.remove(playerID); | 
			
		
	
		
			
				
					|  |  |  |  |                         loadedPlayers.remove(playerEntry); | 
			
		
	
		
			
				
					|  |  |  |  |                         continue; | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     //Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (!loadedPlayer.isAlive() || loadedPlayer.getHidden() > 0) { | 
			
		
	
		
			
				
					|  |  |  |  |                         loadedPlayers.remove(playerID); | 
			
		
	
		
			
				
					|  |  |  |  |                         loadedPlayers.remove(playerEntry); | 
			
		
	
		
			
				
					|  |  |  |  |                         continue; | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -764,12 +518,12 @@ public class MobAI {@@ -764,12 +518,12 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     // No aggro for this race type
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (aiAgent.notEnemy.size() > 0 && aiAgent.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType()) == true) | 
			
		
	
		
			
				
					|  |  |  |  |                     if (aiAgent.notEnemy.size() > 0 && aiAgent.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType())) | 
			
		
	
		
			
				
					|  |  |  |  |                         continue; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     //mob has enemies and this player race is not it
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (aiAgent.enemy.size() > 0 && aiAgent.enemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType()) == false) | 
			
		
	
		
			
				
					|  |  |  |  |                     if (aiAgent.enemy.size() > 0 && !aiAgent.enemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType())) | 
			
		
	
		
			
				
					|  |  |  |  |                         continue; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (MovementUtilities.inRangeToAggro(aiAgent, loadedPlayer)) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -806,27 +560,27 @@ public class MobAI {@@ -806,27 +560,27 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |             return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         try { | 
			
		
	
		
			
				
					|  |  |  |  |             if(mob == null) | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (!MovementUtilities.canMove(mob)) | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             mob.updateLocation(); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             switch (mob.behaviourType) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 case Pet1: | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if ((PlayerCharacter) mob.guardCaptain == null) | 
			
		
	
		
			
				
					|  |  |  |  |                     if (mob.guardCaptain == null) | 
			
		
	
		
			
				
					|  |  |  |  |                         return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (!mob.playerAgroMap.containsKey(((PlayerCharacter) mob.guardCaptain).getObjectUUID())) { | 
			
		
	
		
			
				
					|  |  |  |  |                     if (!mob.playerAgroMap.containsKey(mob.guardCaptain.getObjectUUID())) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                         //mob no longer has its owner loaded, translocate pet to owner
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                         MovementManager.translocate(mob, ((PlayerCharacter) mob.guardCaptain).getLoc(), null); | 
			
		
	
		
			
				
					|  |  |  |  |                         MovementManager.translocate(mob, mob.guardCaptain.getLoc(), null); | 
			
		
	
		
			
				
					|  |  |  |  |                         return; | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  |                     if (mob.getCombatTarget() == null) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -834,11 +588,11 @@ public class MobAI {@@ -834,11 +588,11 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |                         //move back to owner
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                         if (CombatUtilities.inRange2D(mob, (PlayerCharacter) mob.guardCaptain, 6)) | 
			
		
	
		
			
				
					|  |  |  |  |                         if (CombatUtilities.inRange2D(mob, mob.guardCaptain, 6)) | 
			
		
	
		
			
				
					|  |  |  |  |                             return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                         mob.destination = ((PlayerCharacter) mob.guardCaptain).getLoc(); | 
			
		
	
		
			
				
					|  |  |  |  |                         mob.destination = mob.guardCaptain.getLoc(); | 
			
		
	
		
			
				
					|  |  |  |  |                         MovementUtilities.moveToLocation(mob, mob.destination, 5); | 
			
		
	
		
			
				
					|  |  |  |  |                     } else | 
			
		
	
		
			
				
					|  |  |  |  |                         chaseTarget(mob); | 
			
		
	
	
		
			
				
					|  |  |  | @ -886,7 +640,6 @@ public class MobAI {@@ -886,7 +640,6 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |                     if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_WITH_LOOT) { | 
			
		
	
		
			
				
					|  |  |  |  |                         aiAgent.despawn(); | 
			
		
	
		
			
				
					|  |  |  |  |                         aiAgent.deathTime = System.currentTimeMillis(); | 
			
		
	
		
			
				
					|  |  |  |  |                         return; | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  |                     //No items in inventory.
 | 
			
		
	
		
			
				
					|  |  |  |  |                 } else { | 
			
		
	
	
		
			
				
					|  |  |  | @ -895,14 +648,12 @@ public class MobAI {@@ -895,14 +648,12 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |                         if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) { | 
			
		
	
		
			
				
					|  |  |  |  |                             aiAgent.despawn(); | 
			
		
	
		
			
				
					|  |  |  |  |                             aiAgent.deathTime = System.currentTimeMillis(); | 
			
		
	
		
			
				
					|  |  |  |  |                             return; | 
			
		
	
		
			
				
					|  |  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |  |                         //Mob never had Loot.
 | 
			
		
	
		
			
				
					|  |  |  |  |                     } else { | 
			
		
	
		
			
				
					|  |  |  |  |                         if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER) { | 
			
		
	
		
			
				
					|  |  |  |  |                             aiAgent.despawn(); | 
			
		
	
		
			
				
					|  |  |  |  |                             aiAgent.deathTime = System.currentTimeMillis(); | 
			
		
	
		
			
				
					|  |  |  |  |                             return; | 
			
		
	
		
			
				
					|  |  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
	
		
			
				
					|  |  |  | @ -922,14 +673,14 @@ public class MobAI {@@ -922,14 +673,14 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             //checks if mob can attack based on attack timer and range
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.isAlive() == false) | 
			
		
	
		
			
				
					|  |  |  |  |             if (!mob.isAlive()) | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.getCombatTarget() == null) | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false && | 
			
		
	
		
			
				
					|  |  |  |  |                     mob.behaviourType.equals(Enum.MobBehaviourType.Pet1) == false) { | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && !MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) && | 
			
		
	
		
			
				
					|  |  |  |  |                     !mob.behaviourType.equals(Enum.MobBehaviourType.Pet1)) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 mob.setCombatTarget(null); | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
	
		
			
				
					|  |  |  | @ -955,14 +706,11 @@ public class MobAI {@@ -955,14 +706,11 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             //if (mob.getCombatTarget() != null && CombatUtilities.inRange2D(mob, mob.getCombatTarget(), MobAIThread.AI_BASE_AGGRO_RANGE * 0.5f))
 | 
			
		
	
		
			
				
					|  |  |  |  |                 //return;
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.isPlayerGuard() && !mob.despawned) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 City current = ZoneManager.getCityAtLocation(mob.getLoc()); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (current == null || current.equals(mob.getGuild().getOwnedCity()) == false) { | 
			
		
	
		
			
				
					|  |  |  |  |                 if (current == null || !current.equals(mob.getGuild().getOwnedCity())) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     PowersBase recall = PowersManager.getPowerByToken(-1994153779); | 
			
		
	
		
			
				
					|  |  |  |  |                     PowersManager.useMobPower(mob, mob, recall, 40); | 
			
		
	
	
		
			
				
					|  |  |  | @ -978,14 +726,13 @@ public class MobAI {@@ -978,14 +726,13 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } else if (MovementUtilities.inRangeOfBindLocation(mob) == false) { | 
			
		
	
		
			
				
					|  |  |  |  |             } else if (!MovementUtilities.inRangeOfBindLocation(mob)) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 PowersBase recall = PowersManager.getPowerByToken(-1994153779); | 
			
		
	
		
			
				
					|  |  |  |  |                 PowersManager.useMobPower(mob, mob, recall, 40); | 
			
		
	
		
			
				
					|  |  |  |  |                 mob.setCombatTarget(null); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 for (Integer playerEntry : mob.playerAgroMap.keySet()) | 
			
		
	
		
			
				
					|  |  |  |  |                     mob.playerAgroMap.put(playerEntry,0f); | 
			
		
	
		
			
				
					|  |  |  |  |                 mob.playerAgroMap.replaceAll((e, v) -> 0f); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } catch (Exception e) { | 
			
		
	
		
			
				
					|  |  |  |  |             Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome" + " " + e.getMessage()); | 
			
		
	
	
		
			
				
					|  |  |  | @ -1004,10 +751,10 @@ public class MobAI {@@ -1004,10 +751,10 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |             float rangeSquared = mob.getRange() * mob.getRange(); | 
			
		
	
		
			
				
					|  |  |  |  |             float distanceSquared = mob.getLoc().distanceSquared2D(mob.getCombatTarget().getLoc()); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if(mob.isMoving() == true && distanceSquared < rangeSquared - 50) { | 
			
		
	
		
			
				
					|  |  |  |  |             if(mob.isMoving() && distanceSquared < rangeSquared - 50) { | 
			
		
	
		
			
				
					|  |  |  |  |                 mob.destination = mob.getLoc(); | 
			
		
	
		
			
				
					|  |  |  |  |                 MovementUtilities.moveToLocation(mob, mob.destination, 0); | 
			
		
	
		
			
				
					|  |  |  |  |             } else if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { | 
			
		
	
		
			
				
					|  |  |  |  |             } else if (!CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange())) { | 
			
		
	
		
			
				
					|  |  |  |  |                 if (mob.getRange() > 15) { | 
			
		
	
		
			
				
					|  |  |  |  |                     mob.destination = mob.getCombatTarget().getLoc(); | 
			
		
	
		
			
				
					|  |  |  |  |                     MovementUtilities.moveToLocation(mob, mob.destination, 0); | 
			
		
	
	
		
			
				
					|  |  |  | @ -1029,7 +776,6 @@ public class MobAI {@@ -1029,7 +776,6 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             mob.updateMovementState(); | 
			
		
	
		
			
				
					|  |  |  |  |             mob.updateLocation(); | 
			
		
	
		
			
				
					|  |  |  |  |         } catch (Exception e) { | 
			
		
	
		
			
				
					|  |  |  |  |             Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: chaseTarget" + " " + e.getMessage()); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
	
		
			
				
					|  |  |  | @ -1044,7 +790,7 @@ public class MobAI {@@ -1044,7 +790,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 //dont scan self.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (mob.equals(awoMob) || (mob.agentType.equals(Enum.AIAgentType.GUARD)) == true || awoMob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) | 
			
		
	
		
			
				
					|  |  |  |  |                 if (mob.equals(awoMob) || (mob.agentType.equals(Enum.AIAgentType.GUARD)) || awoMob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) | 
			
		
	
		
			
				
					|  |  |  |  |                     continue; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 Mob aggroMob = (Mob) awoMob; | 
			
		
	
	
		
			
				
					|  |  |  | @ -1073,18 +819,6 @@ public class MobAI {@@ -1073,18 +819,6 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.getCombatTarget() == null) | 
			
		
	
		
			
				
					|  |  |  |  |                 CheckForPlayerGuardAggro(mob); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (newTarget != null) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (newTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { | 
			
		
	
		
			
				
					|  |  |  |  |                     if (GuardCanAggro(mob, (PlayerCharacter) newTarget)) | 
			
		
	
		
			
				
					|  |  |  |  |                         mob.setCombatTarget(newTarget); | 
			
		
	
		
			
				
					|  |  |  |  |                 } else | 
			
		
	
		
			
				
					|  |  |  |  |                     mob.setCombatTarget(newTarget); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             CheckMobMovement(mob); | 
			
		
	
		
			
				
					|  |  |  |  |             CheckForAttack(mob); | 
			
		
	
		
			
				
					|  |  |  |  |         } catch (Exception e) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -1099,19 +833,6 @@ public class MobAI {@@ -1099,19 +833,6 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (mob.getCombatTarget() == null) { | 
			
		
	
		
			
				
					|  |  |  |  |                     CheckForPlayerGuardAggro(mob); | 
			
		
	
		
			
				
					|  |  |  |  |                 } else { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (newTarget != null) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                         if (newTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { | 
			
		
	
		
			
				
					|  |  |  |  |                             if (GuardCanAggro(mob, (PlayerCharacter) newTarget)) | 
			
		
	
		
			
				
					|  |  |  |  |                                 mob.setCombatTarget(newTarget); | 
			
		
	
		
			
				
					|  |  |  |  |                         } else | 
			
		
	
		
			
				
					|  |  |  |  |                             mob.setCombatTarget(newTarget); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             }else { | 
			
		
	
		
			
				
					|  |  |  |  |                 if (mob.guardCaptain.getCombatTarget() != null) | 
			
		
	
	
		
			
				
					|  |  |  | @ -1143,7 +864,7 @@ public class MobAI {@@ -1143,7 +864,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |         try { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.guardCaptain == null && mob.isNecroPet() == false && mob.isSiege() == false) | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.guardCaptain == null && !mob.isNecroPet() && !mob.isSiege()) | 
			
		
	
		
			
				
					|  |  |  |  |                 if (ZoneManager.getSeaFloor().zoneMobSet.contains(mob)) | 
			
		
	
		
			
				
					|  |  |  |  |                     mob.killCharacter("no owner"); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -1154,7 +875,7 @@ public class MobAI {@@ -1154,7 +875,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             //recover health
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.getTimestamps().containsKey("HEALTHRECOVERED") == false) | 
			
		
	
		
			
				
					|  |  |  |  |             if (!mob.getTimestamps().containsKey("HEALTHRECOVERED")) | 
			
		
	
		
			
				
					|  |  |  |  |                 mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis()); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.isSit() && mob.getTimeStamp("HEALTHRECOVERED") < System.currentTimeMillis() + 3000) | 
			
		
	
	
		
			
				
					|  |  |  | @ -1179,7 +900,7 @@ public class MobAI {@@ -1179,7 +900,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.getCombatTarget() == null) | 
			
		
	
		
			
				
					|  |  |  |  |                 SafeGuardAggro(mob); | 
			
		
	
		
			
				
					|  |  |  |  |             else if (mob.getCombatTarget().isAlive() == false) | 
			
		
	
		
			
				
					|  |  |  |  |             else if (!mob.getCombatTarget().isAlive()) | 
			
		
	
		
			
				
					|  |  |  |  |                 SafeGuardAggro(mob); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             CheckForAttack(mob); | 
			
		
	
	
		
			
				
					|  |  |  | @ -1194,7 +915,7 @@ public class MobAI {@@ -1194,7 +915,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if(mob.combatTarget != null && mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ | 
			
		
	
		
			
				
					|  |  |  |  |                 PlayerCharacter tar = (PlayerCharacter)mob.combatTarget; | 
			
		
	
		
			
				
					|  |  |  |  |                 if (mob.canSee(tar) == false) { | 
			
		
	
		
			
				
					|  |  |  |  |                 if (!mob.canSee(tar)) { | 
			
		
	
		
			
				
					|  |  |  |  |                     mob.setCombatTarget(null); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
	
		
			
				
					|  |  |  | @ -1245,22 +966,21 @@ public class MobAI {@@ -1245,22 +966,21 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             ConcurrentHashMap<Integer, Float> loadedPlayers = mob.playerAgroMap; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             for (Entry playerEntry : loadedPlayers.entrySet()) { | 
			
		
	
		
			
				
					|  |  |  |  |             for (Integer playerEntry : loadedPlayers.keySet()) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 int playerID = (int) playerEntry.getKey(); | 
			
		
	
		
			
				
					|  |  |  |  |                 PlayerCharacter loadedPlayer = PlayerCharacter.getFromCache(playerID); | 
			
		
	
		
			
				
					|  |  |  |  |                 PlayerCharacter loadedPlayer = PlayerCharacter.getFromCache(playerEntry); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 //Player is null, let's remove them from the list.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (loadedPlayer == null) { | 
			
		
	
		
			
				
					|  |  |  |  |                     loadedPlayers.remove(playerID); | 
			
		
	
		
			
				
					|  |  |  |  |                     loadedPlayers.remove(playerEntry); | 
			
		
	
		
			
				
					|  |  |  |  |                     continue; | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 //Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (!loadedPlayer.isAlive()) { | 
			
		
	
		
			
				
					|  |  |  |  |                     loadedPlayers.remove(playerID); | 
			
		
	
		
			
				
					|  |  |  |  |                     loadedPlayers.remove(playerEntry); | 
			
		
	
		
			
				
					|  |  |  |  |                     continue; | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -1271,7 +991,7 @@ public class MobAI {@@ -1271,7 +991,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 // No aggro for this player
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (GuardCanAggro(mob, loadedPlayer) == false) | 
			
		
	
		
			
				
					|  |  |  |  |                 if (!GuardCanAggro(mob, loadedPlayer)) | 
			
		
	
		
			
				
					|  |  |  |  |                     continue; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (MovementUtilities.inRangeToAggro(mob, loadedPlayer) && mob.getCombatTarget() == null) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -1292,17 +1012,17 @@ public class MobAI {@@ -1292,17 +1012,17 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |                 return false; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.behaviourType.equals(Enum.MobBehaviourType.GuardMinion)) { | 
			
		
	
		
			
				
					|  |  |  |  |                 if (((Mob) mob.guardCaptain).building.getCity().cityOutlaws.contains(target.getObjectUUID()) == true) { | 
			
		
	
		
			
				
					|  |  |  |  |                 if (Objects.requireNonNull(mob.guardCaptain.building.getCity()).cityOutlaws.contains(target.getObjectUUID())) { | 
			
		
	
		
			
				
					|  |  |  |  |                     return true; | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } else if (mob.building.getCity().cityOutlaws.contains(target.getObjectUUID()) == true) { | 
			
		
	
		
			
				
					|  |  |  |  |             } else if (Objects.requireNonNull(mob.building.getCity()).cityOutlaws.contains(target.getObjectUUID())) { | 
			
		
	
		
			
				
					|  |  |  |  |                 return true; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             //first check condemn list for aggro allowed (allies button is checked)
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().reverseKOS) { | 
			
		
	
		
			
				
					|  |  |  |  |                 for (Entry<Integer, Condemned> entry : ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().getCondemned().entrySet()) { | 
			
		
	
		
			
				
					|  |  |  |  |             if (Objects.requireNonNull(ZoneManager.getCityAtLocation(mob.getLoc())).getTOL().reverseKOS) { | 
			
		
	
		
			
				
					|  |  |  |  |                 for (Entry<Integer, Condemned> entry : Objects.requireNonNull(ZoneManager.getCityAtLocation(mob.getLoc())).getTOL().getCondemned().entrySet()) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     //target is listed individually
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -1324,7 +1044,7 @@ public class MobAI {@@ -1324,7 +1044,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 //allies button is not checked
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 for (Entry<Integer, Condemned> entry : ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().getCondemned().entrySet()) { | 
			
		
	
		
			
				
					|  |  |  |  |                 for (Entry<Integer, Condemned> entry : Objects.requireNonNull(ZoneManager.getCityAtLocation(mob.getLoc())).getTOL().getCondemned().entrySet()) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     //target is listed individually
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -1355,7 +1075,7 @@ public class MobAI {@@ -1355,7 +1075,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |             //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
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.isMoving() == true) { | 
			
		
	
		
			
				
					|  |  |  |  |             if (mob.isMoving()) { | 
			
		
	
		
			
				
					|  |  |  |  |                 mob.stopPatrolTime = System.currentTimeMillis(); | 
			
		
	
		
			
				
					|  |  |  |  |                 return; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
	
		
			
				
					|  |  |  | @ -1381,7 +1101,7 @@ public class MobAI {@@ -1381,7 +1101,7 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     //make sure mob is out of combat stance
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                     if (minion.getKey().despawned == false) { | 
			
		
	
		
			
				
					|  |  |  |  |                     if (!minion.getKey().despawned) { | 
			
		
	
		
			
				
					|  |  |  |  |                         if (MovementUtilities.canMove(minion.getKey())) { | 
			
		
	
		
			
				
					|  |  |  |  |                             Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3); | 
			
		
	
		
			
				
					|  |  |  |  |                             minion.getKey().updateLocation(); | 
			
		
	
	
		
			
				
					|  |  |  | @ -1395,40 +1115,4 @@ public class MobAI {@@ -1395,40 +1115,4 @@ public class MobAI { | 
			
		
	
		
			
				
					|  |  |  |  |             Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: randomGuardPatrolPoints" + " " + e.getMessage()); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public static AbstractWorldObject ChangeTargetFromHateValue(Mob mob) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         if(mob.combatTarget != null) | 
			
		
	
		
			
				
					|  |  |  |  |             return mob.combatTarget; | 
			
		
	
		
			
				
					|  |  |  |  |         //try {
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         //    float CurrentHateValue = 0;
 | 
			
		
	
		
			
				
					|  |  |  |  |         //    if (mob.getCombatTarget() != null && mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.Mob)){
 | 
			
		
	
		
			
				
					|  |  |  |  |         //        return mob.getCombatTarget();
 | 
			
		
	
		
			
				
					|  |  |  |  |        //     }
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         //    if (mob.getCombatTarget() != null && mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
 | 
			
		
	
		
			
				
					|  |  |  |  |         //        CurrentHateValue = mob.playerAgroMap.get(mob.combatTarget.getObjectUUID()).floatValue();
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         //    AbstractWorldObject mostHatedTarget = null;
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         //    for (Entry playerEntry : mob.playerAgroMap.entrySet()) {
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         //        PlayerCharacter potentialTarget = PlayerCharacter.getFromCache((int) playerEntry.getKey());
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         //        if (potentialTarget.equals(mob.getCombatTarget()))
 | 
			
		
	
		
			
				
					|  |  |  |  |         //            continue;
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         //        if (potentialTarget != null && mob.playerAgroMap.get(potentialTarget.getObjectUUID()).floatValue() > CurrentHateValue && MovementUtilities.inRangeToAggro(mob, potentialTarget)) {
 | 
			
		
	
		
			
				
					|  |  |  |  |         //            CurrentHateValue = mob.playerAgroMap.get(potentialTarget.getObjectUUID()).floatValue();
 | 
			
		
	
		
			
				
					|  |  |  |  |         //            mostHatedTarget = potentialTarget;
 | 
			
		
	
		
			
				
					|  |  |  |  |         //        }
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         //    }
 | 
			
		
	
		
			
				
					|  |  |  |  |         //    return mostHatedTarget;
 | 
			
		
	
		
			
				
					|  |  |  |  |         //} catch (Exception e) {
 | 
			
		
	
		
			
				
					|  |  |  |  |         //    Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: ChangeTargetFromMostHated" + " " + e.getMessage());
 | 
			
		
	
		
			
				
					|  |  |  |  |         //}
 | 
			
		
	
		
			
				
					|  |  |  |  |         return null; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } |