@ -18,17 +18,16 @@ import engine.mobileAI.Threads.MobAIThread;
import engine.mobileAI.utilities.CombatUtilities ;
import engine.mobileAI.utilities.CombatUtilities ;
import engine.mobileAI.utilities.MovementUtilities ;
import engine.mobileAI.utilities.MovementUtilities ;
import engine.net.DispatchMessage ;
import engine.net.DispatchMessage ;
import engine.net.client.msg.PerformActionMsg ;
import engine.net.client.msg.PowerProjectileMsg ;
import engine.net.client.msg.PowerProjectileMsg ;
import engine.net.client.msg.UpdateStateMsg ;
import engine.objects.* ;
import engine.objects.* ;
import engine.powers.ActionsBase ;
import engine.powers.PowersBase ;
import engine.powers.PowersBase ;
import engine.server.MBServerStatics ;
import engine.server.MBServerStatics ;
import org.pmw.tinylog.Logger ;
import org.pmw.tinylog.Logger ;
import java.util.ArrayList ;
import java.util.HashSet ;
import java.util.HashSet ;
import java.util.Map.Entry ;
import java.util.Map.Entry ;
import java.util.Objects ;
import java.util.concurrent.ConcurrentHashMap ;
import java.util.concurrent.ConcurrentHashMap ;
import java.util.concurrent.ThreadLocalRandom ;
import java.util.concurrent.ThreadLocalRandom ;
@ -54,18 +53,6 @@ public class MobAI {
return ;
return ;
}
}
}
}
if ( target . getObjectType ( ) = = Enum . GameObjectType . PlayerCharacter & & canCast ( mob ) ) {
if ( mob . isPlayerGuard ( ) = = false & & MobCast ( mob ) ) {
mob . updateLocation ( ) ;
return ;
}
if ( mob . isPlayerGuard ( ) = = true & & GuardCast ( mob ) ) {
mob . updateLocation ( ) ;
return ;
}
}
if ( ! CombatUtilities . inRangeToAttack ( mob , target ) )
if ( ! CombatUtilities . inRangeToAttack ( mob , target ) )
return ;
return ;
@ -85,8 +72,6 @@ public class MobAI {
break ;
break ;
}
}
mob . updateLocation ( ) ;
} catch ( Exception e ) {
} catch ( Exception e ) {
Logger . info ( mob . getObjectUUID ( ) + " " + mob . getName ( ) + " Failed At: AttackTarget" + " " + e . getMessage ( ) ) ;
Logger . info ( mob . getObjectUUID ( ) + " " + mob . getName ( ) + " Failed At: AttackTarget" + " " + e . getMessage ( ) ) ;
}
}
@ -148,7 +133,7 @@ public class MobAI {
}
}
if ( target . getPet ( ) ! = null )
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 ) ;
target . getPet ( ) . setCombatTarget ( mob ) ;
} catch ( Exception e ) {
} catch ( Exception e ) {
@ -251,7 +236,7 @@ public class MobAI {
if ( target . isAlive ( ) )
if ( target . isAlive ( ) )
target . setCombatTarget ( mob ) ;
target . setCombatTarget ( mob ) ;
if ( target . isPet ( ) & & target . isAlive ( ) = = false & & target . guardCaptain . isAlive ( ) = = true ) {
if ( target . isPet ( ) & & ! target . isAlive ( ) & & target . guardCaptain . isAlive ( ) ) {
mob . setCombatTarget ( target . guardCaptain ) ;
mob . setCombatTarget ( target . guardCaptain ) ;
}
}
if ( mob . isPet ( ) ) {
if ( mob . isPet ( ) ) {
@ -272,7 +257,7 @@ public class MobAI {
//early exit while waiting to patrol again
//early exit while waiting to patrol again
if ( mob . stopPatrolTime + ( patrolDelay * 1000 ) > System . currentTimeMillis ( ) )
if ( mob . stopPatrolTime + ( patrolDelay * 1000L ) > System . currentTimeMillis ( ) )
return ;
return ;
//guard captains inherit barracks patrol points dynamically
//guard captains inherit barracks patrol points dynamically
@ -302,7 +287,7 @@ public class MobAI {
//make sure mob is out of combat stance
//make sure mob is out of combat stance
if ( minion . getKey ( ) . despawned = = false ) {
if ( ! minion . getKey ( ) . despawned ) {
if ( MovementUtilities . canMove ( minion . getKey ( ) ) ) {
if ( MovementUtilities . canMove ( minion . getKey ( ) ) ) {
Vector3f minionOffset = Formation . getOffset ( 2 , minion . getValue ( ) + 3 ) ;
Vector3f minionOffset = Formation . getOffset ( 2 , minion . getValue ( ) + 3 ) ;
minion . getKey ( ) . updateLocation ( ) ;
minion . getKey ( ) . updateLocation ( ) ;
@ -315,253 +300,6 @@ public class MobAI {
}
}
}
}
public static boolean canCast ( Mob mob ) {
return false ;
//try {
// Performs validation to determine if a
// mobile in the proper state to cast.
//if (mob == null)
// return false;
//if(mob.isPlayerGuard == true){
/// int contractID;
// if (mob.behaviourType.equals(Enum.MobBehaviourType.GuardMinion))
// contractID = mob.guardCaptain.contract.getContractID();
// else
// contractID = mob.contract.getContractID();
// if(Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false)
// return false;
//}
//if (mob.mobPowers.isEmpty())
// return false;
//if (!mob.canSee((PlayerCharacter) mob.getCombatTarget())) {
// mob.setCombatTarget(null);
// return false;
// }
// if (mob.nextCastTime == 0)
// mob.nextCastTime = System.currentTimeMillis();
// return mob.nextCastTime >= System.currentTimeMillis();
//} catch (Exception e) {
// Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: canCast" + " " + e.getMessage());
//}
//return false;
}
public static boolean MobCast ( Mob mob ) {
try {
// Method picks a random spell from a mobile's list of powers
// and casts it on the current target (or itself). Validation
// (including empty lists) is done previously within canCast();
ArrayList < Integer > powerTokens ;
ArrayList < Integer > purgeTokens ;
AbstractCharacter target = ( AbstractCharacter ) mob . getCombatTarget ( ) ;
if ( mob . behaviourType . callsForHelp )
MobCallForHelp ( mob ) ;
// Generate a list of tokens from the mob powers for this mobile.
powerTokens = new ArrayList < > ( mob . mobPowers . keySet ( ) ) ;
purgeTokens = new ArrayList < > ( ) ;
// If player has this effect on them currently then remove
// this token from our list.
for ( int powerToken : powerTokens ) {
PowersBase powerBase = PowersManager . getPowerByToken ( powerToken ) ;
for ( ActionsBase actionBase : powerBase . getActions ( ) ) {
String stackType = actionBase . stackType ;
if ( target . getEffects ( ) ! = null & & target . getEffects ( ) . containsKey ( stackType ) )
purgeTokens . add ( powerToken ) ;
}
}
powerTokens . removeAll ( purgeTokens ) ;
// Sanity check
if ( powerTokens . isEmpty ( ) )
return false ;
// Pick random spell from our list of powers
int powerToken = powerTokens . get ( ThreadLocalRandom . current ( ) . nextInt ( powerTokens . size ( ) ) ) ;
int powerRank = mob . mobPowers . get ( powerToken ) ;
PowersBase mobPower = PowersManager . getPowerByToken ( powerToken ) ;
//check for hit-roll
if ( mobPower . requiresHitRoll )
if ( CombatUtilities . triggerDefense ( mob , mob . getCombatTarget ( ) ) )
return false ;
// Cast the spell
if ( CombatUtilities . inRange2D ( mob , mob . getCombatTarget ( ) , mobPower . getRange ( ) ) ) {
PerformActionMsg msg ;
if ( ! mobPower . isHarmful ( ) | | mobPower . targetSelf ) {
PowersManager . useMobPower ( mob , mob , mobPower , powerRank ) ;
msg = PowersManager . createPowerMsg ( mobPower , powerRank , mob , mob ) ;
} else {
PowersManager . useMobPower ( mob , target , mobPower , powerRank ) ;
msg = PowersManager . createPowerMsg ( mobPower , powerRank , mob , target ) ;
}
msg . setUnknown04 ( 2 ) ;
PowersManager . finishUseMobPower ( msg , mob , 0 , 0 ) ;
long randomCooldown = ( long ) ( ( ThreadLocalRandom . current ( ) . nextInt ( 10 , 15 ) * 1000 ) * MobAIThread . AI_CAST_FREQUENCY ) ;
mob . nextCastTime = System . currentTimeMillis ( ) + randomCooldown ;
return true ;
}
} catch ( Exception e ) {
Logger . info ( mob . getObjectUUID ( ) + " " + mob . getName ( ) + " Failed At: MobCast" + " " + e . getMessage ( ) ) ;
}
return false ;
}
public static boolean GuardCast ( Mob mob ) {
try {
// Method picks a random spell from a mobile's list of powers
// and casts it on the current target (or itself). Validation
// (including empty lists) is done previously within canCast();
ArrayList < Integer > powerTokens ;
ArrayList < Integer > purgeTokens ;
AbstractCharacter target = ( AbstractCharacter ) mob . getCombatTarget ( ) ;
if ( mob . behaviourType . callsForHelp )
MobCallForHelp ( mob ) ;
// Generate a list of tokens from the mob powers for this mobile.
powerTokens = new ArrayList < > ( mob . mobPowers . keySet ( ) ) ;
purgeTokens = new ArrayList < > ( ) ;
// If player has this effect on them currently then remove
// this token from our list.
for ( int powerToken : powerTokens ) {
PowersBase powerBase = PowersManager . getPowerByToken ( powerToken ) ;
for ( ActionsBase actionBase : powerBase . getActions ( ) ) {
String stackType = actionBase . stackType ;
if ( target . getEffects ( ) ! = null & & target . getEffects ( ) . containsKey ( stackType ) )
purgeTokens . add ( powerToken ) ;
}
}
powerTokens . removeAll ( purgeTokens ) ;
// Sanity check
if ( powerTokens . isEmpty ( ) )
return false ;
int powerToken = 0 ;
int nukeRoll = ThreadLocalRandom . current ( ) . nextInt ( 1 , 100 ) ;
if ( nukeRoll < 55 ) {
//use direct damage spell
powerToken = powerTokens . get ( powerTokens . size ( ) - 1 ) ;
} else {
//use random spell
powerToken = powerTokens . get ( ThreadLocalRandom . current ( ) . nextInt ( powerTokens . size ( ) ) ) ;
}
int powerRank = 1 ;
switch ( mob . getRank ( ) ) {
case 1 :
powerRank = 10 ;
break ;
case 2 :
powerRank = 15 ;
break ;
case 3 :
powerRank = 20 ;
break ;
case 4 :
powerRank = 25 ;
break ;
case 5 :
powerRank = 30 ;
break ;
case 6 :
powerRank = 35 ;
break ;
case 7 :
powerRank = 40 ;
break ;
}
PowersBase mobPower = PowersManager . getPowerByToken ( powerToken ) ;
//check for hit-roll
if ( mobPower . requiresHitRoll )
if ( CombatUtilities . triggerDefense ( mob , mob . getCombatTarget ( ) ) )
return false ;
// Cast the spell
if ( CombatUtilities . inRange2D ( mob , mob . getCombatTarget ( ) , mobPower . getRange ( ) ) ) {
PerformActionMsg msg ;
if ( ! mobPower . isHarmful ( ) | | mobPower . targetSelf ) {
if ( mobPower . category . equals ( "DISPEL" ) ) {
PowersManager . useMobPower ( mob , target , mobPower , powerRank ) ;
msg = PowersManager . createPowerMsg ( mobPower , powerRank , mob , target ) ;
} else {
PowersManager . useMobPower ( mob , mob , mobPower , powerRank ) ;
msg = PowersManager . createPowerMsg ( mobPower , powerRank , mob , mob ) ;
}
} else {
PowersManager . useMobPower ( mob , target , mobPower , powerRank ) ;
msg = PowersManager . createPowerMsg ( mobPower , powerRank , mob , target ) ;
}
msg . setUnknown04 ( 2 ) ;
PowersManager . finishUseMobPower ( msg , mob , 0 , 0 ) ;
long randomCooldown = ( long ) ( ( ThreadLocalRandom . current ( ) . nextInt ( 10 , 15 ) * 1000 ) * MobAIThread . AI_CAST_FREQUENCY ) ;
mob . nextCastTime = System . currentTimeMillis ( ) + randomCooldown ;
return true ;
}
} catch ( Exception e ) {
Logger . info ( mob . getObjectUUID ( ) + " " + mob . getName ( ) + " Failed At: MobCast" + " " + e . getMessage ( ) ) ;
}
return false ;
}
public static void MobCallForHelp ( Mob mob ) {
public static void MobCallForHelp ( Mob mob ) {
try {
try {
@ -606,7 +344,7 @@ public class MobAI {
if ( mob = = null )
if ( mob = = null )
return ;
return ;
if ( mob . getTimestamps ( ) . containsKey ( "lastExecution" ) = = false )
if ( ! mob . getTimestamps ( ) . containsKey ( "lastExecution" ) )
mob . getTimestamps ( ) . put ( "lastExecution" , System . currentTimeMillis ( ) ) ;
mob . getTimestamps ( ) . put ( "lastExecution" , System . currentTimeMillis ( ) ) ;
if ( System . currentTimeMillis ( ) < mob . getTimeStamp ( "lastExecution" ) )
if ( System . currentTimeMillis ( ) < mob . getTimeStamp ( "lastExecution" ) )
@ -626,11 +364,11 @@ public class MobAI {
if ( mob . despawned & & mob . isPlayerGuard ) {
if ( mob . despawned & & mob . isPlayerGuard ) {
if ( mob . behaviourType . equals ( Enum . MobBehaviourType . GuardMinion ) ) {
if ( mob . behaviourType . equals ( Enum . MobBehaviourType . 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
//minions don't respawn while guard captain is dead
if ( mob . isAlive ( ) = = false ) {
if ( ! mob . isAlive ( ) ) {
mob . deathTime = System . currentTimeMillis ( ) ;
mob . deathTime = System . currentTimeMillis ( ) ;
return ;
return ;
}
}
@ -642,7 +380,7 @@ public class MobAI {
//check to send mob home for player guards to prevent exploit of dragging guards away and then teleporting
//check to send mob home for player guards to prevent exploit of dragging guards away and then teleporting
if ( mob . behaviourType . equals ( Enum . MobBehaviourType . Pet1 ) = = false )
if ( ! mob . behaviourType . equals ( Enum . MobBehaviourType . Pet1 ) )
CheckToSendMobHome ( mob ) ;
CheckToSendMobHome ( mob ) ;
return ;
return ;
@ -656,30 +394,16 @@ public class MobAI {
}
}
//no players loaded, no need to proceed
//no players loaded, no need to proceed
if ( mob . playerAgroMap . isEmpty ( ) ) {
if ( mob . playerAgroMap . isEmpty ( ) ) {
//attempt to reload agro map
HashSet < AbstractWorldObject > players = WorldGrid . getObjectsInRangePartial ( mob . loc , mob . getAggroRange ( ) , MBServerStatics . MASK_PLAYER ) ;
if ( players . size ( ) > 0 ) {
for ( AbstractWorldObject player : players ) {
if ( mob . playerAgroMap . containsKey ( player . getObjectUUID ( ) ) = = false ) {
PlayerCharacter pc = ( PlayerCharacter ) player ;
mob . playerAgroMap . put ( pc . getObjectUUID ( ) , 0 . 0f ) ;
}
}
}
if ( mob . getCombatTarget ( ) ! = null )
mob . setCombatTarget ( null ) ;
return ;
return ;
}
}
if ( mob . behaviourType . equals ( Enum . MobBehaviourType . Pet1 ) = = false )
if ( ! mob . behaviourType . equals ( Enum . MobBehaviourType . Pet1 ) )
CheckToSendMobHome ( mob ) ;
CheckToSendMobHome ( mob ) ;
if ( mob . getCombatTarget ( ) ! = null ) {
if ( mob . getCombatTarget ( ) ! = null ) {
if ( mob . getCombatTarget ( ) . isAlive ( ) = = false ) {
if ( ! mob . getCombatTarget ( ) . isAlive ( ) ) {
mob . setCombatTarget ( null ) ;
mob . setCombatTarget ( null ) ;
return ;
return ;
}
}
@ -688,19 +412,46 @@ public class MobAI {
PlayerCharacter target = ( PlayerCharacter ) mob . getCombatTarget ( ) ;
PlayerCharacter target = ( PlayerCharacter ) mob . getCombatTarget ( ) ;
if ( mob . playerAgroMap . containsKey ( target . getObjectUUID ( ) ) = = false ) {
if ( ! mob . playerAgroMap . containsKey ( target . getObjectUUID ( ) ) ) {
mob . setCombatTarget ( null ) ;
mob . setCombatTarget ( null ) ;
return ;
return ;
}
}
if ( mob . canSee ( ( PlayerCharacter ) mob . getCombatTarget ( ) ) = = false ) {
if ( ! mob . canSee ( ( PlayerCharacter ) mob . getCombatTarget ( ) ) ) {
mob . setCombatTarget ( null ) ;
mob . setCombatTarget ( null ) ;
return ;
return ;
}
}
}
}
}
}
if ( mob . isMoving ( ) ) {
mob . updateLocation ( ) ;
}
if ( ! mob . isPet ( ) ) {
boolean combatState = mob . isCombat ( ) ;
mob . setCombat ( mob . combatTarget ! = null ) ;
if ( combatState ! = mob . isCombat ( ) ) {
//send message to update combat state
UpdateStateMsg rwss = new UpdateStateMsg ( ) ;
rwss . setPlayer ( mob ) ;
DispatchMessage . sendToAllInRange ( mob , rwss ) ;
}
boolean walking = mob . isWalk ( ) ;
mob . setWalkMode ( mob . combatTarget = = null ) ;
if ( walking ! = mob . isWalk ( ) ) {
//send message to update run/walk state
MovementManager . sendRWSSMsg ( mob ) ;
}
} else {
boolean walking = mob . isWalk ( ) ;
mob . setWalkMode ( mob . guardCaptain . isWalk ( ) ) ;
if ( walking ! = mob . isWalk ( ) ) {
//send message to update run/walk state
MovementManager . sendRWSSMsg ( mob ) ;
}
}
switch ( mob . behaviourType ) {
switch ( mob . behaviourType ) {
case GuardCaptain :
case GuardCaptain :
GuardCaptainLogic ( mob ) ;
GuardCaptainLogic ( mob ) ;
@ -735,41 +486,34 @@ public class MobAI {
if ( ! aiAgent . isAlive ( ) )
if ( ! aiAgent . isAlive ( ) )
return ;
return ;
if ( ! pets ) {
if ( ! pets ) {
ConcurrentHashMap < Integer , Float > loadedPlayers = aiAgent . playerAgroMap ;
ConcurrentHashMap < Integer , Float > loadedPlayers = aiAgent . playerAgroMap ;
for ( Integer playerEntry : loadedPlayers . keySet ( ) ) {
for ( Entry playerEntry : loadedPlayers . entrySet ( ) ) {
PlayerCharacter loadedPlayer = PlayerCharacter . getFromCache ( playerEntry ) ;
int playerID = ( int ) playerEntry . getKey ( ) ;
PlayerCharacter loadedPlayer = PlayerCharacter . getFromCache ( playerID ) ;
//Player is null, let's remove them from the list.
//Player is null, let's remove them from the list.
if ( loadedPlayer = = null ) {
if ( loadedPlayer = = null ) {
loadedPlayers . remove ( playerID ) ;
loadedPlayers . remove ( playerEntry ) ;
continue ;
continue ;
}
}
//Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
//Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
if ( ! loadedPlayer . isAlive ( ) | | loadedPlayer . getHidden ( ) > 0 ) {
if ( ! loadedPlayer . isAlive ( ) | | loadedPlayer . getHidden ( ) > 0 ) {
loadedPlayers . remove ( playerID ) ;
loadedPlayers . remove ( playerEntry ) ;
continue ;
continue ;
}
}
//Can't see target, skip aggro.
//Can't see target, skip aggro.
if ( ! aiAgent . canSee ( loadedPlayer ) )
if ( ! aiAgent . canSee ( loadedPlayer ) )
continue ;
continue ;
// No aggro for this race type
// No aggro for this race type
if ( aiAgent . notEnemy . size ( ) > 0 & & aiAgent . notEnemy . contains ( loadedPlayer . getRace ( ) . getRaceType ( ) . getMonsterType ( ) ) )
if ( aiAgent . notEnemy . size ( ) > 0 & & aiAgent . notEnemy . contains ( loadedPlayer . getRace ( ) . getRaceType ( ) . getMonsterType ( ) ) = = true )
continue ;
continue ;
//mob has enemies and this player race is not it
//mob has enemies and this player race is not it
if ( aiAgent . enemy . size ( ) > 0 & & aiAgent . enemy . contains ( loadedPlayer . getRace ( ) . getRaceType ( ) . getMonsterType ( ) ) = = false )
if ( aiAgent . enemy . size ( ) > 0 & & ! aiAgent . enemy . contains ( loadedPlayer . getRace ( ) . getRaceType ( ) . getMonsterType ( ) ) )
continue ;
continue ;
if ( MovementUtilities . inRangeToAggro ( aiAgent , loadedPlayer ) ) {
if ( MovementUtilities . inRangeToAggro ( aiAgent , loadedPlayer ) ) {
@ -782,7 +526,7 @@ public class MobAI {
//look for pets to aggro if no players found to aggro
//look for pets to aggro if no players found to aggro
HashSet < AbstractWorldObject > awoList = WorldGrid . getObjectsInRangePartial ( aiAgent , MobAIThread . AI_BASE_AGGRO_RANGE , MBServerStatics . MASK_PET ) ;
HashSet < AbstractWorldObject > awoList = WorldGrid . getObjectsInRangePartial ( aiAgent , MobAIThread . AI_BASE_AGGRO_RANGE , MBServerStatics . MASK_MOB ) ;
for ( AbstractWorldObject awoMob : awoList ) {
for ( AbstractWorldObject awoMob : awoList ) {
@ -791,6 +535,9 @@ public class MobAI {
if ( aiAgent . equals ( awoMob ) )
if ( aiAgent . equals ( awoMob ) )
continue ;
continue ;
if ( ! ( ( Mob ) awoMob ) . isPet ( ) )
continue ;
Mob aggroMob = ( Mob ) awoMob ;
Mob aggroMob = ( Mob ) awoMob ;
aiAgent . setCombatTarget ( aggroMob ) ;
aiAgent . setCombatTarget ( aggroMob ) ;
return ;
return ;
@ -806,27 +553,27 @@ public class MobAI {
return ;
return ;
try {
try {
if ( mob = = null )
return ;
if ( ! MovementUtilities . canMove ( mob ) )
if ( ! MovementUtilities . canMove ( mob ) )
return ;
return ;
mob . updateLocation ( ) ;
switch ( mob . behaviourType ) {
switch ( mob . behaviourType ) {
case Pet1 :
case Pet1 :
if ( ( PlayerCharacter ) mob . guardCaptain = = null )
if ( mob . guardCaptain = = null )
return ;
return ;
if ( ! mob . playerAgroMap . containsKey ( ( ( PlayerCharacter ) mob . guardCaptain ) . getObjectUUID ( ) ) ) {
if ( ! mob . playerAgroMap . containsKey ( mob . guardCaptain . getObjectUUID ( ) ) ) {
//mob no longer has its owner loaded, translocate pet to owner
//mob no longer has its owner loaded, translocate pet to owner
MovementManager . translocate ( mob , ( ( PlayerCharacter ) mob . guardCaptain ) . getLoc ( ) , null ) ;
MovementManager . translocate ( mob , mob . guardCaptain . getLoc ( ) , null ) ;
return ;
return ;
}
}
if ( mob . getCombatTarget ( ) = = null ) {
if ( mob . getCombatTarget ( ) = = null ) {
@ -834,11 +581,11 @@ public class MobAI {
//move back to owner
//move back to owner
if ( CombatUtilities . inRange2D ( mob , ( PlayerCharacter ) mob . guardCaptain , 6 ) )
if ( CombatUtilities . inRange2D ( mob , mob . guardCaptain , 6 ) )
return ;
return ;
mob . destination = ( ( PlayerCharacter ) mob . guardCaptain ) . getLoc ( ) ;
mob . destination = mob . guardCaptain . getLoc ( ) ;
MovementUtilities . moveToLocation ( mob , mob . destination , 5 ) ;
MovementUtilities . moveToLocation ( mob , mob . destination , 5 ) ;
} else
} else
chaseTarget ( mob ) ;
chaseTarget ( mob ) ;
@ -886,7 +633,6 @@ public class MobAI {
if ( System . currentTimeMillis ( ) > aiAgent . deathTime + MBServerStatics . DESPAWN_TIMER_WITH_LOOT ) {
if ( System . currentTimeMillis ( ) > aiAgent . deathTime + MBServerStatics . DESPAWN_TIMER_WITH_LOOT ) {
aiAgent . despawn ( ) ;
aiAgent . despawn ( ) ;
aiAgent . deathTime = System . currentTimeMillis ( ) ;
aiAgent . deathTime = System . currentTimeMillis ( ) ;
return ;
}
}
//No items in inventory.
//No items in inventory.
} else {
} else {
@ -895,14 +641,12 @@ public class MobAI {
if ( System . currentTimeMillis ( ) > aiAgent . deathTime + MBServerStatics . DESPAWN_TIMER_ONCE_LOOTED ) {
if ( System . currentTimeMillis ( ) > aiAgent . deathTime + MBServerStatics . DESPAWN_TIMER_ONCE_LOOTED ) {
aiAgent . despawn ( ) ;
aiAgent . despawn ( ) ;
aiAgent . deathTime = System . currentTimeMillis ( ) ;
aiAgent . deathTime = System . currentTimeMillis ( ) ;
return ;
}
}
//Mob never had Loot.
//Mob never had Loot.
} else {
} else {
if ( System . currentTimeMillis ( ) > aiAgent . deathTime + MBServerStatics . DESPAWN_TIMER ) {
if ( System . currentTimeMillis ( ) > aiAgent . deathTime + MBServerStatics . DESPAWN_TIMER ) {
aiAgent . despawn ( ) ;
aiAgent . despawn ( ) ;
aiAgent . deathTime = System . currentTimeMillis ( ) ;
aiAgent . deathTime = System . currentTimeMillis ( ) ;
return ;
}
}
}
}
}
}
@ -922,14 +666,14 @@ public class MobAI {
//checks if mob can attack based on attack timer and range
//checks if mob can attack based on attack timer and range
if ( mob . isAlive ( ) = = false )
if ( ! mob . isAlive ( ) )
return ;
return ;
if ( mob . getCombatTarget ( ) = = null )
if ( mob . getCombatTarget ( ) = = null )
return ;
return ;
if ( mob . getCombatTarget ( ) . getObjectType ( ) . equals ( Enum . GameObjectType . PlayerCharacter ) & & MovementUtilities . inRangeDropAggro ( mob , ( PlayerCharacter ) mob . getCombatTarget ( ) ) = = false & &
if ( mob . getCombatTarget ( ) . getObjectType ( ) . equals ( Enum . GameObjectType . PlayerCharacter ) & & ! MovementUtilities . inRangeDropAggro ( mob , ( PlayerCharacter ) mob . getCombatTarget ( ) ) & &
mob . behaviourType . equals ( Enum . MobBehaviourType . Pet1 ) = = false ) {
! mob . behaviourType . equals ( Enum . MobBehaviourType . Pet1 ) ) {
mob . setCombatTarget ( null ) ;
mob . setCombatTarget ( null ) ;
return ;
return ;
@ -955,14 +699,11 @@ public class MobAI {
}
}
}
}
//if (mob.getCombatTarget() != null && CombatUtilities.inRange2D(mob, mob.getCombatTarget(), MobAIThread.AI_BASE_AGGRO_RANGE * 0.5f))
//return;
if ( mob . isPlayerGuard ( ) & & ! mob . despawned ) {
if ( mob . isPlayerGuard ( ) & & ! mob . despawned ) {
City current = ZoneManager . getCityAtLocation ( mob . getLoc ( ) ) ;
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 ) ;
PowersBase recall = PowersManager . getPowerByToken ( - 1994153779 ) ;
PowersManager . useMobPower ( mob , mob , recall , 40 ) ;
PowersManager . useMobPower ( mob , mob , recall , 40 ) ;
@ -978,14 +719,13 @@ public class MobAI {
}
}
}
}
}
}
} else if ( MovementUtilities . inRangeOfBindLocation ( mob ) = = false ) {
} else if ( ! MovementUtilities . inRangeOfBindLocation ( mob ) ) {
PowersBase recall = PowersManager . getPowerByToken ( - 1994153779 ) ;
PowersBase recall = PowersManager . getPowerByToken ( - 1994153779 ) ;
PowersManager . useMobPower ( mob , mob , recall , 40 ) ;
PowersManager . useMobPower ( mob , mob , recall , 40 ) ;
mob . setCombatTarget ( null ) ;
mob . setCombatTarget ( null ) ;
for ( Integer playerEntry : mob . playerAgroMap . keySet ( ) )
mob . playerAgroMap . replaceAll ( ( e , v ) - > 0f ) ;
mob . playerAgroMap . put ( playerEntry , 0f ) ;
}
}
} catch ( Exception e ) {
} catch ( Exception e ) {
Logger . info ( mob . getObjectUUID ( ) + " " + mob . getName ( ) + " Failed At: CheckToSendMobHome" + " " + e . getMessage ( ) ) ;
Logger . info ( mob . getObjectUUID ( ) + " " + mob . getName ( ) + " Failed At: CheckToSendMobHome" + " " + e . getMessage ( ) ) ;
@ -1001,13 +741,16 @@ public class MobAI {
return ;
return ;
}
}
}
}
float rangeSquared = mob . getRange ( ) * mob . getRange ( ) ;
float range = mob . getRange ( ) ;
if ( range < 6 )
range = 6 ;
float rangeSquared = range * range ;
float distanceSquared = mob . getLoc ( ) . distanceSquared2D ( mob . getCombatTarget ( ) . getLoc ( ) ) ;
float distanceSquared = mob . getLoc ( ) . distanceSquared2D ( mob . getCombatTarget ( ) . getLoc ( ) ) ;
if ( mob . isMoving ( ) = = true & & distanceSquared < rangeSquared - 50 ) {
if ( mob . isMoving ( ) & & distanceSquared < rangeSquared - 50 ) {
mob . destination = mob . getLoc ( ) ;
mob . destination = mob . getLoc ( ) ;
MovementUtilities . moveToLocation ( mob , mob . destination , 0 ) ;
MovementUtilities . moveToLocation ( mob , mob . destination , 0 ) ;
} else if ( CombatUtilities . inRange2D ( mob , mob . getCombatTarget ( ) , mob . getRange ( ) ) = = false ) {
} else if ( ! CombatUtilities . inRange2D ( mob , mob . getCombatTarget ( ) , mob . getRange ( ) ) ) {
if ( mob . getRange ( ) > 15 ) {
if ( mob . getRange ( ) > 15 ) {
mob . destination = mob . getCombatTarget ( ) . getLoc ( ) ;
mob . destination = mob . getCombatTarget ( ) . getLoc ( ) ;
MovementUtilities . moveToLocation ( mob , mob . destination , 0 ) ;
MovementUtilities . moveToLocation ( mob , mob . destination , 0 ) ;
@ -1029,7 +772,6 @@ public class MobAI {
}
}
}
}
mob . updateMovementState ( ) ;
mob . updateMovementState ( ) ;
mob . updateLocation ( ) ;
} catch ( Exception e ) {
} catch ( Exception e ) {
Logger . info ( mob . getObjectUUID ( ) + " " + mob . getName ( ) + " Failed At: chaseTarget" + " " + e . getMessage ( ) ) ;
Logger . info ( mob . getObjectUUID ( ) + " " + mob . getName ( ) + " Failed At: chaseTarget" + " " + e . getMessage ( ) ) ;
}
}
@ -1044,7 +786,7 @@ public class MobAI {
//dont scan self.
//dont scan self.
if ( mob . equals ( awoMob ) | | ( mob . agentType . equals ( Enum . AIAgentType . GUARD ) ) = = true | | awoMob . getObjectType ( ) . equals ( Enum . GameObjectType . PlayerCharacter ) )
if ( mob . equals ( awoMob ) | | ( mob . agentType . equals ( Enum . AIAgentType . GUARD ) ) | | awoMob . getObjectType ( ) . equals ( Enum . GameObjectType . PlayerCharacter ) )
continue ;
continue ;
Mob aggroMob = ( Mob ) awoMob ;
Mob aggroMob = ( Mob ) awoMob ;
@ -1073,18 +815,6 @@ public class MobAI {
if ( mob . getCombatTarget ( ) = = null )
if ( mob . getCombatTarget ( ) = = null )
CheckForPlayerGuardAggro ( mob ) ;
CheckForPlayerGuardAggro ( mob ) ;
AbstractWorldObject newTarget = ChangeTargetFromHateValue ( mob ) ;
if ( newTarget ! = null ) {
if ( newTarget . getObjectType ( ) . equals ( Enum . GameObjectType . PlayerCharacter ) ) {
if ( GuardCanAggro ( mob , ( PlayerCharacter ) newTarget ) )
mob . setCombatTarget ( newTarget ) ;
} else
mob . setCombatTarget ( newTarget ) ;
}
CheckMobMovement ( mob ) ;
CheckMobMovement ( mob ) ;
CheckForAttack ( mob ) ;
CheckForAttack ( mob ) ;
} catch ( Exception e ) {
} catch ( Exception e ) {
@ -1099,19 +829,6 @@ public class MobAI {
if ( mob . getCombatTarget ( ) = = null ) {
if ( mob . getCombatTarget ( ) = = null ) {
CheckForPlayerGuardAggro ( mob ) ;
CheckForPlayerGuardAggro ( mob ) ;
} else {
AbstractWorldObject newTarget = ChangeTargetFromHateValue ( mob ) ;
if ( newTarget ! = null ) {
if ( newTarget . getObjectType ( ) . equals ( Enum . GameObjectType . PlayerCharacter ) ) {
if ( GuardCanAggro ( mob , ( PlayerCharacter ) newTarget ) )
mob . setCombatTarget ( newTarget ) ;
} else
mob . setCombatTarget ( newTarget ) ;
}
}
}
} else {
} else {
if ( mob . guardCaptain . getCombatTarget ( ) ! = null )
if ( mob . guardCaptain . getCombatTarget ( ) ! = null )
@ -1143,7 +860,7 @@ public class MobAI {
try {
try {
if ( mob . guardCaptain = = null & & mob . isNecroPet ( ) = = false & & mob . isSiege ( ) = = false )
if ( mob . guardCaptain = = null & & ! mob . isNecroPet ( ) & & ! mob . isSiege ( ) )
if ( ZoneManager . getSeaFloor ( ) . zoneMobSet . contains ( mob ) )
if ( ZoneManager . getSeaFloor ( ) . zoneMobSet . contains ( mob ) )
mob . killCharacter ( "no owner" ) ;
mob . killCharacter ( "no owner" ) ;
@ -1154,7 +871,7 @@ public class MobAI {
//recover health
//recover health
if ( mob . getTimestamps ( ) . containsKey ( "HEALTHRECOVERED" ) = = false )
if ( ! mob . getTimestamps ( ) . containsKey ( "HEALTHRECOVERED" ) )
mob . getTimestamps ( ) . put ( "HEALTHRECOVERED" , System . currentTimeMillis ( ) ) ;
mob . getTimestamps ( ) . put ( "HEALTHRECOVERED" , System . currentTimeMillis ( ) ) ;
if ( mob . isSit ( ) & & mob . getTimeStamp ( "HEALTHRECOVERED" ) < System . currentTimeMillis ( ) + 3000 )
if ( mob . isSit ( ) & & mob . getTimeStamp ( "HEALTHRECOVERED" ) < System . currentTimeMillis ( ) + 3000 )
@ -1179,7 +896,7 @@ public class MobAI {
if ( mob . getCombatTarget ( ) = = null )
if ( mob . getCombatTarget ( ) = = null )
SafeGuardAggro ( mob ) ;
SafeGuardAggro ( mob ) ;
else if ( mob . getCombatTarget ( ) . isAlive ( ) = = false )
else if ( ! mob . getCombatTarget ( ) . isAlive ( ) )
SafeGuardAggro ( mob ) ;
SafeGuardAggro ( mob ) ;
CheckForAttack ( mob ) ;
CheckForAttack ( mob ) ;
@ -1194,30 +911,22 @@ public class MobAI {
if ( mob . combatTarget ! = null & & mob . combatTarget . getObjectType ( ) . equals ( Enum . GameObjectType . PlayerCharacter ) ) {
if ( mob . combatTarget ! = null & & mob . combatTarget . getObjectType ( ) . equals ( Enum . GameObjectType . PlayerCharacter ) ) {
PlayerCharacter tar = ( PlayerCharacter ) mob . combatTarget ;
PlayerCharacter tar = ( PlayerCharacter ) mob . combatTarget ;
if ( mob . canSee ( tar ) = = false ) {
if ( ! mob . canSee ( tar ) ) {
mob . setCombatTarget ( null ) ;
mob . setCombatTarget ( null ) ;
}
}
}
}
if ( mob . behaviourType . isAgressive ) {
if ( mob . behaviourType . isAgressive ) {
if ( mob . getCombatTarget ( ) = = null ) {
//AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
if ( mob . behaviourType = = Enum . MobBehaviourType . HamletGuard ) {
SafeGuardAggro ( mob ) ; //safehold guard
//if (newTarget != null)
} else {
// mob.setCombatTarget(newTarget);
CheckForAggro ( mob , false ) ; //normal aggro
//else {
if ( mob . combatTarget = = null )
CheckForAggro ( mob , true ) ; // look for pets if no players to aggro
if ( mob . getCombatTarget ( ) = = null ) {
if ( mob . behaviourType = = Enum . MobBehaviourType . HamletGuard ) {
SafeGuardAggro ( mob ) ; //safehold guard
} else {
CheckForAggro ( mob , false ) ; //normal aggro
if ( mob . combatTarget = = null )
CheckForAggro ( mob , true ) ; // look for pets if no players to aggro
}
}
}
}
}
//}
}
//check if mob can move for patrol or moving to target
//check if mob can move for patrol or moving to target
@ -1245,22 +954,21 @@ public class MobAI {
ConcurrentHashMap < Integer , Float > loadedPlayers = mob . playerAgroMap ;
ConcurrentHashMap < Integer , Float > loadedPlayers = mob . playerAgroMap ;
for ( Entry playerEntry : loadedPlayers . entr ySet ( ) ) {
for ( Integer playerEntry : loadedPlayers . k eySet( ) ) {
int playerID = ( int ) playerEntry . getKey ( ) ;
PlayerCharacter loadedPlayer = PlayerCharacter . getFromCache ( playerEntry ) ;
PlayerCharacter loadedPlayer = PlayerCharacter . getFromCache ( playerID ) ;
//Player is null, let's remove them from the list.
//Player is null, let's remove them from the list.
if ( loadedPlayer = = null ) {
if ( loadedPlayer = = null ) {
loadedPlayers . remove ( playerID ) ;
loadedPlayers . remove ( playerEntry ) ;
continue ;
continue ;
}
}
//Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
//Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
if ( ! loadedPlayer . isAlive ( ) ) {
if ( ! loadedPlayer . isAlive ( ) ) {
loadedPlayers . remove ( playerID ) ;
loadedPlayers . remove ( playerEntry ) ;
continue ;
continue ;
}
}
@ -1271,7 +979,7 @@ public class MobAI {
// No aggro for this player
// No aggro for this player
if ( GuardCanAggro ( mob , loadedPlayer ) = = false )
if ( ! GuardCanAggro ( mob , loadedPlayer ) )
continue ;
continue ;
if ( MovementUtilities . inRangeToAggro ( mob , loadedPlayer ) & & mob . getCombatTarget ( ) = = null ) {
if ( MovementUtilities . inRangeToAggro ( mob , loadedPlayer ) & & mob . getCombatTarget ( ) = = null ) {
@ -1292,17 +1000,17 @@ public class MobAI {
return false ;
return false ;
if ( mob . behaviourType . equals ( Enum . MobBehaviourType . GuardMinion ) ) {
if ( mob . behaviourType . equals ( Enum . MobBehaviourType . GuardMinion ) ) {
if ( ( ( Mob ) mob . guardCaptain ) . building . getCity ( ) . cityOutlaws . contains ( target . getObjectUUID ( ) ) = = true ) {
if ( Objects . requireNonNull ( mob . guardCaptain . building . getCity ( ) ) . cityOutlaws . contains ( target . getObjectUUID ( ) ) ) {
return true ;
return true ;
}
}
} else if ( mob . building . getCity ( ) . cityOutlaws . contains ( target . getObjectUUID ( ) ) = = true ) {
} else if ( Objects . requireNonNull ( mob . building . getCity ( ) ) . cityOutlaws . contains ( target . getObjectUUID ( ) ) ) {
return true ;
return true ;
}
}
//first check condemn list for aggro allowed (allies button is checked)
//first check condemn list for aggro allowed (allies button is checked)
if ( ZoneManager . getCityAtLocation ( mob . getLoc ( ) ) . getTOL ( ) . reverseKOS ) {
if ( Objects . requireNonNull ( ZoneManager . getCityAtLocation ( mob . getLoc ( ) ) ) . getTOL ( ) . reverseKOS ) {
for ( Entry < Integer , Condemned > entry : ZoneManager . getCityAtLocation ( mob . getLoc ( ) ) . getTOL ( ) . getCondemned ( ) . entrySet ( ) ) {
for ( Entry < Integer , Condemned > entry : Objects . requireNonNull ( ZoneManager . getCityAtLocation ( mob . getLoc ( ) ) ) . getTOL ( ) . getCondemned ( ) . entrySet ( ) ) {
//target is listed individually
//target is listed individually
@ -1324,7 +1032,7 @@ public class MobAI {
//allies button is not checked
//allies button is not checked
for ( Entry < Integer , Condemned > entry : ZoneManager . getCityAtLocation ( mob . getLoc ( ) ) . getTOL ( ) . getCondemned ( ) . entrySet ( ) ) {
for ( Entry < Integer , Condemned > entry : Objects . requireNonNull ( ZoneManager . getCityAtLocation ( mob . getLoc ( ) ) ) . getTOL ( ) . getCondemned ( ) . entrySet ( ) ) {
//target is listed individually
//target is listed individually
@ -1355,7 +1063,7 @@ public class MobAI {
//early exit for a mob who is already moving to a patrol point
//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
//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 ( ) ;
mob . stopPatrolTime = System . currentTimeMillis ( ) ;
return ;
return ;
}
}
@ -1381,7 +1089,7 @@ public class MobAI {
//make sure mob is out of combat stance
//make sure mob is out of combat stance
if ( minion . getKey ( ) . despawned = = false ) {
if ( ! minion . getKey ( ) . despawned ) {
if ( MovementUtilities . canMove ( minion . getKey ( ) ) ) {
if ( MovementUtilities . canMove ( minion . getKey ( ) ) ) {
Vector3f minionOffset = Formation . getOffset ( 2 , minion . getValue ( ) + 3 ) ;
Vector3f minionOffset = Formation . getOffset ( 2 , minion . getValue ( ) + 3 ) ;
minion . getKey ( ) . updateLocation ( ) ;
minion . getKey ( ) . updateLocation ( ) ;
@ -1395,40 +1103,4 @@ public class MobAI {
Logger . info ( mob . getObjectUUID ( ) + " " + mob . getName ( ) + " Failed At: randomGuardPatrolPoints" + " " + e . getMessage ( ) ) ;
Logger . info ( mob . getObjectUUID ( ) + " " + mob . getName ( ) + " Failed At: randomGuardPatrolPoints" + " " + e . getMessage ( ) ) ;
}
}
}
}
public static AbstractWorldObject ChangeTargetFromHateValue ( Mob mob ) {
if ( mob . combatTarget ! = null )
return mob . combatTarget ;
//try {
// float CurrentHateValue = 0;
// if (mob.getCombatTarget() != null && mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.Mob)){
// return mob.getCombatTarget();
// }
// if (mob.getCombatTarget() != null && mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
// CurrentHateValue = mob.playerAgroMap.get(mob.combatTarget.getObjectUUID()).floatValue();
// AbstractWorldObject mostHatedTarget = null;
// for (Entry playerEntry : mob.playerAgroMap.entrySet()) {
// PlayerCharacter potentialTarget = PlayerCharacter.getFromCache((int) playerEntry.getKey());
// if (potentialTarget.equals(mob.getCombatTarget()))
// continue;
// if (potentialTarget != null && mob.playerAgroMap.get(potentialTarget.getObjectUUID()).floatValue() > CurrentHateValue && MovementUtilities.inRangeToAggro(mob, potentialTarget)) {
// CurrentHateValue = mob.playerAgroMap.get(potentialTarget.getObjectUUID()).floatValue();
// mostHatedTarget = potentialTarget;
// }
// }
// return mostHatedTarget;
//} catch (Exception e) {
// Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: ChangeTargetFromMostHated" + " " + e.getMessage());
//}
return null ;
}
}
}