@ -6,6 +6,7 @@
// Magicbane Emulator Project © 2013 - 2022
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
// www.magicbane.com
package engine.ai ;
package engine.ai ;
import engine.Enum ;
import engine.Enum ;
import engine.Enum.DispatchChannel ;
import engine.Enum.DispatchChannel ;
import engine.InterestManagement.WorldGrid ;
import engine.InterestManagement.WorldGrid ;
@ -22,12 +23,15 @@ import engine.objects.*;
import engine.powers.ActionsBase ;
import engine.powers.ActionsBase ;
import engine.powers.PowersBase ;
import engine.powers.PowersBase ;
import engine.server.MBServerStatics ;
import engine.server.MBServerStatics ;
import java.util.ArrayList ;
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.concurrent.ConcurrentHashMap ;
import java.util.concurrent.ConcurrentHashMap ;
import java.util.concurrent.ThreadLocalRandom ;
import java.util.concurrent.ThreadLocalRandom ;
import static engine.math.FastMath.sqr ;
import static engine.math.FastMath.sqr ;
public class MobileFSM {
public class MobileFSM {
private static void AttackTarget ( Mob mob , AbstractWorldObject target ) {
private static void AttackTarget ( Mob mob , AbstractWorldObject target ) {
if ( mob = = null )
if ( mob = = null )
@ -58,6 +62,7 @@ public class MobileFSM {
break ;
break ;
}
}
}
}
public static void AttackPlayer ( Mob mob , PlayerCharacter target ) {
public static void AttackPlayer ( Mob mob , PlayerCharacter target ) {
if ( ! mob . canSee ( target ) ) {
if ( ! mob . canSee ( target ) ) {
mob . setCombatTarget ( null ) ;
mob . setCombatTarget ( null ) ;
@ -100,6 +105,7 @@ public class MobileFSM {
}
}
}
}
}
}
public static void AttackBuilding ( Mob mob , Building target ) {
public static void AttackBuilding ( Mob mob , Building target ) {
if ( target . getRank ( ) = = - 1 | | ! target . isVulnerable ( ) | | BuildingManager . getBuildingFromCache ( target . getObjectUUID ( ) ) = = null ) {
if ( target . getRank ( ) = = - 1 | | ! target . isVulnerable ( ) | | BuildingManager . getBuildingFromCache ( target . getObjectUUID ( ) ) = = null ) {
mob . setCombatTarget ( null ) ;
mob . setCombatTarget ( null ) ;
@ -140,6 +146,7 @@ public class MobileFSM {
DispatchMessage . dispatchMsgToInterestArea ( mob , ppm , DispatchChannel . SECONDARY , MBServerStatics . CHARACTER_LOAD_RANGE , false , false ) ;
DispatchMessage . dispatchMsgToInterestArea ( mob , ppm , DispatchChannel . SECONDARY , MBServerStatics . CHARACTER_LOAD_RANGE , false , false ) ;
}
}
}
}
public static void AttackMob ( Mob mob , Mob target ) {
public static void AttackMob ( Mob mob , Mob target ) {
if ( mob . getRange ( ) > = 30 & & mob . isMoving ( ) )
if ( mob . getRange ( ) > = 30 & & mob . isMoving ( ) )
return ;
return ;
@ -166,6 +173,7 @@ public class MobileFSM {
mob . setLastAttackTime ( System . currentTimeMillis ( ) + attackDelay ) ;
mob . setLastAttackTime ( System . currentTimeMillis ( ) + attackDelay ) ;
}
}
}
}
private static void Patrol ( Mob mob ) {
private static void Patrol ( Mob mob ) {
//make sure mob is out of combat stance
//make sure mob is out of combat stance
if ( mob . isCombat ( ) & & mob . getCombatTarget ( ) = = null ) {
if ( mob . isCombat ( ) & & mob . getCombatTarget ( ) = = null ) {
@ -214,6 +222,7 @@ public class MobileFSM {
}
}
}
}
}
}
public static boolean canCast ( Mob mob ) {
public static boolean canCast ( Mob mob ) {
// Performs validation to determine if a
// Performs validation to determine if a
// mobile in the proper state to cast.
// mobile in the proper state to cast.
@ -229,6 +238,7 @@ public class MobileFSM {
mob . nextCastTime = System . currentTimeMillis ( ) ;
mob . nextCastTime = System . currentTimeMillis ( ) ;
return mob . nextCastTime < = System . currentTimeMillis ( ) ;
return mob . nextCastTime < = System . currentTimeMillis ( ) ;
}
}
public static boolean MobCast ( Mob mob ) {
public static boolean MobCast ( Mob mob ) {
// Method picks a random spell from a mobile's list of powers
// Method picks a random spell from a mobile's list of powers
// and casts it on the current target (or itself). Validation
// and casts it on the current target (or itself). Validation
@ -291,6 +301,7 @@ public class MobileFSM {
}
}
return false ;
return false ;
}
}
public static void MobCallForHelp ( Mob mob ) {
public static void MobCallForHelp ( Mob mob ) {
boolean callGotResponse = false ;
boolean callGotResponse = false ;
if ( mob . nextCallForHelp = = 0 ) {
if ( mob . nextCallForHelp = = 0 ) {
@ -311,6 +322,7 @@ public class MobileFSM {
//wait 60 seconds to call for help again
//wait 60 seconds to call for help again
mob . nextCallForHelp = System . currentTimeMillis ( ) + 60000 ;
mob . nextCallForHelp = System . currentTimeMillis ( ) + 60000 ;
}
}
public static void DetermineAction ( Mob mob ) {
public static void DetermineAction ( Mob mob ) {
if ( mob = = null )
if ( mob = = null )
return ;
return ;
@ -375,6 +387,7 @@ public class MobileFSM {
break ;
break ;
}
}
}
}
private static void CheckForAggro ( Mob aiAgent ) {
private static void CheckForAggro ( Mob aiAgent ) {
//looks for and sets mobs combatTarget
//looks for and sets mobs combatTarget
if ( ! aiAgent . isAlive ( ) )
if ( ! aiAgent . isAlive ( ) )
@ -405,6 +418,7 @@ public class MobileFSM {
}
}
}
}
}
}
private static void CheckMobMovement ( Mob mob ) {
private static void CheckMobMovement ( Mob mob ) {
if ( ! MovementUtilities . canMove ( mob ) )
if ( ! MovementUtilities . canMove ( mob ) )
return ;
return ;
@ -446,6 +460,7 @@ public class MobileFSM {
break ;
break ;
}
}
}
}
private static void CheckForRespawn ( Mob aiAgent ) {
private static void CheckForRespawn ( Mob aiAgent ) {
if ( aiAgent . deathTime = = 0 ) {
if ( aiAgent . deathTime = = 0 ) {
aiAgent . setDeathTime ( System . currentTimeMillis ( ) ) ;
aiAgent . setDeathTime ( System . currentTimeMillis ( ) ) ;
@ -479,6 +494,7 @@ public class MobileFSM {
aiAgent . respawn ( ) ;
aiAgent . respawn ( ) ;
}
}
}
}
public static void CheckForAttack ( Mob mob ) {
public static void CheckForAttack ( Mob mob ) {
//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 ( ) = = false )
@ -505,10 +521,10 @@ public class MobileFSM {
if ( System . currentTimeMillis ( ) > mob . getLastAttackTime ( ) )
if ( System . currentTimeMillis ( ) > mob . getLastAttackTime ( ) )
AttackTarget ( mob , mob . getCombatTarget ( ) ) ;
AttackTarget ( mob , mob . getCombatTarget ( ) ) ;
}
}
private static void CheckToSendMobHome ( Mob mob ) {
private static void CheckToSendMobHome ( Mob mob ) {
if ( mob . BehaviourType . isAgressive ) {
if ( mob . BehaviourType . isAgressive ) {
if ( mob . isPlayerGuard ( ) )
if ( mob . isPlayerGuard ( ) ) {
{
if ( mob . BehaviourType . ordinal ( ) = = Enum . MobBehaviourType . GuardCaptain . ordinal ( ) ) {
if ( mob . BehaviourType . ordinal ( ) = = Enum . MobBehaviourType . GuardCaptain . ordinal ( ) ) {
CheckForPlayerGuardAggro ( mob ) ;
CheckForPlayerGuardAggro ( mob ) ;
}
}
@ -533,8 +549,7 @@ public class MobileFSM {
}
}
}
}
}
}
}
} else if ( MovementUtilities . inRangeOfBindLocation ( mob ) = = false ) {
else if ( MovementUtilities . inRangeOfBindLocation ( mob ) = = false ) {
PowersBase recall = PowersManager . getPowerByToken ( - 1994153779 ) ;
PowersBase recall = PowersManager . getPowerByToken ( - 1994153779 ) ;
PowersManager . useMobPower ( mob , mob , recall , 40 ) ;
PowersManager . useMobPower ( mob , mob , recall , 40 ) ;
@ -544,6 +559,7 @@ public class MobileFSM {
}
}
}
}
}
}
private static void chaseTarget ( Mob mob ) {
private static void chaseTarget ( Mob mob ) {
mob . updateMovementState ( ) ;
mob . updateMovementState ( ) ;
if ( mob . playerAgroMap . containsKey ( mob . getCombatTarget ( ) . getObjectUUID ( ) ) = = false ) {
if ( mob . playerAgroMap . containsKey ( mob . getCombatTarget ( ) . getObjectUUID ( ) ) = = false ) {
@ -560,6 +576,7 @@ public class MobileFSM {
}
}
}
}
}
}
private static void SafeGuardAggro ( Mob mob ) {
private static void SafeGuardAggro ( Mob mob ) {
HashSet < AbstractWorldObject > awoList = WorldGrid . getObjectsInRangePartial ( mob , 100 , MBServerStatics . MASK_MOB ) ;
HashSet < AbstractWorldObject > awoList = WorldGrid . getObjectsInRangePartial ( mob , 100 , MBServerStatics . MASK_MOB ) ;
for ( AbstractWorldObject awoMob : awoList ) {
for ( AbstractWorldObject awoMob : awoList ) {
@ -575,12 +592,14 @@ public class MobileFSM {
mob . setCombatTarget ( aggroMob ) ;
mob . setCombatTarget ( aggroMob ) ;
}
}
}
}
public static void GuardCaptainLogic ( Mob mob ) {
public static void GuardCaptainLogic ( Mob mob ) {
if ( mob . getCombatTarget ( ) = = null )
if ( mob . getCombatTarget ( ) = = null )
CheckForPlayerGuardAggro ( mob ) ;
CheckForPlayerGuardAggro ( mob ) ;
CheckMobMovement ( mob ) ;
CheckMobMovement ( mob ) ;
CheckForAttack ( mob ) ;
CheckForAttack ( mob ) ;
}
}
public static void GuardMinionLogic ( Mob mob ) {
public static void GuardMinionLogic ( Mob mob ) {
if ( ! mob . npcOwner . isAlive ( ) & & mob . getCombatTarget ( ) = = null ) {
if ( ! mob . npcOwner . isAlive ( ) & & mob . getCombatTarget ( ) = = null ) {
CheckForPlayerGuardAggro ( mob ) ;
CheckForPlayerGuardAggro ( mob ) ;
@ -592,12 +611,14 @@ public class MobileFSM {
CheckMobMovement ( mob ) ;
CheckMobMovement ( mob ) ;
CheckForAttack ( mob ) ;
CheckForAttack ( mob ) ;
}
}
public static void GuardWallArcherLogic ( Mob mob ) {
public static void GuardWallArcherLogic ( Mob mob ) {
if ( mob . getCombatTarget ( ) = = null )
if ( mob . getCombatTarget ( ) = = null )
CheckForPlayerGuardAggro ( mob ) ;
CheckForPlayerGuardAggro ( mob ) ;
else
else
CheckForAttack ( mob ) ;
CheckForAttack ( mob ) ;
}
}
private static void PetLogic ( Mob mob ) {
private static void PetLogic ( Mob mob ) {
if ( mob . getCombatTarget ( ) ! = null & & ! mob . getCombatTarget ( ) . isAlive ( ) )
if ( mob . getCombatTarget ( ) ! = null & & ! mob . getCombatTarget ( ) . isAlive ( ) )
mob . setCombatTarget ( null ) ;
mob . setCombatTarget ( null ) ;
@ -605,6 +626,7 @@ public class MobileFSM {
CheckMobMovement ( mob ) ;
CheckMobMovement ( mob ) ;
CheckForAttack ( mob ) ;
CheckForAttack ( mob ) ;
}
}
private static void HamletGuardLogic ( Mob mob ) {
private static void HamletGuardLogic ( Mob mob ) {
if ( mob . getCombatTarget ( ) = = null ) {
if ( mob . getCombatTarget ( ) = = null ) {
//safehold guard
//safehold guard
@ -616,6 +638,7 @@ public class MobileFSM {
}
}
CheckForAttack ( mob ) ;
CheckForAttack ( mob ) ;
}
}
private static void DefaultLogic ( Mob mob ) {
private static void DefaultLogic ( Mob mob ) {
if ( mob . getObjectUUID ( ) = = 40548 ) {
if ( mob . getObjectUUID ( ) = = 40548 ) {
int thing = 0 ;
int thing = 0 ;
@ -643,6 +666,7 @@ public class MobileFSM {
if ( ! mob . BehaviourType . isWimpy & & ! mob . isMoving ( ) & & mob . combatTarget ! = null )
if ( ! mob . BehaviourType . isWimpy & & ! mob . isMoving ( ) & & mob . combatTarget ! = null )
CheckForAttack ( mob ) ;
CheckForAttack ( mob ) ;
}
}
public static void CheckForPlayerGuardAggro ( Mob mob ) {
public static void CheckForPlayerGuardAggro ( Mob mob ) {
//looks for and sets mobs combatTarget
//looks for and sets mobs combatTarget
if ( ! mob . isAlive ( ) )
if ( ! mob . isAlive ( ) )
@ -673,6 +697,7 @@ public class MobileFSM {
}
}
}
}
}
}
public static Boolean GuardCanAggro ( Mob mob , PlayerCharacter target ) {
public static Boolean GuardCanAggro ( Mob mob , PlayerCharacter target ) {
if ( mob . getGuild ( ) . getNation ( ) . equals ( target . getGuild ( ) . getNation ( ) ) )
if ( mob . getGuild ( ) . getNation ( ) . equals ( target . getGuild ( ) . getNation ( ) ) )
return false ;
return false ;
@ -713,6 +738,7 @@ public class MobileFSM {
}
}
return false ;
return false ;
}
}
public static void randomGuardPatrolPoint ( Mob mob ) {
public static void randomGuardPatrolPoint ( Mob mob ) {
if ( mob . isMoving ( ) = = true ) {
if ( mob . isMoving ( ) = = true ) {
//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
@ -750,6 +776,7 @@ public class MobileFSM {
}
}
}
}
}
}
public static AbstractWorldObject ChangeTargetFromHateValue ( Mob mob ) {
public static AbstractWorldObject ChangeTargetFromHateValue ( Mob mob ) {
float CurrentHateValue = 0 ;
float CurrentHateValue = 0 ;
if ( mob . getCombatTarget ( ) ! = null & & mob . getCombatTarget ( ) . getObjectType ( ) . equals ( Enum . GameObjectType . PlayerCharacter ) ) {
if ( mob . getCombatTarget ( ) ! = null & & mob . getCombatTarget ( ) . getObjectType ( ) . equals ( Enum . GameObjectType . PlayerCharacter ) ) {