From 140ba6ae758a4dd60a2f7a8e77b8590f00eccaa8 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 27 Feb 2025 15:43:43 -0600 Subject: [PATCH] new mob aggro system --- src/engine/gameManager/CombatManager.java | 10 ++ src/engine/gameManager/PowersManager.java | 13 +++ src/engine/mobileAI/MobAI.java | 125 ++++++++++++---------- src/engine/objects/Mob.java | 3 + 4 files changed, 93 insertions(+), 58 deletions(-) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index c6bc2e4d..be582615 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -1006,6 +1006,16 @@ public enum CombatManager { if (ac.isAlive() && tarAc != null && tarAc.isAlive()) handleDamageShields(ac, tarAc, damage); + //handle mob hate values + if(target.getObjectType().equals(GameObjectType.Mob) && ac.getObjectType().equals(GameObjectType.PlayerCharacter)){ + Mob mobTarget = (Mob)target; + if(mobTarget.hate_values.containsKey((PlayerCharacter) ac)){ + mobTarget.hate_values.put((PlayerCharacter) ac,mobTarget.hate_values.get((PlayerCharacter) ac) + damage); + }else{ + mobTarget.hate_values.put((PlayerCharacter) ac, damage); + } + } + } else { // Apply Weapon power effect if any. diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index 8b6c4c38..4f44cf37 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -1015,6 +1015,19 @@ public enum PowersManager { playerCharacter.setHateValue(pb.getHateValue(trains)); + //handle mob hate values + HashSet mobs = WorldGrid.getObjectsInRangePartial(playerCharacter.loc,60.0f,MBServerStatics.MASK_MOB); + for(AbstractWorldObject awo : mobs){ + Mob mobTarget = (Mob)awo; + if(mobTarget.hate_values.containsKey(playerCharacter)){ + mobTarget.hate_values.put(playerCharacter,mobTarget.hate_values.get(playerCharacter) + pb.getHateValue(trains)); + }else{ + mobTarget.hate_values.put(playerCharacter, pb.getHateValue(trains)); + } + } + + + //Send Cast Message. // PerformActionMsg castMsg = new PerformActionMsg(msg); // castMsg.setNumTrains(9999); diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 97d85217..bf59cb46 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -27,6 +27,7 @@ import engine.server.MBServerStatics; import org.pmw.tinylog.Logger; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; @@ -738,6 +739,8 @@ public class MobAI { private static void CheckForAggro(Mob aiAgent) { + + //old system try { //looks for and sets mobs combatTarget @@ -772,13 +775,11 @@ public class MobAI { continue; // No aggro for this race type - - if (aiAgent.notEnemy.size() > 0 && aiAgent.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType()) == true) + if (aiAgent.notEnemy.size() > 0 && aiAgent.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType())) continue; //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; if (MovementUtilities.inRangeToAggro(aiAgent, loadedPlayer)) { @@ -975,7 +976,8 @@ public class MobAI { if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal()) CheckForPlayerGuardAggro(mob); } else { - CheckForAggro(mob); + //CheckForAggro(mob); + NewAggroMechanic(mob); } } @@ -1107,17 +1109,6 @@ public class MobAI { if (mob.getCombatTarget() == null) 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); CheckForAttack(mob); } catch (Exception e) { @@ -1209,17 +1200,11 @@ public class MobAI { if (mob.BehaviourType.isAgressive) { - AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob); - - if (newTarget != null) - mob.setCombatTarget(newTarget); - else { - if (mob.getCombatTarget() == null) { - if (mob.BehaviourType == Enum.MobBehaviourType.HamletGuard) - SafeGuardAggro(mob); //safehold guard - else - CheckForAggro(mob); //normal aggro - } + if (mob.getCombatTarget() == null) { + if (mob.BehaviourType == Enum.MobBehaviourType.HamletGuard) + SafeGuardAggro(mob); //safehold guard + else + NewAggroMechanic(mob);//CheckForAggro(mob); //normal aggro } } @@ -1401,37 +1386,6 @@ public class MobAI { } } - public static AbstractWorldObject ChangeTargetFromHateValue(Mob mob) { - - try { - - float CurrentHateValue = 0; - - if (mob.getCombatTarget() != null && mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) - CurrentHateValue = ((PlayerCharacter) mob.getCombatTarget()).getHateValue(); - - 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 && potentialTarget.getHateValue() > CurrentHateValue && MovementUtilities.inRangeToAggro(mob, potentialTarget)) { - CurrentHateValue = potentialTarget.getHateValue(); - mostHatedTarget = potentialTarget; - } - - } - return mostHatedTarget; - } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: ChangeTargetFromMostHated" + " " + e.getMessage()); - } - return null; - } - public static void RecoverHealth(Mob mob) { //recover health try { @@ -1459,4 +1413,59 @@ public class MobAI { rwss.setPlayer(mob); DispatchMessage.sendToAllInRange(mob, rwss); } + + public static void NewAggroMechanic(Mob mob){ + + if(mob == null || !mob.isAlive()){ + return; + } + + HashSet inRange = WorldGrid.getObjectsInRangePartial(mob.loc,60.0f,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); + } } \ No newline at end of file diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index f104420a..97215eee 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -111,6 +111,8 @@ public class Mob extends AbstractIntelligenceAgent { public boolean StrongholdEpic = false; public boolean isDropper = false; + public HashMap hate_values; + /** * No Id Constructor @@ -1450,6 +1452,7 @@ public class Mob extends AbstractIntelligenceAgent { this.stopPatrolTime = 0; this.lastPatrolPointIndex = 0; InterestManager.setObjectDirty(this); + this.hate_values = new HashMap<>(); } public void despawn() {