2 changed files with 294 additions and 1 deletions
			
			
		| @ -1,9 +1,278 @@@@ -1,9 +1,278 @@ | ||||
| package engine.mobileAI.MobHandlers; | ||||
| 
 | ||||
| import engine.objects.Mob; | ||||
| import engine.Enum; | ||||
| import engine.InterestManagement.InterestManager; | ||||
| import engine.gameManager.ChatManager; | ||||
| import engine.gameManager.PowersManager; | ||||
| import engine.gameManager.ZoneManager; | ||||
| import engine.math.Vector3f; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.mobileAI.Threads.MobAIThread; | ||||
| import engine.mobileAI.utilities.CombatUtilities; | ||||
| import engine.mobileAI.utilities.MovementUtilities; | ||||
| import engine.objects.*; | ||||
| import engine.powers.PowersBase; | ||||
| import engine.server.MBServerStatics; | ||||
| 
 | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.ThreadLocalRandom; | ||||
| 
 | ||||
| public class MobHandler { | ||||
|     public static void run(Mob mob){ | ||||
| 
 | ||||
|         if (!mob.isAlive()) { | ||||
|             CheckForRespawn(mob); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if(mob.playerAgroMap.isEmpty()) | ||||
|             return; | ||||
| 
 | ||||
|         CheckToSendMobHome(mob); | ||||
| 
 | ||||
|         if(mob.combatTarget == null || !mob.combatTarget.isAlive()){ | ||||
|             CheckForAggro(mob); | ||||
|             return; | ||||
|         } | ||||
|         if(mob.combatTarget != null) | ||||
|             CheckToDropAggro(mob); | ||||
| 
 | ||||
|         if(MovementUtilities.canMove(mob)) | ||||
|             CheckMobMovement(mob); | ||||
| 
 | ||||
|         if(mob.combatTarget != null && CombatUtilities.inRangeToAttack(mob,mob.combatTarget)) | ||||
|             CheckToAttack(mob); | ||||
|     } | ||||
| 
 | ||||
|     public static void CheckToDropAggro(Mob mob){ | ||||
|         if(mob.loc.distanceSquared(mob.combatTarget.loc) > (64f * 64f)) | ||||
|             mob.setCombatTarget(null); | ||||
|     } | ||||
| 
 | ||||
|     public static void CheckForRespawn(Mob mob){ | ||||
|         try { | ||||
| 
 | ||||
|             if (mob.deathTime == 0) { | ||||
|                 mob.setDeathTime(System.currentTimeMillis()); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             //handles checking for respawn of dead mobs even when no players have mob loaded
 | ||||
|             //Despawn Timer with Loot currently in inventory.
 | ||||
| 
 | ||||
|             if (!mob.despawned) { | ||||
| 
 | ||||
|                 if (mob.getCharItemManager().getInventoryCount() > 0) { | ||||
|                     if (System.currentTimeMillis() > mob.deathTime + MBServerStatics.DESPAWN_TIMER_WITH_LOOT) { | ||||
|                         mob.despawn(); | ||||
|                         mob.deathTime = System.currentTimeMillis(); | ||||
|                         return; | ||||
|                     } | ||||
|                     //No items in inventory.
 | ||||
|                 } else if (mob.isHasLoot()) { | ||||
|                     if (System.currentTimeMillis() > mob.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) { | ||||
|                         mob.despawn(); | ||||
|                         mob.deathTime = System.currentTimeMillis(); | ||||
|                         return; | ||||
|                     } | ||||
|                     //Mob never had Loot.
 | ||||
|                 } else { | ||||
|                     if (System.currentTimeMillis() > mob.deathTime + MBServerStatics.DESPAWN_TIMER) { | ||||
|                         mob.despawn(); | ||||
|                         mob.deathTime = System.currentTimeMillis(); | ||||
|                         return; | ||||
|                     } | ||||
|                 } | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             if(Mob.discDroppers.contains(mob)) | ||||
|                 return; | ||||
| 
 | ||||
|             if (mob.despawned && System.currentTimeMillis() > (mob.deathTime + (mob.spawnTime * 1000L))) { | ||||
|                 if (!Zone.respawnQue.contains(mob)) { | ||||
|                     Zone.respawnQue.add(mob); | ||||
|                 } | ||||
|             } | ||||
|         } catch (Exception e) { | ||||
|             //(aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForRespawn" + " " + e.getMessage());
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void CheckForAggro(Mob mob){ | ||||
|         PlayerCharacter tar = null; | ||||
|         for(int id : mob.playerAgroMap.keySet()){ | ||||
|             PlayerCharacter target = PlayerCharacter.getFromCache(id); | ||||
|             if(tar == null || mob.loc.distanceSquared(tar.loc) < mob.loc.distanceSquared(target.loc)) | ||||
|                 if(MobCanAggro(mob,target)) | ||||
|                     tar = target; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static Boolean MobCanAggro(Mob mob, PlayerCharacter loadedPlayer){ | ||||
|         if (loadedPlayer == null) | ||||
|             return false; | ||||
| 
 | ||||
|         //Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
 | ||||
|         if (!loadedPlayer.isAlive()) | ||||
|             return false; | ||||
| 
 | ||||
|         //Can't see target, skip aggro.
 | ||||
|         if (!mob.canSee(loadedPlayer)) | ||||
|             return false; | ||||
| 
 | ||||
|         // No aggro for this race type
 | ||||
|         if (mob.notEnemy != null && mob.notEnemy.size() > 0 && mob.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType())) | ||||
|             return false; | ||||
| 
 | ||||
|         //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())) | ||||
|             return false; | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     public static void CheckMobMovement(Mob mob){ | ||||
|         if(!mob.isAlive()) | ||||
|             return; | ||||
| 
 | ||||
|         if(mob.combatTarget == null){ | ||||
|             //patrol
 | ||||
|             Patrol(mob); | ||||
|         }else{ | ||||
|             //combat movement
 | ||||
|             if(CombatUtilities.inRangeToAttack(mob,mob.combatTarget)) | ||||
|                 return; | ||||
|             else | ||||
|                 MovementUtilities.aiMove(mob,mob.combatTarget.loc,false); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void CheckToAttack(Mob mob){ | ||||
|         try { | ||||
| 
 | ||||
|             PlayerCharacter target = (PlayerCharacter) mob.combatTarget; | ||||
| 
 | ||||
|             if (!mob.canSee(target)) { | ||||
|                 mob.setCombatTarget(null); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             if (mob.BehaviourType.callsForHelp) | ||||
|                 MobCallForHelp(mob); | ||||
| 
 | ||||
|             if (mob.isMoving() && mob.getRange() > 20) | ||||
|                 return; | ||||
| 
 | ||||
|             if(target.combatStats == null) | ||||
|                 target.combatStats = new PlayerCombatStats(target); | ||||
| 
 | ||||
|             ItemBase mainHand = mob.getWeaponItemBase(true); | ||||
|             ItemBase offHand = mob.getWeaponItemBase(false); | ||||
| 
 | ||||
|             if (mainHand == null && offHand == null) { | ||||
|                 CombatUtilities.combatCycle(mob, target, true, null); | ||||
|                 int delay = 3000; | ||||
|                 mob.setLastAttackTime(System.currentTimeMillis() + delay); | ||||
|             } else if (mob.getWeaponItemBase(true) != null) { | ||||
|                 int delay = 3000; | ||||
|                 CombatUtilities.combatCycle(mob, target, true, mob.getWeaponItemBase(true)); | ||||
|                 mob.setLastAttackTime(System.currentTimeMillis() + delay); | ||||
|             } else if (mob.getWeaponItemBase(false) != null) { | ||||
|                 int attackDelay = 3000; | ||||
|                 CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false)); | ||||
|                 mob.setLastAttackTime(System.currentTimeMillis() + attackDelay); | ||||
|             } | ||||
| 
 | ||||
|             if (target.getPet() != null) | ||||
|                 if (target.getPet().getCombatTarget() == null && target.getPet().assist) | ||||
|                     target.getPet().setCombatTarget(mob); | ||||
| 
 | ||||
|         } catch (Exception e) { | ||||
|             ////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackPlayer" + " " + e.getMessage());
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void MobCallForHelp(Mob mob) { | ||||
| 
 | ||||
|         try { | ||||
| 
 | ||||
|             boolean callGotResponse = false; | ||||
| 
 | ||||
|             if (mob.nextCallForHelp == 0) | ||||
|                 mob.nextCallForHelp = System.currentTimeMillis(); | ||||
| 
 | ||||
|             if (mob.nextCallForHelp < System.currentTimeMillis()) | ||||
|                 return; | ||||
| 
 | ||||
|             //mob sends call for help message
 | ||||
| 
 | ||||
|             ChatManager.chatSayInfo(null, mob.getName() + " calls for help!"); | ||||
| 
 | ||||
|             Zone mobCamp = mob.getParentZone(); | ||||
| 
 | ||||
|             for (Mob helper : mobCamp.zoneMobSet) { | ||||
|                 if (helper.BehaviourType.respondsToCallForHelp && helper.BehaviourType.BehaviourHelperType.equals(mob.BehaviourType)) { | ||||
|                     helper.setCombatTarget(mob.getCombatTarget()); | ||||
|                     callGotResponse = true; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             //wait 60 seconds to call for help again
 | ||||
| 
 | ||||
|             if (callGotResponse) | ||||
|                 mob.nextCallForHelp = System.currentTimeMillis() + 60000; | ||||
| 
 | ||||
|         } catch (Exception e) { | ||||
|             //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCallForHelp" + " " + e.getMessage());
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private static void Patrol(Mob mob) { | ||||
| 
 | ||||
|         try { | ||||
| 
 | ||||
|             //make sure mob is out of combat stance
 | ||||
| 
 | ||||
|             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
 | ||||
| 
 | ||||
|             if (mob.stopPatrolTime + (patrolDelay * 1000) > System.currentTimeMillis()) | ||||
|                 return; | ||||
| 
 | ||||
|             if (mob.lastPatrolPointIndex > mob.patrolPoints.size() - 1) | ||||
|                 mob.lastPatrolPointIndex = 0; | ||||
| 
 | ||||
|             mob.destination = mob.patrolPoints.get(mob.lastPatrolPointIndex); | ||||
|             mob.lastPatrolPointIndex += 1; | ||||
| 
 | ||||
|             MovementUtilities.aiMove(mob, mob.destination, true); | ||||
| 
 | ||||
|         } catch (Exception e) { | ||||
|             ////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private static void CheckToSendMobHome(Mob mob) { | ||||
| 
 | ||||
|         if(mob.isNecroPet()) | ||||
|             return; | ||||
| 
 | ||||
|         try { | ||||
| 
 | ||||
|             if (!MovementUtilities.inRangeOfBindLocation(mob)) { | ||||
| 
 | ||||
|                 PowersBase recall = PowersManager.getPowerByToken(-1994153779); | ||||
|                 PowersManager.useMobPower(mob, mob, recall, 40); | ||||
| 
 | ||||
|                 for (Map.Entry playerEntry : mob.playerAgroMap.entrySet()) | ||||
|                     PlayerCharacter.getFromCache((int) playerEntry.getKey()).setHateValue(0); | ||||
| 
 | ||||
|                 mob.setCombatTarget(null); | ||||
|             } | ||||
|         } catch (Exception e) { | ||||
|             //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome" + " " + e.getMessage());
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
					Loading…
					
					
				
		Reference in new issue