|  |  | @ -20,7 +20,6 @@ import engine.mobileAI.utilities.MovementUtilities; | 
			
		
	
		
		
			
				
					
					|  |  |  | 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.objects.*; |  |  |  | import engine.objects.*; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.powers.ActionsBase; |  |  |  | import engine.powers.ActionsBase; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.powers.PowersBase; |  |  |  | import engine.powers.PowersBase; | 
			
		
	
	
		
		
			
				
					|  |  | @ -50,12 +49,16 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return; |  |  |  |                 return; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) |  |  |  |             if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 if (MobCast(mob)) { |  |  |  |                 if (mob.isPlayerGuard() == false && MobCast(mob)) { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                     mob.updateLocation(); |  |  |  |                     mob.updateLocation(); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     return; |  |  |  |                     return; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |                 if (mob.isPlayerGuard() == true && GuardCast(mob)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     mob.updateLocation(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     return; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (!CombatUtilities.inRangeToAttack(mob, target)) |  |  |  |             if (!CombatUtilities.inRangeToAttack(mob, target)) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return; |  |  |  |                 return; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -230,8 +233,8 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     attackDelay = 11000; |  |  |  |                     attackDelay = 11000; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false)); |  |  |  |                 CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false)); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 mob.setLastAttackTime(System.currentTimeMillis() + attackDelay); |  |  |  |                 mob.setLastAttackTime(System.currentTimeMillis() + attackDelay); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (target.combatTarget == null) { |  |  |  |                 if (target.getCombatTarget() == null) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     target.combatTarget = mob; |  |  |  |                     target.setCombatTarget(mob); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         } catch (Exception e) { |  |  |  |         } catch (Exception e) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -245,13 +248,6 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //make sure mob is out of combat stance
 |  |  |  |             //make sure mob is out of combat stance
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (mob.isCombat() && mob.getCombatTarget() == null) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 mob.setCombat(false); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 UpdateStateMsg rwss = new UpdateStateMsg(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 rwss.setPlayer(mob); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 DispatchMessage.sendToAllInRange(mob, rwss); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             int patrolDelay = ThreadLocalRandom.current().nextInt((int) (MobAIThread.AI_PATROL_DIVISOR * 0.5f), MobAIThread.AI_PATROL_DIVISOR) + MobAIThread.AI_PATROL_DIVISOR; |  |  |  |             int patrolDelay = ThreadLocalRandom.current().nextInt((int) (MobAIThread.AI_PATROL_DIVISOR * 0.5f), MobAIThread.AI_PATROL_DIVISOR) + MobAIThread.AI_PATROL_DIVISOR; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //early exit while waiting to patrol again
 |  |  |  |             //early exit while waiting to patrol again
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -279,19 +275,12 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             MovementUtilities.aiMove(mob, mob.destination, true); |  |  |  |             MovementUtilities.aiMove(mob, mob.destination, true); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal()) { |  |  |  |             if (mob.BehaviourType.equals(Enum.MobBehaviourType.GuardCaptain)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 for (Entry<Mob, Integer> minion : mob.siegeMinionMap.entrySet()) { |  |  |  |                 for (Entry<Mob, Integer> minion : mob.siegeMinionMap.entrySet()) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     //make sure mob is out of combat stance
 |  |  |  |                     //make sure mob is out of combat stance
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (minion.getKey().despawned == false) { |  |  |  |                     if (minion.getKey().despawned == false) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                         if (minion.getKey().isCombat() && minion.getKey().getCombatTarget() == null) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                             minion.getKey().setCombat(false); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                             UpdateStateMsg rwss = new UpdateStateMsg(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                             rwss.setPlayer(minion.getKey()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                             DispatchMessage.sendToAllInRange(minion.getKey(), rwss); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         if (MovementUtilities.canMove(minion.getKey())) { |  |  |  |                         if (MovementUtilities.canMove(minion.getKey())) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                             Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3); |  |  |  |                             Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3); | 
			
		
	
		
		
			
				
					
					|  |  |  |                             minion.getKey().updateLocation(); |  |  |  |                             minion.getKey().updateLocation(); | 
			
		
	
	
		
		
			
				
					|  |  | @ -316,6 +305,16 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (mob == null) |  |  |  |             if (mob == null) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return false; |  |  |  |                 return false; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if(mob.isPlayerGuard == true){ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 int contractID; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 if(mob.BehaviourType.equals(Enum.MobBehaviourType.GuardMinion)) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     contractID = mob.npcOwner.contract.getContractID(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                  else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     contractID = mob.contract.getContractID(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 if(Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (mob.mobPowers.isEmpty()) |  |  |  |             if (mob.mobPowers.isEmpty()) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return false; |  |  |  |                 return false; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -323,12 +322,6 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 mob.setCombatTarget(null); |  |  |  |                 mob.setCombatTarget(null); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return false; |  |  |  |                 return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             int castRoll = ThreadLocalRandom.current().nextInt(101); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (castRoll <= MobAIThread.AI_POWER_DIVISOR) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (mob.nextCastTime == 0) |  |  |  |             if (mob.nextCastTime == 0) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 mob.nextCastTime = System.currentTimeMillis(); |  |  |  |                 mob.nextCastTime = System.currentTimeMillis(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -349,7 +342,7 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             ArrayList<Integer> powerTokens; |  |  |  |             ArrayList<Integer> powerTokens; | 
			
		
	
		
		
			
				
					
					|  |  |  |             ArrayList<Integer> purgeTokens; |  |  |  |             ArrayList<Integer> purgeTokens; | 
			
		
	
		
		
			
				
					
					|  |  |  |             PlayerCharacter target = (PlayerCharacter) mob.getCombatTarget(); |  |  |  |             AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (mob.BehaviourType.callsForHelp) |  |  |  |             if (mob.BehaviourType.callsForHelp) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 MobCallForHelp(mob); |  |  |  |                 MobCallForHelp(mob); | 
			
		
	
	
		
		
			
				
					|  |  | @ -395,37 +388,152 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget())) |  |  |  |                 if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget())) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     return false; |  |  |  |                     return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             // Cast the spell
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (CombatUtilities.triggerDodge(mob, mob.getCombatTarget())) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     return false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (CombatUtilities.triggerBlock(mob, mob.getCombatTarget())) |  |  |  |                 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; |  |  |  |         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); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (CombatUtilities.triggerParry(mob, mob.getCombatTarget())) |  |  |  |             // Sanity check
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (powerTokens.isEmpty()) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return false; |  |  |  |                 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
 |  |  |  |             // Cast the spell
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) { |  |  |  |             if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 PowersManager.useMobPower(mob, (AbstractCharacter) mob.getCombatTarget(), mobPower, powerRank); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 PerformActionMsg msg; |  |  |  |                 PerformActionMsg msg; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (!mobPower.isHarmful() || mobPower.targetSelf) |  |  |  |                 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); |  |  |  |                         msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 else |  |  |  |                     } | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     PowersManager.useMobPower(mob, target, mobPower, powerRank); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); |  |  |  |                     msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 msg.setUnknown04(2); |  |  |  |                 msg.setUnknown04(2); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 PowersManager.finishUseMobPower(msg, mob, 0, 0); |  |  |  |                 PowersManager.finishUseMobPower(msg, mob, 0, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 // Default minimum seconds between cast = 10
 |  |  |  |                 long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |                 mob.nextCastTime = System.currentTimeMillis() + randomCooldown; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 float randomCooldown = (ThreadLocalRandom.current().nextInt(150) + 100) * 0.01f; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 mob.nextCastTime = System.currentTimeMillis() + (long) ((mobPower.getCooldown() + (MobAIThread.AI_POWER_DIVISOR * 1000)) * randomCooldown); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 return true; |  |  |  |                 return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         } catch (Exception e) { |  |  |  |         } catch (Exception e) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -529,22 +637,15 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //no players loaded, no need to proceed
 |  |  |  |             //no players loaded, no need to proceed
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (mob.playerAgroMap.isEmpty() && mob.isPlayerGuard == false && mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) { |  |  |  |             if (mob.playerAgroMap.isEmpty()) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 if(mob.getCombatTarget() != null) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     mob.setCombatTarget(null); |  |  |  |                     mob.setCombatTarget(null); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return; |  |  |  |                 return; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (mob.isCombat() && mob.getCombatTarget() == null) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 mob.setCombat(false); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 UpdateStateMsg rwss = new UpdateStateMsg(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 rwss.setPlayer(mob); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 DispatchMessage.sendToAllInRange(mob, rwss); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) |  |  |  |             if (mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 CheckToSendMobHome(mob); |  |  |  |                 CheckToSendMobHome(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (mob.combatTarget != null) { |  |  |  |             if (mob.getCombatTarget() != null) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 if (mob.getCombatTarget().isAlive() == false) { |  |  |  |                 if (mob.getCombatTarget().isAlive() == false) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     mob.setCombatTarget(null); |  |  |  |                     mob.setCombatTarget(null); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     return; |  |  |  |                     return; | 
			
		
	
	
		
		
			
				
					|  |  | @ -552,7 +653,7 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (mob.getCombatTarget().getObjectTypeMask() == MBServerStatics.MASK_PLAYER) { |  |  |  |                 if (mob.getCombatTarget().getObjectTypeMask() == MBServerStatics.MASK_PLAYER) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     PlayerCharacter target = (PlayerCharacter) mob.combatTarget; |  |  |  |                     PlayerCharacter target = (PlayerCharacter) mob.getCombatTarget(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (mob.playerAgroMap.containsKey(target.getObjectUUID()) == false) { |  |  |  |                     if (mob.playerAgroMap.containsKey(target.getObjectUUID()) == false) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                         mob.setCombatTarget(null); |  |  |  |                         mob.setCombatTarget(null); | 
			
		
	
	
		
		
			
				
					|  |  | @ -644,7 +745,7 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (aiAgent.combatTarget == null) { |  |  |  |             if (aiAgent.getCombatTarget() == null) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 //look for pets to aggro if no players found to aggro
 |  |  |  |                 //look for pets to aggro if no players found to aggro
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -790,23 +891,8 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false && mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) { |  |  |  |             if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false && mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 mob.setCombatTarget(null); |  |  |  |                 mob.setCombatTarget(null); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (mob.isCombat()) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     mob.setCombat(false); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     UpdateStateMsg rwss = new UpdateStateMsg(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     rwss.setPlayer(mob); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     DispatchMessage.sendToAllInRange(mob, rwss); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return; |  |  |  |                 return; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (!mob.isCombat()) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 mob.setCombat(true); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 UpdateStateMsg rwss = new UpdateStateMsg(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 rwss.setPlayer(mob); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 DispatchMessage.sendToAllInRange(mob, rwss); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (System.currentTimeMillis() > mob.getLastAttackTime()) |  |  |  |             if (System.currentTimeMillis() > mob.getLastAttackTime()) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 AttackTarget(mob, mob.getCombatTarget()); |  |  |  |                 AttackTarget(mob, mob.getCombatTarget()); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -869,10 +955,12 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         try { |  |  |  |         try { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             mob.updateMovementState(); |  |  |  |             float rangeSquared = mob.getRange() * mob.getRange(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             mob.updateLocation(); |  |  |  |             float distanceSquared = mob.getLoc().distanceSquared2D(mob.getCombatTarget().getLoc()); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |             if(mob.isMoving() == true && distanceSquared < rangeSquared - 50) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { |  |  |  |                 mob.destination = mob.getLoc(); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 MovementUtilities.moveToLocation(mob, mob.destination, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } else if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (mob.getRange() > 15) { |  |  |  |                 if (mob.getRange() > 15) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     mob.destination = mob.getCombatTarget().getLoc(); |  |  |  |                     mob.destination = mob.getCombatTarget().getLoc(); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     MovementUtilities.moveToLocation(mob, mob.destination, 0); |  |  |  |                     MovementUtilities.moveToLocation(mob, mob.destination, 0); | 
			
		
	
	
		
		
			
				
					|  |  | @ -891,11 +979,10 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  |                             MovementUtilities.moveToLocation(mob, mob.getCombatTarget().getLoc(), 0); |  |  |  |                             MovementUtilities.moveToLocation(mob, mob.getCombatTarget().getLoc(), 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |                             break; |  |  |  |                             break; | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == true) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         mob.stopMovement(mob.getLoc()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             mob.updateMovementState(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             mob.updateLocation(); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } catch (Exception e) { |  |  |  |         } catch (Exception e) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: chaseTarget" + " " + e.getMessage()); |  |  |  |             Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: chaseTarget" + " " + e.getMessage()); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
	
		
		
			
				
					|  |  | @ -919,7 +1006,8 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (aggroMob.isGuard()) |  |  |  |                 if (aggroMob.isGuard()) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     continue; |  |  |  |                     continue; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |                 if(aggroMob.BehaviourType.equals(Enum.MobBehaviourType.Pet1)) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (mob.getLoc().distanceSquared2D(aggroMob.getLoc()) > sqr(50)) |  |  |  |                 if (mob.getLoc().distanceSquared2D(aggroMob.getLoc()) > sqr(50)) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     continue; |  |  |  |                     continue; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -936,6 +1024,18 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (mob.getCombatTarget() == null) |  |  |  |             if (mob.getCombatTarget() == null) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 CheckForPlayerGuardAggro(mob); |  |  |  |                 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); |  |  |  |             CheckMobMovement(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  |             CheckForAttack(mob); |  |  |  |             CheckForAttack(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } catch (Exception e) { |  |  |  |         } catch (Exception e) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -946,14 +1046,33 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  |     public static void GuardMinionLogic(Mob mob) { |  |  |  |     public static void GuardMinionLogic(Mob mob) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         try { |  |  |  |         try { | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (!mob.npcOwner.isAlive() && mob.getCombatTarget() == null) |  |  |  |             if (!mob.npcOwner.isAlive()) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 if(mob.getCombatTarget() == null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     CheckForPlayerGuardAggro(mob); |  |  |  |                     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.npcOwner.getCombatTarget() != null) |  |  |  |                 if (mob.npcOwner.getCombatTarget() != null) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     if(mob.getCombatTarget() != null && mob.getCombatTarget().equals(mob.npcOwner.getCombatTarget()) == false) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     mob.setCombatTarget(mob.npcOwner.getCombatTarget()); |  |  |  |                     mob.setCombatTarget(mob.npcOwner.getCombatTarget()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 else |  |  |  |                 else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     if(mob.getCombatTarget() != null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                         mob.setCombatTarget(null); |  |  |  |                         mob.setCombatTarget(null); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |                     } | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             CheckMobMovement(mob); |  |  |  |             CheckMobMovement(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  |             CheckForAttack(mob); |  |  |  |             CheckForAttack(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } catch (Exception e) { |  |  |  |         } catch (Exception e) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -1014,7 +1133,7 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (mob.getCombatTarget() == null) |  |  |  |             if (mob.getCombatTarget() == null) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 SafeGuardAggro(mob); |  |  |  |                 SafeGuardAggro(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  |             else if (mob.combatTarget.isAlive() == false) |  |  |  |             else if (mob.getCombatTarget().isAlive() == false) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 SafeGuardAggro(mob); |  |  |  |                 SafeGuardAggro(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             CheckForAttack(mob); |  |  |  |             CheckForAttack(mob); | 
			
		
	
	
		
		
			
				
					|  |  | @ -1055,7 +1174,7 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             //check if mob can attack if it isn't wimpy
 |  |  |  |             //check if mob can attack if it isn't wimpy
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (!mob.BehaviourType.isWimpy && mob.combatTarget != null) |  |  |  |             if (!mob.BehaviourType.isWimpy && mob.getCombatTarget() != null) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 CheckForAttack(mob); |  |  |  |                 CheckForAttack(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         } catch (Exception e) { |  |  |  |         } catch (Exception e) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -1103,7 +1222,7 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (GuardCanAggro(mob, loadedPlayer) == false) |  |  |  |                 if (GuardCanAggro(mob, loadedPlayer) == false) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     continue; |  |  |  |                     continue; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (MovementUtilities.inRangeToAggro(mob, loadedPlayer)) { |  |  |  |                 if (MovementUtilities.inRangeToAggro(mob, loadedPlayer) && mob.getCombatTarget() == null) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                     mob.setCombatTarget(loadedPlayer); |  |  |  |                     mob.setCombatTarget(loadedPlayer); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     return; |  |  |  |                     return; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
	
		
		
			
				
					|  |  | @ -1211,13 +1330,6 @@ public class MobAI { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     //make sure mob is out of combat stance
 |  |  |  |                     //make sure mob is out of combat stance
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (minion.getKey().despawned == false) { |  |  |  |                     if (minion.getKey().despawned == false) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                         if (minion.getKey().isCombat() && minion.getKey().getCombatTarget() == null) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                             minion.getKey().setCombat(false); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                             UpdateStateMsg rwss = new UpdateStateMsg(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                             rwss.setPlayer(minion.getKey()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                             DispatchMessage.sendToAllInRange(minion.getKey(), rwss); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         if (MovementUtilities.canMove(minion.getKey())) { |  |  |  |                         if (MovementUtilities.canMove(minion.getKey())) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                             Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3); |  |  |  |                             Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3); | 
			
		
	
		
		
			
				
					
					|  |  |  |                             minion.getKey().updateLocation(); |  |  |  |                             minion.getKey().updateLocation(); | 
			
		
	
	
		
		
			
				
					|  |  | 
 |