From 2aabafdab8f849b8d7402abbdc58e7e28e45b4be Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 5 Aug 2023 22:54:41 -0500 Subject: [PATCH 01/35] fixed mob cast effect --- src/engine/mobileAI/MobAI.java | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index e533c9e2..c323e6d3 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -324,10 +324,10 @@ public class MobAI { return false; } - int castRoll = ThreadLocalRandom.current().nextInt(101); + //int castRoll = ThreadLocalRandom.current().nextInt(1,101); - if (castRoll <= MobAIThread.AI_POWER_DIVISOR) - return false; + //if (castRoll < MobAIThread.AI_POWER_DIVISOR) + // return false; if (mob.nextCastTime == 0) mob.nextCastTime = System.currentTimeMillis(); @@ -349,7 +349,7 @@ public class MobAI { ArrayList powerTokens; ArrayList purgeTokens; - PlayerCharacter target = (PlayerCharacter) mob.getCombatTarget(); + AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget(); if (mob.BehaviourType.callsForHelp) MobCallForHelp(mob); @@ -410,22 +410,23 @@ public class MobAI { if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) { - PowersManager.useMobPower(mob, (AbstractCharacter) mob.getCombatTarget(), mobPower, powerRank); + PerformActionMsg msg; - if (!mobPower.isHarmful() || mobPower.targetSelf) + if (!mobPower.isHarmful() || mobPower.targetSelf) { + PowersManager.useMobPower(mob, mob, mobPower, powerRank); msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob); - else + } + else { + PowersManager.useMobPower(mob, target, mobPower, powerRank); msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); + } msg.setUnknown04(2); PowersManager.finishUseMobPower(msg, mob, 0, 0); - // Default minimum seconds between cast = 10 - - float randomCooldown = (ThreadLocalRandom.current().nextInt(150) + 100) * 0.01f; - mob.nextCastTime = System.currentTimeMillis() + (long) ((mobPower.getCooldown() + (MobAIThread.AI_POWER_DIVISOR * 1000)) * randomCooldown); + mob.nextCastTime = System.currentTimeMillis() + (long) ((mobPower.getCooldown() + (MobAIThread.AI_POWER_DIVISOR * 1000))); return true; } } catch (Exception e) { From c4af45b9e5c65ad7c4fd988f3bb7eefb939ced3c Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 5 Aug 2023 23:10:06 -0500 Subject: [PATCH 02/35] guard casting system --- src/engine/mobileAI/MobAI.java | 109 ++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 3 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index c323e6d3..72891e4a 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -50,12 +50,16 @@ public class MobAI { return; } - if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) - if (MobCast(mob)) { + if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) { + if (mob.isPlayerGuard() == false && MobCast(mob)) { mob.updateLocation(); return; } - + if (mob.isPlayerGuard() == true && GuardCast(mob)) { + mob.updateLocation(); + return; + } + } if (!CombatUtilities.inRangeToAttack(mob, target)) return; @@ -434,6 +438,105 @@ public class MobAI { } return false; } + public static boolean GuardCast(Mob mob) { + + try { + // 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(); + + ArrayList powerTokens; + ArrayList purgeTokens; + AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget(); + + if (mob.BehaviourType.callsForHelp) + MobCallForHelp(mob); + + // Generate a list of tokens from the mob powers for this mobile. + + powerTokens = new ArrayList<>(mob.mobPowers.keySet()); + purgeTokens = new ArrayList<>(); + + // If player has this effect on them currently then remove + // this token from our list. + + for (int powerToken : powerTokens) { + + PowersBase powerBase = PowersManager.getPowerByToken(powerToken); + + for (ActionsBase actionBase : powerBase.getActions()) { + + String stackType = actionBase.stackType; + + if (target.getEffects() != null && target.getEffects().containsKey(stackType)) + purgeTokens.add(powerToken); + } + } + + powerTokens.removeAll(purgeTokens); + + // Sanity check + + if (powerTokens.isEmpty()) + return false; + int powerToken = 0; + // Pick random spell from our list of powers + if(ThreadLocalRandom.current().nextInt(1,100) < 65){ + //65% direct damage chance + powerToken = powerTokens.get(0); + + } else { + //pull non DD spell + powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(1,powerTokens.size())); + } + int powerRank = mob.mobPowers.get(powerToken); + PowersBase mobPower = PowersManager.getPowerByToken(powerToken); + + //check for hit-roll + + if (mobPower.requiresHitRoll) { + + if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget())) + return false; + + if (CombatUtilities.triggerDodge(mob, mob.getCombatTarget())) + return false; + + if (CombatUtilities.triggerBlock(mob, mob.getCombatTarget())) + return false; + + if (CombatUtilities.triggerParry(mob, mob.getCombatTarget())) + return false; + } + + // Cast the spell + + if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) { + + + PerformActionMsg msg; + + if (!mobPower.isHarmful() || mobPower.targetSelf) { + PowersManager.useMobPower(mob, mob, mobPower, powerRank); + msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob); + } + else { + PowersManager.useMobPower(mob, target, mobPower, powerRank); + msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); + } + + msg.setUnknown04(2); + + PowersManager.finishUseMobPower(msg, mob, 0, 0); + + mob.nextCastTime = System.currentTimeMillis() + (long) ((mobPower.getCooldown() + (MobAIThread.AI_POWER_DIVISOR * 1000))); + return true; + } + } catch (Exception e) { + Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage()); + } + return false; + } public static void MobCallForHelp(Mob mob) { From a79562de01d18941afe90d92c1bab728fcba8954 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 5 Aug 2023 23:23:27 -0500 Subject: [PATCH 03/35] random extra spell cooldown to stagger --- src/engine/mobileAI/MobAI.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 72891e4a..090bcbb0 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -429,8 +429,8 @@ public class MobAI { msg.setUnknown04(2); PowersManager.finishUseMobPower(msg, mob, 0, 0); - - mob.nextCastTime = System.currentTimeMillis() + (long) ((mobPower.getCooldown() + (MobAIThread.AI_POWER_DIVISOR * 1000))); + int randomCooldown = ThreadLocalRandom.current().nextInt(1,10); + mob.nextCastTime = System.currentTimeMillis() + (long) ((mobPower.getCooldown() + (MobAIThread.AI_POWER_DIVISOR * 1000))) + (randomCooldown * 1000); return true; } } catch (Exception e) { @@ -528,8 +528,8 @@ public class MobAI { msg.setUnknown04(2); PowersManager.finishUseMobPower(msg, mob, 0, 0); - - mob.nextCastTime = System.currentTimeMillis() + (long) ((mobPower.getCooldown() + (MobAIThread.AI_POWER_DIVISOR * 1000))); + int randomCooldown = ThreadLocalRandom.current().nextInt(1,10); + mob.nextCastTime = System.currentTimeMillis() + (long) ((mobPower.getCooldown() + (MobAIThread.AI_POWER_DIVISOR * 1000))) + (randomCooldown * 1000); return true; } } catch (Exception e) { From d221daa86455633f91e7298846be5d5042d9cf4c Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 5 Aug 2023 23:38:24 -0500 Subject: [PATCH 04/35] guard power work --- src/engine/mobileAI/MobAI.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 090bcbb0..dea54c94 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -479,16 +479,8 @@ public class MobAI { if (powerTokens.isEmpty()) return false; - int powerToken = 0; - // Pick random spell from our list of powers - if(ThreadLocalRandom.current().nextInt(1,100) < 65){ - //65% direct damage chance - powerToken = powerTokens.get(0); - } else { - //pull non DD spell - powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(1,powerTokens.size())); - } + int powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); int powerRank = mob.mobPowers.get(powerToken); PowersBase mobPower = PowersManager.getPowerByToken(powerToken); From 5d1ccc437c769bc94d584effe9747290674f28a5 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 6 Aug 2023 00:04:42 -0500 Subject: [PATCH 05/35] mele guards dont cast --- src/engine/Enum.java | 3 +++ src/engine/mobileAI/MobAI.java | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/engine/Enum.java b/src/engine/Enum.java index ce5dfa3c..231f1c5f 100644 --- a/src/engine/Enum.java +++ b/src/engine/Enum.java @@ -2679,6 +2679,9 @@ public class Enum { return race; } + public Boolean isMage(){ + return this.minionClass.ordinal() == MinionClass.MAGE.ordinal(); + } } public enum GridObjectType { diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index dea54c94..1fa9a1cf 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -320,6 +320,18 @@ public class MobAI { if (mob == null) return false; + if(mob.isPlayerGuard == true){ + int contractID; + if(mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardMinion.ordinal()){ + contractID = mob.npcOwner.contract.getContractID(); + } else{ + contractID = mob.contract.getContractID(); + } + if(Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false){ + return false; + } + } + if (mob.mobPowers.isEmpty()) return false; @@ -327,12 +339,6 @@ public class MobAI { mob.setCombatTarget(null); return false; } - - //int castRoll = ThreadLocalRandom.current().nextInt(1,101); - - //if (castRoll < MobAIThread.AI_POWER_DIVISOR) - // return false; - if (mob.nextCastTime == 0) mob.nextCastTime = System.currentTimeMillis(); From 345a866f50ef75ba08b54db2e8677695073ee7be Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 6 Aug 2023 00:07:01 -0500 Subject: [PATCH 06/35] mele guards dont cast --- src/engine/mobileAI/MobAI.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 1fa9a1cf..66823709 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -322,14 +322,12 @@ public class MobAI { if(mob.isPlayerGuard == true){ int contractID; - if(mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardMinion.ordinal()){ + if(mob.BehaviourType.equals(Enum.MobBehaviourType.GuardMinion)) contractID = mob.npcOwner.contract.getContractID(); - } else{ + else contractID = mob.contract.getContractID(); - } - if(Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false){ + if(Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false) return false; - } } if (mob.mobPowers.isEmpty()) From dde98c7c58e45427d19d8263a02a22a73728e0b3 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 6 Aug 2023 17:07:25 -0500 Subject: [PATCH 07/35] guard casting work --- src/engine/mobileAI/MobAI.java | 10 ++++++++-- src/engine/mobileAI/Threads/MobAIThread.java | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 66823709..582c6aee 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -483,8 +483,14 @@ public class MobAI { if (powerTokens.isEmpty()) return false; - - int powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); + int powerToken = 0; + if(ThreadLocalRandom.current().nextInt(1,100) < 65){ + //use direct damage spell + powerToken = mob.mobPowers.get(3); + } else{ + //use other random spell + powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size() - 1)); + } int powerRank = mob.mobPowers.get(powerToken); PowersBase mobPower = PowersManager.getPowerByToken(powerToken); diff --git a/src/engine/mobileAI/Threads/MobAIThread.java b/src/engine/mobileAI/Threads/MobAIThread.java index 3e92a1f9..590a133b 100644 --- a/src/engine/mobileAI/Threads/MobAIThread.java +++ b/src/engine/mobileAI/Threads/MobAIThread.java @@ -11,7 +11,7 @@ public class MobAIThread implements Runnable{ public static int AI_DROP_AGGRO_RANGE = 60; public static int AI_PULSE_MOB_THRESHOLD = 200; public static int AI_PATROL_DIVISOR = 15; - public static int AI_POWER_DIVISOR = 20; + public static int AI_POWER_DIVISOR = 10; // Thread constructor public MobAIThread() { From 915f93dc2d58b75c600d064d9c7107ab80971d02 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 6 Aug 2023 17:11:22 -0500 Subject: [PATCH 08/35] safe guards dont aggro pets --- src/engine/mobileAI/MobAI.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 582c6aee..2da3065a 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -1025,7 +1025,8 @@ public class MobAI { if (aggroMob.isGuard()) continue; - + if(aggroMob.BehaviourType.equals(Enum.MobBehaviourType.Pet1)) + continue; if (mob.getLoc().distanceSquared2D(aggroMob.getLoc()) > sqr(50)) continue; From 0d2ea32dbd33fc1f0f617b7d082b60a2e74194fa Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 6 Aug 2023 17:42:24 -0500 Subject: [PATCH 09/35] guards nuke more than they debuff --- src/engine/mobileAI/MobAI.java | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 2da3065a..56f3637c 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -403,15 +403,6 @@ public class MobAI { if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget())) return false; - - if (CombatUtilities.triggerDodge(mob, mob.getCombatTarget())) - return false; - - if (CombatUtilities.triggerBlock(mob, mob.getCombatTarget())) - return false; - - if (CombatUtilities.triggerParry(mob, mob.getCombatTarget())) - return false; } // Cast the spell @@ -484,12 +475,13 @@ public class MobAI { if (powerTokens.isEmpty()) return false; int powerToken = 0; - if(ThreadLocalRandom.current().nextInt(1,100) < 65){ + int nukeRoll = ThreadLocalRandom.current().nextInt(1,100); + if( nukeRoll < 65){ //use direct damage spell - powerToken = mob.mobPowers.get(3); + powerToken = powerTokens.get(3); } else{ - //use other random spell - powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size() - 1)); + //use random spell + powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); } int powerRank = mob.mobPowers.get(powerToken); PowersBase mobPower = PowersManager.getPowerByToken(powerToken); @@ -500,15 +492,6 @@ public class MobAI { if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget())) return false; - - if (CombatUtilities.triggerDodge(mob, mob.getCombatTarget())) - return false; - - if (CombatUtilities.triggerBlock(mob, mob.getCombatTarget())) - return false; - - if (CombatUtilities.triggerParry(mob, mob.getCombatTarget())) - return false; } // Cast the spell From 23783ec7cdbffca949c8875b4bbf994bb97aa5a8 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 6 Aug 2023 17:54:01 -0500 Subject: [PATCH 10/35] spacing cleanup --- src/engine/mobileAI/MobAI.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 56f3637c..9f0c6d9e 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -283,7 +283,7 @@ public class MobAI { MovementUtilities.aiMove(mob, mob.destination, true); - if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal()) { + if (mob.BehaviourType.equals(Enum.MobBehaviourType.GuardCaptain)) { for (Entry minion : mob.siegeMinionMap.entrySet()) { //make sure mob is out of combat stance @@ -295,7 +295,6 @@ public class MobAI { rwss.setPlayer(minion.getKey()); DispatchMessage.sendToAllInRange(minion.getKey(), rwss); } - if (MovementUtilities.canMove(minion.getKey())) { Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3); minion.getKey().updateLocation(); @@ -433,6 +432,7 @@ public class MobAI { } return false; } + public static boolean GuardCast(Mob mob) { try { From a5af696806b87999eb2732f74dd39c9ecf6ca7df Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 6 Aug 2023 19:44:20 -0500 Subject: [PATCH 11/35] guard powers --- src/engine/mobileAI/MobAI.java | 13 +++++++++---- src/engine/mobileAI/Threads/MobAIThread.java | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 9f0c6d9e..5d938d7d 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -476,9 +476,9 @@ public class MobAI { return false; int powerToken = 0; int nukeRoll = ThreadLocalRandom.current().nextInt(1,100); - if( nukeRoll < 65){ + if( nukeRoll < 55){ //use direct damage spell - powerToken = powerTokens.get(3); + powerToken = powerTokens.get(0); } else{ //use random spell powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); @@ -502,8 +502,13 @@ public class MobAI { PerformActionMsg msg; if (!mobPower.isHarmful() || mobPower.targetSelf) { - PowersManager.useMobPower(mob, mob, mobPower, powerRank); - msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob); + if(mobPower.category.equals("DISPEL")){ + PowersManager.useMobPower(mob, target, mobPower, powerRank); + msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); + }else { + PowersManager.useMobPower(mob, mob, mobPower, powerRank); + msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob); + } } else { PowersManager.useMobPower(mob, target, mobPower, powerRank); diff --git a/src/engine/mobileAI/Threads/MobAIThread.java b/src/engine/mobileAI/Threads/MobAIThread.java index 590a133b..3e92a1f9 100644 --- a/src/engine/mobileAI/Threads/MobAIThread.java +++ b/src/engine/mobileAI/Threads/MobAIThread.java @@ -11,7 +11,7 @@ public class MobAIThread implements Runnable{ public static int AI_DROP_AGGRO_RANGE = 60; public static int AI_PULSE_MOB_THRESHOLD = 200; public static int AI_PATROL_DIVISOR = 15; - public static int AI_POWER_DIVISOR = 10; + public static int AI_POWER_DIVISOR = 20; // Thread constructor public MobAIThread() { From 071eb26e48c79cd84e0334e6ae23c1aea6663e4f Mon Sep 17 00:00:00 2001 From: MagicBot Date: Tue, 8 Aug 2023 08:31:11 -0400 Subject: [PATCH 12/35] Powers also loaded from contract. --- src/engine/objects/Mob.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index fc3b508c..43eca335 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -60,7 +60,7 @@ public class Mob extends AbstractIntelligenceAgent { public boolean despawned = false; public Vector3fImmutable destination = Vector3fImmutable.ZERO; public Vector3fImmutable localLoc = Vector3fImmutable.ZERO; - public HashMap mobPowers; + public HashMap mobPowers = new HashMap<>(); public MobBase mobBase; public int spawnTime; public Zone parentZone; @@ -1947,8 +1947,15 @@ public class Mob extends AbstractIntelligenceAgent { } mobPowers = new HashMap<>(); + // Powers from mobbase + if (PowersManager.AllMobPowers.containsKey(this.getMobBaseID())) - mobPowers = PowersManager.AllMobPowers.get(this.getMobBaseID()); + mobPowers.putAll(PowersManager.AllMobPowers.get(this.getMobBaseID())); + + // Powers from contract + + if (PowersManager.AllMobPowers.containsKey(this.contract.getContractID())) + mobPowers.putAll(PowersManager.AllMobPowers.get(this.contract.getContractID())); if (this.equip == null) { Logger.error("Null equipset returned for uuid " + currentID); @@ -1956,7 +1963,7 @@ public class Mob extends AbstractIntelligenceAgent { } // Combine mobbase and mob aggro arrays into one bitvector //skip for pets - if(this.isPet() == false && this.isSummonedPet() == false && this.isNecroPet() == false) { + if (this.isPet() == false && this.isSummonedPet() == false && this.isNecroPet() == false) { if (this.getMobBase().notEnemy.size() > 0) this.notEnemy.addAll(this.getMobBase().notEnemy); From 2e6ebbb9c31c8d02ed81760efc5852ffb5debac4 Mon Sep 17 00:00:00 2001 From: MagicBot Date: Tue, 8 Aug 2023 10:29:01 -0400 Subject: [PATCH 13/35] Refactor of mob powers loading for efficiency. --- src/engine/db/handlers/dbMobBaseHandler.java | 19 ------ src/engine/db/handlers/dbPowerHandler.java | 70 ++++++++++++++++++++ src/engine/gameManager/DbManager.java | 2 + src/engine/gameManager/PowersManager.java | 22 +----- src/engine/objects/Mob.java | 18 +++-- src/engine/powers/MobPowerEntry.java | 17 +++++ src/engine/server/world/WorldServer.java | 2 +- 7 files changed, 103 insertions(+), 47 deletions(-) create mode 100644 src/engine/db/handlers/dbPowerHandler.java create mode 100644 src/engine/powers/MobPowerEntry.java diff --git a/src/engine/db/handlers/dbMobBaseHandler.java b/src/engine/db/handlers/dbMobBaseHandler.java index fce26d02..0337ff76 100644 --- a/src/engine/db/handlers/dbMobBaseHandler.java +++ b/src/engine/db/handlers/dbMobBaseHandler.java @@ -21,7 +21,6 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; -import java.util.HashMap; public class dbMobBaseHandler extends dbHandlerBase { @@ -71,24 +70,6 @@ public class dbMobBaseHandler extends dbHandlerBase { } return mobbaseList; } - public HashMap LOAD_STATIC_POWERS(int mobBaseUUID) { - - HashMap powersList = new HashMap<>(); - - try (Connection connection = DbManager.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_mobbase_powers` WHERE `mobbaseUUID`=?")) { - - preparedStatement.setInt(1, mobBaseUUID); - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) - powersList.put(rs.getInt("token"), rs.getInt("rank")); - - } catch (SQLException e) { - Logger.error(e); - } - return powersList; - } public ArrayList GET_RUNEBASE_EFFECTS(int runeID) { diff --git a/src/engine/db/handlers/dbPowerHandler.java b/src/engine/db/handlers/dbPowerHandler.java new file mode 100644 index 00000000..4b0b984a --- /dev/null +++ b/src/engine/db/handlers/dbPowerHandler.java @@ -0,0 +1,70 @@ +// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . +// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· +// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ +// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ +// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ +// Magicbane Emulator Project © 2013 - 2022 +// www.magicbane.com + + +package engine.db.handlers; + +import engine.gameManager.DbManager; +import engine.objects.Mob; +import engine.powers.MobPowerEntry; +import org.pmw.tinylog.Logger; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; + +public class dbPowerHandler extends dbHandlerBase { + + public dbPowerHandler() { + this.localClass = Mob.class; + this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); + } + + public HashMap> LOAD_MOB_POWERS() { + + HashMap> mobPowers = new HashMap<>(); + MobPowerEntry mobPowerEntry; + + int mobbaseID; + int recordsRead = 0; + + try (Connection connection = DbManager.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_npc_mobbase_powers")) { + + ResultSet rs = preparedStatement.executeQuery(); + + while (rs.next()) { + + recordsRead++; + + mobbaseID = rs.getInt("mobbaseID"); + mobPowerEntry = new MobPowerEntry(rs); + + if (mobPowers.get(mobbaseID) == null) { + ArrayList powerList = new ArrayList<>(); + powerList.add(mobPowerEntry); + mobPowers.put(mobbaseID, powerList); + } else { + ArrayList powerList = mobPowers.get(mobbaseID); + powerList.add(mobPowerEntry); + mobPowers.put(mobbaseID, powerList); + } + } + } catch (SQLException e) { + Logger.error(e); + return mobPowers; + } + + Logger.info("read: " + recordsRead + " cached: " + mobPowers.size()); + return mobPowers; + } + +} diff --git a/src/engine/gameManager/DbManager.java b/src/engine/gameManager/DbManager.java index 25792846..437a9d5c 100644 --- a/src/engine/gameManager/DbManager.java +++ b/src/engine/gameManager/DbManager.java @@ -72,6 +72,8 @@ public enum DbManager { public static final dbShrineHandler ShrineQueries = new dbShrineHandler(); public static final dbHeightMapHandler HeightMapQueries = new dbHeightMapHandler(); public static final dbRunegateHandler RunegateQueries = new dbRunegateHandler(); + + public static final dbPowerHandler PowerQueries = new dbPowerHandler(); private static final EnumMap> objectCache = new EnumMap<>(GameObjectType.class); public static Hasher hasher; private static HikariDataSource connectionPool = null; diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index 5cdd14f5..06b37eaa 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -55,7 +55,7 @@ public enum PowersManager { public static HashMap ActionTokenByIDString = new HashMap<>(); public static HashMap modifiersByToken = new HashMap<>(); public static HashMap AnimationOverrides = new HashMap<>(); - public static HashMap> AllMobPowers = new HashMap<>(); + public static HashMap> AllMobPowers = new HashMap<>(); private static JobScheduler js; private PowersManager() { @@ -2778,26 +2778,6 @@ public enum PowersManager { } } - public static void LoadAllMobPowers() { - - int count = 0; - - for (AbstractGameObject mobBaseAgo : DbManager.getList(GameObjectType.MobBase)) { - - int mobBaseID = ((MobBase) mobBaseAgo).getLoadID(); - - HashMap powersList = DbManager.MobBaseQueries.LOAD_STATIC_POWERS(mobBaseID); - - if (powersList.isEmpty()) - continue; - ; - - AllMobPowers.put(mobBaseID, powersList); - count++; - } - - Logger.info("Powers loaded for " + count + " Mobbases/"); - } } diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index 43eca335..1619b44b 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -29,6 +29,7 @@ import engine.net.DispatchMessage; import engine.net.client.msg.PetMsg; import engine.net.client.msg.PlaceAssetMsg; import engine.powers.EffectsBase; +import engine.powers.MobPowerEntry; import engine.server.MBServerStatics; import org.joda.time.DateTime; import org.pmw.tinylog.Logger; @@ -1950,19 +1951,23 @@ public class Mob extends AbstractIntelligenceAgent { // Powers from mobbase if (PowersManager.AllMobPowers.containsKey(this.getMobBaseID())) - mobPowers.putAll(PowersManager.AllMobPowers.get(this.getMobBaseID())); + for (MobPowerEntry mobPowerEntry : PowersManager.AllMobPowers.get(this.getMobBaseID())) + mobPowers.put(mobPowerEntry.token, mobPowerEntry.rank); // Powers from contract if (PowersManager.AllMobPowers.containsKey(this.contract.getContractID())) - mobPowers.putAll(PowersManager.AllMobPowers.get(this.contract.getContractID())); + for (MobPowerEntry mobPowerEntry : PowersManager.AllMobPowers.get(this.contract.getContractID())) + mobPowers.put(mobPowerEntry.token, mobPowerEntry.rank); if (this.equip == null) { Logger.error("Null equipset returned for uuid " + currentID); this.equip = new HashMap<>(0); } + // Combine mobbase and mob aggro arrays into one bitvector //skip for pets + if (this.isPet() == false && this.isSummonedPet() == false && this.isNecroPet() == false) { if (this.getMobBase().notEnemy.size() > 0) this.notEnemy.addAll(this.getMobBase().notEnemy); @@ -1970,6 +1975,7 @@ public class Mob extends AbstractIntelligenceAgent { if (this.getMobBase().enemy.size() > 0) this.enemy.addAll(this.getMobBase().enemy); } + try { NPCManager.applyRuneSetEffects(this); recalculateStats(); @@ -1980,6 +1986,7 @@ public class Mob extends AbstractIntelligenceAgent { Bounds mobBounds = Bounds.borrow(); mobBounds.setBounds(this.getLoc()); this.setBounds(mobBounds); + if (this.contract != null && this.contract.getContractID() == 910) { this.isPlayerGuard = true; this.BehaviourType = MobBehaviourType.GuardCaptain; @@ -1990,6 +1997,7 @@ public class Mob extends AbstractIntelligenceAgent { if (!this.isGuard() && !this.isPlayerGuard() && !this.isPet() && !this.isNecroPet() && !this.isSummonedPet() && !this.isCharmedPet()) { this.patrolPoints = new ArrayList<>(); + for (int i = 0; i < 5; ++i) { float patrolRadius = this.getSpawnRadius(); @@ -2001,10 +2009,12 @@ public class Mob extends AbstractIntelligenceAgent { Vector3fImmutable newPatrolPoint = Vector3fImmutable.getRandomPointInCircle(this.getBindLoc(), patrolRadius); this.patrolPoints.add(newPatrolPoint); + if (i == 1) MovementManager.translocate(this, newPatrolPoint, null); } } + if (this.BehaviourType == null) this.BehaviourType = this.getMobBase().fsm; @@ -2049,10 +2059,6 @@ public class Mob extends AbstractIntelligenceAgent { this.isSiege = isSiege; } - public long getTimeToSpawnSiege() { - return timeToSpawnSiege; - } - public void setTimeToSpawnSiege(long timeToSpawnSiege) { this.timeToSpawnSiege = timeToSpawnSiege; } diff --git a/src/engine/powers/MobPowerEntry.java b/src/engine/powers/MobPowerEntry.java new file mode 100644 index 00000000..1aee9848 --- /dev/null +++ b/src/engine/powers/MobPowerEntry.java @@ -0,0 +1,17 @@ +package engine.powers; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class MobPowerEntry { + + public int token; + public int rank; + + + public MobPowerEntry(ResultSet rs) throws SQLException { + this.token = rs.getInt("token"); + this.rank = rs.getInt("rank"); + } + +} diff --git a/src/engine/server/world/WorldServer.java b/src/engine/server/world/WorldServer.java index cdcf6f90..023a85e9 100644 --- a/src/engine/server/world/WorldServer.java +++ b/src/engine/server/world/WorldServer.java @@ -349,7 +349,7 @@ public class WorldServer { DbManager.MobBaseQueries.GET_ALL_MOBBASES(); Logger.info("Loading Mob Powers for MobBases"); - PowersManager.LoadAllMobPowers(); + PowersManager.AllMobPowers = DbManager.PowerQueries.LOAD_MOB_POWERS(); Logger.info("Loading item enchants"); DbManager.LootQueries.LOAD_ENCHANT_VALUES(); From 0b1df09f3a01a4bde3e20088aebc27056e610831 Mon Sep 17 00:00:00 2001 From: MagicBot Date: Tue, 8 Aug 2023 10:30:20 -0400 Subject: [PATCH 14/35] Refactor of mob powers loading for efficiency. --- src/engine/db/handlers/dbPowerHandler.java | 2 +- src/engine/server/world/WorldServer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/db/handlers/dbPowerHandler.java b/src/engine/db/handlers/dbPowerHandler.java index 4b0b984a..85a1330a 100644 --- a/src/engine/db/handlers/dbPowerHandler.java +++ b/src/engine/db/handlers/dbPowerHandler.java @@ -45,7 +45,7 @@ public class dbPowerHandler extends dbHandlerBase { recordsRead++; - mobbaseID = rs.getInt("mobbaseID"); + mobbaseID = rs.getInt("mobbaseUUID"); mobPowerEntry = new MobPowerEntry(rs); if (mobPowers.get(mobbaseID) == null) { diff --git a/src/engine/server/world/WorldServer.java b/src/engine/server/world/WorldServer.java index 023a85e9..d312ca10 100644 --- a/src/engine/server/world/WorldServer.java +++ b/src/engine/server/world/WorldServer.java @@ -348,7 +348,7 @@ public class WorldServer { Logger.info("Loading MobBases."); DbManager.MobBaseQueries.GET_ALL_MOBBASES(); - Logger.info("Loading Mob Powers for MobBases"); + Logger.info("Loading Mob Powers"); PowersManager.AllMobPowers = DbManager.PowerQueries.LOAD_MOB_POWERS(); Logger.info("Loading item enchants"); From fbf865e865702520ebe87ff43094f60a9b53d9c4 Mon Sep 17 00:00:00 2001 From: MagicBot Date: Tue, 8 Aug 2023 10:32:20 -0400 Subject: [PATCH 15/35] Methods moved to new dbPowersHandler. --- src/engine/db/handlers/dbPowerHandler.java | 58 ++++++++++++++++++++ src/engine/gameManager/PowersManager.java | 63 ++-------------------- 2 files changed, 61 insertions(+), 60 deletions(-) diff --git a/src/engine/db/handlers/dbPowerHandler.java b/src/engine/db/handlers/dbPowerHandler.java index 85a1330a..b1fe5636 100644 --- a/src/engine/db/handlers/dbPowerHandler.java +++ b/src/engine/db/handlers/dbPowerHandler.java @@ -9,8 +9,12 @@ package engine.db.handlers; +import engine.Enum; import engine.gameManager.DbManager; +import engine.gameManager.PowersManager; import engine.objects.Mob; +import engine.objects.PreparedStatementShared; +import engine.powers.EffectsBase; import engine.powers.MobPowerEntry; import org.pmw.tinylog.Logger; @@ -20,6 +24,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; public class dbPowerHandler extends dbHandlerBase { @@ -28,6 +33,59 @@ public class dbPowerHandler extends dbHandlerBase { this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); } + public static void addAllSourceTypes() { + PreparedStatementShared ps = null; + try { + ps = new PreparedStatementShared("SELECT * FROM static_power_sourcetype"); + ResultSet rs = ps.executeQuery(); + String IDString, source; + while (rs.next()) { + IDString = rs.getString("IDString"); + int token = DbManager.hasher.SBStringHash(IDString); + + + source = rs.getString("source").replace("-", "").trim(); + Enum.EffectSourceType effectSourceType = Enum.EffectSourceType.GetEffectSourceType(source); + + if (EffectsBase.effectSourceTypeMap.containsKey(token) == false) + EffectsBase.effectSourceTypeMap.put(token, new HashSet<>()); + + EffectsBase.effectSourceTypeMap.get(token).add(effectSourceType); + } + rs.close(); + } catch (Exception e) { + Logger.error(e); + } finally { + ps.release(); + } + } + + public static void addAllAnimationOverrides() { + PreparedStatementShared ps = null; + try { + ps = new PreparedStatementShared("SELECT * FROM static_power_animation_override"); + ResultSet rs = ps.executeQuery(); + String IDString; + int animation; + while (rs.next()) { + IDString = rs.getString("IDString"); + + EffectsBase eb = PowersManager.getEffectByIDString(IDString); + if (eb != null) + IDString = eb.getIDString(); + + animation = rs.getInt("animation"); + PowersManager.AnimationOverrides.put(IDString, animation); + + } + rs.close(); + } catch (Exception e) { + Logger.error(e); + } finally { + ps.release(); + } + } + public HashMap> LOAD_MOB_POWERS() { HashMap> mobPowers = new HashMap<>(); diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index 06b37eaa..eec316dd 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -12,6 +12,7 @@ import engine.Enum.*; import engine.InterestManagement.HeightMap; import engine.InterestManagement.WorldGrid; import engine.db.handlers.dbEffectsBaseHandler; +import engine.db.handlers.dbPowerHandler; import engine.db.handlers.dbSkillReqHandler; import engine.job.AbstractJob; import engine.job.AbstractScheduleJob; @@ -32,7 +33,6 @@ import engine.powers.poweractions.TrackPowerAction; import engine.server.MBServerStatics; import org.pmw.tinylog.Logger; -import java.sql.ResultSet; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -85,10 +85,6 @@ public enum PowersManager { return PowersManager.effectsBaseByIDString.get(IDString); } - public static AbstractPowerAction getPowerActionByID(Integer id) { - return PowersManager.powerActionsByID.get(id); - } - public static AbstractPowerAction getPowerActionByIDString(String IDString) { return PowersManager.powerActionsByIDString.get(IDString); } @@ -128,8 +124,8 @@ public enum PowersManager { dbEffectsBaseHandler.cacheAllEffectModifiers(); // Add Source Types to Effects - PowersManager.addAllSourceTypes(); - PowersManager.addAllAnimationOverrides(); + dbPowerHandler.addAllSourceTypes(); + dbPowerHandler.addAllAnimationOverrides(); // Add PowerActions AbstractPowerAction.getAllPowerActions(PowersManager.powerActionsByIDString, PowersManager.powerActionsByID, PowersManager.effectsBaseByIDString); @@ -156,59 +152,6 @@ public enum PowersManager { } - private static void addAllSourceTypes() { - PreparedStatementShared ps = null; - try { - ps = new PreparedStatementShared("SELECT * FROM static_power_sourcetype"); - ResultSet rs = ps.executeQuery(); - String IDString, source; - while (rs.next()) { - IDString = rs.getString("IDString"); - int token = DbManager.hasher.SBStringHash(IDString); - - - source = rs.getString("source").replace("-", "").trim(); - EffectSourceType effectSourceType = EffectSourceType.GetEffectSourceType(source); - - if (EffectsBase.effectSourceTypeMap.containsKey(token) == false) - EffectsBase.effectSourceTypeMap.put(token, new HashSet<>()); - - EffectsBase.effectSourceTypeMap.get(token).add(effectSourceType); - } - rs.close(); - } catch (Exception e) { - Logger.error(e); - } finally { - ps.release(); - } - } - - private static void addAllAnimationOverrides() { - PreparedStatementShared ps = null; - try { - ps = new PreparedStatementShared("SELECT * FROM static_power_animation_override"); - ResultSet rs = ps.executeQuery(); - String IDString; - int animation; - while (rs.next()) { - IDString = rs.getString("IDString"); - - EffectsBase eb = PowersManager.getEffectByIDString(IDString); - if (eb != null) - IDString = eb.getIDString(); - - animation = rs.getInt("animation"); - PowersManager.AnimationOverrides.put(IDString, animation); - - } - rs.close(); - } catch (Exception e) { - Logger.error(e); - } finally { - ps.release(); - } - } - public static EffectsBase setEffectToken(int ID, int token) { for (EffectsBase eb : PowersManager.effectsBaseByIDString.values()) { if (eb.getUUID() == ID) { From 1fb2d8cadf686835998d3b0f80b2e2260c2c3320 Mon Sep 17 00:00:00 2001 From: MagicBot Date: Tue, 8 Aug 2023 10:39:19 -0400 Subject: [PATCH 16/35] Power loading work. --- src/engine/db/handlers/dbPowerHandler.java | 2 +- src/engine/gameManager/PowersManager.java | 4 +--- src/engine/objects/Mob.java | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/engine/db/handlers/dbPowerHandler.java b/src/engine/db/handlers/dbPowerHandler.java index b1fe5636..18088913 100644 --- a/src/engine/db/handlers/dbPowerHandler.java +++ b/src/engine/db/handlers/dbPowerHandler.java @@ -86,7 +86,7 @@ public class dbPowerHandler extends dbHandlerBase { } } - public HashMap> LOAD_MOB_POWERS() { + public static HashMap> LOAD_MOB_POWERS() { HashMap> mobPowers = new HashMap<>(); MobPowerEntry mobPowerEntry; diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index eec316dd..4bc2d34c 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -27,7 +27,6 @@ import engine.net.client.ClientConnection; import engine.net.client.msg.*; import engine.objects.*; import engine.powers.*; -import engine.powers.effectmodifiers.AbstractEffectModifier; import engine.powers.poweractions.AbstractPowerAction; import engine.powers.poweractions.TrackPowerAction; import engine.server.MBServerStatics; @@ -53,9 +52,8 @@ public enum PowersManager { public static HashMap powerActionsByIDString = new HashMap<>(); public static HashMap powerActionsByID = new HashMap<>(); public static HashMap ActionTokenByIDString = new HashMap<>(); - public static HashMap modifiersByToken = new HashMap<>(); public static HashMap AnimationOverrides = new HashMap<>(); - public static HashMap> AllMobPowers = new HashMap<>(); + public static HashMap> AllMobPowers; private static JobScheduler js; private PowersManager() { diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index 1619b44b..2038c7c5 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -1946,7 +1946,6 @@ public class Mob extends AbstractIntelligenceAgent { } catch (Exception e) { Logger.error(e.getMessage()); } - mobPowers = new HashMap<>(); // Powers from mobbase From 434078cebfdeb51a739004e337d65ba445bfef39 Mon Sep 17 00:00:00 2001 From: MagicBot Date: Tue, 8 Aug 2023 10:44:26 -0400 Subject: [PATCH 17/35] Power loading work. --- src/engine/objects/Mob.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index 2038c7c5..16a1cce9 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -1955,7 +1955,7 @@ public class Mob extends AbstractIntelligenceAgent { // Powers from contract - if (PowersManager.AllMobPowers.containsKey(this.contract.getContractID())) + if (this.contract != null && PowersManager.AllMobPowers.containsKey(this.contract.getContractID())) for (MobPowerEntry mobPowerEntry : PowersManager.AllMobPowers.get(this.contract.getContractID())) mobPowers.put(mobPowerEntry.token, mobPowerEntry.rank); From 31122cf6d32853e2223550d3e5071858e809d735 Mon Sep 17 00:00:00 2001 From: MagicBot Date: Tue, 8 Aug 2023 11:01:05 -0400 Subject: [PATCH 18/35] AIinfo updated with token list. --- src/engine/devcmd/cmds/aiInfoCmd.java | 80 +++++++++++---------------- 1 file changed, 33 insertions(+), 47 deletions(-) diff --git a/src/engine/devcmd/cmds/aiInfoCmd.java b/src/engine/devcmd/cmds/aiInfoCmd.java index 3f1c3869..95957a75 100644 --- a/src/engine/devcmd/cmds/aiInfoCmd.java +++ b/src/engine/devcmd/cmds/aiInfoCmd.java @@ -11,9 +11,7 @@ package engine.devcmd.cmds; import engine.Enum.GameObjectType; import engine.devcmd.AbstractDevCmd; -import engine.gameManager.BuildingManager; import engine.objects.AbstractGameObject; -import engine.objects.Building; import engine.objects.Mob; import engine.objects.PlayerCharacter; @@ -30,55 +28,40 @@ public class aiInfoCmd extends AbstractDevCmd { } @Override - protected void _doCmd(PlayerCharacter pc, String[] words, + protected void _doCmd(PlayerCharacter playerCharacter, String[] words, AbstractGameObject target) { + // Arg Count Check + if (words.length != 1) { - this.sendUsage(pc); + this.sendUsage(playerCharacter); return; } - if (pc == null) { + + if (playerCharacter == null) return; - } String newline = "\r\n "; - try { - int targetID = Integer.parseInt(words[0]); - Building b = BuildingManager.getBuilding(targetID); - if (b == null) - throwbackError(pc, "Building with ID " + targetID - + " not found"); - else - target = b; - } catch (Exception e) { - } - - if (target == null) { - throwbackError(pc, "Target is unknown or of an invalid type." - + newline + "Type ID: 0x" - + pc.getLastTargetType().toString() - + " Table ID: " + pc.getLastTargetID()); - return; - } - GameObjectType objType = target.getObjectType(); - int objectUUID = target.getObjectUUID(); String output; if (objType != GameObjectType.Mob) { output = "Please Select A Mob For AI Info" + newline; - } else { - Mob mob = (Mob) target; - output = "Mob AI Information:" + newline; - output += mob.getName() + newline; - if (mob.BehaviourType != null) { - output += "BehaviourType: " + mob.BehaviourType.toString() + newline; - if (mob.BehaviourType.BehaviourHelperType != null) { - output += "Behaviour Helper Type: " + mob.BehaviourType.BehaviourHelperType.toString() + newline; - } else { - output += "Behaviour Helper Type: NULL" + newline; + throwbackInfo(playerCharacter, output); + return; + } + + Mob mob = (Mob) target; + output = "Mob AI Information:" + newline; + output += mob.getName() + newline; + if (mob.BehaviourType != null) { + output += "BehaviourType: " + mob.BehaviourType.toString() + newline; + if (mob.BehaviourType.BehaviourHelperType != null) { + output += "Behaviour Helper Type: " + mob.BehaviourType.BehaviourHelperType.toString() + newline; + } else { + output += "Behaviour Helper Type: NULL" + newline; } output += "Wimpy: " + mob.BehaviourType.isWimpy + newline; output += "Agressive: " + mob.BehaviourType.isAgressive + newline; @@ -90,18 +73,21 @@ public class aiInfoCmd extends AbstractDevCmd { } output += "Aggro Range: " + mob.getAggroRange() + 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() + " Is Safemode: " + entry.getValue() + newline; - } - if (mob.getCombatTarget() != null) - output += "Current Target: " + mob.getCombatTarget().getName() + newline; - else - output += "Current Target: NULL" + newline; + if (mob.playerAgroMap.size() > 0) { + output += "Players Loaded:" + newline; + } + for (Map.Entry entry : mob.playerAgroMap.entrySet()) { + output += "Player ID: " + entry.getKey() + " Is Safemode: " + entry.getValue() + newline; } - throwbackInfo(pc, output); + if (mob.getCombatTarget() != null) + output += "Current Target: " + mob.getCombatTarget().getName() + newline; + else + output += "Current Target: NULL" + newline; + + for (int token : mob.mobPowers.keySet()) + output += token + newline; + + throwbackInfo(playerCharacter, output); } @Override From 35dc1239f8b91fd0efc91417de2a087afca2e8a2 Mon Sep 17 00:00:00 2001 From: MagicBot Date: Tue, 8 Aug 2023 11:12:32 -0400 Subject: [PATCH 19/35] Record sort ASC is required. --- src/engine/db/handlers/dbPowerHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/db/handlers/dbPowerHandler.java b/src/engine/db/handlers/dbPowerHandler.java index 18088913..27b3142f 100644 --- a/src/engine/db/handlers/dbPowerHandler.java +++ b/src/engine/db/handlers/dbPowerHandler.java @@ -95,7 +95,7 @@ public class dbPowerHandler extends dbHandlerBase { int recordsRead = 0; try (Connection connection = DbManager.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_npc_mobbase_powers")) { + PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_npc_mobbase_powers ORDER BY `id ASC;")) { ResultSet rs = preparedStatement.executeQuery(); From 1cc8d2919a828d52d165fa7409c1842969f9960e Mon Sep 17 00:00:00 2001 From: MagicBot Date: Tue, 8 Aug 2023 11:19:18 -0400 Subject: [PATCH 20/35] DD is last element in contract power list. --- src/engine/mobileAI/MobAI.java | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 5d938d7d..790c1cea 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -476,41 +476,42 @@ public class MobAI { return false; int powerToken = 0; int nukeRoll = ThreadLocalRandom.current().nextInt(1,100); - if( nukeRoll < 55){ + + if (nukeRoll < 55) { + //use direct damage spell - powerToken = powerTokens.get(0); - } else{ + powerToken = powerTokens.get(powerTokens.size() - 1); + + } else { //use random spell powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); } + int powerRank = mob.mobPowers.get(powerToken); PowersBase mobPower = PowersManager.getPowerByToken(powerToken); //check for hit-roll - if (mobPower.requiresHitRoll) { - + if (mobPower.requiresHitRoll) if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget())) return false; - } // Cast the spell if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) { - PerformActionMsg msg; if (!mobPower.isHarmful() || mobPower.targetSelf) { - if(mobPower.category.equals("DISPEL")){ + + if (mobPower.category.equals("DISPEL")) { PowersManager.useMobPower(mob, target, mobPower, powerRank); msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); - }else { + } else { PowersManager.useMobPower(mob, mob, mobPower, powerRank); msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob); } - } - else { + } else { PowersManager.useMobPower(mob, target, mobPower, powerRank); msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); } @@ -519,6 +520,7 @@ public class MobAI { PowersManager.finishUseMobPower(msg, mob, 0, 0); int randomCooldown = ThreadLocalRandom.current().nextInt(1,10); + mob.nextCastTime = System.currentTimeMillis() + (long) ((mobPower.getCooldown() + (MobAIThread.AI_POWER_DIVISOR * 1000))) + (randomCooldown * 1000); return true; } From 2ce13ac4638159e131f45ff8eb731038ffa4c3cb Mon Sep 17 00:00:00 2001 From: MagicBot Date: Tue, 8 Aug 2023 11:24:13 -0400 Subject: [PATCH 21/35] typo in sql --- src/engine/db/handlers/dbPowerHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/db/handlers/dbPowerHandler.java b/src/engine/db/handlers/dbPowerHandler.java index 27b3142f..664da1de 100644 --- a/src/engine/db/handlers/dbPowerHandler.java +++ b/src/engine/db/handlers/dbPowerHandler.java @@ -95,7 +95,7 @@ public class dbPowerHandler extends dbHandlerBase { int recordsRead = 0; try (Connection connection = DbManager.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_npc_mobbase_powers ORDER BY `id ASC;")) { + PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_npc_mobbase_powers ORDER BY `id` ASC;")) { ResultSet rs = preparedStatement.executeQuery(); From ec43c54affbc5b38ff26a8443c5b206adc189577 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 8 Aug 2023 10:54:36 -0500 Subject: [PATCH 22/35] mob cast delay cached --- src/engine/mobileAI/MobAI.java | 9 ++++----- src/engine/mobileAI/Threads/MobAIThread.java | 6 +++++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 790c1cea..10e719d5 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -423,8 +423,8 @@ public class MobAI { msg.setUnknown04(2); PowersManager.finishUseMobPower(msg, mob, 0, 0); - int randomCooldown = ThreadLocalRandom.current().nextInt(1,10); - mob.nextCastTime = System.currentTimeMillis() + (long) ((mobPower.getCooldown() + (MobAIThread.AI_POWER_DIVISOR * 1000))) + (randomCooldown * 1000); + long randomCooldown = (long)(ThreadLocalRandom.current().nextInt(10,15) * MobAIThread.AI_CAST_FREQUENCY); + mob.nextCastTime = System.currentTimeMillis() + randomCooldown; return true; } } catch (Exception e) { @@ -519,9 +519,8 @@ public class MobAI { msg.setUnknown04(2); PowersManager.finishUseMobPower(msg, mob, 0, 0); - int randomCooldown = ThreadLocalRandom.current().nextInt(1,10); - - mob.nextCastTime = System.currentTimeMillis() + (long) ((mobPower.getCooldown() + (MobAIThread.AI_POWER_DIVISOR * 1000))) + (randomCooldown * 1000); + long randomCooldown = (long)(ThreadLocalRandom.current().nextInt(10,15) * MobAIThread.AI_CAST_FREQUENCY); + mob.nextCastTime = System.currentTimeMillis() + randomCooldown; return true; } } catch (Exception e) { diff --git a/src/engine/mobileAI/Threads/MobAIThread.java b/src/engine/mobileAI/Threads/MobAIThread.java index 3e92a1f9..a10e6c24 100644 --- a/src/engine/mobileAI/Threads/MobAIThread.java +++ b/src/engine/mobileAI/Threads/MobAIThread.java @@ -1,9 +1,11 @@ package engine.mobileAI.Threads; +import engine.gameManager.ConfigManager; import engine.mobileAI.MobAI; import engine.gameManager.ZoneManager; import engine.objects.Mob; import engine.objects.Zone; +import engine.server.MBServerStatics; import org.pmw.tinylog.Logger; public class MobAIThread implements Runnable{ @@ -11,7 +13,7 @@ public class MobAIThread implements Runnable{ public static int AI_DROP_AGGRO_RANGE = 60; public static int AI_PULSE_MOB_THRESHOLD = 200; public static int AI_PATROL_DIVISOR = 15; - public static int AI_POWER_DIVISOR = 20; + public static float AI_CAST_FREQUENCY; // Thread constructor public MobAIThread() { @@ -21,6 +23,8 @@ public class MobAIThread implements Runnable{ @Override public void run() { + //cache config value for mobile casting delay + AI_CAST_FREQUENCY = Float.parseFloat(ConfigManager.MB_AI_CAST_FREQUENCY.getValue()); while (true) { for (Zone zone : ZoneManager.getAllZones()) { From c8b91fc264a20f4841ec1aed621ecf8aec27c610 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 8 Aug 2023 10:56:33 -0500 Subject: [PATCH 23/35] aggro raneg configurable --- src/engine/mobileAI/Threads/MobAIThread.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/mobileAI/Threads/MobAIThread.java b/src/engine/mobileAI/Threads/MobAIThread.java index a10e6c24..b3699879 100644 --- a/src/engine/mobileAI/Threads/MobAIThread.java +++ b/src/engine/mobileAI/Threads/MobAIThread.java @@ -25,6 +25,7 @@ public class MobAIThread implements Runnable{ public void run() { //cache config value for mobile casting delay AI_CAST_FREQUENCY = Float.parseFloat(ConfigManager.MB_AI_CAST_FREQUENCY.getValue()); + AI_BASE_AGGRO_RANGE = (int)(60 * Float.parseFloat(ConfigManager.MB_AI_AGGRO_RANGE.getValue())); while (true) { for (Zone zone : ZoneManager.getAllZones()) { From 564968a1e3d17f0ff60ceadde09a17ed03cb4eb7 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 8 Aug 2023 11:07:41 -0500 Subject: [PATCH 24/35] scaling guard powers based on rank --- src/engine/mobileAI/MobAI.java | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 10e719d5..0944536d 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -423,7 +423,7 @@ public class MobAI { msg.setUnknown04(2); PowersManager.finishUseMobPower(msg, mob, 0, 0); - long randomCooldown = (long)(ThreadLocalRandom.current().nextInt(10,15) * MobAIThread.AI_CAST_FREQUENCY); + long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY); mob.nextCastTime = System.currentTimeMillis() + randomCooldown; return true; } @@ -487,7 +487,30 @@ public class MobAI { powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); } - int powerRank = mob.mobPowers.get(powerToken); + int powerRank = 1; + switch(mob.getRank()){ + case 1: + powerRank = 10; + break; + case 2: + powerRank = 15; + break; + case 3: + powerRank = 20; + break; + case 4: + powerRank = 25; + break; + case 5: + powerRank = 30; + break; + case 6: + powerRank = 35; + break; + case 7: + powerRank = 40; + break; + } PowersBase mobPower = PowersManager.getPowerByToken(powerToken); //check for hit-roll @@ -519,7 +542,7 @@ public class MobAI { msg.setUnknown04(2); PowersManager.finishUseMobPower(msg, mob, 0, 0); - long randomCooldown = (long)(ThreadLocalRandom.current().nextInt(10,15) * MobAIThread.AI_CAST_FREQUENCY); + long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY); mob.nextCastTime = System.currentTimeMillis() + randomCooldown; return true; } From 9f0fb26e1f29bd94b736b4a9d2f9fe47a36ecfe4 Mon Sep 17 00:00:00 2001 From: MagicBot Date: Tue, 8 Aug 2023 12:24:27 -0400 Subject: [PATCH 25/35] Need to preserver order of hashmap insertion. --- src/engine/mobileAI/MobAI.java | 4 ++++ src/engine/objects/Mob.java | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 0944536d..a1b5168c 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -474,6 +474,7 @@ public class MobAI { if (powerTokens.isEmpty()) return false; + int powerToken = 0; int nukeRoll = ThreadLocalRandom.current().nextInt(1,100); @@ -488,6 +489,7 @@ public class MobAI { } int powerRank = 1; + switch(mob.getRank()){ case 1: powerRank = 10; @@ -511,6 +513,7 @@ public class MobAI { powerRank = 40; break; } + PowersBase mobPower = PowersManager.getPowerByToken(powerToken); //check for hit-roll @@ -542,6 +545,7 @@ public class MobAI { msg.setUnknown04(2); PowersManager.finishUseMobPower(msg, mob, 0, 0); + long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY); mob.nextCastTime = System.currentTimeMillis() + randomCooldown; return true; diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index 16a1cce9..e2f8d728 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -39,6 +39,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -61,7 +62,7 @@ public class Mob extends AbstractIntelligenceAgent { public boolean despawned = false; public Vector3fImmutable destination = Vector3fImmutable.ZERO; public Vector3fImmutable localLoc = Vector3fImmutable.ZERO; - public HashMap mobPowers = new HashMap<>(); + public LinkedHashMap mobPowers = new LinkedHashMap<>(); public MobBase mobBase; public int spawnTime; public Zone parentZone; From f852037a617b42caa36f2a6bf5b72451c83f4a11 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 8 Aug 2023 11:30:19 -0500 Subject: [PATCH 26/35] guard minion aggro fixed --- src/engine/mobileAI/MobAI.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index a1b5168c..56259939 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -1069,14 +1069,14 @@ public class MobAI { public static void GuardMinionLogic(Mob mob) { try { - if (!mob.npcOwner.isAlive() && mob.getCombatTarget() == null) + if (!mob.npcOwner.isAlive() && mob.getCombatTarget() == null) { CheckForPlayerGuardAggro(mob); - - if (mob.npcOwner.getCombatTarget() != null) - mob.setCombatTarget(mob.npcOwner.getCombatTarget()); - else - mob.setCombatTarget(null); - + }else { + if (mob.npcOwner.getCombatTarget() != null) + mob.setCombatTarget(mob.npcOwner.getCombatTarget()); + else + mob.setCombatTarget(null); + } CheckMobMovement(mob); CheckForAttack(mob); } catch (Exception e) { From 49c403bacc7ad71345e79251bc72c592daf1cdd8 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 8 Aug 2023 11:43:27 -0500 Subject: [PATCH 27/35] aiInfo display hate value --- src/engine/devcmd/cmds/aiInfoCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/devcmd/cmds/aiInfoCmd.java b/src/engine/devcmd/cmds/aiInfoCmd.java index 95957a75..1caf90c9 100644 --- a/src/engine/devcmd/cmds/aiInfoCmd.java +++ b/src/engine/devcmd/cmds/aiInfoCmd.java @@ -77,7 +77,7 @@ public class aiInfoCmd extends AbstractDevCmd { output += "Players Loaded:" + newline; } for (Map.Entry entry : mob.playerAgroMap.entrySet()) { - output += "Player ID: " + entry.getKey() + " Is Safemode: " + entry.getValue() + newline; + output += "Player ID: " + entry.getKey() + " Hate Value: " + ((PlayerCharacter) mob.getCombatTarget()).getHateValue() + newline; } if (mob.getCombatTarget() != null) output += "Current Target: " + mob.getCombatTarget().getName() + newline; From 59c976c073d0c3ddb21aaf017558918f626b5664 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 8 Aug 2023 11:45:42 -0500 Subject: [PATCH 28/35] guards use hate value --- src/engine/mobileAI/MobAI.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 56259939..76c143d1 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -1058,7 +1058,10 @@ public class MobAI { try { if (mob.getCombatTarget() == null) CheckForPlayerGuardAggro(mob); + AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob); + if (newTarget != null) + mob.setCombatTarget(newTarget); CheckMobMovement(mob); CheckForAttack(mob); } catch (Exception e) { From 6e255d9c75071d3636cefd7a5fe0586b49f4f719 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 8 Aug 2023 11:51:04 -0500 Subject: [PATCH 29/35] guards hate value change target --- src/engine/devcmd/cmds/aiInfoCmd.java | 2 +- src/engine/mobileAI/MobAI.java | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/engine/devcmd/cmds/aiInfoCmd.java b/src/engine/devcmd/cmds/aiInfoCmd.java index 1caf90c9..e31060bb 100644 --- a/src/engine/devcmd/cmds/aiInfoCmd.java +++ b/src/engine/devcmd/cmds/aiInfoCmd.java @@ -77,7 +77,7 @@ public class aiInfoCmd extends AbstractDevCmd { output += "Players Loaded:" + newline; } for (Map.Entry entry : mob.playerAgroMap.entrySet()) { - output += "Player ID: " + entry.getKey() + " Hate Value: " + ((PlayerCharacter) mob.getCombatTarget()).getHateValue() + newline; + output += "Player ID: " + entry.getKey() + " Hate Value: " + (PlayerCharacter.getPlayerCharacter(entry.getKey())).getHateValue() + newline; } if (mob.getCombatTarget() != null) output += "Current Target: " + mob.getCombatTarget().getName() + newline; diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 76c143d1..6be7f853 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -1073,7 +1073,13 @@ public class MobAI { try { if (!mob.npcOwner.isAlive() && mob.getCombatTarget() == null) { - CheckForPlayerGuardAggro(mob); + if(mob.getCombatTarget() == null) { + CheckForPlayerGuardAggro(mob); + }else { + AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob); + if (newTarget != null) + mob.setCombatTarget(newTarget); + } }else { if (mob.npcOwner.getCombatTarget() != null) mob.setCombatTarget(mob.npcOwner.getCombatTarget()); From e88e8b56c6804eca88a558478696af97dcf83ad8 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 8 Aug 2023 12:49:25 -0500 Subject: [PATCH 30/35] mobs only toggle combat mode when changing combat target --- src/engine/mobileAI/MobAI.java | 47 +---------------------- src/engine/objects/AbstractCharacter.java | 19 +++++++++ 2 files changed, 21 insertions(+), 45 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 6be7f853..cfa0b840 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -235,7 +235,7 @@ public class MobAI { CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false)); mob.setLastAttackTime(System.currentTimeMillis() + attackDelay); if (target.combatTarget == null) { - target.combatTarget = mob; + target.setCombatTarget(mob); } } } catch (Exception e) { @@ -249,13 +249,6 @@ public class MobAI { //make sure mob is out of combat stance - if (mob.isCombat() && mob.getCombatTarget() == null) { - mob.setCombat(false); - UpdateStateMsg rwss = new UpdateStateMsg(); - rwss.setPlayer(mob); - DispatchMessage.sendToAllInRange(mob, rwss); - } - int patrolDelay = ThreadLocalRandom.current().nextInt((int) (MobAIThread.AI_PATROL_DIVISOR * 0.5f), MobAIThread.AI_PATROL_DIVISOR) + MobAIThread.AI_PATROL_DIVISOR; //early exit while waiting to patrol again @@ -289,12 +282,6 @@ public class MobAI { //make sure mob is out of combat stance if (minion.getKey().despawned == false) { - if (minion.getKey().isCombat() && minion.getKey().getCombatTarget() == null) { - minion.getKey().setCombat(false); - UpdateStateMsg rwss = new UpdateStateMsg(); - rwss.setPlayer(minion.getKey()); - DispatchMessage.sendToAllInRange(minion.getKey(), rwss); - } if (MovementUtilities.canMove(minion.getKey())) { Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3); minion.getKey().updateLocation(); @@ -655,14 +642,6 @@ public class MobAI { mob.setCombatTarget(null); return; } - - if (mob.isCombat() && mob.getCombatTarget() == null) { - mob.setCombat(false); - UpdateStateMsg rwss = new UpdateStateMsg(); - rwss.setPlayer(mob); - DispatchMessage.sendToAllInRange(mob, rwss); - } - if (mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) CheckToSendMobHome(mob); @@ -912,23 +891,8 @@ public class MobAI { if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false && mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) { mob.setCombatTarget(null); - - if (mob.isCombat()) { - mob.setCombat(false); - UpdateStateMsg rwss = new UpdateStateMsg(); - rwss.setPlayer(mob); - DispatchMessage.sendToAllInRange(mob, rwss); - } return; } - - if (!mob.isCombat()) { - mob.setCombat(true); - UpdateStateMsg rwss = new UpdateStateMsg(); - rwss.setPlayer(mob); - DispatchMessage.sendToAllInRange(mob, rwss); - } - if (System.currentTimeMillis() > mob.getLastAttackTime()) AttackTarget(mob, mob.getCombatTarget()); @@ -1072,7 +1036,7 @@ public class MobAI { public static void GuardMinionLogic(Mob mob) { try { - if (!mob.npcOwner.isAlive() && mob.getCombatTarget() == null) { + if (!mob.npcOwner.isAlive()) { if(mob.getCombatTarget() == null) { CheckForPlayerGuardAggro(mob); }else { @@ -1343,13 +1307,6 @@ public class MobAI { //make sure mob is out of combat stance if (minion.getKey().despawned == false) { - if (minion.getKey().isCombat() && minion.getKey().getCombatTarget() == null) { - minion.getKey().setCombat(false); - UpdateStateMsg rwss = new UpdateStateMsg(); - rwss.setPlayer(minion.getKey()); - DispatchMessage.sendToAllInRange(minion.getKey(), rwss); - } - if (MovementUtilities.canMove(minion.getKey())) { Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3); minion.getKey().updateLocation(); diff --git a/src/engine/objects/AbstractCharacter.java b/src/engine/objects/AbstractCharacter.java index 5728617b..3b8615d2 100644 --- a/src/engine/objects/AbstractCharacter.java +++ b/src/engine/objects/AbstractCharacter.java @@ -28,6 +28,8 @@ import engine.math.AtomicFloat; import engine.math.Bounds; import engine.math.Vector3fImmutable; import engine.net.ByteBufferWriter; +import engine.net.DispatchMessage; +import engine.net.client.msg.UpdateStateMsg; import engine.powers.EffectsBase; import engine.server.MBServerStatics; import org.pmw.tinylog.Logger; @@ -1160,6 +1162,23 @@ public abstract class AbstractCharacter extends AbstractWorldObject { } public final void setCombatTarget(final AbstractWorldObject value) { + if(value.getObjectTypeMask() == MBServerStatics.MASK_MOB) { + if (value == null) { + if (this.isCombat()) { + this.setCombat(false); + UpdateStateMsg rwss = new UpdateStateMsg(); + rwss.setPlayer(this); + DispatchMessage.sendToAllInRange(this, rwss); + } else { + if (!this.isCombat()) { + this.setCombat(true); + UpdateStateMsg rwss = new UpdateStateMsg(); + rwss.setPlayer(this); + DispatchMessage.sendToAllInRange(this, rwss); + } + } + } + } this.combatTarget = value; } From 923447e983ae167931ab3724c0de86bc8e6a5543 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 8 Aug 2023 13:36:46 -0500 Subject: [PATCH 31/35] infinite loop fix --- src/engine/gameManager/NPCManager.java | 2 +- src/engine/mobileAI/MobAI.java | 24 +++++++++++++---------- src/engine/objects/AbstractCharacter.java | 16 +++++++-------- src/engine/objects/Mob.java | 10 +++++----- 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/engine/gameManager/NPCManager.java b/src/engine/gameManager/NPCManager.java index 176e4278..114da8ad 100644 --- a/src/engine/gameManager/NPCManager.java +++ b/src/engine/gameManager/NPCManager.java @@ -108,7 +108,7 @@ public enum NPCManager { public static void dismissNecroPet(Mob necroPet, boolean updateOwner) { - necroPet.combatTarget = null; + necroPet.setCombatTarget(null); necroPet.hasLoot = false; if (necroPet.parentZone != null) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index cfa0b840..514ad546 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -234,7 +234,7 @@ public class MobAI { attackDelay = 11000; CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false)); mob.setLastAttackTime(System.currentTimeMillis() + attackDelay); - if (target.combatTarget == null) { + if (target.getCombatTarget() == null) { target.setCombatTarget(mob); } } @@ -638,14 +638,15 @@ public class MobAI { //no players loaded, no need to proceed - if (mob.playerAgroMap.isEmpty() && mob.isPlayerGuard == false && mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) { - mob.setCombatTarget(null); + if (mob.playerAgroMap.isEmpty()) { + if(mob.getCombatTarget() != null) + mob.setCombatTarget(null); return; } if (mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) CheckToSendMobHome(mob); - if (mob.combatTarget != null) { + if (mob.getCombatTarget() != null) { if (mob.getCombatTarget().isAlive() == false) { mob.setCombatTarget(null); return; @@ -653,7 +654,7 @@ public class MobAI { if (mob.getCombatTarget().getObjectTypeMask() == MBServerStatics.MASK_PLAYER) { - PlayerCharacter target = (PlayerCharacter) mob.combatTarget; + PlayerCharacter target = (PlayerCharacter) mob.getCombatTarget(); if (mob.playerAgroMap.containsKey(target.getObjectUUID()) == false) { mob.setCombatTarget(null); @@ -745,7 +746,7 @@ public class MobAI { } - if (aiAgent.combatTarget == null) { + if (aiAgent.getCombatTarget() == null) { //look for pets to aggro if no players found to aggro @@ -1046,9 +1047,12 @@ public class MobAI { } }else { if (mob.npcOwner.getCombatTarget() != null) + if(mob.getCombatTarget() != null && mob.getCombatTarget().equals(mob.npcOwner.getCombatTarget()) == false) mob.setCombatTarget(mob.npcOwner.getCombatTarget()); else - mob.setCombatTarget(null); + if(mob.getCombatTarget() != null) { + mob.setCombatTarget(null); + } } CheckMobMovement(mob); CheckForAttack(mob); @@ -1110,7 +1114,7 @@ public class MobAI { if (mob.getCombatTarget() == null) SafeGuardAggro(mob); - else if (mob.combatTarget.isAlive() == false) + else if (mob.getCombatTarget().isAlive() == false) SafeGuardAggro(mob); CheckForAttack(mob); @@ -1151,7 +1155,7 @@ public class MobAI { //check if mob can attack if it isn't wimpy - if (!mob.BehaviourType.isWimpy && mob.combatTarget != null) + if (!mob.BehaviourType.isWimpy && mob.getCombatTarget() != null) CheckForAttack(mob); } catch (Exception e) { @@ -1199,7 +1203,7 @@ public class MobAI { if (GuardCanAggro(mob, loadedPlayer) == false) continue; - if (MovementUtilities.inRangeToAggro(mob, loadedPlayer)) { + if (MovementUtilities.inRangeToAggro(mob, loadedPlayer) && mob.getCombatTarget() == null) { mob.setCombatTarget(loadedPlayer); return; } diff --git a/src/engine/objects/AbstractCharacter.java b/src/engine/objects/AbstractCharacter.java index 3b8615d2..6f4bee73 100644 --- a/src/engine/objects/AbstractCharacter.java +++ b/src/engine/objects/AbstractCharacter.java @@ -1162,20 +1162,20 @@ public abstract class AbstractCharacter extends AbstractWorldObject { } public final void setCombatTarget(final AbstractWorldObject value) { - if(value.getObjectTypeMask() == MBServerStatics.MASK_MOB) { + if(this.getObjectTypeMask() == 2050) {//MOB? if (value == null) { if (this.isCombat()) { this.setCombat(false); UpdateStateMsg rwss = new UpdateStateMsg(); rwss.setPlayer(this); DispatchMessage.sendToAllInRange(this, rwss); - } else { - if (!this.isCombat()) { - this.setCombat(true); - UpdateStateMsg rwss = new UpdateStateMsg(); - rwss.setPlayer(this); - DispatchMessage.sendToAllInRange(this, rwss); - } + } + }else { + if (!this.isCombat()) { + this.setCombat(true); + UpdateStateMsg rwss = new UpdateStateMsg(); + rwss.setPlayer(this); + DispatchMessage.sendToAllInRange(this, rwss); } } } diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index e2f8d728..b5183c00 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -1305,7 +1305,7 @@ public class Mob extends AbstractIntelligenceAgent { } catch (Exception e) { Logger.error(e.getMessage()); } - this.combatTarget = null; + this.setCombatTarget(null); this.hasLoot = false; this.playerAgroMap.clear(); @@ -1329,7 +1329,7 @@ public class Mob extends AbstractIntelligenceAgent { } else if (this.isPet() || this.isNecroPet()) { //this.state = STATE.Disabled; - this.combatTarget = null; + this.setCombatTarget(null); this.hasLoot = false; //if (this.parentZone != null) @@ -1372,7 +1372,7 @@ public class Mob extends AbstractIntelligenceAgent { this.combat = false; this.walkMode = true; - this.combatTarget = null; + this.setCombatTarget(null); this.hasLoot = this.charItemManager.getInventoryCount() > 0; } catch (Exception e) { @@ -1391,7 +1391,7 @@ public class Mob extends AbstractIntelligenceAgent { this.mana.set(this.manaMax); this.combat = false; this.walkMode = true; - this.combatTarget = null; + this.setCombatTarget(null); this.isAlive.set(true); this.deathTime = 0; this.lastBindLoc = this.bindLoc; @@ -2079,7 +2079,7 @@ public class Mob extends AbstractIntelligenceAgent { PlayerCharacter player = (PlayerCharacter) ac; if (this.getCombatTarget() == null) { - this.combatTarget = ac; + this.setCombatTarget(ac); return; } From 0e78902ff61fd8397a582320e2f2c6036fab5b92 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 8 Aug 2023 14:22:49 -0500 Subject: [PATCH 32/35] ranged mobs attack at range again --- src/engine/mobileAI/MobAI.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 514ad546..0cb34cca 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -956,10 +956,12 @@ public class MobAI { try { - mob.updateMovementState(); - mob.updateLocation(); - - if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { + float rangeSquared = mob.getRange() * mob.getRange(); + float distanceSquared = mob.getLoc().distanceSquared2D(mob.getCombatTarget().getLoc()); + if(mob.isMoving() == true && distanceSquared < rangeSquared - 50) { + mob.destination = mob.getLoc(); + MovementUtilities.moveToLocation(mob, mob.destination, 0); + } else if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { if (mob.getRange() > 15) { mob.destination = mob.getCombatTarget().getLoc(); MovementUtilities.moveToLocation(mob, mob.destination, 0); @@ -978,11 +980,10 @@ public class MobAI { MovementUtilities.moveToLocation(mob, mob.getCombatTarget().getLoc(), 0); break; } - if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == true) { - mob.stopMovement(mob.getLoc()); - } } } + mob.updateMovementState(); + mob.updateLocation(); } catch (Exception e) { Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: chaseTarget" + " " + e.getMessage()); } From d04ee197d92ea9271dd883fc92310cd068da5097 Mon Sep 17 00:00:00 2001 From: MagicBot Date: Tue, 8 Aug 2023 18:25:40 -0400 Subject: [PATCH 33/35] Schema change to reflect new package. --- src/engine/db/handlers/dbLootHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/db/handlers/dbLootHandler.java b/src/engine/db/handlers/dbLootHandler.java index f44dfb3e..14c4bb99 100644 --- a/src/engine/db/handlers/dbLootHandler.java +++ b/src/engine/db/handlers/dbLootHandler.java @@ -191,7 +191,7 @@ public class dbLootHandler extends dbHandlerBase { int recordsRead = 0; try (Connection connection = DbManager.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_npc_bootySet")) { + PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_loot_bootySet")) { ResultSet rs = preparedStatement.executeQuery(); From b96b22232729c978372bd2ee92f712bae2a9a06f Mon Sep 17 00:00:00 2001 From: MagicBot Date: Tue, 8 Aug 2023 18:30:21 -0400 Subject: [PATCH 34/35] Booty moved to LootManager --- src/engine/devcmd/cmds/SimulateBootyCmd.java | 5 ++--- src/engine/gameManager/LootManager.java | 9 +++++---- src/engine/gameManager/NPCManager.java | 4 +--- src/engine/objects/MobBase.java | 4 ++-- src/engine/objects/NPC.java | 2 +- src/engine/server/world/WorldServer.java | 4 ++-- 6 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/engine/devcmd/cmds/SimulateBootyCmd.java b/src/engine/devcmd/cmds/SimulateBootyCmd.java index a6696881..f6ef0bb0 100644 --- a/src/engine/devcmd/cmds/SimulateBootyCmd.java +++ b/src/engine/devcmd/cmds/SimulateBootyCmd.java @@ -2,7 +2,6 @@ package engine.devcmd.cmds; import engine.devcmd.AbstractDevCmd; import engine.gameManager.LootManager; -import engine.gameManager.NPCManager; import engine.gameManager.ZoneManager; import engine.loot.BootySetEntry; import engine.objects.*; @@ -33,7 +32,7 @@ public class SimulateBootyCmd extends AbstractDevCmd { output += "Special Loot:" + newline; if (mob.bootySet != 0) { - for (BootySetEntry entry : NPCManager._bootySetMap.get(mob.bootySet)) { + for (BootySetEntry entry : LootManager._bootySetMap.get(mob.bootySet)) { ItemBase item = ItemBase.getItemBase(entry.itemBase); if (item != null) { output += "[" + entry.bootyType + "] " + item.getName() + " [Chance] " + entry.dropChance + newline; @@ -118,7 +117,7 @@ public class SimulateBootyCmd extends AbstractDevCmd { else dropRate = LootManager.NORMAL_DROP_RATE; - for (BootySetEntry entry : NPCManager._bootySetMap.get(mob.getMobBase().bootySet)) { + for (BootySetEntry entry : LootManager._bootySetMap.get(mob.getMobBase().bootySet)) { if (entry.bootyType.equals("GOLD")) output += "NORMAL TABLE [" + entry.bootyType + "] " + entry.genTable + ": " + entry.dropChance + newline; diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index 56b19d59..3b42d940 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -42,6 +42,7 @@ public enum LootManager { public static float HOTZONE_DROP_RATE; public static float HOTZONE_EXP_RATE; public static float HOTZONE_GOLD_RATE; + public static HashMap> _bootySetMap = new HashMap<>(); // Bootstrap routine to initialize the Loot Manager @@ -73,11 +74,11 @@ public enum LootManager { //iterate the booty sets - if (mob.getMobBase().bootySet != 0 && NPCManager._bootySetMap.containsKey(mob.getMobBase().bootySet) == true) - RunBootySet(NPCManager._bootySetMap.get(mob.getMobBase().bootySet), mob, inHotzone, fromDeath); + if (mob.getMobBase().bootySet != 0 && _bootySetMap.containsKey(mob.getMobBase().bootySet) == true) + RunBootySet(_bootySetMap.get(mob.getMobBase().bootySet), mob, inHotzone, fromDeath); - if (mob.bootySet != 0 && NPCManager._bootySetMap.containsKey(mob.bootySet) == true) - RunBootySet(NPCManager._bootySetMap.get(mob.bootySet), mob, inHotzone, fromDeath); + if (mob.bootySet != 0 && _bootySetMap.containsKey(mob.bootySet) == true) + RunBootySet(_bootySetMap.get(mob.bootySet), mob, inHotzone, fromDeath); //lastly, check mobs inventory for godly or disc runes to send a server announcement diff --git a/src/engine/gameManager/NPCManager.java b/src/engine/gameManager/NPCManager.java index 114da8ad..7465fddc 100644 --- a/src/engine/gameManager/NPCManager.java +++ b/src/engine/gameManager/NPCManager.java @@ -2,7 +2,6 @@ package engine.gameManager; import engine.Enum; import engine.InterestManagement.WorldGrid; -import engine.loot.BootySetEntry; import engine.net.Dispatch; import engine.net.DispatchMessage; import engine.net.client.msg.PetMsg; @@ -18,14 +17,13 @@ public enum NPCManager { NPC_MANAGER; public static HashMap> _runeSetMap = new HashMap<>(); - public static HashMap> _bootySetMap = new HashMap<>(); public static void LoadAllRuneSets() { _runeSetMap = DbManager.ItemBaseQueries.LOAD_RUNES_FOR_NPC_AND_MOBS(); } public static void LoadAllBootySets() { - _bootySetMap = DbManager.LootQueries.LOAD_BOOTY_TABLES(); + LootManager._bootySetMap = DbManager.LootQueries.LOAD_BOOTY_TABLES(); } public static void applyRuneSetEffects(Mob mob) { diff --git a/src/engine/objects/MobBase.java b/src/engine/objects/MobBase.java index 66620a25..80adffb0 100644 --- a/src/engine/objects/MobBase.java +++ b/src/engine/objects/MobBase.java @@ -12,7 +12,7 @@ package engine.objects; import ch.claude_martin.enumbitset.EnumBitSet; import engine.Enum; import engine.gameManager.DbManager; -import engine.gameManager.NPCManager; +import engine.gameManager.LootManager; import engine.loot.BootySetEntry; import engine.server.MBServerStatics; @@ -119,7 +119,7 @@ public class MobBase extends AbstractGameObject { if (equipmentSetID == 0) return equip; - equipList = NPCManager._bootySetMap.get(equipmentSetID); + equipList = LootManager._bootySetMap.get(equipmentSetID); if (equipList == null) return equip; diff --git a/src/engine/objects/NPC.java b/src/engine/objects/NPC.java index ae21de63..a45da7a3 100644 --- a/src/engine/objects/NPC.java +++ b/src/engine/objects/NPC.java @@ -617,7 +617,7 @@ public class NPC extends AbstractCharacter { public static boolean UpdateEquipSetID(NPC npc, int equipSetID) { - if (!NPCManager._bootySetMap.containsKey(equipSetID)) + if (!LootManager._bootySetMap.containsKey(equipSetID)) return false; if (!DbManager.NPCQueries.UPDATE_EQUIPSET(npc, equipSetID)) diff --git a/src/engine/server/world/WorldServer.java b/src/engine/server/world/WorldServer.java index d312ca10..f08a93ea 100644 --- a/src/engine/server/world/WorldServer.java +++ b/src/engine/server/world/WorldServer.java @@ -333,8 +333,8 @@ public class WorldServer { Logger.info("Loading NPC and Mob Rune Sets"); NPCManager.LoadAllRuneSets(); - Logger.info("Loading Mobile Booty Sets"); - NPCManager.LoadAllBootySets(); + Logger.info("Loading Booty Sets"); + LootManager._bootySetMap = DbManager.LootQueries.LOAD_BOOTY_TABLES(); // Load new loot system Logger.info("Initializing Loot Manager"); From 64ca876920e18bc7ca3d93a6c6957f1ae7658185 Mon Sep 17 00:00:00 2001 From: MagicBot Date: Tue, 8 Aug 2023 19:08:51 -0400 Subject: [PATCH 35/35] CanAggro check added to guard logic. --- src/engine/mobileAI/MobAI.java | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 0cb34cca..a54ea968 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -20,7 +20,6 @@ import engine.mobileAI.utilities.MovementUtilities; import engine.net.DispatchMessage; import engine.net.client.msg.PerformActionMsg; import engine.net.client.msg.PowerProjectileMsg; -import engine.net.client.msg.UpdateStateMsg; import engine.objects.*; import engine.powers.ActionsBase; import engine.powers.PowersBase; @@ -1024,10 +1023,19 @@ public class MobAI { try { if (mob.getCombatTarget() == null) CheckForPlayerGuardAggro(mob); + AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob); - if (newTarget != null) - mob.setCombatTarget(newTarget); + 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) { @@ -1039,12 +1047,22 @@ public class MobAI { try { if (!mob.npcOwner.isAlive()) { + if(mob.getCombatTarget() == null) { CheckForPlayerGuardAggro(mob); }else { + AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob); - if (newTarget != null) - mob.setCombatTarget(newTarget); + + if (newTarget != null) { + + if (newTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { + if (GuardCanAggro(mob, (PlayerCharacter) newTarget)) + mob.setCombatTarget(newTarget); + } else + mob.setCombatTarget(newTarget); + + } } }else { if (mob.npcOwner.getCombatTarget() != null)