From c722450f653f93c8b62697a1a89c30152219a0d8 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 12 Feb 2025 17:06:44 -0600 Subject: [PATCH 001/151] proper XP group scaling --- src/engine/objects/Experience.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/engine/objects/Experience.java b/src/engine/objects/Experience.java index fcac28f9..6e1edae7 100644 --- a/src/engine/objects/Experience.java +++ b/src/engine/objects/Experience.java @@ -409,7 +409,6 @@ public class Experience { grantedExperience = (double) LOOTMANAGER.NORMAL_EXP_RATE * maxXPPerKill(playerCharacter.getLevel()); - grantedExperience *= (1/ giveEXPTo.size()+0.9); // Adjust XP for Mob Level grantedExperience *= getConMod(playerCharacter, mob); @@ -446,6 +445,9 @@ public class Experience { if (grantedExperience == 0) grantedExperience = 1; + //scaling + grantedExperience *= (1 / giveEXPTo.size()+0.9); + // Grant the player the EXP playerCharacter.grantXP((int) Math.floor(grantedExperience)); } @@ -469,9 +471,13 @@ public class Experience { grantedExperience *= LOOTMANAGER.HOTZONE_EXP_RATE; // Errant penalty - if (grantedExperience != 1) + if (grantedExperience != 1) { if (killer.getGuild().isEmptyGuild()) - grantedExperience *= .6; + grantedExperience *= 0.6f; + } + + //bonus for no group + grantedExperience *= 1.9f; // Grant XP killer.grantXP((int) Math.floor(grantedExperience)); From 6ed648d6d4b514c0e2f0d3c94adee9394ec1f94a Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 12 Feb 2025 17:14:04 -0600 Subject: [PATCH 002/151] catch weird city null error --- src/engine/objects/City.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/engine/objects/City.java b/src/engine/objects/City.java index 48551a82..ad6b3f93 100644 --- a/src/engine/objects/City.java +++ b/src/engine/objects/City.java @@ -395,8 +395,14 @@ public class City extends AbstractWorldObject { //open city, just list if (city.open && city.getTOL() != null && city.getTOL().getRank() > 4) { cities.add(city); - }else if(city.getGuild().getNation().equals(pc.guild.getNation())){ - cities.add(city); + }else { + try { + if (city.getGuild().getNation().equals(pc.guild.getNation())) { + cities.add(city); + } + }catch(Exception e){ + Logger.error(e); + } } } } else if (city.isNpc == 1) { From 86c95f0eb5dac6963f70bb9a95903bb770fea6bd Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 12 Feb 2025 17:20:15 -0600 Subject: [PATCH 003/151] disable gimme command --- src/engine/gameManager/DevCmdManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/gameManager/DevCmdManager.java b/src/engine/gameManager/DevCmdManager.java index f6d74a11..1016bfcf 100644 --- a/src/engine/gameManager/DevCmdManager.java +++ b/src/engine/gameManager/DevCmdManager.java @@ -207,7 +207,7 @@ public enum DevCmdManager { case "printskills": case "printpowers": case "printbonuses": - case "gimme": + //case "gimme": playerAllowed = true; if (!a.status.equals(Enum.AccountStatus.ADMIN)) target = pcSender; From 7b33c1392ad2438f17e87c3024db2d26454ae6cf Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 13 Feb 2025 20:21:52 -0600 Subject: [PATCH 004/151] set mob level earlier in routine --- src/engine/objects/Mob.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index c9472b91..c9479788 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -620,6 +620,7 @@ public class Mob extends AbstractIntelligenceAgent { DbManager.addToCache(mob); mob.setPet(owner, true); mob.setWalkMode(false); + mob.level = level; mob.runAfterLoad(); } catch (Exception e) { @@ -628,9 +629,9 @@ public class Mob extends AbstractIntelligenceAgent { createLock.writeLock().unlock(); } parent.zoneMobSet.add(mob); - mob.level = level; - mob.healthMax = mob.getMobBase().getHealthMax() * (mob.level * 0.5f); - mob.health.set(mob.healthMax); + // mob.level = level; + //mob.healthMax = mob.getMobBase().getHealthMax() * (mob.level * 0.5f); + //mob.health.set(mob.healthMax); return mob; } From d56d58492a9c558bc96710626a63fa5eb3645b43 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 13 Feb 2025 20:29:35 -0600 Subject: [PATCH 005/151] huntress pets properly granted modifiers --- src/engine/objects/Mob.java | 8 ++++++-- src/engine/objects/MobBase.java | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index c9479788..f104420a 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -630,8 +630,12 @@ public class Mob extends AbstractIntelligenceAgent { } parent.zoneMobSet.add(mob); // mob.level = level; - //mob.healthMax = mob.getMobBase().getHealthMax() * (mob.level * 0.5f); - //mob.health.set(mob.healthMax); + float healthMax = mob.getMobBase().getHealthMax(); + if(mob.bonuses != null){ + healthMax += mob.bonuses.getFloat(ModType.HealthFull,SourceType.None); + } + mob.healthMax = healthMax; + mob.health.set(mob.healthMax); return mob; } diff --git a/src/engine/objects/MobBase.java b/src/engine/objects/MobBase.java index 6fb2efc6..ce41d879 100644 --- a/src/engine/objects/MobBase.java +++ b/src/engine/objects/MobBase.java @@ -308,6 +308,10 @@ public class MobBase extends AbstractGameObject { } public static void applyMobbaseEffects(Mob mob){ + if(mob.getMobBaseID() == 12008) + mob.level = 65; + else if(mob.getMobBaseID() == 12019) + mob.level = 80; for(MobBaseEffects mbe : mob.mobBase.mobbaseEffects){ if(mob.level >= mbe.getReqLvl()){ try { From a75670bf0e053e87c238ab04823f9abab4efdbe9 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 13 Feb 2025 20:32:16 -0600 Subject: [PATCH 006/151] retaliate handled properly --- src/engine/mobileAI/utilities/CombatUtilities.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/engine/mobileAI/utilities/CombatUtilities.java b/src/engine/mobileAI/utilities/CombatUtilities.java index 6cc19a04..4b95d5cc 100644 --- a/src/engine/mobileAI/utilities/CombatUtilities.java +++ b/src/engine/mobileAI/utilities/CombatUtilities.java @@ -201,12 +201,10 @@ public class CombatUtilities { return; int anim = 75; - float speed; - if (mainHand) - speed = agent.getSpeedHandOne(); - else - speed = agent.getSpeedHandTwo(); + //handle the retaliate here because even if the mob misses you can still retaliate + if (AbstractWorldObject.IsAbstractCharacter(target)) + CombatManager.handleRetaliate((AbstractCharacter) target, agent); DamageType dt = DamageType.Crush; @@ -288,11 +286,6 @@ public class CombatUtilities { if (((Mob) target).isSiege()) return; - //handle the retaliate - - if (AbstractWorldObject.IsAbstractCharacter(target)) - CombatManager.handleRetaliate((AbstractCharacter) target, agent); - if (target.getObjectType() == GameObjectType.Mob) { Mob targetMob = (Mob) target; if (targetMob.isSiege()) From 24e01acff435120535fcb28f265012ffb32d6a1d Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 13 Feb 2025 20:37:45 -0600 Subject: [PATCH 007/151] pet assistance --- src/engine/gameManager/CombatManager.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index ca22e760..32367e01 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -301,6 +301,17 @@ public enum CombatManager { if (target == null) return 0; + //pet to assist in attacking target + if(abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter)){ + PlayerCharacter attacker = (PlayerCharacter)abstractCharacter; + if(attacker.getPet() != null){ + Mob pet = attacker.getPet(); + if(pet.combatTarget == null && pet.assist) + pet.setCombatTarget(attacker.combatTarget); + } + } + + //target must be valid type if (AbstractWorldObject.IsAbstractCharacter(target)) { From 048474b014a89ec3ec40c2508ba95dffe1ea4042 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 15 Feb 2025 06:44:16 -0600 Subject: [PATCH 008/151] must be in safezone to switch boxes --- src/engine/objects/PlayerCharacter.java | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 241e066c..8f519ec9 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -5229,14 +5229,22 @@ public class PlayerCharacter extends AbstractCharacter { } } - for(PlayerCharacter pc : sameMachine) - pc.isBoxed = true; - - player.isBoxed = false; - if(player.containsEffect(1672601862)) { - player.removeEffectBySource(EffectSourceType.DeathShroud,41,false); + boolean valid = true; + for(PlayerCharacter pc : sameMachine){ + if(!pc.safeZone) + valid = false; } + if(valid) { + for (PlayerCharacter pc : sameMachine) + pc.isBoxed = true; + player.isBoxed = false; + if (player.containsEffect(1672601862)) { + player.removeEffectBySource(EffectSourceType.DeathShroud, 41, false); + } + }else{ + ChatManager.chatSystemInfo(player, "All Boxes Must Be In Safezone To Switch"); + } } public static boolean checkIfBoxed(PlayerCharacter player){ if(ConfigManager.MB_WORLD_BOXLIMIT.getValue().equals("false")) { From 5a3f4e690f209ca91f3b58500ce50932dccf5d22 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 15 Feb 2025 06:46:17 -0600 Subject: [PATCH 009/151] mobs will attack player pets --- src/engine/mobileAI/MobAI.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index ee73be43..fb99aa09 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -106,6 +106,11 @@ public class MobAI { return; } + if(target.getPet() != null && target.getPet().isAlive()){ + mob.setCombatTarget(target.getPet()); + return; + } + if (mob.BehaviourType.callsForHelp) MobCallForHelp(mob); From c5e6205801948faf5ff3ea8b89291ea8c0b2e463 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 15 Feb 2025 07:52:39 -0600 Subject: [PATCH 010/151] invis mob solution --- src/engine/mobileAI/MobAI.java | 8 ++++++++ src/engine/mobileAI/Threads/MobRespawnThread.java | 9 ++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index fb99aa09..d5f01e7d 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -9,6 +9,7 @@ package engine.mobileAI; import engine.Enum; +import engine.InterestManagement.InterestManager; import engine.InterestManagement.WorldGrid; import engine.gameManager.*; import engine.math.Vector3f; @@ -161,6 +162,12 @@ public class MobAI { if (target.getPet().getCombatTarget() == null && target.getPet().assist == true) target.getPet().setCombatTarget(mob); + try{ + InterestManager.forceLoad(mob); + }catch(Exception e){ + + } + } catch (Exception e) { Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackPlayer" + " " + e.getMessage()); } @@ -1221,6 +1228,7 @@ public class MobAI { if (!mob.BehaviourType.isWimpy && mob.getCombatTarget() != null) CheckForAttack(mob); + } catch (Exception e) { Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DefaultLogic" + " " + e.getMessage()); } diff --git a/src/engine/mobileAI/Threads/MobRespawnThread.java b/src/engine/mobileAI/Threads/MobRespawnThread.java index 7bc3a9d6..717c5c2c 100644 --- a/src/engine/mobileAI/Threads/MobRespawnThread.java +++ b/src/engine/mobileAI/Threads/MobRespawnThread.java @@ -43,14 +43,13 @@ public class MobRespawnThread implements Runnable { if (zones != null) { for (Zone zone : zones) { synchronized (zone) { // Optional: Synchronize on zone - if (!zone.respawnQue.isEmpty() && - zone.lastRespawn + RESPAWN_INTERVAL < System.currentTimeMillis()) { + if (!Zone.respawnQue.isEmpty() && Zone.lastRespawn + RESPAWN_INTERVAL < System.currentTimeMillis()) { - Mob respawner = zone.respawnQue.iterator().next(); + Mob respawner = Zone.respawnQue.iterator().next(); if (respawner != null) { respawner.respawn(); - zone.respawnQue.remove(respawner); - zone.lastRespawn = System.currentTimeMillis(); + Zone.respawnQue.remove(respawner); + Zone.lastRespawn = System.currentTimeMillis(); Thread.sleep(100); } } From 4ae64ab94c13985cea57c1440c86adf98e27383c Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 15 Feb 2025 10:46:14 -0600 Subject: [PATCH 011/151] pet aggro fix --- 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 d5f01e7d..d2d79c38 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -107,8 +107,9 @@ public class MobAI { return; } - if(target.getPet() != null && target.getPet().isAlive()){ + if(target.getPet() != null && target.getPet().isAlive() && !target.getPet().isSiege()){ mob.setCombatTarget(target.getPet()); + AttackTarget(mob,mob.combatTarget); return; } From 8d587538e0aa5ba7044707070993ce4f870ffd04 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 15 Feb 2025 12:08:40 -0600 Subject: [PATCH 012/151] uptime to show boxed and active players --- src/engine/server/world/WorldServer.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/engine/server/world/WorldServer.java b/src/engine/server/world/WorldServer.java index 62ac5654..fd9ed067 100644 --- a/src/engine/server/world/WorldServer.java +++ b/src/engine/server/world/WorldServer.java @@ -164,7 +164,17 @@ public class WorldServer { long uptimeSeconds = Math.abs(uptimeDuration.getSeconds()); String uptime = String.format("%d hours %02d minutes %02d seconds", uptimeSeconds / 3600, (uptimeSeconds % 3600) / 60, (uptimeSeconds % 60)); outString += "uptime: " + uptime; - outString += " pop: " + SessionManager.getActivePlayerCharacterCount() + " max pop: " + SessionManager._maxPopulation; + int activePop = 0; + int boxedPop = 0; + for(PlayerCharacter pc : SessionManager.getAllActivePlayerCharacters()){ + if(pc.isBoxed){ + boxedPop ++; + }else{ + activePop ++; + } + } + //outString += " pop: " + SessionManager.getActivePlayerCharacterCount() + " max pop: " + SessionManager._maxPopulation; + outString += "Active Players: " + activePop + " Boxed Players: " + boxedPop; } catch (Exception e) { Logger.error("Failed to build string"); } From 4ad7e0f021b4db0b5cd103f9b9b837cd8ce7aced Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 15 Feb 2025 12:19:29 -0600 Subject: [PATCH 013/151] fix track power range --- src/engine/gameManager/PowersManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index 77c74054..b8d0bcb5 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -1627,6 +1627,7 @@ public enum PowersManager { case 431511776: case 429578587: case 429503360: + case 44106356: trackChars = getTrackList(playerCharacter); break; default: From e6eb75366671a5b90cf2ed695ed654fe00293ceb Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 15 Feb 2025 22:12:37 -0600 Subject: [PATCH 014/151] audit chat messages for target ID --- src/engine/gameManager/ChatManager.java | 5 +++++ src/engine/util/KeyCloneAudit.java | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/engine/gameManager/ChatManager.java b/src/engine/gameManager/ChatManager.java index 496cfb6c..b2542227 100644 --- a/src/engine/gameManager/ChatManager.java +++ b/src/engine/gameManager/ChatManager.java @@ -27,6 +27,7 @@ import engine.objects.*; import engine.server.MBServerStatics; import engine.server.world.WorldServer; import engine.session.Session; +import engine.util.KeyCloneAudit; import org.pmw.tinylog.Logger; import java.util.ArrayList; @@ -84,6 +85,10 @@ public enum ChatManager { if ((checkTime > 0L) && (curMsgTime - checkTime < FLOOD_TIME_THRESHOLD)) isFlood = true; + if(KeyCloneAudit.auditChatMsg(pc,msg.getMessage())){ + return; + } + switch (protocolMsg) { case CHATSAY: ChatManager.chatSay(pc, msg.getMessage(), isFlood); diff --git a/src/engine/util/KeyCloneAudit.java b/src/engine/util/KeyCloneAudit.java index 9307930e..52629844 100644 --- a/src/engine/util/KeyCloneAudit.java +++ b/src/engine/util/KeyCloneAudit.java @@ -2,6 +2,7 @@ package engine.util; import engine.gameManager.ConfigManager; import engine.gameManager.DbManager; +import engine.gameManager.GroupManager; import engine.gameManager.SessionManager; import engine.net.client.ClientConnection; import engine.net.client.Protocol; @@ -15,6 +16,24 @@ import org.pmw.tinylog.Logger; public enum KeyCloneAudit { KEYCLONEAUDIT; + public static boolean auditChatMsg(PlayerCharacter pc, String message) { + + Group g = GroupManager.getGroup(pc); + + if(g == null) + return false; + + if(pc.combatTarget != null && message.contains(String.valueOf(pc.combatTarget.getObjectUUID()))){ + //targeting software detected + for(PlayerCharacter member : g.members){ + member.getClientConnection().forceDisconnect(); + } + return true; + } + + return false; + } + public void audit(PlayerCharacter player, Group group) { int machineCount = 0; From 944290f9589820e27d91161c4693031df8638f98 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 16 Feb 2025 08:58:49 -0600 Subject: [PATCH 015/151] audit chat messages for target ID --- src/engine/util/KeyCloneAudit.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/engine/util/KeyCloneAudit.java b/src/engine/util/KeyCloneAudit.java index 52629844..95a89fed 100644 --- a/src/engine/util/KeyCloneAudit.java +++ b/src/engine/util/KeyCloneAudit.java @@ -18,16 +18,17 @@ public enum KeyCloneAudit { public static boolean auditChatMsg(PlayerCharacter pc, String message) { - Group g = GroupManager.getGroup(pc); + if(pc.combatTarget != null && message.contains(String.valueOf(pc.combatTarget.getObjectUUID()))) { + //targeting software detected - if(g == null) - return false; + Group g = GroupManager.getGroup(pc); + + if (g == null) + pc.getClientConnection().forceDisconnect(); + else + for (PlayerCharacter member : g.members) + member.getClientConnection().forceDisconnect(); - if(pc.combatTarget != null && message.contains(String.valueOf(pc.combatTarget.getObjectUUID()))){ - //targeting software detected - for(PlayerCharacter member : g.members){ - member.getClientConnection().forceDisconnect(); - } return true; } From 9d79afa3955d2413d1d9d8626580aa185e29be77 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 15 Feb 2025 06:28:25 -0600 Subject: [PATCH 016/151] player update optimized --- src/engine/workthreads/UpdateThread.java | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/engine/workthreads/UpdateThread.java b/src/engine/workthreads/UpdateThread.java index 27d5f4b2..86b3ff80 100644 --- a/src/engine/workthreads/UpdateThread.java +++ b/src/engine/workthreads/UpdateThread.java @@ -45,18 +45,12 @@ public class UpdateThread implements Runnable { public void run() { lastRun = System.currentTimeMillis(); while (true) { - if (System.currentTimeMillis() >= lastRun + instancedelay) { // Correct condition + try { this.processPlayerUpdate(); - lastRun = System.currentTimeMillis(); // Update lastRun after processing - }else { - try { - Thread.sleep(100); // Pause for 100ms to reduce CPU usage - } catch (InterruptedException e) { - Logger.error("Thread interrupted", e); - Thread.currentThread().interrupt(); - } + Thread.sleep(100); // Pause for 100ms to reduce CPU usage + } catch (InterruptedException e) { + Logger.error("Thread interrupted", e); } - Thread.yield(); } } From 96731bd9bbcaee9e1f47cb123059e8e97067d3b0 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 17 Feb 2025 17:00:34 -0600 Subject: [PATCH 017/151] saetor inherit racetype --- src/engine/Enum.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/engine/Enum.java b/src/engine/Enum.java index c464da5f..d82f9f4d 100644 --- a/src/engine/Enum.java +++ b/src/engine/Enum.java @@ -150,7 +150,8 @@ public class Enum { NEPHFEMALE(2026, MonsterType.Nephilim, RunSpeed.STANDARD, CharacterSex.FEMALE, 1.1f), HALFGIANTFEMALE(2027, MonsterType.HalfGiant, RunSpeed.STANDARD, CharacterSex.FEMALE, 1.15f), VAMPMALE(2028, MonsterType.Vampire, RunSpeed.STANDARD, CharacterSex.MALE, 1), - VAMPFEMALE(2029, MonsterType.Vampire, RunSpeed.STANDARD, CharacterSex.FEMALE, 1); + VAMPFEMALE(2029, MonsterType.Vampire, RunSpeed.STANDARD, CharacterSex.FEMALE, 1), + SAETOR(1999,MonsterType.Minotaur, RunSpeed.MINOTAUR, CharacterSex.MALE,1); @SuppressWarnings("unchecked") private static HashMap _raceTypeByID = new HashMap<>(); From 3cf38da5675e71ebf5b0b3680caa55ba07188e1f Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 17 Feb 2025 17:09:11 -0600 Subject: [PATCH 018/151] no stam drain while TS --- src/engine/objects/PlayerCharacter.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 8f519ec9..e0d3a85e 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -5759,10 +5759,15 @@ public class PlayerCharacter extends AbstractCharacter { } else { healthRegen = 0; manaRegen = 0; - if (this.combat == true) - stamRegen = MBServerStatics.STAMINA_REGEN_RUN_COMBAT; - else - stamRegen = MBServerStatics.STAMINA_REGEN_RUN_NONCOMBAT; + + if(this.containsEffect(441156479) || this.containsEffect(441156455)) { + stamRegen = MBServerStatics.STAMINA_REGEN_WALK; + }else { + if (this.combat == true) + stamRegen = MBServerStatics.STAMINA_REGEN_RUN_COMBAT; + else + stamRegen = MBServerStatics.STAMINA_REGEN_RUN_NONCOMBAT; + } } break; case FLYING: From 4c0b480aebaa5d4a79fef608bf165c29e1944f21 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 17 Feb 2025 19:06:28 -0600 Subject: [PATCH 019/151] trainer merchants --- src/engine/objects/Contract.java | 15 +++++++++++++++ src/engine/objects/VendorDialog.java | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/engine/objects/Contract.java b/src/engine/objects/Contract.java index 97d689fa..f814212f 100644 --- a/src/engine/objects/Contract.java +++ b/src/engine/objects/Contract.java @@ -323,6 +323,21 @@ public class Contract extends AbstractGameObject { pc.charItemManager.updateInventory(); } + + public static boolean isClassTrainer(int id){ + if(id >= 5 && id <= 30) + return true; + return false; + } + public static VendorDialog trainerDialog(VendorDialog vd){ + VendorDialog returnedVD = new VendorDialog("Test","Test",19991999); + returnedVD.options = new ArrayList(); + if(isClassTrainer(vd.getObjectUUID())) { + MenuOption option1 = new MenuOption(19991999, "Class Market", 19991999); + vd.getOptions().add(option1); + } + return returnedVD; + } public static VendorDialog HandleBaneCommanderOptions(int optionId, NPC npc, PlayerCharacter pc){ pc.setLastNPCDialog(npc); VendorDialog vd = new VendorDialog(VendorDialog.getHostileVendorDialog().getDialogType(),VendorDialog.getHostileVendorDialog().getIntro(),-1);//VendorDialog.getHostileVendorDialog(); diff --git a/src/engine/objects/VendorDialog.java b/src/engine/objects/VendorDialog.java index 674f34ea..f2071bf2 100644 --- a/src/engine/objects/VendorDialog.java +++ b/src/engine/objects/VendorDialog.java @@ -21,7 +21,7 @@ public class VendorDialog extends AbstractGameObject { private static VendorDialog vd; private final String dialogType; private final String intro; - private ArrayList options = new ArrayList<>(); + ArrayList options = new ArrayList<>(); public VendorDialog(String dialogType, String intro, int UUID) { super(UUID); From bb05bdd87c7538244b19ea2b5f03c37ed7184f56 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 17 Feb 2025 19:30:58 -0600 Subject: [PATCH 020/151] handle trainer inventories --- .../net/client/msg/VendorDialogMsg.java | 6 ++++++ src/engine/objects/Contract.java | 21 +++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/engine/net/client/msg/VendorDialogMsg.java b/src/engine/net/client/msg/VendorDialogMsg.java index 3fcb2b83..7053a90d 100644 --- a/src/engine/net/client/msg/VendorDialogMsg.java +++ b/src/engine/net/client/msg/VendorDialogMsg.java @@ -82,6 +82,11 @@ public class VendorDialogMsg extends ClientNetMsg { return; } + if(msg.getUnknown03() == 19991999){ + Contract.handleTrainerInventoryWindow(playerCharacter,msg); + return; + } + // Get NPC that player is talking to NPC npc = NPC.getFromCache(msg.vendorObjectID); int npcClassID; @@ -147,6 +152,7 @@ public class VendorDialogMsg extends ClientNetMsg { return; } //vd = VendorDialog.getVendorDialog(msg.unknown03); + vd = Contract.trainerDialog(vd); msg.updateMessage(3, vd); } diff --git a/src/engine/objects/Contract.java b/src/engine/objects/Contract.java index f814212f..c9c7723b 100644 --- a/src/engine/objects/Contract.java +++ b/src/engine/objects/Contract.java @@ -16,6 +16,7 @@ import engine.net.Dispatch; import engine.net.DispatchMessage; import engine.net.client.msg.CityDataMsg; import engine.net.client.msg.ErrorPopupMsg; +import engine.net.client.msg.VendorDialogMsg; import org.joda.time.DateTime; import org.pmw.tinylog.Logger; @@ -329,15 +330,23 @@ public class Contract extends AbstractGameObject { return true; return false; } - public static VendorDialog trainerDialog(VendorDialog vd){ - VendorDialog returnedVD = new VendorDialog("Test","Test",19991999); - returnedVD.options = new ArrayList(); - if(isClassTrainer(vd.getObjectUUID())) { - MenuOption option1 = new MenuOption(19991999, "Class Market", 19991999); - vd.getOptions().add(option1); + + public static void handleTrainerInventoryWindow(PlayerCharacter pc, VendorDialogMsg msg){ + + } + public static VendorDialog trainerDialog(VendorDialog vd) { + + VendorDialog returnedVD = new VendorDialog(vd.getDialogType(), vd.getIntro(), 19991999); + returnedVD.options = new ArrayList<>(); + for (MenuOption mo : vd.options) + returnedVD.options.add(mo); + if (isClassTrainer(vd.getObjectUUID())) { + MenuOption option1 = new MenuOption(19991999, "Buy", 19991999); + returnedVD.options.add(option1); } return returnedVD; } + public static VendorDialog HandleBaneCommanderOptions(int optionId, NPC npc, PlayerCharacter pc){ pc.setLastNPCDialog(npc); VendorDialog vd = new VendorDialog(VendorDialog.getHostileVendorDialog().getDialogType(),VendorDialog.getHostileVendorDialog().getIntro(),-1);//VendorDialog.getHostileVendorDialog(); From 5dc9e127bbf713082377e1a6f0addfaf133489f3 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 17 Feb 2025 20:11:48 -0600 Subject: [PATCH 021/151] undo --- src/engine/net/client/msg/VendorDialogMsg.java | 6 ------ src/engine/objects/Contract.java | 17 ----------------- 2 files changed, 23 deletions(-) diff --git a/src/engine/net/client/msg/VendorDialogMsg.java b/src/engine/net/client/msg/VendorDialogMsg.java index 7053a90d..3fcb2b83 100644 --- a/src/engine/net/client/msg/VendorDialogMsg.java +++ b/src/engine/net/client/msg/VendorDialogMsg.java @@ -82,11 +82,6 @@ public class VendorDialogMsg extends ClientNetMsg { return; } - if(msg.getUnknown03() == 19991999){ - Contract.handleTrainerInventoryWindow(playerCharacter,msg); - return; - } - // Get NPC that player is talking to NPC npc = NPC.getFromCache(msg.vendorObjectID); int npcClassID; @@ -152,7 +147,6 @@ public class VendorDialogMsg extends ClientNetMsg { return; } //vd = VendorDialog.getVendorDialog(msg.unknown03); - vd = Contract.trainerDialog(vd); msg.updateMessage(3, vd); } diff --git a/src/engine/objects/Contract.java b/src/engine/objects/Contract.java index c9c7723b..3172b27c 100644 --- a/src/engine/objects/Contract.java +++ b/src/engine/objects/Contract.java @@ -330,23 +330,6 @@ public class Contract extends AbstractGameObject { return true; return false; } - - public static void handleTrainerInventoryWindow(PlayerCharacter pc, VendorDialogMsg msg){ - - } - public static VendorDialog trainerDialog(VendorDialog vd) { - - VendorDialog returnedVD = new VendorDialog(vd.getDialogType(), vd.getIntro(), 19991999); - returnedVD.options = new ArrayList<>(); - for (MenuOption mo : vd.options) - returnedVD.options.add(mo); - if (isClassTrainer(vd.getObjectUUID())) { - MenuOption option1 = new MenuOption(19991999, "Buy", 19991999); - returnedVD.options.add(option1); - } - return returnedVD; - } - public static VendorDialog HandleBaneCommanderOptions(int optionId, NPC npc, PlayerCharacter pc){ pc.setLastNPCDialog(npc); VendorDialog vd = new VendorDialog(VendorDialog.getHostileVendorDialog().getDialogType(),VendorDialog.getHostileVendorDialog().getIntro(),-1);//VendorDialog.getHostileVendorDialog(); From a99047aee81f11d0929acb67cd7615c6b2d8fce8 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 18 Feb 2025 09:47:38 -0600 Subject: [PATCH 022/151] ranged based tracking --- src/engine/gameManager/PowersManager.java | 30 +++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index b8d0bcb5..f16288eb 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -1623,18 +1623,28 @@ public enum PowersManager { // create list of characters HashSet trackChars; - switch(msg.getPowerToken()){ - case 431511776: - case 429578587: - case 429503360: - case 44106356: - trackChars = getTrackList(playerCharacter); - break; - default: - trackChars = RangeBasedAwo.getTrackList(allTargets, playerCharacter, maxTargets); - break; + + PowersBase trackPower = PowersManager.getPowerByToken(msg.getPowerToken()); + if(trackPower != null && trackPower.category.equals("TRACK")){ + trackChars = getTrackList(playerCharacter); + }else{ + trackChars = RangeBasedAwo.getTrackList(allTargets, playerCharacter, maxTargets); } + + + //switch(msg.getPowerToken()){ + // case 431511776: // Hunt Foe Huntress + // case 429578587: // Hunt Foe Scout + // case 429503360: // Track Huntsman + // case 44106356: // + // trackChars = getTrackList(playerCharacter); + // break; + // default: + // trackChars = RangeBasedAwo.getTrackList(allTargets, playerCharacter, maxTargets); + // break; + //} + TrackWindowMsg trackWindowMsg = new TrackWindowMsg(msg); // send track window From 1f7d2a14bfff0e6c5ffc3e7be831ae541205590c Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 18 Feb 2025 09:53:53 -0600 Subject: [PATCH 023/151] death no longer releases mine claims --- src/engine/objects/PlayerCharacter.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index e0d3a85e..d3ac92b7 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -1964,8 +1964,7 @@ public class PlayerCharacter extends AbstractCharacter { this.altitude = (float) 0; // Release Mine Claims - - Mine.releaseMineClaims(this); + //Mine.releaseMineClaims(this); this.getCharItemManager().closeTradeWindow(); From df2271fe2c74a407bc86251d7008c16655ce69fa Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 18 Feb 2025 17:46:26 -0600 Subject: [PATCH 024/151] universal rune drops --- src/engine/gameManager/LootManager.java | 72 ++++++++++++++----------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index 8b3ff967..034a8fad 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -258,37 +258,47 @@ public enum LootManager { } public static void SpecialCaseRuneDrop(Mob mob,ArrayList entries){ - int lootTableID = 0; - for(BootySetEntry entry : entries){ - if(entry.bootyType.equals("LOOT")){ - lootTableID = entry.genTable; - break; - } - } - - if(lootTableID == 0) - return; - - int RuneTableID = 0; - for(GenTableEntry entry : _genTables.get(lootTableID)){ - try { - if (ItemBase.getItemBase(_itemTables.get(entry.itemTableID).get(0).cacheID).getType().equals(Enum.ItemType.RUNE)) { - RuneTableID = entry.itemTableID; - break; + // int lootTableID = 0; + // for(BootySetEntry entry : entries){ + // if(entry.bootyType.equals("LOOT")){ + // lootTableID = entry.genTable; + // break; + // } + // } +// + //if(lootTableID == 0) + // return; +// + //int RuneTableID = 0; + //for(GenTableEntry entry : _genTables.get(lootTableID)){ + // try { + // if (ItemBase.getItemBase(_itemTables.get(entry.itemTableID).get(0).cacheID).getType().equals(Enum.ItemType.RUNE)) { + // RuneTableID = entry.itemTableID; + // break; + /// } + // }catch(Exception e){ + + // } + //} + + //if(RuneTableID == 0) + // return; + + NPC RuneMerchant = NPC.getNPC(801321); + if(RuneMerchant != null) { + ArrayList runeItems = RuneMerchant.contract.getSellInventory(); + int roll = ThreadLocalRandom.current().nextInt(0, runeItems.size()); + MobEquipment me = runeItems.get(roll); + if (me != null) { + ItemBase ib = me.getItemBase(); + if (ib != null) { + MobLoot toAdd = new MobLoot(mob, ib, false); + mob.getCharItemManager().addItemToInventory(toAdd); } - }catch(Exception e){ - } } - if(RuneTableID == 0) - return; - ItemBase ib = ItemBase.getItemBase(rollRandomItem(RuneTableID)); - if(ib != null){ - MobLoot toAdd = new MobLoot(mob,ib,false); - mob.getCharItemManager().addItemToInventory(toAdd); - } } public static void SpecialCaseResourceDrop(Mob mob,ArrayList entries){ @@ -572,7 +582,7 @@ public enum LootManager { ItemBase itemBase = me.getItemBase(); if(isVorg) { mob.spawnTime = ThreadLocalRandom.current().nextInt(300, 2700); - dropChance = 10; + dropChance = 7.5f; itemBase = getRandomVorg(itemBase); } if (equipmentRoll > dropChance) @@ -708,7 +718,7 @@ public enum LootManager { public static ItemBase getRandomVorg(ItemBase itemBase){ int roll = 0; if(vorg_ha_uuids.contains(itemBase.getUUID())) { - roll = ThreadLocalRandom.current().nextInt(0, 10); + roll = ThreadLocalRandom.current().nextInt(0, 9); switch (roll) { case 1: return ItemBase.getItemBase(vorg_ha_uuids.get(0)); @@ -732,7 +742,7 @@ public enum LootManager { } if(vorg_ma_uuids.contains(itemBase.getUUID())) { - roll = ThreadLocalRandom.current().nextInt(0, 10); + roll = ThreadLocalRandom.current().nextInt(0, 8); switch (roll) { case 1: return ItemBase.getItemBase(vorg_ma_uuids.get(0)); @@ -754,7 +764,7 @@ public enum LootManager { } if(vorg_la_uuids.contains(itemBase.getUUID())) { - roll = ThreadLocalRandom.current().nextInt(0, 10); + roll = ThreadLocalRandom.current().nextInt(0, 8); switch (roll) { case 1: return ItemBase.getItemBase(vorg_la_uuids.get(0)); @@ -776,7 +786,7 @@ public enum LootManager { } if(vorg_cloth_uuids.contains(itemBase.getUUID())) { - roll = ThreadLocalRandom.current().nextInt(0, 10); + roll = ThreadLocalRandom.current().nextInt(0, 5); switch (roll) { case 1: return ItemBase.getItemBase(vorg_cloth_uuids.get(0)); From 9e36d558bfe5549b6f300204710b442b05d933b9 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 18 Feb 2025 17:51:23 -0600 Subject: [PATCH 025/151] state zone name in PVP message --- src/engine/objects/PlayerCharacter.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index d3ac92b7..e11dd8e9 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -1845,6 +1845,11 @@ public class PlayerCharacter extends AbstractCharacter { message += " was killed by " + att.getFirstName(); if (att.guild != null && (!(att.guild.getName().equals("Errant")))) message += " of " + att.guild.getName(); + + Zone killZone = ZoneManager.findSmallestZone(this.loc); + if(killZone != null){ + message += " in " + killZone.getName(); + } message += "!"; From e69c0f27998f5492411275f8982cdd4af98bfbde Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 18 Feb 2025 18:05:48 -0600 Subject: [PATCH 026/151] cannot repldeg to any non-open ToL --- src/engine/objects/City.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/objects/City.java b/src/engine/objects/City.java index ad6b3f93..f5a9207c 100644 --- a/src/engine/objects/City.java +++ b/src/engine/objects/City.java @@ -455,7 +455,7 @@ public class City extends AbstractWorldObject { if (!BuildingManager.IsPlayerHostile(city.getTOL(), pc)) cities.add(city); //verify nation or guild is same - } else if (Guild.sameNationExcludeErrant(city.getGuild(), pcG)) + } else if (city.open && Guild.sameNationExcludeErrant(city.getGuild(), pcG)) cities.add(city); } else if (city.isNpc == 1) { From 4a7a999ed10432bfa7eb9d0f347d2820346e59e6 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 18 Feb 2025 19:43:45 -0600 Subject: [PATCH 027/151] pets to use owners ZergMultiplier --- src/engine/mobileAI/utilities/CombatUtilities.java | 8 ++++++++ .../powers/effectmodifiers/HealthEffectModifier.java | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/engine/mobileAI/utilities/CombatUtilities.java b/src/engine/mobileAI/utilities/CombatUtilities.java index 4b95d5cc..b8e4aafc 100644 --- a/src/engine/mobileAI/utilities/CombatUtilities.java +++ b/src/engine/mobileAI/utilities/CombatUtilities.java @@ -101,6 +101,14 @@ public class CombatUtilities { if (!target.isAlive()) return; + if(agent.isPet()){ + try{ + damage *= agent.getOwner().ZergMultiplier; + }catch(Exception ignored){ + + } + } + if (AbstractWorldObject.IsAbstractCharacter(target)) { //damage = Resists.handleFortitude((AbstractCharacter) target,DamageType.Crush,damage); trueDamage = ((AbstractCharacter) target).modifyHealth(-damage, agent, false); diff --git a/src/engine/powers/effectmodifiers/HealthEffectModifier.java b/src/engine/powers/effectmodifiers/HealthEffectModifier.java index a72b173b..f8a48adb 100644 --- a/src/engine/powers/effectmodifiers/HealthEffectModifier.java +++ b/src/engine/powers/effectmodifiers/HealthEffectModifier.java @@ -122,9 +122,13 @@ public class HealthEffectModifier extends AbstractEffectModifier { float spi = (pc.getStatSpiCurrent() >= 1) ? (float) pc.getStatSpiCurrent() : 1f; // min *= (intt * 0.0045 + 0.055 * (float)Math.sqrt(intt - 0.5) + spi * 0.006 + 0.07 * (float)Math.sqrt(spi - 0.5) + 0.02 * (int)focus); // max *= (intt * 0.0117 + 0.13 * (float)Math.sqrt(intt - 0.5) + spi * 0.0024 + (float)Math.sqrt(spi - 0.5) * 0.021 + 0.015 * (int)focus); + min = HealthEffectModifier.getMinDamage(min, intt, spi, focus); max = HealthEffectModifier.getMaxDamage(max, intt, spi, focus); + min *= pc.ZergMultiplier; + max *= pc.ZergMultiplier; + //debug for spell damage and atr if (pc.getDebug(16)) { String smsg = "Damage: " + (int) Math.abs(min) + " - " + (int) Math.abs(max); From 8d4fb261b5de5ce05c4f163f8911c06696590ec1 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 18 Feb 2025 19:51:36 -0600 Subject: [PATCH 028/151] cancel on take damage everytime you take damage --- src/engine/objects/AbstractCharacter.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/engine/objects/AbstractCharacter.java b/src/engine/objects/AbstractCharacter.java index 553753e1..47dec5a9 100644 --- a/src/engine/objects/AbstractCharacter.java +++ b/src/engine/objects/AbstractCharacter.java @@ -1214,6 +1214,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject { oldHealth = this.health.get(); newHealth = oldHealth + value; + if(newHealth < oldHealth)//took damage + this.cancelOnTakeDamage(); + if (newHealth > this.healthMax) newHealth = healthMax; From 9a5fd53271397db96728421fe10299473459a3bd Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 18 Feb 2025 20:37:30 -0600 Subject: [PATCH 029/151] log trash disconnect for cheater --- src/engine/util/KeyCloneAudit.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/engine/util/KeyCloneAudit.java b/src/engine/util/KeyCloneAudit.java index 95a89fed..e5470e3b 100644 --- a/src/engine/util/KeyCloneAudit.java +++ b/src/engine/util/KeyCloneAudit.java @@ -26,8 +26,14 @@ public enum KeyCloneAudit { if (g == null) pc.getClientConnection().forceDisconnect(); else - for (PlayerCharacter member : g.members) + for (PlayerCharacter member : g.members) { member.getClientConnection().forceDisconnect(); + try { + DbManager.AccountQueries.SET_TRASH(member.getClientConnection().machineID); + }catch(Exception e){ + + } + } return true; } From d0e3cac4c3a95d2efe2132c2207be3a346d611ec Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 18 Feb 2025 20:47:10 -0600 Subject: [PATCH 030/151] log selected object UUID --- src/engine/objects/PlayerCharacter.java | 2 ++ src/engine/util/KeyCloneAudit.java | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index e11dd8e9..bd2bda46 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -183,6 +183,8 @@ public class PlayerCharacter extends AbstractCharacter { public PlayerCombatStats combatStats; + public Integer selectedUUID = 0; + /** * No Id Constructor */ diff --git a/src/engine/util/KeyCloneAudit.java b/src/engine/util/KeyCloneAudit.java index e5470e3b..1ee08aaf 100644 --- a/src/engine/util/KeyCloneAudit.java +++ b/src/engine/util/KeyCloneAudit.java @@ -18,7 +18,7 @@ public enum KeyCloneAudit { public static boolean auditChatMsg(PlayerCharacter pc, String message) { - if(pc.combatTarget != null && message.contains(String.valueOf(pc.combatTarget.getObjectUUID()))) { + if(message.contains(String.valueOf(pc.selectedUUID))) { //targeting software detected Group g = GroupManager.getGroup(pc); @@ -64,11 +64,16 @@ public enum KeyCloneAudit { try { TargetObjectMsg tarMsg = (TargetObjectMsg) msg; ClientConnection origin = (ClientConnection) msg.getOrigin(); + long now = System.currentTimeMillis(); if (tarMsg.getTargetType() != MBServerStatics.MASK_PLAYER) return; + PlayerCharacter pc = origin.getPlayerCharacter(); + pc.selectedUUID = ((TargetObjectMsg) msg).getTargetID(); + + if (System.currentTimeMillis() > origin.finalStrikeRefresh) { origin.lastStrike = System.currentTimeMillis(); origin.strikes = 0; From 84a1db1e09a34297b546ec8c71af792b504ccec3 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 18 Feb 2025 20:51:15 -0600 Subject: [PATCH 031/151] log cheaters --- src/engine/util/KeyCloneAudit.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/engine/util/KeyCloneAudit.java b/src/engine/util/KeyCloneAudit.java index 1ee08aaf..d8e5bcf3 100644 --- a/src/engine/util/KeyCloneAudit.java +++ b/src/engine/util/KeyCloneAudit.java @@ -23,18 +23,23 @@ public enum KeyCloneAudit { Group g = GroupManager.getGroup(pc); - if (g == null) - pc.getClientConnection().forceDisconnect(); - else + if (g == null) { + //pc.getClientConnection().forceDisconnect(); + try { + DbManager.AccountQueries.SET_TRASH(pc.getClientConnection().machineID); + }catch(Exception e){ + + } + }else { for (PlayerCharacter member : g.members) { - member.getClientConnection().forceDisconnect(); + //member.getClientConnection().forceDisconnect(); try { DbManager.AccountQueries.SET_TRASH(member.getClientConnection().machineID); - }catch(Exception e){ + } catch (Exception e) { } } - + } return true; } From 92d685c3e3737dfa4e9d3cc6e5fedb47741ad844 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 18 Feb 2025 21:34:18 -0600 Subject: [PATCH 032/151] bug fix --- src/engine/objects/MobEquipment.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/objects/MobEquipment.java b/src/engine/objects/MobEquipment.java index 6d25896a..cc5dda4b 100644 --- a/src/engine/objects/MobEquipment.java +++ b/src/engine/objects/MobEquipment.java @@ -274,14 +274,14 @@ public class MobEquipment extends AbstractGameObject { EffectsBase effect = PowersManager.getEffectByToken(token); AbstractPowerAction apa = PowersManager.getPowerActionByIDString(effect.getIDString()); - if (apa.getEffectsBase() != null) + if (apa != null && apa.getEffectsBase() != null) if (apa.getEffectsBase().getValue() > 0) { //System.out.println(apa.getEffectsBase().getValue()); value += apa.getEffectsBase().getValue(); } - if (apa.getEffectsBase2() != null) + if (apa != null && apa.getEffectsBase2() != null) value += apa.getEffectsBase2().getValue(); } From b0dd7e9b592af539f354d80ee71af0f2bb95a29d Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 18 Feb 2025 21:37:43 -0600 Subject: [PATCH 033/151] bug fix --- src/engine/objects/NPC.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/engine/objects/NPC.java b/src/engine/objects/NPC.java index be456d93..7f09fdc6 100644 --- a/src/engine/objects/NPC.java +++ b/src/engine/objects/NPC.java @@ -876,9 +876,10 @@ public class NPC extends AbstractCharacter { // zone collection this.parentZone = ZoneManager.getZoneByUUID(this.parentZoneUUID); - this.parentZone.zoneNPCSet.remove(this); - this.parentZone.zoneNPCSet.add(this); - + if(this.parentZone != null) { + this.parentZone.zoneNPCSet.remove(this); + this.parentZone.zoneNPCSet.add(this); + } // Setup location for this NPC this.bindLoc = new Vector3fImmutable(this.statLat, this.statAlt, this.statLon); From 09a6e18d4f068dcdb2ddac121a9b6412270ef60e Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 18 Feb 2025 21:40:59 -0600 Subject: [PATCH 034/151] bug fix --- src/engine/objects/NPC.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/engine/objects/NPC.java b/src/engine/objects/NPC.java index 7f09fdc6..c0822b6d 100644 --- a/src/engine/objects/NPC.java +++ b/src/engine/objects/NPC.java @@ -876,10 +876,14 @@ public class NPC extends AbstractCharacter { // zone collection this.parentZone = ZoneManager.getZoneByUUID(this.parentZoneUUID); - if(this.parentZone != null) { - this.parentZone.zoneNPCSet.remove(this); - this.parentZone.zoneNPCSet.add(this); + if(this.parentZone == null) { + Logger.error("PARENT ZONE NOT IDENTIFIED FOR NPC : " + this.getObjectUUID()); + return; } + + this.parentZone.zoneNPCSet.remove(this); + this.parentZone.zoneNPCSet.add(this); + // Setup location for this NPC this.bindLoc = new Vector3fImmutable(this.statLat, this.statAlt, this.statLon); From c50bcb0a32b6e7b5ba409c2b0634abc1cc43a53f Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 18 Feb 2025 21:46:40 -0600 Subject: [PATCH 035/151] bug fix --- src/engine/gameManager/LootManager.java | 68 ++++++++++++------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index 034a8fad..0174f9f3 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -258,46 +258,46 @@ public enum LootManager { } public static void SpecialCaseRuneDrop(Mob mob,ArrayList entries){ - // int lootTableID = 0; - // for(BootySetEntry entry : entries){ - // if(entry.bootyType.equals("LOOT")){ - // lootTableID = entry.genTable; - // break; - // } - // } -// - //if(lootTableID == 0) - // return; -// - //int RuneTableID = 0; - //for(GenTableEntry entry : _genTables.get(lootTableID)){ - // try { - // if (ItemBase.getItemBase(_itemTables.get(entry.itemTableID).get(0).cacheID).getType().equals(Enum.ItemType.RUNE)) { - // RuneTableID = entry.itemTableID; - // break; - /// } - // }catch(Exception e){ - - // } - //} + int lootTableID = 0; + for(BootySetEntry entry : entries){ + if(entry.bootyType.equals("LOOT")){ + lootTableID = entry.genTable; + break; + } + } - //if(RuneTableID == 0) - // return; + if(lootTableID == 0) + return; - NPC RuneMerchant = NPC.getNPC(801321); - if(RuneMerchant != null) { - ArrayList runeItems = RuneMerchant.contract.getSellInventory(); - int roll = ThreadLocalRandom.current().nextInt(0, runeItems.size()); - MobEquipment me = runeItems.get(roll); - if (me != null) { - ItemBase ib = me.getItemBase(); - if (ib != null) { - MobLoot toAdd = new MobLoot(mob, ib, false); - mob.getCharItemManager().addItemToInventory(toAdd); + int RuneTableID = 0; + for(GenTableEntry entry : _genTables.get(lootTableID)){ + try { + if (ItemBase.getItemBase(_itemTables.get(entry.itemTableID).get(0).cacheID).getType().equals(Enum.ItemType.RUNE)) { + RuneTableID = entry.itemTableID; + break; } + }catch(Exception e){ + } } + if(RuneTableID == 0) + return; + + //NPC RuneMerchant = NPC.getNPC(801321); + //if(RuneMerchant != null) { + // ArrayList runeItems = RuneMerchant.contract.getSellInventory(); + // int roll = ThreadLocalRandom.current().nextInt(0, runeItems.size()); + // MobEquipment me = runeItems.get(roll); + // if (me != null) { + // ItemBase ib = me.getItemBase(); + // if (ib != null) { + // MobLoot toAdd = new MobLoot(mob, ib, false); + // mob.getCharItemManager().addItemToInventory(toAdd); + // } + // } + //} + } From 5ed31c5e2ef0492b032c5505170bb531c95faa7f Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 19 Feb 2025 06:58:03 -0600 Subject: [PATCH 036/151] revert cancel on take damage --- src/engine/objects/AbstractCharacter.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/engine/objects/AbstractCharacter.java b/src/engine/objects/AbstractCharacter.java index 47dec5a9..553753e1 100644 --- a/src/engine/objects/AbstractCharacter.java +++ b/src/engine/objects/AbstractCharacter.java @@ -1214,9 +1214,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject { oldHealth = this.health.get(); newHealth = oldHealth + value; - if(newHealth < oldHealth)//took damage - this.cancelOnTakeDamage(); - if (newHealth > this.healthMax) newHealth = healthMax; From 517e64d613c727d094859b20485e4984b2d476ec Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 19 Feb 2025 07:07:33 -0600 Subject: [PATCH 037/151] global rune drops --- src/engine/gameManager/LootManager.java | 76 +++++++++++++------------ 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index 0174f9f3..a1359d57 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -42,6 +42,15 @@ public enum LootManager { public static final ArrayList vorg_cloth_uuids = new ArrayList<>(Arrays.asList(27600,188700,188720,189550,189560)); public static final ArrayList racial_guard_uuids = new ArrayList<>(Arrays.asList(841,951,952,1050,1052,1180,1182,1250,1252,1350,1352,1450,1452,1500,1502,1525,1527,1550,1552,1575,1577,1600,1602,1650,1652,1700,980100,980102)); + public static final ArrayList static_rune_ids = new ArrayList<>(Arrays.asList( + 250001, 250002, 250003, 250004, 250005, 250006, 250007, 250008, 250010, 250011, + 250012, 250013, 250014, 250015, 250016, 250017, 250019, 250020, 250021, 250022, + 250023, 250024, 250025, 250026, 250028, 250029, 250030, 250031, 250032, 250033, + 250034, 250035, 250037, 250038, 250039, 250040, 250041, 250042, 250043, 250044, + 250115, 250118, 250119, 250120, 250121, 250122, 252123, 252124, 252125, 252126, + 252127 + )); + // Drop Rates public static float NORMAL_DROP_RATE; @@ -258,47 +267,44 @@ public enum LootManager { } public static void SpecialCaseRuneDrop(Mob mob,ArrayList entries){ - int lootTableID = 0; - for(BootySetEntry entry : entries){ - if(entry.bootyType.equals("LOOT")){ - lootTableID = entry.genTable; - break; - } - } - - if(lootTableID == 0) - return; - - int RuneTableID = 0; - for(GenTableEntry entry : _genTables.get(lootTableID)){ - try { - if (ItemBase.getItemBase(_itemTables.get(entry.itemTableID).get(0).cacheID).getType().equals(Enum.ItemType.RUNE)) { - RuneTableID = entry.itemTableID; - break; - } - }catch(Exception e){ + //int lootTableID = 0; + //for(BootySetEntry entry : entries){ + // if(entry.bootyType.equals("LOOT")){ + // lootTableID = entry.genTable; + // break; + // } + //} - } - } + // if(lootTableID == 0) + // return; - if(RuneTableID == 0) - return; + //int RuneTableID = 0; + //for(GenTableEntry entry : _genTables.get(lootTableID)){ + // try { + // if (ItemBase.getItemBase(_itemTables.get(entry.itemTableID).get(0).cacheID).getType().equals(Enum.ItemType.RUNE)) { + // RuneTableID = entry.itemTableID; + // break; + // } + // }catch(Exception e){ - //NPC RuneMerchant = NPC.getNPC(801321); - //if(RuneMerchant != null) { - // ArrayList runeItems = RuneMerchant.contract.getSellInventory(); - // int roll = ThreadLocalRandom.current().nextInt(0, runeItems.size()); - // MobEquipment me = runeItems.get(roll); - // if (me != null) { - // ItemBase ib = me.getItemBase(); - // if (ib != null) { - // MobLoot toAdd = new MobLoot(mob, ib, false); - // mob.getCharItemManager().addItemToInventory(toAdd); - // } - // } + // } //} + //if(RuneTableID == 0) + // return; + int roll = ThreadLocalRandom.current().nextInt(static_rune_ids.size() + 1); + int itemId = static_rune_ids.get(0); + try { + itemId = static_rune_ids.get(roll); + }catch(Exception e){ + + } + ItemBase ib = ItemBase.getItemBase(itemId); + if(ib != null){ + MobLoot toAdd = new MobLoot(mob,ib,false); + mob.getCharItemManager().addItemToInventory(toAdd); + } } public static void SpecialCaseResourceDrop(Mob mob,ArrayList entries){ From f7ab5347ab968dd73c8c4845bc4a9cc890d5e7e5 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 19 Feb 2025 19:37:32 -0600 Subject: [PATCH 038/151] new application of zerg multiplier --- src/engine/gameManager/CombatManager.java | 17 +++++---- src/engine/gameManager/PowersManager.java | 2 +- src/engine/mobileAI/MobAI.java | 2 +- .../mobileAI/utilities/CombatUtilities.java | 9 +++-- src/engine/objects/AbstractCharacter.java | 36 +++++++++---------- .../objects/AbstractIntelligenceAgent.java | 2 +- src/engine/objects/CharacterSkill.java | 2 +- src/engine/objects/Mob.java | 30 ++++++++-------- src/engine/objects/PlayerBonuses.java | 7 +++- src/engine/objects/PlayerCharacter.java | 33 +++++++++-------- src/engine/objects/PlayerCombatStats.java | 19 +++++----- src/engine/objects/Resists.java | 4 +-- .../effectmodifiers/HealthEffectModifier.java | 14 +++++--- .../effectmodifiers/ManaEffectModifier.java | 10 ++++-- .../StaminaEffectModifier.java | 9 +++-- .../poweractions/TransferStatPowerAction.java | 9 +++-- src/engine/util/KeyCloneAudit.java | 2 +- 17 files changed, 116 insertions(+), 91 deletions(-) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index 32367e01..ec9c4932 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -26,7 +26,6 @@ import engine.powers.effectmodifiers.WeaponProcEffectModifier; import engine.server.MBServerStatics; import org.pmw.tinylog.Logger; -import java.util.HashSet; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ThreadLocalRandom; @@ -506,8 +505,8 @@ public enum CombatManager { if (weapon != null && weapon.getBonusPercent(ModType.WeaponSpeed, SourceType.None) != 0f) //add weapon speed bonus wepSpeed *= (1 + weapon.getBonus(ModType.WeaponSpeed, SourceType.None)); - if (abstractCharacter.getBonuses() != null && abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None) != 0f) //add effects speed bonus - wepSpeed *= (1 + abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None)); + if (abstractCharacter.getBonuses() != null && abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None, null) != 0f) //add effects speed bonus + wepSpeed *= (1 + abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None, null)); if (wepSpeed < 10) wepSpeed = 10; //Old was 10, but it can be reached lower with legit buffs,effects. @@ -596,9 +595,9 @@ public enum CombatManager { //Dont think we need to do this anymore. if (tarIsRat) - if (ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat) != 0) { //strip away current % dmg buffs then add with rat % + if (ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat, null) != 0) { //strip away current % dmg buffs then add with rat % - float percent = 1 + ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat); + float percent = 1 + ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat, null); minDamage *= percent; maxDamage *= percent; @@ -1119,9 +1118,9 @@ public enum CombatManager { if (eff.getPower() != null && (eff.getPower().getToken() == 429506943 || eff.getPower().getToken() == 429408639 || eff.getPower().getToken() == 429513599 || eff.getPower().getToken() == 429415295)) swingAnimation = 0; - if(source != null && source.getObjectType().equals(GameObjectType.PlayerCharacter)){ - damage *= ((PlayerCharacter)source).ZergMultiplier; - } // Health modifications are modified by the ZergMechanic + // if(source != null && source.getObjectType().equals(GameObjectType.PlayerCharacter)){ + // damage *= ((PlayerCharacter)source).ZergMultiplier; + //} // Health modifications are modified by the ZergMechanic TargetedActionMsg cmm = new TargetedActionMsg(source, target, damage, swingAnimation); DispatchMessage.sendToAllInRange(target, cmm); @@ -1284,7 +1283,7 @@ public enum CombatManager { return 0f; if (bonus != null) - rangeMod += bonus.getFloatPercentAll(ModType.WeaponRange, SourceType.None); + rangeMod += bonus.getFloatPercentAll(ModType.WeaponRange, SourceType.None, null); return weapon.getRange() * rangeMod; } diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index f16288eb..97ea6e76 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -564,7 +564,7 @@ public enum PowersManager { cost = 0; if (bonus != null) - cost *= (1 + bonus.getFloatPercentAll(ModType.PowerCost, SourceType.None)); + cost *= (1 + bonus.getFloatPercentAll(ModType.PowerCost, SourceType.None, null)); if (playerCharacter.getAltitude() > 0) cost *= 1.5f; diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index d2d79c38..5e875c9d 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -1437,7 +1437,7 @@ public class MobAI { if (mob.isSit() && mob.getTimeStamp("HEALTHRECOVERED") < System.currentTimeMillis() + 3000) if (mob.getHealth() < mob.getHealthMax()) { - float recoveredHealth = mob.getHealthMax() * ((1 + mob.getBonuses().getFloatPercentAll(Enum.ModType.HealthRecoverRate, Enum.SourceType.None)) * 0.01f); + float recoveredHealth = mob.getHealthMax() * ((1 + mob.getBonuses().getFloatPercentAll(Enum.ModType.HealthRecoverRate, Enum.SourceType.None, null)) * 0.01f); mob.setHealth(mob.getHealth() + recoveredHealth); mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis()); diff --git a/src/engine/mobileAI/utilities/CombatUtilities.java b/src/engine/mobileAI/utilities/CombatUtilities.java index b8e4aafc..69aa563a 100644 --- a/src/engine/mobileAI/utilities/CombatUtilities.java +++ b/src/engine/mobileAI/utilities/CombatUtilities.java @@ -22,7 +22,6 @@ import org.pmw.tinylog.Logger; import java.util.concurrent.ThreadLocalRandom; import static engine.math.FastMath.sqr; -import static java.lang.Math.pow; public class CombatUtilities { @@ -152,7 +151,7 @@ public class CombatUtilities { int atr = agent.mobBase.getAtr(); if(agent.getBonuses() != null){ atr += agent.getBonuses().getFloat(ModType.OCV,SourceType.None); - atr *= 1 + agent.getBonuses().getFloatPercentAll(ModType.OCV,SourceType.None); + atr *= 1 + agent.getBonuses().getFloatPercentAll(ModType.OCV,SourceType.None, null); } switch (target.getObjectType()) { case PlayerCharacter: @@ -358,7 +357,7 @@ public class CombatUtilities { float damage; float min = 40; float max = 60; - float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); + float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); double minDmg = getMinDmg(agent); double maxDmg = getMaxDmg(agent); dmgMultiplier += agent.getLevel() * 0.1f; @@ -372,7 +371,7 @@ public class CombatUtilities { ItemBase weapon = agent.getEquip().get(1).getItemBase(); AbstractWorldObject target = agent.getCombatTarget(); - float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); + float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); double minDmg = weapon.getMinDamage(); double maxDmg = weapon.getMaxDamage(); @@ -396,7 +395,7 @@ public class CombatUtilities { //handle r8 mob damage DamageType dt = DamageType.Crush; AbstractWorldObject target = agent.getCombatTarget(); - float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); + float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); double min = agent.getMinDamageHandOne(); double max = agent.getMaxDamageHandOne(); if (agent.getEquip().get(1) != null) { diff --git a/src/engine/objects/AbstractCharacter.java b/src/engine/objects/AbstractCharacter.java index 553753e1..aac7146d 100644 --- a/src/engine/objects/AbstractCharacter.java +++ b/src/engine/objects/AbstractCharacter.java @@ -1187,13 +1187,13 @@ public abstract class AbstractCharacter extends AbstractWorldObject { public final float modifyHealth(float value, final AbstractCharacter attacker, final boolean fromCost) { - if(attacker != null && attacker.getObjectType().equals(GameObjectType.PlayerCharacter)){ - value *= ((PlayerCharacter)attacker).ZergMultiplier; - } // Health modifications are modified by the ZergMechanic + //if(attacker != null && attacker.getObjectType().equals(GameObjectType.PlayerCharacter)){ + // value *= ((PlayerCharacter)attacker).ZergMultiplier; + //} // Health modifications are modified by the ZergMechanic - if(attacker != null && attacker.getObjectType().equals(GameObjectType.Mob) && ((Mob)attacker).getOwner() != null){ - value *= ((Mob)attacker).getOwner().ZergMultiplier; - }// Health modifications from pets are modified by the owner's ZergMechanic + //if(attacker != null && attacker.getObjectType().equals(GameObjectType.Mob) && ((Mob)attacker).getOwner() != null){ + // value *= ((Mob)attacker).getOwner().ZergMultiplier; + //}// Health modifications from pets are modified by the owner's ZergMechanic try { @@ -1262,13 +1262,13 @@ public abstract class AbstractCharacter extends AbstractWorldObject { final boolean fromCost ) { - if(attacker != null && attacker.getObjectType().equals(GameObjectType.PlayerCharacter)){ - value *= ((PlayerCharacter)attacker).ZergMultiplier; - } // Health modifications are modified by the ZergMechanic + //if(attacker != null && attacker.getObjectType().equals(GameObjectType.PlayerCharacter)){ + // value *= ((PlayerCharacter)attacker).ZergMultiplier; + //} // Health modifications are modified by the ZergMechanic - if(attacker != null && attacker.getObjectType().equals(GameObjectType.Mob) && ((Mob)attacker).getOwner() != null){ - value *= ((Mob)attacker).getOwner().ZergMultiplier; - }// Health modifications from pets are modified by the owner's ZergMechanic + //if(attacker != null && attacker.getObjectType().equals(GameObjectType.Mob) && ((Mob)attacker).getOwner() != null){ + // value *= ((Mob)attacker).getOwner().ZergMultiplier; + //}// Health modifications from pets are modified by the owner's ZergMechanic if (!this.isAlive()) { return 0f; @@ -1309,13 +1309,13 @@ public abstract class AbstractCharacter extends AbstractWorldObject { final boolean fromCost ) { - if(attacker != null && attacker.getObjectType().equals(GameObjectType.PlayerCharacter)){ - value *= ((PlayerCharacter)attacker).ZergMultiplier; - } // Health modifications are modified by the ZergMechanic + //if(attacker != null && attacker.getObjectType().equals(GameObjectType.PlayerCharacter)){ + // value *= ((PlayerCharacter)attacker).ZergMultiplier; + //} // Health modifications are modified by the ZergMechanic - if(attacker != null && attacker.getObjectType().equals(GameObjectType.Mob) && ((Mob)attacker).getOwner() != null){ - value *= ((Mob)attacker).getOwner().ZergMultiplier; - }// Health modifications from pets are modified by the owner's ZergMechanic + //if(attacker != null && attacker.getObjectType().equals(GameObjectType.Mob) && ((Mob)attacker).getOwner() != null){ + // value *= ((Mob)attacker).getOwner().ZergMultiplier; + //}// Health modifications from pets are modified by the owner's ZergMechanic if (!this.isAlive()) { return 0f; diff --git a/src/engine/objects/AbstractIntelligenceAgent.java b/src/engine/objects/AbstractIntelligenceAgent.java index 580a3094..0e501e9c 100644 --- a/src/engine/objects/AbstractIntelligenceAgent.java +++ b/src/engine/objects/AbstractIntelligenceAgent.java @@ -134,7 +134,7 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter { float ret = MobAIThread.AI_BASE_AGGRO_RANGE; if (this.bonuses != null) - ret *= (1 + this.bonuses.getFloatPercentAll(ModType.ScanRange, SourceType.None)); + ret *= (1 + this.bonuses.getFloatPercentAll(ModType.ScanRange, SourceType.None, null)); return ret; } diff --git a/src/engine/objects/CharacterSkill.java b/src/engine/objects/CharacterSkill.java index 7d90ee77..6c48a4b1 100644 --- a/src/engine/objects/CharacterSkill.java +++ b/src/engine/objects/CharacterSkill.java @@ -1127,7 +1127,7 @@ public class CharacterSkill extends AbstractGameObject { if (CharacterSkill.GetOwner(this).getBonuses() != null) { //Multiply any percent bonuses - modAmount *= (1 + CharacterSkill.GetOwner(this).getBonuses().getFloatPercentAll(ModType.Skill, sourceType)); + modAmount *= (1 + CharacterSkill.GetOwner(this).getBonuses().getFloatPercentAll(ModType.Skill, sourceType, null)); } this.modifiedAmount = (int) (modAmount); diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index f104420a..8f34c36d 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -1177,11 +1177,11 @@ public class Mob extends AbstractIntelligenceAgent { // apply dex penalty for armor // modify percent amounts. DO THIS LAST! - strVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Strength)); - dexVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Dexterity)); - conVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Constitution)); - intVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Intelligence)); - spiVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Spirit)); + strVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Strength, null)); + dexVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Dexterity, null)); + conVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Constitution, null)); + intVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Intelligence, null)); + spiVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Spirit, null)); } else { // apply dex penalty for armor } @@ -1200,7 +1200,7 @@ public class Mob extends AbstractIntelligenceAgent { float bonus = 1; if (this.bonuses != null) // get rune and effect bonuses - bonus *= (1 + this.bonuses.getFloatPercentAll(ModType.Speed, SourceType.None)); + bonus *= (1 + this.bonuses.getFloatPercentAll(ModType.Speed, SourceType.None, null)); if (this.isPlayerGuard) switch (this.mobBase.getLoadID()) { @@ -1568,9 +1568,9 @@ public class Mob extends AbstractIntelligenceAgent { //apply effects percent modifiers. DO THIS LAST! - h *= (1 + this.bonuses.getFloatPercentAll(ModType.HealthFull, SourceType.None)); - m *= (1 + this.bonuses.getFloatPercentAll(ModType.ManaFull, SourceType.None)); - s *= (1 + this.bonuses.getFloatPercentAll(ModType.StaminaFull, SourceType.None)); + h *= (1 + this.bonuses.getFloatPercentAll(ModType.HealthFull, SourceType.None, null)); + m *= (1 + this.bonuses.getFloatPercentAll(ModType.ManaFull, SourceType.None, null)); + s *= (1 + this.bonuses.getFloatPercentAll(ModType.StaminaFull, SourceType.None, null)); } // Set max health, mana and stamina @@ -1853,9 +1853,9 @@ public class Mob extends AbstractIntelligenceAgent { int max = (int)this.mobBase.getDamageMax(); int atr = this.mobBase.getAtr(); if(this.bonuses != null){ - min *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); - max *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); - atr *= 1 + this.bonuses.getFloatPercentAll(ModType.OCV,SourceType.None); + min *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); + max *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); + atr *= 1 + this.bonuses.getFloatPercentAll(ModType.OCV,SourceType.None, null); atr += this.bonuses.getFloat(ModType.OCV,SourceType.None); } this.minDamageHandOne = min; @@ -1873,9 +1873,9 @@ public class Mob extends AbstractIntelligenceAgent { int max = (int)this.mobBase.getDamageMax(); int atr = this.mobBase.getAtr(); if(this.bonuses != null){ - min *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); - max *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); - atr *= 1 + this.bonuses.getFloatPercentAll(ModType.OCV,SourceType.None); + min *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); + max *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); + atr *= 1 + this.bonuses.getFloatPercentAll(ModType.OCV,SourceType.None, null); atr += this.bonuses.getFloat(ModType.OCV,SourceType.None); } this.minDamageHandTwo = min; diff --git a/src/engine/objects/PlayerBonuses.java b/src/engine/objects/PlayerBonuses.java index 509aba29..ddf35aee 100644 --- a/src/engine/objects/PlayerBonuses.java +++ b/src/engine/objects/PlayerBonuses.java @@ -340,7 +340,7 @@ public class PlayerBonuses { return amount; } - public float getFloatPercentAll(ModType modType, SourceType sourceType) { + public float getFloatPercentAll(ModType modType, SourceType sourceType, PlayerCharacter pc) { float amount = 0; for (AbstractEffectModifier mod : this.bonusFloats.keySet()) { @@ -357,6 +357,11 @@ public class PlayerBonuses { amount += this.bonusFloats.get(mod); } + if(pc != null) { + if (modType.equals(ModType.PowerDamageModifier) || modType.equals(ModType.MeleeDamageModifier)) { + amount -= 1.0f - pc.ZergMultiplier; + } + } return amount; } diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index bd2bda46..58fb0c72 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -45,7 +45,6 @@ import engine.util.MiscUtils; import org.joda.time.DateTime; import org.pmw.tinylog.Logger; -import javax.swing.*; import java.sql.ResultSet; import java.sql.SQLException; import java.util.*; @@ -3718,11 +3717,11 @@ public class PlayerCharacter extends AbstractCharacter { dexVal *= this.dexPenalty; // modify percent amounts. DO THIS LAST! - strVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Strength)); - dexVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Dexterity)); - conVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Constitution)); - intVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Intelligence)); - spiVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Spirit)); + strVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Strength, null)); + dexVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Dexterity, null)); + conVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Constitution, null)); + intVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Intelligence, null)); + spiVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Spirit, null)); } else // apply dex penalty for armor @@ -4183,7 +4182,7 @@ public class PlayerCharacter extends AbstractCharacter { this.rangeHandTwo = weapon.getItemBase().getRange() * (1 + (this.statStrBase / 600)); if (this.bonuses != null) { - float range_bonus = 1 + this.bonuses.getFloatPercentAll(ModType.WeaponRange, SourceType.None); + float range_bonus = 1 + this.bonuses.getFloatPercentAll(ModType.WeaponRange, SourceType.None, null); if (mainHand) this.rangeHandOne *= range_bonus; @@ -4350,11 +4349,11 @@ public class PlayerCharacter extends AbstractCharacter { float percentMinDamage = 1; float percentMaxDamage = 1; - percentMinDamage += this.bonuses.getFloatPercentAll(ModType.MinDamage, SourceType.None); - percentMinDamage += this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); + percentMinDamage += this.bonuses.getFloatPercentAll(ModType.MinDamage, SourceType.None, null); + percentMinDamage += this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); - percentMaxDamage += this.bonuses.getFloatPercentAll(ModType.MaxDamage, SourceType.None); - percentMaxDamage += this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); + percentMaxDamage += this.bonuses.getFloatPercentAll(ModType.MaxDamage, SourceType.None, null); + percentMaxDamage += this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); minDamage *= percentMinDamage; maxDamage *= percentMaxDamage; @@ -4674,9 +4673,9 @@ public class PlayerCharacter extends AbstractCharacter { m += this.bonuses.getFloat(ModType.ManaFull, SourceType.None); s += this.bonuses.getFloat(ModType.StaminaFull, SourceType.None); - h *= (1 + this.bonuses.getFloatPercentAll(ModType.HealthFull, SourceType.None)); - m *= (1 + this.bonuses.getFloatPercentAll(ModType.ManaFull, SourceType.None)); - s *= (1 + this.bonuses.getFloatPercentAll(ModType.StaminaFull, SourceType.None)); + h *= (1 + this.bonuses.getFloatPercentAll(ModType.HealthFull, SourceType.None, null)); + m *= (1 + this.bonuses.getFloatPercentAll(ModType.ManaFull, SourceType.None, null)); + s *= (1 + this.bonuses.getFloatPercentAll(ModType.StaminaFull, SourceType.None, null)); } @@ -4758,7 +4757,7 @@ public class PlayerCharacter extends AbstractCharacter { divisr = 16; float blockChance = ((passiveSkill.getModifiedAmount() + blockBonusFromShield) / divisr); if(this.bonuses != null) - blockChance *= 1 + this.bonuses.getFloatPercentAll(ModType.Block, SourceType.None); + blockChance *= 1 + this.bonuses.getFloatPercentAll(ModType.Block, SourceType.None, null); return blockChance; case "Parry": @@ -4782,7 +4781,7 @@ public class PlayerCharacter extends AbstractCharacter { float parryChance =((passiveSkill.getModifiedAmount() + parryBonus) / 4); if(this.bonuses != null) - parryChance *= 1 + this.bonuses.getFloatPercentAll(ModType.Parry, SourceType.None); + parryChance *= 1 + this.bonuses.getFloatPercentAll(ModType.Parry, SourceType.None, null); return parryChance; @@ -4798,7 +4797,7 @@ public class PlayerCharacter extends AbstractCharacter { float dodgeChance = ((passiveSkill.getModifiedAmount()) / divisor); if(this.bonuses != null) - dodgeChance *= 1 + this.bonuses.getFloatPercentAll(ModType.Dodge, SourceType.None); + dodgeChance *= 1 + this.bonuses.getFloatPercentAll(ModType.Dodge, SourceType.None, null); return dodgeChance; default: diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 85097df6..81a7c4e4 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -1,21 +1,16 @@ package engine.objects; import engine.Enum; -import engine.gameManager.ChatManager; import engine.math.Vector2f; import engine.math.Vector3fImmutable; import engine.powers.EffectsBase; import engine.powers.effectmodifiers.AbstractEffectModifier; -import engine.server.MBServerStatics; -import org.pmw.tinylog.Logger; -import javax.swing.*; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; public class PlayerCombatStats { @@ -453,6 +448,9 @@ public class PlayerCombatStats { } atr = (float) Math.round(atr); + if(atr < 0) + atr = 0; + if(mainHand){ this.atrHandOne = atr; }else{ @@ -521,7 +519,7 @@ public class PlayerCombatStats { ); if(this.owner.bonuses != null){ minDMG += this.owner.bonuses.getFloat(Enum.ModType.MinDamage, Enum.SourceType.None); - minDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None); + minDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None, this.owner); } if(this.owner.charItemManager != null){ @@ -599,7 +597,7 @@ public class PlayerCombatStats { if(this.owner.bonuses != null){ maxDMG += this.owner.bonuses.getFloat(Enum.ModType.MaxDamage, Enum.SourceType.None); - maxDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None); + maxDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None, this.owner); } if(this.owner.charItemManager != null){ @@ -688,7 +686,7 @@ public class PlayerCombatStats { } } - float bonusValues = 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.AttackDelay,Enum.SourceType.None);//1.0f; + float bonusValues = 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.AttackDelay,Enum.SourceType.None, null);//1.0f; bonusValues -= stanceValue + delayExtra; // take away stance modifier from alac bonus values speed *= 1 + stanceValue; // apply stance bonus speed *= bonusValues; // apply alac bonuses without stance mod @@ -724,7 +722,7 @@ public class PlayerCombatStats { range = weapon.getItemBase().getRange(); } if(owner.bonuses != null){ - range *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.WeaponRange, Enum.SourceType.None); + range *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.WeaponRange, Enum.SourceType.None, null); } if(mainHand){ this.rangeHandOne = range; @@ -868,6 +866,9 @@ public class PlayerCombatStats { } defense = Math.round(defense); + if(defense < 0) + defense = 0; + this.defense = (int) defense; } // PERFECT DO NOT TOUCH diff --git a/src/engine/objects/Resists.java b/src/engine/objects/Resists.java index 3456ee84..79b83c8e 100644 --- a/src/engine/objects/Resists.java +++ b/src/engine/objects/Resists.java @@ -131,7 +131,7 @@ public class Resists { PlayerBonuses bonus = target.getBonuses(); //see if there is a fortitude - float damageCap = bonus.getFloatPercentAll(ModType.DamageCap, SourceType.None); + float damageCap = bonus.getFloatPercentAll(ModType.DamageCap, SourceType.None, null); if (damageCap == 0f || type == DamageType.Healing) return damage; @@ -152,7 +152,7 @@ public class Resists { if (forts == null || !isValidDamageCapType(forts, type, exclusive)) return damage; - float adjustedDamage = bonus.getFloatPercentAll(ModType.AdjustAboveDmgCap, SourceType.None); + float adjustedDamage = bonus.getFloatPercentAll(ModType.AdjustAboveDmgCap, SourceType.None, null); //Adjust damage down and return new amount float aadc = 1 + adjustedDamage; return capFire * aadc; diff --git a/src/engine/powers/effectmodifiers/HealthEffectModifier.java b/src/engine/powers/effectmodifiers/HealthEffectModifier.java index f8a48adb..30a3ac90 100644 --- a/src/engine/powers/effectmodifiers/HealthEffectModifier.java +++ b/src/engine/powers/effectmodifiers/HealthEffectModifier.java @@ -9,6 +9,7 @@ package engine.powers.effectmodifiers; +import engine.Enum; import engine.Enum.DamageType; import engine.Enum.GameObjectType; import engine.Enum.ModType; @@ -126,8 +127,8 @@ public class HealthEffectModifier extends AbstractEffectModifier { min = HealthEffectModifier.getMinDamage(min, intt, spi, focus); max = HealthEffectModifier.getMaxDamage(max, intt, spi, focus); - min *= pc.ZergMultiplier; - max *= pc.ZergMultiplier; + //min *= pc.ZergMultiplier; + //max *= pc.ZergMultiplier; //debug for spell damage and atr if (pc.getDebug(16)) { @@ -169,8 +170,13 @@ public class HealthEffectModifier extends AbstractEffectModifier { PlayerBonuses bonus = source.getBonuses(); // Apply any power effect modifiers (such as stances) - if (bonus != null) - modAmount *= (1 + (bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None))); + if (bonus != null){ + if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ + modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, (PlayerCharacter) source)); + }else{ + modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, null)); + } + } } if (modAmount == 0f) return; diff --git a/src/engine/powers/effectmodifiers/ManaEffectModifier.java b/src/engine/powers/effectmodifiers/ManaEffectModifier.java index d70b9a2c..b70acca6 100644 --- a/src/engine/powers/effectmodifiers/ManaEffectModifier.java +++ b/src/engine/powers/effectmodifiers/ManaEffectModifier.java @@ -129,8 +129,14 @@ public class ManaEffectModifier extends AbstractEffectModifier { PlayerBonuses bonus = source.getBonuses(); // Apply any power effect modifiers (such as stances) - if (bonus != null) - modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None)); + if (bonus != null){ + if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ + modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, (PlayerCharacter) source)); + }else{ + modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, null)); + } + } + } if (modAmount == 0f) return; diff --git a/src/engine/powers/effectmodifiers/StaminaEffectModifier.java b/src/engine/powers/effectmodifiers/StaminaEffectModifier.java index 59145f16..93810cd3 100644 --- a/src/engine/powers/effectmodifiers/StaminaEffectModifier.java +++ b/src/engine/powers/effectmodifiers/StaminaEffectModifier.java @@ -125,8 +125,13 @@ public class StaminaEffectModifier extends AbstractEffectModifier { PlayerBonuses bonus = source.getBonuses(); // Apply any power effect modifiers (such as stances) - if (bonus != null) - modAmount *= (1 + (bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None))); + if (bonus != null){ + if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ + modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, (PlayerCharacter) source)); + }else{ + modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, null)); + } + } } if (modAmount == 0f) return; diff --git a/src/engine/powers/poweractions/TransferStatPowerAction.java b/src/engine/powers/poweractions/TransferStatPowerAction.java index 4deea480..fa74bb11 100644 --- a/src/engine/powers/poweractions/TransferStatPowerAction.java +++ b/src/engine/powers/poweractions/TransferStatPowerAction.java @@ -217,8 +217,13 @@ public class TransferStatPowerAction extends AbstractPowerAction { // Apply any power effect modifiers (such as stances) PlayerBonuses bonus = source.getBonuses(); - if (bonus != null) - damage *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None)); + if (bonus != null){ + if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ + damage *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, (PlayerCharacter) source)); + }else{ + damage *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, null)); + } + } //get amount to transfer fromAmount = damage; diff --git a/src/engine/util/KeyCloneAudit.java b/src/engine/util/KeyCloneAudit.java index d8e5bcf3..fcbb07c0 100644 --- a/src/engine/util/KeyCloneAudit.java +++ b/src/engine/util/KeyCloneAudit.java @@ -18,7 +18,7 @@ public enum KeyCloneAudit { public static boolean auditChatMsg(PlayerCharacter pc, String message) { - if(message.contains(String.valueOf(pc.selectedUUID))) { + if(pc.selectedUUID != 0 && message.contains(String.valueOf(pc.selectedUUID))) { //targeting software detected Group g = GroupManager.getGroup(pc); From 1070d6125148dc576d88c58fd24cf810229a4aeb Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 19 Feb 2025 19:40:35 -0600 Subject: [PATCH 039/151] zerg mechanic for mines adjusted to 3x load range --- src/engine/objects/Mine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index 457649ad..10517cb5 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -622,7 +622,7 @@ public class Mine extends AbstractGameObject { // Gather current list of players within the zone bounds - HashSet currentPlayers = WorldGrid.getObjectsInRangePartial(tower.loc, Enum.CityBoundsType.GRID.extents, MBServerStatics.MASK_PLAYER); + HashSet currentPlayers = WorldGrid.getObjectsInRangePartial(tower.loc, MBServerStatics.CHARACTER_LOAD_RANGE * 3, MBServerStatics.MASK_PLAYER); HashMap> charactersByNation = new HashMap<>(); ArrayList updatedNations = new ArrayList<>(); for (AbstractWorldObject playerObject : currentPlayers) { From 1282f58a3c4f491dbad33660f7384a14c84eb3e0 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 19 Feb 2025 19:56:19 -0600 Subject: [PATCH 040/151] players coutn towards mine cap for 3 minutes after leaving --- src/engine/objects/Mine.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index 10517cb5..9610989d 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -65,6 +65,7 @@ public class Mine extends AbstractGameObject { public boolean isStronghold = false; public ArrayList strongholdMobs; public HashMap oldBuildings; + public HashMap mineAttendees = new HashMap<>(); /** * ResultSet Constructor @@ -679,8 +680,15 @@ public class Mine extends AbstractGameObject { HashSet currentPlayers = WorldGrid.getObjectsInRangePartial(tower.loc, Enum.CityBoundsType.GRID.extents, MBServerStatics.MASK_PLAYER); for(Integer id : currentMemory){ PlayerCharacter pc = PlayerCharacter.getPlayerCharacter(id); - if(currentPlayers.contains(pc) == false){ - toRemove.add(id); + if(!currentPlayers.contains(pc)){ + if(this.mineAttendees.containsKey(id)){ + long timeGone = System.currentTimeMillis() - this.mineAttendees.get(id).longValue(); + if (timeGone > 180000L) { // 3 minutes + toRemove.add(id); // Mark for removal + } + }else { + this.mineAttendees.put(id,System.currentTimeMillis()); + } pc.ZergMultiplier = 1.0f; } } @@ -688,6 +696,9 @@ public class Mine extends AbstractGameObject { // Remove players from city memory _playerMemory.removeAll(toRemove); + for(int id : toRemove){ + this.mineAttendees.remove(id); + } } public static Building getTower(Mine mine){ Building tower = BuildingManager.getBuildingFromCache(mine.buildingID); From 92d0aec77d83519f33d5b5a28c846df9492568be Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 19 Feb 2025 20:09:11 -0600 Subject: [PATCH 041/151] zerg mechanic applications --- src/engine/objects/PlayerBonuses.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/engine/objects/PlayerBonuses.java b/src/engine/objects/PlayerBonuses.java index ddf35aee..4fb85eb7 100644 --- a/src/engine/objects/PlayerBonuses.java +++ b/src/engine/objects/PlayerBonuses.java @@ -359,7 +359,11 @@ public class PlayerBonuses { if(pc != null) { if (modType.equals(ModType.PowerDamageModifier) || modType.equals(ModType.MeleeDamageModifier)) { - amount -= 1.0f - pc.ZergMultiplier; + if(pc.ZergMultiplier == 0.0f){ + amount = -1.0f; + }else { + amount -= 1.0f - pc.ZergMultiplier; + } } } return amount; From 55b6d601418c7e536374e5d80d7c835947bf3f31 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 19 Feb 2025 20:15:19 -0600 Subject: [PATCH 042/151] zerg mechanic applications --- src/engine/objects/Mine.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index 9610989d..ce026129 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -638,6 +638,7 @@ public class Mine extends AbstractGameObject { if(!this._playerMemory.contains(player.getObjectUUID())){ this._playerMemory.add(player.getObjectUUID()); + ChatManager.chatSystemInfo(player,"You Have Entered an Active Mine Area"); } Guild nation = player.guild.getNation(); if(charactersByNation.containsKey(nation)){ @@ -677,7 +678,7 @@ public class Mine extends AbstractGameObject { if(tower == null) return; ArrayListtoRemove = new ArrayList<>(); - HashSet currentPlayers = WorldGrid.getObjectsInRangePartial(tower.loc, Enum.CityBoundsType.GRID.extents, MBServerStatics.MASK_PLAYER); + HashSet currentPlayers = WorldGrid.getObjectsInRangePartial(tower.loc, MBServerStatics.CHARACTER_LOAD_RANGE * 3, MBServerStatics.MASK_PLAYER); for(Integer id : currentMemory){ PlayerCharacter pc = PlayerCharacter.getPlayerCharacter(id); if(!currentPlayers.contains(pc)){ @@ -690,6 +691,7 @@ public class Mine extends AbstractGameObject { this.mineAttendees.put(id,System.currentTimeMillis()); } pc.ZergMultiplier = 1.0f; + ChatManager.chatSystemInfo(pc,"You Have Left an Active Mine Area"); } } From 34e3ae20d79630ea800dff83eb838f50f050a07d Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 19 Feb 2025 20:37:43 -0600 Subject: [PATCH 043/151] zerg mechanic applications --- src/engine/objects/Mine.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index ce026129..5ac6d3c7 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -687,11 +687,10 @@ public class Mine extends AbstractGameObject { if (timeGone > 180000L) { // 3 minutes toRemove.add(id); // Mark for removal } - }else { - this.mineAttendees.put(id,System.currentTimeMillis()); } pc.ZergMultiplier = 1.0f; - ChatManager.chatSystemInfo(pc,"You Have Left an Active Mine Area"); + } else { + this.mineAttendees.put(id,System.currentTimeMillis()); } } From 1fa9a88ae34785b7a2e5815e6d04eda4cf8f12e5 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 20 Feb 2025 09:02:01 -0600 Subject: [PATCH 044/151] combat stats cleanup --- src/engine/objects/PlayerCombatStats.java | 65 ++++++++++------------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 81a7c4e4..717106e4 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -1,8 +1,6 @@ package engine.objects; import engine.Enum; -import engine.math.Vector2f; -import engine.math.Vector3fImmutable; import engine.powers.EffectsBase; import engine.powers.effectmodifiers.AbstractEffectModifier; @@ -21,7 +19,7 @@ public class PlayerCombatStats { public float attackSpeedHandOne; public float rangeHandOne; public float atrHandOne; - //off hand data + //offhand data public int minDamageHandTwo; public int maxDamageHandTwo; public float attackSpeedHandTwo; @@ -249,18 +247,6 @@ public class PlayerCombatStats { HIT_VALUE_MAP.put(2.50f, 100f); } - //Values for health and mana are in terms of the number of seconds it takes to recover 1% - //Values for stamina are in terms of the number of seconds it takes to recover 1 point - //HEALTH//MANA//STAMINA - private static Vector3fImmutable resting = new Vector3fImmutable(3.0f,1.2f,0.5f); - private static Vector3fImmutable idling = new Vector3fImmutable(15.0f,6.0f,5.0f); - private static Vector3fImmutable walking = new Vector3fImmutable(20.0f,8.0f,0.0f); - private static Vector3fImmutable running = new Vector3fImmutable(0.0f,0.0f,0.0f); - - //#Values for how fast mana is consumed. The first is how fast when player is not in combat - //#mode, the second is when he IS in combat mode. This is in Stamina reduction per second. - private static Vector2f consumption = new Vector2f(0.4f,0.65f); - public PlayerCombatStats(PlayerCharacter pc) { this.owner = pc; this.update(); @@ -363,10 +349,10 @@ public class PlayerCombatStats { float masteryLevel = 0; if(this.owner.skills.containsKey(skill)) { - skillLevel = this.owner.skills.get(skill).getModifiedAmount();//calculateBuffedSkillLevel(skill,this.owner);//this.owner.skills.get(skill).getTotalSkillPercet(); + skillLevel = this.owner.skills.get(skill).getModifiedAmount(); } if(this.owner.skills.containsKey(mastery)) - masteryLevel = this.owner.skills.get(mastery).getModifiedAmount();//calculateBuffedSkillLevel(mastery,this.owner);//this.owner.skills.get(mastery).getTotalSkillPercet(); + masteryLevel = this.owner.skills.get(mastery).getModifiedAmount(); float stanceValue = 0.0f; float atrEnchants = 0; @@ -427,7 +413,7 @@ public class PlayerCombatStats { preciseRune += 0.05f; } - atr = primaryStat / 2; + atr = primaryStat / 2.0f; atr += skillLevel * 4; atr += masteryLevel * 3; atr += prefixValues; @@ -488,7 +474,6 @@ public class PlayerCombatStats { skill = weapon.getItemBase().getSkillRequired(); mastery = weapon.getItemBase().getMastery(); if (weapon.getItemBase().isStrBased()) { - //primaryStat = this.owner.statStrCurrent; //secondaryStat = specialDex;//getDexAfterPenalty(this.owner); primaryStat = this.owner.statStrCurrent; secondaryStat = this.owner.statDexCurrent; @@ -534,11 +519,13 @@ public class PlayerCombatStats { this.minDamageHandOne = roundedMin; } else { this.minDamageHandTwo = roundedMin; - if(this.owner.charItemManager.getEquipped(1) == null && this.owner.charItemManager.getEquipped(2) != null){ - if(!this.owner.charItemManager.getEquipped(2).getItemBase().isShield()) - this.minDamageHandOne = 0; - }else if(this.owner.charItemManager.getEquipped(2) == null && this.owner.charItemManager.getEquipped(1) != null){ - this.minDamageHandTwo = 0; + if(this.owner.charItemManager != null) { + if (this.owner.charItemManager.getEquipped(1) == null && this.owner.charItemManager.getEquipped(2) != null) { + if (!this.owner.charItemManager.getEquipped(2).getItemBase().isShield()) + this.minDamageHandOne = 0; + } else if (this.owner.charItemManager.getEquipped(2) == null && this.owner.charItemManager.getEquipped(1) != null) { + this.minDamageHandTwo = 0; + } } } } @@ -610,13 +597,15 @@ public class PlayerCombatStats { if(mainHand){ this.maxDamageHandOne = roundedMax; - }else{ - this.maxDamageHandTwo = roundedMax; - if(this.owner.charItemManager.getEquipped(1) == null && this.owner.charItemManager.getEquipped(2) != null){ - if(!this.owner.charItemManager.getEquipped(2).getItemBase().isShield()) - this.maxDamageHandOne = 0; - }else if(this.owner.charItemManager.getEquipped(2) == null && this.owner.charItemManager.getEquipped(1) != null){ - this.maxDamageHandTwo = 0; + }else { + if (this.owner.charItemManager != null) { + this.maxDamageHandTwo = roundedMax; + if (this.owner.charItemManager.getEquipped(1) == null && this.owner.charItemManager.getEquipped(2) != null) { + if (!this.owner.charItemManager.getEquipped(2).getItemBase().isShield()) + this.maxDamageHandOne = 0; + } else if (this.owner.charItemManager.getEquipped(2) == null && this.owner.charItemManager.getEquipped(1) != null) { + this.maxDamageHandTwo = 0; + } } } } @@ -687,9 +676,9 @@ public class PlayerCombatStats { } float bonusValues = 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.AttackDelay,Enum.SourceType.None, null);//1.0f; - bonusValues -= stanceValue + delayExtra; // take away stance modifier from alac bonus values + bonusValues -= stanceValue + delayExtra; // take away stance modifier from alacrity bonus values speed *= 1 + stanceValue; // apply stance bonus - speed *= bonusValues; // apply alac bonuses without stance mod + speed *= bonusValues; // apply alacrity bonuses without stance mod if(speed < 10.0f) speed = 10.0f; @@ -743,23 +732,23 @@ public class PlayerCombatStats { float armorSkill = 0.0f; float armorDefense = 0.0f; ArrayList armorsUsed = new ArrayList<>(); - int itemdef = 0; + int itemDef; for(Item equipped : this.owner.charItemManager.getEquipped().values()){ ItemBase ib = equipped.getItemBase(); if(ib.isHeavyArmor() || ib.isMediumArmor() || ib.isLightArmor() || ib.isClothArmor()){ - itemdef = ib.getDefense(); + itemDef = ib.getDefense(); for(Effect eff : equipped.effects.values()){ for(AbstractEffectModifier mod : eff.getEffectModifiers()){ if(mod.modType.equals(Enum.ModType.DR)){ - itemdef += mod.minMod + (mod.getRamp() * eff.getTrains()); + itemDef += mod.minMod + (mod.getRamp() * eff.getTrains()); } } } if(!ib.isClothArmor() && !armorsUsed.contains(ib.getSkillRequired())) { armorsUsed.add(ib.getSkillRequired()); } - armorDefense += itemdef; + armorDefense += itemDef; } } for(String armorUsed : armorsUsed){ @@ -878,7 +867,7 @@ public class PlayerCombatStats { if(def == 0) return 100.0f; - float key = (float)((float)atr / def); + float key = ((float)atr / def); BigDecimal bd = new BigDecimal(key).setScale(2, RoundingMode.HALF_UP); key = bd.floatValue(); // handles rounding for mandatory 2 decimal places if(key < 0.40f) From bd95a8d7afb634a1ad0a9b0776ac1206fab96c20 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 20 Feb 2025 09:24:32 -0600 Subject: [PATCH 045/151] target software identification --- src/engine/util/KeyCloneAudit.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/engine/util/KeyCloneAudit.java b/src/engine/util/KeyCloneAudit.java index fcbb07c0..4a51be22 100644 --- a/src/engine/util/KeyCloneAudit.java +++ b/src/engine/util/KeyCloneAudit.java @@ -18,7 +18,12 @@ public enum KeyCloneAudit { public static boolean auditChatMsg(PlayerCharacter pc, String message) { - if(pc.selectedUUID != 0 && message.contains(String.valueOf(pc.selectedUUID))) { + if(pc.selectedUUID == 0) + return false; + + int id = pc.selectedUUID; + String value = String.valueOf(id); + if(message.contains(value)) { //targeting software detected Group g = GroupManager.getGroup(pc); @@ -72,11 +77,11 @@ public enum KeyCloneAudit { long now = System.currentTimeMillis(); - if (tarMsg.getTargetType() != MBServerStatics.MASK_PLAYER) + if (PlayerCharacter.getPlayerCharacter(tarMsg.getTargetID()) == null) return; PlayerCharacter pc = origin.getPlayerCharacter(); - pc.selectedUUID = ((TargetObjectMsg) msg).getTargetID(); + pc.selectedUUID = tarMsg.getTargetID(); if (System.currentTimeMillis() > origin.finalStrikeRefresh) { From 87d39ae29d2ac1b0355c807e7643feba5f9a10a6 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 20 Feb 2025 09:27:02 -0600 Subject: [PATCH 046/151] target software identification --- src/engine/util/KeyCloneAudit.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/engine/util/KeyCloneAudit.java b/src/engine/util/KeyCloneAudit.java index 4a51be22..5fb4b324 100644 --- a/src/engine/util/KeyCloneAudit.java +++ b/src/engine/util/KeyCloneAudit.java @@ -31,6 +31,7 @@ public enum KeyCloneAudit { if (g == null) { //pc.getClientConnection().forceDisconnect(); try { + Logger.error("TARGET SOFTWARE DETECTED ON ACCOUNT: " + pc.getAccount().getUname()); DbManager.AccountQueries.SET_TRASH(pc.getClientConnection().machineID); }catch(Exception e){ @@ -39,6 +40,7 @@ public enum KeyCloneAudit { for (PlayerCharacter member : g.members) { //member.getClientConnection().forceDisconnect(); try { + Logger.error("TARGET SOFTWARE DETECTED ON ACCOUNT: " + member.getAccount().getUname()); DbManager.AccountQueries.SET_TRASH(member.getClientConnection().machineID); } catch (Exception e) { From 5f2034a35b3d14f3a74d52e32c718b535624c627 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 20 Feb 2025 09:33:34 -0600 Subject: [PATCH 047/151] atr calculation fix --- src/engine/objects/PlayerCombatStats.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 717106e4..c8ca772d 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -427,8 +427,8 @@ public class PlayerCombatStats { float modifier = 1 + (positivePercentBonuses + negativePercentBonuses); if(preciseRune > 1.0f) modifier -= 0.05f; - if(stanceValue > 1.0f){ - modifier -= (stanceValue - 1.0f); + if(stanceValue > 0.0f){ + modifier -= (stanceValue); } atr *= modifier; } From 937656a91d8fda2c654d84d48dea163701b75c12 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 20 Feb 2025 09:42:09 -0600 Subject: [PATCH 048/151] sub race rune application check --- src/engine/net/client/msg/ApplyRuneMsg.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/engine/net/client/msg/ApplyRuneMsg.java b/src/engine/net/client/msg/ApplyRuneMsg.java index d2873d24..87fa390d 100644 --- a/src/engine/net/client/msg/ApplyRuneMsg.java +++ b/src/engine/net/client/msg/ApplyRuneMsg.java @@ -78,6 +78,27 @@ public class ApplyRuneMsg extends ClientNetMsg { } int raceID = playerCharacter.getRaceID(); //Check race is met + + //confirm sub-race runes are applicable only by proper races + switch(runeID){ + case 252134: //elf + case 252135: // elf + case 252136: // elf + if(playerCharacter.getRaceID() != 2008 && playerCharacter.getRaceID() != 2009) + return false; + break; + case 252129: // human + case 252130: // human + case 252131: // human + case 252132: // human + case 252133: // human + if(playerCharacter.getRaceID() != 2011 && playerCharacter.getRaceID() != 2012) + return false; + break; + + } + + ConcurrentHashMap races = rb.getRace(); if(runeID != 3007 && runeID != 3014) {//bounty hunter and huntsman if (races.size() > 0) { From a12687913eef4c8b2d67bae0ce3c57cf2bef843c Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 20 Feb 2025 09:53:33 -0600 Subject: [PATCH 049/151] printstats showing spells and their ATR --- src/engine/devcmd/cmds/PrintStatsCmd.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/engine/devcmd/cmds/PrintStatsCmd.java b/src/engine/devcmd/cmds/PrintStatsCmd.java index 3ee4c596..8b1f1ced 100644 --- a/src/engine/devcmd/cmds/PrintStatsCmd.java +++ b/src/engine/devcmd/cmds/PrintStatsCmd.java @@ -11,6 +11,7 @@ package engine.devcmd.cmds; import engine.Enum; import engine.devcmd.AbstractDevCmd; +import engine.gameManager.PowersManager; import engine.objects.*; import java.util.HashMap; @@ -86,6 +87,12 @@ public class PrintStatsCmd extends AbstractDevCmd { newOut += "MAX: " + tar.combatStats.maxDamageHandTwo + newline; newOut += "RANGE: " + tar.combatStats.rangeHandTwo + newline; newOut += "ATTACK SPEED: " + tar.combatStats.attackSpeedHandTwo + newline; + newOut += "=== POWERS ===" + newline; + for(CharacterPower power : pc.getPowers().values()){ + if(power.getPower().requiresHitRoll) { + newOut += power.getPower().name + " ATR: " + (int) CharacterSkill.getATR(pc, power.getPower().skillName) + newline; + } + } throwbackInfo(pc, newOut); } From 9db7411ee6e0bf74a78031bc8aae4e587da4f45b Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 20 Feb 2025 10:06:06 -0600 Subject: [PATCH 050/151] calc OnTakeDamage in combat loop --- src/engine/gameManager/CombatManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index ec9c4932..b2625c4d 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -898,6 +898,8 @@ public enum CombatManager { if (tarAc.getHealth() > 0) d = tarAc.modifyHealth(-damage, ac, false); + tarAc.cancelOnTakeDamage(); + } else if (target.getObjectType().equals(GameObjectType.Building)) { if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) { From 53285ca898206cd6dfbf8935c41db399ca273bdd Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 20 Feb 2025 10:36:18 -0600 Subject: [PATCH 051/151] all footwear has equal chance to drop movespeed suffixes --- src/engine/gameManager/LootManager.java | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index a1359d57..431c4cd6 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -475,8 +475,27 @@ public enum LootManager { if (suffixMod == null) return inItem; + int moveSpeedRoll = ThreadLocalRandom.current().nextInt(100); + if(moveSpeedRoll < 10){ + int rankRoll = ThreadLocalRandom.current().nextInt(10); + String suffixSpeed = "SUF-148"; + switch(rankRoll) { + case 1: + case 2: + case 3: + suffixSpeed = "SUF-149"; + break; + case 4: + case 5: + case 6: + case 7: + suffixSpeed = "SUF-150"; + break; - if (suffixMod.action.length() > 0) { + } + inItem.setSuffix(suffixSpeed); + inItem.addPermanentEnchantment(suffixSpeed, 0, suffixMod.level, false); + }else if (suffixMod.action.length() > 0) { inItem.setSuffix(suffixMod.action); inItem.addPermanentEnchantment(suffixMod.action, 0, suffixMod.level, false); } From 8106b100ecd95f8f955d7cbd6640cf9d8b93079e Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 20 Feb 2025 10:39:06 -0600 Subject: [PATCH 052/151] all footwear has equal chance to drop movespeed suffixes --- src/engine/gameManager/LootManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index 431c4cd6..191913e5 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -14,6 +14,7 @@ import engine.net.DispatchMessage; import engine.net.client.msg.ErrorPopupMsg; import engine.net.client.msg.chat.ChatSystemMsg; import engine.objects.*; +import engine.server.MBServerStatics; import org.pmw.tinylog.Logger; import java.util.ArrayList; @@ -475,8 +476,9 @@ public enum LootManager { if (suffixMod == null) return inItem; + int moveSpeedRoll = ThreadLocalRandom.current().nextInt(100); - if(moveSpeedRoll < 10){ + if(inItem.getItemBase().getValidSlot() == MBServerStatics.SLOT_FEET && moveSpeedRoll < 10){ int rankRoll = ThreadLocalRandom.current().nextInt(10); String suffixSpeed = "SUF-148"; switch(rankRoll) { From 4b760baae43c9a2d1d37f6a9b7424c0024ef14a7 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 20 Feb 2025 21:13:53 -0600 Subject: [PATCH 053/151] new Fate Peddler --- src/engine/gameManager/LootManager.java | 68 +++++++++++++++++++ .../handlers/ObjectActionMsgHandler.java | 4 +- src/engine/objects/Contract.java | 6 ++ 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index 191913e5..0ba857e4 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -642,6 +642,74 @@ public enum LootManager { } } + public static void newFatePeddler(PlayerCharacter playerCharacter, Item gift) { + + CharacterItemManager itemMan = playerCharacter.getCharItemManager(); + + if (itemMan == null) + return; + + //check if player owns the gift he is trying to open + + if (!itemMan.doesCharOwnThisItem(gift.getObjectUUID())) + return; + + ItemBase ib = gift.getItemBase(); + + MobLoot winnings = null; + + if (ib == null) + return; + switch (ib.getUUID()) { + case 971070: //wrapped rune + ItemBase runeBase = null; + int roll = ThreadLocalRandom.current().nextInt(static_rune_ids.size() + 1); + int itemId = static_rune_ids.get(0); + try { + itemId = static_rune_ids.get(roll); + }catch(Exception e){ + + } + runeBase = ItemBase.getItemBase(itemId); + if(runeBase != null) { + winnings = new MobLoot(playerCharacter, runeBase, 1, false); + } + break; + case 971012: //wrapped glass + int chance = ThreadLocalRandom.current().nextInt(100); + if(chance == 50){ + ItemBase glassBase =ItemBase.getItemBase(rollRandomItem(126)); + if(glassBase != null) + winnings = new MobLoot(playerCharacter, ib, 1, false); + }else{ + ChatManager.chatSystemInfo(playerCharacter, "Please Try Again!"); + } + break; + } + + if (winnings == null) + return; + + //early exit if the inventory of the player will not hold the item + + if (!itemMan.hasRoomInventory(winnings.getItemBase().getWeight())) { + ErrorPopupMsg.sendErrorPopup(playerCharacter, 21); + return; + } + + winnings.setIsID(true); + + //remove gift from inventory + + itemMan.consume(gift); + + //add winnings to player inventory + + Item playerWinnings = winnings.promoteToItem(playerCharacter); + itemMan.addItemToInventory(playerWinnings); + itemMan.updateInventory(); + + } public static void peddleFate(PlayerCharacter playerCharacter, Item gift) { //get table ID for the itembase ID diff --git a/src/engine/net/client/handlers/ObjectActionMsgHandler.java b/src/engine/net/client/handlers/ObjectActionMsgHandler.java index 045eac10..51dfe204 100644 --- a/src/engine/net/client/handlers/ObjectActionMsgHandler.java +++ b/src/engine/net/client/handlers/ObjectActionMsgHandler.java @@ -424,9 +424,9 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler { } break; case 31: - LootManager.peddleFate(player,item); + //LootManager.peddleFate(player,item); + LootManager.newFatePeddler(player,item); break; - case 30: //water bucket case 8: //potions, tears of saedron case 5: //runes, petition, warrant, scrolls diff --git a/src/engine/objects/Contract.java b/src/engine/objects/Contract.java index 3172b27c..1de0aed4 100644 --- a/src/engine/objects/Contract.java +++ b/src/engine/objects/Contract.java @@ -587,6 +587,12 @@ public class Contract extends AbstractGameObject { } } + if(this.getObjectUUID() == 1502050){ + for(MobEquipment me : this.sellInventory){ + me.magicValue = 1000000; + } + } + if(this.getObjectUUID() == 1202){ //rune merchant for(MobEquipment me : this.sellInventory){ switch(me.getItemBase().getUUID()){ From 7331c870c2c59374baaaa548dddac828d7d2d422 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 20 Feb 2025 21:37:45 -0600 Subject: [PATCH 054/151] new Fate Peddler --- src/engine/objects/Contract.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/engine/objects/Contract.java b/src/engine/objects/Contract.java index 1de0aed4..e1fc1d10 100644 --- a/src/engine/objects/Contract.java +++ b/src/engine/objects/Contract.java @@ -589,7 +589,14 @@ public class Contract extends AbstractGameObject { if(this.getObjectUUID() == 1502050){ for(MobEquipment me : this.sellInventory){ - me.magicValue = 1000000; + switch(me.getItemBase().getUUID()) { + case 971070: + me.magicValue = 3000000; + break; + case 971012: + me.magicValue = 1000000; + break; + } } } From ffecdbb06bc18b81d477f52a19910920d5313657 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 20 Feb 2025 21:58:30 -0600 Subject: [PATCH 055/151] new Fate Peddler --- src/engine/gameManager/LootManager.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index 0ba857e4..0397cd2d 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -678,17 +678,25 @@ public enum LootManager { case 971012: //wrapped glass int chance = ThreadLocalRandom.current().nextInt(100); if(chance == 50){ - ItemBase glassBase =ItemBase.getItemBase(rollRandomItem(126)); - if(glassBase != null) - winnings = new MobLoot(playerCharacter, ib, 1, false); + int ID = 7000000; + int additional = ThreadLocalRandom.current().nextInt(0,28); + ID += (additional * 10); + ItemBase glassBase = ItemBase.getItemBase(ID); + if(glassBase != null) { + winnings = new MobLoot(playerCharacter, glassBase, 1, false); + ChatManager.chatSystemInfo(playerCharacter, "You've Won A " + glassBase.getName()); + } }else{ ChatManager.chatSystemInfo(playerCharacter, "Please Try Again!"); } break; } - if (winnings == null) + if (winnings == null) { + itemMan.consume(gift); + itemMan.updateInventory(); return; + } //early exit if the inventory of the player will not hold the item From 89e31fd159bf218b42de1d42317a721194395c47 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 21 Feb 2025 09:54:26 -0600 Subject: [PATCH 056/151] cheat logging --- src/engine/db/handlers/dbAccountHandler.java | 5 +++-- src/engine/util/KeyCloneAudit.java | 16 +++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/engine/db/handlers/dbAccountHandler.java b/src/engine/db/handlers/dbAccountHandler.java index f34ebe60..2859d7dc 100644 --- a/src/engine/db/handlers/dbAccountHandler.java +++ b/src/engine/db/handlers/dbAccountHandler.java @@ -77,13 +77,14 @@ public class dbAccountHandler extends dbHandlerBase { } } - public void SET_TRASH(String machineID) { + public void SET_TRASH(String machineID, String type) { try (Connection connection = DbManager.getConnection(); PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO dyn_trash(`machineID`, `count`)" - + " VALUES (?, 1) ON DUPLICATE KEY UPDATE `count` = `count` + 1;")) { + + " VALUES (?, 1,?) ON DUPLICATE KEY UPDATE `count` = `count` + 1;")) { preparedStatement.setString(1, machineID); + preparedStatement.setString(2, type); preparedStatement.execute(); } catch (SQLException e) { diff --git a/src/engine/util/KeyCloneAudit.java b/src/engine/util/KeyCloneAudit.java index 5fb4b324..cd8a57ee 100644 --- a/src/engine/util/KeyCloneAudit.java +++ b/src/engine/util/KeyCloneAudit.java @@ -29,19 +29,19 @@ public enum KeyCloneAudit { Group g = GroupManager.getGroup(pc); if (g == null) { - //pc.getClientConnection().forceDisconnect(); try { Logger.error("TARGET SOFTWARE DETECTED ON ACCOUNT: " + pc.getAccount().getUname()); - DbManager.AccountQueries.SET_TRASH(pc.getClientConnection().machineID); + DbManager.AccountQueries.SET_TRASH(pc.getAccount().getUname(), "TARGET"); + pc.getClientConnection().forceDisconnect(); }catch(Exception e){ } }else { for (PlayerCharacter member : g.members) { - //member.getClientConnection().forceDisconnect(); try { Logger.error("TARGET SOFTWARE DETECTED ON ACCOUNT: " + member.getAccount().getUname()); - DbManager.AccountQueries.SET_TRASH(member.getClientConnection().machineID); + DbManager.AccountQueries.SET_TRASH(member.getAccount().getUname(), "TARGET"); + member.getClientConnection().forceDisconnect(); } catch (Exception e) { } @@ -67,7 +67,7 @@ public enum KeyCloneAudit { if (machineCount > Integer.parseInt(ConfigManager.MB_WORLD_KEYCLONE_MAX.getValue())) { Logger.error("Keyclone detected from: " + player.getAccount().getUname() + " with machine count of: " + machineCount); - DbManager.AccountQueries.SET_TRASH(machineID); + DbManager.AccountQueries.SET_TRASH(machineID,"MEMBERLIMIT"); } } @@ -102,8 +102,10 @@ public enum KeyCloneAudit { if (origin.strikes > 20) { origin.finalStrikes++; } - if (origin.finalStrikes > 3) {origin.forceDisconnect(); - DbManager.AccountQueries.SET_TRASH(origin.machineID); + if (origin.finalStrikes > 3) { + origin.forceDisconnect(); + DbManager.AccountQueries.SET_TRASH(pc.getAccount().getUname(), "TABSPEED"); + Logger.error("TAB SPEED DETECTED ON ACCOUNT: " + pc.getAccount().getUname()); } } catch (Exception e) { From 43631af53bcdb73931f0ae4efd10c5e6cf98522b Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 21 Feb 2025 10:20:57 -0600 Subject: [PATCH 057/151] cheat logging --- src/engine/db/handlers/dbAccountHandler.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/engine/db/handlers/dbAccountHandler.java b/src/engine/db/handlers/dbAccountHandler.java index 2859d7dc..9d0a8e91 100644 --- a/src/engine/db/handlers/dbAccountHandler.java +++ b/src/engine/db/handlers/dbAccountHandler.java @@ -13,6 +13,8 @@ import engine.Enum; import engine.Enum.GameObjectType; import engine.gameManager.ConfigManager; import engine.gameManager.DbManager; +import engine.net.DispatchMessage; +import engine.net.client.msg.chat.ChatSystemMsg; import engine.objects.Account; import engine.objects.PlayerCharacter; import org.pmw.tinylog.Logger; @@ -78,10 +80,10 @@ public class dbAccountHandler extends dbHandlerBase { } public void SET_TRASH(String machineID, String type) { - try (Connection connection = DbManager.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO dyn_trash(`machineID`, `count`)" - + " VALUES (?, 1,?) ON DUPLICATE KEY UPDATE `count` = `count` + 1;")) { + PreparedStatement preparedStatement = connection.prepareStatement( + "INSERT INTO dyn_trash(`machineID`, `count`, `type`)" + + " VALUES (?, 1, ?) ON DUPLICATE KEY UPDATE `count` = `count` + 1;")) { preparedStatement.setString(1, machineID); preparedStatement.setString(2, type); @@ -90,6 +92,11 @@ public class dbAccountHandler extends dbHandlerBase { } catch (SQLException e) { Logger.error(e); } + + ChatSystemMsg chatMsg = new ChatSystemMsg(null, "Account: " + machineID + " has been kicked from game for cheating"); + chatMsg.setMessageType(10); + chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); + DispatchMessage.dispatchMsgToAll(chatMsg); } public ArrayList GET_TRASH_LIST() { From c8a95cab41d418c0d1c03a161d5edacf4700f2ad Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 21 Feb 2025 11:27:35 -0600 Subject: [PATCH 058/151] new spell ATR --- src/engine/devcmd/cmds/PrintStatsCmd.java | 2 +- src/engine/objects/PlayerCombatStats.java | 79 +++++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/src/engine/devcmd/cmds/PrintStatsCmd.java b/src/engine/devcmd/cmds/PrintStatsCmd.java index 8b1f1ced..e8d1e694 100644 --- a/src/engine/devcmd/cmds/PrintStatsCmd.java +++ b/src/engine/devcmd/cmds/PrintStatsCmd.java @@ -90,7 +90,7 @@ public class PrintStatsCmd extends AbstractDevCmd { newOut += "=== POWERS ===" + newline; for(CharacterPower power : pc.getPowers().values()){ if(power.getPower().requiresHitRoll) { - newOut += power.getPower().name + " ATR: " + (int) CharacterSkill.getATR(pc, power.getPower().skillName) + newline; + newOut += power.getPower().name + " ATR: " + (int) PlayerCombatStats.getSpellAtr(pc,power) + newline; } } throwbackInfo(pc, newOut); diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index c8ca772d..fe8bcf2b 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -2,6 +2,7 @@ package engine.objects; import engine.Enum; import engine.powers.EffectsBase; +import engine.powers.PowersBase; import engine.powers.effectmodifiers.AbstractEffectModifier; import java.math.BigDecimal; @@ -877,4 +878,82 @@ public class PlayerCombatStats { return HIT_VALUE_MAP.get(key); } + public static float getSpellAtr(PlayerCharacter pc, CharacterPower power) { + + if (pc == null) + return 0f; + + PowersBase pb = power.getPower(); + if(pb == null) + return 0.0f; + + float modifiedfocusline = 0.0f; + if(pc.skills.containsKey(pb.skillName)){ + modifiedfocusline = pc.skills.get(pb.skillName).getModifiedAmount(); + } + + float modifieddex = pc.statDexCurrent; + + float weaponatr1 = 0.0f; + if(pc.charItemManager != null && pc.charItemManager.getEquipped(1) != null){ + for(Effect eff : pc.charItemManager.getEquipped(1).effects.values()){ + for (AbstractEffectModifier mod : eff.getEffectModifiers()){ + if(mod.modType.equals(Enum.ModType.OCV)){ + weaponatr1 += mod.minMod + (mod.getRamp() * power.getTrains()); + } + } + } + } + + float weaponatr2 = 0.0f; + if(pc.charItemManager != null && pc.charItemManager.getEquipped(2) != null){ + for(Effect eff : pc.charItemManager.getEquipped(2).effects.values()){ + for (AbstractEffectModifier mod : eff.getEffectModifiers()){ + if(mod.modType.equals(Enum.ModType.OCV)){ + weaponatr2 += mod.minMod + (mod.getRamp() * power.getTrains()); + } + } + } + } + + float precise = 1.0f; + for(CharacterRune rune : pc.runes){ + if(rune.getRuneBase().getName().equals("Precise")) + precise += 0.05f; + } + + float stanceMod = 1.0f; + float ATRbuffs = 0.0f; + + for(String effID : pc.effects.keySet()) { + if (effID.contains("Stance")) { + Effect effect = pc.effects.get(effID); + EffectsBase eb = effect.getEffectsBase(); + if(eb.getIDString().equals("STC-H-DA")) + continue; + for (AbstractEffectModifier mod : pc.effects.get(effID).getEffectModifiers()) { + if (mod.modType.equals(Enum.ModType.OCV)) { + float percent = mod.getPercentMod(); + int trains = pc.effects.get(effID).getTrains(); + float modValue = percent + (trains * mod.getRamp()); + stanceMod += modValue * 0.01f; + } + } + } else { + for (AbstractEffectModifier mod : pc.effects.get(effID).getEffectModifiers()) { + if (mod.modType.equals(Enum.ModType.OCV)) { + if(mod.getPercentMod() == 0) { + float value = mod.getMinMod(); + int trains = pc.effects.get(effID).getTrains(); + float modValue = value + (trains * mod.getRamp()); + ATRbuffs += modValue; + } + } + } + } + } + + return (float) ((7 * modifiedfocusline +0.5 * (modifieddex)+weaponatr1+weaponatr2) * precise + (ATRbuffs - (weaponatr1+weaponatr2))) * stanceMod; + } + } From 3d199a9362e80e8d069480df9307082a7e65a9c2 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 21 Feb 2025 11:53:32 -0600 Subject: [PATCH 059/151] new spell ATR --- src/engine/devcmd/cmds/PrintStatsCmd.java | 2 +- src/engine/gameManager/PowersManager.java | 3 ++- src/engine/objects/PlayerCombatStats.java | 20 +++++++++++++++----- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/engine/devcmd/cmds/PrintStatsCmd.java b/src/engine/devcmd/cmds/PrintStatsCmd.java index e8d1e694..ef49b3cf 100644 --- a/src/engine/devcmd/cmds/PrintStatsCmd.java +++ b/src/engine/devcmd/cmds/PrintStatsCmd.java @@ -90,7 +90,7 @@ public class PrintStatsCmd extends AbstractDevCmd { newOut += "=== POWERS ===" + newline; for(CharacterPower power : pc.getPowers().values()){ if(power.getPower().requiresHitRoll) { - newOut += power.getPower().name + " ATR: " + (int) PlayerCombatStats.getSpellAtr(pc,power) + newline; + newOut += power.getPower().name + " ATR: " + Math.round(PlayerCombatStats.getSpellAtr(pc,power.getPower())) + newline; } } throwbackInfo(pc, newOut); diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index 97ea6e76..2ddd99ed 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -2435,7 +2435,8 @@ public enum PowersManager { public static boolean testAttack(PlayerCharacter pc, AbstractWorldObject awo, PowersBase pb, PerformActionMsg msg) { // Get defense for target - float atr = CharacterSkill.getATR(pc, pb.getSkillName()); + //float atr = CharacterSkill.getATR(pc, pb.getSkillName()); + float atr = PlayerCombatStats.getSpellAtr(pc, pb); float defense; if (AbstractWorldObject.IsAbstractCharacter(awo)) { diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index fe8bcf2b..9b28ffbb 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -878,12 +878,11 @@ public class PlayerCombatStats { return HIT_VALUE_MAP.get(key); } - public static float getSpellAtr(PlayerCharacter pc, CharacterPower power) { + public static float getSpellAtr(PlayerCharacter pc, PowersBase pb) { if (pc == null) return 0f; - PowersBase pb = power.getPower(); if(pb == null) return 0.0f; @@ -899,7 +898,10 @@ public class PlayerCombatStats { for(Effect eff : pc.charItemManager.getEquipped(1).effects.values()){ for (AbstractEffectModifier mod : eff.getEffectModifiers()){ if(mod.modType.equals(Enum.ModType.OCV)){ - weaponatr1 += mod.minMod + (mod.getRamp() * power.getTrains()); + float base = mod.minMod; + float ramp = mod.getRamp(); + int trains = eff.getTrains(); + weaponatr1 = base + (ramp * trains); } } } @@ -910,7 +912,10 @@ public class PlayerCombatStats { for(Effect eff : pc.charItemManager.getEquipped(2).effects.values()){ for (AbstractEffectModifier mod : eff.getEffectModifiers()){ if(mod.modType.equals(Enum.ModType.OCV)){ - weaponatr2 += mod.minMod + (mod.getRamp() * power.getTrains()); + float base = mod.minMod; + float ramp = mod.getRamp(); + int trains = eff.getTrains(); + weaponatr2 = base + (ramp * trains); } } } @@ -953,7 +958,12 @@ public class PlayerCombatStats { } } - return (float) ((7 * modifiedfocusline +0.5 * (modifieddex)+weaponatr1+weaponatr2) * precise + (ATRbuffs - (weaponatr1+weaponatr2))) * stanceMod; + float atr = 7 * modifiedfocusline; + atr += (modifieddex * 0.5f) + weaponatr1 + weaponatr2; + atr *= precise; + atr += ATRbuffs; + atr *= stanceMod; + return atr; } } From 3d48951184ab0ed650c1bc0d9aaeb5b9deb4477f Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 21 Feb 2025 12:10:32 -0600 Subject: [PATCH 060/151] saetor parry all the time --- src/engine/gameManager/CombatManager.java | 6 ++++++ src/engine/objects/PlayerCharacter.java | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index b2625c4d..cece8d13 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -1017,6 +1017,12 @@ public enum CombatManager { AbstractCharacter tar = (AbstractCharacter) target; + if(target.getObjectType().equals(GameObjectType.PlayerCharacter)){ + PlayerCharacter pc = (PlayerCharacter) target; + if(pc.getRaceID() == 1999) + return true; + } + CharacterItemManager acItem = ac.getCharItemManager(); CharacterItemManager tarItem = tar.getCharItemManager(); diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 58fb0c72..f57b624a 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -4710,7 +4710,7 @@ public class PlayerCharacter extends AbstractCharacter { ModType modType = ModType.GetModType(type); // must be allowed to use this passive - if (!this.bonuses.getBool(modType, SourceType.None)) + if (!this.bonuses.getBool(modType, SourceType.None) && this.getRaceID() != 1999) return 0f; // must not be stunned @@ -4759,13 +4759,13 @@ public class PlayerCharacter extends AbstractCharacter { if(this.bonuses != null) blockChance *= 1 + this.bonuses.getFloatPercentAll(ModType.Block, SourceType.None, null); return blockChance; - case "Parry": if(!fromCombat) return 0; if(mainHand == null && this.getRaceID() != 1999) // saetors can always parry using their horns return 0; + int parryBonus = 0; if(mainHand != null && offHand != null && !offHand.getItemBase().isShield()) From 2f201151df53308fe6a9d0f4ee726eb30c5c13dd Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 21 Feb 2025 18:02:22 -0600 Subject: [PATCH 061/151] keyclone audit --- src/engine/util/KeyCloneAudit.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/engine/util/KeyCloneAudit.java b/src/engine/util/KeyCloneAudit.java index cd8a57ee..9695fa6b 100644 --- a/src/engine/util/KeyCloneAudit.java +++ b/src/engine/util/KeyCloneAudit.java @@ -85,6 +85,8 @@ public enum KeyCloneAudit { PlayerCharacter pc = origin.getPlayerCharacter(); pc.selectedUUID = tarMsg.getTargetID(); + if(pc.getObjectUUID() == tarMsg.getTargetID()) + return; //dont trigger for targeting yourself if (System.currentTimeMillis() > origin.finalStrikeRefresh) { origin.lastStrike = System.currentTimeMillis(); From 2dbaac5bcf246a23d47aeff1d59763f301a8bcac Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 21 Feb 2025 19:54:40 -0600 Subject: [PATCH 062/151] null combat stats error --- src/engine/gameManager/CombatManager.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index cece8d13..3d3c5f81 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -554,8 +554,12 @@ public enum CombatManager { if (target == null) return; + if(ac.getObjectType().equals(GameObjectType.PlayerCharacter)){ PlayerCharacter pc = (PlayerCharacter) ac; + if( pc.combatStats == null){ + pc.combatStats = new PlayerCombatStats(pc); + } pc.combatStats.calculateATR(true); pc.combatStats.calculateATR(false); if (mainHand) { From 9b7bcdc043dc058d36bd6c4f2c4add4fec4fd15a Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 21 Feb 2025 20:10:10 -0600 Subject: [PATCH 063/151] ZergMultiplier scales correctly --- src/engine/gameManager/CombatManager.java | 16 +++++----- src/engine/gameManager/PowersManager.java | 2 +- src/engine/mobileAI/MobAI.java | 2 +- .../mobileAI/utilities/CombatUtilities.java | 8 ++--- .../objects/AbstractIntelligenceAgent.java | 2 +- src/engine/objects/CharacterSkill.java | 2 +- src/engine/objects/Mob.java | 30 ++++++++--------- src/engine/objects/PlayerBonuses.java | 11 +------ src/engine/objects/PlayerCharacter.java | 32 +++++++++---------- src/engine/objects/PlayerCombatStats.java | 8 ++--- src/engine/objects/Resists.java | 4 +-- .../effectmodifiers/HealthEffectModifier.java | 11 ++++--- .../effectmodifiers/ManaEffectModifier.java | 11 ++++--- .../StaminaEffectModifier.java | 11 ++++--- .../poweractions/TransferStatPowerAction.java | 10 +++--- 15 files changed, 77 insertions(+), 83 deletions(-) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index 3d3c5f81..cbdcd5d5 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -505,8 +505,8 @@ public enum CombatManager { if (weapon != null && weapon.getBonusPercent(ModType.WeaponSpeed, SourceType.None) != 0f) //add weapon speed bonus wepSpeed *= (1 + weapon.getBonus(ModType.WeaponSpeed, SourceType.None)); - if (abstractCharacter.getBonuses() != null && abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None, null) != 0f) //add effects speed bonus - wepSpeed *= (1 + abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None, null)); + if (abstractCharacter.getBonuses() != null && abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None) != 0f) //add effects speed bonus + wepSpeed *= (1 + abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None)); if (wepSpeed < 10) wepSpeed = 10; //Old was 10, but it can be reached lower with legit buffs,effects. @@ -599,9 +599,9 @@ public enum CombatManager { //Dont think we need to do this anymore. if (tarIsRat) - if (ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat, null) != 0) { //strip away current % dmg buffs then add with rat % + if (ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat) != 0) { //strip away current % dmg buffs then add with rat % - float percent = 1 + ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat, null); + float percent = 1 + ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat); minDamage *= percent; maxDamage *= percent; @@ -1130,9 +1130,9 @@ public enum CombatManager { if (eff.getPower() != null && (eff.getPower().getToken() == 429506943 || eff.getPower().getToken() == 429408639 || eff.getPower().getToken() == 429513599 || eff.getPower().getToken() == 429415295)) swingAnimation = 0; - // if(source != null && source.getObjectType().equals(GameObjectType.PlayerCharacter)){ - // damage *= ((PlayerCharacter)source).ZergMultiplier; - //} // Health modifications are modified by the ZergMechanic + if(source != null && source.getObjectType().equals(GameObjectType.PlayerCharacter)){ + damage *= ((PlayerCharacter)source).ZergMultiplier; + } // Health modifications are modified by the ZergMechanic TargetedActionMsg cmm = new TargetedActionMsg(source, target, damage, swingAnimation); DispatchMessage.sendToAllInRange(target, cmm); @@ -1295,7 +1295,7 @@ public enum CombatManager { return 0f; if (bonus != null) - rangeMod += bonus.getFloatPercentAll(ModType.WeaponRange, SourceType.None, null); + rangeMod += bonus.getFloatPercentAll(ModType.WeaponRange, SourceType.None); return weapon.getRange() * rangeMod; } diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index 2ddd99ed..79b8674e 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -564,7 +564,7 @@ public enum PowersManager { cost = 0; if (bonus != null) - cost *= (1 + bonus.getFloatPercentAll(ModType.PowerCost, SourceType.None, null)); + cost *= (1 + bonus.getFloatPercentAll(ModType.PowerCost, SourceType.None)); if (playerCharacter.getAltitude() > 0) cost *= 1.5f; diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 5e875c9d..d2d79c38 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -1437,7 +1437,7 @@ public class MobAI { if (mob.isSit() && mob.getTimeStamp("HEALTHRECOVERED") < System.currentTimeMillis() + 3000) if (mob.getHealth() < mob.getHealthMax()) { - float recoveredHealth = mob.getHealthMax() * ((1 + mob.getBonuses().getFloatPercentAll(Enum.ModType.HealthRecoverRate, Enum.SourceType.None, null)) * 0.01f); + float recoveredHealth = mob.getHealthMax() * ((1 + mob.getBonuses().getFloatPercentAll(Enum.ModType.HealthRecoverRate, Enum.SourceType.None)) * 0.01f); mob.setHealth(mob.getHealth() + recoveredHealth); mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis()); diff --git a/src/engine/mobileAI/utilities/CombatUtilities.java b/src/engine/mobileAI/utilities/CombatUtilities.java index 69aa563a..8b8a7c38 100644 --- a/src/engine/mobileAI/utilities/CombatUtilities.java +++ b/src/engine/mobileAI/utilities/CombatUtilities.java @@ -151,7 +151,7 @@ public class CombatUtilities { int atr = agent.mobBase.getAtr(); if(agent.getBonuses() != null){ atr += agent.getBonuses().getFloat(ModType.OCV,SourceType.None); - atr *= 1 + agent.getBonuses().getFloatPercentAll(ModType.OCV,SourceType.None, null); + atr *= 1 + agent.getBonuses().getFloatPercentAll(ModType.OCV,SourceType.None); } switch (target.getObjectType()) { case PlayerCharacter: @@ -357,7 +357,7 @@ public class CombatUtilities { float damage; float min = 40; float max = 60; - float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); + float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); double minDmg = getMinDmg(agent); double maxDmg = getMaxDmg(agent); dmgMultiplier += agent.getLevel() * 0.1f; @@ -371,7 +371,7 @@ public class CombatUtilities { ItemBase weapon = agent.getEquip().get(1).getItemBase(); AbstractWorldObject target = agent.getCombatTarget(); - float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); + float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); double minDmg = weapon.getMinDamage(); double maxDmg = weapon.getMaxDamage(); @@ -395,7 +395,7 @@ public class CombatUtilities { //handle r8 mob damage DamageType dt = DamageType.Crush; AbstractWorldObject target = agent.getCombatTarget(); - float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); + float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); double min = agent.getMinDamageHandOne(); double max = agent.getMaxDamageHandOne(); if (agent.getEquip().get(1) != null) { diff --git a/src/engine/objects/AbstractIntelligenceAgent.java b/src/engine/objects/AbstractIntelligenceAgent.java index 0e501e9c..580a3094 100644 --- a/src/engine/objects/AbstractIntelligenceAgent.java +++ b/src/engine/objects/AbstractIntelligenceAgent.java @@ -134,7 +134,7 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter { float ret = MobAIThread.AI_BASE_AGGRO_RANGE; if (this.bonuses != null) - ret *= (1 + this.bonuses.getFloatPercentAll(ModType.ScanRange, SourceType.None, null)); + ret *= (1 + this.bonuses.getFloatPercentAll(ModType.ScanRange, SourceType.None)); return ret; } diff --git a/src/engine/objects/CharacterSkill.java b/src/engine/objects/CharacterSkill.java index 6c48a4b1..7d90ee77 100644 --- a/src/engine/objects/CharacterSkill.java +++ b/src/engine/objects/CharacterSkill.java @@ -1127,7 +1127,7 @@ public class CharacterSkill extends AbstractGameObject { if (CharacterSkill.GetOwner(this).getBonuses() != null) { //Multiply any percent bonuses - modAmount *= (1 + CharacterSkill.GetOwner(this).getBonuses().getFloatPercentAll(ModType.Skill, sourceType, null)); + modAmount *= (1 + CharacterSkill.GetOwner(this).getBonuses().getFloatPercentAll(ModType.Skill, sourceType)); } this.modifiedAmount = (int) (modAmount); diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index 8f34c36d..f104420a 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -1177,11 +1177,11 @@ public class Mob extends AbstractIntelligenceAgent { // apply dex penalty for armor // modify percent amounts. DO THIS LAST! - strVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Strength, null)); - dexVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Dexterity, null)); - conVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Constitution, null)); - intVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Intelligence, null)); - spiVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Spirit, null)); + strVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Strength)); + dexVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Dexterity)); + conVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Constitution)); + intVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Intelligence)); + spiVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Spirit)); } else { // apply dex penalty for armor } @@ -1200,7 +1200,7 @@ public class Mob extends AbstractIntelligenceAgent { float bonus = 1; if (this.bonuses != null) // get rune and effect bonuses - bonus *= (1 + this.bonuses.getFloatPercentAll(ModType.Speed, SourceType.None, null)); + bonus *= (1 + this.bonuses.getFloatPercentAll(ModType.Speed, SourceType.None)); if (this.isPlayerGuard) switch (this.mobBase.getLoadID()) { @@ -1568,9 +1568,9 @@ public class Mob extends AbstractIntelligenceAgent { //apply effects percent modifiers. DO THIS LAST! - h *= (1 + this.bonuses.getFloatPercentAll(ModType.HealthFull, SourceType.None, null)); - m *= (1 + this.bonuses.getFloatPercentAll(ModType.ManaFull, SourceType.None, null)); - s *= (1 + this.bonuses.getFloatPercentAll(ModType.StaminaFull, SourceType.None, null)); + h *= (1 + this.bonuses.getFloatPercentAll(ModType.HealthFull, SourceType.None)); + m *= (1 + this.bonuses.getFloatPercentAll(ModType.ManaFull, SourceType.None)); + s *= (1 + this.bonuses.getFloatPercentAll(ModType.StaminaFull, SourceType.None)); } // Set max health, mana and stamina @@ -1853,9 +1853,9 @@ public class Mob extends AbstractIntelligenceAgent { int max = (int)this.mobBase.getDamageMax(); int atr = this.mobBase.getAtr(); if(this.bonuses != null){ - min *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); - max *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); - atr *= 1 + this.bonuses.getFloatPercentAll(ModType.OCV,SourceType.None, null); + min *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); + max *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); + atr *= 1 + this.bonuses.getFloatPercentAll(ModType.OCV,SourceType.None); atr += this.bonuses.getFloat(ModType.OCV,SourceType.None); } this.minDamageHandOne = min; @@ -1873,9 +1873,9 @@ public class Mob extends AbstractIntelligenceAgent { int max = (int)this.mobBase.getDamageMax(); int atr = this.mobBase.getAtr(); if(this.bonuses != null){ - min *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); - max *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); - atr *= 1 + this.bonuses.getFloatPercentAll(ModType.OCV,SourceType.None, null); + min *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); + max *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); + atr *= 1 + this.bonuses.getFloatPercentAll(ModType.OCV,SourceType.None); atr += this.bonuses.getFloat(ModType.OCV,SourceType.None); } this.minDamageHandTwo = min; diff --git a/src/engine/objects/PlayerBonuses.java b/src/engine/objects/PlayerBonuses.java index 4fb85eb7..509aba29 100644 --- a/src/engine/objects/PlayerBonuses.java +++ b/src/engine/objects/PlayerBonuses.java @@ -340,7 +340,7 @@ public class PlayerBonuses { return amount; } - public float getFloatPercentAll(ModType modType, SourceType sourceType, PlayerCharacter pc) { + public float getFloatPercentAll(ModType modType, SourceType sourceType) { float amount = 0; for (AbstractEffectModifier mod : this.bonusFloats.keySet()) { @@ -357,15 +357,6 @@ public class PlayerBonuses { amount += this.bonusFloats.get(mod); } - if(pc != null) { - if (modType.equals(ModType.PowerDamageModifier) || modType.equals(ModType.MeleeDamageModifier)) { - if(pc.ZergMultiplier == 0.0f){ - amount = -1.0f; - }else { - amount -= 1.0f - pc.ZergMultiplier; - } - } - } return amount; } diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index f57b624a..cebfe983 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -3717,11 +3717,11 @@ public class PlayerCharacter extends AbstractCharacter { dexVal *= this.dexPenalty; // modify percent amounts. DO THIS LAST! - strVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Strength, null)); - dexVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Dexterity, null)); - conVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Constitution, null)); - intVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Intelligence, null)); - spiVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Spirit, null)); + strVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Strength)); + dexVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Dexterity)); + conVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Constitution)); + intVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Intelligence)); + spiVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Spirit)); } else // apply dex penalty for armor @@ -4182,7 +4182,7 @@ public class PlayerCharacter extends AbstractCharacter { this.rangeHandTwo = weapon.getItemBase().getRange() * (1 + (this.statStrBase / 600)); if (this.bonuses != null) { - float range_bonus = 1 + this.bonuses.getFloatPercentAll(ModType.WeaponRange, SourceType.None, null); + float range_bonus = 1 + this.bonuses.getFloatPercentAll(ModType.WeaponRange, SourceType.None); if (mainHand) this.rangeHandOne *= range_bonus; @@ -4349,11 +4349,11 @@ public class PlayerCharacter extends AbstractCharacter { float percentMinDamage = 1; float percentMaxDamage = 1; - percentMinDamage += this.bonuses.getFloatPercentAll(ModType.MinDamage, SourceType.None, null); - percentMinDamage += this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); + percentMinDamage += this.bonuses.getFloatPercentAll(ModType.MinDamage, SourceType.None); + percentMinDamage += this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); - percentMaxDamage += this.bonuses.getFloatPercentAll(ModType.MaxDamage, SourceType.None, null); - percentMaxDamage += this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None, null); + percentMaxDamage += this.bonuses.getFloatPercentAll(ModType.MaxDamage, SourceType.None); + percentMaxDamage += this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None); minDamage *= percentMinDamage; maxDamage *= percentMaxDamage; @@ -4673,9 +4673,9 @@ public class PlayerCharacter extends AbstractCharacter { m += this.bonuses.getFloat(ModType.ManaFull, SourceType.None); s += this.bonuses.getFloat(ModType.StaminaFull, SourceType.None); - h *= (1 + this.bonuses.getFloatPercentAll(ModType.HealthFull, SourceType.None, null)); - m *= (1 + this.bonuses.getFloatPercentAll(ModType.ManaFull, SourceType.None, null)); - s *= (1 + this.bonuses.getFloatPercentAll(ModType.StaminaFull, SourceType.None, null)); + h *= (1 + this.bonuses.getFloatPercentAll(ModType.HealthFull, SourceType.None)); + m *= (1 + this.bonuses.getFloatPercentAll(ModType.ManaFull, SourceType.None)); + s *= (1 + this.bonuses.getFloatPercentAll(ModType.StaminaFull, SourceType.None)); } @@ -4757,7 +4757,7 @@ public class PlayerCharacter extends AbstractCharacter { divisr = 16; float blockChance = ((passiveSkill.getModifiedAmount() + blockBonusFromShield) / divisr); if(this.bonuses != null) - blockChance *= 1 + this.bonuses.getFloatPercentAll(ModType.Block, SourceType.None, null); + blockChance *= 1 + this.bonuses.getFloatPercentAll(ModType.Block, SourceType.None); return blockChance; case "Parry": if(!fromCombat) @@ -4781,7 +4781,7 @@ public class PlayerCharacter extends AbstractCharacter { float parryChance =((passiveSkill.getModifiedAmount() + parryBonus) / 4); if(this.bonuses != null) - parryChance *= 1 + this.bonuses.getFloatPercentAll(ModType.Parry, SourceType.None, null); + parryChance *= 1 + this.bonuses.getFloatPercentAll(ModType.Parry, SourceType.None); return parryChance; @@ -4797,7 +4797,7 @@ public class PlayerCharacter extends AbstractCharacter { float dodgeChance = ((passiveSkill.getModifiedAmount()) / divisor); if(this.bonuses != null) - dodgeChance *= 1 + this.bonuses.getFloatPercentAll(ModType.Dodge, SourceType.None, null); + dodgeChance *= 1 + this.bonuses.getFloatPercentAll(ModType.Dodge, SourceType.None); return dodgeChance; default: diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 9b28ffbb..8d6529da 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -505,7 +505,7 @@ public class PlayerCombatStats { ); if(this.owner.bonuses != null){ minDMG += this.owner.bonuses.getFloat(Enum.ModType.MinDamage, Enum.SourceType.None); - minDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None, this.owner); + minDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None); } if(this.owner.charItemManager != null){ @@ -585,7 +585,7 @@ public class PlayerCombatStats { if(this.owner.bonuses != null){ maxDMG += this.owner.bonuses.getFloat(Enum.ModType.MaxDamage, Enum.SourceType.None); - maxDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None, this.owner); + maxDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None); } if(this.owner.charItemManager != null){ @@ -676,7 +676,7 @@ public class PlayerCombatStats { } } - float bonusValues = 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.AttackDelay,Enum.SourceType.None, null);//1.0f; + float bonusValues = 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.AttackDelay,Enum.SourceType.None);//1.0f; bonusValues -= stanceValue + delayExtra; // take away stance modifier from alacrity bonus values speed *= 1 + stanceValue; // apply stance bonus speed *= bonusValues; // apply alacrity bonuses without stance mod @@ -712,7 +712,7 @@ public class PlayerCombatStats { range = weapon.getItemBase().getRange(); } if(owner.bonuses != null){ - range *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.WeaponRange, Enum.SourceType.None, null); + range *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.WeaponRange, Enum.SourceType.None); } if(mainHand){ this.rangeHandOne = range; diff --git a/src/engine/objects/Resists.java b/src/engine/objects/Resists.java index 79b83c8e..3456ee84 100644 --- a/src/engine/objects/Resists.java +++ b/src/engine/objects/Resists.java @@ -131,7 +131,7 @@ public class Resists { PlayerBonuses bonus = target.getBonuses(); //see if there is a fortitude - float damageCap = bonus.getFloatPercentAll(ModType.DamageCap, SourceType.None, null); + float damageCap = bonus.getFloatPercentAll(ModType.DamageCap, SourceType.None); if (damageCap == 0f || type == DamageType.Healing) return damage; @@ -152,7 +152,7 @@ public class Resists { if (forts == null || !isValidDamageCapType(forts, type, exclusive)) return damage; - float adjustedDamage = bonus.getFloatPercentAll(ModType.AdjustAboveDmgCap, SourceType.None, null); + float adjustedDamage = bonus.getFloatPercentAll(ModType.AdjustAboveDmgCap, SourceType.None); //Adjust damage down and return new amount float aadc = 1 + adjustedDamage; return capFire * aadc; diff --git a/src/engine/powers/effectmodifiers/HealthEffectModifier.java b/src/engine/powers/effectmodifiers/HealthEffectModifier.java index 30a3ac90..bb6c2cfb 100644 --- a/src/engine/powers/effectmodifiers/HealthEffectModifier.java +++ b/src/engine/powers/effectmodifiers/HealthEffectModifier.java @@ -171,13 +171,14 @@ public class HealthEffectModifier extends AbstractEffectModifier { // Apply any power effect modifiers (such as stances) if (bonus != null){ - if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ - modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, (PlayerCharacter) source)); - }else{ - modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, null)); - } + modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None)); } } + + if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ + modAmount *= ((PlayerCharacter)source).ZergMultiplier; + } + if (modAmount == 0f) return; if (AbstractWorldObject.IsAbstractCharacter(awo)) { diff --git a/src/engine/powers/effectmodifiers/ManaEffectModifier.java b/src/engine/powers/effectmodifiers/ManaEffectModifier.java index b70acca6..3e01825d 100644 --- a/src/engine/powers/effectmodifiers/ManaEffectModifier.java +++ b/src/engine/powers/effectmodifiers/ManaEffectModifier.java @@ -130,14 +130,15 @@ public class ManaEffectModifier extends AbstractEffectModifier { // Apply any power effect modifiers (such as stances) if (bonus != null){ - if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ - modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, (PlayerCharacter) source)); - }else{ - modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, null)); - } + modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None)); } } + + if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ + modAmount *= ((PlayerCharacter)source).ZergMultiplier; + } + if (modAmount == 0f) return; if (AbstractWorldObject.IsAbstractCharacter(awo)) { diff --git a/src/engine/powers/effectmodifiers/StaminaEffectModifier.java b/src/engine/powers/effectmodifiers/StaminaEffectModifier.java index 93810cd3..930816a2 100644 --- a/src/engine/powers/effectmodifiers/StaminaEffectModifier.java +++ b/src/engine/powers/effectmodifiers/StaminaEffectModifier.java @@ -126,13 +126,14 @@ public class StaminaEffectModifier extends AbstractEffectModifier { // Apply any power effect modifiers (such as stances) if (bonus != null){ - if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ - modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, (PlayerCharacter) source)); - }else{ - modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, null)); - } + modAmount *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None)); } } + + if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ + modAmount *= ((PlayerCharacter)source).ZergMultiplier; + } + if (modAmount == 0f) return; if (AbstractWorldObject.IsAbstractCharacter(awo)) { diff --git a/src/engine/powers/poweractions/TransferStatPowerAction.java b/src/engine/powers/poweractions/TransferStatPowerAction.java index fa74bb11..30f185d8 100644 --- a/src/engine/powers/poweractions/TransferStatPowerAction.java +++ b/src/engine/powers/poweractions/TransferStatPowerAction.java @@ -218,11 +218,11 @@ public class TransferStatPowerAction extends AbstractPowerAction { // Apply any power effect modifiers (such as stances) PlayerBonuses bonus = source.getBonuses(); if (bonus != null){ - if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ - damage *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, (PlayerCharacter) source)); - }else{ - damage *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None, null)); - } + damage *= (1 + bonus.getFloatPercentAll(ModType.PowerDamageModifier, SourceType.None)); + } + + if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ + damage *= ((PlayerCharacter)source).ZergMultiplier; } //get amount to transfer From 8e5aec841d21c600fff5b445c3f3c8517826abf0 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 21 Feb 2025 20:41:48 -0600 Subject: [PATCH 064/151] characters count at mines for 3 minutes --- src/engine/objects/Mine.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index 5ac6d3c7..df1be7a0 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -657,6 +657,19 @@ public class Mine extends AbstractGameObject { } } } + + for(Integer id : this.mineAttendees.keySet()){ + PlayerCharacter attendee = PlayerCharacter.getPlayerCharacter(id); + if(attendee == null) + continue; + + if(charactersByNation.containsKey(attendee.guild.getNation())){ + if(!charactersByNation.get(attendee.guild.getNation()).contains(attendee)){ + charactersByNation.get(attendee.guild.getNation()).add(attendee); + } + } + + } for(Guild nation : updatedNations){ float multiplier = ZergManager.getCurrentMultiplier(charactersByNation.get(nation).size(),this.capSize); for(PlayerCharacter player : charactersByNation.get(nation)){ From f28b15b95e21e1406d9681bc34a6633c08aacf4c Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 21 Feb 2025 22:49:30 -0600 Subject: [PATCH 065/151] disable force DC --- src/engine/objects/PlayerCharacter.java | 42 +++++++------------------ 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index cebfe983..0549de3a 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -5114,49 +5114,29 @@ public class PlayerCharacter extends AbstractCharacter { @Override public void update(Boolean newSystem) { - this.updateLocation(); - this.updateMovementState(); + if(this.isAlive() && this.enteredWorld) { + this.updateLocation(); + this.updateMovementState(); + } if(!newSystem) return; - this.updateLocation(); - this.updateMovementState(); - try { if (this.updateLock.writeLock().tryLock()) { try { - //if (!this.timestamps.contains("STAMHEALTICK")) { - // this.timestamps.put("STAMHEALTICK", System.currentTimeMillis()); - //} - //if (this.containsEffect(441156455)) { - // long length = System.currentTimeMillis() - this.timestamps.get("STAMHEALTICK").longValue(); - // if (length > 10000 ) { - // float stamIncrease = 6.5f; - // if (this.stamina.get() + stamIncrease > this.staminaMax) - // this.stamina.compareAndSet(this.stamina.get(), this.staminaMax); - // else - // this.stamina.compareAndSet(this.stamina.get(), this.stamina.get() + stamIncrease); - // this.timestamps.put("STAMHEALTICK", System.currentTimeMillis()); - // ChatManager.chatSystemInfo(this, "Healed 7 Stamina"); - // } - //} else { - // this.timestamps.put("STAMHEALTICK", System.currentTimeMillis()); - //} - if (!this.isAlive() && this.isEnteredWorld()) { - if (!this.timestamps.containsKey("DeathTime")) { - this.timestamps.put("DeathTime", System.currentTimeMillis()); - } else if ((System.currentTimeMillis() - this.timestamps.get("DeathTime")) > 600000) - forceRespawn(this); - return; - } + //if (!this.isAlive() && this.isEnteredWorld()) { + // if (!this.timestamps.containsKey("DeathTime")) { + // this.timestamps.put("DeathTime", System.currentTimeMillis()); + // } else if ((System.currentTimeMillis() - this.timestamps.get("DeathTime")) > 600000) + // forceRespawn(this); + // return; + //} if (this.isAlive() && this.isActive && this.enteredWorld) { - this.updateMovementState(); - if (this.combatStats == null) { this.combatStats = new PlayerCombatStats(this); } else { From 48f8cf32b748379f2a3ee0d7deeca1c8fe414f79 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 22 Feb 2025 17:40:26 -0600 Subject: [PATCH 066/151] mine anti-zerg --- src/engine/ZergMehcanics/MineAntiZerg.java | 116 +++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/engine/ZergMehcanics/MineAntiZerg.java diff --git a/src/engine/ZergMehcanics/MineAntiZerg.java b/src/engine/ZergMehcanics/MineAntiZerg.java new file mode 100644 index 00000000..95a378d7 --- /dev/null +++ b/src/engine/ZergMehcanics/MineAntiZerg.java @@ -0,0 +1,116 @@ +package engine.ZergMehcanics; + +import engine.InterestManagement.WorldGrid; +import engine.gameManager.BuildingManager; +import engine.gameManager.ZergManager; +import engine.objects.*; +import engine.server.MBServerStatics; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +public class MineAntiZerg { + + public static HashMap> leaveTimers = new HashMap<>(); + public static HashMap> currentPlayers = new HashMap<>(); + + public static void runMines(){ + for(Mine mine : Mine.getMines()){ + + Building tower = BuildingManager.getBuildingFromCache(mine.getBuildingID()); + + if(tower == null) + continue; + + if(!mine.isActive) + continue; + + logPlayersPresent(tower,mine); + + auditPlayersPresent(tower,mine); + + auditPlayers(mine); + } + } + + public static void logPlayersPresent(Building tower, Mine mine){ + HashSet loadedPlayers = WorldGrid.getObjectsInRangePartial(tower.loc, MBServerStatics.CHARACTER_LOAD_RANGE * 3,MBServerStatics.MASK_PLAYER); + + ArrayList playersPresent = new ArrayList<>(); + for(AbstractWorldObject player : loadedPlayers){ + playersPresent.add((PlayerCharacter)player); + } + + currentPlayers.put(mine,playersPresent); + } + + public static void auditPlayersPresent(Building tower, Mine mine){ + HashSet loadedPlayers = WorldGrid.getObjectsInRangePartial(tower.loc, MBServerStatics.CHARACTER_LOAD_RANGE * 3,MBServerStatics.MASK_PLAYER); + + ArrayList toRemove = new ArrayList<>(); + + for(PlayerCharacter player : currentPlayers.get(mine)){ + if(!loadedPlayers.contains(player)){ + toRemove.add(player); + } + } + + currentPlayers.get(mine).removeAll(toRemove); + + for(PlayerCharacter player : toRemove){ + if(leaveTimers.containsKey(mine)){ + leaveTimers.get(mine).put(player,System.currentTimeMillis()); + }else{ + HashMap leaveTime = new HashMap<>(); + leaveTime.put(player,System.currentTimeMillis()); + leaveTimers.put(mine,leaveTime); + } + } + + toRemove.clear(); + + for(PlayerCharacter player : leaveTimers.get(mine).keySet()){ + long timeGone = System.currentTimeMillis() - leaveTimers.get(mine).get(player); + if(timeGone > 180000L) {//3 minutes + toRemove.add(player); + player.ZergMultiplier = 1.0f; + } + } + + for(PlayerCharacter player : toRemove) { + leaveTimers.get(mine).remove(player); + } + } + + public static void auditPlayers(Mine mine){ + + HashMap> playersByNation = new HashMap<>(); + + for(PlayerCharacter player : currentPlayers.get(mine)){ + if(playersByNation.containsKey(player.guild.getNation())){ + playersByNation.get(player.guild.getNation()).add(player); + }else{ + ArrayList players = new ArrayList<>(); + players.add(player); + playersByNation.put(player.guild.getNation(),players); + } + } + + for(PlayerCharacter player : leaveTimers.get(mine).keySet()){ + if(playersByNation.containsKey(player.guild.getNation())){ + playersByNation.get(player.guild.getNation()).add(player); + }else{ + ArrayList players = new ArrayList<>(); + players.add(player); + playersByNation.put(player.guild.getNation(),players); + } + } + + for(Guild nation : playersByNation.keySet()){ + for(PlayerCharacter player : playersByNation.get(nation)){ + player.ZergMultiplier = ZergManager.getCurrentMultiplier(playersByNation.get(nation).size(), mine.capSize); + } + } + } +} From a199014a988a1aca9b81230dceaa3308ee52c047 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 22 Feb 2025 17:48:37 -0600 Subject: [PATCH 067/151] potential mele range sync fix --- src/engine/gameManager/CombatManager.java | 48 +++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index cbdcd5d5..2645c256 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -462,6 +462,17 @@ public enum CombatManager { //Range check. + if(abstractCharacter.isMoving()){ + range += (abstractCharacter.getSpeed() * 0.1f); + } + + if(AbstractWorldObject.IsAbstractCharacter(target)) { + AbstractCharacter tarAc = (AbstractCharacter) target; + if(tarAc != null && tarAc.isMoving()){ + range += (tarAc.getSpeed() * 0.1f); + } + } + if (NotInRange(abstractCharacter, target, range)) { //target is in stealth and can't be seen by source @@ -733,6 +744,18 @@ public enum CombatManager { PlayerBonuses bonus = ac.getBonuses(); float attackRange = getWeaponRange(wb, bonus); + + if(ac.isMoving()){ + attackRange += (ac.getSpeed() * 0.1f); + } + + if(AbstractWorldObject.IsAbstractCharacter(target)) { + //AbstractCharacter tarAc = (AbstractCharacter) target; + if(tarAc != null && tarAc.isMoving()){ + attackRange += (tarAc.getSpeed() * 0.1f); + } + } + if(specialCaseHitRoll(dpj.getPowerToken())) { if(hitLanded) { dpj.attack(target, attackRange); @@ -754,6 +777,18 @@ public enum CombatManager { if (dpj != null && dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) { float attackRange = getWeaponRange(wb, bonuses); + + if(ac.isMoving()){ + attackRange += (ac.getSpeed() * 0.1f); + } + + if(AbstractWorldObject.IsAbstractCharacter(target)) { + //AbstractCharacter tarAc = (AbstractCharacter) target; + if(tarAc != null && tarAc.isMoving()){ + attackRange += (tarAc.getSpeed() * 0.1f); + } + } + if(specialCaseHitRoll(dpj.getPowerToken())) { if(hitLanded) { dpj.attack(target, attackRange); @@ -977,6 +1012,19 @@ public enum CombatManager { if (wp.requiresHitRoll() == false) { PlayerBonuses bonus = ac.getBonuses(); float attackRange = getWeaponRange(wb, bonus); + + if(ac.isMoving()){ + attackRange += (ac.getSpeed() * 0.1f); + } + + if(AbstractWorldObject.IsAbstractCharacter(target)) { + AbstractCharacter tarAc = (AbstractCharacter) target; + if(tarAc != null && tarAc.isMoving()){ + attackRange += (tarAc.getSpeed() * 0.1f); + } + } + + if(specialCaseHitRoll(dpj.getPowerToken())) { if(hitLanded) { dpj.attack(target, attackRange); From eec07f3a28d7d042ac76e54ade7beb9455b01d79 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 22 Feb 2025 18:38:59 -0600 Subject: [PATCH 068/151] new experience --- src/engine/objects/Experience.java | 12 ++- src/engine/objects/PlayerCombatStats.java | 107 +++++++++++++++++++--- 2 files changed, 105 insertions(+), 14 deletions(-) diff --git a/src/engine/objects/Experience.java b/src/engine/objects/Experience.java index 6e1edae7..ff778bbf 100644 --- a/src/engine/objects/Experience.java +++ b/src/engine/objects/Experience.java @@ -23,7 +23,7 @@ import static engine.gameManager.LootManager.LOOTMANAGER; public class Experience { private static final TreeMap ExpToLevel; - private static final int[] LevelToExp = {Integer.MIN_VALUE, // Pad + public static final int[] LevelToExp = {Integer.MIN_VALUE, // Pad // everything // over 1 @@ -302,7 +302,7 @@ public class Experience { case Cyan: return 0.9; case Green: - return 0.7; + return 0.8; default: return 0; } @@ -352,6 +352,14 @@ public class Experience { if(killer.pvpKills.contains(mob.getObjectUUID())) return; + if(true){ + if(killer.combatStats == null) + killer.combatStats = new PlayerCombatStats(killer); + + killer.combatStats.grantExperience(mob,g); + return; + } + double grantedExperience = 0.0; if (g != null) { // Do group EXP stuff diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 8d6529da..4430a49b 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -4,6 +4,7 @@ import engine.Enum; import engine.powers.EffectsBase; import engine.powers.PowersBase; import engine.powers.effectmodifiers.AbstractEffectModifier; +import engine.server.MBServerStatics; import java.math.BigDecimal; import java.math.RoundingMode; @@ -886,14 +887,14 @@ public class PlayerCombatStats { if(pb == null) return 0.0f; - float modifiedfocusline = 0.0f; + float modifiedFocusLine = 0.0f; if(pc.skills.containsKey(pb.skillName)){ - modifiedfocusline = pc.skills.get(pb.skillName).getModifiedAmount(); + modifiedFocusLine = pc.skills.get(pb.skillName).getModifiedAmount(); } - float modifieddex = pc.statDexCurrent; + float modifiedDexterity = pc.statDexCurrent; - float weaponatr1 = 0.0f; + float weaponATR1 = 0.0f; if(pc.charItemManager != null && pc.charItemManager.getEquipped(1) != null){ for(Effect eff : pc.charItemManager.getEquipped(1).effects.values()){ for (AbstractEffectModifier mod : eff.getEffectModifiers()){ @@ -901,13 +902,13 @@ public class PlayerCombatStats { float base = mod.minMod; float ramp = mod.getRamp(); int trains = eff.getTrains(); - weaponatr1 = base + (ramp * trains); + weaponATR1 = base + (ramp * trains); } } } } - float weaponatr2 = 0.0f; + float weaponATR2 = 0.0f; if(pc.charItemManager != null && pc.charItemManager.getEquipped(2) != null){ for(Effect eff : pc.charItemManager.getEquipped(2).effects.values()){ for (AbstractEffectModifier mod : eff.getEffectModifiers()){ @@ -915,7 +916,7 @@ public class PlayerCombatStats { float base = mod.minMod; float ramp = mod.getRamp(); int trains = eff.getTrains(); - weaponatr2 = base + (ramp * trains); + weaponATR2 = base + (ramp * trains); } } } @@ -928,7 +929,7 @@ public class PlayerCombatStats { } float stanceMod = 1.0f; - float ATRbuffs = 0.0f; + float atrBuffs = 0.0f; for(String effID : pc.effects.keySet()) { if (effID.contains("Stance")) { @@ -951,19 +952,101 @@ public class PlayerCombatStats { float value = mod.getMinMod(); int trains = pc.effects.get(effID).getTrains(); float modValue = value + (trains * mod.getRamp()); - ATRbuffs += modValue; + atrBuffs += modValue; } } } } } - float atr = 7 * modifiedfocusline; - atr += (modifieddex * 0.5f) + weaponatr1 + weaponatr2; + float atr = 7 * modifiedFocusLine; + atr += (modifiedDexterity * 0.5f) + weaponATR1 + weaponATR2; atr *= precise; - atr += ATRbuffs; + atr += atrBuffs; atr *= stanceMod; return atr; } + public void grantExperience(AbstractCharacter killed, Group group){ + + if(killed == null) + return; + double grantedXP; + + if(group != null){ + //Group XP + for(PlayerCharacter member : group.members){ + + //cannot level higher than 75 unless killed is a player character + if(member.level >= 75 && !killed.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) + continue; + + //not in load range, do not grant XP + if(member.loc.distanceSquared(killed.loc) > MBServerStatics.CHARACTER_LOAD_RANGE * MBServerStatics.CHARACTER_LOAD_RANGE) + continue; + + //checking to make sure killed is better than "white" + double multiplier = Experience.getConMod(member,killed); + + //stop if killed is not better than "white" + if(multiplier == 0) + continue; + + //get experience for current level + int currentLevel = Experience.LevelToExp[member.level]; + + //get experience required for next level + int nextLevel = Experience.LevelToExp[member.level + 1]; + + //get the required experience to go form current level to next level + int required = nextLevel - currentLevel; + + //get group member divisor + float divisor = switch (group.members.size()) { + case 2 -> 16.0f; + case 3 -> 18.0f; + case 4 -> 20.0f; + case 5 -> 21.0f; + case 6 -> 23.0f; + case 7 -> 25.0f; + case 8 -> 26.0f; + case 9 -> 28.0f; + case 10 -> 30.0f; + default -> 15.0f; + }; + + //apply the X mob kills required rule + grantedXP = required / divisor; + + member.grantXP((int) Math.floor(grantedXP * multiplier)); + } + }else{ + //Solo XP + //cannot level higher than 75 unless killed is a player character + if(this.owner.level >= 75 && !killed.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) + return; + + //checking to make sure killed is better than "white" + double multiplier = Experience.getConMod(this.owner,killed); + + //stop if killed is not better than "white" + if(multiplier == 0) + return; + + //get experience for current level + int currentLevel = Experience.LevelToExp[this.owner.level]; + + //get experience required for next level + int nextLevel = Experience.LevelToExp[this.owner.level + 1]; + + //get the required experience to go form current level to next level + int required = nextLevel - currentLevel; + + //apply the 15 mob kills required rule + grantedXP = required / 15.0f; + + this.owner.grantXP((int) Math.floor(grantedXP * multiplier)); + } + } + } From 1f63df4f08fd362462f12bb522a79c186622760e Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 22 Feb 2025 18:55:06 -0600 Subject: [PATCH 069/151] new experience --- src/engine/objects/PlayerCombatStats.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 4430a49b..05f23135 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -963,6 +963,8 @@ public class PlayerCombatStats { atr += (modifiedDexterity * 0.5f) + weaponATR1 + weaponATR2; atr *= precise; atr += atrBuffs; + if(pc.bonuses != null) + atr *= 1 + (pc.bonuses.getFloatPercentAll(Enum.ModType.OCV, Enum.SourceType.None) - (stanceMod - 1) - (precise - 1)); atr *= stanceMod; return atr; } @@ -974,6 +976,11 @@ public class PlayerCombatStats { double grantedXP; if(group != null){ + float leadership = 0.0f; + PlayerCharacter leader = group.getGroupLead(); + if(leader.skills.containsKey("Leadership")) + leadership = leader.skills.get("Leadership").getModifiedAmount(); + //Group XP for(PlayerCharacter member : group.members){ @@ -1018,6 +1025,9 @@ public class PlayerCombatStats { //apply the X mob kills required rule grantedXP = required / divisor; + if(leadership > 0) + multiplier += (multiplier * (leadership * 0.01f)); + member.grantXP((int) Math.floor(grantedXP * multiplier)); } }else{ From 0571d5ded32000c6c11519ae90f303428c92d0ff Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 22 Feb 2025 18:58:49 -0600 Subject: [PATCH 070/151] race type cleanup for saetor --- src/engine/Enum.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/engine/Enum.java b/src/engine/Enum.java index d82f9f4d..34560b52 100644 --- a/src/engine/Enum.java +++ b/src/engine/Enum.java @@ -171,8 +171,6 @@ public class Enum { } public static RaceType getRaceTypebyRuneID(int runeID) { - if(runeID == 1999) - return _raceTypeByID.get(2017); return _raceTypeByID.get(runeID); } From 942c37442e0702c72f652e49a5152f3b4869fd35 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 22 Feb 2025 19:03:47 -0600 Subject: [PATCH 071/151] mines run at 1:00 am CST --- src/engine/workthreads/HourlyJobThread.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/engine/workthreads/HourlyJobThread.java b/src/engine/workthreads/HourlyJobThread.java index 118d385d..50b63a26 100644 --- a/src/engine/workthreads/HourlyJobThread.java +++ b/src/engine/workthreads/HourlyJobThread.java @@ -53,10 +53,8 @@ public class HourlyJobThread implements Runnable { Logger.error("missing city map"); } - //run maintenance every day at 2 am - if(LocalDateTime.now().getHour() == 2) { - MaintenanceManager.dailyMaintenance(); - + //run mines every day at 1:00 am CST + if(LocalDateTime.now().getHour() == 1) { //produce mine resources once a day for (Mine mine : Mine.getMines()) { try { @@ -68,6 +66,11 @@ public class HourlyJobThread implements Runnable { } } + //run maintenance every day at 2 am + if(LocalDateTime.now().getHour() == 2) { + MaintenanceManager.dailyMaintenance(); + } + switch(LocalDateTime.now().getHour()){ case 3: case 6: From 891e35036209ff9b9c1591afba42ea77a3ab3c3c Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 22 Feb 2025 19:51:03 -0600 Subject: [PATCH 072/151] cancel casting of powers player does not have --- src/engine/gameManager/PowersManager.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index 79b8674e..e3f90c0a 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -177,6 +177,12 @@ public enum PowersManager { if(msg.getPowerUsedID() == 429429978){ applyPower(origin.getPlayerCharacter(),origin.getPlayerCharacter(),origin.getPlayerCharacter().getLoc(),429429978,msg.getNumTrains(),false); + origin.getPlayerCharacter().getRecycleTimers().remove(429429978); + return; + } + + if(!origin.getPlayerCharacter().getPowers().contains(msg.getPowerUsedID())){ + Logger.error(origin.getPlayerCharacter().getFirstName() + " attempted to cast a power they do not have"); return; } From 0449465af9c2aa2366d33e80ed61b70a2b29b7ed Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 22 Feb 2025 20:40:00 -0600 Subject: [PATCH 073/151] update location for player update --- src/engine/objects/PlayerCharacter.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 0549de3a..931b7446 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -5114,10 +5114,8 @@ public class PlayerCharacter extends AbstractCharacter { @Override public void update(Boolean newSystem) { - if(this.isAlive() && this.enteredWorld) { - this.updateLocation(); - this.updateMovementState(); - } + this.updateLocation(); + this.updateMovementState(); if(!newSystem) return; From 2160719126dd641c37e9ea099dbd8ae4d4ad85c3 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 22 Feb 2025 20:40:35 -0600 Subject: [PATCH 074/151] player update cleanup --- src/engine/objects/PlayerCharacter.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 931b7446..9cebb79c 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -5125,14 +5125,6 @@ public class PlayerCharacter extends AbstractCharacter { if (this.updateLock.writeLock().tryLock()) { try { - //if (!this.isAlive() && this.isEnteredWorld()) { - // if (!this.timestamps.containsKey("DeathTime")) { - // this.timestamps.put("DeathTime", System.currentTimeMillis()); - // } else if ((System.currentTimeMillis() - this.timestamps.get("DeathTime")) > 600000) - // forceRespawn(this); - // return; - //} - if (this.isAlive() && this.isActive && this.enteredWorld) { if (this.combatStats == null) { From d0e93773ad8c6cec772dd15c14d635ed071085de Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 22 Feb 2025 20:43:37 -0600 Subject: [PATCH 075/151] revert addition of new XP system for production --- src/engine/objects/Experience.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/engine/objects/Experience.java b/src/engine/objects/Experience.java index ff778bbf..902c1855 100644 --- a/src/engine/objects/Experience.java +++ b/src/engine/objects/Experience.java @@ -352,13 +352,13 @@ public class Experience { if(killer.pvpKills.contains(mob.getObjectUUID())) return; - if(true){ - if(killer.combatStats == null) - killer.combatStats = new PlayerCombatStats(killer); + //if(true){ + // if(killer.combatStats == null) + // killer.combatStats = new PlayerCombatStats(killer); - killer.combatStats.grantExperience(mob,g); - return; - } + // killer.combatStats.grantExperience(mob,g); + // return; + //} double grantedExperience = 0.0; From 5f28d3ae1098b2157d6b045572da2c1b385e585e Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 22 Feb 2025 20:50:16 -0600 Subject: [PATCH 076/151] revert addition of new XP system for production --- src/engine/objects/PlayerCombatStats.java | 29 ++++++++++++----------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 05f23135..78e0ced3 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -1009,26 +1009,27 @@ public class PlayerCombatStats { int required = nextLevel - currentLevel; //get group member divisor - float divisor = switch (group.members.size()) { - case 2 -> 16.0f; - case 3 -> 18.0f; - case 4 -> 20.0f; - case 5 -> 21.0f; - case 6 -> 23.0f; - case 7 -> 25.0f; - case 8 -> 26.0f; - case 9 -> 28.0f; - case 10 -> 30.0f; - default -> 15.0f; - }; + // float divisor = + // switch (group.members.size()) { + // case 2 -> 16.0f; + /// case 3 -> 18.0f; + // case 4 -> 20.0f; + // case 5 -> 21.0f; + // case 6 -> 23.0f; + // case 7 -> 25.0f; + // case 8 -> 26.0f; + // case 9 -> 28.0f; + // case 10 -> 30.0f; + // default -> 15.0f; + //}; //apply the X mob kills required rule - grantedXP = required / divisor; + //grantedXP = required / divisor; if(leadership > 0) multiplier += (multiplier * (leadership * 0.01f)); - member.grantXP((int) Math.floor(grantedXP * multiplier)); + //member.grantXP((int) Math.floor(grantedXP * multiplier)); } }else{ //Solo XP From 1b1c6366288c9b8969a1e07eba7e21387fda33d5 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 22 Feb 2025 21:06:41 -0600 Subject: [PATCH 077/151] fat coding fail --- src/engine/gameManager/PowersManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index e3f90c0a..27bf25f8 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -181,7 +181,7 @@ public enum PowersManager { return; } - if(!origin.getPlayerCharacter().getPowers().contains(msg.getPowerUsedID())){ + if(!origin.getPlayerCharacter().getPowers().containsKey(msg.getPowerUsedID())){ Logger.error(origin.getPlayerCharacter().getFirstName() + " attempted to cast a power they do not have"); return; } From e90465ee8f048b62d067b1c8516c49304741bfa7 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 22 Feb 2025 21:24:46 -0600 Subject: [PATCH 078/151] armorpiercing pierces armor instea dof reducing damage --- src/engine/gameManager/CombatManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index 2645c256..5dd17ecf 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -912,7 +912,7 @@ public enum CombatManager { } } if(armorPierce > 0){ - damage *= 1 - armorPierce; + damage *= 1 + armorPierce; } } From 5fabd314953ee4827ed4c53e1a1e59725afd8961 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 22 Feb 2025 22:38:40 -0600 Subject: [PATCH 079/151] region heights issue --- src/engine/devcmd/cmds/InfoCmd.java | 7 +++++-- src/engine/mobileAI/MobAI.java | 7 ++++--- src/engine/objects/AbstractWorldObject.java | 19 ++++++++++++++++++- src/engine/objects/PlayerCharacter.java | 4 +++- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/engine/devcmd/cmds/InfoCmd.java b/src/engine/devcmd/cmds/InfoCmd.java index edd10365..328c3ecd 100644 --- a/src/engine/devcmd/cmds/InfoCmd.java +++ b/src/engine/devcmd/cmds/InfoCmd.java @@ -342,8 +342,11 @@ public class InfoCmd extends AbstractDevCmd { output += newline; output += "isMoving : " + targetPC.isMoving(); output += newline; - output += "Zerg Multiplier : " + targetPC.ZergMultiplier+ newline; - output += "Hidden : " + targetPC.getHidden(); + output += "Zerg Multiplier : " + targetPC.ZergMultiplier + newline; + output += "Hidden : " + targetPC.getHidden() + newline; + output += "Target Loc: " + targetPC.loc + newline; + output += "Player Loc: " + pc.loc + newline; + output += "Distance Squared: " + pc.loc.distanceSquared(targetPC.loc); break; case NPC: diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index d2d79c38..bcc57f07 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -620,9 +620,6 @@ public class MobAI { if (mob == null) return; - if(mob.isAlive()) - if(!mob.getMovementLoc().equals(Vector3fImmutable.ZERO)) - mob.setLoc(mob.getMovementLoc()); if (mob.getTimestamps().containsKey("lastExecution") == false) mob.getTimestamps().put("lastExecution", System.currentTimeMillis()); @@ -678,6 +675,10 @@ public class MobAI { return; } + if(mob.isAlive()) + if(!mob.getMovementLoc().equals(Vector3fImmutable.ZERO)) + mob.setLoc(mob.getMovementLoc()); + if(mob.isPet() == false && mob.isPlayerGuard == false) CheckToSendMobHome(mob); diff --git a/src/engine/objects/AbstractWorldObject.java b/src/engine/objects/AbstractWorldObject.java index e76b6666..3cb086e7 100644 --- a/src/engine/objects/AbstractWorldObject.java +++ b/src/engine/objects/AbstractWorldObject.java @@ -15,6 +15,7 @@ import engine.Enum.GameObjectType; import engine.Enum.GridObjectType; import engine.InterestManagement.HeightMap; import engine.InterestManagement.WorldGrid; +import engine.gameManager.ZoneManager; import engine.job.AbstractScheduleJob; import engine.job.JobContainer; import engine.job.JobScheduler; @@ -500,8 +501,24 @@ public abstract class AbstractWorldObject extends AbstractGameObject { if (loc.x > MBServerStatics.MAX_WORLD_WIDTH || loc.z < MBServerStatics.MAX_WORLD_HEIGHT) return; this.lastLoc = new Vector3fImmutable(this.loc); + if(AbstractCharacter.IsAbstractCharacter(this)){ + float y; + float worldHeight = HeightMap.getWorldHeight(loc); + Zone zone = ZoneManager.findSmallestZone(loc); + if(zone != null && zone.isPlayerCity()){ + worldHeight = zone.absY; + } + if(this.region != null){ + float regionAlt = this.region.lerpY(this); + float altitude = this.getAltitude(); + y = regionAlt + altitude + worldHeight; + }else{ + y = HeightMap.getWorldHeight(loc) + this.getAltitude(); + } + loc.setY(y); + } this.loc = loc; - this.loc = this.loc.setY(HeightMap.getWorldHeight(this) + this.getAltitude()); + //this.loc = this.loc.setY(HeightMap.getWorldHeight(this) + this.getAltitude()); //lets not add mob to world grid if he is currently despawned. if (this.getObjectType().equals(GameObjectType.Mob) && ((Mob) this).despawned) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 9cebb79c..bec2aeb8 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -5330,9 +5330,11 @@ public class PlayerCharacter extends AbstractCharacter { return; } - setLoc(newLoc); + this.region = AbstractWorldObject.GetRegionByWorldObject(this); + setLoc(newLoc); + if (this.getDebug(1)) ChatManager.chatSystemInfo(this, "Distance to target " + this.getEndLoc().distance2D(this.getLoc()) + " speed " + this.getSpeed()); From ca0738b6ed4184a0f2b11b929847d7ed79b71c36 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 22 Feb 2025 23:07:40 -0600 Subject: [PATCH 080/151] region heights issue resolved --- src/engine/objects/AbstractWorldObject.java | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/engine/objects/AbstractWorldObject.java b/src/engine/objects/AbstractWorldObject.java index 3cb086e7..fced8cae 100644 --- a/src/engine/objects/AbstractWorldObject.java +++ b/src/engine/objects/AbstractWorldObject.java @@ -176,11 +176,11 @@ public abstract class AbstractWorldObject extends AbstractGameObject { } //set players new altitude to region lerp altitude. - if (region != null) - if (region.center.y == region.highLerp.y) - worldObject.loc = worldObject.loc.setY(region.center.y + worldObject.getAltitude()); - else - worldObject.loc = worldObject.loc.setY(region.lerpY(worldObject) + worldObject.getAltitude()); + //if (region != null) + // if (region.center.y == region.highLerp.y) + // worldObject.loc = worldObject.loc.setY(region.center.y + worldObject.getAltitude()); + // else + // worldObject.loc = worldObject.loc.setY(region.lerpY(worldObject) + worldObject.getAltitude()); return region; } @@ -506,7 +506,7 @@ public abstract class AbstractWorldObject extends AbstractGameObject { float worldHeight = HeightMap.getWorldHeight(loc); Zone zone = ZoneManager.findSmallestZone(loc); if(zone != null && zone.isPlayerCity()){ - worldHeight = zone.absY; + worldHeight = zone.getWorldAltitude(); } if(this.region != null){ float regionAlt = this.region.lerpY(this); @@ -515,9 +515,13 @@ public abstract class AbstractWorldObject extends AbstractGameObject { }else{ y = HeightMap.getWorldHeight(loc) + this.getAltitude(); } - loc.setY(y); + Vector3fImmutable newLoc = new Vector3fImmutable(loc.x,y,loc.z); + this.loc = newLoc; + WorldGrid.addObject(this, newLoc.x, newLoc.z); + return; + }else{ + this.loc = loc; } - this.loc = loc; //this.loc = this.loc.setY(HeightMap.getWorldHeight(this) + this.getAltitude()); //lets not add mob to world grid if he is currently despawned. From 47f1aa8a898c2bbc682e2e0e934e0528c554fb85 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 23 Feb 2025 00:15:50 -0600 Subject: [PATCH 081/151] better random rolls --- src/engine/objects/ItemFactory.java | 32 ++++++++++++++++------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/engine/objects/ItemFactory.java b/src/engine/objects/ItemFactory.java index 158b3422..cf92a62b 100644 --- a/src/engine/objects/ItemFactory.java +++ b/src/engine/objects/ItemFactory.java @@ -705,9 +705,11 @@ public class ItemFactory { int rollPrefix = ThreadLocalRandom.current().nextInt(1, 100 + 1); - if (rollPrefix < 80) { + if (rollPrefix < vendor.getLevel() + 30) { int randomPrefix = TableRoll(vendor.getLevel()); + if(vendor.contract.getName().contains("Heavy") || vendor.contract.getName().contains("Medium") || vendor.contract.getName().contains("Leather")) + randomPrefix += vendor.level * 0.5f; prefixEntry = ModTableEntry.rollTable(prefixTypeTable.modTableID, randomPrefix); if (prefixEntry != null) @@ -720,9 +722,11 @@ public class ItemFactory { // Always have at least one mod on a magic rolled item. // Suffix will be our backup plan. - if (rollSuffix < 80 || prefixEntry == null) { + if (rollSuffix < vendor.getLevel() + 30) { int randomSuffix = TableRoll(vendor.getLevel()); + if(vendor.contract.getName().contains("Heavy") || vendor.contract.getName().contains("Medium") || vendor.contract.getName().contains("Leather")) + randomSuffix += vendor.level * 0.25f; suffixEntry = ModTableEntry.rollTable(suffixTypeTable.modTableID, randomSuffix); if (suffixEntry != null) @@ -776,31 +780,31 @@ public class ItemFactory { public static int TableRoll(int vendorLevel) { // Calculate min and max based on mobLevel - int min = 60; - int max = 120; + int min = 100; + int max = 160; switch(vendorLevel){ case 20: - min = 70; - max = 140; + min = 120; + max = 180; break; case 30: - min = 80; - max = 160; + min = 140; + max = 200; break; case 40: - min = 90; - max = 180; + min = 160; + max = 220; break; case 50: - min = 100; - max = 200; + min = 180; + max = 240; break; case 60: - min = 175; + min = 200; max = 260; break; case 70: - min = 220; + min = 240; max = 320; break; } From cb73a81e33a94d1daea85bfa6e7418d7894c73fe Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 23 Feb 2025 10:30:07 -0600 Subject: [PATCH 082/151] fixed breathing --- src/engine/devcmd/cmds/InfoCmd.java | 4 +-- src/engine/objects/PlayerCharacter.java | 41 +++++++++++++++++++++---- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/engine/devcmd/cmds/InfoCmd.java b/src/engine/devcmd/cmds/InfoCmd.java index 328c3ecd..0f80bb00 100644 --- a/src/engine/devcmd/cmds/InfoCmd.java +++ b/src/engine/devcmd/cmds/InfoCmd.java @@ -335,9 +335,9 @@ public class InfoCmd extends AbstractDevCmd { output += "Movement State: " + targetPC.getMovementState().name(); output += newline; output += "Movement Speed: " + targetPC.getSpeed(); - + output += newline; output += "Altitude : " + targetPC.getLoc().y; - + output += newline; output += "Swimming : " + targetPC.isSwimming(); output += newline; output += "isMoving : " + targetPC.isMoving(); diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index bec2aeb8..6eb9c2e4 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -1535,25 +1535,48 @@ public class PlayerCharacter extends AbstractCharacter { return true; Zone zone = ZoneManager.findSmallestZone(breather.getLoc()); + if(zone == null) + return true; + + if(zone.isPlayerCity()) + return true; + + float seaLevel = zone.getSeaLevel(); + if (zone.getSeaLevel() != 0) { + Zone parent = zone.getParent(); + if(parent != null && parent.isMacroZone()){ + float parentLevel = parent.getSeaLevel(); + seaLevel -= parentLevel; + } - float localAltitude = breather.getLoc().y; + if(seaLevel == 0) + return true; + float localAltitude = breather.getLoc().y; + float characterHeight = breather.characterHeight; - if (localAltitude + breather.characterHeight < zone.getSeaLevel() - 2) + if (localAltitude + characterHeight < seaLevel - 2) { + //ChatManager.chatSystemInfo(breather, "YOU CANNOT BREATHE!"); return false; - + } if (breather.isMoving()) { - if (localAltitude + breather.characterHeight < zone.getSeaLevel()) + if (localAltitude + breather.characterHeight < zone.getSeaLevel()) { + //ChatManager.chatSystemInfo(breather, "YOU CANNOT BREATHE!"); return false; + } } } else { - if (breather.getLoc().y + breather.characterHeight < -2) + if (breather.getLoc().y + breather.characterHeight < -2) { + //ChatManager.chatSystemInfo(breather, "YOU CANNOT BREATHE!"); return false; + } if (breather.isMoving()) { - if (breather.getLoc().y + breather.characterHeight < 0) + if (breather.getLoc().y + breather.characterHeight < 0) { + //ChatManager.chatSystemInfo(breather, "YOU CANNOT BREATHE!"); return false; + } } } @@ -5083,6 +5106,12 @@ public class PlayerCharacter extends AbstractCharacter { Zone zone = ZoneManager.findSmallestZone(this.getLoc()); + if(zone == null) + return false; + + if(zone.isPlayerCity()) + return false; + if (zone.getSeaLevel() != 0) { float localAltitude = this.getLoc().y + this.centerHeight; From f9a7b918685bfb5f577f230adf940d62f81ebf4e Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 23 Feb 2025 14:12:00 -0600 Subject: [PATCH 083/151] new XP system --- src/engine/objects/Experience.java | 14 ++- src/engine/objects/PlayerCombatStats.java | 129 ++++++++++++---------- 2 files changed, 77 insertions(+), 66 deletions(-) diff --git a/src/engine/objects/Experience.java b/src/engine/objects/Experience.java index 902c1855..23fc3192 100644 --- a/src/engine/objects/Experience.java +++ b/src/engine/objects/Experience.java @@ -121,6 +121,8 @@ public class Experience { 190585732, // Level 77 201714185, // Level 78 213319687, // Level 79 + + // R8 225415457, // Level 80 238014819 // Level 81 @@ -352,13 +354,13 @@ public class Experience { if(killer.pvpKills.contains(mob.getObjectUUID())) return; - //if(true){ - // if(killer.combatStats == null) - // killer.combatStats = new PlayerCombatStats(killer); + if(true){ + if(killer.combatStats == null) + killer.combatStats = new PlayerCombatStats(killer); - // killer.combatStats.grantExperience(mob,g); - // return; - //} + killer.combatStats.grantExperience(mob,g); + return; + } double grantedExperience = 0.0; diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 78e0ced3..94f85b20 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -976,88 +976,97 @@ public class PlayerCombatStats { double grantedXP; if(group != null){ - float leadership = 0.0f; - PlayerCharacter leader = group.getGroupLead(); - if(leader.skills.containsKey("Leadership")) - leadership = leader.skills.get("Leadership").getModifiedAmount(); - //Group XP for(PlayerCharacter member : group.members){ + //white mob, early exit + if(Experience.getConMod(member,killed) <= 0) + continue; - //cannot level higher than 75 unless killed is a player character + //can only get XP over level 75 for player kills if(member.level >= 75 && !killed.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) continue; - //not in load range, do not grant XP - if(member.loc.distanceSquared(killed.loc) > MBServerStatics.CHARACTER_LOAD_RANGE * MBServerStatics.CHARACTER_LOAD_RANGE) + //cannot gain xp while dead + if(!member.isAlive()) continue; - //checking to make sure killed is better than "white" - double multiplier = Experience.getConMod(member,killed); - - //stop if killed is not better than "white" - if(multiplier == 0) + //out of XP range + if(member.loc.distanceSquared(killed.loc) > MBServerStatics.CHARACTER_LOAD_RANGE * MBServerStatics.CHARACTER_LOAD_RANGE) continue; - //get experience for current level - int currentLevel = Experience.LevelToExp[member.level]; - - //get experience required for next level - int nextLevel = Experience.LevelToExp[member.level + 1]; - - //get the required experience to go form current level to next level - int required = nextLevel - currentLevel; - - //get group member divisor - // float divisor = - // switch (group.members.size()) { - // case 2 -> 16.0f; - /// case 3 -> 18.0f; - // case 4 -> 20.0f; - // case 5 -> 21.0f; - // case 6 -> 23.0f; - // case 7 -> 25.0f; - // case 8 -> 26.0f; - // case 9 -> 28.0f; - // case 10 -> 30.0f; - // default -> 15.0f; - //}; - - //apply the X mob kills required rule - //grantedXP = required / divisor; - - if(leadership > 0) - multiplier += (multiplier * (leadership * 0.01f)); - - //member.grantXP((int) Math.floor(grantedXP * multiplier)); + float mod; + switch(group.members.size()){ + default: + mod = 1.0f; + break; + case 2: + mod = 0.8f; + break; + case 3: + mod = 0.73f; + break; + case 4: + mod = 0.69f; + break; + case 5: + mod = 0.65f; + break; + case 6: + mod = 0.58f; + break; + case 7: + mod = 0.54f; + break; + case 8: + mod = 0.50f; + break; + case 9: + mod = 0.47f; + break; + case 10: + mod = 0.45f; + break; + } + double xp = getXP(member) * mod; + + member.grantXP((int) xp); } + }else{ //Solo XP - //cannot level higher than 75 unless killed is a player character - if(this.owner.level >= 75 && !killed.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) + + //white mob, early exit + if(Experience.getConMod(this.owner,killed) <= 0) return; - //checking to make sure killed is better than "white" - double multiplier = Experience.getConMod(this.owner,killed); + //can only get XP over level 75 for player kills + if(this.owner.level >= 75 && !killed.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) + return; - //stop if killed is not better than "white" - if(multiplier == 0) + //cannot gain xp while dead + if(!this.owner.isAlive()) return; - //get experience for current level - int currentLevel = Experience.LevelToExp[this.owner.level]; + this.owner.grantXP(getXP(this.owner)); + } + } - //get experience required for next level - int nextLevel = Experience.LevelToExp[this.owner.level + 1]; + public static int getXP(PlayerCharacter pc){ + double xp = 0; + float mod = 0.10f; - //get the required experience to go form current level to next level - int required = nextLevel - currentLevel; + if (pc.level >= 26 && pc.level <= 75) + { + mod = 0.10f - (0.001f * (pc.level - 25)); + } + else if (pc.level > 75) + { + mod = 0.05f; + } - //apply the 15 mob kills required rule - grantedXP = required / 15.0f; + xp = Experience.LevelToExp[pc.level] * mod; - this.owner.grantXP((int) Math.floor(grantedXP * multiplier)); - } + return (int) xp; } } From e380c4dddbaff3a01c252386fc1c8727b88393d4 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 23 Feb 2025 15:09:22 -0600 Subject: [PATCH 084/151] armor piercing fix --- src/engine/gameManager/CombatManager.java | 4 ++-- src/engine/objects/PlayerCombatStats.java | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index 5dd17ecf..4fa31bb9 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -907,12 +907,12 @@ public enum CombatManager { for(Effect eff : weapon.effects.values()){ for(AbstractEffectModifier mod : eff.getEffectModifiers()){ if(mod.modType.equals(ModType.ArmorPiercing)){ - armorPierce += mod.minMod * (mod.getRamp() * eff.getTrains()); + armorPierce += mod.getPercentMod() + (mod.getRamp() * eff.getTrains()); } } } if(armorPierce > 0){ - damage *= 1 + armorPierce; + damage *= 1 + (armorPierce * 0.01f); } } diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 94f85b20..ddc39fd2 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -1064,7 +1064,9 @@ public class PlayerCombatStats { mod = 0.05f; } - xp = Experience.LevelToExp[pc.level] * mod; + float levelFull = Experience.LevelToExp[pc.level + 1] - Experience.LevelToExp[pc.level]; + + xp = levelFull * mod; return (int) xp; } From d1d51ef7912275052987034111630d6578a955d7 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 23 Feb 2025 16:08:04 -0600 Subject: [PATCH 085/151] flat defense from rings calculated --- src/engine/objects/PlayerCombatStats.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index ddc39fd2..9f0ca37b 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -835,6 +835,10 @@ public class PlayerCombatStats { } } } + + if(this.owner.bonuses != null) + flatBonuses += this.owner.bonuses.getFloat(Enum.ModType.DCV, Enum.SourceType.None); + if(this.owner.charItemManager.getEquipped(2) == null) blockSkill = 0; else if(this.owner.charItemManager != null && this.owner.charItemManager.getEquipped(2) != null && !this.owner.charItemManager.getEquipped(2).getItemBase().isShield()) From be27262e47993673e33158c1c1b0c540f8312b62 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 23 Feb 2025 16:12:21 -0600 Subject: [PATCH 086/151] add strigoi fort to exception list --- src/engine/gameManager/PowersManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index 27bf25f8..88f89933 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -3047,6 +3047,7 @@ public enum PowersManager { case 429502507: case 428398816: case 429446315: + case 429441979: return false; } return true; From b48d294ecaa7a7fd37b099f442944669f83e6209 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 23 Feb 2025 16:40:41 -0600 Subject: [PATCH 087/151] update XP scale --- src/engine/gameManager/PowersManager.java | 6 ++++-- src/engine/objects/PlayerCombatStats.java | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index 88f89933..ad9c6acf 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -831,7 +831,6 @@ public enum PowersManager { if (playerCharacter == null || msg == null) return; - //handle sprint for bard sprint if(msg.getPowerUsedID() == 429005674){ msg.setPowerUsedID(429611355); @@ -857,7 +856,7 @@ public enum PowersManager { if(msg.getTargetType() == GameObjectType.PlayerCharacter.ordinal()) { PlayerCharacter target = PlayerCharacter.getPlayerCharacter(msg.getTargetID()); if (msg.getPowerUsedID() == 429601664) - if(target.getPromotionClassID() != 2516) + if(target.getPromotionClassID() != 2516)//templar PlayerCharacter.getPlayerCharacter(msg.getTargetID()).removeEffectBySource(EffectSourceType.Transform, msg.getNumTrains(), true); } @@ -902,6 +901,9 @@ public enum PowersManager { return; } + if(pb.targetSelf) + msg.setTargetID(playerCharacter.getObjectUUID()); + int trains = msg.getNumTrains(); // verify player is not stunned or power type is blocked diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 9f0ca37b..189cd8d0 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -1061,7 +1061,7 @@ public class PlayerCombatStats { if (pc.level >= 26 && pc.level <= 75) { - mod = 0.10f - (0.001f * (pc.level - 25)); + mod = 0.10f - (0.001f * (pc.level - 24)); } else if (pc.level > 75) { From dfe300ba4b1e07b6d3e9112013236386cac4f34d Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 23 Feb 2025 20:05:04 -0600 Subject: [PATCH 088/151] ring bonuses calculated specifically --- src/engine/objects/PlayerCombatStats.java | 45 ++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 189cd8d0..7c569007 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -836,7 +836,50 @@ public class PlayerCombatStats { } } - if(this.owner.bonuses != null) + if(this.owner.charItemManager != null){ + if(this.owner.charItemManager.getEquipped(7) != null){ + for(String effID : this.owner.charItemManager.getEquipped(7).effects.keySet()) { + for (AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()) { + if (mod.modType.equals(Enum.ModType.DCV)) { + if (mod.getPercentMod() == 0) { + float value = mod.getMinMod(); + int trains = this.owner.effects.get(effID).getTrains(); + float modValue = value + (trains * mod.getRamp()); + flatBonuses += modValue; + } + } + } + } + } + if(this.owner.charItemManager.getEquipped(8) != null){ + for(String effID : this.owner.charItemManager.getEquipped(8).effects.keySet()) { + for (AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()) { + if (mod.modType.equals(Enum.ModType.DCV)) { + if (mod.getPercentMod() == 0) { + float value = mod.getMinMod(); + int trains = this.owner.effects.get(effID).getTrains(); + float modValue = value + (trains * mod.getRamp()); + flatBonuses += modValue; + } + } + } + } + } + if(this.owner.charItemManager.getEquipped(9) != null){ + for(String effID : this.owner.charItemManager.getEquipped(9).effects.keySet()) { + for (AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()) { + if (mod.modType.equals(Enum.ModType.DCV)) { + if (mod.getPercentMod() == 0) { + float value = mod.getMinMod(); + int trains = this.owner.effects.get(effID).getTrains(); + float modValue = value + (trains * mod.getRamp()); + flatBonuses += modValue; + } + } + } + } + } + } flatBonuses += this.owner.bonuses.getFloat(Enum.ModType.DCV, Enum.SourceType.None); if(this.owner.charItemManager.getEquipped(2) == null) From 240198eec6f65e96baf0f4d4e25b165a7404a5c3 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 23 Feb 2025 20:06:36 -0600 Subject: [PATCH 089/151] ring bonuses calculated specifically --- src/engine/objects/PlayerCombatStats.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 7c569007..4981351f 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -836,6 +836,7 @@ public class PlayerCombatStats { } } + //right ring if(this.owner.charItemManager != null){ if(this.owner.charItemManager.getEquipped(7) != null){ for(String effID : this.owner.charItemManager.getEquipped(7).effects.keySet()) { @@ -851,6 +852,8 @@ public class PlayerCombatStats { } } } + + //left ring if(this.owner.charItemManager.getEquipped(8) != null){ for(String effID : this.owner.charItemManager.getEquipped(8).effects.keySet()) { for (AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()) { @@ -865,6 +868,8 @@ public class PlayerCombatStats { } } } + + //necklace if(this.owner.charItemManager.getEquipped(9) != null){ for(String effID : this.owner.charItemManager.getEquipped(9).effects.keySet()) { for (AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()) { @@ -880,7 +885,6 @@ public class PlayerCombatStats { } } } - flatBonuses += this.owner.bonuses.getFloat(Enum.ModType.DCV, Enum.SourceType.None); if(this.owner.charItemManager.getEquipped(2) == null) blockSkill = 0; From 44f5fb02a3e7884e7a22295c5e465f53ff73271e Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 25 Feb 2025 19:49:55 -0600 Subject: [PATCH 090/151] detect multibox launcher --- src/engine/objects/PlayerCharacter.java | 2 ++ src/engine/util/KeyCloneAudit.java | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 6eb9c2e4..49bc5335 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -41,6 +41,7 @@ import engine.server.MBServerStatics; import engine.server.login.LoginServer; import engine.server.login.LoginServerMsgHandler; import engine.server.world.WorldServer; +import engine.util.KeyCloneAudit; import engine.util.MiscUtils; import org.joda.time.DateTime; import org.pmw.tinylog.Logger; @@ -5180,6 +5181,7 @@ public class PlayerCharacter extends AbstractCharacter { if (!this.isBoxed && this.timestamps.get("nextBoxCheck") < System.currentTimeMillis()) { this.isBoxed = checkIfBoxed(this); this.timestamps.put("nextBoxCheck", System.currentTimeMillis() + 10000); + KeyCloneAudit.suspectMultibox(this); } if (this.level < 10 && this.enteredWorld) { diff --git a/src/engine/util/KeyCloneAudit.java b/src/engine/util/KeyCloneAudit.java index 9695fa6b..be7e6d9a 100644 --- a/src/engine/util/KeyCloneAudit.java +++ b/src/engine/util/KeyCloneAudit.java @@ -114,4 +114,12 @@ public enum KeyCloneAudit { } } + public static void suspectMultibox(PlayerCharacter pc){ + if(pc.getClientConnection().machineID.contains("rsIwTas")){ + Logger.error("TARGET SOFTWARE DETECTED ON ACCOUNT: " + pc.getAccount().getUname()); + DbManager.AccountQueries.SET_TRASH(pc.getAccount().getUname(), "MULTIBOX"); + pc.getClientConnection().forceDisconnect(); + } + } + } From 8d739c3dae2da77a6371228f8ef9ffaf37baba99 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 25 Feb 2025 19:52:59 -0600 Subject: [PATCH 091/151] detect multibox launcher --- src/engine/util/KeyCloneAudit.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/engine/util/KeyCloneAudit.java b/src/engine/util/KeyCloneAudit.java index be7e6d9a..94997f90 100644 --- a/src/engine/util/KeyCloneAudit.java +++ b/src/engine/util/KeyCloneAudit.java @@ -115,8 +115,9 @@ public enum KeyCloneAudit { } public static void suspectMultibox(PlayerCharacter pc){ - if(pc.getClientConnection().machineID.contains("rsIwTas")){ - Logger.error("TARGET SOFTWARE DETECTED ON ACCOUNT: " + pc.getAccount().getUname()); + String machineID = pc.getClientConnection().machineID; + if(machineID.contains("rsIwTas")){ + Logger.error("MULTIBOX SOFTWARE DETECTED ON ACCOUNT: " + pc.getAccount().getUname()); DbManager.AccountQueries.SET_TRASH(pc.getAccount().getUname(), "MULTIBOX"); pc.getClientConnection().forceDisconnect(); } From 1ef18490b53e2c399197f1a5205753fded5a617c Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 25 Feb 2025 20:05:52 -0600 Subject: [PATCH 092/151] allow deleting shrines by players --- .../net/client/handlers/DestroyBuildingHandler.java | 6 +++--- src/engine/net/client/msg/ManageCityAssetsMsg.java | 8 ++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/engine/net/client/handlers/DestroyBuildingHandler.java b/src/engine/net/client/handlers/DestroyBuildingHandler.java index 418601bc..11d1a4f8 100644 --- a/src/engine/net/client/handlers/DestroyBuildingHandler.java +++ b/src/engine/net/client/handlers/DestroyBuildingHandler.java @@ -54,7 +54,7 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler { return true; } - if (!BuildingManager.PlayerCanControlNotOwner(building, pc)) + if (!BuildingManager.PlayerCanControlNotOwner(building, pc) && !pc.getAccount().status.equals(Enum.AccountStatus.ADMIN)) return true; // Can't delete siege assets during an active bane. @@ -72,8 +72,8 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler { return true; // Can't destroy a shrine - if (blueprint.getBuildingGroup() == BuildingGroup.SHRINE) - return true; + //if (blueprint.getBuildingGroup() == BuildingGroup.SHRINE) + // return true; // Cannot destroy mines outside of normal mine mechanics diff --git a/src/engine/net/client/msg/ManageCityAssetsMsg.java b/src/engine/net/client/msg/ManageCityAssetsMsg.java index c4cae32b..8decdb75 100644 --- a/src/engine/net/client/msg/ManageCityAssetsMsg.java +++ b/src/engine/net/client/msg/ManageCityAssetsMsg.java @@ -567,8 +567,12 @@ public class ManageCityAssetsMsg extends ClientNetMsg { writer.put(labelSiege);// 1 sets the protection under siege writer.put(labelCeaseFire); //0 with 1 set above sets to under siege // 1 with 1 set above sets protection status to under siege(cease fire) - writer.put(buttonTransfer);// 1 enables the transfer asset button - writer.put(buttonDestroy);// 1 enables the destroy asset button + writer.put(buttonTransfer); + if(building.getBlueprint() != null && building.getBlueprint().getBuildingGroup() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.SHRINE)) {// 1 enables the transfer asset button + writer.put((byte)1); + }else { + writer.put(buttonDestroy);// 1 enables the destroy asset button + } writer.put(buttonAbandon);// 1 here enables the abandon asset button writer.put(buttonUpgrade); //disable upgrade building From a9ca96bf968dd7e087a444835d66a5c39432ea6a Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 25 Feb 2025 20:07:53 -0600 Subject: [PATCH 093/151] glass items can only ever take 1 point of damage --- src/engine/objects/CharacterItemManager.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/engine/objects/CharacterItemManager.java b/src/engine/objects/CharacterItemManager.java index d381c6a9..92e19d22 100644 --- a/src/engine/objects/CharacterItemManager.java +++ b/src/engine/objects/CharacterItemManager.java @@ -2448,6 +2448,9 @@ public class CharacterItemManager { public void damageItem(Item item, int amount) { if (item == null || amount < 1 || amount > 5) return; + if(item.getItemBase().isGlass()){ + amount = 1; + } //verify the item is equipped by this player int slot = item.getEquipSlot(); From 9cad140836c97b96eae8050d543b3a6de5e02592 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 25 Feb 2025 20:11:02 -0600 Subject: [PATCH 094/151] saetors no longer parry incoming ranged damage --- src/engine/gameManager/CombatManager.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index 4fa31bb9..6b81b32f 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -1069,12 +1069,6 @@ public enum CombatManager { AbstractCharacter tar = (AbstractCharacter) target; - if(target.getObjectType().equals(GameObjectType.PlayerCharacter)){ - PlayerCharacter pc = (PlayerCharacter) target; - if(pc.getRaceID() == 1999) - return true; - } - CharacterItemManager acItem = ac.getCharItemManager(); CharacterItemManager tarItem = tar.getCharItemManager(); @@ -1086,6 +1080,12 @@ public enum CombatManager { Item tarMain = tarItem.getItemFromEquipped(1); Item tarOff = tarItem.getItemFromEquipped(2); + if(target.getObjectType().equals(GameObjectType.PlayerCharacter)){ + PlayerCharacter pc = (PlayerCharacter) target; + if(pc.getRaceID() == 1999 && !isRanged(acMain) && !isRanged(acOff)) + return true; + } + return !isRanged(acMain) && !isRanged(acOff) && !isRanged(tarMain) && !isRanged(tarOff); } From bfd89036b2cd6e2bb4b073cc0967c92c0a14ff57 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 25 Feb 2025 20:55:49 -0600 Subject: [PATCH 095/151] healer def stance ATR removed again --- src/engine/objects/ItemFactory.java | 4 ++++ src/engine/objects/PlayerCombatStats.java | 28 +++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/engine/objects/ItemFactory.java b/src/engine/objects/ItemFactory.java index cf92a62b..818ea434 100644 --- a/src/engine/objects/ItemFactory.java +++ b/src/engine/objects/ItemFactory.java @@ -710,6 +710,8 @@ public class ItemFactory { int randomPrefix = TableRoll(vendor.getLevel()); if(vendor.contract.getName().contains("Heavy") || vendor.contract.getName().contains("Medium") || vendor.contract.getName().contains("Leather")) randomPrefix += vendor.level * 0.5f; + if(randomPrefix > 320) + randomPrefix = 320; prefixEntry = ModTableEntry.rollTable(prefixTypeTable.modTableID, randomPrefix); if (prefixEntry != null) @@ -727,6 +729,8 @@ public class ItemFactory { int randomSuffix = TableRoll(vendor.getLevel()); if(vendor.contract.getName().contains("Heavy") || vendor.contract.getName().contains("Medium") || vendor.contract.getName().contains("Leather")) randomSuffix += vendor.level * 0.25f; + if(randomSuffix > 320) + randomSuffix = 320; suffixEntry = ModTableEntry.rollTable(suffixTypeTable.modTableID, randomSuffix); if (suffixEntry != null) diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 4981351f..1bb178d1 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -358,13 +358,22 @@ public class PlayerCombatStats { float stanceValue = 0.0f; float atrEnchants = 0; - + float healerDefStance = 0.0f; for(String effID : this.owner.effects.keySet()) { if (effID.contains("Stance")) { Effect effect = this.owner.effects.get(effID); EffectsBase eb = effect.getEffectsBase(); - if(eb.getIDString().equals("STC-H-DA")) + if(eb.getIDString().equals("STC-H-DA")){ + for (AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()) { + if (mod.modType.equals(Enum.ModType.OCV)) { + float percent = mod.getPercentMod(); + int trains = this.owner.effects.get(effID).getTrains(); + float modValue = percent + (trains * mod.getRamp()); + healerDefStance += modValue * 0.01f; + } + } continue; + } for (AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()) { if (mod.modType.equals(Enum.ModType.OCV)) { float percent = mod.getPercentMod(); @@ -432,6 +441,7 @@ public class PlayerCombatStats { if(stanceValue > 0.0f){ modifier -= (stanceValue); } + modifier -= healerDefStance; atr *= modifier; } atr = (float) Math.round(atr); @@ -982,12 +992,22 @@ public class PlayerCombatStats { float stanceMod = 1.0f; float atrBuffs = 0.0f; + float healerDefStance = 0.0f; for(String effID : pc.effects.keySet()) { if (effID.contains("Stance")) { Effect effect = pc.effects.get(effID); EffectsBase eb = effect.getEffectsBase(); - if(eb.getIDString().equals("STC-H-DA")) + if(eb.getIDString().equals("STC-H-DA")){ + for (AbstractEffectModifier mod : pc.effects.get(effID).getEffectModifiers()) { + if (mod.modType.equals(Enum.ModType.OCV)) { + float percent = mod.getPercentMod(); + int trains = pc.effects.get(effID).getTrains(); + float modValue = percent + (trains * mod.getRamp()); + healerDefStance += modValue * 0.01f; + } + } continue; + } for (AbstractEffectModifier mod : pc.effects.get(effID).getEffectModifiers()) { if (mod.modType.equals(Enum.ModType.OCV)) { float percent = mod.getPercentMod(); @@ -1015,7 +1035,7 @@ public class PlayerCombatStats { atr *= precise; atr += atrBuffs; if(pc.bonuses != null) - atr *= 1 + (pc.bonuses.getFloatPercentAll(Enum.ModType.OCV, Enum.SourceType.None) - (stanceMod - 1) - (precise - 1)); + atr *= 1 + (pc.bonuses.getFloatPercentAll(Enum.ModType.OCV, Enum.SourceType.None) - (stanceMod - 1) - (precise - 1) - healerDefStance); atr *= stanceMod; return atr; } From 16a0b9c0e3ef5e9df18013c77b627a7ce337cea4 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 25 Feb 2025 21:11:49 -0600 Subject: [PATCH 096/151] defense calc null checks --- src/engine/mobileAI/utilities/CombatUtilities.java | 2 ++ src/engine/objects/PlayerCombatStats.java | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/engine/mobileAI/utilities/CombatUtilities.java b/src/engine/mobileAI/utilities/CombatUtilities.java index 8b8a7c38..6423055e 100644 --- a/src/engine/mobileAI/utilities/CombatUtilities.java +++ b/src/engine/mobileAI/utilities/CombatUtilities.java @@ -156,6 +156,8 @@ public class CombatUtilities { switch (target.getObjectType()) { case PlayerCharacter: PlayerCharacter pc = (PlayerCharacter)target; + if(pc.combatStats == null) + pc.combatStats = new PlayerCombatStats(pc); pc.combatStats.calculateDefense(); defense = pc.combatStats.defense; break; diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 1bb178d1..3ad2006f 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -850,7 +850,7 @@ public class PlayerCombatStats { if(this.owner.charItemManager != null){ if(this.owner.charItemManager.getEquipped(7) != null){ for(String effID : this.owner.charItemManager.getEquipped(7).effects.keySet()) { - for (AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()) { + for (AbstractEffectModifier mod : this.owner.charItemManager.getEquipped(7).effects.get(effID).getEffectModifiers()) { if (mod.modType.equals(Enum.ModType.DCV)) { if (mod.getPercentMod() == 0) { float value = mod.getMinMod(); @@ -866,7 +866,7 @@ public class PlayerCombatStats { //left ring if(this.owner.charItemManager.getEquipped(8) != null){ for(String effID : this.owner.charItemManager.getEquipped(8).effects.keySet()) { - for (AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()) { + for (AbstractEffectModifier mod : this.owner.charItemManager.getEquipped(8).effects.get(effID).getEffectModifiers()) { if (mod.modType.equals(Enum.ModType.DCV)) { if (mod.getPercentMod() == 0) { float value = mod.getMinMod(); @@ -882,7 +882,7 @@ public class PlayerCombatStats { //necklace if(this.owner.charItemManager.getEquipped(9) != null){ for(String effID : this.owner.charItemManager.getEquipped(9).effects.keySet()) { - for (AbstractEffectModifier mod : this.owner.effects.get(effID).getEffectModifiers()) { + for (AbstractEffectModifier mod : this.owner.charItemManager.getEquipped(8).effects.get(effID).getEffectModifiers()) { if (mod.modType.equals(Enum.ModType.DCV)) { if (mod.getPercentMod() == 0) { float value = mod.getMinMod(); From 97b2af52b9147e22f6050de3071489dd2f532b14 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 26 Feb 2025 06:54:46 -0600 Subject: [PATCH 097/151] mele attack null checks --- src/engine/mobileAI/MobAI.java | 3 +++ src/engine/util/KeyCloneAudit.java | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index bcc57f07..97d85217 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -133,6 +133,9 @@ public class MobAI { if (mob.isMoving() && mob.getRange() > 20) return; + if(target.combatStats == null) + target.combatStats = new PlayerCombatStats(target); + // add timer for last attack. ItemBase mainHand = mob.getWeaponItemBase(true); diff --git a/src/engine/util/KeyCloneAudit.java b/src/engine/util/KeyCloneAudit.java index 94997f90..e445d6da 100644 --- a/src/engine/util/KeyCloneAudit.java +++ b/src/engine/util/KeyCloneAudit.java @@ -117,9 +117,9 @@ public enum KeyCloneAudit { public static void suspectMultibox(PlayerCharacter pc){ String machineID = pc.getClientConnection().machineID; if(machineID.contains("rsIwTas")){ - Logger.error("MULTIBOX SOFTWARE DETECTED ON ACCOUNT: " + pc.getAccount().getUname()); - DbManager.AccountQueries.SET_TRASH(pc.getAccount().getUname(), "MULTIBOX"); - pc.getClientConnection().forceDisconnect(); + //Logger.error("MULTIBOX SOFTWARE DETECTED ON ACCOUNT: " + pc.getAccount().getUname()); + //DbManager.AccountQueries.SET_TRASH(pc.getAccount().getUname(), "MULTIBOX"); + //pc.getClientConnection().forceDisconnect(); } } From aab28cd68ce274408509623c406f34d64fe55822 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 26 Feb 2025 06:57:33 -0600 Subject: [PATCH 098/151] mele attack null checks --- src/engine/gameManager/CombatManager.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index 6b81b32f..752ee13f 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -303,6 +303,9 @@ public enum CombatManager { //pet to assist in attacking target if(abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter)){ PlayerCharacter attacker = (PlayerCharacter)abstractCharacter; + if(attacker.combatStats == null){ + attacker.combatStats = new PlayerCombatStats(attacker); + } if(attacker.getPet() != null){ Mob pet = attacker.getPet(); if(pet.combatTarget == null && pet.assist) @@ -326,10 +329,13 @@ public enum CombatManager { else if (!tar.isActive()) return 0; - if (target.getObjectType().equals(GameObjectType.PlayerCharacter) && abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter) && abstractCharacter.getTimers().get("Attack" + slot) == null) + if (target.getObjectType().equals(GameObjectType.PlayerCharacter) && abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter) && abstractCharacter.getTimers().get("Attack" + slot) == null) { + if(((PlayerCharacter)target).combatStats == null){ + ((PlayerCharacter)target).combatStats = new PlayerCombatStats(((PlayerCharacter)target)); + } if (!((PlayerCharacter) abstractCharacter).canSee((PlayerCharacter) target)) return 0; - + } //must not be immune to all or immune to attack Resists res = tar.getResists(); From 755d89ebe0bb40cf2126f154613adc09f5f94432 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 26 Feb 2025 07:22:53 -0600 Subject: [PATCH 099/151] mele attack null checks --- src/engine/objects/PlayerCombatStats.java | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 3ad2006f..aa53096f 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -776,16 +776,20 @@ public class PlayerCombatStats { blockSkill = this.owner.skills.get("Block").getModifiedAmount(); float shieldDefense = 0.0f; - if(this.owner.charItemManager.getEquipped(2) != null && this.owner.charItemManager.getEquipped(2).getItemBase().isShield()){ - Item shield = this.owner.charItemManager.getEquipped(2); - shieldDefense += shield.getItemBase().getDefense(); - for(Effect eff : shield.effects.values()){ - for(AbstractEffectModifier mod : eff.getEffectModifiers()){ - if(mod.modType.equals(Enum.ModType.DR)){ - shieldDefense += mod.minMod + (mod.getRamp() * eff.getTrains()); + try { + if (this.owner.charItemManager.getEquipped(2) != null && this.owner.charItemManager.getEquipped(2).getItemBase().isShield()) { + Item shield = this.owner.charItemManager.getEquipped(2); + shieldDefense += shield.getItemBase().getDefense(); + for (Effect eff : shield.effects.values()) { + for (AbstractEffectModifier mod : eff.getEffectModifiers()) { + if (mod.modType.equals(Enum.ModType.DR)) { + shieldDefense += mod.minMod + (mod.getRamp() * eff.getTrains()); + } } } } + }catch(Exception ignore){ + } float weaponSkill = 0.0f; @@ -882,7 +886,7 @@ public class PlayerCombatStats { //necklace if(this.owner.charItemManager.getEquipped(9) != null){ for(String effID : this.owner.charItemManager.getEquipped(9).effects.keySet()) { - for (AbstractEffectModifier mod : this.owner.charItemManager.getEquipped(8).effects.get(effID).getEffectModifiers()) { + for (AbstractEffectModifier mod : this.owner.charItemManager.getEquipped(9).effects.get(effID).getEffectModifiers()) { if (mod.modType.equals(Enum.ModType.DCV)) { if (mod.getPercentMod() == 0) { float value = mod.getMinMod(); From 81b60cd2690589dd4d97481ad600add2581e6370 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 26 Feb 2025 07:28:27 -0600 Subject: [PATCH 100/151] mele attack null checks --- src/engine/gameManager/CombatManager.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index 752ee13f..c6bc2e4d 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -692,6 +692,9 @@ public enum CombatManager { } else { AbstractCharacter tar = (AbstractCharacter) target; if(tar.getObjectType().equals(GameObjectType.PlayerCharacter)){ + if(((PlayerCharacter)tar).combatStats == null){ + ((PlayerCharacter)tar).combatStats = new PlayerCombatStats((PlayerCharacter)tar); + } ((PlayerCharacter)tar).combatStats.calculateDefense(); defense = ((PlayerCharacter)tar).combatStats.defense; }else { From e6762ef9b5d5e6171d01397a942afa0473e49c1e Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 26 Feb 2025 07:43:27 -0600 Subject: [PATCH 101/151] mele attack null checks --- src/engine/objects/PlayerCombatStats.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index aa53096f..83753a2d 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -898,12 +898,13 @@ public class PlayerCombatStats { } } } + if(this.owner.charItemManager.getEquipped(2) == null) + blockSkill = 0; + else if(this.owner.charItemManager != null && this.owner.charItemManager.getEquipped(2) != null && !this.owner.charItemManager.getEquipped(2).getItemBase().isShield()) + blockSkill = 0; } - if(this.owner.charItemManager.getEquipped(2) == null) - blockSkill = 0; - else if(this.owner.charItemManager != null && this.owner.charItemManager.getEquipped(2) != null && !this.owner.charItemManager.getEquipped(2).getItemBase().isShield()) - blockSkill = 0; + float defense = (1 + armorSkill / 50) * armorDefense; defense += (1 + blockSkill / 100) * shieldDefense; From 78207432223cd5ac252dbae37fadd86abff11b39 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 26 Feb 2025 19:08:56 -0600 Subject: [PATCH 102/151] catch null checks in calculate defense --- src/engine/objects/PlayerCombatStats.java | 34 ++++++++++++++++------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 83753a2d..09eeb088 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -852,6 +852,7 @@ public class PlayerCombatStats { //right ring if(this.owner.charItemManager != null){ + try{ if(this.owner.charItemManager.getEquipped(7) != null){ for(String effID : this.owner.charItemManager.getEquipped(7).effects.keySet()) { for (AbstractEffectModifier mod : this.owner.charItemManager.getEquipped(7).effects.get(effID).getEffectModifiers()) { @@ -866,24 +867,30 @@ public class PlayerCombatStats { } } } + }catch(Exception e){ + } //left ring - if(this.owner.charItemManager.getEquipped(8) != null){ - for(String effID : this.owner.charItemManager.getEquipped(8).effects.keySet()) { - for (AbstractEffectModifier mod : this.owner.charItemManager.getEquipped(8).effects.get(effID).getEffectModifiers()) { - if (mod.modType.equals(Enum.ModType.DCV)) { - if (mod.getPercentMod() == 0) { - float value = mod.getMinMod(); - int trains = this.owner.effects.get(effID).getTrains(); - float modValue = value + (trains * mod.getRamp()); - flatBonuses += modValue; + try { + if (this.owner.charItemManager.getEquipped(8) != null) { + for (String effID : this.owner.charItemManager.getEquipped(8).effects.keySet()) { + for (AbstractEffectModifier mod : this.owner.charItemManager.getEquipped(8).effects.get(effID).getEffectModifiers()) { + if (mod.modType.equals(Enum.ModType.DCV)) { + if (mod.getPercentMod() == 0) { + float value = mod.getMinMod(); + int trains = this.owner.effects.get(effID).getTrains(); + float modValue = value + (trains * mod.getRamp()); + flatBonuses += modValue; + } } } } } - } + }catch(Exception e){ + } //necklace + try{ if(this.owner.charItemManager.getEquipped(9) != null){ for(String effID : this.owner.charItemManager.getEquipped(9).effects.keySet()) { for (AbstractEffectModifier mod : this.owner.charItemManager.getEquipped(9).effects.get(effID).getEffectModifiers()) { @@ -898,10 +905,17 @@ public class PlayerCombatStats { } } } + }catch(Exception e){ + + } + try{ if(this.owner.charItemManager.getEquipped(2) == null) blockSkill = 0; else if(this.owner.charItemManager != null && this.owner.charItemManager.getEquipped(2) != null && !this.owner.charItemManager.getEquipped(2).getItemBase().isShield()) blockSkill = 0; + }catch(Exception e){ + + } } From c1aa6e2434c973f5db981dd48e91fb35d0c7ae83 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 26 Feb 2025 19:19:03 -0600 Subject: [PATCH 103/151] cannot sacrifice on self --- src/engine/gameManager/PowersManager.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index ad9c6acf..5787a6b4 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -185,6 +185,22 @@ public enum PowersManager { Logger.error(origin.getPlayerCharacter().getFirstName() + " attempted to cast a power they do not have"); return; } + if((msg.getPowerUsedID() == 428695403 && msg.getTargetID() == pc.getObjectUUID())){ + RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID()); + Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), recyclePowerMsg); + DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); + + // Send Fail to cast message + if (pc != null) { + sendPowerMsg(pc, 2, msg); + if (pc.isCasting()) { + pc.update(false); + } + + pc.setIsCasting(false); + } + return; + } if (usePowerA(msg, origin, sendCastToSelf)) { // Cast failed for some reason, reset timer From 69113ee3c4073a252ded57e3c485bc4be0d6932d Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 26 Feb 2025 19:31:01 -0600 Subject: [PATCH 104/151] catch failure in combat stats to prevent deadlock --- src/engine/objects/PlayerCharacter.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 49bc5335..446b60c8 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -5160,7 +5160,11 @@ public class PlayerCharacter extends AbstractCharacter { if (this.combatStats == null) { this.combatStats = new PlayerCombatStats(this); } else { - this.combatStats.update(); + try { + this.combatStats.update(); + }catch(Exception ignored){ + + } } this.doRegen(); } From d5eb423db8062e7f6af4c4cc6084ffd3e4a91db2 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 26 Feb 2025 19:37:12 -0600 Subject: [PATCH 105/151] damage effect modifier --- src/engine/powers/effectmodifiers/HealthEffectModifier.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/engine/powers/effectmodifiers/HealthEffectModifier.java b/src/engine/powers/effectmodifiers/HealthEffectModifier.java index bb6c2cfb..770bda54 100644 --- a/src/engine/powers/effectmodifiers/HealthEffectModifier.java +++ b/src/engine/powers/effectmodifiers/HealthEffectModifier.java @@ -176,7 +176,8 @@ public class HealthEffectModifier extends AbstractEffectModifier { } if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ - modAmount *= ((PlayerCharacter)source).ZergMultiplier; + float multiplier = ((PlayerCharacter)source).ZergMultiplier; + modAmount *= multiplier; } if (modAmount == 0f) From c01d47fe2105d94fa43fb3ef9f9d53141afb0ccb Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 26 Feb 2025 19:46:51 -0600 Subject: [PATCH 106/151] perma root and perma stun --- src/engine/objects/PlayerCharacter.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 446b60c8..40b59849 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -5219,6 +5219,11 @@ public class PlayerCharacter extends AbstractCharacter { } } + try { + this.clearClientEffects(); + }catch(Exception ignored){ + + } } catch (Exception e) { Logger.error(e); @@ -5230,6 +5235,17 @@ public class PlayerCharacter extends AbstractCharacter { Logger.error("UPDATE ISSUE: " + e); } } + + public void clearClientEffects(){ + if(this.bonuses != null) { + if (!bonuses.getBool(ModType.Stunned, SourceType.None)) { + this.removeEffectBySource(EffectSourceType.Stun, 40, true); + } + if(!this.bonuses.getBool(Enum.ModType.CannotMove,Enum.SourceType.None)){ + this.removeEffectBySource(EffectSourceType.Root,40,true); + } + } + } public static void unboxPlayer(PlayerCharacter player){ String machineID = player.getClientConnection().machineID; ArrayList sameMachine = new ArrayList<>(); From 57e7c3285f0339e48c1bc2b9c9d965b9051d0aec Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 26 Feb 2025 20:59:31 -0600 Subject: [PATCH 107/151] remove multibox checks for banned --- src/engine/objects/PlayerCharacter.java | 3 +-- src/engine/util/KeyCloneAudit.java | 9 --------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 40b59849..2a9877e4 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -5184,8 +5184,7 @@ public class PlayerCharacter extends AbstractCharacter { if (!this.isBoxed && this.timestamps.get("nextBoxCheck") < System.currentTimeMillis()) { this.isBoxed = checkIfBoxed(this); - this.timestamps.put("nextBoxCheck", System.currentTimeMillis() + 10000); - KeyCloneAudit.suspectMultibox(this); + this.timestamps.put("nextBoxCheck", System.currentTimeMillis() + 10000);); } if (this.level < 10 && this.enteredWorld) { diff --git a/src/engine/util/KeyCloneAudit.java b/src/engine/util/KeyCloneAudit.java index e445d6da..9695fa6b 100644 --- a/src/engine/util/KeyCloneAudit.java +++ b/src/engine/util/KeyCloneAudit.java @@ -114,13 +114,4 @@ public enum KeyCloneAudit { } } - public static void suspectMultibox(PlayerCharacter pc){ - String machineID = pc.getClientConnection().machineID; - if(machineID.contains("rsIwTas")){ - //Logger.error("MULTIBOX SOFTWARE DETECTED ON ACCOUNT: " + pc.getAccount().getUname()); - //DbManager.AccountQueries.SET_TRASH(pc.getAccount().getUname(), "MULTIBOX"); - //pc.getClientConnection().forceDisconnect(); - } - } - } From dbfc33563c50802bc07f1ed8a356aa8f981bc833 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 26 Feb 2025 21:13:09 -0600 Subject: [PATCH 108/151] add stored procedure call --- src/engine/db/handlers/dbAccountHandler.java | 22 ++++++++++++++++---- src/engine/server/login/LoginServer.java | 3 +++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/engine/db/handlers/dbAccountHandler.java b/src/engine/db/handlers/dbAccountHandler.java index 9d0a8e91..987562eb 100644 --- a/src/engine/db/handlers/dbAccountHandler.java +++ b/src/engine/db/handlers/dbAccountHandler.java @@ -19,10 +19,7 @@ import engine.objects.Account; import engine.objects.PlayerCharacter; import org.pmw.tinylog.Logger; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; +import java.sql.*; import java.util.ArrayList; public class dbAccountHandler extends dbHandlerBase { @@ -278,4 +275,21 @@ public class dbAccountHandler extends dbHandlerBase { } } + public void TRASH_CHEATERS() { + try (Connection connection = DbManager.getConnection(); + CallableStatement callableStatement = connection.prepareCall("{CALL BanAccountsWithMachineID()}")) { + + boolean hasResultSet = callableStatement.execute(); + + if (!hasResultSet && callableStatement.getUpdateCount() > 0) { + Logger.info("TRASHED CHEATERS"); + } else { + Logger.warn("No cheaters to trash."); + } + + } catch (SQLException e) { + Logger.error("Error trashing cheaters: ", e); + } + } + } diff --git a/src/engine/server/login/LoginServer.java b/src/engine/server/login/LoginServer.java index 2c2b5bf9..efe072fe 100644 --- a/src/engine/server/login/LoginServer.java +++ b/src/engine/server/login/LoginServer.java @@ -281,6 +281,9 @@ public class LoginServer { Logger.info("Loading All Realms"); Realm.loadAllRealms(); + Logger.info("Trashing Multibox Cheaters"); + DbManager.AccountQueries.TRASH_CHEATERS(); + Logger.info("***Boot Successful***"); return true; } From b94f8e4b034d57c683aafe437e9a6718a586efba Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 26 Feb 2025 21:20:34 -0600 Subject: [PATCH 109/151] build cleanup --- src/engine/objects/PlayerCharacter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 2a9877e4..3e947951 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -5184,7 +5184,7 @@ public class PlayerCharacter extends AbstractCharacter { if (!this.isBoxed && this.timestamps.get("nextBoxCheck") < System.currentTimeMillis()) { this.isBoxed = checkIfBoxed(this); - this.timestamps.put("nextBoxCheck", System.currentTimeMillis() + 10000);); + this.timestamps.put("nextBoxCheck", System.currentTimeMillis() + 10000); } if (this.level < 10 && this.enteredWorld) { From c5b2db051be48da26648387766796327adcfd504 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 26 Feb 2025 21:21:54 -0600 Subject: [PATCH 110/151] run ban cleanup hourly --- src/engine/workthreads/HourlyJobThread.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/engine/workthreads/HourlyJobThread.java b/src/engine/workthreads/HourlyJobThread.java index 50b63a26..9d935b5c 100644 --- a/src/engine/workthreads/HourlyJobThread.java +++ b/src/engine/workthreads/HourlyJobThread.java @@ -97,5 +97,12 @@ public class HourlyJobThread implements Runnable { bane.setDefaultTime(); } } + + try{ + Logger.info("Trashing Multibox Cheaters"); + DbManager.AccountQueries.TRASH_CHEATERS(); + }catch(Exception e){ + Logger.error("Failed To Run Ban Multibox Abusers"); + } } } From a5e0396dc63bacf70332d02485a577628bbba183 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 27 Feb 2025 05:15:29 -0600 Subject: [PATCH 111/151] Dungeon System draft --- src/engine/Dungeons/Dungeon.java | 61 +++++++++++++ src/engine/Dungeons/DungeonManager.java | 103 ++++++++++++++++++++++ src/engine/devcmd/cmds/DungenonCmd.java | 70 +++++++++++++++ src/engine/gameManager/DevCmdManager.java | 1 + 4 files changed, 235 insertions(+) create mode 100644 src/engine/Dungeons/Dungeon.java create mode 100644 src/engine/Dungeons/DungeonManager.java create mode 100644 src/engine/devcmd/cmds/DungenonCmd.java diff --git a/src/engine/Dungeons/Dungeon.java b/src/engine/Dungeons/Dungeon.java new file mode 100644 index 00000000..05ec4ef2 --- /dev/null +++ b/src/engine/Dungeons/Dungeon.java @@ -0,0 +1,61 @@ +package engine.Dungeons; + +import engine.Enum; +import engine.InterestManagement.WorldGrid; +import engine.gameManager.PowersManager; +import engine.math.Vector3fImmutable; +import engine.objects.*; +import engine.powers.EffectsBase; +import engine.server.MBServerStatics; + +import java.util.ArrayList; +import java.util.HashSet; + +public class Dungeon { + + public static int NoFlyEffectID = -1733819072; + public static int NoTeleportEffectID = -1971545187; + public static int NoSummonEffectID = 2122002462; + public ArrayList participants; + public int maxPerGuild; + public Vector3fImmutable entrance; + public ArrayList dungeon_mobs; + public Long respawnTime = 0L; + + public Dungeon(Vector3fImmutable entrance, int maxCount){ + this.participants = new ArrayList<>(); + this.entrance = entrance; + this.dungeon_mobs = new ArrayList<>(); + this.maxPerGuild = maxCount; + } + public void applyDungeonEffects(PlayerCharacter player){ + EffectsBase noFly = PowersManager.getEffectByToken(NoFlyEffectID); + EffectsBase noTele = PowersManager.getEffectByToken(NoTeleportEffectID); + EffectsBase noSum = PowersManager.getEffectByToken(NoSummonEffectID); + + if(noFly != null) + player.addEffectNoTimer(noFly.getName(),noFly,40,true); + + if(noTele != null) + player.addEffectNoTimer(noTele.getName(),noTele,40,true); + + if(noSum != null) + player.addEffectNoTimer(noSum.getName(),noSum,40,true); + } + + public void removeDungeonEffects(PlayerCharacter player) { + EffectsBase noFly = PowersManager.getEffectByToken(NoFlyEffectID); + EffectsBase noTele = PowersManager.getEffectByToken(NoTeleportEffectID); + EffectsBase noSum = PowersManager.getEffectByToken(NoSummonEffectID); + for (Effect eff : player.effects.values()) { + if (noFly != null && eff.getEffectsBase().equals(noFly)) + eff.endEffect(); + + if (noTele != null && eff.getEffectsBase().equals(noTele)) + eff.endEffect(); + + if (noSum != null && eff.getEffectsBase().equals(noSum)) + eff.endEffect(); + } + } +} diff --git a/src/engine/Dungeons/DungeonManager.java b/src/engine/Dungeons/DungeonManager.java new file mode 100644 index 00000000..7792699b --- /dev/null +++ b/src/engine/Dungeons/DungeonManager.java @@ -0,0 +1,103 @@ +package engine.Dungeons; + +import engine.InterestManagement.WorldGrid; +import engine.objects.AbstractWorldObject; +import engine.objects.Guild; +import engine.objects.Mob; +import engine.objects.PlayerCharacter; +import engine.powers.EffectsBase; +import engine.server.MBServerStatics; + +import java.util.ArrayList; +import java.util.HashSet; + +public class DungeonManager { + public static ArrayList dungeons; + + private static final float dungeonAiRange = 64f; + private static final float maxTravel = 64f; + + public static void joinDungeon(PlayerCharacter pc, Dungeon dungeon){ + if(requestEnter(pc,dungeon)) { + dungeon.participants.add(pc); + dungeon.applyDungeonEffects(pc); + translocateToDungeon(pc, dungeon); + } + } + + public static void leaveDungeon(PlayerCharacter pc, Dungeon dungeon){ + dungeon.participants.remove(pc); + dungeon.removeDungeonEffects(pc); + translocateOutOfDungeon(pc); + } + + public static boolean requestEnter(PlayerCharacter pc, Dungeon dungeon){ + int current = 0; + Guild nation = pc.guild.getNation(); + + if(nation == null) + return false; + + for(PlayerCharacter participant : dungeon.participants){ + if(participant.guild.getNation().equals(nation)){ + current ++; + } + } + + if(current >= dungeon.maxPerGuild) + return false; + + return true; + } + + public static void translocateToDungeon(PlayerCharacter pc, Dungeon dungeon){ + pc.teleport(dungeon.entrance); + pc.setSafeMode(); + } + + public static void translocateOutOfDungeon(PlayerCharacter pc){ + pc.teleport(pc.bindLoc); + pc.setSafeMode(); + } + + public static void pulse_dungeons(){ + for(Dungeon dungeon : dungeons){ + + //early exit, if no players present don't waste resources + if(dungeon.participants.isEmpty()) + continue; + + if(dungeon.respawnTime > 0 && System.currentTimeMillis() > dungeon.respawnTime){ + respawnMobs(dungeon); + } + + //remove any players that have left + HashSet obj = WorldGrid.getObjectsInRangePartial(dungeon.entrance,4096f,MBServerStatics.MASK_PLAYER); + for(PlayerCharacter player : dungeon.participants) + if(!obj.contains(player)) + leaveDungeon(player,dungeon); + + //cycle dungeon mob AI + for(Mob mob : dungeon.dungeon_mobs) + dungeonMobAI(mob); + } + } + + public static void dungeonMobAI(Mob mob){ + + } + + public static void respawnMobs(Dungeon dungeon){ + for(Mob mob : dungeon.dungeon_mobs){ + + if(!mob.isAlive() && mob.despawned) + mob.respawn(); + + if(!mob.isAlive() && !mob.despawned){ + mob.despawn(); + mob.respawn(); + } + + } + } +} diff --git a/src/engine/devcmd/cmds/DungenonCmd.java b/src/engine/devcmd/cmds/DungenonCmd.java new file mode 100644 index 00000000..650a063f --- /dev/null +++ b/src/engine/devcmd/cmds/DungenonCmd.java @@ -0,0 +1,70 @@ +// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . +// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· +// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ +// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ +// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ +// Magicbane Emulator Project © 2013 - 2022 +// www.magicbane.com + + +package engine.devcmd.cmds; + +import engine.Enum.GameObjectType; +import engine.devcmd.AbstractDevCmd; +import engine.gameManager.ChatManager; +import engine.gameManager.DbManager; +import engine.gameManager.ZoneManager; +import engine.math.Vector3fImmutable; +import engine.objects.*; +import org.pmw.tinylog.Logger; + +/** + * @author Eighty + */ +public class DungenonCmd extends AbstractDevCmd { + + public DungenonCmd() { + super("dungeon"); + } + + @Override + protected void _doCmd(PlayerCharacter pc, String[] words, + AbstractGameObject target) { + if (words.length != 1) { + this.sendUsage(pc); + return; + } + if(words.length < 1) { + throwbackInfo(pc, this._getHelpString()); + return; + } + Zone parent = ZoneManager.findSmallestZone(pc.loc); + if(parent == null) + return; + + switch(words[0]){ + case "mob": + int mobbase = Integer.parseInt(words[1]); + int level = Integer.parseInt(words[2]); + Mob.createStrongholdMob(mobbase,pc.loc,Guild.getErrantGuild(),true,parent,null,0,"",level); + break; + case "building": + int blueprint = Integer.parseInt(words[1]); + int rank = Integer.parseInt(words[2]); + int rot = Integer.parseInt(words[3]); + + break; + } + } + + @Override + protected String _getHelpString() { + return "indicate mob or building followed by an id and a level"; + } + + @Override + protected String _getUsageString() { + return "'/dungeon mob 2001 10'"; + } + +} diff --git a/src/engine/gameManager/DevCmdManager.java b/src/engine/gameManager/DevCmdManager.java index 1016bfcf..ed1cc819 100644 --- a/src/engine/gameManager/DevCmdManager.java +++ b/src/engine/gameManager/DevCmdManager.java @@ -85,6 +85,7 @@ public enum DevCmdManager { DevCmdManager.registerDevCmd(new AddBuildingCmd()); DevCmdManager.registerDevCmd(new AddNPCCmd()); DevCmdManager.registerDevCmd(new AddMobCmd()); + DevCmdManager.registerDevCmd(new DungenonCmd()); DevCmdManager.registerDevCmd(new RemoveObjectCmd()); DevCmdManager.registerDevCmd(new RotateCmd()); DevCmdManager.registerDevCmd(new FlashMsgCmd()); From 5f169fcfae1f3d98b27dc4a9c9e47aac0a16555d Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 27 Feb 2025 05:51:50 -0600 Subject: [PATCH 112/151] disconnect caught cheaters after trashing account --- src/engine/workthreads/HourlyJobThread.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/engine/workthreads/HourlyJobThread.java b/src/engine/workthreads/HourlyJobThread.java index 9d935b5c..93751791 100644 --- a/src/engine/workthreads/HourlyJobThread.java +++ b/src/engine/workthreads/HourlyJobThread.java @@ -101,6 +101,21 @@ public class HourlyJobThread implements Runnable { try{ Logger.info("Trashing Multibox Cheaters"); DbManager.AccountQueries.TRASH_CHEATERS(); + + //disconnect all players who were banned and are still in game + for(PlayerCharacter pc : SessionManager.getAllActivePlayers()){ + Account account = pc.getClientConnection().getAccount(); + if(account == null) + continue; + try { + boolean banned = DbManager.AccountQueries.GET_ACCOUNT(account.getUname()).status.equals(Enum.AccountStatus.BANNED); + if (banned) { + pc.getClientConnection().forceDisconnect(); + } + }catch(Exception e){ + Logger.error(e.getMessage()); + } + } }catch(Exception e){ Logger.error("Failed To Run Ban Multibox Abusers"); } From c24d779d086fa15c4b81244eeb4718d86e4fff1d Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 27 Feb 2025 15:04:55 -0600 Subject: [PATCH 113/151] clear recycle timer for reveal thyself --- src/engine/gameManager/PowersManager.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index 5787a6b4..8b6c4c38 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -175,16 +175,12 @@ public enum PowersManager { if(pc.isMoving()) pc.stopMovement(pc.getMovementLoc()); - if(msg.getPowerUsedID() == 429429978){ - applyPower(origin.getPlayerCharacter(),origin.getPlayerCharacter(),origin.getPlayerCharacter().getLoc(),429429978,msg.getNumTrains(),false); - origin.getPlayerCharacter().getRecycleTimers().remove(429429978); - return; - } - if(!origin.getPlayerCharacter().getPowers().containsKey(msg.getPowerUsedID())){ Logger.error(origin.getPlayerCharacter().getFirstName() + " attempted to cast a power they do not have"); return; } + + //crusader sacrifice if((msg.getPowerUsedID() == 428695403 && msg.getTargetID() == pc.getObjectUUID())){ RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID()); Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), recyclePowerMsg); @@ -220,6 +216,10 @@ public enum PowersManager { } } + + if(msg.getPowerUsedID() == 429429978){ + origin.getPlayerCharacter().getRecycleTimers().remove(429429978); + } } public static void useMobPower(Mob caster, AbstractCharacter target, PowersBase pb, int rank) { From 140ba6ae758a4dd60a2f7a8e77b8590f00eccaa8 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 27 Feb 2025 15:43:43 -0600 Subject: [PATCH 114/151] 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() { From 80b1ab709d09f556122ec96ad93707a34c24f686 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 27 Feb 2025 19:16:37 -0600 Subject: [PATCH 115/151] relog crash bug --- src/engine/InterestManagement/InterestManager.java | 12 ++++++++++++ src/engine/mobileAI/MobAI.java | 12 +++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/engine/InterestManagement/InterestManager.java b/src/engine/InterestManagement/InterestManager.java index 854f0da9..e44da878 100644 --- a/src/engine/InterestManagement/InterestManager.java +++ b/src/engine/InterestManagement/InterestManager.java @@ -511,6 +511,18 @@ public enum InterestManager implements Runnable { if (player == null) return; + for(PlayerCharacter pc : SessionManager.getAllActivePlayerCharacters()){ + if(pc.equals(player)){ + try{ + WorldGrid.RemoveWorldObject(player); + }catch(Exception e){ + + } + } + } + + + ClientConnection origin = player.getClientConnection(); if (origin == null) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index bf59cb46..ee1863e6 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -976,8 +976,8 @@ public class MobAI { if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal()) CheckForPlayerGuardAggro(mob); } else { - //CheckForAggro(mob); - NewAggroMechanic(mob); + if(mob.combatTarget == null) + NewAggroMechanic(mob); } } @@ -1416,10 +1416,16 @@ public class MobAI { public static void NewAggroMechanic(Mob mob){ - if(mob == null || !mob.isAlive()){ + if(mob == null || !mob.isAlive() || mob.playerAgroMap.isEmpty()){ return; } + if(mob.hate_values == null) + mob.hate_values = new HashMap<>(); + + if(mob.combatTarget != null) + return; + HashSet inRange = WorldGrid.getObjectsInRangePartial(mob.loc,60.0f,MBServerStatics.MASK_PLAYER); if(inRange.isEmpty()){ From af684c69680187c9c3ac535397b103334d260a66 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 27 Feb 2025 19:44:48 -0600 Subject: [PATCH 116/151] fix casting form mob hates --- src/engine/gameManager/PowersManager.java | 24 ++++++++++------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index 4f44cf37..927c270f 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -1015,19 +1015,6 @@ 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); @@ -1189,7 +1176,16 @@ public enum PowersManager { //DispatchMessage.dispatchMsgToInterestArea(playerCharacter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); - +//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)); + } + } } From b795db7fbd35b6dab7ce39bad09fb301b2c9703f Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 27 Feb 2025 19:55:30 -0600 Subject: [PATCH 117/151] fix casting form mob hates --- src/engine/gameManager/PowersManager.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index 927c270f..c7f70bef 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -1180,10 +1180,12 @@ public enum PowersManager { 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)); + if(mobTarget.hate_values != null) { + 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)); + } } } From 2b4a87777ca1f69b0f31afec2e1bac4b720fac4f Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 27 Feb 2025 20:02:42 -0600 Subject: [PATCH 118/151] rune merchant price adjustments --- src/engine/objects/Contract.java | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/engine/objects/Contract.java b/src/engine/objects/Contract.java index e1fc1d10..09d554b2 100644 --- a/src/engine/objects/Contract.java +++ b/src/engine/objects/Contract.java @@ -608,53 +608,63 @@ public class Contract extends AbstractGameObject { case 250019: case 250028: case 250037: - me.magicValue = 3000000; + me.magicValue = 1000000; break; case 250002: //10 stats case 250011: case 250020: case 250029: case 250038: - me.magicValue = 4000000; + me.magicValue = 2000000; break; case 250003: //15 stats case 250012: case 250021: case 250030: case 250039: - me.magicValue = 5000000; + me.magicValue = 3000000; break; case 250004: //20 stats case 250013: case 250022: case 250031: case 250040: - me.magicValue = 6000000; + me.magicValue = 4000000; break; case 250005: //25 stats case 250014: case 250023: case 250032: case 250041: - me.magicValue = 7000000; + me.magicValue = 5000000; break; case 250006: //30 stats case 250015: case 250024: case 250033: case 250042: - me.magicValue = 8000000; + me.magicValue = 6000000; break; case 250007: //35 stats case 250016: case 250025: case 250034: case 250043: - me.magicValue = 9000000; + me.magicValue = 7000000; break; - default: + case 250008: //40 stats + case 250017: + case 250026: + case 250035: + case 250044: me.magicValue = 10000000; break; + case 252127: + me.magicValue = 5000000; + break; + default: + me.magicValue = 1000000; + break; } } } From 6d004d631cbebc5534d9e033a432a11911eb706a Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 28 Feb 2025 13:17:38 -0600 Subject: [PATCH 119/151] add XP config multiplier --- src/engine/objects/PlayerCharacter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 3e947951..fecc31b4 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -2958,6 +2958,7 @@ public class PlayerCharacter extends AbstractCharacter { } public synchronized void grantXP(int xp) { + xp *= LootManager.NORMAL_EXP_RATE; int groupSize = 1; if(GroupManager.getGroup(this)!= null) groupSize = GroupManager.getGroup(this).members.size(); From 2c47f593f3cf0aed88fbf03de1ca6c241ed453ff Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 28 Feb 2025 14:10:48 -0600 Subject: [PATCH 120/151] dungeon generation --- src/engine/Dungeons/DungeonManager.java | 30 +++++++++++++++++++++---- src/engine/devcmd/cmds/DungenonCmd.java | 24 +++----------------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/engine/Dungeons/DungeonManager.java b/src/engine/Dungeons/DungeonManager.java index 7792699b..651ccb5f 100644 --- a/src/engine/Dungeons/DungeonManager.java +++ b/src/engine/Dungeons/DungeonManager.java @@ -1,10 +1,11 @@ package engine.Dungeons; +import engine.Enum; import engine.InterestManagement.WorldGrid; -import engine.objects.AbstractWorldObject; -import engine.objects.Guild; -import engine.objects.Mob; -import engine.objects.PlayerCharacter; +import engine.gameManager.DbManager; +import engine.gameManager.ZoneManager; +import engine.math.Vector3fImmutable; +import engine.objects.*; import engine.powers.EffectsBase; import engine.server.MBServerStatics; @@ -100,4 +101,25 @@ public class DungeonManager { } } + + public static void createDungeon(Vector3fImmutable loc, int count){ + + Zone parent = ZoneManager.findSmallestZone(loc); + + Dungeon dungeon = new Dungeon(loc,count); + + Vector3fImmutable loc1 = new Vector3fImmutable(loc.x + 128,loc.y,loc.z + 128); + Vector3fImmutable loc2 = new Vector3fImmutable(loc.x - 128,loc.y,loc.z - 128); + Vector3fImmutable loc3 = new Vector3fImmutable(loc.x - 128,loc.y,loc.z + 128); + Vector3fImmutable loc4 = new Vector3fImmutable(loc.x + 128,loc.y,loc.z - 128); + + Building building1 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450200,loc1,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,454200,0f,0f); + Building building2 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450200,loc2,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,454200,0f,0f); + Building building3 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450200,loc3,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,454200,0f,0f); + Building building4 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450200,loc4,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,454200,0f,0f); + WorldGrid.addObject(building1,loc1.x,loc1.z); + WorldGrid.addObject(building2,loc2.x,loc2.z); + WorldGrid.addObject(building3,loc3.x,loc3.z); + WorldGrid.addObject(building4,loc4.x,loc4.z); + } } diff --git a/src/engine/devcmd/cmds/DungenonCmd.java b/src/engine/devcmd/cmds/DungenonCmd.java index 650a063f..d20fa518 100644 --- a/src/engine/devcmd/cmds/DungenonCmd.java +++ b/src/engine/devcmd/cmds/DungenonCmd.java @@ -9,6 +9,7 @@ package engine.devcmd.cmds; +import engine.Dungeons.DungeonManager; import engine.Enum.GameObjectType; import engine.devcmd.AbstractDevCmd; import engine.gameManager.ChatManager; @@ -30,31 +31,12 @@ public class DungenonCmd extends AbstractDevCmd { @Override protected void _doCmd(PlayerCharacter pc, String[] words, AbstractGameObject target) { - if (words.length != 1) { - this.sendUsage(pc); - return; - } - if(words.length < 1) { - throwbackInfo(pc, this._getHelpString()); - return; - } + Zone parent = ZoneManager.findSmallestZone(pc.loc); if(parent == null) return; - switch(words[0]){ - case "mob": - int mobbase = Integer.parseInt(words[1]); - int level = Integer.parseInt(words[2]); - Mob.createStrongholdMob(mobbase,pc.loc,Guild.getErrantGuild(),true,parent,null,0,"",level); - break; - case "building": - int blueprint = Integer.parseInt(words[1]); - int rank = Integer.parseInt(words[2]); - int rot = Integer.parseInt(words[3]); - - break; - } + DungeonManager.createDungeon(parent.getLoc(),5); } @Override From 601687133f1c460091fca09c8fdd135b6f24a33e Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 28 Feb 2025 14:22:40 -0600 Subject: [PATCH 121/151] dungeon generation --- src/engine/Dungeons/DungeonManager.java | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/engine/Dungeons/DungeonManager.java b/src/engine/Dungeons/DungeonManager.java index 651ccb5f..4ba38ecf 100644 --- a/src/engine/Dungeons/DungeonManager.java +++ b/src/engine/Dungeons/DungeonManager.java @@ -104,19 +104,23 @@ public class DungeonManager { public static void createDungeon(Vector3fImmutable loc, int count){ - Zone parent = ZoneManager.findSmallestZone(loc); + Zone parent = ZoneManager.getZoneByUUID(993); Dungeon dungeon = new Dungeon(loc,count); - Vector3fImmutable loc1 = new Vector3fImmutable(loc.x + 128,loc.y,loc.z + 128); - Vector3fImmutable loc2 = new Vector3fImmutable(loc.x - 128,loc.y,loc.z - 128); - Vector3fImmutable loc3 = new Vector3fImmutable(loc.x - 128,loc.y,loc.z + 128); - Vector3fImmutable loc4 = new Vector3fImmutable(loc.x + 128,loc.y,loc.z - 128); - - Building building1 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450200,loc1,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,454200,0f,0f); - Building building2 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450200,loc2,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,454200,0f,0f); - Building building3 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450200,loc3,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,454200,0f,0f); - Building building4 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450200,loc4,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,454200,0f,0f); + Vector3fImmutable loc1 = new Vector3fImmutable(128,0,128); + Vector3fImmutable loc2 = new Vector3fImmutable(-128,0,-128); + Vector3fImmutable loc3 = new Vector3fImmutable(-128,0,128); + Vector3fImmutable loc4 = new Vector3fImmutable(128,0,-128); + + Building building1 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450800,loc1,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450800,0f,0f); + Building building2 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450800,loc2,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450800,0f,0f); + Building building3 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450800,loc3,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450800,0f,0f); + Building building4 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450800,loc4,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450800,0f,0f); + building1.setLoc(loc1); + building2.setLoc(loc2); + building3.setLoc(loc3); + building4.setLoc(loc4); WorldGrid.addObject(building1,loc1.x,loc1.z); WorldGrid.addObject(building2,loc2.x,loc2.z); WorldGrid.addObject(building3,loc3.x,loc3.z); From 22c975d25192356e69d64aa456cae1ecc20b3a50 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 28 Feb 2025 14:35:00 -0600 Subject: [PATCH 122/151] dungeon generation --- src/engine/Dungeons/DungeonManager.java | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/engine/Dungeons/DungeonManager.java b/src/engine/Dungeons/DungeonManager.java index 4ba38ecf..b4ac9fec 100644 --- a/src/engine/Dungeons/DungeonManager.java +++ b/src/engine/Dungeons/DungeonManager.java @@ -113,17 +113,13 @@ public class DungeonManager { Vector3fImmutable loc3 = new Vector3fImmutable(-128,0,128); Vector3fImmutable loc4 = new Vector3fImmutable(128,0,-128); - Building building1 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450800,loc1,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450800,0f,0f); - Building building2 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450800,loc2,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450800,0f,0f); - Building building3 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450800,loc3,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450800,0f,0f); - Building building4 = DbManager.BuildingQueries.CREATE_BUILDING(parent.getObjectUUID(),1,"Building",450800,loc4,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450800,0f,0f); - building1.setLoc(loc1); - building2.setLoc(loc2); - building3.setLoc(loc3); - building4.setLoc(loc4); - WorldGrid.addObject(building1,loc1.x,loc1.z); - WorldGrid.addObject(building2,loc2.x,loc2.z); - WorldGrid.addObject(building3,loc3.x,loc3.z); - WorldGrid.addObject(building4,loc4.x,loc4.z); + Building building1 = DbManager.BuildingQueries.CREATE_BUILDING(993,1,"Building",450750,loc1,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450750,0f,0f); + Building building2 = DbManager.BuildingQueries.CREATE_BUILDING(993,1,"Building",450750,loc2,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450750,0f,0f); + Building building3 = DbManager.BuildingQueries.CREATE_BUILDING(993,1,"Building",450750,loc3,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450750,0f,0f); + Building building4 = DbManager.BuildingQueries.CREATE_BUILDING(993,1,"Building",450750,loc4,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450750,0f,0f); + WorldGrid.addObject(building1,parent.getLoc().x + loc1.x,parent.getLoc().z + loc1.z); + WorldGrid.addObject(building2,parent.getLoc().x + loc2.x,parent.getLoc().z + loc2.z); + WorldGrid.addObject(building3,parent.getLoc().x + loc3.x,parent.getLoc().z + loc3.z); + WorldGrid.addObject(building4,parent.getLoc().x + loc4.x,parent.getLoc().z + loc4.z); } } From 9ba2f375cf1b007c226fc771eee472e93cfbf6c0 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 28 Feb 2025 17:27:14 -0600 Subject: [PATCH 123/151] hamlet guards don't aggro --- src/engine/mobileAI/MobAI.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index ee1863e6..43a104fb 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -1420,6 +1420,10 @@ public class MobAI { return; } + if(mob.BehaviourType.equals(Enum.MobBehaviourType.HamletGuard)){ + return; + } + if(mob.hate_values == null) mob.hate_values = new HashMap<>(); From 846d720c2f3f0a86ac40c81cd80d828c81abeefd Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 28 Feb 2025 17:30:34 -0600 Subject: [PATCH 124/151] attempt to stop second box crash --- src/engine/objects/PlayerCharacter.java | 28 +++++++++++++------------ 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index fecc31b4..71c782fb 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -5180,24 +5180,26 @@ public class PlayerCharacter extends AbstractCharacter { this.updateBlessingMessage(); this.safeZone = this.isInSafeZone(); - if (!this.timestamps.containsKey("nextBoxCheck")) - this.timestamps.put("nextBoxCheck", System.currentTimeMillis() + 10000); - if (!this.isBoxed && this.timestamps.get("nextBoxCheck") < System.currentTimeMillis()) { - this.isBoxed = checkIfBoxed(this); - this.timestamps.put("nextBoxCheck", System.currentTimeMillis() + 10000); - } + if(this.isActive && this.enteredWorld) { + if (!this.timestamps.containsKey("nextBoxCheck")) + this.timestamps.put("nextBoxCheck", System.currentTimeMillis() + 10000); - if (this.level < 10 && this.enteredWorld) { - while (this.level < 10) { - grantXP(Experience.getBaseExperience(this.level + 1) - this.exp); + if (!this.isBoxed && this.timestamps.get("nextBoxCheck") < System.currentTimeMillis()) { + this.isBoxed = checkIfBoxed(this); + this.timestamps.put("nextBoxCheck", System.currentTimeMillis() + 10000); } - } - if (this.isBoxed && !this.containsEffect(1672601862)) { - PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 1672601862, 40, false); - } + if (this.level < 10 && this.enteredWorld) { + while (this.level < 10) { + grantXP(Experience.getBaseExperience(this.level + 1) - this.exp); + } + } + if (this.isBoxed && !this.containsEffect(1672601862)) { + PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 1672601862, 40, false); + } + } if (this.isFlying()) { if (this.effects.containsKey("MoveBuff")) { GroundPlayer(this); From 9b2a1a271e33dd6675f08881948253eafc9525ea Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 28 Feb 2025 17:31:11 -0600 Subject: [PATCH 125/151] attempt to stop second box crash --- src/engine/objects/PlayerCharacter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 71c782fb..0121da8a 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -5684,6 +5684,7 @@ public class PlayerCharacter extends AbstractCharacter { } public void setEnteredWorld(boolean enteredWorld) { + this.timestamps.put("nextBoxCheck", System.currentTimeMillis() + 10000); this.enteredWorld = enteredWorld; } From 78131ed6f29b79a122a74af94765c859a2b100ef Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 28 Feb 2025 17:31:40 -0600 Subject: [PATCH 126/151] attempt to stop second box crash --- src/engine/objects/PlayerCharacter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 0121da8a..7bdd71a0 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -5684,7 +5684,8 @@ public class PlayerCharacter extends AbstractCharacter { } public void setEnteredWorld(boolean enteredWorld) { - this.timestamps.put("nextBoxCheck", System.currentTimeMillis() + 10000); + if(enteredWorld) + this.timestamps.put("nextBoxCheck", System.currentTimeMillis() + 10000); this.enteredWorld = enteredWorld; } From 2e7707fcbe16071e7b55f704732b813dddc3bc80 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 28 Feb 2025 17:44:05 -0600 Subject: [PATCH 127/151] remove mob ai spam logging --- src/engine/mobileAI/MobAI.java | 54 +++++++++++++++++----------------- src/engine/objects/Item.java | 18 +++++++----- 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 43a104fb..890781d4 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -95,7 +95,7 @@ public class MobAI { } } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage()); + ////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage()); } } @@ -174,7 +174,7 @@ public class MobAI { } } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackPlayer" + " " + e.getMessage()); + ////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackPlayer" + " " + e.getMessage()); } } @@ -232,7 +232,7 @@ public class MobAI { //} } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackBuilding" + " " + e.getMessage()); + ////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackBuilding" + " " + e.getMessage()); } } @@ -271,7 +271,7 @@ public class MobAI { } } } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackMob" + " " + e.getMessage()); + ////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackMob" + " " + e.getMessage()); } } @@ -324,7 +324,7 @@ public class MobAI { } } } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage()); + ////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage()); } } @@ -368,7 +368,7 @@ public class MobAI { return mob.nextCastTime <= System.currentTimeMillis(); } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: canCast" + " " + e.getMessage()); + ////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: canCast" + " " + e.getMessage()); } return false; } @@ -454,7 +454,7 @@ public class MobAI { return true; } } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage()); + ////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage()); } return false; } @@ -576,7 +576,7 @@ public class MobAI { return true; } } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage()); + ////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage()); } return false; } @@ -612,7 +612,7 @@ public class MobAI { mob.nextCallForHelp = System.currentTimeMillis() + 60000; } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCallForHelp" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCallForHelp" + " " + e.getMessage()); } } @@ -733,7 +733,7 @@ public class MobAI { if(mob.isAlive()) RecoverHealth(mob); } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DetermineAction" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DetermineAction" + " " + e.getMessage()); } } @@ -808,7 +808,7 @@ public class MobAI { } } } catch (Exception e) { - Logger.info(aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForAggro" + " " + e.getMessage()); + //(aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForAggro" + " " + e.getMessage()); } } @@ -869,7 +869,7 @@ public class MobAI { } } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckMobMovement" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckMobMovement" + " " + e.getMessage()); } } @@ -923,7 +923,7 @@ public class MobAI { } } } catch (Exception e) { - Logger.info(aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForRespawn" + " " + e.getMessage()); + //(aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForRespawn" + " " + e.getMessage()); } } @@ -949,7 +949,7 @@ public class MobAI { AttackTarget(mob, mob.getCombatTarget()); } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForAttack" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForAttack" + " " + e.getMessage()); } } @@ -1011,7 +1011,7 @@ public class MobAI { mob.setCombatTarget(null); } } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome" + " " + e.getMessage()); } } @@ -1054,7 +1054,7 @@ public class MobAI { mob.updateMovementState(); mob.updateLocation(); } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: chaseTarget" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: chaseTarget" + " " + e.getMessage()); } } @@ -1086,7 +1086,7 @@ public class MobAI { mob.setCombatTarget(aggroMob); } } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: SafeGuardAggro" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: SafeGuardAggro" + " " + e.getMessage()); } } @@ -1112,7 +1112,7 @@ public class MobAI { CheckMobMovement(mob); CheckForAttack(mob); } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardCaptainLogic" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardCaptainLogic" + " " + e.getMessage()); } } @@ -1134,7 +1134,7 @@ public class MobAI { CheckMobMovement(mob); CheckForAttack(mob); } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardMinionLogic" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardMinionLogic" + " " + e.getMessage()); } } @@ -1148,7 +1148,7 @@ public class MobAI { else CheckForAttack(mob); } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardWallArcherLogic" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardWallArcherLogic" + " " + e.getMessage()); } } @@ -1169,7 +1169,7 @@ public class MobAI { CheckForAttack(mob); } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: PetLogic" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: PetLogic" + " " + e.getMessage()); } } @@ -1185,7 +1185,7 @@ public class MobAI { CheckForAttack(mob); } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: HamletGuardLogic" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: HamletGuardLogic" + " " + e.getMessage()); } } @@ -1220,7 +1220,7 @@ public class MobAI { } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DefaultLogic" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DefaultLogic" + " " + e.getMessage()); } } @@ -1270,7 +1270,7 @@ public class MobAI { } } } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForPlayerGuardAggro" + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForPlayerGuardAggro" + e.getMessage()); } } @@ -1333,7 +1333,7 @@ public class MobAI { } } } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardCanAggro" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardCanAggro" + " " + e.getMessage()); } return false; } @@ -1382,7 +1382,7 @@ public class MobAI { } } } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: randomGuardPatrolPoints" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: randomGuardPatrolPoints" + " " + e.getMessage()); } } @@ -1403,7 +1403,7 @@ public class MobAI { mob.setHealth(mob.getHealthMax()); } } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: RecoverHealth" + " " + e.getMessage()); + //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: RecoverHealth" + " " + e.getMessage()); } } diff --git a/src/engine/objects/Item.java b/src/engine/objects/Item.java index 45601326..bcfa2120 100644 --- a/src/engine/objects/Item.java +++ b/src/engine/objects/Item.java @@ -818,15 +818,19 @@ public class Item extends AbstractWorldObject { } public void stripCastableEnchants(){ - ArrayList ToRemove = new ArrayList<>(); - for(Effect eff : this.effects.values()){ - if(eff.getJobContainer() != null && !eff.getJobContainer().noTimer()){ - eff.endEffectNoPower(); - eff.getJobContainer().cancelJob(); - ToRemove.add(eff); + try { + ArrayList ToRemove = new ArrayList<>(); + for (Effect eff : this.effects.values()) { + if (eff.getJobContainer() != null && !eff.getJobContainer().noTimer()) { + eff.endEffectNoPower(); + eff.getJobContainer().cancelJob(); + ToRemove.add(eff); + } } + this.effects.values().removeAll(ToRemove); + }catch(Exception ignored){ + } - this.effects.values().removeAll(ToRemove); } //Only to be used for trading public void setOwnerID(int ownerID) { From 8ff059433391ce710de539810cad7260fb4f06c0 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 28 Feb 2025 17:51:57 -0600 Subject: [PATCH 128/151] announce XP rate on login --- src/engine/net/client/handlers/ArcLoginNotifyMsgHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/net/client/handlers/ArcLoginNotifyMsgHandler.java b/src/engine/net/client/handlers/ArcLoginNotifyMsgHandler.java index 02b0518c..fa6a35fa 100644 --- a/src/engine/net/client/handlers/ArcLoginNotifyMsgHandler.java +++ b/src/engine/net/client/handlers/ArcLoginNotifyMsgHandler.java @@ -66,6 +66,7 @@ public class ArcLoginNotifyMsgHandler extends AbstractClientMsgHandler { // Send Guild, Nation and IC MOTD GuildManager.enterWorldMOTD(player); ChatManager.sendSystemMessage(player, ConfigManager.MB_WORLD_GREETING.getValue()); + ChatManager.sendSystemMessage(player, " Experience Gain: " + ConfigManager.MB_NORMAL_EXP_RATE.getValue()); // Send branch string if available from ConfigManager. From 9d8467613ab7344a82317dc522f358ed8fb0060e Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 1 Mar 2025 18:04:43 -0600 Subject: [PATCH 129/151] new combat manager first draft --- src/engine/gameManager/CombatSystem.java | 329 +++++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 src/engine/gameManager/CombatSystem.java diff --git a/src/engine/gameManager/CombatSystem.java b/src/engine/gameManager/CombatSystem.java new file mode 100644 index 00000000..e388b837 --- /dev/null +++ b/src/engine/gameManager/CombatSystem.java @@ -0,0 +1,329 @@ +package engine.gameManager; + +import engine.Enum; +import engine.jobs.DeferredPowerJob; +import engine.net.DispatchMessage; +import engine.net.client.msg.TargetedActionMsg; +import engine.objects.*; +import engine.powers.DamageShield; +import engine.powers.effectmodifiers.AbstractEffectModifier; +import engine.powers.effectmodifiers.WeaponProcEffectModifier; +import engine.server.MBServerStatics; +import org.pmw.tinylog.Logger; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ThreadLocalRandom; + +public class CombatSystem { + + public static void attemptCombat(AbstractCharacter source, AbstractWorldObject target, boolean mainhand){ + + //1. source or target doesn't exist, early exit + if(source == null || target == null) + return; + + //2. source or target is dead, early exit + if(!source.isAlive() || !target.isAlive()) + return; + + //3. make sure if target is a building to ensure that it is damageable + if(target.getObjectType().equals(Enum.GameObjectType.Building)){ + Building building = (Building)target; + if(building.assetIsProtected() || building.getProtectionState().equals(Enum.ProtectionState.NPC)) + return; + } + + //after thought: make sure target is in range of source + if(!inRange(source,target,mainhand)) + return; + + //4. apply any weapon powers and then clear the weapon power memory for the player + if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { + PlayerCharacter pc = (PlayerCharacter)source; + if(pc.getWeaponPower() != null){ + pc.getWeaponPower().attack(target,pc.getRange()); + pc.setWeaponPower(null); + } + } + + //5. make sure if target is AbstractCharacter to check for defense trigger and passive trigger + if(AbstractCharacter.IsAbstractCharacter(target)) { + int atr; + int def; + if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { + PlayerCharacter pc = (PlayerCharacter)source; + if(pc.combatStats == null) + pc.combatStats = new PlayerCombatStats(pc); + atr = (int) pc.combatStats.atrHandOne; + if(!mainhand) + atr =(int) pc.combatStats.atrHandTwo; + + def = pc.combatStats.defense; + } else { + atr = (int) ((source.getAtrHandOne() + source.getAtrHandTwo()) * 0.5f); + def = source.defenseRating; + } + + if(!LandHit(atr,def)) + return; + + if(source.getBonuses() != null) + if(!source.getBonuses().getBool(Enum.ModType.IgnorePassiveDefense, Enum.SourceType.None)) + if(triggerPassive(source,target)) + return; + } + + //commence actual combat management + + //6. check for any procs + if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { + PlayerCharacter pc = (PlayerCharacter)source; + if(pc.getCharItemManager() != null && pc.getCharItemManager().getEquipped() != null){ + Item weapon = pc.getCharItemManager().getEquipped(1); + if(!mainhand) + weapon = pc.getCharItemManager().getEquipped(2); + if(weapon != null){ + if(weapon.effects != null){ + for (Effect eff : weapon.effects.values()){ + for(AbstractEffectModifier mod : eff.getEffectModifiers()){ + if(mod.modType.equals(Enum.ModType.WeaponProc)){ + int procChance = ThreadLocalRandom.current().nextInt(0,101); + if (procChance <= MBServerStatics.PROC_CHANCE) { + try { + ((WeaponProcEffectModifier) mod).applyProc(source, target); + }catch(Exception e){ + Logger.error(eff.getName() + " Failed To Cast Proc"); + } + } + } + } + } + } + } + } + } + + //7. configure damage amounts and type + Enum.DamageType damageType = Enum.DamageType.Crush; + int min = 0; + int max = 0; + if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { + PlayerCharacter pc = (PlayerCharacter) source; + if(mainhand){ + min = pc.combatStats.minDamageHandOne; + max = pc.combatStats.maxDamageHandOne; + }else{ + min = pc.combatStats.minDamageHandTwo; + max = pc.combatStats.maxDamageHandTwo; + } + }else if (source.getObjectType().equals(Enum.GameObjectType.Mob)) { + Mob mob = (Mob) source; + min = (int) mob.mobBase.getDamageMin(); + max = (int) mob.mobBase.getDamageMax(); + } + + int damage = ThreadLocalRandom.current().nextInt(min,max + 1); + + if(source.getBonuses() != null){ + damage *= 1 + source.getBonuses().getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None); + } + if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { + PlayerCharacter pc = (PlayerCharacter) source; + damage *= pc.ZergMultiplier; + } + + //8. configure the attack message to be sent to the clients + int animation = 0; + ItemBase wb = null; + if(source.getCharItemManager() != null && source.getCharItemManager().getEquipped() != null) { + Item weapon = source.getCharItemManager().getEquipped(1); + if (!mainhand) + weapon = source.getCharItemManager().getEquipped(2); + + if(weapon != null && weapon.getItemBase().getAnimations() != null && !weapon.getItemBase().getAnimations().isEmpty()){ + animation = weapon.getItemBase().getAnimations().get(0); + wb = weapon.getItemBase(); + damageType = wb.getDamageType(); + } + } + + //9. reduce damage from resists and apply damage shields + if(AbstractCharacter.IsAbstractCharacter(target)){ + AbstractCharacter abs = (AbstractCharacter) target; + damage = (int) abs.getResists().getResistedDamage(source, abs,damageType,damage,1); + handleDamageShields(source,abs,damage); + } + + + + sendCombatMessage(source, target, 0f, wb, null, mainhand, animation); + + //if attacker is player, set last attack timestamp + if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) + updateAttackTimers((PlayerCharacter) source, target); + + //10. cancel all effects that cancel on attack + source.cancelOnAttack(); + } + + public static boolean LandHit(int ATR, int DEF){ + + int roll = ThreadLocalRandom.current().nextInt(101); + + float chance = PlayerCombatStats.getHitChance(ATR,DEF); + return chance >= roll; + } + + private static void sendCombatMessage(AbstractCharacter source, AbstractWorldObject target, float damage, ItemBase wb, DeferredPowerJob dpj, boolean mainHand, int swingAnimation) { + + if (dpj != null) + if (PowersManager.AnimationOverrides.containsKey(dpj.getAction().getEffectID())) + swingAnimation = PowersManager.AnimationOverrides.get(dpj.getAction().getEffectID()); + + if (source.getObjectType() == Enum.GameObjectType.PlayerCharacter) + for (Effect eff : source.getEffects().values()) + if (eff.getPower() != null && (eff.getPower().getToken() == 429506943 || eff.getPower().getToken() == 429408639 || eff.getPower().getToken() == 429513599 || eff.getPower().getToken() == 429415295)) + swingAnimation = 0; + + TargetedActionMsg cmm = new TargetedActionMsg(source, target, damage, swingAnimation); + DispatchMessage.sendToAllInRange(target, cmm); + } + + private static void updateAttackTimers(PlayerCharacter pc, AbstractWorldObject target) { + + //Set Attack Timers + + if (target.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) + pc.setLastPlayerAttackTime(); + } + + public static void handleDamageShields(AbstractCharacter ac, AbstractCharacter target, float damage) { + + if (ac == null || target == null) + return; + + PlayerBonuses bonuses = target.getBonuses(); + + if (bonuses != null) { + + ConcurrentHashMap damageShields = bonuses.getDamageShields(); + float total = 0; + + for (DamageShield ds : damageShields.values()) { + + //get amount to damage back + + float amount; + + if (ds.usePercent()) + amount = damage * ds.getAmount() / 100; + else + amount = ds.getAmount(); + + //get resisted damage for damagetype + + Resists resists = ac.getResists(); + + if (resists != null) { + amount = resists.getResistedDamage(target, ac, ds.getDamageType(), amount, 0); + } + total += amount; + } + + if (total > 0) { + + //apply Damage back + + ac.modifyHealth(-total, target, true); + + TargetedActionMsg cmm = new TargetedActionMsg(ac, ac, total, 0); + DispatchMessage.sendToAllInRange(target, cmm); + + } + } + } + + public static boolean inRange(AbstractCharacter source, AbstractWorldObject target, boolean mainhand){ + + if(source == null || target == null) + return false; + + float distanceSquared = source.loc.distanceSquared(target.loc); + + float rangeSquared = 16.0f; + + if(source.getCharItemManager() != null && source.getCharItemManager().getEquipped() != null){ + Item weapon = source.getCharItemManager().getEquipped(1); + if(!mainhand) + weapon = source.getCharItemManager().getEquipped(2); + if(weapon != null) + rangeSquared = weapon.getItemBase().getRange() * weapon.getItemBase().getRange(); + } + + if(source.getBonuses() != null){ + rangeSquared *= 1 + source.getBonuses().getFloatPercentAll(Enum.ModType.WeaponRange, Enum.SourceType.None); + } + + return distanceSquared <= rangeSquared; + } + + public static boolean triggerPassive(AbstractCharacter source, AbstractWorldObject target) { + boolean passiveFired = false; + + if (!AbstractCharacter.IsAbstractCharacter(target)) + return false; + + AbstractCharacter tarAc = (AbstractCharacter) target; + //Handle Block passive + if (testPassive(source, tarAc, "Block")) { + sendPassiveDefenseMessage(source, null, target, MBServerStatics.COMBAT_SEND_DODGE, null, true); + return true; + } + + //Handle Parry passive + if (testPassive(source, tarAc, "Parry")) { + sendPassiveDefenseMessage(source, null, target, MBServerStatics.COMBAT_SEND_DODGE, null, true); + return true; + } + + //Handle Dodge passive + if (testPassive(source, tarAc, "Dodge")) { + sendPassiveDefenseMessage(source, null, target, MBServerStatics.COMBAT_SEND_DODGE, null, true); + return true; + } + return false; + } + + private static void sendPassiveDefenseMessage(AbstractCharacter source, ItemBase wb, AbstractWorldObject target, int passiveType, DeferredPowerJob dpj, boolean mainHand) { + + int swingAnimation = 75; + + if (dpj != null) + if (PowersManager.AnimationOverrides.containsKey(dpj.getAction().getEffectID())) + swingAnimation = PowersManager.AnimationOverrides.get(dpj.getAction().getEffectID()); + + TargetedActionMsg cmm = new TargetedActionMsg(source, swingAnimation, target, passiveType); + DispatchMessage.sendToAllInRange(target, cmm); + } + private static boolean testPassive(AbstractCharacter source, AbstractCharacter target, String type) { + + if(target.getBonuses() != null) + if(target.getBonuses().getBool(Enum.ModType.Stunned, Enum.SourceType.None)) + return false; + + float chance = target.getPassiveChance(type, source.getLevel(), true); + + if (chance == 0f) + return false; + + //max 75% chance of passive to fire + + if (chance > 75f) + chance = 75f; + + int roll = ThreadLocalRandom.current().nextInt(1,100); + + return roll < chance; + + } +} From ac5528382c6b0b25b57c410c05aaf26c59b394c1 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 1 Mar 2025 18:17:12 -0600 Subject: [PATCH 130/151] new combat manager first draft --- src/engine/gameManager/CombatSystem.java | 105 ++++++++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) diff --git a/src/engine/gameManager/CombatSystem.java b/src/engine/gameManager/CombatSystem.java index e388b837..a2eadb3b 100644 --- a/src/engine/gameManager/CombatSystem.java +++ b/src/engine/gameManager/CombatSystem.java @@ -1,8 +1,14 @@ package engine.gameManager; import engine.Enum; +import engine.exception.MsgSendException; +import engine.job.JobContainer; +import engine.job.JobScheduler; +import engine.jobs.AttackJob; import engine.jobs.DeferredPowerJob; import engine.net.DispatchMessage; +import engine.net.client.ClientConnection; +import engine.net.client.msg.AttackCmdMsg; import engine.net.client.msg.TargetedActionMsg; import engine.objects.*; import engine.powers.DamageShield; @@ -64,13 +70,17 @@ public class CombatSystem { def = source.defenseRating; } - if(!LandHit(atr,def)) + if(!LandHit(atr,def)) { + createTimer(source,mainhand); return; + } if(source.getBonuses() != null) if(!source.getBonuses().getBool(Enum.ModType.IgnorePassiveDefense, Enum.SourceType.None)) - if(triggerPassive(source,target)) + if(triggerPassive(source,target)) { + createTimer(source,mainhand); return; + } } //commence actual combat management @@ -305,6 +315,7 @@ public class CombatSystem { TargetedActionMsg cmm = new TargetedActionMsg(source, swingAnimation, target, passiveType); DispatchMessage.sendToAllInRange(target, cmm); } + private static boolean testPassive(AbstractCharacter source, AbstractCharacter target, String type) { if(target.getBonuses() != null) @@ -326,4 +337,94 @@ public class CombatSystem { return roll < chance; } + + private static void createTimer(AbstractCharacter source, boolean mainhand) { + + ConcurrentHashMap timers = source.getTimers(); + int slot = 1; + if(!mainhand) + slot = 2; + + int time = 3000; + if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ + PlayerCharacter pc = (PlayerCharacter)source; + if(mainhand){ + time = (int) pc.combatStats.attackSpeedHandOne; + }else{ + time = (int) pc.combatStats.attackSpeedHandTwo; + } + } + + if (timers != null) { + AttackJob aj = new AttackJob(source, slot, true); + JobContainer job; + job = JobScheduler.getInstance().scheduleJob(aj, (time * 100)); + timers.put("Attack" + slot, job); + } else { + Logger.error("Unable to find Timers for Character " + source.getObjectUUID()); + } + } + + public static void setAttackTarget(AttackCmdMsg msg, ClientConnection origin) throws MsgSendException { + + PlayerCharacter player; + int targetType; + AbstractWorldObject target; + + if (TargetedActionMsg.un2cnt == 60 || TargetedActionMsg.un2cnt == 70) + return; + + player = SessionManager.getPlayerCharacter(origin); + + if (player == null) + return; + + //source must match player this account belongs to + + if (player.getObjectUUID() != msg.getSourceID() || player.getObjectType().ordinal() != msg.getSourceType()) { + Logger.error("Msg Source ID " + msg.getSourceID() + " Does not Match Player ID " + player.getObjectUUID()); + return; + } + + targetType = msg.getTargetType(); + + if (targetType == Enum.GameObjectType.PlayerCharacter.ordinal()) { + target = PlayerCharacter.getFromCache(msg.getTargetID()); + } else if (targetType == Enum.GameObjectType.Building.ordinal()) { + target = BuildingManager.getBuildingFromCache(msg.getTargetID()); + } else if (targetType == Enum.GameObjectType.Mob.ordinal()) { + target = Mob.getFromCache(msg.getTargetID()); + } else { + player.setCombatTarget(null); + return; //not valid type to attack + } + + // quit of the combat target is already the current combat target + // or there is no combat target + + if (target == null) + return; + + //set sources target + + player.setCombatTarget(target); + + boolean hasMain = false; + boolean hasOff = false; + if(player.getCharItemManager() != null && player.getCharItemManager().getEquipped() != null){ + if(player.getCharItemManager().getEquipped(1) != null) + hasMain = true; + if(player.getCharItemManager().getEquipped(2) != null && !player.getCharItemManager().getEquipped(2).getItemBase().isShield()) + hasOff = true; + } + + if(hasMain){ + createTimer(player,true); + } + + if(hasOff){ + createTimer(player,false); + } + + } } From 06e31c1243d1710e1d7b62360837fbf865dfa28b Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 2 Mar 2025 18:18:04 -0600 Subject: [PATCH 131/151] update stat and mastery pricing --- src/engine/objects/ItemBase.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/engine/objects/ItemBase.java b/src/engine/objects/ItemBase.java index b6bda4bb..b5af8368 100644 --- a/src/engine/objects/ItemBase.java +++ b/src/engine/objects/ItemBase.java @@ -259,51 +259,53 @@ public class ItemBase { case 250019: case 250028: case 250037: - return 3000000; + return 1000000; case 250002: //10 stats case 250011: case 250020: case 250029: case 250038: - return 4000000; + return 2000000; case 250003: //15 stats case 250012: case 250021: case 250030: case 250039: - return 5000000; + return 3000000; case 250004: //20 stats case 250013: case 250022: case 250031: case 250040: - return 6000000; + return 4000000; case 250005: //25 stats case 250014: case 250023: case 250032: case 250041: - return 7000000; + return 5000000; case 250006: //30 stats case 250015: case 250024: case 250033: case 250042: - return 8000000; + return 6000000; case 250007: //35 stats case 250016: case 250025: case 250034: case 250043: - return 9000000; + return 7000000; case 250008: //40 stats case 250017: case 250026: case 250035: case 250044: return 10000000; + case 252127: + return 5000000; } - return 10000000; + return 1000000; } /* From b3247160d7bd58cd4040f0f847782c58e81a0080 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 2 Mar 2025 18:20:53 -0600 Subject: [PATCH 132/151] fix join heavens host --- src/engine/gameManager/PowersManager.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index c7f70bef..d5d3592e 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -174,12 +174,12 @@ public enum PowersManager { if(pc.isMoving()) pc.stopMovement(pc.getMovementLoc()); - - if(!origin.getPlayerCharacter().getPowers().containsKey(msg.getPowerUsedID())){ - Logger.error(origin.getPlayerCharacter().getFirstName() + " attempted to cast a power they do not have"); - return; + if(msg.getPowerUsedID() != 421084024 && origin.getPlayerCharacter().getPromotionClassID() != 2513) { + if (!origin.getPlayerCharacter().getPowers().containsKey(msg.getPowerUsedID())) { + Logger.error(origin.getPlayerCharacter().getFirstName() + " attempted to cast a power they do not have"); + return; + } } - //crusader sacrifice if((msg.getPowerUsedID() == 428695403 && msg.getTargetID() == pc.getObjectUUID())){ RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID()); From d5e69446c78862cc7d75da8b5e0f6273cab249e8 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 2 Mar 2025 21:29:01 -0600 Subject: [PATCH 133/151] admin building creation --- .../client/handlers/PlaceAssetMsgHandler.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/engine/net/client/handlers/PlaceAssetMsgHandler.java b/src/engine/net/client/handlers/PlaceAssetMsgHandler.java index 9d96dfb3..99158058 100644 --- a/src/engine/net/client/handlers/PlaceAssetMsgHandler.java +++ b/src/engine/net/client/handlers/PlaceAssetMsgHandler.java @@ -1027,6 +1027,10 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { private boolean placeCityWalls(PlayerCharacter player, ClientConnection origin, PlaceAssetMsg msg) { + if(player.getAccount().status.equals(AccountStatus.ADMIN)){ + adminCreateBuildings(player,msg); + return false; + } // Member variables Zone serverZone; @@ -1165,7 +1169,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { return true; } - private Building createStructure(PlayerCharacter playerCharacter, PlacementInfo buildingInfo, Zone currentZone) { + private static Building createStructure(PlayerCharacter playerCharacter, PlacementInfo buildingInfo, Zone currentZone) { Blueprint blueprint; Building newMesh; @@ -1387,4 +1391,14 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { return true; } + + public static void adminCreateBuildings(PlayerCharacter pc, PlaceAssetMsg msg){ + //handled for building dungeon layouts + Zone zone = ZoneManager.getZoneByZoneID(993); + for(PlacementInfo placement : msg.getPlacementInfo()){ + Building building = createStructure(pc,placement,zone); + if(building != null) + building.setProtectionState(ProtectionState.NPC); + } + } } \ No newline at end of file From 8e5584f413207ddcfde8cc9f4f249a8f04e8e81f Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 2 Mar 2025 21:52:02 -0600 Subject: [PATCH 134/151] admin building creation --- src/engine/net/client/handlers/PlaceAssetMsgHandler.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/engine/net/client/handlers/PlaceAssetMsgHandler.java b/src/engine/net/client/handlers/PlaceAssetMsgHandler.java index 99158058..e516a963 100644 --- a/src/engine/net/client/handlers/PlaceAssetMsgHandler.java +++ b/src/engine/net/client/handlers/PlaceAssetMsgHandler.java @@ -1397,8 +1397,10 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { Zone zone = ZoneManager.getZoneByZoneID(993); for(PlacementInfo placement : msg.getPlacementInfo()){ Building building = createStructure(pc,placement,zone); - if(building != null) + if(building != null) { building.setProtectionState(ProtectionState.NPC); + building.setRank(1); + } } } } \ No newline at end of file From 6127bbadb44d06597f7a88cb1a6a39bbea55b8ea Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 2 Mar 2025 22:08:47 -0600 Subject: [PATCH 135/151] dungeon work --- src/engine/Dungeons/DungeonManager.java | 20 -------------------- src/engine/devcmd/cmds/DungenonCmd.java | 4 +++- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/engine/Dungeons/DungeonManager.java b/src/engine/Dungeons/DungeonManager.java index b4ac9fec..65f8d2b3 100644 --- a/src/engine/Dungeons/DungeonManager.java +++ b/src/engine/Dungeons/DungeonManager.java @@ -102,24 +102,4 @@ public class DungeonManager { } } - public static void createDungeon(Vector3fImmutable loc, int count){ - - Zone parent = ZoneManager.getZoneByUUID(993); - - Dungeon dungeon = new Dungeon(loc,count); - - Vector3fImmutable loc1 = new Vector3fImmutable(128,0,128); - Vector3fImmutable loc2 = new Vector3fImmutable(-128,0,-128); - Vector3fImmutable loc3 = new Vector3fImmutable(-128,0,128); - Vector3fImmutable loc4 = new Vector3fImmutable(128,0,-128); - - Building building1 = DbManager.BuildingQueries.CREATE_BUILDING(993,1,"Building",450750,loc1,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450750,0f,0f); - Building building2 = DbManager.BuildingQueries.CREATE_BUILDING(993,1,"Building",450750,loc2,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450750,0f,0f); - Building building3 = DbManager.BuildingQueries.CREATE_BUILDING(993,1,"Building",450750,loc3,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450750,0f,0f); - Building building4 = DbManager.BuildingQueries.CREATE_BUILDING(993,1,"Building",450750,loc4,1.0f,5000, Enum.ProtectionState.NPC,0,1,null,450750,0f,0f); - WorldGrid.addObject(building1,parent.getLoc().x + loc1.x,parent.getLoc().z + loc1.z); - WorldGrid.addObject(building2,parent.getLoc().x + loc2.x,parent.getLoc().z + loc2.z); - WorldGrid.addObject(building3,parent.getLoc().x + loc3.x,parent.getLoc().z + loc3.z); - WorldGrid.addObject(building4,parent.getLoc().x + loc4.x,parent.getLoc().z + loc4.z); - } } diff --git a/src/engine/devcmd/cmds/DungenonCmd.java b/src/engine/devcmd/cmds/DungenonCmd.java index d20fa518..39ea68c4 100644 --- a/src/engine/devcmd/cmds/DungenonCmd.java +++ b/src/engine/devcmd/cmds/DungenonCmd.java @@ -12,6 +12,7 @@ package engine.devcmd.cmds; import engine.Dungeons.DungeonManager; import engine.Enum.GameObjectType; import engine.devcmd.AbstractDevCmd; +import engine.gameManager.BuildingManager; import engine.gameManager.ChatManager; import engine.gameManager.DbManager; import engine.gameManager.ZoneManager; @@ -36,7 +37,8 @@ public class DungenonCmd extends AbstractDevCmd { if(parent == null) return; - DungeonManager.createDungeon(parent.getLoc(),5); + Vector3fImmutable loc = Vector3fImmutable.getRandomPointOnCircle(BuildingManager.getBuilding(2827951).loc,30f); + pc.teleport(loc); } @Override From 5841db2a0da8c1b83e4d967a2ee7469fc8c9c109 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 2 Mar 2025 22:30:24 -0600 Subject: [PATCH 136/151] serialize dungeon for teleport --- src/engine/Dungeons/Dungeon.java | 93 +++++++++++++++++++ .../client/msg/TeleportRepledgeListMsg.java | 4 +- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/src/engine/Dungeons/Dungeon.java b/src/engine/Dungeons/Dungeon.java index 05ec4ef2..bb6e6aad 100644 --- a/src/engine/Dungeons/Dungeon.java +++ b/src/engine/Dungeons/Dungeon.java @@ -2,12 +2,17 @@ package engine.Dungeons; import engine.Enum; import engine.InterestManagement.WorldGrid; +import engine.gameManager.BuildingManager; import engine.gameManager.PowersManager; +import engine.gameManager.ZoneManager; import engine.math.Vector3fImmutable; +import engine.net.ByteBufferWriter; import engine.objects.*; import engine.powers.EffectsBase; import engine.server.MBServerStatics; +import org.pmw.tinylog.Logger; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.HashSet; @@ -58,4 +63,92 @@ public class Dungeon { eff.endEffect(); } } + + public static void serializeForClientMsgTeleport(ByteBufferWriter writer) { + Guild rulingGuild = Guild.getErrantGuild(); + Guild rulingNation = Guild.getErrantGuild(); + + Zone zone = ZoneManager.getZoneByUUID(994); + // Begin Serialzing soverign guild data + writer.putInt(Enum.GameObjectType.Zone.ordinal()); + writer.putInt(994); + writer.putString("Whitehorn Citadel"); + writer.putInt(rulingGuild.getObjectType().ordinal()); + writer.putInt(rulingGuild.getObjectUUID()); + + writer.putString(rulingGuild.getName()); + writer.putString(""); + writer.putString(rulingGuild.getLeadershipType()); + + // Serialize guild ruler's name + // If tree is abandoned blank out the name + // to allow them a rename. + + writer.putString(""); + + writer.putInt(rulingGuild.getCharter()); + writer.putInt(0); // always 00000000 + + writer.put((byte)0); + + writer.put((byte) 1); + writer.put((byte) 1); // *** Refactor: What are these flags? + writer.put((byte) 1); + writer.put((byte) 1); + writer.put((byte) 1); + + GuildTag._serializeForDisplay(rulingGuild.getGuildTag(), writer); + GuildTag._serializeForDisplay(rulingNation.getGuildTag(), writer); + + writer.putInt(0);// TODO Implement description text + + writer.put((byte) 1); + writer.put((byte) 0); + writer.put((byte) 1); + + // Begin serializing nation guild info + + if (rulingNation.isEmptyGuild()) { + writer.putInt(rulingGuild.getObjectType().ordinal()); + writer.putInt(rulingGuild.getObjectUUID()); + } else { + writer.putInt(rulingNation.getObjectType().ordinal()); + writer.putInt(rulingNation.getObjectUUID()); + } + + + // Serialize nation name + + if (rulingNation.isEmptyGuild()) + writer.putString("None"); + else + writer.putString(rulingNation.getName()); + + writer.putInt(1); + + writer.putInt(0xFFFFFFFF); + + writer.putInt(0); + + if (rulingNation.isEmptyGuild()) + writer.putString(" "); + + writer.putLocalDateTime(LocalDateTime.now()); + + //location + Vector3fImmutable loc = Vector3fImmutable.getRandomPointOnCircle(BuildingManager.getBuilding(2827951).loc,30f); + + writer.putFloat(loc.x); + writer.putFloat(loc.y); + writer.putFloat(loc.z); + + writer.putInt(0); + + writer.put((byte) 1); + writer.put((byte) 0); + writer.putInt(0x64); + writer.put((byte) 0); + writer.put((byte) 0); + writer.put((byte) 0); + } } diff --git a/src/engine/net/client/msg/TeleportRepledgeListMsg.java b/src/engine/net/client/msg/TeleportRepledgeListMsg.java index 69b73e43..84e60fd8 100644 --- a/src/engine/net/client/msg/TeleportRepledgeListMsg.java +++ b/src/engine/net/client/msg/TeleportRepledgeListMsg.java @@ -10,6 +10,7 @@ package engine.net.client.msg; +import engine.Dungeons.Dungeon; import engine.net.AbstractConnection; import engine.net.AbstractNetMsg; import engine.net.ByteBufferReader; @@ -108,7 +109,7 @@ public class TeleportRepledgeListMsg extends ClientNetMsg { for (int i = 0; i < 3; i++) writer.putInt(0); - writer.putInt(cities.size() + mines.size()); + writer.putInt(cities.size() + mines.size() + 1); for (City city : cities) City.serializeForClientMsg(city, writer); @@ -116,6 +117,7 @@ public class TeleportRepledgeListMsg extends ClientNetMsg { for(Mine mine : mines) Mine.serializeForClientMsgTeleport(mine, writer); + Dungeon.serializeForClientMsgTeleport(writer); } public PlayerCharacter getPlayer() { From 251210d166e768f0c71410a6f3b45ec3b4df51f0 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 2 Mar 2025 22:48:37 -0600 Subject: [PATCH 137/151] remove dungeon teleport from base game --- src/engine/Dungeons/Dungeon.java | 16 ++++++---------- .../net/client/handlers/MerchantMsgHandler.java | 8 ++++++++ .../net/client/msg/TeleportRepledgeListMsg.java | 4 ++-- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/engine/Dungeons/Dungeon.java b/src/engine/Dungeons/Dungeon.java index bb6e6aad..dc325f2f 100644 --- a/src/engine/Dungeons/Dungeon.java +++ b/src/engine/Dungeons/Dungeon.java @@ -76,15 +76,15 @@ public class Dungeon { writer.putInt(rulingGuild.getObjectType().ordinal()); writer.putInt(rulingGuild.getObjectUUID()); - writer.putString(rulingGuild.getName()); - writer.putString(""); + writer.putString("Whitehorn Militants"); // guild name + writer.putString("In the Citadel, We Fight!"); // motto writer.putString(rulingGuild.getLeadershipType()); // Serialize guild ruler's name // If tree is abandoned blank out the name // to allow them a rename. - writer.putString(""); + writer.putString("Kol'roth The Destroyer");//sovreign writer.putInt(rulingGuild.getCharter()); writer.putInt(0); // always 00000000 @@ -119,19 +119,15 @@ public class Dungeon { // Serialize nation name - if (rulingNation.isEmptyGuild()) - writer.putString("None"); - else - writer.putString(rulingNation.getName()); + writer.putString("Whitehorn Militants"); //nation name - writer.putInt(1); + writer.putInt(-1);//city rank, -1 puts it at top of list always writer.putInt(0xFFFFFFFF); writer.putInt(0); - if (rulingNation.isEmptyGuild()) - writer.putString(" "); + writer.putString("Kol'roth The Destroyer");//nation ruler writer.putLocalDateTime(LocalDateTime.now()); diff --git a/src/engine/net/client/handlers/MerchantMsgHandler.java b/src/engine/net/client/handlers/MerchantMsgHandler.java index 2515646d..ddd2ccc0 100644 --- a/src/engine/net/client/handlers/MerchantMsgHandler.java +++ b/src/engine/net/client/handlers/MerchantMsgHandler.java @@ -282,6 +282,14 @@ public class MerchantMsgHandler extends AbstractClientMsgHandler { } } if(mineTele == null){ + //must be the dungeon request? + Vector3fImmutable loc = Vector3fImmutable.getRandomPointOnCircle(BuildingManager.getBuilding(2827951).loc,30f); + ChatManager.chatSystemInfo(player, "You Will Teleport To Whitehorn Citadel In " + 10 + " Seconds."); + if (10 > 0) { + //TODO add timer to teleport + TeleportJob tj = new TeleportJob(player, npc, loc, origin, true); + JobScheduler.getInstance().scheduleJob(tj, 10 * 1000); + } return; }else { int time = MBServerStatics.TELEPORT_TIME_IN_SECONDS; diff --git a/src/engine/net/client/msg/TeleportRepledgeListMsg.java b/src/engine/net/client/msg/TeleportRepledgeListMsg.java index 84e60fd8..d623ed5b 100644 --- a/src/engine/net/client/msg/TeleportRepledgeListMsg.java +++ b/src/engine/net/client/msg/TeleportRepledgeListMsg.java @@ -109,7 +109,7 @@ public class TeleportRepledgeListMsg extends ClientNetMsg { for (int i = 0; i < 3; i++) writer.putInt(0); - writer.putInt(cities.size() + mines.size() + 1); + writer.putInt(cities.size() + mines.size());// + 1); for (City city : cities) City.serializeForClientMsg(city, writer); @@ -117,7 +117,7 @@ public class TeleportRepledgeListMsg extends ClientNetMsg { for(Mine mine : mines) Mine.serializeForClientMsgTeleport(mine, writer); - Dungeon.serializeForClientMsgTeleport(writer); + //Dungeon.serializeForClientMsgTeleport(writer); } public PlayerCharacter getPlayer() { From 9f09a0e8b0b00176f74921d7f6feb2b8c22ddb3e Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Mar 2025 06:33:31 -0600 Subject: [PATCH 138/151] proc chance broken into separate method --- src/engine/gameManager/CombatManager.java | 55 ++- src/engine/gameManager/CombatSystem.java | 430 ---------------------- 2 files changed, 35 insertions(+), 450 deletions(-) delete mode 100644 src/engine/gameManager/CombatSystem.java diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index be582615..fb952d51 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -978,26 +978,7 @@ public enum CombatManager { errorTrack = 14; //handle procs - - if (weapon != null && tarAc != null && tarAc.isAlive()) { - - if(weapon.effects != null){ - for (Effect eff : weapon.effects.values()){ - for(AbstractEffectModifier mod : eff.getEffectModifiers()){ - if(mod.modType.equals(ModType.WeaponProc)){ - int procChance = ThreadLocalRandom.current().nextInt(100); - if (procChance < MBServerStatics.PROC_CHANCE) { - try { - ((WeaponProcEffectModifier) mod).applyProc(ac, target); - }catch(Exception e){ - Logger.error(eff.getName() + " Failed To Cast Proc"); - } - } - } - } - } - } - } + procChanceHandler(weapon,ac,tarAc); errorTrack = 15; @@ -1081,6 +1062,40 @@ public enum CombatManager { } } + private static void procChanceHandler(Item weapon, AbstractCharacter ac, AbstractCharacter tarAc) { + + //no weapon means no proc + if(weapon == null) + return; + + //caster is dead of null, no proc + if(ac == null || !ac.isAlive()) + return; + + //target is dead or null, no proc + if(tarAc == null || !tarAc.isAlive()) + return; + + //no effects on weapon, skip proc + if(weapon.effects == null || weapon.effects.isEmpty()) + return; + + for (Effect eff : weapon.effects.values()){ + for(AbstractEffectModifier mod : eff.getEffectModifiers()) { + if (mod.modType.equals(ModType.WeaponProc)) { + int procChance = ThreadLocalRandom.current().nextInt(100); + if (procChance < MBServerStatics.PROC_CHANCE) { + try { + ((WeaponProcEffectModifier) mod).applyProc(ac, tarAc); + } catch (Exception e) { + Logger.error(eff.getName() + " Failed To Cast Proc"); + } + } + } + } + } + } + public static boolean canTestParry(AbstractCharacter ac, AbstractWorldObject target) { if (ac == null || target == null || !AbstractWorldObject.IsAbstractCharacter(target)) diff --git a/src/engine/gameManager/CombatSystem.java b/src/engine/gameManager/CombatSystem.java deleted file mode 100644 index a2eadb3b..00000000 --- a/src/engine/gameManager/CombatSystem.java +++ /dev/null @@ -1,430 +0,0 @@ -package engine.gameManager; - -import engine.Enum; -import engine.exception.MsgSendException; -import engine.job.JobContainer; -import engine.job.JobScheduler; -import engine.jobs.AttackJob; -import engine.jobs.DeferredPowerJob; -import engine.net.DispatchMessage; -import engine.net.client.ClientConnection; -import engine.net.client.msg.AttackCmdMsg; -import engine.net.client.msg.TargetedActionMsg; -import engine.objects.*; -import engine.powers.DamageShield; -import engine.powers.effectmodifiers.AbstractEffectModifier; -import engine.powers.effectmodifiers.WeaponProcEffectModifier; -import engine.server.MBServerStatics; -import org.pmw.tinylog.Logger; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ThreadLocalRandom; - -public class CombatSystem { - - public static void attemptCombat(AbstractCharacter source, AbstractWorldObject target, boolean mainhand){ - - //1. source or target doesn't exist, early exit - if(source == null || target == null) - return; - - //2. source or target is dead, early exit - if(!source.isAlive() || !target.isAlive()) - return; - - //3. make sure if target is a building to ensure that it is damageable - if(target.getObjectType().equals(Enum.GameObjectType.Building)){ - Building building = (Building)target; - if(building.assetIsProtected() || building.getProtectionState().equals(Enum.ProtectionState.NPC)) - return; - } - - //after thought: make sure target is in range of source - if(!inRange(source,target,mainhand)) - return; - - //4. apply any weapon powers and then clear the weapon power memory for the player - if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { - PlayerCharacter pc = (PlayerCharacter)source; - if(pc.getWeaponPower() != null){ - pc.getWeaponPower().attack(target,pc.getRange()); - pc.setWeaponPower(null); - } - } - - //5. make sure if target is AbstractCharacter to check for defense trigger and passive trigger - if(AbstractCharacter.IsAbstractCharacter(target)) { - int atr; - int def; - if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { - PlayerCharacter pc = (PlayerCharacter)source; - if(pc.combatStats == null) - pc.combatStats = new PlayerCombatStats(pc); - atr = (int) pc.combatStats.atrHandOne; - if(!mainhand) - atr =(int) pc.combatStats.atrHandTwo; - - def = pc.combatStats.defense; - } else { - atr = (int) ((source.getAtrHandOne() + source.getAtrHandTwo()) * 0.5f); - def = source.defenseRating; - } - - if(!LandHit(atr,def)) { - createTimer(source,mainhand); - return; - } - - if(source.getBonuses() != null) - if(!source.getBonuses().getBool(Enum.ModType.IgnorePassiveDefense, Enum.SourceType.None)) - if(triggerPassive(source,target)) { - createTimer(source,mainhand); - return; - } - } - - //commence actual combat management - - //6. check for any procs - if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { - PlayerCharacter pc = (PlayerCharacter)source; - if(pc.getCharItemManager() != null && pc.getCharItemManager().getEquipped() != null){ - Item weapon = pc.getCharItemManager().getEquipped(1); - if(!mainhand) - weapon = pc.getCharItemManager().getEquipped(2); - if(weapon != null){ - if(weapon.effects != null){ - for (Effect eff : weapon.effects.values()){ - for(AbstractEffectModifier mod : eff.getEffectModifiers()){ - if(mod.modType.equals(Enum.ModType.WeaponProc)){ - int procChance = ThreadLocalRandom.current().nextInt(0,101); - if (procChance <= MBServerStatics.PROC_CHANCE) { - try { - ((WeaponProcEffectModifier) mod).applyProc(source, target); - }catch(Exception e){ - Logger.error(eff.getName() + " Failed To Cast Proc"); - } - } - } - } - } - } - } - } - } - - //7. configure damage amounts and type - Enum.DamageType damageType = Enum.DamageType.Crush; - int min = 0; - int max = 0; - if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { - PlayerCharacter pc = (PlayerCharacter) source; - if(mainhand){ - min = pc.combatStats.minDamageHandOne; - max = pc.combatStats.maxDamageHandOne; - }else{ - min = pc.combatStats.minDamageHandTwo; - max = pc.combatStats.maxDamageHandTwo; - } - }else if (source.getObjectType().equals(Enum.GameObjectType.Mob)) { - Mob mob = (Mob) source; - min = (int) mob.mobBase.getDamageMin(); - max = (int) mob.mobBase.getDamageMax(); - } - - int damage = ThreadLocalRandom.current().nextInt(min,max + 1); - - if(source.getBonuses() != null){ - damage *= 1 + source.getBonuses().getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None); - } - if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { - PlayerCharacter pc = (PlayerCharacter) source; - damage *= pc.ZergMultiplier; - } - - //8. configure the attack message to be sent to the clients - int animation = 0; - ItemBase wb = null; - if(source.getCharItemManager() != null && source.getCharItemManager().getEquipped() != null) { - Item weapon = source.getCharItemManager().getEquipped(1); - if (!mainhand) - weapon = source.getCharItemManager().getEquipped(2); - - if(weapon != null && weapon.getItemBase().getAnimations() != null && !weapon.getItemBase().getAnimations().isEmpty()){ - animation = weapon.getItemBase().getAnimations().get(0); - wb = weapon.getItemBase(); - damageType = wb.getDamageType(); - } - } - - //9. reduce damage from resists and apply damage shields - if(AbstractCharacter.IsAbstractCharacter(target)){ - AbstractCharacter abs = (AbstractCharacter) target; - damage = (int) abs.getResists().getResistedDamage(source, abs,damageType,damage,1); - handleDamageShields(source,abs,damage); - } - - - - sendCombatMessage(source, target, 0f, wb, null, mainhand, animation); - - //if attacker is player, set last attack timestamp - if (source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) - updateAttackTimers((PlayerCharacter) source, target); - - //10. cancel all effects that cancel on attack - source.cancelOnAttack(); - } - - public static boolean LandHit(int ATR, int DEF){ - - int roll = ThreadLocalRandom.current().nextInt(101); - - float chance = PlayerCombatStats.getHitChance(ATR,DEF); - return chance >= roll; - } - - private static void sendCombatMessage(AbstractCharacter source, AbstractWorldObject target, float damage, ItemBase wb, DeferredPowerJob dpj, boolean mainHand, int swingAnimation) { - - if (dpj != null) - if (PowersManager.AnimationOverrides.containsKey(dpj.getAction().getEffectID())) - swingAnimation = PowersManager.AnimationOverrides.get(dpj.getAction().getEffectID()); - - if (source.getObjectType() == Enum.GameObjectType.PlayerCharacter) - for (Effect eff : source.getEffects().values()) - if (eff.getPower() != null && (eff.getPower().getToken() == 429506943 || eff.getPower().getToken() == 429408639 || eff.getPower().getToken() == 429513599 || eff.getPower().getToken() == 429415295)) - swingAnimation = 0; - - TargetedActionMsg cmm = new TargetedActionMsg(source, target, damage, swingAnimation); - DispatchMessage.sendToAllInRange(target, cmm); - } - - private static void updateAttackTimers(PlayerCharacter pc, AbstractWorldObject target) { - - //Set Attack Timers - - if (target.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) - pc.setLastPlayerAttackTime(); - } - - public static void handleDamageShields(AbstractCharacter ac, AbstractCharacter target, float damage) { - - if (ac == null || target == null) - return; - - PlayerBonuses bonuses = target.getBonuses(); - - if (bonuses != null) { - - ConcurrentHashMap damageShields = bonuses.getDamageShields(); - float total = 0; - - for (DamageShield ds : damageShields.values()) { - - //get amount to damage back - - float amount; - - if (ds.usePercent()) - amount = damage * ds.getAmount() / 100; - else - amount = ds.getAmount(); - - //get resisted damage for damagetype - - Resists resists = ac.getResists(); - - if (resists != null) { - amount = resists.getResistedDamage(target, ac, ds.getDamageType(), amount, 0); - } - total += amount; - } - - if (total > 0) { - - //apply Damage back - - ac.modifyHealth(-total, target, true); - - TargetedActionMsg cmm = new TargetedActionMsg(ac, ac, total, 0); - DispatchMessage.sendToAllInRange(target, cmm); - - } - } - } - - public static boolean inRange(AbstractCharacter source, AbstractWorldObject target, boolean mainhand){ - - if(source == null || target == null) - return false; - - float distanceSquared = source.loc.distanceSquared(target.loc); - - float rangeSquared = 16.0f; - - if(source.getCharItemManager() != null && source.getCharItemManager().getEquipped() != null){ - Item weapon = source.getCharItemManager().getEquipped(1); - if(!mainhand) - weapon = source.getCharItemManager().getEquipped(2); - if(weapon != null) - rangeSquared = weapon.getItemBase().getRange() * weapon.getItemBase().getRange(); - } - - if(source.getBonuses() != null){ - rangeSquared *= 1 + source.getBonuses().getFloatPercentAll(Enum.ModType.WeaponRange, Enum.SourceType.None); - } - - return distanceSquared <= rangeSquared; - } - - public static boolean triggerPassive(AbstractCharacter source, AbstractWorldObject target) { - boolean passiveFired = false; - - if (!AbstractCharacter.IsAbstractCharacter(target)) - return false; - - AbstractCharacter tarAc = (AbstractCharacter) target; - //Handle Block passive - if (testPassive(source, tarAc, "Block")) { - sendPassiveDefenseMessage(source, null, target, MBServerStatics.COMBAT_SEND_DODGE, null, true); - return true; - } - - //Handle Parry passive - if (testPassive(source, tarAc, "Parry")) { - sendPassiveDefenseMessage(source, null, target, MBServerStatics.COMBAT_SEND_DODGE, null, true); - return true; - } - - //Handle Dodge passive - if (testPassive(source, tarAc, "Dodge")) { - sendPassiveDefenseMessage(source, null, target, MBServerStatics.COMBAT_SEND_DODGE, null, true); - return true; - } - return false; - } - - private static void sendPassiveDefenseMessage(AbstractCharacter source, ItemBase wb, AbstractWorldObject target, int passiveType, DeferredPowerJob dpj, boolean mainHand) { - - int swingAnimation = 75; - - if (dpj != null) - if (PowersManager.AnimationOverrides.containsKey(dpj.getAction().getEffectID())) - swingAnimation = PowersManager.AnimationOverrides.get(dpj.getAction().getEffectID()); - - TargetedActionMsg cmm = new TargetedActionMsg(source, swingAnimation, target, passiveType); - DispatchMessage.sendToAllInRange(target, cmm); - } - - private static boolean testPassive(AbstractCharacter source, AbstractCharacter target, String type) { - - if(target.getBonuses() != null) - if(target.getBonuses().getBool(Enum.ModType.Stunned, Enum.SourceType.None)) - return false; - - float chance = target.getPassiveChance(type, source.getLevel(), true); - - if (chance == 0f) - return false; - - //max 75% chance of passive to fire - - if (chance > 75f) - chance = 75f; - - int roll = ThreadLocalRandom.current().nextInt(1,100); - - return roll < chance; - - } - - private static void createTimer(AbstractCharacter source, boolean mainhand) { - - ConcurrentHashMap timers = source.getTimers(); - int slot = 1; - if(!mainhand) - slot = 2; - - int time = 3000; - if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ - PlayerCharacter pc = (PlayerCharacter)source; - if(mainhand){ - time = (int) pc.combatStats.attackSpeedHandOne; - }else{ - time = (int) pc.combatStats.attackSpeedHandTwo; - } - } - - if (timers != null) { - AttackJob aj = new AttackJob(source, slot, true); - JobContainer job; - job = JobScheduler.getInstance().scheduleJob(aj, (time * 100)); - timers.put("Attack" + slot, job); - } else { - Logger.error("Unable to find Timers for Character " + source.getObjectUUID()); - } - } - - public static void setAttackTarget(AttackCmdMsg msg, ClientConnection origin) throws MsgSendException { - - PlayerCharacter player; - int targetType; - AbstractWorldObject target; - - if (TargetedActionMsg.un2cnt == 60 || TargetedActionMsg.un2cnt == 70) - return; - - player = SessionManager.getPlayerCharacter(origin); - - if (player == null) - return; - - //source must match player this account belongs to - - if (player.getObjectUUID() != msg.getSourceID() || player.getObjectType().ordinal() != msg.getSourceType()) { - Logger.error("Msg Source ID " + msg.getSourceID() + " Does not Match Player ID " + player.getObjectUUID()); - return; - } - - targetType = msg.getTargetType(); - - if (targetType == Enum.GameObjectType.PlayerCharacter.ordinal()) { - target = PlayerCharacter.getFromCache(msg.getTargetID()); - } else if (targetType == Enum.GameObjectType.Building.ordinal()) { - target = BuildingManager.getBuildingFromCache(msg.getTargetID()); - } else if (targetType == Enum.GameObjectType.Mob.ordinal()) { - target = Mob.getFromCache(msg.getTargetID()); - } else { - player.setCombatTarget(null); - return; //not valid type to attack - } - - // quit of the combat target is already the current combat target - // or there is no combat target - - if (target == null) - return; - - //set sources target - - player.setCombatTarget(target); - - boolean hasMain = false; - boolean hasOff = false; - if(player.getCharItemManager() != null && player.getCharItemManager().getEquipped() != null){ - if(player.getCharItemManager().getEquipped(1) != null) - hasMain = true; - if(player.getCharItemManager().getEquipped(2) != null && !player.getCharItemManager().getEquipped(2).getItemBase().isShield()) - hasOff = true; - } - - if(hasMain){ - createTimer(player,true); - } - - if(hasOff){ - createTimer(player,false); - } - - } -} From 67628a21b39b8ed2eaad3c0b5121f3b23e38a6f7 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Mar 2025 06:35:06 -0600 Subject: [PATCH 139/151] proc chance broken into separate method --- src/engine/gameManager/CombatManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index fb952d51..de311023 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -1087,6 +1087,7 @@ public enum CombatManager { if (procChance < MBServerStatics.PROC_CHANCE) { try { ((WeaponProcEffectModifier) mod).applyProc(ac, tarAc); + break; } catch (Exception e) { Logger.error(eff.getName() + " Failed To Cast Proc"); } From 898f6dfa6956c43872e578558486a22f29433dae Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Mar 2025 06:37:39 -0600 Subject: [PATCH 140/151] strip item enchants --- src/engine/objects/Item.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/engine/objects/Item.java b/src/engine/objects/Item.java index bcfa2120..056df1cd 100644 --- a/src/engine/objects/Item.java +++ b/src/engine/objects/Item.java @@ -827,7 +827,12 @@ public class Item extends AbstractWorldObject { ToRemove.add(eff); } } - this.effects.values().removeAll(ToRemove); + + for(Effect eff : ToRemove)//{ + this.effects.remove(eff.getEffectsBase().getIDString()); + //} + + //this.effects.values().removeAll(ToRemove); }catch(Exception ignored){ } From 46b9da0612fb5b8c9fe5f8861104d860a176d3cc Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Mar 2025 07:17:12 -0600 Subject: [PATCH 141/151] strip item enchants --- src/engine/objects/CharacterItemManager.java | 2 ++ src/engine/objects/Item.java | 31 +++++++++++++------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/engine/objects/CharacterItemManager.java b/src/engine/objects/CharacterItemManager.java index 92e19d22..16376023 100644 --- a/src/engine/objects/CharacterItemManager.java +++ b/src/engine/objects/CharacterItemManager.java @@ -1058,6 +1058,7 @@ public class CharacterItemManager { i.addToCache(); try { i.stripCastableEnchants(); + this.updateInventory(); }catch(Exception ignored){ Logger.error("FAILED TO STRIP CASTABLE ENCHANTS: Move Item To Bank"); } @@ -1203,6 +1204,7 @@ public class CharacterItemManager { try { i.stripCastableEnchants(); + this.updateInventory(); }catch(Exception ignored){ Logger.error("FAILED TO STRIP CASTABLE ENCHANTS: Move Item To Vault"); } diff --git a/src/engine/objects/Item.java b/src/engine/objects/Item.java index 056df1cd..77d250c9 100644 --- a/src/engine/objects/Item.java +++ b/src/engine/objects/Item.java @@ -819,19 +819,30 @@ public class Item extends AbstractWorldObject { public void stripCastableEnchants(){ try { - ArrayList ToRemove = new ArrayList<>(); - for (Effect eff : this.effects.values()) { - if (eff.getJobContainer() != null && !eff.getJobContainer().noTimer()) { - eff.endEffectNoPower(); - eff.getJobContainer().cancelJob(); - ToRemove.add(eff); - } + //ArrayList ToRemove = new ArrayList<>(); + //for (Effect eff : this.effects.values()) { + // if (eff.getJobContainer() != null && !eff.getJobContainer().noTimer()) { + // eff.endEffectNoPower(); + // eff.getJobContainer().cancelJob(); + // ToRemove.add(eff); + // } + //} + + //strip procs + if(this.effects.get("EnchantWeapon") != null){ + this.effects.remove("EnchantWeapon"); + Effect eff = this.effects.get("EnchantWeapon"); + eff.endEffectNoPower(); } - for(Effect eff : ToRemove)//{ - this.effects.remove(eff.getEffectsBase().getIDString()); - //} + //strip forge master hone armor + if(this.effects.get("1000") != null){ + this.effects.remove("1000"); + Effect eff = this.effects.get("1000"); + eff.endEffectNoPower(); + } + this.applyAllBonuses(); //this.effects.values().removeAll(ToRemove); }catch(Exception ignored){ From 5b6896e537d6bb74c1e15ae4fac078a3da4fbb14 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Mar 2025 07:37:52 -0600 Subject: [PATCH 142/151] strip item enchants --- src/engine/objects/Item.java | 52 ++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/engine/objects/Item.java b/src/engine/objects/Item.java index 77d250c9..b8937d99 100644 --- a/src/engine/objects/Item.java +++ b/src/engine/objects/Item.java @@ -819,29 +819,59 @@ public class Item extends AbstractWorldObject { public void stripCastableEnchants(){ try { - //ArrayList ToRemove = new ArrayList<>(); - //for (Effect eff : this.effects.values()) { - // if (eff.getJobContainer() != null && !eff.getJobContainer().noTimer()) { - // eff.endEffectNoPower(); - // eff.getJobContainer().cancelJob(); - // ToRemove.add(eff); - // } - //} - - //strip procs + //strip EnchantWeapon if(this.effects.get("EnchantWeapon") != null){ this.effects.remove("EnchantWeapon"); Effect eff = this.effects.get("EnchantWeapon"); eff.endEffectNoPower(); } - //strip forge master hone armor + //strip FGM-003 if(this.effects.get("1000") != null){ this.effects.remove("1000"); Effect eff = this.effects.get("1000"); eff.endEffectNoPower(); } + //strip FGM-001 + if(this.effects.get("996") != null){ + this.effects.remove("996"); + Effect eff = this.effects.get("996"); + eff.endEffectNoPower(); + } + + //strip ENC-001 + if(this.effects.get("957") != null){ + this.effects.remove("957"); + Effect eff = this.effects.get("957"); + eff.endEffectNoPower(); + } + if(this.effects.get("958") != null){ + this.effects.remove("958"); + Effect eff = this.effects.get("958"); + eff.endEffectNoPower(); + } + if(this.effects.get("959") != null){ + this.effects.remove("959"); + Effect eff = this.effects.get("959"); + eff.endEffectNoPower(); + } + if(this.effects.get("960") != null){ + this.effects.remove("960"); + Effect eff = this.effects.get("960"); + eff.endEffectNoPower(); + } + if(this.effects.get("961") != null){ + this.effects.remove("961"); + Effect eff = this.effects.get("961"); + eff.endEffectNoPower(); + } + if(this.effects.get("962") != null){ + this.effects.remove("962"); + Effect eff = this.effects.get("962"); + eff.endEffectNoPower(); + } + this.applyAllBonuses(); //this.effects.values().removeAll(ToRemove); }catch(Exception ignored){ From e4ac2bc48934f4713c8a8a2cb7bcb93347fdc7a8 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Mar 2025 12:44:39 -0600 Subject: [PATCH 143/151] 3 man zerg multiplier update --- src/engine/gameManager/ZergManager.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/gameManager/ZergManager.java b/src/engine/gameManager/ZergManager.java index 649f8c5a..a340b0e0 100644 --- a/src/engine/gameManager/ZergManager.java +++ b/src/engine/gameManager/ZergManager.java @@ -21,9 +21,9 @@ public class ZergManager { return 0.0f; switch(count){ - case 4: return 0.63f; - case 5: return 0.40f; - case 6: return 0.25f; + case 4: return 0.50f; + case 5: return 0.0f; + case 6: return 0.0f; default: return 1.0f; } } From 6311f8b2f819a1711bd6bb33f938e142804aeb2d Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Mar 2025 13:00:11 -0600 Subject: [PATCH 144/151] different location sync system --- src/engine/objects/PlayerCharacter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 7bdd71a0..a486e8c4 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -5145,7 +5145,9 @@ public class PlayerCharacter extends AbstractCharacter { @Override public void update(Boolean newSystem) { - this.updateLocation(); + if(!newSystem) + this.updateLocation(); + this.updateMovementState(); if(!newSystem) From b33af64f6086ded3635dfc874cdbbc21adb605b3 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Mar 2025 13:23:37 -0600 Subject: [PATCH 145/151] remove unessecary player sync --- src/engine/objects/PlayerCharacter.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index a486e8c4..f42fc281 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -5223,11 +5223,6 @@ public class PlayerCharacter extends AbstractCharacter { } } - try { - this.clearClientEffects(); - }catch(Exception ignored){ - - } } catch (Exception e) { Logger.error(e); @@ -5239,17 +5234,6 @@ public class PlayerCharacter extends AbstractCharacter { Logger.error("UPDATE ISSUE: " + e); } } - - public void clearClientEffects(){ - if(this.bonuses != null) { - if (!bonuses.getBool(ModType.Stunned, SourceType.None)) { - this.removeEffectBySource(EffectSourceType.Stun, 40, true); - } - if(!this.bonuses.getBool(Enum.ModType.CannotMove,Enum.SourceType.None)){ - this.removeEffectBySource(EffectSourceType.Root,40,true); - } - } - } public static void unboxPlayer(PlayerCharacter player){ String machineID = player.getClientConnection().machineID; ArrayList sameMachine = new ArrayList<>(); From 0a82a69a95d0055a77f77adcf0fdb8ef291e4afa Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Mar 2025 13:30:13 -0600 Subject: [PATCH 146/151] remove style casting --- src/engine/objects/PlayerCombatStats.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 09eeb088..58ce1222 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -1,6 +1,7 @@ package engine.objects; import engine.Enum; +import engine.jobs.DeferredPowerJob; import engine.powers.EffectsBase; import engine.powers.PowersBase; import engine.powers.effectmodifiers.AbstractEffectModifier; @@ -1053,8 +1054,14 @@ public class PlayerCombatStats { atr += (modifiedDexterity * 0.5f) + weaponATR1 + weaponATR2; atr *= precise; atr += atrBuffs; + if(pc.getWeaponPower() != null){ + DeferredPowerJob dpj = pc.getWeaponPower(); + dpj.endEffect(); + } + if(pc.bonuses != null) atr *= 1 + (pc.bonuses.getFloatPercentAll(Enum.ModType.OCV, Enum.SourceType.None) - (stanceMod - 1) - (precise - 1) - healerDefStance); + atr *= stanceMod; return atr; } From 58e84bfc21db7999262f1aeb1547a330a9713c08 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Mar 2025 13:31:54 -0600 Subject: [PATCH 147/151] remove style casting --- src/engine/objects/PlayerCombatStats.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index 58ce1222..f397e306 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -434,7 +434,7 @@ public class PlayerCombatStats { atr *= 1.0f + stanceValue; if(this.owner.bonuses != null) { - float positivePercentBonuses = this.owner.bonuses.getFloatPercentPositive(Enum.ModType.OCV, Enum.SourceType.None); + float positivePercentBonuses = this.owner.bonuses.getFloatPercentPositive(Enum.ModType.OCV, Enum.SourceType.None) - stanceValue; float negativePercentBonuses = this.owner.bonuses.getFloatPercentNegative(Enum.ModType.OCV, Enum.SourceType.None); float modifier = 1 + (positivePercentBonuses + negativePercentBonuses); if(preciseRune > 1.0f) From 4ea4609b1be0aad992f5ba612cfe298a2a673110 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Mar 2025 13:43:14 -0600 Subject: [PATCH 148/151] check for immunity and no od prior to running power action --- src/engine/gameManager/PowersManager.java | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index d5d3592e..5c9fff80 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -28,6 +28,7 @@ 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; @@ -1968,9 +1969,7 @@ public enum PowersManager { } } - public static void runPowerAction(AbstractCharacter source, - AbstractWorldObject awo, Vector3fImmutable targetLoc, - ActionsBase ab, int trains, PowersBase pb) { + public static void runPowerAction(AbstractCharacter source, AbstractWorldObject awo, Vector3fImmutable targetLoc, ActionsBase ab, int trains, PowersBase pb) { AbstractPowerAction pa = ab.getPowerAction(); if (pa == null) { Logger.error( @@ -1978,6 +1977,22 @@ public enum PowersManager { + ab.getEffectID()); return; } + + if(AbstractCharacter.IsAbstractCharacter(awo)) { + boolean immune = false; + AbstractCharacter absChar = (AbstractCharacter)awo; + for (AbstractEffectModifier mod : ab.getPowerAction().getEffectsBase().getModifiers()) { + if (absChar.getBonuses() != null){ + if(absChar.getBonuses().getBool(ModType.ImmuneTo, mod.sourceType) || absChar.getBonuses().getBool(ModType.NoMod, mod.sourceType)) + immune = true; + } + } + + if(immune) + return; + } + + pa.startAction(source, awo, targetLoc, trains, ab, pb); } From d074aa8f1cb659796af94239daa233862ed9985b Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Mar 2025 18:17:50 -0600 Subject: [PATCH 149/151] fix for backstab --- src/engine/gameManager/PowersManager.java | 26 ++++++++++++------- .../handlers/RequestEnterWorldHandler.java | 16 +++++++++--- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index 5c9fff80..f0deebf3 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -199,6 +199,10 @@ public enum PowersManager { return; } + if(msg.getPowerUsedID() == -1851459567){//backstab + applyPower(pc,pc,pc.loc,-1851459567,msg.getNumTrains(),false); + } + if (usePowerA(msg, origin, sendCastToSelf)) { // Cast failed for some reason, reset timer @@ -1979,17 +1983,21 @@ public enum PowersManager { } if(AbstractCharacter.IsAbstractCharacter(awo)) { - boolean immune = false; - AbstractCharacter absChar = (AbstractCharacter)awo; - for (AbstractEffectModifier mod : ab.getPowerAction().getEffectsBase().getModifiers()) { - if (absChar.getBonuses() != null){ - if(absChar.getBonuses().getBool(ModType.ImmuneTo, mod.sourceType) || absChar.getBonuses().getBool(ModType.NoMod, mod.sourceType)) - immune = true; + try { + boolean immune = false; + AbstractCharacter absChar = (AbstractCharacter) awo; + for (AbstractEffectModifier mod : ab.getPowerAction().getEffectsBase().getModifiers()) { + if (absChar.getBonuses() != null) { + if (absChar.getBonuses().getBool(ModType.ImmuneTo, mod.sourceType) || absChar.getBonuses().getBool(ModType.NoMod, mod.sourceType)) + immune = true; + } } - } - if(immune) - return; + if (immune) + return; + }catch(Exception e){ + + } } diff --git a/src/engine/net/client/handlers/RequestEnterWorldHandler.java b/src/engine/net/client/handlers/RequestEnterWorldHandler.java index 18b48254..79f276a8 100644 --- a/src/engine/net/client/handlers/RequestEnterWorldHandler.java +++ b/src/engine/net/client/handlers/RequestEnterWorldHandler.java @@ -48,7 +48,7 @@ public class RequestEnterWorldHandler extends AbstractClientMsgHandler { PlayerCharacter player = origin.getPlayerCharacter(); - WorldGrid.RemoveWorldObject(player); + Dispatch dispatch; if (player == null) { @@ -57,6 +57,11 @@ public class RequestEnterWorldHandler extends AbstractClientMsgHandler { return true; } + //if(player.isEnteredWorld()){ + // if(player != null) { + // WorldGrid.RemoveWorldObject(player); + // } + //} player.setEnteredWorld(false); Account acc = SessionManager.getAccount(origin); @@ -106,9 +111,14 @@ public class RequestEnterWorldHandler extends AbstractClientMsgHandler { player.getTimestamps().put("EnterWorld", System.currentTimeMillis()); - if (player.getLoc().equals(Vector3fImmutable.ZERO) || System.currentTimeMillis() > player.getTimeStamp("logout") + (15 * 60 * 1000)) { + Long logout = player.getTimeStamp("logout"); + if (player.getLoc().equals(Vector3fImmutable.ZERO) || System.currentTimeMillis() > logout + (15 * 60 * 1000)) { player.stopMovement(player.getBindLoc()); - player.setSafeMode(); + try { + player.setSafeMode(); + }catch(Exception e){ + Logger.error(e); + } player.updateLocation(); player.setRegion(AbstractWorldObject.GetRegionByWorldObject(player)); } From cf6db2444cd931d6c139a5adca6d615fcfe9e74a Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Mar 2025 18:32:59 -0600 Subject: [PATCH 150/151] fix for backstab --- src/engine/gameManager/CombatManager.java | 2 +- src/engine/objects/PlayerCombatStats.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index de311023..51e95243 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -8,6 +8,7 @@ package engine.gameManager; +import engine.Enum; import engine.Enum.*; import engine.exception.MsgSendException; import engine.job.JobContainer; @@ -924,7 +925,6 @@ public enum CombatManager { damage *= 1 + (armorPierce * 0.01f); } } - //Resists.handleFortitude(tarAc,damageType,damage); float d = 0f; diff --git a/src/engine/objects/PlayerCombatStats.java b/src/engine/objects/PlayerCombatStats.java index f397e306..ec3e58b6 100644 --- a/src/engine/objects/PlayerCombatStats.java +++ b/src/engine/objects/PlayerCombatStats.java @@ -517,6 +517,7 @@ public class PlayerCombatStats { ); if(this.owner.bonuses != null){ minDMG += this.owner.bonuses.getFloat(Enum.ModType.MinDamage, Enum.SourceType.None); + minDMG += this.owner.bonuses.getFloat(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None); minDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None); } @@ -597,6 +598,7 @@ public class PlayerCombatStats { if(this.owner.bonuses != null){ maxDMG += this.owner.bonuses.getFloat(Enum.ModType.MaxDamage, Enum.SourceType.None); + maxDMG += this.owner.bonuses.getFloat(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None); maxDMG *= 1 + this.owner.bonuses.getFloatPercentAll(Enum.ModType.MeleeDamageModifier, Enum.SourceType.None); } From ef9c431d5e5e85cd3b4e07c9576071e3ba55eb29 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Mar 2025 18:37:46 -0600 Subject: [PATCH 151/151] fix for dodging spells --- src/engine/gameManager/PowersManager.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index f0deebf3..f121bdd3 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -2537,10 +2537,12 @@ public enum PowersManager { return true; } else if (testPassive(pc, tarAc, "Block")) { // Dodge fired, send dodge message - PerformActionMsg dodgeMsg = new PerformActionMsg(msg); - dodgeMsg.setTargetType(awo.getObjectType().ordinal()); - dodgeMsg.setTargetID(awo.getObjectUUID()); - sendPowerMsg(pc, 4, dodgeMsg); + //PerformActionMsg dodgeMsg = new PerformActionMsg(msg); + //dodgeMsg.setTargetType(awo.getObjectType().ordinal()); + //dodgeMsg.setTargetID(awo.getObjectUUID()); + //sendPowerMsg(pc, 4, dodgeMsg); + TargetedActionMsg cmm = new TargetedActionMsg(pc, 75, tarAc, MBServerStatics.COMBAT_SEND_BLOCK); + DispatchMessage.sendToAllInRange(tarAc, cmm); return true; } }