diff --git a/src/engine/ai/MobileFSM.java b/src/engine/ai/MobileFSM.java index f977be90..c087814a 100644 --- a/src/engine/ai/MobileFSM.java +++ b/src/engine/ai/MobileFSM.java @@ -35,6 +35,7 @@ public class MobileFSM { private static void AttackTarget(Mob mob, AbstractWorldObject target) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.ATTACKTARGET; if (mob == null) return; if (target == null || !target.isAlive()) { @@ -67,6 +68,7 @@ public class MobileFSM { } public static void AttackPlayer(Mob mob, PlayerCharacter target) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.ATTACKPLAYER; if (!mob.canSee(target)) { mob.setCombatTarget(null); return; @@ -115,6 +117,7 @@ public class MobileFSM { } public static void AttackBuilding(Mob mob, Building target) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.ATTACKBUILDING; if (target.getRank() == -1 || !target.isVulnerable() || BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) { mob.setCombatTarget(null); return; @@ -156,6 +159,7 @@ public class MobileFSM { } public static void AttackMob(Mob mob, Mob target) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.ATTACKMOB; if (mob.getRange() >= 30 && mob.isMoving()) return; //no weapons, default mob attack speed 3 seconds. @@ -186,6 +190,7 @@ public class MobileFSM { } private static void Patrol(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.PATROL; //make sure mob is out of combat stance if (mob.isCombat() && mob.getCombatTarget() == null) { mob.setCombat(false); @@ -235,6 +240,7 @@ public class MobileFSM { } public static boolean canCast(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.CANCAST; // Performs validation to determine if a // mobile in the proper state to cast. if (mob == null) @@ -256,6 +262,7 @@ public class MobileFSM { } public static boolean MobCast(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.MOBCAST; // 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(); @@ -320,6 +327,7 @@ public class MobileFSM { } public static void MobCallForHelp(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.MOBCALLFORHELP; boolean callGotResponse = false; if (mob.nextCallForHelp == 0) { mob.nextCallForHelp = System.currentTimeMillis(); @@ -341,6 +349,7 @@ public class MobileFSM { } public static void DetermineAction(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.DETERMINEACTION; //always check the respawn que, respawn 1 mob max per second to not flood the client if (mob == null) @@ -430,6 +439,7 @@ public class MobileFSM { } private static void CheckForAggro(Mob aiAgent) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.CHECKFORAGRO; //looks for and sets mobs combatTarget if (!aiAgent.isAlive()) return; @@ -477,6 +487,7 @@ public class MobileFSM { } private static void CheckMobMovement(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.CHECKMOBMOVEMENT; if (!MovementUtilities.canMove(mob)) return; mob.updateLocation(); @@ -523,6 +534,7 @@ public class MobileFSM { } private static void CheckForRespawn(Mob aiAgent) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.CHECKFORRESPAWN; if (aiAgent.deathTime == 0) { aiAgent.setDeathTime(System.currentTimeMillis()); return; @@ -561,6 +573,7 @@ public class MobileFSM { } public static void CheckForAttack(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.CHECKFORATTACK; //checks if mob can attack based on attack timer and range if (mob.isAlive() == false) return; @@ -588,6 +601,7 @@ public class MobileFSM { } private static void CheckToSendMobHome(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.CHECKTOSENDMOBHOME; if (mob.BehaviourType.isAgressive) { if (mob.isPlayerGuard()) { if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal()) { @@ -626,6 +640,7 @@ public class MobileFSM { } private static void chaseTarget(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.CHASETARGET; mob.updateMovementState(); mob.updateLocation(); if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { @@ -651,6 +666,7 @@ public class MobileFSM { } private static void SafeGuardAggro(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.SAFEGUARDAGRO; HashSet awoList = WorldGrid.getObjectsInRangePartial(mob, 100, MBServerStatics.MASK_MOB); for (AbstractWorldObject awoMob : awoList) { //dont scan self. @@ -667,6 +683,7 @@ public class MobileFSM { } public static void GuardCaptainLogic(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.GUARDCAPTAINLOGIC; if (mob.getCombatTarget() == null) CheckForPlayerGuardAggro(mob); CheckMobMovement(mob); @@ -674,6 +691,7 @@ public class MobileFSM { } public static void GuardMinionLogic(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.GUARDMINIONLOGIC; if (!mob.npcOwner.isAlive() && mob.getCombatTarget() == null) { CheckForPlayerGuardAggro(mob); } @@ -686,6 +704,7 @@ public class MobileFSM { } public static void GuardWallArcherLogic(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.GUARDWALLARCHERLOGIC; if (mob.getCombatTarget() == null) CheckForPlayerGuardAggro(mob); else @@ -693,6 +712,7 @@ public class MobileFSM { } private static void PetLogic(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.PETLOGIC; if(mob.getOwner() == null && mob.isNecroPet() == false && mob.isSiege() == false){ if(ZoneManager.getSeaFloor().zoneMobSet.contains(mob)){ mob.killCharacter("no owner"); @@ -718,6 +738,7 @@ public class MobileFSM { } private static void HamletGuardLogic(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.HAMLETGUARDLOGIC; if (mob.getCombatTarget() == null) { //safehold guard SafeGuardAggro(mob); @@ -730,6 +751,7 @@ public class MobileFSM { } private static void DefaultLogic(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.DEFAULTLOGIC; //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){ mob.setCombatTarget(null); @@ -758,6 +780,7 @@ public class MobileFSM { } public static void CheckForPlayerGuardAggro(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.CHECKFORPLAYERGUARDAGRO; //looks for and sets mobs combatTarget if (!mob.isAlive()) return; @@ -789,6 +812,7 @@ public class MobileFSM { } public static Boolean GuardCanAggro(Mob mob, PlayerCharacter target) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.GUARDCANAGRO; if (mob.getGuild().getNation().equals(target.getGuild().getNation())) return false; if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardMinion.ordinal()) { @@ -830,6 +854,7 @@ public class MobileFSM { } public static void randomGuardPatrolPoint(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.RANDOMGUARDPATROLPOINTS; if (mob.isMoving() == true) { //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 @@ -868,6 +893,7 @@ public class MobileFSM { } public static AbstractWorldObject ChangeTargetFromHateValue(Mob mob) { + MobileFSMManager.getInstance().currentState = MobileFSMManager.fsmState.CHANGETARGETFROMHATEVALUE; float CurrentHateValue = 0; if (mob.getCombatTarget() != null && mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { CurrentHateValue = ((PlayerCharacter) mob.getCombatTarget()).getHateValue(); diff --git a/src/engine/ai/MobileFSMManager.java b/src/engine/ai/MobileFSMManager.java index b57ac4fa..07bc6628 100644 --- a/src/engine/ai/MobileFSMManager.java +++ b/src/engine/ai/MobileFSMManager.java @@ -29,16 +29,44 @@ public class MobileFSMManager { //AI variables moved form mb_server_statics public static int AI_BASE_AGGRO_RANGE = 60; public static int AI_DROP_AGGRO_RANGE = 60; - public static int AI_RECALL_RANGE = 400; public static int AI_PULSE_MOB_THRESHOLD = 200; - public static int AI_THREAD_SLEEP = 1000; public static int AI_PATROL_DIVISOR = 15; public static int AI_POWER_DIVISOR = 20; - public static float AI_MAX_ANGLE = 10f; private volatile boolean alive; private long timeOfKill = -1; - - + public fsmState currentState; + public Mob currentMob; + public enum fsmState { + ATTACKTARGET, + ATTACKPLAYER, + ATTACKBUILDING, + ATTACKMOB, + PATROL, + CANCAST, + MOBCAST, + MOBCALLFORHELP, + DETERMINEACTION, + CHECKFORAGRO, + CHECKMOBMOVEMENT, + CHECKFORRESPAWN, + CHECKFORATTACK, + CHECKTOSENDMOBHOME, + CHASETARGET, + SAFEGUARDAGRO, + GUARDCAPTAINLOGIC, + GUARDMINIONLOGIC, + GUARDWALLARCHERLOGIC, + PETLOGIC, + HAMLETGUARDLOGIC, + DEFAULTLOGIC, + CHECKFORPLAYERGUARDAGRO, + GUARDCANAGRO, + RANDOMGUARDPATROLPOINTS, + CHANGETARGETFROMHATEVALUE + } + public String getFSMState(){ + return "Executing: " + this.currentState + " on Mobile UUID: " + this.currentMob.getObjectUUID() + " " + this.currentMob.getName(); + } private MobileFSMManager() { Runnable worker = new Runnable() { diff --git a/src/engine/devcmd/cmds/AuditAI.java b/src/engine/devcmd/cmds/AuditAI.java new file mode 100644 index 00000000..39889109 --- /dev/null +++ b/src/engine/devcmd/cmds/AuditAI.java @@ -0,0 +1,44 @@ +// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . +// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· +// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ +// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ +// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ +// Magicbane Emulator Project © 2013 - 2022 +// www.magicbane.com + + +package engine.devcmd.cmds; + +import engine.ai.MobileFSMManager; +import engine.devcmd.AbstractDevCmd; +import engine.objects.AbstractGameObject; +import engine.objects.PlayerCharacter; + +/** + * ./auditai <- display the current state of mob AI thread + */ + +public class AuditAI extends AbstractDevCmd { + + public AuditAI() { + super("auditai"); + } + + @Override + protected void _doCmd(PlayerCharacter playerCharacter, String[] words, AbstractGameObject target) { + throwbackInfo(playerCharacter, MobileFSMManager.getInstance().getFSMState()); + } + + @Override + protected String _getHelpString() { + return "displays the current state and mob running thought he AI system"; + } + + @Override + protected String _getUsageString() { + return "'./auditai"; + } + + +} + diff --git a/src/engine/gameManager/DevCmdManager.java b/src/engine/gameManager/DevCmdManager.java index 33ba103d..056bb62a 100644 --- a/src/engine/gameManager/DevCmdManager.java +++ b/src/engine/gameManager/DevCmdManager.java @@ -58,6 +58,7 @@ public enum DevCmdManager { DevCmdManager.registerDevCmd(new InfoCmd()); DevCmdManager.registerDevCmd(new aiInfoCmd()); DevCmdManager.registerDevCmd(new simulateBootyCmd()); + DevCmdManager.registerDevCmd(new AuditAI()); DevCmdManager.registerDevCmd(new GetHeightCmd()); // Tester