|  |  | @ -34,6 +34,7 @@ import java.util.ArrayList; | 
			
		
	
		
		
			
				
					
					|  |  |  | import java.util.HashMap; |  |  |  | import java.util.HashMap; | 
			
		
	
		
		
			
				
					
					|  |  |  | import java.util.HashSet; |  |  |  | import java.util.HashSet; | 
			
		
	
		
		
			
				
					
					|  |  |  | import java.util.Map.Entry; |  |  |  | import java.util.Map.Entry; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | import java.util.Random; | 
			
		
	
		
		
			
				
					
					|  |  |  | import java.util.concurrent.ConcurrentHashMap; |  |  |  | import java.util.concurrent.ConcurrentHashMap; | 
			
		
	
		
		
			
				
					
					|  |  |  | import java.util.concurrent.ThreadLocalRandom; |  |  |  | import java.util.concurrent.ThreadLocalRandom; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -41,7 +42,6 @@ import static engine.math.FastMath.sqr; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | public class MobileFSM { |  |  |  | public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     public enum STATE { |  |  |  |     public enum STATE { | 
			
		
	
		
		
			
				
					
					|  |  |  |         Disabled, |  |  |  |         Disabled, | 
			
		
	
		
		
			
				
					
					|  |  |  |         Respawn, |  |  |  |         Respawn, | 
			
		
	
	
		
		
			
				
					|  |  | @ -56,13 +56,10 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |         Recalling, |  |  |  |         Recalling, | 
			
		
	
		
		
			
				
					
					|  |  |  |         Retaliate |  |  |  |         Retaliate | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     public static void run(Mob mob) { |  |  |  |     public static void run(Mob mob) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (mob == null) { |  |  |  |         if (mob == null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         STATE state = mob.getState(); |  |  |  |         STATE state = mob.getState(); | 
			
		
	
		
		
			
				
					
					|  |  |  |         switch (state) { |  |  |  |         switch (state) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             case Idle: |  |  |  |             case Idle: | 
			
		
	
	
		
		
			
				
					|  |  | @ -73,11 +70,9 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     guardAwake(mob); |  |  |  |                     guardAwake(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     break; |  |  |  |                     break; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 idle(mob); |  |  |  |                 idle(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 break; |  |  |  |                 break; | 
			
		
	
		
		
			
				
					
					|  |  |  |             case Awake: |  |  |  |             case Awake: | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (mob.isAlive()) |  |  |  |                 if (mob.isAlive()) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     mob.updateLocation(); |  |  |  |                     mob.updateLocation(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -91,11 +86,8 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     else |  |  |  |                     else | 
			
		
	
		
		
			
				
					
					|  |  |  |                         awake(mob); |  |  |  |                         awake(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 break; |  |  |  |                 break; | 
			
		
	
		
		
			
				
					
					|  |  |  |             case Aggro: |  |  |  |             case Aggro: | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (mob.isAlive()) |  |  |  |                 if (mob.isAlive()) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     mob.updateLocation(); |  |  |  |                     mob.updateLocation(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -609,8 +601,12 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     aiAgent.setState(STATE.Idle); |  |  |  |                     aiAgent.setState(STATE.Idle); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     return; |  |  |  |                     return; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |                 if(canCast(aiAgent) == true){ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 handlePlayerAttackForMob(aiAgent, player); |  |  |  |                     MobCast(aiAgent); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     handlePlayerAttackForMob(aiAgent, player); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                 break; |  |  |  |                 break; | 
			
		
	
		
		
			
				
					
					|  |  |  |             case Building: |  |  |  |             case Building: | 
			
		
	
		
		
			
				
					
					|  |  |  |                 Building building = (Building) target; |  |  |  |                 Building building = (Building) target; | 
			
		
	
	
		
		
			
				
					|  |  | @ -824,20 +820,6 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (aiAgent.getLastMobPowerToken() != 0) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             PowersBase mobPower = PowersManager.getPowerByToken(aiAgent.getLastMobPowerToken()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (System.currentTimeMillis() > aiAgent.getTimeStamp("FInishCast")) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 PerformActionMsg msg = PowersManager.createPowerMsg(mobPower, 40, aiAgent, player); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 msg.setUnknown04(2); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 PowersManager.finishUseMobPower(msg, aiAgent, 0, 0); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 aiAgent.setLastMobPowerToken(0); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 aiAgent.setIsCasting(false); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (System.currentTimeMillis() > aiAgent.getTimeStamp("CallForHelp")) { |  |  |  |         if (System.currentTimeMillis() > aiAgent.getTimeStamp("CallForHelp")) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             CombatUtilities.CallForHelp(aiAgent); |  |  |  |             CombatUtilities.CallForHelp(aiAgent); | 
			
		
	
		
		
			
				
					
					|  |  |  |             aiAgent.getTimestamps().put("CallForHelp", System.currentTimeMillis() + 60000); |  |  |  |             aiAgent.getTimestamps().put("CallForHelp", System.currentTimeMillis() + 60000); | 
			
		
	
	
		
		
			
				
					|  |  | @ -1682,8 +1664,12 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     aiAgent.setState(STATE.Idle); |  |  |  |                     aiAgent.setState(STATE.Idle); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     return; |  |  |  |                     return; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |                 if(canCast(aiAgent) == true){ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 handlePlayerAttackForMob(aiAgent, player); |  |  |  |                     MobCast(aiAgent); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     handlePlayerAttackForMob(aiAgent, player); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                 break; |  |  |  |                 break; | 
			
		
	
		
		
			
				
					
					|  |  |  |             case Building: |  |  |  |             case Building: | 
			
		
	
		
		
			
				
					
					|  |  |  |                 Logger.info("PLAYER GUARD ATTEMPTING TO ATTACK BUILDING IN " + aiAgent.getParentZone().getName()); |  |  |  |                 Logger.info("PLAYER GUARD ATTEMPTING TO ATTACK BUILDING IN " + aiAgent.getParentZone().getName()); | 
			
		
	
	
		
		
			
				
					|  |  | @ -1765,4 +1751,42 @@ public class MobileFSM { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         MovementManager.translocate(mob, regionObject.getLoc(), null); |  |  |  |         MovementManager.translocate(mob, regionObject.getLoc(), null); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     public static boolean canCast(Mob mob){ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(mob == null || mob.mobPowers.isEmpty() || mob.nextCastTime > System.currentTimeMillis()){ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         else{ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     public static void MobCast(Mob mob){ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(mob.getMobBase().getFlags().contains(Enum.MobFlagType.CALLSFORHELP)){ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             MobCallForHelp(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             PlayerCharacter target = (PlayerCharacter)mob.getCombatTarget(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             Random rand = new Random(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             int powerPos = rand.nextInt(mob.mobPowers.size()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             int spellId = mob.mobPowers.get(powerPos); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             PowersBase mobPower = PowersManager.getPowerByToken(spellId); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if(CombatUtilities.inRangeToCast2D(mob, mob.getCombatTarget(),mobPower)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 PerformActionMsg msg = PowersManager.createPowerMsg(mobPower, 40, mob, target); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 msg.setUnknown04(2); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 PowersManager.finishUseMobPower(msg, mob, 0, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 mob.setLastMobPowerToken(0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 mob.setIsCasting(false); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 mob.nextCastTime = System.currentTimeMillis() + mobPower.getCooldown(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             }else{ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 MovementUtilities.moveToLocation(mob,mob.getCombatTarget().getLoc(),mobPower.getRange()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     public static void MobCallForHelp(Mob mob){ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         Zone mobCamp = mob.getParentZone(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         for (Mob mob1 : mobCamp.zoneMobSet) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if(mob1.getMobBase().getFlags().contains(Enum.MobFlagType.RESPONDSTOCALLSFORHELP)){ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 mob1.setCombatTarget(mob.getCombatTarget()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 mob1.setState(STATE.Aggro); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
	
		
		
			
				
					|  |  | 
 |