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