|
|
|
@ -43,6 +43,7 @@ public class MobAI {
@@ -43,6 +43,7 @@ public class MobAI {
|
|
|
|
|
// Controls all mob actions from regular mobs to pets and guards.
|
|
|
|
|
// Initiates in the "DetermineAction" method and branches from there
|
|
|
|
|
//
|
|
|
|
|
// CombatManager.class implements shared combat routines for all avatars.
|
|
|
|
|
|
|
|
|
|
private static void attackTarget(Mob mob, AbstractWorldObject target) { |
|
|
|
|
|
|
|
|
@ -56,8 +57,7 @@ public class MobAI {
@@ -56,8 +57,7 @@ public class MobAI {
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (target.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter) && |
|
|
|
|
!mob.canSee((AbstractCharacter) target)) { |
|
|
|
|
if (target.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter) && !mob.canSee((AbstractCharacter) target)) { |
|
|
|
|
mob.setCombatTarget(null); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -125,7 +125,7 @@ public class MobAI {
@@ -125,7 +125,7 @@ public class MobAI {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (target.getPet() != null) |
|
|
|
|
if (target.getPet().getCombatTarget() == null && target.getPet().assist == true) |
|
|
|
|
if (target.getPet().getCombatTarget() == null && target.getPet().assist) |
|
|
|
|
target.getPet().setCombatTarget(mob); |
|
|
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
@ -177,7 +177,6 @@ public class MobAI {
@@ -177,7 +177,6 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
//no weapons, default mob attack speed 3 seconds.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CombatManager.combatCycle(mob, target); |
|
|
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
@ -194,10 +193,9 @@ public class MobAI {
@@ -194,10 +193,9 @@ public class MobAI {
|
|
|
|
|
// early exit while waiting to patrol again.
|
|
|
|
|
// Minions are force marched if captain is alive
|
|
|
|
|
|
|
|
|
|
boolean forced = mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION) && |
|
|
|
|
mob.guardCaptain.isAlive(); |
|
|
|
|
boolean forced = mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION) && mob.guardCaptain.isAlive(); |
|
|
|
|
|
|
|
|
|
if (mob.stopPatrolTime + (patrolDelay * 1000) > System.currentTimeMillis()) |
|
|
|
|
if (mob.stopPatrolTime + (patrolDelay * 1000L) > System.currentTimeMillis()) |
|
|
|
|
if (!forced) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
@ -258,7 +256,7 @@ public class MobAI {
@@ -258,7 +256,7 @@ public class MobAI {
|
|
|
|
|
if (mob == null) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
if (mob.isPlayerGuard() == true) { |
|
|
|
|
if (mob.isPlayerGuard()) { |
|
|
|
|
|
|
|
|
|
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDWALLARCHER)) |
|
|
|
|
return false; //wall archers don't cast
|
|
|
|
@ -269,14 +267,13 @@ public class MobAI {
@@ -269,14 +267,13 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
// exception allowing werewolf and werebear guard captains to cast
|
|
|
|
|
|
|
|
|
|
if (mbEnums.MinionType.ContractToMinionMap.get(contractID).isMage() == false && contractID != 980103 && contractID != 980104) |
|
|
|
|
if (!mbEnums.MinionType.ContractToMinionMap.get(contractID).isMage() && contractID != 980103 && contractID != 980104) |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Mobile has no powers defined in mobbase or contract..
|
|
|
|
|
|
|
|
|
|
if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() && |
|
|
|
|
PowersManager.getPowersForRune(contractID).isEmpty()) |
|
|
|
|
if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() && PowersManager.getPowersForRune(contractID).isEmpty()) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
if (mob.nextCastTime == 0) |
|
|
|
@ -376,7 +373,7 @@ public class MobAI {
@@ -376,7 +373,7 @@ public class MobAI {
|
|
|
|
|
msg.setUnknown04(2); |
|
|
|
|
|
|
|
|
|
PowersManager.finishUseMobPower(msg, mob, 0, 0); |
|
|
|
|
long randomCooldown = (long) ((ThreadLocalRandom.current().nextInt(10, 15) * 1000) * MobAIThread.AI_CAST_FREQUENCY); |
|
|
|
|
long randomCooldown = (long) ((ThreadLocalRandom.current().nextInt(10, 15) * 1000L) * MobAIThread.AI_CAST_FREQUENCY); |
|
|
|
|
|
|
|
|
|
mob.nextCastTime = System.currentTimeMillis() + randomCooldown; |
|
|
|
|
return true; |
|
|
|
@ -460,7 +457,7 @@ public class MobAI {
@@ -460,7 +457,7 @@ public class MobAI {
|
|
|
|
|
if (mob == null) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (mob.getTimestamps().containsKey("lastExecution") == false) |
|
|
|
|
if (!mob.getTimestamps().containsKey("lastExecution")) |
|
|
|
|
mob.getTimestamps().put("lastExecution", System.currentTimeMillis()); |
|
|
|
|
|
|
|
|
|
if (System.currentTimeMillis() < mob.getTimeStamp("lastExecution")) |
|
|
|
@ -480,11 +477,11 @@ public class MobAI {
@@ -480,11 +477,11 @@ public class MobAI {
|
|
|
|
|
if (mob.despawned && mob.isPlayerGuard()) { |
|
|
|
|
|
|
|
|
|
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION)) { |
|
|
|
|
if (mob.guardCaptain.isAlive() == false || ((Mob) mob.guardCaptain).despawned == true) { |
|
|
|
|
if (!mob.guardCaptain.isAlive() || ((Mob) mob.guardCaptain).despawned) { |
|
|
|
|
|
|
|
|
|
//minions don't respawn while guard captain is dead
|
|
|
|
|
|
|
|
|
|
if (mob.isAlive() == false) { |
|
|
|
|
if (!mob.isAlive()) { |
|
|
|
|
mob.deathTime = System.currentTimeMillis(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -525,12 +522,12 @@ public class MobAI {
@@ -525,12 +522,12 @@ public class MobAI {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (mob.agentType.equals(mbEnums.AIAgentType.PET) == false) |
|
|
|
|
if (!mob.agentType.equals(mbEnums.AIAgentType.PET)) |
|
|
|
|
checkToSendMobHome(mob); |
|
|
|
|
|
|
|
|
|
if (mob.getCombatTarget() != null) { |
|
|
|
|
|
|
|
|
|
if (mob.getCombatTarget().isAlive() == false) { |
|
|
|
|
if (!mob.getCombatTarget().isAlive()) { |
|
|
|
|
mob.setCombatTarget(null); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -539,12 +536,12 @@ public class MobAI {
@@ -539,12 +536,12 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
PlayerCharacter target = (PlayerCharacter) mob.getCombatTarget(); |
|
|
|
|
|
|
|
|
|
if (mob.playerAgroMap.containsKey(target.getObjectUUID()) == false) { |
|
|
|
|
if (!mob.playerAgroMap.containsKey(target.getObjectUUID())) { |
|
|
|
|
mob.setCombatTarget(null); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (mob.canSee((PlayerCharacter) mob.getCombatTarget()) == false) { |
|
|
|
|
if (!mob.canSee((PlayerCharacter) mob.getCombatTarget())) { |
|
|
|
|
mob.setCombatTarget(null); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -611,12 +608,12 @@ public class MobAI {
@@ -611,12 +608,12 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
// No aggro for this race type
|
|
|
|
|
|
|
|
|
|
if (aiAgent.notEnemy.size() > 0 && aiAgent.notEnemy.contains(loadedPlayer.race.getRaceType().getMonsterType()) == true) |
|
|
|
|
if (aiAgent.notEnemy.size() > 0 && aiAgent.notEnemy.contains(loadedPlayer.race.getRaceType().getMonsterType())) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
//mob has enemies and this player race is not it
|
|
|
|
|
|
|
|
|
|
if (aiAgent.enemy.size() > 0 && aiAgent.enemy.contains(loadedPlayer.race.getRaceType().getMonsterType()) == false) |
|
|
|
|
if (aiAgent.enemy.size() > 0 && !aiAgent.enemy.contains(loadedPlayer.race.getRaceType().getMonsterType())) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (MovementUtilities.inRangeToAggro(aiAgent, loadedPlayer)) { |
|
|
|
@ -690,9 +687,9 @@ public class MobAI {
@@ -690,9 +687,9 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
// Minions only patrol on their own if captain is dead.
|
|
|
|
|
|
|
|
|
|
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION) == false) |
|
|
|
|
if (!mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION)) |
|
|
|
|
patrol(mob); |
|
|
|
|
else if (mob.guardCaptain.isAlive() == false) |
|
|
|
|
else if (!mob.guardCaptain.isAlive()) |
|
|
|
|
patrol(mob); |
|
|
|
|
} else |
|
|
|
|
mob.stopPatrolTime = System.currentTimeMillis(); |
|
|
|
@ -724,7 +721,6 @@ public class MobAI {
@@ -724,7 +721,6 @@ public class MobAI {
|
|
|
|
|
if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_WITH_LOOT) { |
|
|
|
|
aiAgent.despawn(); |
|
|
|
|
aiAgent.deathTime = System.currentTimeMillis(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
//No items in inventory.
|
|
|
|
|
} else { |
|
|
|
@ -733,14 +729,12 @@ public class MobAI {
@@ -733,14 +729,12 @@ public class MobAI {
|
|
|
|
|
if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) { |
|
|
|
|
aiAgent.despawn(); |
|
|
|
|
aiAgent.deathTime = System.currentTimeMillis(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
//Mob never had Loot.
|
|
|
|
|
} else { |
|
|
|
|
if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER) { |
|
|
|
|
aiAgent.despawn(); |
|
|
|
|
aiAgent.deathTime = System.currentTimeMillis(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -758,14 +752,13 @@ public class MobAI {
@@ -758,14 +752,13 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
//checks if mob can attack based on attack timer and range
|
|
|
|
|
|
|
|
|
|
if (mob.isAlive() == false) |
|
|
|
|
if (!mob.isAlive()) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (mob.getCombatTarget() == null) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (mob.getCombatTarget().getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false && |
|
|
|
|
mob.agentType.equals(mbEnums.AIAgentType.PET) == false) { |
|
|
|
|
if (mob.getCombatTarget().getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter) && !MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) && !mob.agentType.equals(mbEnums.AIAgentType.PET)) { |
|
|
|
|
|
|
|
|
|
mob.setCombatTarget(null); |
|
|
|
|
return; |
|
|
|
@ -788,7 +781,7 @@ public class MobAI {
@@ -788,7 +781,7 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
City current = ZoneManager.getCityAtLocation(mob.getLoc()); |
|
|
|
|
|
|
|
|
|
if (current == null || current.equals(mob.getGuild().getOwnedCity()) == false) { |
|
|
|
|
if (current == null || !current.equals(mob.getGuild().getOwnedCity())) { |
|
|
|
|
|
|
|
|
|
PowersBase recall = PowersManager.getPowerByToken(-1994153779); |
|
|
|
|
PowersManager.useMobPower(mob, mob, recall, 40); |
|
|
|
@ -806,7 +799,7 @@ public class MobAI {
@@ -806,7 +799,7 @@ public class MobAI {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else if (MovementUtilities.inRangeOfBindLocation(mob) == false) { |
|
|
|
|
} else if (!MovementUtilities.inRangeOfBindLocation(mob)) { |
|
|
|
|
|
|
|
|
|
PowersBase recall = PowersManager.getPowerByToken(-1994153779); |
|
|
|
|
PowersManager.useMobPower(mob, mob, recall, 40); |
|
|
|
@ -824,7 +817,7 @@ public class MobAI {
@@ -824,7 +817,7 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
|
|
if (mob.getTimestamps().containsKey("lastChase") == false) |
|
|
|
|
if (!mob.getTimestamps().containsKey("lastChase")) |
|
|
|
|
mob.getTimestamps().put("lastChase", System.currentTimeMillis()); |
|
|
|
|
else if (System.currentTimeMillis() < mob.getTimestamps().get("lastChase").longValue() + (750 + ThreadLocalRandom.current().nextInt(0, 500))) |
|
|
|
|
return; |
|
|
|
@ -874,7 +867,7 @@ public class MobAI {
@@ -874,7 +867,7 @@ public class MobAI {
|
|
|
|
|
Mob aggroMob = (Mob) awoMob; |
|
|
|
|
|
|
|
|
|
//don't attack other guards
|
|
|
|
|
if (aggroMob.isGuard() == true) |
|
|
|
|
if (aggroMob.isGuard()) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
//don't attack pets
|
|
|
|
@ -925,7 +918,7 @@ public class MobAI {
@@ -925,7 +918,7 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
|
|
if (mob.guardCaptain == null && mob.isNecroPet() == false && mob.isSiege() == false) |
|
|
|
|
if (mob.guardCaptain == null && !mob.isNecroPet() && !mob.isSiege()) |
|
|
|
|
if (ZoneManager.seaFloor.zoneMobSet.contains(mob)) |
|
|
|
|
mob.killCharacter("no owner"); |
|
|
|
|
|
|
|
|
@ -936,7 +929,7 @@ public class MobAI {
@@ -936,7 +929,7 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
//recover health
|
|
|
|
|
|
|
|
|
|
if (mob.getTimestamps().containsKey("HEALTHRECOVERED") == false) |
|
|
|
|
if (!mob.getTimestamps().containsKey("HEALTHRECOVERED")) |
|
|
|
|
mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis()); |
|
|
|
|
|
|
|
|
|
if (mob.isSit() && mob.getTimeStamp("HEALTHRECOVERED") < System.currentTimeMillis() + 3000) |
|
|
|
@ -961,7 +954,7 @@ public class MobAI {
@@ -961,7 +954,7 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
if (mob.getCombatTarget() == null) |
|
|
|
|
safeGuardAggro(mob); |
|
|
|
|
else if (mob.getCombatTarget().isAlive() == false) |
|
|
|
|
else if (!mob.getCombatTarget().isAlive()) |
|
|
|
|
safeGuardAggro(mob); |
|
|
|
|
|
|
|
|
|
checkForAttack(mob); |
|
|
|
@ -976,7 +969,7 @@ public class MobAI {
@@ -976,7 +969,7 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
//check for players that can be aggroed if mob is agressive and has no target
|
|
|
|
|
|
|
|
|
|
if (mob.getCombatTarget() != null && mob.playerAgroMap.containsKey(mob.getCombatTarget().getObjectUUID()) == false) |
|
|
|
|
if (mob.getCombatTarget() != null && !mob.playerAgroMap.containsKey(mob.getCombatTarget().getObjectUUID())) |
|
|
|
|
mob.setCombatTarget(null); |
|
|
|
|
|
|
|
|
|
if (mob.behaviourType.isAgressive) { |
|
|
|
@ -1021,9 +1014,7 @@ public class MobAI {
@@ -1021,9 +1014,7 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
// Defer to captain if possible for current target
|
|
|
|
|
|
|
|
|
|
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION) && |
|
|
|
|
mob.guardCaptain.isAlive() |
|
|
|
|
&& mob.guardCaptain.combatTarget != null) { |
|
|
|
|
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION) && mob.guardCaptain.isAlive() && mob.guardCaptain.combatTarget != null) { |
|
|
|
|
mob.setCombatTarget(mob.guardCaptain.combatTarget); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -1056,7 +1047,7 @@ public class MobAI {
@@ -1056,7 +1047,7 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
// No aggro for this player
|
|
|
|
|
|
|
|
|
|
if (guardCanAggro(mob, loadedPlayer) == false) |
|
|
|
|
if (!guardCanAggro(mob, loadedPlayer)) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (MovementUtilities.inRangeToAggro(mob, loadedPlayer) && mob.getCombatTarget() == null) { |
|
|
|
@ -1090,12 +1081,12 @@ public class MobAI {
@@ -1090,12 +1081,12 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
|
|
if (ConfigManager.MB_RULESET.getValue().equals("LORE") && target.guild.equals(Guild.getErrantGuild()) == false) { |
|
|
|
|
if(mob.guild.charter.equals(target.guild.charter) == true) |
|
|
|
|
if (ConfigManager.MB_RULESET.getValue().equals("LORE") && !target.guild.equals(Guild.getErrantGuild())) { |
|
|
|
|
if (mob.guild.charter.equals(target.guild.charter)) |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (mob.guardedCity.cityOutlaws.contains(target.getObjectUUID()) == true) |
|
|
|
|
if (mob.guardedCity.cityOutlaws.contains(target.getObjectUUID())) |
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
if (mob.getGuild().getNation().equals(target.getGuild().getNation())) |
|
|
|
@ -1157,7 +1148,7 @@ public class MobAI {
@@ -1157,7 +1148,7 @@ public class MobAI {
|
|
|
|
|
//early exit for a mob who is already moving to a patrol point
|
|
|
|
|
//while mob moving, update lastPatrolTime so that when they stop moving the 10 second timer can begin
|
|
|
|
|
|
|
|
|
|
if (mob.isMoving() == true) { |
|
|
|
|
if (mob.isMoving()) { |
|
|
|
|
mob.stopPatrolTime = System.currentTimeMillis(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -1185,7 +1176,7 @@ public class MobAI {
@@ -1185,7 +1176,7 @@ public class MobAI {
|
|
|
|
|
|
|
|
|
|
//make sure mob is out of combat stance
|
|
|
|
|
|
|
|
|
|
if (minion.despawned == false) { |
|
|
|
|
if (!minion.despawned) { |
|
|
|
|
if (MovementUtilities.canMove(minion)) { |
|
|
|
|
Vector3f minionOffset = mbEnums.FormationType.getOffset(2, mob.minions.indexOf(minionUUID) + 3); |
|
|
|
|
minion.updateLocation(); |
|
|
|
@ -1218,9 +1209,9 @@ public class MobAI {
@@ -1218,9 +1209,9 @@ public class MobAI {
|
|
|
|
|
if (potentialTarget.equals(mob.getCombatTarget())) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (ConfigManager.MB_RULESET.getValue().equals("LORE") && potentialTarget.guild.equals(Guild.getErrantGuild()) == false) { |
|
|
|
|
if(mob.guild.charter.equals(potentialTarget.guild.charter) == true) |
|
|
|
|
continue; |
|
|
|
|
if (ConfigManager.MB_RULESET.getValue().equals("LORE") && !potentialTarget.guild.equals(Guild.getErrantGuild())) { |
|
|
|
|
if (mob.guild.charter.equals(potentialTarget.guild.charter)) |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (potentialTarget != null && mob.playerAgroMap.get(potentialTarget.getObjectUUID()).floatValue() > CurrentHateValue && MovementUtilities.inRangeToAggro(mob, potentialTarget)) { |
|
|
|
|