From cfa59d801233cf5846ef667303614640f2fec858 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 15 Apr 2023 22:04:55 -0500 Subject: [PATCH] pet AI implemented --- src/engine/ai/MobileFSM.java | 132 ++++++++++++------- src/engine/devcmd/cmds/aiInfoCmd.java | 20 +-- src/engine/net/client/ClientMessagePump.java | 1 - src/engine/objects/Mob.java | 10 +- 4 files changed, 101 insertions(+), 62 deletions(-) diff --git a/src/engine/ai/MobileFSM.java b/src/engine/ai/MobileFSM.java index b651084b..ca05ba8b 100644 --- a/src/engine/ai/MobileFSM.java +++ b/src/engine/ai/MobileFSM.java @@ -56,7 +56,7 @@ public class MobileFSM { SpellAggroGrouperWimpy(Spell, true, false, true, false, false), //Independent Types SimpleStandingGuard(null, false, false, false, false, false), - Pet1(null, false, false, false, false, false), + Pet1(null, false, false, true, false, false), Simple(null, false, false, true, false, false), Helpee(null, false, true, true, false, true), HelpeeWimpy(null, true, false, true, false, false), @@ -566,34 +566,43 @@ public class MobileFSM { } } public static void run(Mob mob) { - if (mob == null || mob.BehaviourType == MobBehaviourType.None) { + if (mob == null) { return; } - if (mob.isAlive() == false) { - //no need to continue if mob is dead, check for respawn and move on - CheckForRespawn(mob); - return; - } - //check to see if mob has wandered too far from his bind loc - CheckToSendMobHome(mob); - //check to see if players have mob loaded - if (mob.playerAgroMap.isEmpty()) { - //no players loaded, no need to proceed - return; - } - //check for players that can be aggroed if mob is agressive and has no target - if (mob.BehaviourType.isAgressive && mob.getCombatTarget() == null) { - CheckForAggro(mob); - } - //check if mob can move for patrol or moving to target - if (mob.BehaviourType.canRoam) { + if (mob.isPet() == false && mob.isSummonedPet() == false && mob.isNecroPet() == false) { + if (mob.BehaviourType != null && mob.BehaviourType == MobBehaviourType.None) { + return; + } + if (mob.isAlive() == false) { + //no need to continue if mob is dead, check for respawn and move on + CheckForRespawn(mob); + return; + } + //check to see if mob has wandered too far from his bind loc + CheckToSendMobHome(mob); + //check to see if players have mob loaded + if (mob.playerAgroMap.isEmpty()) { + //no players loaded, no need to proceed + return; + } + //check for players that can be aggroed if mob is agressive and has no target + if (mob.BehaviourType.isAgressive && mob.getCombatTarget() == null) { + CheckForAggro(mob); + } + //check if mob can move for patrol or moving to target + if (mob.BehaviourType.canRoam) { + CheckMobMovement(mob); + } + //check if mob can attack if it isn't wimpy + if (!mob.BehaviourType.isWimpy && !mob.isMoving() && mob.combatTarget != null) { + CheckForAttack(mob); + } + } else { CheckMobMovement(mob); - } - //check if mob can attack if it isn't wimpy - if (!mob.BehaviourType.isWimpy && !mob.isMoving() && mob.combatTarget != null) { CheckForAttack(mob); } } + private static void CheckForAggro(Mob aiAgent) { //looks for and sets mobs combatTarget if (!aiAgent.isAlive()) { @@ -629,36 +638,59 @@ public class MobileFSM { } private static void CheckMobMovement(Mob mob) { mob.updateLocation(); - if (mob.getCombatTarget() == null) { - //patrol - int patrolRandom = ThreadLocalRandom.current().nextInt(1000); - if (patrolRandom <= MBServerStatics.AI_PATROL_DIVISOR) { - if (MovementUtilities.canMove(mob) && !mob.isMoving()) { - if (mob.isPlayerGuard()) { - guardPatrol(mob); - return; + if (mob.isPet() == false && mob.isSummonedPet() == false && mob.isNecroPet() == false) { + if (mob.getCombatTarget() == null) { + //patrol + int patrolRandom = ThreadLocalRandom.current().nextInt(1000); + if (patrolRandom <= MBServerStatics.AI_PATROL_DIVISOR) { + if (MovementUtilities.canMove(mob) && !mob.isMoving()) { + if (mob.isPlayerGuard()) { + guardPatrol(mob); + return; + } + float patrolRadius = mob.getSpawnRadius(); + + if (patrolRadius > 256) + patrolRadius = 256; + + if (patrolRadius < 60) + patrolRadius = 60; + + MovementUtilities.aiMove(mob, Vector3fImmutable.getRandomPointInCircle(mob.getBindLoc(), patrolRadius), true); + } + } + } else { + //chase target + mob.updateMovementState(); + if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { + if (mob.getRange() > 15) { + mob.destination = mob.getCombatTarget().getLoc(); + MovementUtilities.moveToLocation(mob, mob.destination, 0); + } else { + mob.destination = MovementUtilities.GetDestinationToCharacter(mob, (AbstractCharacter) mob.getCombatTarget()); + MovementUtilities.moveToLocation(mob, mob.destination, mob.getRange()); } - float patrolRadius = mob.getSpawnRadius(); - - if (patrolRadius > 256) - patrolRadius = 256; - - if (patrolRadius < 60) - patrolRadius = 60; - - MovementUtilities.aiMove(mob, Vector3fImmutable.getRandomPointInCircle(mob.getBindLoc(), patrolRadius), true); } } - }else { - //chase target - mob.updateMovementState(); - if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { - if (mob.getRange() > 15) { - mob.destination = mob.getCombatTarget().getLoc(); - MovementUtilities.moveToLocation(mob, mob.destination, 0); - } else { - mob.destination = MovementUtilities.GetDestinationToCharacter(mob, (AbstractCharacter) mob.getCombatTarget()); - MovementUtilities.moveToLocation(mob, mob.destination, mob.getRange()); + } else{ + //pet logic + if (mob.getCombatTarget() == null || mob.combatTarget.isAlive() == false) { + //move back to owner + if (CombatUtilities.inRange2D(mob, mob.getOwner(), 5) == false) { + mob.destination = mob.getOwner().getLoc(); + MovementUtilities.moveToLocation(mob, mob.destination, 5); + } + } else { + //chase target + mob.updateMovementState(); + if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { + if (mob.getRange() > 15) { + mob.destination = mob.getCombatTarget().getLoc(); + MovementUtilities.moveToLocation(mob, mob.destination, 0); + } else { + mob.destination = MovementUtilities.GetDestinationToCharacter(mob, (AbstractCharacter) mob.getCombatTarget()); + MovementUtilities.moveToLocation(mob, mob.destination, mob.getRange()); + } } } } diff --git a/src/engine/devcmd/cmds/aiInfoCmd.java b/src/engine/devcmd/cmds/aiInfoCmd.java index 5b51b1b9..5e5483f3 100644 --- a/src/engine/devcmd/cmds/aiInfoCmd.java +++ b/src/engine/devcmd/cmds/aiInfoCmd.java @@ -79,19 +79,23 @@ public class aiInfoCmd extends AbstractDevCmd { Mob mob = (Mob) target; output = "Mob AI Information:" + newline; output += mob.getName() + newline; - output += "BehaviourType: " + mob.BehaviourType.toString() + newline; - output += "Behaviour Helper Type: " + mob.BehaviourType.BehaviourHelperType.toString() + newline; - output += "Wimpy: " + mob.BehaviourType.isWimpy + newline; - output += "Agressive: " + mob.BehaviourType.isAgressive + newline; - output += "Can Roam: " + mob.BehaviourType.canRoam + newline; - output += "Calls For Help: " + mob.BehaviourType.callsForHelp + newline; - output += "Responds To Call For Help: " + mob.BehaviourType.respondsToCallForHelp + newline; + if(mob.BehaviourType != null) { + output += "BehaviourType: " + mob.BehaviourType.toString() + newline; + output += "Behaviour Helper Type: " + mob.BehaviourType.BehaviourHelperType.toString() + newline; + output += "Wimpy: " + mob.BehaviourType.isWimpy + newline; + output += "Agressive: " + mob.BehaviourType.isAgressive + newline; + output += "Can Roam: " + mob.BehaviourType.canRoam + newline; + output += "Calls For Help: " + mob.BehaviourType.callsForHelp + newline; + output += "Responds To Call For Help: " + mob.BehaviourType.respondsToCallForHelp + newline; + } else{ + output += "BehaviourType: NULL" + newline; + } output += "Player Aggro Map Size: " + mob.playerAgroMap.size() + newline; if(mob.playerAgroMap.size() > 0){ output += "Players Loaded:" + newline; } for(Map.Entry entry : mob.playerAgroMap.entrySet()){ - output += "Player ID: " + entry.getKey() + "In Range To Aggro: " + entry.getValue() + newline; + output += "Player ID: " + entry.getKey() + " In Range To Aggro: " + entry.getValue() + newline; } } throwbackInfo(pc, output); diff --git a/src/engine/net/client/ClientMessagePump.java b/src/engine/net/client/ClientMessagePump.java index 59cff4e0..0f749d0e 100644 --- a/src/engine/net/client/ClientMessagePump.java +++ b/src/engine/net/client/ClientMessagePump.java @@ -2022,7 +2022,6 @@ public class ClientMessagePump implements NetMsgHandler { return; CombatManager.setAttackTarget(msg, conn); - if (pet.getCombatTarget() == null) return; } diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index 4144c4db..02df689b 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -181,6 +181,7 @@ public class Mob extends AbstractIntelligenceAgent { this.parentZone = parent; this.parentZoneID = (parent != null) ? parent.getObjectUUID() : 0; this.ownerUID = owner.getObjectUUID(); + this.BehaviourType = MobileFSM.MobBehaviourType.Pet1; initializeMob(true, false, false); clearStatic(); } @@ -1955,10 +1956,13 @@ public class Mob extends AbstractIntelligenceAgent { } // Combine mobbase and mob aggro arrays into one bitvector + try { + this.notEnemy.addAll(this.getMobBase().notEnemy); + this.enemy.addAll(this.getMobBase().enemy); + } + catch(Exception ex){ - this.notEnemy.addAll(this.getMobBase().notEnemy); - this.enemy.addAll(this.getMobBase().enemy); - + } try { NPCManager.applyRuneSetEffects(this); recalculateStats();