|  |  | @ -7,6 +7,9 @@ import engine.mobileAI.utilities.CombatUtilities; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.mobileAI.utilities.MovementUtilities; |  |  |  | import engine.mobileAI.utilities.MovementUtilities; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.objects.*; |  |  |  | import engine.objects.*; | 
			
		
	
		
		
			
				
					
					|  |  |  | import engine.server.MBServerStatics; |  |  |  | import engine.server.MBServerStatics; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | import java.util.ArrayList; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | import java.util.HashMap; | 
			
		
	
		
		
			
				
					
					|  |  |  | import java.util.HashSet; |  |  |  | import java.util.HashSet; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | public class StandardMob { |  |  |  | public class StandardMob { | 
			
		
	
	
		
		
			
				
					|  |  | @ -17,19 +20,22 @@ public class StandardMob { | 
			
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         mob.updateLocation(); |  |  |  |         if (mob.isMoving()) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             mob.setLoc(mob.getMovementLoc()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             mob.updateLocation(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(mob.combatTarget == null) { |  |  |  |         if(mob.combatTarget == null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(mob.loc, MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER); |  |  |  |             HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(mob.loc, MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER); | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (!inRange.isEmpty()) { |  |  |  |             if (!inRange.isEmpty()) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 CheckForAggro(mob, inRange); |  |  |  |                 CheckForAggro(mob); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 return; |  |  |  |                 return; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         }else{ |  |  |  |         }else{ | 
			
		
	
		
		
			
				
					
					|  |  |  |             CheckToDropCombatTarget(mob); |  |  |  |             CheckToDropCombatTarget(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  |             if(mob.combatTarget == null){ |  |  |  |             if(mob.combatTarget == null){ | 
			
		
	
		
		
			
				
					
					|  |  |  |                 HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(mob.loc, MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER); |  |  |  |                 HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(mob.loc, MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 CheckForAggro(mob, inRange); |  |  |  |                 CheckForAggro(mob); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 return; |  |  |  |                 return; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
	
		
		
			
				
					|  |  | @ -37,7 +43,7 @@ public class StandardMob { | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(MovementUtilities.canMove(mob)) |  |  |  |         if(MovementUtilities.canMove(mob)) | 
			
		
	
		
		
			
				
					
					|  |  |  |             CheckForMovement(mob); |  |  |  |             CheckForMovement(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(mob.combatTarget != null) |  |  |  |         if(mob.combatTarget != null && !mob.isMoving()) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             CheckForAttack(mob); |  |  |  |             CheckForAttack(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -103,20 +109,76 @@ public class StandardMob { | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     public static void CheckForAggro(Mob mob, HashSet<AbstractWorldObject> inRange){ |  |  |  |     public static void CheckForAggro(Mob mob){ | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(mob == null || !mob.isAlive() || mob.playerAgroMap.isEmpty()){ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(mob.BehaviourType.equals(Enum.MobBehaviourType.HamletGuard)){ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(mob.hate_values == null) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             mob.hate_values = new HashMap<>(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(mob.combatTarget != null) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(mob.loc, 60f, MBServerStatics.MASK_PLAYER); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(inRange.isEmpty()){ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             mob.setCombatTarget(null); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         //clear out any players who are not in hated range anymore
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         ArrayList<PlayerCharacter> toRemove = new ArrayList<>(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         for(PlayerCharacter pc : mob.hate_values.keySet()){ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if(!inRange.contains(pc)) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 toRemove.add(pc); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         for(PlayerCharacter pc : toRemove){ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             mob.hate_values.remove(pc); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         //find most hated target
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         PlayerCharacter mostHated = (PlayerCharacter)inRange.iterator().next(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         for(AbstractWorldObject awo : inRange){ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             PlayerCharacter loadedPlayer = (PlayerCharacter)awo; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (loadedPlayer == null) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             //Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (!loadedPlayer.isAlive()) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             //Can't see target, skip aggro.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (!mob.canSee(loadedPlayer)) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 continue; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             // No aggro for this race type
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (mob.notEnemy != null && mob.notEnemy.size() > 0 && mob.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType())) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             //mob has enemies and this player race is not it
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if (mob.enemy != null && mob.enemy.size() > 0 && !mob.enemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType())) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if(mob.hate_values.containsKey(loadedPlayer)) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 if(mob.hate_values.get(loadedPlayer) > mob.hate_values.get(mostHated)) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     mostHated = loadedPlayer; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(mostHated != null) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             mob.setCombatTarget(mostHated); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     public static void CheckForMovement(Mob mob){ |  |  |  |     public static void CheckForMovement(Mob mob){ | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(mob.combatTarget != null){ |  |  |  |         if(mob.combatTarget != null){ | 
			
		
	
		
		
			
				
					
					|  |  |  |             //chase player
 |  |  |  |             //chase player
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             float rangeSquared = mob.getRange() * mob.getRange(); |  |  |  |             if(!CombatUtilities.inRange2D(mob,mob.combatTarget,mob.getRange())) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             Vector3fImmutable loc2D = mob.loc; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             loc2D.setY(0); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             Vector3fImmutable tarLoc2D = mob.combatTarget.loc; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             tarLoc2D.setY(0); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if(loc2D.distanceSquared(tarLoc2D) > rangeSquared) |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 MovementUtilities.aiMove(mob,mob.combatTarget.loc,false); |  |  |  |                 MovementUtilities.aiMove(mob,mob.combatTarget.loc,false); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         }else{ |  |  |  |         }else{ | 
			
		
	
	
		
		
			
				
					|  |  | @ -130,20 +192,20 @@ public class StandardMob { | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     public static void CheckForAttack(Mob mob){ |  |  |  |     public static void CheckForAttack(Mob mob){ | 
			
		
	
		
		
			
				
					
					|  |  |  |         float rangeSquared = mob.getRange() * mob.getRange(); |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         Vector3fImmutable loc2D = mob.loc; |  |  |  |         if(mob.isMoving()) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         loc2D.setY(0); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         Vector3fImmutable tarLoc2D = mob.combatTarget.loc; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         tarLoc2D.setY(0); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(loc2D.distanceSquared(tarLoc2D) > rangeSquared) |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (mob.BehaviourType.callsForHelp) |  |  |  |         if (mob.BehaviourType.callsForHelp) | 
			
		
	
		
		
			
				
					
					|  |  |  |             MobCallForHelp(mob); |  |  |  |             MobCallForHelp(mob); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         ItemBase mainHand = mob.getWeaponItemBase(true); |  |  |  |         ItemBase mainHand = mob.getWeaponItemBase(true); | 
			
		
	
		
		
			
				
					
					|  |  |  |         ItemBase offHand = mob.getWeaponItemBase(false); |  |  |  |         ItemBase offHand = mob.getWeaponItemBase(false); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(!CombatUtilities.inRange2D(mob,mob.combatTarget,mob.getRange())) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (mainHand == null && offHand == null) { |  |  |  |         if (mainHand == null && offHand == null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             CombatUtilities.combatCycle(mob, mob.combatTarget, true, null); |  |  |  |             CombatUtilities.combatCycle(mob, mob.combatTarget, true, null); | 
			
		
	
		
		
			
				
					
					|  |  |  |             int delay = 3000; |  |  |  |             int delay = 3000; | 
			
		
	
	
		
		
			
				
					|  |  | @ -159,7 +221,7 @@ public class StandardMob { | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     public static void MobCallForHelp(Mob mob){ |  |  |  |     public static void MobCallForHelp(Mob mob){ | 
			
		
	
		
		
			
				
					
					|  |  |  |         HashSet<AbstractWorldObject> mobs = WorldGrid.getObjectsInRangePartial(mob.loc,60f, MBServerStatics.MASK_MOB); |  |  |  |         HashSet<AbstractWorldObject> mobs = WorldGrid.getObjectsInRangePartial(mob.loc,20f, MBServerStatics.MASK_MOB); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         for(AbstractWorldObject awo : mobs){ |  |  |  |         for(AbstractWorldObject awo : mobs){ | 
			
		
	
		
		
			
				
					
					|  |  |  |             Mob responder = (Mob)awo; |  |  |  |             Mob responder = (Mob)awo; | 
			
		
	
		
		
			
				
					
					|  |  |  |             if(responder.combatTarget == null) |  |  |  |             if(responder.combatTarget == null) | 
			
		
	
	
		
		
			
				
					|  |  | 
 |