From 1c5d78d5663e504493adb227e06bd7f16c8de31e Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Mar 2025 19:52:30 -0600 Subject: [PATCH] simplified mob aI --- .../mobileAI/Behaviours/StandardMob.java | 98 +++++++++++++++---- .../mobileAI/utilities/CombatUtilities.java | 2 + .../mobileAI/utilities/MovementUtilities.java | 2 +- 3 files changed, 83 insertions(+), 19 deletions(-) diff --git a/src/engine/mobileAI/Behaviours/StandardMob.java b/src/engine/mobileAI/Behaviours/StandardMob.java index 50b413c4..ba79649b 100644 --- a/src/engine/mobileAI/Behaviours/StandardMob.java +++ b/src/engine/mobileAI/Behaviours/StandardMob.java @@ -7,6 +7,9 @@ import engine.mobileAI.utilities.CombatUtilities; import engine.mobileAI.utilities.MovementUtilities; import engine.objects.*; import engine.server.MBServerStatics; + +import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; public class StandardMob { @@ -17,19 +20,22 @@ public class StandardMob { return; } - mob.updateLocation(); + if (mob.isMoving()) { + mob.setLoc(mob.getMovementLoc()); + mob.updateLocation(); + } if(mob.combatTarget == null) { HashSet inRange = WorldGrid.getObjectsInRangePartial(mob.loc, MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER); if (!inRange.isEmpty()) { - CheckForAggro(mob, inRange); + CheckForAggro(mob); return; } }else{ CheckToDropCombatTarget(mob); if(mob.combatTarget == null){ HashSet inRange = WorldGrid.getObjectsInRangePartial(mob.loc, MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER); - CheckForAggro(mob, inRange); + CheckForAggro(mob); return; } } @@ -37,7 +43,7 @@ public class StandardMob { if(MovementUtilities.canMove(mob)) CheckForMovement(mob); - if(mob.combatTarget != null) + if(mob.combatTarget != null && !mob.isMoving()) CheckForAttack(mob); } @@ -103,20 +109,76 @@ public class StandardMob { } } - public static void CheckForAggro(Mob mob, HashSet inRange){ + public static void CheckForAggro(Mob mob){ + + if(mob == null || !mob.isAlive() || mob.playerAgroMap.isEmpty()){ + return; + } + + if(mob.BehaviourType.equals(Enum.MobBehaviourType.HamletGuard)){ + return; + } + + if(mob.hate_values == null) + mob.hate_values = new HashMap<>(); + + if(mob.combatTarget != null) + return; + + HashSet inRange = WorldGrid.getObjectsInRangePartial(mob.loc, 60f, MBServerStatics.MASK_PLAYER); + + if(inRange.isEmpty()){ + mob.setCombatTarget(null); + return; + } + + //clear out any players who are not in hated range anymore + ArrayList toRemove = new ArrayList<>(); + for(PlayerCharacter pc : mob.hate_values.keySet()){ + if(!inRange.contains(pc)) + toRemove.add(pc); + } + for(PlayerCharacter pc : toRemove){ + mob.hate_values.remove(pc); + } + + //find most hated target + PlayerCharacter mostHated = (PlayerCharacter)inRange.iterator().next(); + for(AbstractWorldObject awo : inRange){ + PlayerCharacter loadedPlayer = (PlayerCharacter)awo; + if (loadedPlayer == null) + continue; + + //Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map. + if (!loadedPlayer.isAlive()) + continue; + + //Can't see target, skip aggro. + if (!mob.canSee(loadedPlayer)) + continue; + // No aggro for this race type + if (mob.notEnemy != null && mob.notEnemy.size() > 0 && mob.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType())) + continue; + + //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())) + continue; + + if(mob.hate_values.containsKey(loadedPlayer)) + if(mob.hate_values.get(loadedPlayer) > mob.hate_values.get(mostHated)) + mostHated = loadedPlayer; + } + + if(mostHated != null) + mob.setCombatTarget(mostHated); } public static void CheckForMovement(Mob mob){ if(mob.combatTarget != null){ //chase player - float rangeSquared = mob.getRange() * mob.getRange(); - Vector3fImmutable loc2D = mob.loc; - loc2D.setY(0); - Vector3fImmutable tarLoc2D = mob.combatTarget.loc; - tarLoc2D.setY(0); - if(loc2D.distanceSquared(tarLoc2D) > rangeSquared) + if(!CombatUtilities.inRange2D(mob,mob.combatTarget,mob.getRange())) MovementUtilities.aiMove(mob,mob.combatTarget.loc,false); }else{ @@ -130,20 +192,20 @@ public class StandardMob { } public static void CheckForAttack(Mob mob){ - float rangeSquared = mob.getRange() * mob.getRange(); - Vector3fImmutable loc2D = mob.loc; - loc2D.setY(0); - Vector3fImmutable tarLoc2D = mob.combatTarget.loc; - tarLoc2D.setY(0); - if(loc2D.distanceSquared(tarLoc2D) > rangeSquared) + + if(mob.isMoving()) return; + if (mob.BehaviourType.callsForHelp) MobCallForHelp(mob); ItemBase mainHand = mob.getWeaponItemBase(true); ItemBase offHand = mob.getWeaponItemBase(false); + if(!CombatUtilities.inRange2D(mob,mob.combatTarget,mob.getRange())) + return; + if (mainHand == null && offHand == null) { CombatUtilities.combatCycle(mob, mob.combatTarget, true, null); int delay = 3000; @@ -159,7 +221,7 @@ public class StandardMob { } } public static void MobCallForHelp(Mob mob){ - HashSet mobs = WorldGrid.getObjectsInRangePartial(mob.loc,60f, MBServerStatics.MASK_MOB); + HashSet mobs = WorldGrid.getObjectsInRangePartial(mob.loc,20f, MBServerStatics.MASK_MOB); for(AbstractWorldObject awo : mobs){ Mob responder = (Mob)awo; if(responder.combatTarget == null) diff --git a/src/engine/mobileAI/utilities/CombatUtilities.java b/src/engine/mobileAI/utilities/CombatUtilities.java index 6423055e..f6655410 100644 --- a/src/engine/mobileAI/utilities/CombatUtilities.java +++ b/src/engine/mobileAI/utilities/CombatUtilities.java @@ -132,6 +132,8 @@ public class CombatUtilities { } public static boolean canSwing(Mob agent) { + if(!CombatUtilities.inRange2D(agent,agent.combatTarget,agent.getRange())) + return false; return (agent.isAlive() && !agent.getBonuses().getBool(ModType.Stunned, SourceType.None)); } diff --git a/src/engine/mobileAI/utilities/MovementUtilities.java b/src/engine/mobileAI/utilities/MovementUtilities.java index 32221fac..87e6a4cc 100644 --- a/src/engine/mobileAI/utilities/MovementUtilities.java +++ b/src/engine/mobileAI/utilities/MovementUtilities.java @@ -194,7 +194,7 @@ public class MovementUtilities { public static void aiMove(Mob agent, Vector3fImmutable vect, boolean isWalking) { - InterestManager.forceLoad(agent); + //InterestManager.forceLoad(agent); //update our walk/run state. if (isWalking && !agent.isWalk()) { agent.setWalkMode(true);