From fa5ac4fea3e5fccc45103df9491707ae11c0dada Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 15 May 2024 15:50:23 -0500 Subject: [PATCH 01/68] euro mines time changed up by 4 hours --- src/engine/objects/Mine.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index 1b65dedf..25d181f4 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -120,13 +120,13 @@ public class Mine extends AbstractGameObject { public static void SetTimes(){ try { - EuroMines.get(0).liveTime = 16; - EuroMines.get(1).liveTime = 16; - EuroMines.get(2).liveTime = 16; - EuroMines.get(3).liveTime = 16; - EuroMines.get(4).liveTime = 16; - EuroMines.get(5).liveTime = 16; - EuroMines.get(6).liveTime = 16; + EuroMines.get(0).liveTime = 20; + EuroMines.get(1).liveTime = 20; + EuroMines.get(2).liveTime = 20; + EuroMines.get(3).liveTime = 20; + EuroMines.get(4).liveTime = 20; + EuroMines.get(5).liveTime = 20; + EuroMines.get(6).liveTime = 20; }catch(Exception e){ } From a4efe199c6678fe1db03553e6dd29cf173e69af6 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 15 May 2024 15:54:19 -0500 Subject: [PATCH 02/68] saetor starting runes added --- src/engine/objects/PlayerCharacter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index e8f19335..4669c704 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -908,6 +908,8 @@ public class PlayerCharacter extends AbstractCharacter { case "Tough Hide": case "Fleet of Foot": case "Born in the Country": + case "Raised by Thieves' Guild": + case "Raised in the Woods": bypassCheck = true; break; } From e222cb354394b33ffd11ef28b0581cc1403a0c95 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 15 May 2024 17:00:16 -0500 Subject: [PATCH 03/68] zerg multiplier application work --- src/engine/gameManager/CombatManager.java | 11 ++----- .../effectmodifiers/HealthEffectModifier.java | 31 ++++++------------- .../effectmodifiers/ManaEffectModifier.java | 16 +++++----- .../StaminaEffectModifier.java | 17 +++++----- 4 files changed, 31 insertions(+), 44 deletions(-) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index 1f47a54d..709ff575 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -812,10 +812,6 @@ public enum CombatManager { float damage; damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists); - - //if(ac.getObjectType().equals(GameObjectType.PlayerCharacter) && target.getObjectType().equals(GameObjectType.PlayerCharacter)){ - // damage *= ZergManager.getReducedZergMultiplier((PlayerCharacter)ac,(PlayerCharacter)target); - //} float d = 0f; errorTrack = 12; @@ -844,9 +840,6 @@ public enum CombatManager { } mobTarget.handleDirectAggro(ac); } - if(ac.getObjectType().equals(GameObjectType.PlayerCharacter) && tarAc.getObjectType().equals(GameObjectType.PlayerCharacter) && tarAc.equals(ac) == false){ - damage *= ((PlayerCharacter)ac).ZergMultiplier; - } if (tarAc.getHealth() > 0) d = tarAc.modifyHealth(-damage, ac, false); subTrack = 5; @@ -1041,7 +1034,9 @@ public enum CombatManager { damage += minDamage; //calculate resists in if any - + if(source.getObjectType().equals(GameObjectType.PlayerCharacter)){ + damage *= ((PlayerCharacter)source).ZergMultiplier; + } if (resists != null) return resists.getResistedDamage(source, target, damageType, damage, 0); else diff --git a/src/engine/powers/effectmodifiers/HealthEffectModifier.java b/src/engine/powers/effectmodifiers/HealthEffectModifier.java index 4c3404b0..d6cf82e7 100644 --- a/src/engine/powers/effectmodifiers/HealthEffectModifier.java +++ b/src/engine/powers/effectmodifiers/HealthEffectModifier.java @@ -171,16 +171,21 @@ public class HealthEffectModifier extends AbstractEffectModifier { } if (modAmount == 0f) return; + if(source.getObjectType().equals(GameObjectType.PlayerCharacter)){ + modAmount *= ((PlayerCharacter)source).ZergMultiplier; + } + if(source.getObjectType().equals(GameObjectType.Mob)){ + Mob mob = (Mob)source; + if(mob.isPet() && mob.guardCaptain.getObjectType().equals(GameObjectType.PlayerCharacter)){ + modAmount *= ((PlayerCharacter)mob.guardCaptain).ZergMultiplier; + } + } if (AbstractWorldObject.IsAbstractCharacter(awo)) { AbstractCharacter ac = (AbstractCharacter) awo; if (!ac.isAlive()) return; - //if(ac.getObjectType().equals(GameObjectType.PlayerCharacter) && ac.combatTarget.getObjectType().equals(GameObjectType.PlayerCharacter)){ - // modAmount *= ZergManager.getReducedZergMultiplier((PlayerCharacter)ac,(PlayerCharacter)ac.combatTarget); - //} - int powerID = 0, effectID = 0; String powerName = ""; if (effect.getPower() != null) { @@ -199,15 +204,6 @@ public class HealthEffectModifier extends AbstractEffectModifier { //see if target is immune to heals if (modAmount > 0f) { boolean skipImmune = false; - // first tick of HoT going thru SM was removed in a later patch - /*if (effect.getAction().getPowerAction() instanceof DirectDamagePowerAction) { - ArrayList actions = effect.getPower().getActions(); - for (ActionsBase ab : actions) { - AbstractPowerAction apa = ab.getPowerAction(); - if (apa instanceof DamageOverTimePowerAction) - skipImmune = true; - } - }*/ PlayerBonuses bonus = ac.getBonuses(); if (!skipImmune && bonus.getFloat(ModType.BlackMantle, SourceType.Heal) >= trains) { @@ -318,15 +314,6 @@ public class HealthEffectModifier extends AbstractEffectModifier { AbstractCharacter ac = (AbstractCharacter) awo; if (ac.isSit()) damage *= 2.5f; // increase damage if sitting - if(source.getObjectType().equals(GameObjectType.PlayerCharacter)){ - damage *= ((PlayerCharacter)source).ZergMultiplier; - } - if(source.getObjectType().equals(GameObjectType.Mob) && ((Mob)source).isPet()){ - AbstractCharacter owner = ((Mob)source).guardCaptain; - if(owner.getObjectType().equals(GameObjectType.PlayerCharacter)){ - damage *= ((PlayerCharacter)owner).ZergMultiplier; - } - } } return damage; diff --git a/src/engine/powers/effectmodifiers/ManaEffectModifier.java b/src/engine/powers/effectmodifiers/ManaEffectModifier.java index ab9b63fd..4c00bebd 100644 --- a/src/engine/powers/effectmodifiers/ManaEffectModifier.java +++ b/src/engine/powers/effectmodifiers/ManaEffectModifier.java @@ -14,7 +14,6 @@ import engine.Enum.DamageType; import engine.Enum.ModType; import engine.Enum.SourceType; import engine.gameManager.ChatManager; -import engine.gameManager.ZergManager; import engine.jobs.AbstractEffectJob; import engine.jobs.DamageOverTimeJob; import engine.net.DispatchMessage; @@ -135,6 +134,15 @@ public class ManaEffectModifier extends AbstractEffectModifier { } if (modAmount == 0f) return; + if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ + modAmount *= ((PlayerCharacter)source).ZergMultiplier; + } + if(source.getObjectType().equals(Enum.GameObjectType.Mob)){ + Mob mob = (Mob)source; + if(mob.isPet() && mob.guardCaptain.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ + modAmount *= ((PlayerCharacter)mob.guardCaptain).ZergMultiplier; + } + } if (AbstractWorldObject.IsAbstractCharacter(awo)) { AbstractCharacter ac = (AbstractCharacter) awo; int powerID = 0, effectID = 0; @@ -158,9 +166,6 @@ public class ManaEffectModifier extends AbstractEffectModifier { skipImmune = true; } } - //if(ac.getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && ac.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ - // modAmount *= ZergManager.getReducedZergMultiplier((PlayerCharacter)ac,(PlayerCharacter)ac.combatTarget); - //} PlayerBonuses bonus = ac.getBonuses(); if (!skipImmune && bonus.getFloat(ModType.BlackMantle, SourceType.Heal) >= trains) { ModifyHealthMsg mhm = new ModifyHealthMsg(source, ac, 0f, 0f, 0f, powerID, powerName, trains, effectID); @@ -207,9 +212,6 @@ public class ManaEffectModifier extends AbstractEffectModifier { AbstractCharacter ac = (AbstractCharacter) awo; if (ac.isSit()) damage *= 2.5f; // increase damage if sitting - if(ac.getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && !source.equals(ac)){ - damage *= ((PlayerCharacter)source).ZergMultiplier; - } } return damage; diff --git a/src/engine/powers/effectmodifiers/StaminaEffectModifier.java b/src/engine/powers/effectmodifiers/StaminaEffectModifier.java index 1f33822e..2b0896d1 100644 --- a/src/engine/powers/effectmodifiers/StaminaEffectModifier.java +++ b/src/engine/powers/effectmodifiers/StaminaEffectModifier.java @@ -14,7 +14,6 @@ import engine.Enum.DamageType; import engine.Enum.ModType; import engine.Enum.SourceType; import engine.gameManager.ChatManager; -import engine.gameManager.ZergManager; import engine.jobs.AbstractEffectJob; import engine.jobs.DamageOverTimeJob; import engine.net.DispatchMessage; @@ -131,6 +130,16 @@ public class StaminaEffectModifier extends AbstractEffectModifier { } if (modAmount == 0f) return; + if(source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ + modAmount *= ((PlayerCharacter)source).ZergMultiplier; + } + if(source.getObjectType().equals(Enum.GameObjectType.Mob)){ + Mob mob = (Mob)source; + if(mob.isPet() && mob.guardCaptain.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ + modAmount *= ((PlayerCharacter)mob.guardCaptain).ZergMultiplier; + } + } + if (AbstractWorldObject.IsAbstractCharacter(awo)) { AbstractCharacter ac = (AbstractCharacter) awo; int powerID = 0, effectID = 0; @@ -154,9 +163,6 @@ public class StaminaEffectModifier extends AbstractEffectModifier { skipImmune = true; } } - //if(ac.getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && ac.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ - // modAmount *= ZergManager.getReducedZergMultiplier((PlayerCharacter)ac,(PlayerCharacter)ac.combatTarget); - //} PlayerBonuses bonus = ac.getBonuses(); if (!skipImmune && bonus.getFloat(ModType.BlackMantle, SourceType.Heal) >= trains) { ModifyHealthMsg mhm = new ModifyHealthMsg(source, ac, 0f, 0f, 0f, powerID, powerName, trains, effectID); @@ -205,9 +211,6 @@ public class StaminaEffectModifier extends AbstractEffectModifier { AbstractCharacter ac = (AbstractCharacter) awo; if (ac.isSit()) damage *= 2.5f; // increase damage if sitting - if(ac.getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && !source.equals(ac)){ - damage *= ((PlayerCharacter)source).ZergMultiplier; - } } return damage; From 59592090810f3fe41945c728a82b494080896d11 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 15 May 2024 17:33:14 -0500 Subject: [PATCH 04/68] fly work --- src/engine/gameManager/MovementManager.java | 1 - src/engine/objects/PlayerCharacter.java | 18 ------------------ 2 files changed, 19 deletions(-) diff --git a/src/engine/gameManager/MovementManager.java b/src/engine/gameManager/MovementManager.java index f38b502e..14f5f35d 100644 --- a/src/engine/gameManager/MovementManager.java +++ b/src/engine/gameManager/MovementManager.java @@ -71,7 +71,6 @@ public enum MovementManager { ((PlayerCharacter) toMove).update(); } - toMove.setIsCasting(false); toMove.setItemCasting(false); diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 4669c704..f9aff3f3 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -4829,24 +4829,6 @@ public class PlayerCharacter extends AbstractCharacter { if (!this.isAlive()) return; - if(this.isFlying()){ - if (this.containsEffect(487604089)) { - PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 57584498, 40, false); - } - if (this.containsEffect(296836988)) { - PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 57584498, 40, false); - } - if (this.containsEffect(163174641)) { - PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 57584498, 40, false); - } - if (this.containsEffect(163419371)) { - PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 57584498, 40, false); - } - if (this.containsEffect(79883622)) { - PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 57584498, 40, false); - } - } - updateLocation(); updateMovementState(); updateRegen(); From e3a278e09092032f6d9c946b6e4e7939641dd95e Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 15 May 2024 17:43:13 -0500 Subject: [PATCH 05/68] moving in the air with movebuff will result in immediate ground --- src/engine/gameManager/MovementManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/engine/gameManager/MovementManager.java b/src/engine/gameManager/MovementManager.java index 14f5f35d..5def9688 100644 --- a/src/engine/gameManager/MovementManager.java +++ b/src/engine/gameManager/MovementManager.java @@ -69,6 +69,8 @@ public enum MovementManager { if (toMove.getObjectType().equals(GameObjectType.PlayerCharacter)) { if (((PlayerCharacter) toMove).isCasting()) ((PlayerCharacter) toMove).update(); + if(((PlayerCharacter) toMove).isFlying() && toMove.getEffects().containsKey("MoveBuff")) + PlayerCharacter.GroundPlayer(((PlayerCharacter) toMove)); } toMove.setIsCasting(false); From a943a5a51dfe948b6af5d4ef64e1d54523079ea3 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 15 May 2024 20:42:28 -0500 Subject: [PATCH 06/68] update saetor stats --- src/engine/devcmd/cmds/PrintStatsCmd.java | 1 + src/engine/objects/Race.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/engine/devcmd/cmds/PrintStatsCmd.java b/src/engine/devcmd/cmds/PrintStatsCmd.java index 2d8f5c96..e8046a9d 100644 --- a/src/engine/devcmd/cmds/PrintStatsCmd.java +++ b/src/engine/devcmd/cmds/PrintStatsCmd.java @@ -56,6 +56,7 @@ public class PrintStatsCmd extends AbstractDevCmd { } public void printStatsPlayer(PlayerCharacter pc, PlayerCharacter tar) { + tar.calculateMaxHealthManaStamina(); String newline = "\r\n "; String out = "Server stats for Player " + tar.getFirstName() + newline; out += "Unused Stats: " + tar.getUnusedStatPoints() + newline; diff --git a/src/engine/objects/Race.java b/src/engine/objects/Race.java index ce994482..b655e434 100644 --- a/src/engine/objects/Race.java +++ b/src/engine/objects/Race.java @@ -163,7 +163,7 @@ public class Race { skillsGrantedSaetor.add(new SkillReq(27, (short) 1)); // parry ArrayList powersGrantedSaetor = new ArrayList<>(); ArrayList effectsListSaetor = new ArrayList<>(); - Race saetor = new Race(1999,"Saetor","Half goat half man, the Saetor race does the bidding of the Choas Gods.",new Vector3f(35,30,85),new Vector3f(55,50,120),new Vector3f(50,45,115),new Vector3f(45,40,110),new Vector3f(35,30,85),(byte)20,19991999,(short)0,(short)0,5.0f,(short)0,baseClassesSaetor,skillsGrantedSaetor,powersGrantedSaetor,effectsListSaetor); + Race saetor = new Race(1999,"Saetor","Half goat half man, the Saetor race does the bidding of the Choas Gods.",new Vector3f(35,30,85),new Vector3f(55,50,120),new Vector3f(50,45,115),new Vector3f(45,40,110),new Vector3f(35,30,85),(byte)20,19991999,(short)20,(short)70,5.0f,(short)10,baseClassesSaetor,skillsGrantedSaetor,powersGrantedSaetor,effectsListSaetor); Race._raceByID.put(1999,saetor); } From 910a5d9e3cebfa605fe3707a68327d571ce9f854 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 15 May 2024 21:21:35 -0500 Subject: [PATCH 07/68] prospector costs 500k --- src/engine/objects/Contract.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/engine/objects/Contract.java b/src/engine/objects/Contract.java index f1736f78..4b1f3b76 100644 --- a/src/engine/objects/Contract.java +++ b/src/engine/objects/Contract.java @@ -210,6 +210,15 @@ public class Contract extends AbstractGameObject { } return returnList; } + if(this.getObjectUUID() == 900){ + for(MobEquipment me : this.sellInventory){ + if(me.getItemBase().getName().equals("Prospector")){ + me.magicValue = 500; + } else{ + me.magicValue = 1000; + } + } + } return this.sellInventory; } From 742232166e5a8f1106de205fb684dd70ca16c132 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 15 May 2024 21:32:01 -0500 Subject: [PATCH 08/68] prospector cost reduced to 500k on disc merchant --- src/engine/net/client/ClientMessagePump.java | 2 ++ src/engine/objects/Contract.java | 2 +- src/engine/objects/MobEquipment.java | 9 +++++++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/engine/net/client/ClientMessagePump.java b/src/engine/net/client/ClientMessagePump.java index a7864bcb..54cbc291 100644 --- a/src/engine/net/client/ClientMessagePump.java +++ b/src/engine/net/client/ClientMessagePump.java @@ -1422,6 +1422,8 @@ public class ClientMessagePump implements NetMsgHandler { return; } int cost = me.magicValue; + if(npc.getContractID() == 1201 && me.getItemBase().getName().equals("Prospector")) + cost = 50; int resourceCost = Warehouse.getCostForResource(me.getItemBase().getUUID()); if (resourceCost != 0) cost = resourceCost; diff --git a/src/engine/objects/Contract.java b/src/engine/objects/Contract.java index 4b1f3b76..627a9c2d 100644 --- a/src/engine/objects/Contract.java +++ b/src/engine/objects/Contract.java @@ -213,7 +213,7 @@ public class Contract extends AbstractGameObject { if(this.getObjectUUID() == 900){ for(MobEquipment me : this.sellInventory){ if(me.getItemBase().getName().equals("Prospector")){ - me.magicValue = 500; + me.magicValue = 50; } else{ me.magicValue = 1000; } diff --git a/src/engine/objects/MobEquipment.java b/src/engine/objects/MobEquipment.java index f2a81405..52156693 100644 --- a/src/engine/objects/MobEquipment.java +++ b/src/engine/objects/MobEquipment.java @@ -112,8 +112,13 @@ public class MobEquipment extends AbstractGameObject { writer.putInt((int)(mobEquipment.itemBase.getBaseValue() * 0.5f)); writer.putInt((int)(mobEquipment.itemBase.getBaseValue() * 0.5f)); }else { - writer.putInt(mobEquipment.magicValue); - writer.putInt(mobEquipment.magicValue); + if(mobEquipment.itemBase.getName().equals("Prospector")){ + writer.putInt(50); + writer.putInt(50); + }else { + writer.putInt(mobEquipment.magicValue); + writer.putInt(mobEquipment.magicValue); + } } } From e560c07aba054ef43587e9e7eb46a98bad33020f Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 15 May 2024 21:43:29 -0500 Subject: [PATCH 09/68] track chaining for same nations --- src/engine/gameManager/PowersManager.java | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/engine/gameManager/PowersManager.java b/src/engine/gameManager/PowersManager.java index 38afeb55..43e0e7e4 100644 --- a/src/engine/gameManager/PowersManager.java +++ b/src/engine/gameManager/PowersManager.java @@ -1577,7 +1577,7 @@ public enum PowersManager { trackChars = new HashSet<>(); HashSet allInRange = WorldGrid.getObjectsInRangePartial(playerCharacter.loc,MBServerStatics.CHARACTER_LOAD_RANGE,MBServerStatics.MASK_PLAYER); - ArrayList nationsInRange = new ArrayList<>(); + //ArrayList nationsInRange = new ArrayList<>(); ArrayList purgeList = new ArrayList<>(); for(AbstractWorldObject trackChar : allInRange) { if(trackChar.equals(playerCharacter) || !trackChar.isAlive() || !((PlayerCharacter)trackChar).isActive()) @@ -1592,24 +1592,24 @@ public enum PowersManager { continue; if(allInRange.contains(trackChar)) { trackChars.add((AbstractCharacter)trackChar); - Guild nation = ((AbstractCharacter)trackChar).guild.getNation(); - if(nationsInRange.contains(nation) == false) - nationsInRange.add(nation); } } - //second round add all others in window if they share a nation with a current - for(AbstractWorldObject trackChar : allInRange) { + //track full range for chaining nation members + ArrayList nationsInRange = new ArrayList<>(); + for(AbstractCharacter pc : trackChars){ + if(nationsInRange.contains(pc.guild.getNation()) == false) + nationsInRange.add(pc.guild.getNation()); + } + HashSet fullRange = WorldGrid.getObjectsInRangePartial(playerCharacter.loc,1024,MBServerStatics.MASK_PLAYER); + for(AbstractWorldObject trackChar : fullRange) { if(trackChar.equals(playerCharacter) || !trackChar.isAlive() || !((PlayerCharacter)trackChar).isActive()) continue; - - Guild nation = ((AbstractCharacter) trackChar).guild.getNation(); - if (allInRange.contains(trackChar) == true && nationsInRange.add(nation) == true && trackChars.contains(trackChar) == false) - trackChars.add((AbstractCharacter) trackChar); - else if(((AbstractCharacter) trackChar).guild.getNation().equals(playerCharacter.guild.getNation())) - trackChars.add((AbstractCharacter) trackChar); + if(nationsInRange.contains(((PlayerCharacter) trackChar).guild.getNation()) && trackChars.contains(trackChar) == false) + trackChars.add((AbstractCharacter)trackChar); } + TrackWindowMsg trackWindowMsg = new TrackWindowMsg(msg); // send track window From 72faafedfecd1e705325f0d709d4d9b7c97b9851 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Fri, 17 May 2024 23:14:15 -0500 Subject: [PATCH 10/68] resource merchant --- src/engine/objects/Contract.java | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/engine/objects/Contract.java b/src/engine/objects/Contract.java index 627a9c2d..e18efab9 100644 --- a/src/engine/objects/Contract.java +++ b/src/engine/objects/Contract.java @@ -198,25 +198,10 @@ public class Contract extends AbstractGameObject { } public ArrayList getSellInventory() { - if(this.getObjectUUID() == 900){ - ArrayList returnList = new ArrayList<>(); - for (int resourceID : Warehouse.getMaxResources().keySet()) { - //MobLoot resource = new MobLoot(resourceMerchant,ItemBase.getItemBase(resourceID),1,false); - //resource.magicValue = Warehouse.getCostForResource(resourceID); - ItemBase ib = ItemBase.getItemBase(resourceID); - MobEquipment resource = new MobEquipment(ib, 0,0); - resource.magicValue = Warehouse.getCostForResource(resourceID); - returnList.add(resource); - } - return returnList; - } + if(this.getObjectUUID() == 900){ for(MobEquipment me : this.sellInventory){ - if(me.getItemBase().getName().equals("Prospector")){ - me.magicValue = 50; - } else{ - me.magicValue = 1000; - } + me.magicValue = Warehouse.getCostForResource(me.getItemBase().getUUID()); } } return this.sellInventory; From 7bd6e3a1490c2d1422d3d520a92713ecdb103004 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 15 May 2024 16:46:00 -0500 Subject: [PATCH 11/68] mob AI message cleanup --- src/engine/mobileAI/MobAI.java | 456 +++--------------- .../mobileAI/utilities/CombatUtilities.java | 212 ++++++++ .../mobileAI/utilities/MovementUtilities.java | 9 - src/engine/objects/AbstractCharacter.java | 17 - 4 files changed, 282 insertions(+), 412 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index 571532a0..a9c8b992 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -18,17 +18,16 @@ import engine.mobileAI.Threads.MobAIThread; import engine.mobileAI.utilities.CombatUtilities; import engine.mobileAI.utilities.MovementUtilities; import engine.net.DispatchMessage; -import engine.net.client.msg.PerformActionMsg; import engine.net.client.msg.PowerProjectileMsg; +import engine.net.client.msg.UpdateStateMsg; import engine.objects.*; -import engine.powers.ActionsBase; import engine.powers.PowersBase; import engine.server.MBServerStatics; import org.pmw.tinylog.Logger; -import java.util.ArrayList; import java.util.HashSet; import java.util.Map.Entry; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ThreadLocalRandom; @@ -54,18 +53,6 @@ public class MobAI { return; } } - if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) { - - if (mob.isPlayerGuard() == false && MobCast(mob)) { - mob.updateLocation(); - return; - } - - if (mob.isPlayerGuard() == true && GuardCast(mob)) { - mob.updateLocation(); - return; - } - } if (!CombatUtilities.inRangeToAttack(mob, target)) return; @@ -85,8 +72,6 @@ public class MobAI { break; } - mob.updateLocation(); - } catch (Exception e) { Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage()); } @@ -148,7 +133,7 @@ public class MobAI { } if (target.getPet() != null) - if (target.getPet().getCombatTarget() == null && target.getPet().assist == true) + if (target.getPet().getCombatTarget() == null && target.getPet().assist) target.getPet().setCombatTarget(mob); } catch (Exception e) { @@ -251,7 +236,7 @@ public class MobAI { if(target.isAlive()) target.setCombatTarget(mob); - if(target.isPet() && target.isAlive() == false && target.guardCaptain.isAlive() == true){ + if(target.isPet() && !target.isAlive() && target.guardCaptain.isAlive()){ mob.setCombatTarget(target.guardCaptain); } if(mob.isPet()){ @@ -272,7 +257,7 @@ public class MobAI { //early exit while waiting to patrol again - if (mob.stopPatrolTime + (patrolDelay * 1000) > System.currentTimeMillis()) + if (mob.stopPatrolTime + (patrolDelay * 1000L) > System.currentTimeMillis()) return; //guard captains inherit barracks patrol points dynamically @@ -302,7 +287,7 @@ public class MobAI { //make sure mob is out of combat stance - if (minion.getKey().despawned == false) { + if (!minion.getKey().despawned) { if (MovementUtilities.canMove(minion.getKey())) { Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3); minion.getKey().updateLocation(); @@ -315,253 +300,6 @@ public class MobAI { } } - public static boolean canCast(Mob mob) { - return false; - //try { - - // Performs validation to determine if a - // mobile in the proper state to cast. - - //if (mob == null) - // return false; - - //if(mob.isPlayerGuard == true){ - - /// int contractID; - - // if (mob.behaviourType.equals(Enum.MobBehaviourType.GuardMinion)) - // contractID = mob.guardCaptain.contract.getContractID(); - // else - // contractID = mob.contract.getContractID(); - - // if(Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false) - // return false; - //} - - //if (mob.mobPowers.isEmpty()) - // return false; - - //if (!mob.canSee((PlayerCharacter) mob.getCombatTarget())) { - // mob.setCombatTarget(null); - // return false; - // } - // if (mob.nextCastTime == 0) - // mob.nextCastTime = System.currentTimeMillis(); - - // return mob.nextCastTime >= System.currentTimeMillis(); - - //} catch (Exception e) { - // Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: canCast" + " " + e.getMessage()); - //} - //return false; - } - - public static boolean MobCast(Mob mob) { - - try { - // Method picks a random spell from a mobile's list of powers - // and casts it on the current target (or itself). Validation - // (including empty lists) is done previously within canCast(); - - ArrayList powerTokens; - ArrayList purgeTokens; - AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget(); - - if (mob.behaviourType.callsForHelp) - MobCallForHelp(mob); - - // Generate a list of tokens from the mob powers for this mobile. - - powerTokens = new ArrayList<>(mob.mobPowers.keySet()); - purgeTokens = new ArrayList<>(); - - // If player has this effect on them currently then remove - // this token from our list. - - for (int powerToken : powerTokens) { - - PowersBase powerBase = PowersManager.getPowerByToken(powerToken); - - for (ActionsBase actionBase : powerBase.getActions()) { - - String stackType = actionBase.stackType; - - if (target.getEffects() != null && target.getEffects().containsKey(stackType)) - purgeTokens.add(powerToken); - } - } - - powerTokens.removeAll(purgeTokens); - - // Sanity check - - if (powerTokens.isEmpty()) - return false; - - // Pick random spell from our list of powers - - int powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); - int powerRank = mob.mobPowers.get(powerToken); - - PowersBase mobPower = PowersManager.getPowerByToken(powerToken); - - //check for hit-roll - - if (mobPower.requiresHitRoll) - if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget())) - return false; - - // Cast the spell - - if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) { - - PerformActionMsg msg; - - if (!mobPower.isHarmful() || mobPower.targetSelf) { - PowersManager.useMobPower(mob, mob, mobPower, powerRank); - msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob); - } else { - PowersManager.useMobPower(mob, target, mobPower, powerRank); - msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); - } - - msg.setUnknown04(2); - - PowersManager.finishUseMobPower(msg, mob, 0, 0); - long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY); - - mob.nextCastTime = System.currentTimeMillis() + randomCooldown; - return true; - } - } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage()); - } - return false; - } - - public static boolean GuardCast(Mob mob) { - - try { - // Method picks a random spell from a mobile's list of powers - // and casts it on the current target (or itself). Validation - // (including empty lists) is done previously within canCast(); - - ArrayList powerTokens; - ArrayList purgeTokens; - AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget(); - - if (mob.behaviourType.callsForHelp) - MobCallForHelp(mob); - - // Generate a list of tokens from the mob powers for this mobile. - - powerTokens = new ArrayList<>(mob.mobPowers.keySet()); - purgeTokens = new ArrayList<>(); - - // If player has this effect on them currently then remove - // this token from our list. - - for (int powerToken : powerTokens) { - - PowersBase powerBase = PowersManager.getPowerByToken(powerToken); - - for (ActionsBase actionBase : powerBase.getActions()) { - - String stackType = actionBase.stackType; - - if (target.getEffects() != null && target.getEffects().containsKey(stackType)) - purgeTokens.add(powerToken); - } - } - - powerTokens.removeAll(purgeTokens); - - // Sanity check - - if (powerTokens.isEmpty()) - return false; - - int powerToken = 0; - int nukeRoll = ThreadLocalRandom.current().nextInt(1,100); - - if (nukeRoll < 55) { - - //use direct damage spell - powerToken = powerTokens.get(powerTokens.size() - 1); - - } else { - //use random spell - powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); - } - - int powerRank = 1; - - switch(mob.getRank()){ - case 1: - powerRank = 10; - break; - case 2: - powerRank = 15; - break; - case 3: - powerRank = 20; - break; - case 4: - powerRank = 25; - break; - case 5: - powerRank = 30; - break; - case 6: - powerRank = 35; - break; - case 7: - powerRank = 40; - break; - } - - PowersBase mobPower = PowersManager.getPowerByToken(powerToken); - - //check for hit-roll - - if (mobPower.requiresHitRoll) - if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget())) - return false; - - // Cast the spell - - if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) { - - PerformActionMsg msg; - - if (!mobPower.isHarmful() || mobPower.targetSelf) { - - if (mobPower.category.equals("DISPEL")) { - PowersManager.useMobPower(mob, target, mobPower, powerRank); - msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); - } else { - PowersManager.useMobPower(mob, mob, mobPower, powerRank); - msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob); - } - } else { - PowersManager.useMobPower(mob, target, mobPower, powerRank); - msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); - } - - msg.setUnknown04(2); - - PowersManager.finishUseMobPower(msg, mob, 0, 0); - - long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY); - mob.nextCastTime = System.currentTimeMillis() + randomCooldown; - return true; - } - } catch (Exception e) { - Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage()); - } - return false; - } - public static void MobCallForHelp(Mob mob) { try { @@ -606,7 +344,7 @@ public class MobAI { if (mob == null) return; - if (mob.getTimestamps().containsKey("lastExecution") == false) + if (!mob.getTimestamps().containsKey("lastExecution")) mob.getTimestamps().put("lastExecution", System.currentTimeMillis()); if (System.currentTimeMillis() < mob.getTimeStamp("lastExecution")) @@ -626,11 +364,11 @@ public class MobAI { if (mob.despawned && mob.isPlayerGuard) { if (mob.behaviourType.equals(Enum.MobBehaviourType.GuardMinion)) { - if (mob.guardCaptain.isAlive() == false || ((Mob) mob.guardCaptain).despawned == true) { + if (!mob.guardCaptain.isAlive() || ((Mob) mob.guardCaptain).despawned) { //minions don't respawn while guard captain is dead - if (mob.isAlive() == false) { + if (!mob.isAlive()) { mob.deathTime = System.currentTimeMillis(); return; } @@ -642,7 +380,7 @@ public class MobAI { //check to send mob home for player guards to prevent exploit of dragging guards away and then teleporting - if (mob.behaviourType.equals(Enum.MobBehaviourType.Pet1) == false) + if (!mob.behaviourType.equals(Enum.MobBehaviourType.Pet1)) CheckToSendMobHome(mob); return; @@ -662,7 +400,7 @@ public class MobAI { HashSet players = WorldGrid.getObjectsInRangePartial(mob.loc, mob.getAggroRange(), MBServerStatics.MASK_PLAYER); if(players.size() > 0){ for(AbstractWorldObject player : players){ - if(mob.playerAgroMap.containsKey(player.getObjectUUID()) == false) { + if(!mob.playerAgroMap.containsKey(player.getObjectUUID())) { PlayerCharacter pc = (PlayerCharacter) player; mob.playerAgroMap.put(pc.getObjectUUID(), 0.0f); } @@ -674,12 +412,12 @@ public class MobAI { return; } - if (mob.behaviourType.equals(Enum.MobBehaviourType.Pet1) == false) + if (!mob.behaviourType.equals(Enum.MobBehaviourType.Pet1)) CheckToSendMobHome(mob); if (mob.getCombatTarget() != null) { - if (mob.getCombatTarget().isAlive() == false) { + if (!mob.getCombatTarget().isAlive()) { mob.setCombatTarget(null); return; } @@ -688,18 +426,35 @@ public class MobAI { PlayerCharacter target = (PlayerCharacter) mob.getCombatTarget(); - if (mob.playerAgroMap.containsKey(target.getObjectUUID()) == false) { + if (!mob.playerAgroMap.containsKey(target.getObjectUUID())) { mob.setCombatTarget(null); return; } - if (mob.canSee((PlayerCharacter) mob.getCombatTarget()) == false) { + if (!mob.canSee((PlayerCharacter) mob.getCombatTarget())) { mob.setCombatTarget(null); return; } } } + if (mob.isMoving()) { + mob.updateLocation(); + } + boolean combatState = mob.isCombat(); + mob.setCombat(mob.combatTarget != null); + if(combatState != mob.isCombat()){ + //send message to update combat state + UpdateStateMsg rwss = new UpdateStateMsg(); + rwss.setPlayer(mob); + DispatchMessage.sendToAllInRange(mob, rwss); + } + boolean walking = mob.isWalk(); + mob.setWalkMode(mob.combatTarget == null); + if(walking != mob.isWalk()){ + //send message to update run/walk state + MovementManager.sendRWSSMsg(mob); + } switch (mob.behaviourType) { case GuardCaptain: @@ -738,22 +493,21 @@ public class MobAI { if(!pets) { ConcurrentHashMap loadedPlayers = aiAgent.playerAgroMap; - for (Entry playerEntry : loadedPlayers.entrySet()) { + for (Integer playerEntry : loadedPlayers.keySet()) { - int playerID = (int) playerEntry.getKey(); - PlayerCharacter loadedPlayer = PlayerCharacter.getFromCache(playerID); + PlayerCharacter loadedPlayer = PlayerCharacter.getFromCache(playerEntry); //Player is null, let's remove them from the list. if (loadedPlayer == null) { - loadedPlayers.remove(playerID); + loadedPlayers.remove(playerEntry); continue; } //Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map. if (!loadedPlayer.isAlive() || loadedPlayer.getHidden() > 0) { - loadedPlayers.remove(playerID); + loadedPlayers.remove(playerEntry); continue; } @@ -764,12 +518,12 @@ public class MobAI { // 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)) { @@ -806,27 +560,27 @@ public class MobAI { return; try { + if(mob == null) + return; if (!MovementUtilities.canMove(mob)) return; - mob.updateLocation(); - switch (mob.behaviourType) { case Pet1: - if ((PlayerCharacter) mob.guardCaptain == null) + if (mob.guardCaptain == null) return; - if (!mob.playerAgroMap.containsKey(((PlayerCharacter) mob.guardCaptain).getObjectUUID())) { + if (!mob.playerAgroMap.containsKey(mob.guardCaptain.getObjectUUID())) { //mob no longer has its owner loaded, translocate pet to owner - MovementManager.translocate(mob, ((PlayerCharacter) mob.guardCaptain).getLoc(), null); + MovementManager.translocate(mob, mob.guardCaptain.getLoc(), null); return; } if (mob.getCombatTarget() == null) { @@ -834,11 +588,11 @@ public class MobAI { //move back to owner - if (CombatUtilities.inRange2D(mob, (PlayerCharacter) mob.guardCaptain, 6)) + if (CombatUtilities.inRange2D(mob, mob.guardCaptain, 6)) return; - mob.destination = ((PlayerCharacter) mob.guardCaptain).getLoc(); + mob.destination = mob.guardCaptain.getLoc(); MovementUtilities.moveToLocation(mob, mob.destination, 5); } else chaseTarget(mob); @@ -886,7 +640,6 @@ public class MobAI { if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_WITH_LOOT) { aiAgent.despawn(); aiAgent.deathTime = System.currentTimeMillis(); - return; } //No items in inventory. } else { @@ -895,14 +648,12 @@ public class MobAI { if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) { aiAgent.despawn(); aiAgent.deathTime = System.currentTimeMillis(); - return; } //Mob never had Loot. } else { if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER) { aiAgent.despawn(); aiAgent.deathTime = System.currentTimeMillis(); - return; } } } @@ -922,14 +673,14 @@ public class MobAI { //checks if mob can attack based on attack timer and range - if (mob.isAlive() == false) + if (!mob.isAlive()) return; if (mob.getCombatTarget() == null) return; - if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false && - mob.behaviourType.equals(Enum.MobBehaviourType.Pet1) == false) { + if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && !MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) && + !mob.behaviourType.equals(Enum.MobBehaviourType.Pet1)) { mob.setCombatTarget(null); return; @@ -955,14 +706,11 @@ public class MobAI { } } - //if (mob.getCombatTarget() != null && CombatUtilities.inRange2D(mob, mob.getCombatTarget(), MobAIThread.AI_BASE_AGGRO_RANGE * 0.5f)) - //return; - if (mob.isPlayerGuard() && !mob.despawned) { City current = ZoneManager.getCityAtLocation(mob.getLoc()); - if (current == null || current.equals(mob.getGuild().getOwnedCity()) == false) { + if (current == null || !current.equals(mob.getGuild().getOwnedCity())) { PowersBase recall = PowersManager.getPowerByToken(-1994153779); PowersManager.useMobPower(mob, mob, recall, 40); @@ -978,14 +726,13 @@ public class MobAI { } } } - } else if (MovementUtilities.inRangeOfBindLocation(mob) == false) { + } else if (!MovementUtilities.inRangeOfBindLocation(mob)) { PowersBase recall = PowersManager.getPowerByToken(-1994153779); PowersManager.useMobPower(mob, mob, recall, 40); mob.setCombatTarget(null); - for (Integer playerEntry : mob.playerAgroMap.keySet()) - mob.playerAgroMap.put(playerEntry,0f); + mob.playerAgroMap.replaceAll((e, v) -> 0f); } } catch (Exception e) { Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome" + " " + e.getMessage()); @@ -1004,10 +751,10 @@ public class MobAI { float rangeSquared = mob.getRange() * mob.getRange(); float distanceSquared = mob.getLoc().distanceSquared2D(mob.getCombatTarget().getLoc()); - if(mob.isMoving() == true && distanceSquared < rangeSquared - 50) { + if(mob.isMoving() && distanceSquared < rangeSquared - 50) { mob.destination = mob.getLoc(); MovementUtilities.moveToLocation(mob, mob.destination, 0); - } else if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { + } else if (!CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange())) { if (mob.getRange() > 15) { mob.destination = mob.getCombatTarget().getLoc(); MovementUtilities.moveToLocation(mob, mob.destination, 0); @@ -1029,7 +776,6 @@ public class MobAI { } } mob.updateMovementState(); - mob.updateLocation(); } catch (Exception e) { Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: chaseTarget" + " " + e.getMessage()); } @@ -1044,7 +790,7 @@ public class MobAI { //dont scan self. - if (mob.equals(awoMob) || (mob.agentType.equals(Enum.AIAgentType.GUARD)) == true || awoMob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) + if (mob.equals(awoMob) || (mob.agentType.equals(Enum.AIAgentType.GUARD)) || awoMob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) continue; Mob aggroMob = (Mob) awoMob; @@ -1073,18 +819,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) { @@ -1099,19 +833,6 @@ public class MobAI { if (mob.getCombatTarget() == null) { CheckForPlayerGuardAggro(mob); - } else { - - 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); - - } } }else { if (mob.guardCaptain.getCombatTarget() != null) @@ -1143,7 +864,7 @@ public class MobAI { try { - if (mob.guardCaptain == null && mob.isNecroPet() == false && mob.isSiege() == false) + if (mob.guardCaptain == null && !mob.isNecroPet() && !mob.isSiege()) if (ZoneManager.getSeaFloor().zoneMobSet.contains(mob)) mob.killCharacter("no owner"); @@ -1154,7 +875,7 @@ public class MobAI { //recover health - if (mob.getTimestamps().containsKey("HEALTHRECOVERED") == false) + if (!mob.getTimestamps().containsKey("HEALTHRECOVERED")) mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis()); if (mob.isSit() && mob.getTimeStamp("HEALTHRECOVERED") < System.currentTimeMillis() + 3000) @@ -1179,7 +900,7 @@ public class MobAI { if (mob.getCombatTarget() == null) SafeGuardAggro(mob); - else if (mob.getCombatTarget().isAlive() == false) + else if (!mob.getCombatTarget().isAlive()) SafeGuardAggro(mob); CheckForAttack(mob); @@ -1194,7 +915,7 @@ public class MobAI { if(mob.combatTarget != null && mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ PlayerCharacter tar = (PlayerCharacter)mob.combatTarget; - if (mob.canSee(tar) == false) { + if (!mob.canSee(tar)) { mob.setCombatTarget(null); } } @@ -1245,22 +966,21 @@ public class MobAI { ConcurrentHashMap loadedPlayers = mob.playerAgroMap; - for (Entry playerEntry : loadedPlayers.entrySet()) { + for (Integer playerEntry : loadedPlayers.keySet()) { - int playerID = (int) playerEntry.getKey(); - PlayerCharacter loadedPlayer = PlayerCharacter.getFromCache(playerID); + PlayerCharacter loadedPlayer = PlayerCharacter.getFromCache(playerEntry); //Player is null, let's remove them from the list. if (loadedPlayer == null) { - loadedPlayers.remove(playerID); + loadedPlayers.remove(playerEntry); continue; } //Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map. if (!loadedPlayer.isAlive()) { - loadedPlayers.remove(playerID); + loadedPlayers.remove(playerEntry); continue; } @@ -1271,7 +991,7 @@ public class MobAI { // No aggro for this player - if (GuardCanAggro(mob, loadedPlayer) == false) + if (!GuardCanAggro(mob, loadedPlayer)) continue; if (MovementUtilities.inRangeToAggro(mob, loadedPlayer) && mob.getCombatTarget() == null) { @@ -1292,17 +1012,17 @@ public class MobAI { return false; if (mob.behaviourType.equals(Enum.MobBehaviourType.GuardMinion)) { - if (((Mob) mob.guardCaptain).building.getCity().cityOutlaws.contains(target.getObjectUUID()) == true) { + if (Objects.requireNonNull(mob.guardCaptain.building.getCity()).cityOutlaws.contains(target.getObjectUUID())) { return true; } - } else if (mob.building.getCity().cityOutlaws.contains(target.getObjectUUID()) == true) { + } else if (Objects.requireNonNull(mob.building.getCity()).cityOutlaws.contains(target.getObjectUUID())) { return true; } //first check condemn list for aggro allowed (allies button is checked) - if (ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().reverseKOS) { - for (Entry entry : ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().getCondemned().entrySet()) { + if (Objects.requireNonNull(ZoneManager.getCityAtLocation(mob.getLoc())).getTOL().reverseKOS) { + for (Entry entry : Objects.requireNonNull(ZoneManager.getCityAtLocation(mob.getLoc())).getTOL().getCondemned().entrySet()) { //target is listed individually @@ -1324,7 +1044,7 @@ public class MobAI { //allies button is not checked - for (Entry entry : ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().getCondemned().entrySet()) { + for (Entry entry : Objects.requireNonNull(ZoneManager.getCityAtLocation(mob.getLoc())).getTOL().getCondemned().entrySet()) { //target is listed individually @@ -1355,7 +1075,7 @@ public class MobAI { //early exit for a mob who is already moving to a patrol point //while mob moving, update lastPatrolTime so that when they stop moving the 10 second timer can begin - if (mob.isMoving() == true) { + if (mob.isMoving()) { mob.stopPatrolTime = System.currentTimeMillis(); return; } @@ -1381,7 +1101,7 @@ public class MobAI { //make sure mob is out of combat stance - if (minion.getKey().despawned == false) { + if (!minion.getKey().despawned) { if (MovementUtilities.canMove(minion.getKey())) { Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3); minion.getKey().updateLocation(); @@ -1395,40 +1115,4 @@ public class MobAI { Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: randomGuardPatrolPoints" + " " + e.getMessage()); } } - - public static AbstractWorldObject ChangeTargetFromHateValue(Mob mob) { - - if(mob.combatTarget != null) - return mob.combatTarget; - //try { - - // float CurrentHateValue = 0; - // if (mob.getCombatTarget() != null && mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.Mob)){ - // return mob.getCombatTarget(); - // } - - // if (mob.getCombatTarget() != null && mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) - // CurrentHateValue = mob.playerAgroMap.get(mob.combatTarget.getObjectUUID()).floatValue(); - - // 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 && mob.playerAgroMap.get(potentialTarget.getObjectUUID()).floatValue() > CurrentHateValue && MovementUtilities.inRangeToAggro(mob, potentialTarget)) { - // CurrentHateValue = mob.playerAgroMap.get(potentialTarget.getObjectUUID()).floatValue(); - // mostHatedTarget = potentialTarget; - // } - - // } - // return mostHatedTarget; - //} catch (Exception e) { - // Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: ChangeTargetFromMostHated" + " " + e.getMessage()); - //} - return null; - } } \ No newline at end of file diff --git a/src/engine/mobileAI/utilities/CombatUtilities.java b/src/engine/mobileAI/utilities/CombatUtilities.java index 021082cd..29021e50 100644 --- a/src/engine/mobileAI/utilities/CombatUtilities.java +++ b/src/engine/mobileAI/utilities/CombatUtilities.java @@ -12,13 +12,20 @@ package engine.mobileAI.utilities; import engine.Enum.*; import engine.gameManager.ChatManager; import engine.gameManager.CombatManager; +import engine.gameManager.PowersManager; import engine.math.Vector3fImmutable; +import engine.mobileAI.MobAI; +import engine.mobileAI.Threads.MobAIThread; import engine.net.DispatchMessage; +import engine.net.client.msg.PerformActionMsg; import engine.net.client.msg.TargetedActionMsg; import engine.objects.*; +import engine.powers.ActionsBase; +import engine.powers.PowersBase; import engine.server.MBServerStatics; import org.pmw.tinylog.Logger; +import java.util.ArrayList; import java.util.concurrent.ThreadLocalRandom; import static engine.math.FastMath.sqr; @@ -513,4 +520,209 @@ public class CombatUtilities { return agent.getMaxDamageHandOne(); } + public static boolean MobCast(Mob mob) { + + try { + // Method picks a random spell from a mobile's list of powers + // and casts it on the current target (or itself). Validation + // (including empty lists) is done previously within canCast(); + + ArrayList powerTokens; + ArrayList purgeTokens; + AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget(); + + if (mob.behaviourType.callsForHelp) + MobAI.MobCallForHelp(mob); + + // Generate a list of tokens from the mob powers for this mobile. + + powerTokens = new ArrayList<>(mob.mobPowers.keySet()); + purgeTokens = new ArrayList<>(); + + // If player has this effect on them currently then remove + // this token from our list. + + for (int powerToken : powerTokens) { + + PowersBase powerBase = PowersManager.getPowerByToken(powerToken); + + for (ActionsBase actionBase : powerBase.getActions()) { + + String stackType = actionBase.stackType; + + if (target.getEffects() != null && target.getEffects().containsKey(stackType)) + purgeTokens.add(powerToken); + } + } + + powerTokens.removeAll(purgeTokens); + + // Sanity check + + if (powerTokens.isEmpty()) + return false; + + // Pick random spell from our list of powers + + int powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); + int powerRank = mob.mobPowers.get(powerToken); + + PowersBase mobPower = PowersManager.getPowerByToken(powerToken); + + //check for hit-roll + + if (mobPower.requiresHitRoll) + if (triggerDefense(mob, mob.getCombatTarget())) + return false; + + // Cast the spell + + if (inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) { + + PerformActionMsg msg; + + if (!mobPower.isHarmful() || mobPower.targetSelf) { + PowersManager.useMobPower(mob, mob, mobPower, powerRank); + msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob); + } else { + PowersManager.useMobPower(mob, target, mobPower, powerRank); + msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); + } + + msg.setUnknown04(2); + + PowersManager.finishUseMobPower(msg, mob, 0, 0); + long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000L) * MobAIThread.AI_CAST_FREQUENCY); + + mob.nextCastTime = System.currentTimeMillis() + randomCooldown; + return true; + } + } catch (Exception e) { + Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage()); + } + return false; + } + + public static boolean GuardCast(Mob mob) { + + try { + // Method picks a random spell from a mobile's list of powers + // and casts it on the current target (or itself). Validation + // (including empty lists) is done previously within canCast(); + + ArrayList powerTokens; + ArrayList purgeTokens; + AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget(); + + if (mob.behaviourType.callsForHelp) + MobAI.MobCallForHelp(mob); + + // Generate a list of tokens from the mob powers for this mobile. + + powerTokens = new ArrayList<>(mob.mobPowers.keySet()); + purgeTokens = new ArrayList<>(); + + // If player has this effect on them currently then remove + // this token from our list. + + for (int powerToken : powerTokens) { + + PowersBase powerBase = PowersManager.getPowerByToken(powerToken); + + for (ActionsBase actionBase : powerBase.getActions()) { + + String stackType = actionBase.stackType; + + if (target.getEffects() != null && target.getEffects().containsKey(stackType)) + purgeTokens.add(powerToken); + } + } + + powerTokens.removeAll(purgeTokens); + + // Sanity check + + if (powerTokens.isEmpty()) + return false; + + int powerToken; + int nukeRoll = ThreadLocalRandom.current().nextInt(1,100); + + if (nukeRoll < 55) { + + //use direct damage spell + powerToken = powerTokens.get(powerTokens.size() - 1); + + } else { + //use random spell + powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); + } + + int powerRank = 1; + + switch(mob.getRank()){ + case 1: + powerRank = 10; + break; + case 2: + powerRank = 15; + break; + case 3: + powerRank = 20; + break; + case 4: + powerRank = 25; + break; + case 5: + powerRank = 30; + break; + case 6: + powerRank = 35; + break; + case 7: + powerRank = 40; + break; + } + + PowersBase mobPower = PowersManager.getPowerByToken(powerToken); + + //check for hit-roll + + if (mobPower.requiresHitRoll) + if (triggerDefense(mob, mob.getCombatTarget())) + return false; + + // Cast the spell + + if (inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) { + + PerformActionMsg msg; + + if (!mobPower.isHarmful() || mobPower.targetSelf) { + + if (mobPower.category.equals("DISPEL")) { + PowersManager.useMobPower(mob, target, mobPower, powerRank); + msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); + } else { + PowersManager.useMobPower(mob, mob, mobPower, powerRank); + msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob); + } + } else { + PowersManager.useMobPower(mob, target, mobPower, powerRank); + msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); + } + + msg.setUnknown04(2); + + PowersManager.finishUseMobPower(msg, mob, 0, 0); + + long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000L) * MobAIThread.AI_CAST_FREQUENCY); + mob.nextCastTime = System.currentTimeMillis() + randomCooldown; + return true; + } + } catch (Exception e) { + Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage()); + } + return false; + } } diff --git a/src/engine/mobileAI/utilities/MovementUtilities.java b/src/engine/mobileAI/utilities/MovementUtilities.java index 8d78b817..088c2a2e 100644 --- a/src/engine/mobileAI/utilities/MovementUtilities.java +++ b/src/engine/mobileAI/utilities/MovementUtilities.java @@ -143,15 +143,6 @@ public class MovementUtilities { public static void aiMove(Mob agent, Vector3fImmutable vect, boolean isWalking) { - //update our walk/run state. - if (isWalking && !agent.isWalk()) { - agent.setWalkMode(true); - MovementManager.sendRWSSMsg(agent); - } else if (!isWalking && agent.isWalk()) { - agent.setWalkMode(false); - MovementManager.sendRWSSMsg(agent); - } - MoveToPointMsg msg = new MoveToPointMsg(); diff --git a/src/engine/objects/AbstractCharacter.java b/src/engine/objects/AbstractCharacter.java index b65e07a5..be10959a 100644 --- a/src/engine/objects/AbstractCharacter.java +++ b/src/engine/objects/AbstractCharacter.java @@ -1113,23 +1113,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject { } public final void setCombatTarget(final AbstractWorldObject value) { - if(this.getObjectTypeMask() == 2050) {//MOB? - if (value == null) { - if (this.isCombat()) { - this.setCombat(false); - UpdateStateMsg rwss = new UpdateStateMsg(); - rwss.setPlayer(this); - DispatchMessage.sendToAllInRange(this, rwss); - } - }else { - if (!this.isCombat()) { - this.setCombat(true); - UpdateStateMsg rwss = new UpdateStateMsg(); - rwss.setPlayer(this); - DispatchMessage.sendToAllInRange(this, rwss); - } - } - } this.combatTarget = value; } From bb28d3873532418b97d70376fdb1b3260c0e2646 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 19 May 2024 07:19:32 -0500 Subject: [PATCH 12/68] mob AI aggro cleanup --- src/engine/mobileAI/MobAI.java | 53 ++++++++++------------------------ 1 file changed, 15 insertions(+), 38 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index a9c8b992..a44722a7 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -394,21 +394,7 @@ public class MobAI { } //no players loaded, no need to proceed - if (mob.playerAgroMap.isEmpty()) { - //attempt to reload agro map - HashSet players = WorldGrid.getObjectsInRangePartial(mob.loc, mob.getAggroRange(), MBServerStatics.MASK_PLAYER); - if(players.size() > 0){ - for(AbstractWorldObject player : players){ - if(!mob.playerAgroMap.containsKey(player.getObjectUUID())) { - PlayerCharacter pc = (PlayerCharacter) player; - mob.playerAgroMap.put(pc.getObjectUUID(), 0.0f); - } - } - } - - if(mob.getCombatTarget() != null) - mob.setCombatTarget(null); return; } @@ -441,6 +427,7 @@ public class MobAI { if (mob.isMoving()) { mob.updateLocation(); } + boolean combatState = mob.isCombat(); mob.setCombat(mob.combatTarget != null); if(combatState != mob.isCombat()){ @@ -449,6 +436,7 @@ public class MobAI { rwss.setPlayer(mob); DispatchMessage.sendToAllInRange(mob, rwss); } + boolean walking = mob.isWalk(); mob.setWalkMode(mob.combatTarget == null); if(walking != mob.isWalk()){ @@ -490,34 +478,28 @@ public class MobAI { if (!aiAgent.isAlive()) return; + if(!pets) { ConcurrentHashMap loadedPlayers = aiAgent.playerAgroMap; - for (Integer playerEntry : loadedPlayers.keySet()) { PlayerCharacter loadedPlayer = PlayerCharacter.getFromCache(playerEntry); - //Player is null, let's remove them from the list. - if (loadedPlayer == null) { loadedPlayers.remove(playerEntry); continue; } - //Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map. - if (!loadedPlayer.isAlive() || loadedPlayer.getHidden() > 0) { loadedPlayers.remove(playerEntry); continue; } //Can't see target, skip aggro. - if (!aiAgent.canSee(loadedPlayer)) continue; // No aggro for this race type - if (aiAgent.notEnemy.size() > 0 && aiAgent.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType())) continue; @@ -536,7 +518,7 @@ public class MobAI { //look for pets to aggro if no players found to aggro - HashSet awoList = WorldGrid.getObjectsInRangePartial(aiAgent, MobAIThread.AI_BASE_AGGRO_RANGE, MBServerStatics.MASK_PET); + HashSet awoList = WorldGrid.getObjectsInRangePartial(aiAgent, MobAIThread.AI_BASE_AGGRO_RANGE, MBServerStatics.MASK_MOB); for (AbstractWorldObject awoMob : awoList) { @@ -545,6 +527,9 @@ public class MobAI { if (aiAgent.equals(awoMob)) continue; + if(!((Mob)awoMob).isPet()) + continue; + Mob aggroMob = (Mob) awoMob; aiAgent.setCombatTarget(aggroMob); return; @@ -921,24 +906,16 @@ 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,false); //normal aggro - if(mob.combatTarget == null) - CheckForAggro(mob,true); // look for pets if no players to aggro - } + if (mob.getCombatTarget() == null) { + if (mob.behaviourType == Enum.MobBehaviourType.HamletGuard) { + SafeGuardAggro(mob); //safehold guard + } else { + CheckForAggro(mob, false); //normal aggro + if (mob.combatTarget == null) + CheckForAggro(mob, true); // look for pets if no players to aggro } } - //} + } //check if mob can move for patrol or moving to target From 40078df067849a67aeebe8a35fb0b1404cb6f7f5 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 00:03:04 -0500 Subject: [PATCH 13/68] optimized --- src/engine/gameManager/LootManager.java | 606 ++++++++---------- src/engine/gameManager/ZergManager.java | 134 +--- src/engine/objects/Warehouse.java | 240 +++---- .../workthreads/ZergMechanicThread.java | 232 +++---- 4 files changed, 455 insertions(+), 757 deletions(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index b0cc259b..538e69ff 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -73,38 +73,38 @@ public enum LootManager { } public static void GenerateMobLoot(Mob mob) { + int mobBootySet = mob.getMobBase().bootySet; + if (mobBootySet != 0) { + RunBootySetIfPresent(mobBootySet, mob); + } - //iterate the booty sets - - if (mob.getMobBase().bootySet != 0 && _bootySetMap.containsKey(mob.getMobBase().bootySet) == true) - RunBootySet(_bootySetMap.get(mob.getMobBase().bootySet), mob); - - if (mob.bootySet != 0 && _bootySetMap.containsKey(mob.bootySet) == true) - RunBootySet(_bootySetMap.get(mob.bootySet), mob); - - //lastly, check mobs inventory for godly or disc runes to send a server announcement - for (Item it : mob.getInventory()) { + mobBootySet = mob.bootySet; + if (mobBootySet != 0) { + RunBootySetIfPresent(mobBootySet, mob); + } - ItemBase ib = it.getItemBase(); - if(ib == null) - break; - if (ib.getName().toLowerCase().contains("of the gods")) { - ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + ib.getName() + ". Are you tough enough to take it?"); - chatMsg.setMessageType(10); - chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); - DispatchMessage.dispatchMsgToAll(chatMsg); - } + // Check mob's inventory for godly or disc runes to send a server announcement + for (Item item : mob.getInventory()) { + ItemBase itemBase = item.getItemBase(); + if (itemBase != null && itemBase.getName().toLowerCase().contains("of the gods")) { + ChatSystemMsg chatMsg = new ChatSystemMsg( + null, + mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + itemBase.getName() + ". Are you tough enough to take it?" + ); + chatMsg.setMessageType(10); + chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); + DispatchMessage.dispatchMsgToAll(chatMsg); } - + } } private static void RunBootySet(ArrayList entries, Mob mob) { - float dropRate = NORMAL_DROP_RATE; - //roll the geenric world drop table - if(mob.parentZone.getSafeZone() == 0) { + boolean isSafeZone = mob.parentZone.getSafeZone() == 0; + + if (isSafeZone) { GenerateLootDrop(mob, 1300); - if(ThreadLocalRandom.current().nextInt(1, 10000) == 5000) { + if (ThreadLocalRandom.current().nextInt(1, 10000) == 5000) { MobLoot extraLoot = rollForGlass(mob); if (extraLoot != null) { mob.getCharItemManager().addItemToInventory(extraLoot); @@ -112,7 +112,6 @@ public enum LootManager { } } - // Iterate all entries in this bootySet and process accordingly boolean hasExtraRolled = false; for (BootySetEntry bse : entries) { switch (bse.bootyType) { @@ -120,169 +119,161 @@ public enum LootManager { GenerateGoldDrop(mob, bse); break; case "LOOT": - if (ThreadLocalRandom.current().nextInt(1, 100 + 1) < (bse.dropChance * dropRate)) - GenerateLootDrop(mob, bse.genTable); //generate normal loot drop - if (mob.parentZone.getSafeZone() == 0 && hasExtraRolled == false && ThreadLocalRandom.current().nextInt(1, 5000) < 15 * dropRate) { - int roll = ThreadLocalRandom.current().nextInt(1, 101); - MobLoot extraLoot = null; - if (roll <= 50) { - extraLoot = rollForContract(bse.genTable, mob); - } - if (roll >= 51) { - extraLoot = rollForRune(bse.genTable, mob); - } - if (extraLoot != null) { - mob.getCharItemManager().addItemToInventory(extraLoot); - } - hasExtraRolled = true; + if (ThreadLocalRandom.current().nextInt(1, 101) < (bse.dropChance * dropRate)) { + GenerateLootDrop(mob, bse.genTable); + } + if (isSafeZone && !hasExtraRolled && ThreadLocalRandom.current().nextInt(1, 5000) < 15 * dropRate) { + MobLoot extraLoot = (ThreadLocalRandom.current().nextInt(1, 101) <= 50) + ? rollForContract(bse.genTable, mob) + : rollForRune(bse.genTable, mob); + if (extraLoot != null) { + mob.getCharItemManager().addItemToInventory(extraLoot); } + hasExtraRolled = true; + } break; case "ITEM": GenerateInventoryDrop(mob, bse); break; } } + + MobLoot specialDrop = getSpecialDropForMob(mob); + if (specialDrop != null) { + enhanceMob(mob, specialDrop); + } + } + + private static void RunBootySetIfPresent(int bootySet, Mob mob) { + if (_bootySetMap.containsKey(bootySet)) { + RunBootySet(_bootySetMap.get(bootySet), mob); + } + } + + private static MobLoot getSpecialDropForMob(Mob mob) { MobLoot specialDrop = null; - switch(mob.getObjectUUID()) { - case 22595://elf 1 - specialDrop = new MobLoot(mob,ItemBase.getItemBase(252134),true); - mob.setFirstName("Melandrach The Blood-Mage"); + int mobUUID = mob.getObjectUUID(); + switch (mobUUID) { + case 22595: + specialDrop = createSpecialDrop(mob, 252134, "Melandrach The Blood-Mage"); break; - case 22432: //elf 2 - specialDrop = new MobLoot(mob,ItemBase.getItemBase(252135),true); - mob.setFirstName("Kyrtaar The Blood-Mage"); + case 22432: + specialDrop = createSpecialDrop(mob, 252135, "Kyrtaar The Blood-Mage"); break; - case 22537: //elf 3 - specialDrop = new MobLoot(mob,ItemBase.getItemBase(252136),true); - mob.setFirstName("Vamir The Blood-Mage"); + case 22537: + specialDrop = createSpecialDrop(mob, 252136, "Vamir The Blood-Mage"); break; - case 16387: //human 4 DONE - specialDrop = new MobLoot(mob,ItemBase.getItemBase(252129),true); - mob.setFirstName("Alatar The Blood-Mage"); + case 16387: + specialDrop = createSpecialDrop(mob, 252129, "Alatar The Blood-Mage"); break; - case 32724:// human 5 GOOD - specialDrop = new MobLoot(mob,ItemBase.getItemBase(252130),true); - mob.setFirstName("Elphaba The Blood-Mage"); + case 32724: + specialDrop = createSpecialDrop(mob, 252130, "Elphaba The Blood-Mage"); break; - case 23379: //human 1 GOOD - specialDrop = new MobLoot(mob,ItemBase.getItemBase(252131),true); - mob.setFirstName("Bavmorda The Blood-Mage"); + case 23379: + specialDrop = createSpecialDrop(mob, 252131, "Bavmorda The Blood-Mage"); break; - case 10826: //human 2 REDO - specialDrop = new MobLoot(mob,ItemBase.getItemBase(252132),true); - mob.setFirstName("Draco The Blood-Mage"); + case 10826: + specialDrop = createSpecialDrop(mob, 252132, "Draco The Blood-Mage"); break; - case 15929: //human 3 GOOD - specialDrop = new MobLoot(mob,ItemBase.getItemBase(252133),true); - mob.setFirstName("Atlantes The Blood-Mage"); + case 15929: + specialDrop = createSpecialDrop(mob, 252133, "Atlantes The Blood-Mage"); break; } - if(specialDrop != null) { - mob.setLevel((short) 65); - mob.setSpawnTime(10800); - mob.healthMax = (7500); - mob.setHealth(7500); - ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + specialDrop.getName() + ". Are you tough enough to take it?"); - chatMsg.setMessageType(10); - chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); - DispatchMessage.dispatchMsgToAll(chatMsg); - mob.getCharItemManager().addItemToInventory(specialDrop); - mob.setResists(new Resists("Dropper")); - } + return specialDrop; } - public static MobLoot getGenTableItem(int genTableID, AbstractCharacter mob) { - - if (mob == null || _genTables.containsKey(genTableID) == false) - return null; + private static MobLoot createSpecialDrop(Mob mob, int itemBaseId, String name) { + mob.setFirstName(name); + return new MobLoot(mob, ItemBase.getItemBase(itemBaseId), true); + } - MobLoot outItem; + private static void enhanceMob(Mob mob, MobLoot specialDrop) { + mob.setLevel((short) 65); + mob.setSpawnTime(10800); + mob.healthMax = 7500; + mob.setHealth(7500); + ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + specialDrop.getName() + ". Are you tough enough to take it?"); + chatMsg.setMessageType(10); + chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); + DispatchMessage.dispatchMsgToAll(chatMsg); + mob.getCharItemManager().addItemToInventory(specialDrop); + mob.setResists(new Resists("Dropper")); + } - int genRoll = ThreadLocalRandom.current().nextInt(1,94 + 1); + public static MobLoot getGenTableItem(int genTableID, AbstractCharacter mob) { + if (mob == null || !_genTables.containsKey(genTableID)) { + return null; + } + int genRoll = ThreadLocalRandom.current().nextInt(1, 95); GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll, 1.0f); - if (selectedRow == null) + if (selectedRow == null || !_itemTables.containsKey(selectedRow.itemTableID)) { return null; + } - int itemTableId = selectedRow.itemTableID; + int itemTableRoll = (mob.getObjectType().ordinal() == 52) ? + ThreadLocalRandom.current().nextInt(1, 321) : + TableRoll(mob.level); - if (_itemTables.containsKey(itemTableId) == false) - return null; + ItemTableEntry tableRow = ItemTableEntry.rollTable(selectedRow.itemTableID, itemTableRoll); - //gets the 1-320 roll for this mob - int itemTableRoll = 0; - int objectType = mob.getObjectType().ordinal(); - if(mob.getObjectType().ordinal() == 52) { //52 = player character - itemTableRoll = ThreadLocalRandom.current().nextInt(1,320 + 1); - } else{ - itemTableRoll = TableRoll(mob.level); - } - ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, itemTableRoll); - if (tableRow == null) + if (tableRow == null || tableRow.cacheID == 0) { return null; + } - int itemUUID = tableRow.cacheID; - - if (itemUUID == 0) + ItemBase itemBase = ItemBase.getItemBase(tableRow.cacheID); + if (itemBase == null) { return null; + } - if (ItemBase.getItemBase(itemUUID).getType().ordinal() == Enum.ItemType.RESOURCE.ordinal()) { - int chance = ThreadLocalRandom.current().nextInt(1,101); - if(chance > 10) + if (itemBase.getType() == Enum.ItemType.RESOURCE) { + if (ThreadLocalRandom.current().nextInt(1, 101) > 10) { return null; - int amount = ThreadLocalRandom.current().nextInt((int)(tableRow.minSpawn * 0.5f), (int)((tableRow.maxSpawn + 1) * 0.5f)); - return new MobLoot(mob, ItemBase.getItemBase(itemUUID), amount, false); + } + int amount = ThreadLocalRandom.current().nextInt((int) (tableRow.minSpawn * 0.5f), + (int) ((tableRow.maxSpawn + 1) * 0.5f)); + return new MobLoot(mob, itemBase, amount, false); } - outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false); - Enum.ItemType outType = outItem.getItemBase().getType(); - - - if(selectedRow.pModTable != 0){ - try { + MobLoot outItem = new MobLoot(mob, itemBase, false); + try { + if (selectedRow.pModTable != 0) { outItem = GeneratePrefix(mob, outItem, genTableID, genRoll); outItem.setIsID(false); - } catch (Exception e) { - Logger.error("Failed to GeneratePrefix for item: " + outItem.getName()); } - } - if(selectedRow.sModTable != 0){ - try { + if (selectedRow.sModTable != 0) { outItem = GenerateSuffix(mob, outItem, genTableID, genRoll); outItem.setIsID(false); - } catch (Exception e) { - Logger.error("Failed to GenerateSuffix for item: " + outItem.getName()); } + } catch (Exception e) { + Logger.error("Failed to generate mod for item: " + outItem.getName(), e); } + return outItem; } private static MobLoot GeneratePrefix(AbstractCharacter mob, MobLoot inItem, int genTableID, int genRoll) { - GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll, 1.0f); - - if (selectedRow == null) + if (selectedRow == null) { return inItem; + } - int prefixroll = ThreadLocalRandom.current().nextInt(1, 100 + 1); - - ModTypeTableEntry prefixTable = ModTypeTableEntry.rollTable(selectedRow.pModTable, prefixroll); - - if (prefixTable == null) + ModTypeTableEntry prefixTable = ModTypeTableEntry.rollTable(selectedRow.pModTable, ThreadLocalRandom.current().nextInt(1, 101)); + if (prefixTable == null) { return inItem; - int prefixTableRoll = 0; - if(mob.getObjectType().ordinal() == 52) { - prefixTableRoll = ThreadLocalRandom.current().nextInt(1,320 + 1); - } else{ - prefixTableRoll = TableRoll(mob.level); } - ModTableEntry prefixMod = ModTableEntry.rollTable(prefixTable.modTableID, prefixTableRoll); - if (prefixMod == null) + int prefixTableRoll = (mob.getObjectType().ordinal() == 52) ? + ThreadLocalRandom.current().nextInt(1, 321) : + TableRoll(mob.level); + + ModTableEntry prefixMod = ModTableEntry.rollTable(prefixTable.modTableID, prefixTableRoll); + if (prefixMod == null) { return inItem; + } - if (prefixMod.action.length() > 0) { + if (!prefixMod.action.isEmpty()) { inItem.setPrefix(prefixMod.action); inItem.addPermanentEnchantment(prefixMod.action, 0, prefixMod.level, true); } @@ -291,30 +282,26 @@ public enum LootManager { } private static MobLoot GenerateSuffix(AbstractCharacter mob, MobLoot inItem, int genTableID, int genRoll) { - GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll, 1.0f); - - if (selectedRow == null) + if (selectedRow == null) { return inItem; + } - int suffixRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1); - - ModTypeTableEntry suffixTable = ModTypeTableEntry.rollTable(selectedRow.sModTable, suffixRoll); - - if (suffixTable == null) + ModTypeTableEntry suffixTable = ModTypeTableEntry.rollTable(selectedRow.sModTable, ThreadLocalRandom.current().nextInt(1, 101)); + if (suffixTable == null) { return inItem; - int suffixTableRoll = 0; - if(mob.getObjectType().ordinal() == 52) { - suffixTableRoll = ThreadLocalRandom.current().nextInt(1,320 + 1); - } else{ - suffixTableRoll = TableRoll(mob.level); } - ModTableEntry suffixMod = ModTableEntry.rollTable(suffixTable.modTableID, suffixTableRoll); - if (suffixMod == null) + int suffixTableRoll = (mob.getObjectType().ordinal() == 52) ? + ThreadLocalRandom.current().nextInt(1, 321) : + TableRoll(mob.level); + + ModTableEntry suffixMod = ModTableEntry.rollTable(suffixTable.modTableID, suffixTableRoll); + if (suffixMod == null) { return inItem; + } - if (suffixMod.action.length() > 0) { + if (!suffixMod.action.isEmpty()) { inItem.setSuffix(suffixMod.action); inItem.addPermanentEnchantment(suffixMod.action, 0, suffixMod.level, false); } @@ -323,150 +310,141 @@ public enum LootManager { } public static int TableRoll(int mobLevel) { + mobLevel = Math.min(mobLevel, 65); - if (mobLevel > 65) - mobLevel = 65; - - int max = (int) (4.882 * mobLevel + 127.0); - - if (max > 319) - max = 319; + int max = Math.min((int) (4.882 * mobLevel + 127.0), 319); + int min = Math.max((int) (4.469 * mobLevel - 3.469), 70); - int min = (int) (4.469 * mobLevel - 3.469); - - if (min < 70) - min = 70; - - int roll = ThreadLocalRandom.current().nextInt(min, max + 1); - - return roll; + return ThreadLocalRandom.current().nextInt(min, max + 1); } public static void GenerateGoldDrop(Mob mob, BootySetEntry bse) { + int chanceRoll = ThreadLocalRandom.current().nextInt(1, 101); // Simplified the chance roll to be out of 100 directly - int chanceRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1); - - //early exit, failed to hit minimum chance roll - - if (chanceRoll > bse.dropChance) + // Early exit if failed to hit minimum chance roll + if (chanceRoll > bse.dropChance) { return; + } - //determine and add gold to mob inventory - - int high = (int)(bse.highGold * NORMAL_GOLD_RATE); - int low = (int)(bse.lowGold * NORMAL_GOLD_RATE); + // Determine and add gold to mob inventory + int high = (int) (bse.highGold * NORMAL_GOLD_RATE); + int low = (int) (bse.lowGold * NORMAL_GOLD_RATE); int gold = ThreadLocalRandom.current().nextInt(low, high); if (gold > 0) { MobLoot goldAmount = new MobLoot(mob, gold); mob.getCharItemManager().addItemToInventory(goldAmount); } - } public static void GenerateLootDrop(Mob mob, int tableID) { + if (mob.parentZone.getSafeZone() == 1) { + return; // Exit early if in a safe zone + } try { - if(mob.parentZone.getSafeZone() == 1) { - return; - } MobLoot toAdd = getGenTableItem(tableID, mob); - if(toAdd.getItemBase().getType().equals(Enum.ItemType.CONTRACT) || toAdd.getItemBase().getType().equals(Enum.ItemType.RUNE)) - return;//block all contracts and runes that drop outside the confines of the new system - - if (toAdd != null) { + if (toAdd != null && !isContractOrRune(toAdd)) { toAdd.setIsID(true); mob.getCharItemManager().addItemToInventory(toAdd); } } catch (Exception e) { - //TODO chase down loot generation error, affects roughly 2% of drops + // Handle exceptions if necessary } } - public static void GenerateEquipmentDrop(Mob mob) { + private static boolean isContractOrRune(MobLoot loot) { + Enum.ItemType type = loot.getItemBase().getType(); + return type == Enum.ItemType.CONTRACT || type == Enum.ItemType.RUNE; + } - if(mob.parentZone.getSafeZone() == 1) { + public static void GenerateEquipmentDrop(Mob mob) { + if (mob.parentZone.getSafeZone() == 1) { return; } - //do equipment here int dropCount = 0; - if (mob.getEquip() != null) + if (mob.getEquip() != null) { for (MobEquipment me : mob.getEquip().values()) { - - if (me.getDropChance() == 0) + if (me.getDropChance() == 0) { continue; + } - float equipmentRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1); + float equipmentRoll = ThreadLocalRandom.current().nextInt(1, 101); // Simplified the roll to be out of 100 directly float dropChance = me.getDropChance() * 100; - if (equipmentRoll > dropChance) + + if (equipmentRoll > dropChance) { continue; + } + ItemBase genericIB = me.getItemBase(); - if(genericIB.isVorg()){ - if(genericIB.isClothArmor()){ - //get random cloth piece - genericIB = getRandomVorgCloth();//ItemBase.getItemBase(vorg_cloth_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_cloth_uuids.size() - 1))); - } else if(genericIB.isHeavyArmor()){ - //get random heavy armor piece - genericIB = getRandomVorgHA();//ItemBase.getItemBase(vorg_ha_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_ha_uuids.size() - 1))); - } else if(genericIB.isMediumArmor()){ - //get random medium armor piece - genericIB = getRandomVorgMA();//ItemBase.getItemBase(vorg_ma_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_ma_uuids.size() - 1))); - } else if(genericIB.isLightArmor()){ - //get random light armor piece - genericIB = getRandomVorgLA();//ItemBase.getItemBase(vorg_la_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_la_uuids.size() - 1))); - } - mob.spawnTime = ThreadLocalRandom.current().nextInt(300,2700); + if (genericIB.isVorg()) { + genericIB = getRandomVorgPiece(genericIB); // Replaced separate method calls with a single one + mob.spawnTime = ThreadLocalRandom.current().nextInt(300, 2700); } - MobLoot ml = new MobLoot(mob, genericIB, false); - if (ml != null && dropCount < 1 && genericIB.isVorg() == false) { + MobLoot ml = new MobLoot(mob, genericIB, false); + + if (ml != null && dropCount < 1) { ml.setIsID(true); ml.setDurabilityCurrent((short) (ml.getDurabilityCurrent() - ThreadLocalRandom.current().nextInt(5) + 1)); mob.getCharItemManager().addItemToInventory(ml); - dropCount = 1; - //break; // Exit on first successful roll. + dropCount++; } - if(ml != null && genericIB.isVorg() && mob.getMobBaseID() != 14062){ + + if (ml != null && genericIB.isVorg() && mob.getMobBaseID() != 14062) { ml.setIsID(true); ml.setDurabilityCurrent(ml.getDurabilityMax()); mob.getCharItemManager().addItemToInventory(ml); } } + } } - public static void GenerateInventoryDrop(Mob mob, BootySetEntry bse) { + private static ItemBase getRandomVorgPiece(ItemBase genericIB) { + if (genericIB.isClothArmor()) { + return getRandomVorgCloth(); + } else if (genericIB.isHeavyArmor()) { + return getRandomVorgHA(); + } else if (genericIB.isMediumArmor()) { + return getRandomVorgMA(); + } else if (genericIB.isLightArmor()) { + return getRandomVorgLA(); + } + return genericIB; // Return the original item base if it's not a vorg piece + } - if(ItemBase.getItemBase(bse.itemBase).isDiscRune()) { - if(!Mob.disciplineDroppers.contains(mob)) + public static void GenerateInventoryDrop(Mob mob, BootySetEntry bse) { + // Check if the item is a discipline rune + if (ItemBase.getItemBase(bse.itemBase).isDiscRune()) { + if (!Mob.disciplineDroppers.contains(mob)) { Mob.disciplineDroppers.add(mob); - - mob.setResists(new Resists("Dropper")); - ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + ItemBase.getItemBase(bse.itemBase).getName() + ". Are you tough enough to take it?"); - chatMsg.setMessageType(10); - chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); - DispatchMessage.dispatchMsgToAll(chatMsg); + mob.setResists(new Resists("Dropper")); + ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + ItemBase.getItemBase(bse.itemBase).getName() + ". Are you tough enough to take it?"); + chatMsg.setMessageType(10); + chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); + DispatchMessage.dispatchMsgToAll(chatMsg); + } } - //if((bse.itemBase == 3040 || bse.itemBase == 3021) && mob.level < 80){ - // chance = 100; - //} - - if(mob.parentZone.getSafeZone() == 1) { + // Skip drop if mob is in a safe zone + if (mob.parentZone.getSafeZone() == 1) { return; } - int chanceRoll = ThreadLocalRandom.current().nextInt(1, 99); - - //early exit, failed to hit minimum chance roll + // Roll for drop chance + int chanceRoll = ThreadLocalRandom.current().nextInt(1, 100); // Changed upper bound to 100 - if (chanceRoll > bse.dropChance) - return; + // Check if the chance roll exceeds drop chance + if (chanceRoll > bse.dropChance) { + return; // Early exit if the drop chance fails + } + // Create and add the loot item to the mob's inventory MobLoot lootItem = new MobLoot(mob, ItemBase.getItemBase(bse.itemBase), true); - - if (lootItem != null) + if (lootItem != null) { mob.getCharItemManager().addItemToInventory(lootItem); + } } public static void peddleFate(PlayerCharacter playerCharacter, Item gift) { @@ -553,151 +531,75 @@ public enum LootManager { itemMan.updateInventory(); } - public static MobLoot rollForContract(int table, Mob mob){ - - int roll = 99; - if (table == 1900 || table == 1500) - roll = 73; + public static MobLoot rollForContract(int table, Mob mob) { + int roll = (table == 1900 || table == 1500) ? 73 : 99; GenTableEntry selectedRow = GenTableEntry.rollTable(table, roll, 1.0f); - if (selectedRow == null) + if (selectedRow == null) { return null; + } int itemTableId = selectedRow.itemTableID; - - if (_itemTables.containsKey(itemTableId) == false) - return null; - ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, ThreadLocalRandom.current().nextInt(1,321)); - if (tableRow == null) + if (!_itemTables.containsKey(itemTableId)) { return null; + } - int itemUUID = tableRow.cacheID; - - if (itemUUID == 0) + ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, ThreadLocalRandom.current().nextInt(1, 321)); + if (tableRow == null || tableRow.cacheID == 0) { return null; + } - MobLoot outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false); - if(outItem != null) - return outItem; - return null; + return new MobLoot(mob, ItemBase.getItemBase(tableRow.cacheID), false); } - public static MobLoot rollForRune(int table, Mob mob){ - int roll = 97; - if(table == 1900 || table == 1500){ - roll = 77; - } + + public static MobLoot rollForRune(int table, Mob mob) { + int roll = (table == 1900 || table == 1500) ? 77 : 97; GenTableEntry selectedRow = GenTableEntry.rollTable(table, roll, 1.0f); - if (selectedRow == null) + if (selectedRow == null) { return null; + } int itemTableId = selectedRow.itemTableID; - - if (_itemTables.containsKey(itemTableId) == false) + if (!_itemTables.containsKey(itemTableId)) { return null; - ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, ThreadLocalRandom.current().nextInt(1,321)); - if (tableRow == null) - return null; - - int itemUUID = tableRow.cacheID; + } - if (itemUUID == 0) + ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, ThreadLocalRandom.current().nextInt(1, 321)); + if (tableRow == null || tableRow.cacheID == 0) { return null; + } - MobLoot outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false); - if(outItem != null) - return outItem; - return null; + return new MobLoot(mob, ItemBase.getItemBase(tableRow.cacheID), false); } - public static MobLoot rollForGlass( Mob mob){ - ItemTableEntry tableRow = ItemTableEntry.rollTable(126, ThreadLocalRandom.current().nextInt(1,321)); - if (tableRow == null) - return null; - int itemUUID = tableRow.cacheID; - - if (itemUUID == 0) - return null; - - MobLoot outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false); - if(outItem != null) - return outItem; + public static MobLoot rollForGlass(Mob mob) { + ItemTableEntry tableRow = ItemTableEntry.rollTable(126, ThreadLocalRandom.current().nextInt(1, 321)); + if (tableRow != null && tableRow.cacheID != 0) { + return new MobLoot(mob, ItemBase.getItemBase(tableRow.cacheID), false); + } return null; } - public static ItemBase getRandomVorgCloth(){ - int random = ThreadLocalRandom.current().nextInt(100); - if(random < 20) - return ItemBase.getItemBase(27600); - if(random > 20 && random < 40) - return ItemBase.getItemBase(188700); - if(random > 40 && random < 60) - return ItemBase.getItemBase(188720); - if(random > 60 && random < 80) - return ItemBase.getItemBase(189550); - if(random > 80) - return ItemBase.getItemBase(189560); - return null; + public static ItemBase getRandomVorgItem(int maxRandom, int... itemBaseIDs) { + int random = ThreadLocalRandom.current().nextInt(maxRandom); + int index = random / (maxRandom / itemBaseIDs.length); + if (index >= itemBaseIDs.length) { + index = itemBaseIDs.length - 1; + } + return ItemBase.getItemBase(itemBaseIDs[index]); + } + public static ItemBase getRandomVorgCloth() { + return getRandomVorgItem(100, 27600, 188700, 188720, 189550, 189560); } - public static ItemBase getRandomVorgLA(){ - int random = ThreadLocalRandom.current().nextInt(160); - if(random < 20) - return ItemBase.getItemBase(27550); - if(random > 20 && random < 40) - return ItemBase.getItemBase(27560); - if(random > 40 && random < 60) - return ItemBase.getItemBase(189100); - if(random > 60 && random < 80) - return ItemBase.getItemBase(189110); - if(random > 80 && random < 100) - return ItemBase.getItemBase(189120); - if(random > 100 && random < 120) - return ItemBase.getItemBase(189130); - if(random > 120 && random < 140) - return ItemBase.getItemBase(189140); - if(random > 140) - return ItemBase.getItemBase(189150); - return null; + public static ItemBase getRandomVorgLA() { + return getRandomVorgItem(160, 27550, 27560, 189100, 189110, 189120, 189130, 189140, 189150); } - public static ItemBase getRandomVorgMA(){ - int random = ThreadLocalRandom.current().nextInt(160); - if(random < 20) - return ItemBase.getItemBase(27570); - if(random > 20 && random < 40) - return ItemBase.getItemBase(188900); - if(random > 40 && random < 60) - return ItemBase.getItemBase(188910); - if(random > 60 && random < 80) - return ItemBase.getItemBase(188920); - if(random > 80 && random < 100) - return ItemBase.getItemBase(188930); - if(random > 100 && random < 120) - return ItemBase.getItemBase(188940); - if(random > 120 && random < 140) - return ItemBase.getItemBase(188950); - if(random > 140) - return ItemBase.getItemBase(189500); - return null; + + public static ItemBase getRandomVorgMA() { + return getRandomVorgItem(160, 27570, 188900, 188910, 188920, 188930, 188940, 188950, 189500); } - public static ItemBase getRandomVorgHA(){ - int random = ThreadLocalRandom.current().nextInt(180); - if(random < 20) - return ItemBase.getItemBase(27580); - if(random > 20 && random < 40) - return ItemBase.getItemBase(27590); - if(random > 40 && random < 60) - return ItemBase.getItemBase(188500); - if(random > 60 && random < 80) - return ItemBase.getItemBase(188510); - if(random > 80 && random < 100) - return ItemBase.getItemBase(188520); - if(random > 100 && random < 120) - return ItemBase.getItemBase(188530); - if(random > 120 && random < 140) - return ItemBase.getItemBase(188540); - if(random > 140 && random < 160) - return ItemBase.getItemBase(188550); - if(random > 160) - return ItemBase.getItemBase(189510); - return null; + + public static ItemBase getRandomVorgHA() { + return getRandomVorgItem(180, 27580, 27590, 188500, 188510, 188520, 188530, 188540, 188550, 189510); } } diff --git a/src/engine/gameManager/ZergManager.java b/src/engine/gameManager/ZergManager.java index 337bc4ed..c92f28d8 100644 --- a/src/engine/gameManager/ZergManager.java +++ b/src/engine/gameManager/ZergManager.java @@ -4,117 +4,51 @@ import engine.objects.Guild; public class ZergManager { - public static int getBaneCap(Guild guild){ - if(guild.getOwnedCity().getTOL().getRank() == 8) - return 20; - - if(guild.getNation().getSubGuildList().size() + 1 <= 4) - return 10; - - return 20; + public static int getBaneCap(Guild guild) { + int cityRank = guild.getOwnedCity().getTOL().getRank(); + return (cityRank == 8) ? 20 : ((guild.getNation().getSubGuildList().size() + 1 <= 4) ? 10 : 20); } - public static float getMultiplier3Man(int count){ - float multiplier = 1.0f; - - if(count <= 3) - return 1.0f; - - if(count > 6) - return 0.0f; - - switch(count){ - case 4: - multiplier -= 0.37f; - break; + public static float getCurrentMultiplier(int count, int maxCount){ + switch(maxCount) { + case 3: + return getMultiplier3Man(count); case 5: - multiplier -= 0.60f; - break; - case 6: - multiplier -= 0.75f; - break; - } - return multiplier; - } - - public static float getMultiplier5Man(int count){ - float multiplier = 1.0f; - - if(count <= 5) - return 1.0f; - - if(count > 10) - return 0.0f; - - switch(count){ - case 6: - multiplier -= 0.25f; - break; - case 7: - multiplier -= 0.43f; - break; - case 8: - multiplier -= 0.56f; - break; - case 9: - multiplier -= 0.67f; - break; + return getMultiplier5Man(count); case 10: - multiplier -= 0.75f; - break; + return getMultiplier10Man(count); + case 20: + return getMultiplier20Man(count); + default: + return getMultiplier40Man(count); } - return multiplier; + } + public static float getMultiplier(int count, int maxCount, float[] thresholds) { + if (count <= maxCount) return 1.0f; + if (count > thresholds.length) return 0.0f; + return 1.0f - thresholds[count - maxCount - 1]; } - public static float getMultiplier10Man(int count){ - float multiplier = 1.0f; - - if(count <= 10) - return 1.0f; + public static float getMultiplier3Man(int count) { + float[] thresholds = {0.37f, 0.60f, 0.75f}; + return getMultiplier(count, 3, thresholds); + } - if(count > 20) - return 0.0f; + public static float getMultiplier5Man(int count) { + float[] thresholds = {0.25f, 0.43f, 0.56f, 0.67f, 0.75f}; + return getMultiplier(count, 5, thresholds); + } - switch(count){ - case 11: - multiplier -= 0.14f; - break; - case 12: - multiplier -= 0.25f; - break; - case 13: - multiplier -= 0.35f; - break; - case 14: - multiplier -= 0.43f; - break; - case 15: - multiplier -= 0.50f; - break; - case 16: - multiplier -= 0.56f; - break; - case 17: - multiplier -= 0.62f; - break; - case 18: - multiplier -= 0.67f; - break; - case 19: - multiplier -= 0.71f; - break; - case 20: - multiplier -= 0.75f; - break; - } - return multiplier; + public static float getMultiplier10Man(int count) { + float[] thresholds = {0.14f, 0.25f, 0.35f, 0.43f, 0.50f, 0.56f, 0.62f, 0.67f, 0.71f, 0.75f}; + return getMultiplier(count, 10, thresholds); } - public static float getMultiplier20Man(int count){ - return getMultiplier10Man(((int)(count * 0.5f))); + public static float getMultiplier20Man(int count) { + return getMultiplier10Man(count * 2); } - public static float getMultiplier40Man(int count){ - return getMultiplier10Man(((int)(count * 0.25f))); + public static float getMultiplier40Man(int count) { + return getMultiplier10Man(count * 4); } -} +} \ No newline at end of file diff --git a/src/engine/objects/Warehouse.java b/src/engine/objects/Warehouse.java index c24513fc..813df7a8 100644 --- a/src/engine/objects/Warehouse.java +++ b/src/engine/objects/Warehouse.java @@ -128,38 +128,33 @@ public class Warehouse extends AbstractWorldObject { } public static void warehouseDeposit(MerchantMsg msg, PlayerCharacter player, NPC npc, ClientConnection origin) { - - Building warehouseBuilding; - Warehouse warehouse; - int depositAmount; - Dispatch dispatch; - Item resource = Item.getFromCache(msg.getItemID()); - if (resource == null) + if (resource == null) { return; + } - depositAmount = msg.getAmount(); + int depositAmount = msg.getAmount(); CharacterItemManager itemMan = player.getCharItemManager(); - if (itemMan.doesCharOwnThisItem(resource.getObjectUUID()) == false) + if (!itemMan.doesCharOwnThisItem(resource.getObjectUUID())) { return; + } - warehouseBuilding = npc.getBuilding(); - - if (warehouseBuilding == null) + Building warehouseBuilding = npc.getBuilding(); + if (warehouseBuilding == null) { return; + } - warehouse = warehouseByBuildingUUID.get(warehouseBuilding.getObjectUUID()); - - if (warehouse == null) + Warehouse warehouse = warehouseByBuildingUUID.get(warehouseBuilding.getObjectUUID()); + if (warehouse == null) { return; - - ItemBase ib = resource.getItemBase(); + } if (!warehouse.deposit(player, resource, depositAmount, true, true)) { - // ChatManager.chatGuildError(player, "Failed to deposit " + ib.getName() +"."); - // Logger.debug("OpenWindow", player.getName() + " Failed to deposit Item with ID " + resource.getObjectUUID() + " from Warehouse With ID = " + warehouseBuilding.getObjectUUID()); + // Optional: Uncomment these lines for debugging/logging purposes. + // ChatManager.chatGuildError(player, "Failed to deposit " + resource.getItemBase().getName() + "."); + // Logger.debug("OpenWindow", player.getName() + " Failed to deposit Item with ID " + resource.getObjectUUID() + " from Warehouse With ID = " + warehouseBuilding.getObjectUUID()); return; } @@ -167,7 +162,7 @@ public class Warehouse extends AbstractWorldObject { vrm.setGuild(player.getGuild()); vrm.setWarehouseBuilding(warehouseBuilding); vrm.configure(); - dispatch = Dispatch.borrow(player, vrm); + Dispatch dispatch = Dispatch.borrow(player, vrm); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); } @@ -294,172 +289,103 @@ public class Warehouse extends AbstractWorldObject { } public synchronized boolean deposit(PlayerCharacter pc, Item resource, int amount, boolean removeFromInventory, boolean transaction) { - ClientConnection origin = pc.getClientConnection(); - if (origin == null) - return false; - - if (amount < 0) { - Logger.info(pc.getFirstName() + " Attempting to Dupe!!!!!!"); + if (origin == null || amount < 0 || resource == null) { + if (amount < 0) Logger.info(pc.getFirstName() + " Attempting to Dupe!!!!!!"); return false; } ItemBase ib = resource.getItemBase(); + if (ib == null) return false; - if (ib == null) - return false; - - if (this.resources.get(ib) == null) - return false; + Integer currentResourceAmount = this.resources.get(ib); + if (currentResourceAmount == null) return false; CharacterItemManager itemMan = pc.getCharItemManager(); - - if (itemMan == null) - return false; - + if (itemMan == null || !itemMan.doesCharOwnThisItem(resource.getObjectUUID())) return false; if (itemMan.getGoldTrading() > 0) { ErrorPopupMsg.sendErrorPopup(pc, 195); return false; } + if (!resource.validForInventory(origin, pc, itemMan) || resource.getNumOfItems() < amount) return false; - if (!itemMan.doesCharOwnThisItem(resource.getObjectUUID())) - return false; - - if (!resource.validForInventory(origin, pc, itemMan)) - return false; - - if (resource.getNumOfItems() < amount) - return false; - - int oldAmount = resources.get(ib); - - int newAmount = oldAmount + amount; - - if (newAmount > Warehouse.getMaxResources().get(ib.getUUID())) { - //ChatManager.chatSystemInfo(pc, "The Warehouse is at it's maximum for this type of resource."); + int newAmount = currentResourceAmount + amount; + Integer maxResourceAmount = Warehouse.getMaxResources().get(ib.getUUID()); + if (newAmount > (maxResourceAmount != null ? maxResourceAmount : Integer.MAX_VALUE)) { + // ChatManager.chatSystemInfo(pc, "The Warehouse is at its maximum for this type of resource."); return false; } - if (removeFromInventory) { - if (ib.getUUID() == 7) { - - if (itemMan.getGoldInventory().getNumOfItems() - amount < 0) - return false; + if (!removeFromInventory(itemMan, ib, amount, pc)) return false; + } - if (itemMan.getGoldInventory().getNumOfItems() - amount > MBServerStatics.PLAYER_GOLD_LIMIT) - return false; + itemMan.updateInventory(); + if (!updateDatabase(ib.getUUID(), newAmount)) return false; - if (!itemMan.modifyInventoryGold(-amount)) { - //ChatManager.chatSystemError(pc, "You do not have this Gold."); - return false; - } + this.resources.put(ib, newAmount); - UpdateGoldMsg ugm = new UpdateGoldMsg(pc); - ugm.configure(); - Dispatch dispatch = Dispatch.borrow(pc, ugm); - DispatchMessage.dispatchMsgDispatch(dispatch, engine.Enum.DispatchChannel.SECONDARY); + if (transaction) { + Resource resourceType = getResourceType(resource); + this.AddTransactionToWarehouse(pc.getObjectType(), pc.getObjectUUID(), TransactionType.DEPOSIT, resourceType, amount); + } - itemMan.updateInventory(); + return true; + } - } else { - itemMan.delete(resource); - itemMan.updateInventory(); + private boolean removeFromInventory(CharacterItemManager itemMan, ItemBase ib, int amount, PlayerCharacter pc) { + if (ib.getUUID() == 7) { + if (!itemMan.modifyInventoryGold(-amount)) { + // ChatManager.chatSystemError(pc, "You do not have this Gold."); + return false; } + UpdateGoldMsg ugm = new UpdateGoldMsg(pc); + ugm.configure(); + Dispatch dispatch = Dispatch.borrow(pc, ugm); + DispatchMessage.dispatchMsgDispatch(dispatch, engine.Enum.DispatchChannel.SECONDARY); + } else { + Item resource = itemMan.getItemByUUID(ib.getUUID()); + if (resource == null) return false; + itemMan.delete(resource); } - itemMan.updateInventory(); - int itemID = ib.getUUID(); - boolean worked = false; + return true; + } + + private boolean updateDatabase(int itemID, int newAmount) { switch (itemID) { - case 7: - worked = DbManager.WarehouseQueries.updateGold(this, newAmount); - break; - case 1580000: - worked = DbManager.WarehouseQueries.updateStone(this, newAmount); - break; - case 1580001: - worked = DbManager.WarehouseQueries.updateTruesteel(this, newAmount); - break; - case 1580002: - worked = DbManager.WarehouseQueries.updateIron(this, newAmount); - break; - case 1580003: - worked = DbManager.WarehouseQueries.updateAdamant(this, newAmount); - break; - case 1580004: - worked = DbManager.WarehouseQueries.updateLumber(this, newAmount); - break; - case 1580005: - worked = DbManager.WarehouseQueries.updateOak(this, newAmount); - break; - case 1580006: - worked = DbManager.WarehouseQueries.updateBronzewood(this, newAmount); - break; - case 1580007: - worked = DbManager.WarehouseQueries.updateMandrake(this, newAmount); - break; - case 1580008: - worked = DbManager.WarehouseQueries.updateCoal(this, newAmount); - break; - case 1580009: - worked = DbManager.WarehouseQueries.updateAgate(this, newAmount); - break; - case 1580010: - worked = DbManager.WarehouseQueries.updateDiamond(this, newAmount); - break; - case 1580011: - worked = DbManager.WarehouseQueries.updateOnyx(this, newAmount); - break; - case 1580012: - worked = DbManager.WarehouseQueries.updateAzoth(this, newAmount); - break; - case 1580013: - worked = DbManager.WarehouseQueries.updateOrichalk(this, newAmount); - break; - case 1580014: - worked = DbManager.WarehouseQueries.updateAntimony(this, newAmount); - break; - case 1580015: - worked = DbManager.WarehouseQueries.updateSulfur(this, newAmount); - break; - case 1580016: - worked = DbManager.WarehouseQueries.updateQuicksilver(this, newAmount); - break; - case 1580017: - worked = DbManager.WarehouseQueries.updateGalvor(this, newAmount); - break; - case 1580018: - worked = DbManager.WarehouseQueries.updateWormwood(this, newAmount); - break; - case 1580019: - worked = DbManager.WarehouseQueries.updateObsidian(this, newAmount); - break; - case 1580020: - worked = DbManager.WarehouseQueries.updateBloodstone(this, newAmount); - break; - case 1580021: - worked = DbManager.WarehouseQueries.updateMithril(this, newAmount); - break; + case 7: return DbManager.WarehouseQueries.updateGold(this, newAmount); + case 1580000: return DbManager.WarehouseQueries.updateStone(this, newAmount); + case 1580001: return DbManager.WarehouseQueries.updateTruesteel(this, newAmount); + case 1580002: return DbManager.WarehouseQueries.updateIron(this, newAmount); + case 1580003: return DbManager.WarehouseQueries.updateAdamant(this, newAmount); + case 1580004: return DbManager.WarehouseQueries.updateLumber(this, newAmount); + case 1580005: return DbManager.WarehouseQueries.updateOak(this, newAmount); + case 1580006: return DbManager.WarehouseQueries.updateBronzewood(this, newAmount); + case 1580007: return DbManager.WarehouseQueries.updateMandrake(this, newAmount); + case 1580008: return DbManager.WarehouseQueries.updateCoal(this, newAmount); + case 1580009: return DbManager.WarehouseQueries.updateAgate(this, newAmount); + case 1580010: return DbManager.WarehouseQueries.updateDiamond(this, newAmount); + case 1580011: return DbManager.WarehouseQueries.updateOnyx(this, newAmount); + case 1580012: return DbManager.WarehouseQueries.updateAzoth(this, newAmount); + case 1580013: return DbManager.WarehouseQueries.updateOrichalk(this, newAmount); + case 1580014: return DbManager.WarehouseQueries.updateAntimony(this, newAmount); + case 1580015: return DbManager.WarehouseQueries.updateSulfur(this, newAmount); + case 1580016: return DbManager.WarehouseQueries.updateQuicksilver(this, newAmount); + case 1580017: return DbManager.WarehouseQueries.updateGalvor(this, newAmount); + case 1580018: return DbManager.WarehouseQueries.updateWormwood(this, newAmount); + case 1580019: return DbManager.WarehouseQueries.updateObsidian(this, newAmount); + case 1580020: return DbManager.WarehouseQueries.updateBloodstone(this, newAmount); + case 1580021: return DbManager.WarehouseQueries.updateMithril(this, newAmount); + default: return false; } + } - if (!worked) - return false; - - resources.put(ib, newAmount); - - Resource resourceType; - - if (resource.getItemBase().getType().equals(engine.Enum.ItemType.GOLD)) - resourceType = Resource.GOLD; - else - resourceType = Resource.valueOf(resource.getItemBase().getName().toUpperCase()); - - if (transaction) - this.AddTransactionToWarehouse(pc.getObjectType(), pc.getObjectUUID(), TransactionType.DEPOSIT, resourceType, amount); - - return true; + private Resource getResourceType(Item resource) { + return resource.getItemBase().getType().equals(engine.Enum.ItemType.GOLD) + ? Resource.GOLD + : Resource.valueOf(resource.getItemBase().getName().toUpperCase()); } //for mine deposit diff --git a/src/engine/workthreads/ZergMechanicThread.java b/src/engine/workthreads/ZergMechanicThread.java index 58e6231e..27cb9493 100644 --- a/src/engine/workthreads/ZergMechanicThread.java +++ b/src/engine/workthreads/ZergMechanicThread.java @@ -8,196 +8,132 @@ package engine.workthreads; - import engine.Enum; import engine.InterestManagement.WorldGrid; -import engine.db.archive.DataWarehouse; -import engine.db.archive.MineRecord; import engine.gameManager.*; -import engine.mobileAI.Threads.MobAIThread; -import engine.net.DispatchMessage; -import engine.net.MessageDispatcher; -import engine.net.client.msg.chat.ChatSystemMsg; import engine.objects.*; import engine.server.MBServerStatics; -import engine.server.world.WorldServer; import org.pmw.tinylog.Logger; - -import java.time.LocalDateTime; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -import java.util.concurrent.ConcurrentHashMap; - -import static engine.server.MBServerStatics.MINE_LATE_WINDOW; -public class ZergMechanicThread implements Runnable { -public Bane bane = null; -public Mine mine = null; -public ArrayList affectedPlayers = new ArrayList<>(); - - public ZergMechanicThread(Bane b, Mine m) { - this.mine = m; - this.bane = b; - } + public class ZergMechanicThread implements Runnable { + private final Mine mine; + private final Bane bane; + private final HashSet affectedPlayers = new HashSet<>(); - @Override - public void run() { + public ZergMechanicThread(Bane b, Mine m) { + this.mine = m; + this.bane = b; + } + @Override + public void run() { if (mine != null) RunMineMechanic(); if (bane != null) RunBaneMechanic(); - } - - public void RunMineMechanic(){ - while(mine.isActive) { - HashSet currentPlayers; - PlayerCharacter player; + } - // Gather current list of players within the zone bounds + private void RunMineMechanic() { Building tower = BuildingManager.getBuildingFromCache(mine.getBuildingID()); - currentPlayers = WorldGrid.getObjectsInRangePartial(tower.loc, Enum.CityBoundsType.GRID.extents * 0.5f, MBServerStatics.MASK_PLAYER); + float zoneBounds = Enum.CityBoundsType.GRID.extents * 0.5f; - for (AbstractWorldObject playerObject : currentPlayers) { + while (mine.isActive) { + HashSet currentPlayers = WorldGrid.getObjectsInRangePartial(tower.loc, zoneBounds, MBServerStatics.MASK_PLAYER); - if (playerObject == null) - continue; + for (AbstractWorldObject playerObject : currentPlayers) { + PlayerCharacter player = (PlayerCharacter) playerObject; - player = (PlayerCharacter) playerObject; + affectedPlayers.add(player); - if(!this.affectedPlayers.contains(player)) - this.affectedPlayers.add(player); - - //ChatManager.chatSystemInfo(player, "TESTING ZERG MECHANIC"); - if (mine._recentMemory.containsKey(player.getObjectUUID())) mine._recentMemory.remove(player.getObjectUUID()); - if (mine._playerMemory.contains(player.getObjectUUID())) - continue; + mine._playerMemory.add(player.getObjectUUID()); + } - mine._playerMemory.add(player.getObjectUUID()); + try { + mine.onExit(currentPlayers); + } catch (Exception e) { + Logger.error(e.getMessage()); + } - } - boolean updated = false; - try { - mine.onExit(currentPlayers); - } catch (Exception e) { - Logger.error(e.getMessage()); - } - mine.dividedPlayers = new HashMap<>(); - for (Integer playerID : mine._playerMemory) { - player = PlayerCharacter.getFromCache(playerID); - Guild nation = player.getGuild().getNation(); - Guild entry; - if (mine.dividedPlayers.containsKey(nation)) { - mine.dividedPlayers.get(nation).add(playerID); - } else { - ArrayList newEntry = new ArrayList<>(); - newEntry.add(playerID); - mine.dividedPlayers.put(nation, newEntry); + mine.dividedPlayers = new HashMap<>(); + for (Integer playerID : mine._playerMemory) { + PlayerCharacter player = PlayerCharacter.getFromCache(playerID); + Guild nation = player.getGuild().getNation(); + mine.dividedPlayers.computeIfAbsent(nation, k -> new ArrayList<>()).add(playerID); } - } - for (Integer playerID : mine._playerMemory) { - player = PlayerCharacter.getFromCache(playerID); - if (mine.dividedPlayers.containsKey(player.getGuild().getNation())) { - int count = mine.dividedPlayers.get(player.getGuild().getNation()).size(); - switch (mine.capSize) { - case 3: - player.ZergMultiplier = ZergManager.getMultiplier3Man(count); - break; - case 5: - player.ZergMultiplier = ZergManager.getMultiplier5Man(count); - break; - case 10: - player.ZergMultiplier = ZergManager.getMultiplier10Man(count); - break; - case 20: - player.ZergMultiplier = ZergManager.getMultiplier20Man(count); - break; + + for (Integer playerID : mine._playerMemory) { + PlayerCharacter player = PlayerCharacter.getFromCache(playerID); + Guild nation = player.getGuild().getNation(); + + if (mine.dividedPlayers.containsKey(nation)) { + int count = mine.dividedPlayers.get(nation).size(); + player.ZergMultiplier = ZergManager.getCurrentMultiplier(count, mine.capSize); + player.mineAppliedID = mine.getObjectUUID(); + } else { + player.ZergMultiplier = 1.0f; + player.mineAppliedID = 0; } - player.mineAppliedID = mine.getObjectUUID(); - } else { - player.ZergMultiplier = 1.0f; - player.mineAppliedID = 0; } } - } - for(PlayerCharacter player : this.affectedPlayers) - player.ZergMultiplier = 1.0f; - } - - public void RunBaneMechanic(){ - while(bane.getSiegePhase().equals(Enum.SiegePhase.WAR)) { - HashSet currentPlayers; - - currentPlayers = WorldGrid.getObjectsInRangePartial(bane.getCity().loc, Enum.CityBoundsType.GRID.extents * 2.0f, MBServerStatics.MASK_PLAYER); - - Guild attacker = bane.getStone().getGuild().getNation(); - Guild defender = bane.getCity().getGuild().getNation(); - - ArrayList attackers = new ArrayList<>(); - ArrayList defenders = new ArrayList<>(); + resetZergMultiplier(); + } - for (AbstractWorldObject awo : currentPlayers) { + private void RunBaneMechanic() { + while (bane.getSiegePhase().equals(Enum.SiegePhase.WAR)) { + HashSet currentPlayers = WorldGrid.getObjectsInRangePartial(bane.getCity().loc, Enum.CityBoundsType.GRID.extents * 2.0f, MBServerStatics.MASK_PLAYER); + Guild attacker = bane.getStone().getGuild().getNation(); + Guild defender = bane.getCity().getGuild().getNation(); + ArrayList attackers = new ArrayList<>(); + ArrayList defenders = new ArrayList<>(); + + for (AbstractWorldObject awo : currentPlayers) { + PlayerCharacter pc = (PlayerCharacter) awo; + affectedPlayers.add(pc); + + if (!pc.getGuild().getNation().equals(attacker) && !pc.getGuild().getNation().equals(defender)) { + pc.teleport(pc.bindLoc); + pc.ZergMultiplier = 1.0f; + } - if(!this.affectedPlayers.contains((PlayerCharacter)awo)) - this.affectedPlayers.add((PlayerCharacter)awo); + if (pc.getGuild().getNation().equals(attacker)) + attackers.add(pc); - PlayerCharacter pc = (PlayerCharacter) awo; - if (!pc.getGuild().getNation().equals(attacker) && !pc.getGuild().getNation().equals(defender)) { - pc.teleport(pc.bindLoc); - pc.ZergMultiplier = 1.0f; + if (pc.getGuild().getNation().equals(defender)) + defenders.add(pc); } - if (pc.getGuild().getNation().equals(attacker)) - attackers.add(pc); - - if (pc.getGuild().getNation().equals(defender)) - defenders.add(pc); - } - - //int treeRank = bane.getCity().getTOL().getRank(); - - for (PlayerCharacter pc : attackers) { - switch(bane.capSize){ - case 10: - pc.ZergMultiplier = ZergManager.getMultiplier10Man(attackers.size()); - break; - case 20: - pc.ZergMultiplier = ZergManager.getMultiplier20Man(attackers.size()); - break; + for (PlayerCharacter pc : attackers) { + pc.ZergMultiplier = ZergManager.getCurrentMultiplier(attackers.size(), bane.capSize); } - } - for (PlayerCharacter pc : defenders) { - switch(bane.capSize){ - case 10: - pc.ZergMultiplier = ZergManager.getMultiplier10Man(defenders.size()); - break; - case 20: - pc.ZergMultiplier = ZergManager.getMultiplier20Man(defenders.size()); - break; + for (PlayerCharacter pc : defenders) { + pc.ZergMultiplier = ZergManager.getCurrentMultiplier(defenders.size(), bane.capSize); } } + + resetZergMultiplier(); } - for(PlayerCharacter player : this.affectedPlayers) - player.ZergMultiplier = 1.0f; - } + private void resetZergMultiplier() { + for (PlayerCharacter player : affectedPlayers) + player.ZergMultiplier = 1.0f; + } - public static void startZergThreadMine(Mine mine) { - Thread zergMechanicThread; - zergMechanicThread = new Thread(new ZergMechanicThread(null, mine)); - zergMechanicThread.setName(mine.getParentZone().getName() + "Mine"); - zergMechanicThread.start(); - } + public static void startZergThreadMine(Mine mine) { + Thread zergMechanicThread = new Thread(new ZergMechanicThread(null, mine)); + zergMechanicThread.setName(mine.getParentZone().getName() + "Mine"); + zergMechanicThread.start(); + } - public static void startZergThreadBane(Bane bane) { - Thread zergMechanicThread; - zergMechanicThread = new Thread(new ZergMechanicThread(bane, null)); - zergMechanicThread.setName(bane.getCity().getGuild().getName() + "Bane"); - zergMechanicThread.start(); + public static void startZergThreadBane(Bane bane) { + Thread zergMechanicThread = new Thread(new ZergMechanicThread(bane, null)); + zergMechanicThread.setName(bane.getCity().getGuild().getName() + "Bane"); + zergMechanicThread.start(); + } } -} From 7745ef6949cc94f9f5ab7bb1de127276f555006e Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 10:07:04 -0500 Subject: [PATCH 14/68] optimized looting system --- src/engine/gameManager/LootActionManager.java | 199 +++++++++++++++ src/engine/net/client/ClientMessagePump.java | 231 +----------------- 2 files changed, 200 insertions(+), 230 deletions(-) create mode 100644 src/engine/gameManager/LootActionManager.java diff --git a/src/engine/gameManager/LootActionManager.java b/src/engine/gameManager/LootActionManager.java new file mode 100644 index 00000000..91e713f9 --- /dev/null +++ b/src/engine/gameManager/LootActionManager.java @@ -0,0 +1,199 @@ +package engine.gameManager; + +import engine.Enum; +import engine.exception.MsgSendException; +import engine.net.Dispatch; +import engine.net.DispatchMessage; +import engine.net.client.ClientConnection; +import engine.net.client.msg.LootMsg; +import engine.net.client.msg.TransferItemFromEquipToInventoryMsg; +import engine.net.client.msg.UpdateGoldMsg; +import engine.objects.*; +import engine.server.MBServerStatics; +import org.pmw.tinylog.Logger; + +import static engine.math.FastMath.sqr; + +public class LootActionManager { + public static void loot(LootMsg msg, ClientConnection origin) throws MsgSendException { + PlayerCharacter player = SessionManager.getPlayerCharacter(origin); + if (player == null || !player.isAlive() || player.getAltitude() > 0) { + return; + } + + Item item = msg.getItem(); + if (item == null) { + return; + } + + if (item.lootLock.tryLock()) { + try { + handleLoot(msg, player, item, origin); + } catch (Exception e) { + Logger.info(e.getMessage()); + } finally { + item.lootLock.unlock(); + } + } + } + + private static void handleLoot(LootMsg msg, PlayerCharacter player, Item item, ClientConnection origin) { + int targetType = msg.getTargetType(); + int targetID = msg.getTargetID(); + + if (!isValidTargetType(targetType)) { + targetType = msg.getSourceID2(); + targetID = msg.getUnknown01(); + } + + AbstractCharacter targetCharacter; + Corpse corpse; + + if (isCharacterOrMob(targetType)) { + targetCharacter = getTargetCharacter(targetType, targetID); + if (targetCharacter == null || isInvalidLootTarget(player, targetCharacter)) { + return; + } + + if (!lootCharacter(player, item, origin, targetCharacter)) { + return; + } + + handleCharacterLoot(player, msg, item, targetCharacter); + } else if (targetType == Enum.GameObjectType.Corpse.ordinal()) { + corpse = Corpse.getCorpse(targetID); + if (corpse == null || isTooFarToLoot(player, corpse)) { + return; + } + + if (!lootCorpse(player, item, origin, corpse)) { + return; + } + + handleCorpseLoot(player, msg, item, corpse); + } + } + + private static boolean isValidTargetType(int targetType) { + return targetType == Enum.GameObjectType.PlayerCharacter.ordinal() || + targetType == Enum.GameObjectType.Mob.ordinal() || + targetType == Enum.GameObjectType.Corpse.ordinal(); + } + + private static boolean isCharacterOrMob(int targetType) { + return targetType == Enum.GameObjectType.PlayerCharacter.ordinal() || + targetType == Enum.GameObjectType.Mob.ordinal() || + targetType == Enum.GameObjectType.NPC.ordinal(); + } + + private static AbstractCharacter getTargetCharacter(int targetType, int targetID) { + if (targetType == Enum.GameObjectType.PlayerCharacter.ordinal()) { + return PlayerCharacter.getFromCache(targetID); + } else if (targetType == Enum.GameObjectType.NPC.ordinal()) { + return NPC.getFromCache(targetID); + } else if (targetType == Enum.GameObjectType.Mob.ordinal()) { + return Mob.getFromCache(targetID); + } + return null; + } + + private static boolean isInvalidLootTarget(PlayerCharacter player, AbstractCharacter target) { + return target.equals(player) || + (target.getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && + player.getObjectUUID() != target.getObjectUUID() && + ((PlayerCharacter) target).isInSafeZone()) || + player.getLoc().distanceSquared2D(target.getLoc()) > sqr(MBServerStatics.LOOT_RANGE) || + target.isAlive(); + } + + private static boolean isTooFarToLoot(PlayerCharacter player, Corpse corpse) { + return player.getLoc().distanceSquared2D(corpse.getLoc()) > sqr(MBServerStatics.LOOT_RANGE); + } + + private static boolean lootCharacter(PlayerCharacter player, Item item, ClientConnection origin, AbstractCharacter target) { + if (!GroupManager.goldSplit(player, item, origin, target)) { + if (target.getCharItemManager() != null) { + Item itemRet = target.getCharItemManager().lootItemFromMe(item, player, origin); + if (target.getObjectType() == Enum.GameObjectType.Mob && itemRet != null && item.getObjectType() == Enum.GameObjectType.MobLoot) { + handleMobEquipmentLoot(player, target); + } + return itemRet != null; + } + } + return false; + } + + private static void handleMobEquipmentLoot(PlayerCharacter player, AbstractCharacter target) { + Mob mobTarget = (Mob) target; + for (MobEquipment equip : mobTarget.getEquip().values()) { + TransferItemFromEquipToInventoryMsg back = new TransferItemFromEquipToInventoryMsg(mobTarget, equip.getSlot()); + DispatchMessage.dispatchMsgToInterestArea(mobTarget, back, Enum.DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); + + LootMsg lootMsg = new LootMsg(0, 0, target.getObjectType().ordinal(), target.getObjectUUID(), equip); + Dispatch dispatch = Dispatch.borrow(player, lootMsg); + DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); + break; + } + } + + private static boolean lootCorpse(PlayerCharacter player, Item item, ClientConnection origin, Corpse corpse) { + Item itemRet = null; + if (player.getObjectUUID() == corpse.getBelongsToID()) { + itemRet = corpse.lootItem(item, player); + } else if (!GroupManager.goldSplit(player, item, origin, corpse)) { + itemRet = corpse.lootItem(item, player); + } + return itemRet != null; + } + + private static void handleCharacterLoot(PlayerCharacter player, LootMsg msg, Item item, AbstractCharacter target) { + if (item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD)) { + updateGold(player, target); + } else { + dispatchLootMessage(player, msg, target, item); + } + sendGroupLootMessage(player, item); + } + + private static void handleCorpseLoot(PlayerCharacter player, LootMsg msg, Item item, Corpse corpse) { + if (item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD)) { + updateGold(player, corpse); + } else { + DispatchMessage.dispatchMsgToInterestArea(corpse, msg, Enum.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, true); + } + sendGroupLootMessage(player, item); + } + + private static void updateGold(PlayerCharacter player, AbstractWorldObject target) { + UpdateGoldMsg updateTargetGold = new UpdateGoldMsg(target); + updateTargetGold.configure(); + DispatchMessage.dispatchMsgToInterestArea(target, updateTargetGold, Enum.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); + + UpdateGoldMsg ugm = new UpdateGoldMsg(player); + ugm.configure(); + Dispatch dispatch = Dispatch.borrow(player, ugm); + DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); + } + + private static void dispatchLootMessage(PlayerCharacter player, LootMsg msg, AbstractCharacter target, Item item) { + msg.setSourceType1(0); + msg.setSourceType2(0); + msg.setSourceID1(0); + msg.setSourceID2(0); + Dispatch dispatch = Dispatch.borrow(player, msg); + DispatchMessage.dispatchMsgToInterestArea(target, msg, Enum.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, true); + + LootMsg newItemMsg = new LootMsg(Enum.GameObjectType.PlayerCharacter.ordinal(), player.getObjectUUID(), 0, 0, item); + dispatch = Dispatch.borrow(player, newItemMsg); + DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY); + } + + private static void sendGroupLootMessage(PlayerCharacter player, Item item) { + Group group = GroupManager.getGroup(player); + if (group != null && group.getSplitGold() && !item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD)) { + String name = item.getName(); + String text = player.getFirstName() + " has looted " + name + '.'; + ChatManager.chatGroupInfoCanSee(player, text); + } + } +} diff --git a/src/engine/net/client/ClientMessagePump.java b/src/engine/net/client/ClientMessagePump.java index 54cbc291..4cfb8ad6 100644 --- a/src/engine/net/client/ClientMessagePump.java +++ b/src/engine/net/client/ClientMessagePump.java @@ -773,235 +773,6 @@ public class ClientMessagePump implements NetMsgHandler { } - private static void loot(LootMsg msg, ClientConnection origin) throws MsgSendException { - - PlayerCharacter player = SessionManager.getPlayerCharacter(origin); - if (player == null) - return; - - if (!player.isAlive()) - return; - - Item item = msg.getItem(); - - if (item == null) - return; - - if (item.lootLock.tryLock()) { - try { - Item itemRet = null; - // get current owner - int targetType = msg.getTargetType(); - int targetID = msg.getTargetID(); - - if (targetType == GameObjectType.PlayerCharacter.ordinal() || targetType == GameObjectType.Mob.ordinal() || targetType == GameObjectType.Corpse.ordinal()) { - } else { //needed for getting contracts for some reason - targetType = msg.getSourceID2(); - targetID = msg.getUnknown01(); - } - - //can't loot while flying - if (player.getAltitude() > 0) - return; - - AbstractCharacter tar = null; - Corpse corpse = null; - - if (targetType == GameObjectType.PlayerCharacter.ordinal() || targetType == GameObjectType.Mob.ordinal()) { - - if (targetType == GameObjectType.PlayerCharacter.ordinal()) { - tar = PlayerCharacter.getFromCache(targetID); - - if (tar == null) - return; - - if (player.getObjectUUID() != tar.getObjectUUID() && ((PlayerCharacter) tar).isInSafeZone()) - return; - - } else if (targetType == GameObjectType.NPC.ordinal()) - tar = NPC.getFromCache(targetID); - else if (targetType == GameObjectType.Mob.ordinal()) - tar = Mob.getFromCache(targetID); - if (tar == null) - return; - - if (tar.equals(player)) { - ErrorPopupMsg.sendErrorMsg(player, "Cannot loot this item."); - return; - } - - - if (player.getLoc().distanceSquared2D(tar.getLoc()) > sqr(MBServerStatics.LOOT_RANGE)) { - ErrorPopupMsg.sendErrorMsg(player, "You are too far away to loot this corpse."); - - Logger.info(player.getFirstName() + " tried looting at " + player.getLoc().distance2D(tar.getLoc()) + " distance."); - return; - } - - //can't loot from someone who is alive. - if (AbstractWorldObject.IsAbstractCharacter(tar)) { - if (tar.isAlive()) - return; - // Logger.error("WorldServer.loot", "Looting from live player"); - } - - if (!GroupManager.goldSplit(player, item, origin, tar)) { - - if (tar.getCharItemManager() != null) { - - itemRet = tar.getCharItemManager().lootItemFromMe(item, player, origin); - - //Take equipment off mob - if (tar.getObjectType() == GameObjectType.Mob && itemRet != null) { - Mob mobTarget = (Mob) tar; - - if (item != null && item.getObjectType() == GameObjectType.MobLoot) { - - for (MobEquipment equip : mobTarget.getEquip().values()) { - - TransferItemFromEquipToInventoryMsg back = new TransferItemFromEquipToInventoryMsg(mobTarget, equip.getSlot()); - DispatchMessage.dispatchMsgToInterestArea(mobTarget, back, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); - - LootMsg lootMsg = new LootMsg(0, 0, tar.getObjectType().ordinal(), tar.getObjectUUID(), equip); - Dispatch dispatch = Dispatch.borrow(player, lootMsg); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); - break; - } - } - } - } - - } - } else if (targetType == GameObjectType.Corpse.ordinal()) { - corpse = Corpse.getCorpse(targetID); - if (corpse == null) - return; - - if (player.getLoc().distanceSquared2D(corpse.getLoc()) > sqr(MBServerStatics.LOOT_RANGE)) { - ErrorPopupMsg.sendErrorMsg(player, "You are too far away to loot this corpse."); - - Logger.info(player.getFirstName() + " tried looting at " + player.getLoc().distance2D(corpse.getLoc()) + " distance."); - return; - } - - - //can't loot other players in safe zone. - if (corpse.getBelongsToType() == GameObjectType.PlayerCharacter.ordinal()) { - - if (player.getObjectUUID() == corpse.getBelongsToID()) - itemRet = corpse.lootItem(item, player); - else if (!GroupManager.goldSplit(player, item, origin, corpse)) { - itemRet = corpse.lootItem(item, player); - - } - - if (itemRet == null) - return; - - - if (item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD)) { - // this is done to prevent the temporary goldItem item - // (from the mob) from appearing in player's inventory. - // It also updates the goldItem quantity display - UpdateGoldMsg updateTargetGold = null; - - - if (corpse != null) - updateTargetGold = new UpdateGoldMsg(corpse); - - updateTargetGold.configure(); - DispatchMessage.dispatchMsgToInterestArea(corpse, updateTargetGold, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); - - UpdateGoldMsg ugm = new UpdateGoldMsg(player); - ugm.configure(); - Dispatch dispatch = Dispatch.borrow(player, ugm); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); - - // respond back loot message. Try sending to everyone. - - } else { - - DispatchMessage.dispatchMsgToInterestArea(corpse, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, true); - - - //player.getCharItemManager().updateInventory(); - } - - //TODO send group loot message if player is grouped and visible - Group group = GroupManager.getGroup(player); - - if (group != null && group.getSplitGold() && (item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD) == false)) { - String name = item.getName(); - String text = player.getFirstName() + " has looted " + name + '.'; - ChatManager.chatGroupInfoCanSee(player, text); - } - - return; - } - - - } else - return; - - - if (itemRet == null) { - return; - } - - if (item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD)) { - // this is done to prevent the temporary goldItem item - // (from the mob) from appearing in player's inventory. - // It also updates the goldItem quantity display - UpdateGoldMsg updateTargetGold = null; - - if (tar != null) - updateTargetGold = new UpdateGoldMsg(tar); - else if (corpse != null) - updateTargetGold = new UpdateGoldMsg(corpse); - - updateTargetGold.configure(); - DispatchMessage.dispatchMsgToInterestArea(tar, updateTargetGold, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); - - UpdateGoldMsg ugm = new UpdateGoldMsg(player); - ugm.configure(); - Dispatch dispatch = Dispatch.borrow(player, ugm); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); - - // respond back loot message. Try sending to everyone. - - } else { - msg.setSourceType1(0); - msg.setSourceType2(0); - msg.setSourceID1(0); - msg.setSourceID2(0); - Dispatch dispatch = Dispatch.borrow(player, msg); - //DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); - DispatchMessage.dispatchMsgToInterestArea(tar, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, true); - LootMsg newItemMsg = new LootMsg(GameObjectType.PlayerCharacter.ordinal(), player.getObjectUUID(), 0, 0, itemRet); - dispatch = Dispatch.borrow(player, newItemMsg); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); - - //player.getCharItemManager().updateInventory(); - } - - //TODO send group loot message if player is grouped and visible - Group group = GroupManager.getGroup(player); - - if (group != null && group.getSplitGold() && (item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD) == false)) { - String name = item.getName(); - String text = player.getFirstName() + " has looted " + name + '.'; - ChatManager.chatGroupInfoCanSee(player, text); - } - } catch (Exception e) { - Logger.info(e.getMessage()); - } finally { - item.lootLock.unlock(); - } - } - - - } - // called when player types /show private static void show(ShowMsg msg, ClientConnection origin) throws MsgSendException { @@ -1997,7 +1768,7 @@ public class ClientMessagePump implements NetMsgHandler { lootWindowRequest((LootWindowRequestMsg) msg, origin); break; case MOVEOBJECTTOCONTAINER: - loot((LootMsg) msg, origin); + LootActionManager.loot((LootMsg) msg, origin); break; case SHOWCOMBATINFO: show((ShowMsg) msg, origin); From 0ac7a1a7fa7a2fa8c20479b807aa46120cbe2c45 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 10:30:37 -0500 Subject: [PATCH 15/68] optimized deleting items --- src/engine/net/client/ClientMessagePump.java | 64 +++++++++----------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/src/engine/net/client/ClientMessagePump.java b/src/engine/net/client/ClientMessagePump.java index 4cfb8ad6..d674c05b 100644 --- a/src/engine/net/client/ClientMessagePump.java +++ b/src/engine/net/client/ClientMessagePump.java @@ -542,53 +542,43 @@ public class ClientMessagePump implements NetMsgHandler { } - private static void DeleteItem(DeleteItemMsg msg, ClientConnection origin) { - - CharacterItemManager itemManager = origin.getPlayerCharacter().getCharItemManager(); - int uuid = msg.getUUID(); - - + private static void deleteItem(DeleteItemMsg msg, ClientConnection origin) { PlayerCharacter sourcePlayer = origin.getPlayerCharacter(); - - if (sourcePlayer == null) + if (sourcePlayer == null || !sourcePlayer.isAlive()) { return; + } - if (!sourcePlayer.isAlive()) - return; - - Item i = Item.getFromCache(msg.getUUID()); - - if (i == null) - return; - - if(i.getItemBaseID() == 7) - return; //cant delete gold - - if (!itemManager.doesCharOwnThisItem(i.getObjectUUID())) + CharacterItemManager itemManager = sourcePlayer.getCharItemManager(); + Item item = Item.getFromCache(msg.getUUID()); + if (item == null || !canDeleteItem(item, itemManager)) { return; + } - if (!itemManager.inventoryContains(i)) - return; + int value = item.getItemBase().value; + if (item.getItemBase().isRune()) { + value = 500000; + } - if(i.getItemBaseID() == 980066) + if (sourcePlayer.getCharItemManager().getGoldInventory().getNumOfItems() + value > 10000000) { return; + } - if (i.canDestroy) { - int value = i.getItemBase().value; - if(i.getItemBase().isRune()) - value = 500000; - if(sourcePlayer.getCharItemManager().getGoldInventory().getNumOfItems() + value > 10000000){ - return; - } - if (itemManager.delete(i) == true) { - sourcePlayer.getCharItemManager().addGoldToInventory(value,false); - sourcePlayer.getCharItemManager().updateInventory(); - Dispatch dispatch = Dispatch.borrow(sourcePlayer, msg); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); - } + if (itemManager.delete(item)) { + itemManager.addGoldToInventory(value, false); + itemManager.updateInventory(); + Dispatch dispatch = Dispatch.borrow(sourcePlayer, msg); + DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); } } + private static boolean canDeleteItem(Item item, CharacterItemManager itemManager) { + return item.getItemBaseID() != 7 && // Can't delete gold + item.getItemBaseID() != 980066 && // Can't delete conc pots + item.canDestroy && + itemManager.doesCharOwnThisItem(item.getObjectUUID()) && + itemManager.inventoryContains(item); + } + private static void ackBankWindowOpened(AckBankWindowOpenedMsg msg, ClientConnection origin) { // According to the Wiki, the client should not send this message. // Log the instance to investigate, and modify Wiki accordingly. @@ -1750,7 +1740,7 @@ public class ClientMessagePump implements NetMsgHandler { TransferItemFromInventoryToEquip((TransferItemFromInventoryToEquipMsg) msg, origin); break; case DELETEOBJECT: - DeleteItem((DeleteItemMsg) msg, origin); + deleteItem((DeleteItemMsg) msg, origin); break; case VIEWRESOURCES: ViewResourcesMessage((ViewResourcesMessage) msg, origin); From 85717a1880f6a1ede0c645fc5fd99a3beca95a17 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 10:46:37 -0500 Subject: [PATCH 16/68] Revert "optimized looting system" This reverts commit 7745ef6949cc94f9f5ab7bb1de127276f555006e. --- src/engine/gameManager/LootActionManager.java | 199 --------------- src/engine/net/client/ClientMessagePump.java | 231 +++++++++++++++++- 2 files changed, 230 insertions(+), 200 deletions(-) delete mode 100644 src/engine/gameManager/LootActionManager.java diff --git a/src/engine/gameManager/LootActionManager.java b/src/engine/gameManager/LootActionManager.java deleted file mode 100644 index 91e713f9..00000000 --- a/src/engine/gameManager/LootActionManager.java +++ /dev/null @@ -1,199 +0,0 @@ -package engine.gameManager; - -import engine.Enum; -import engine.exception.MsgSendException; -import engine.net.Dispatch; -import engine.net.DispatchMessage; -import engine.net.client.ClientConnection; -import engine.net.client.msg.LootMsg; -import engine.net.client.msg.TransferItemFromEquipToInventoryMsg; -import engine.net.client.msg.UpdateGoldMsg; -import engine.objects.*; -import engine.server.MBServerStatics; -import org.pmw.tinylog.Logger; - -import static engine.math.FastMath.sqr; - -public class LootActionManager { - public static void loot(LootMsg msg, ClientConnection origin) throws MsgSendException { - PlayerCharacter player = SessionManager.getPlayerCharacter(origin); - if (player == null || !player.isAlive() || player.getAltitude() > 0) { - return; - } - - Item item = msg.getItem(); - if (item == null) { - return; - } - - if (item.lootLock.tryLock()) { - try { - handleLoot(msg, player, item, origin); - } catch (Exception e) { - Logger.info(e.getMessage()); - } finally { - item.lootLock.unlock(); - } - } - } - - private static void handleLoot(LootMsg msg, PlayerCharacter player, Item item, ClientConnection origin) { - int targetType = msg.getTargetType(); - int targetID = msg.getTargetID(); - - if (!isValidTargetType(targetType)) { - targetType = msg.getSourceID2(); - targetID = msg.getUnknown01(); - } - - AbstractCharacter targetCharacter; - Corpse corpse; - - if (isCharacterOrMob(targetType)) { - targetCharacter = getTargetCharacter(targetType, targetID); - if (targetCharacter == null || isInvalidLootTarget(player, targetCharacter)) { - return; - } - - if (!lootCharacter(player, item, origin, targetCharacter)) { - return; - } - - handleCharacterLoot(player, msg, item, targetCharacter); - } else if (targetType == Enum.GameObjectType.Corpse.ordinal()) { - corpse = Corpse.getCorpse(targetID); - if (corpse == null || isTooFarToLoot(player, corpse)) { - return; - } - - if (!lootCorpse(player, item, origin, corpse)) { - return; - } - - handleCorpseLoot(player, msg, item, corpse); - } - } - - private static boolean isValidTargetType(int targetType) { - return targetType == Enum.GameObjectType.PlayerCharacter.ordinal() || - targetType == Enum.GameObjectType.Mob.ordinal() || - targetType == Enum.GameObjectType.Corpse.ordinal(); - } - - private static boolean isCharacterOrMob(int targetType) { - return targetType == Enum.GameObjectType.PlayerCharacter.ordinal() || - targetType == Enum.GameObjectType.Mob.ordinal() || - targetType == Enum.GameObjectType.NPC.ordinal(); - } - - private static AbstractCharacter getTargetCharacter(int targetType, int targetID) { - if (targetType == Enum.GameObjectType.PlayerCharacter.ordinal()) { - return PlayerCharacter.getFromCache(targetID); - } else if (targetType == Enum.GameObjectType.NPC.ordinal()) { - return NPC.getFromCache(targetID); - } else if (targetType == Enum.GameObjectType.Mob.ordinal()) { - return Mob.getFromCache(targetID); - } - return null; - } - - private static boolean isInvalidLootTarget(PlayerCharacter player, AbstractCharacter target) { - return target.equals(player) || - (target.getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && - player.getObjectUUID() != target.getObjectUUID() && - ((PlayerCharacter) target).isInSafeZone()) || - player.getLoc().distanceSquared2D(target.getLoc()) > sqr(MBServerStatics.LOOT_RANGE) || - target.isAlive(); - } - - private static boolean isTooFarToLoot(PlayerCharacter player, Corpse corpse) { - return player.getLoc().distanceSquared2D(corpse.getLoc()) > sqr(MBServerStatics.LOOT_RANGE); - } - - private static boolean lootCharacter(PlayerCharacter player, Item item, ClientConnection origin, AbstractCharacter target) { - if (!GroupManager.goldSplit(player, item, origin, target)) { - if (target.getCharItemManager() != null) { - Item itemRet = target.getCharItemManager().lootItemFromMe(item, player, origin); - if (target.getObjectType() == Enum.GameObjectType.Mob && itemRet != null && item.getObjectType() == Enum.GameObjectType.MobLoot) { - handleMobEquipmentLoot(player, target); - } - return itemRet != null; - } - } - return false; - } - - private static void handleMobEquipmentLoot(PlayerCharacter player, AbstractCharacter target) { - Mob mobTarget = (Mob) target; - for (MobEquipment equip : mobTarget.getEquip().values()) { - TransferItemFromEquipToInventoryMsg back = new TransferItemFromEquipToInventoryMsg(mobTarget, equip.getSlot()); - DispatchMessage.dispatchMsgToInterestArea(mobTarget, back, Enum.DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); - - LootMsg lootMsg = new LootMsg(0, 0, target.getObjectType().ordinal(), target.getObjectUUID(), equip); - Dispatch dispatch = Dispatch.borrow(player, lootMsg); - DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); - break; - } - } - - private static boolean lootCorpse(PlayerCharacter player, Item item, ClientConnection origin, Corpse corpse) { - Item itemRet = null; - if (player.getObjectUUID() == corpse.getBelongsToID()) { - itemRet = corpse.lootItem(item, player); - } else if (!GroupManager.goldSplit(player, item, origin, corpse)) { - itemRet = corpse.lootItem(item, player); - } - return itemRet != null; - } - - private static void handleCharacterLoot(PlayerCharacter player, LootMsg msg, Item item, AbstractCharacter target) { - if (item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD)) { - updateGold(player, target); - } else { - dispatchLootMessage(player, msg, target, item); - } - sendGroupLootMessage(player, item); - } - - private static void handleCorpseLoot(PlayerCharacter player, LootMsg msg, Item item, Corpse corpse) { - if (item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD)) { - updateGold(player, corpse); - } else { - DispatchMessage.dispatchMsgToInterestArea(corpse, msg, Enum.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, true); - } - sendGroupLootMessage(player, item); - } - - private static void updateGold(PlayerCharacter player, AbstractWorldObject target) { - UpdateGoldMsg updateTargetGold = new UpdateGoldMsg(target); - updateTargetGold.configure(); - DispatchMessage.dispatchMsgToInterestArea(target, updateTargetGold, Enum.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); - - UpdateGoldMsg ugm = new UpdateGoldMsg(player); - ugm.configure(); - Dispatch dispatch = Dispatch.borrow(player, ugm); - DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); - } - - private static void dispatchLootMessage(PlayerCharacter player, LootMsg msg, AbstractCharacter target, Item item) { - msg.setSourceType1(0); - msg.setSourceType2(0); - msg.setSourceID1(0); - msg.setSourceID2(0); - Dispatch dispatch = Dispatch.borrow(player, msg); - DispatchMessage.dispatchMsgToInterestArea(target, msg, Enum.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, true); - - LootMsg newItemMsg = new LootMsg(Enum.GameObjectType.PlayerCharacter.ordinal(), player.getObjectUUID(), 0, 0, item); - dispatch = Dispatch.borrow(player, newItemMsg); - DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY); - } - - private static void sendGroupLootMessage(PlayerCharacter player, Item item) { - Group group = GroupManager.getGroup(player); - if (group != null && group.getSplitGold() && !item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD)) { - String name = item.getName(); - String text = player.getFirstName() + " has looted " + name + '.'; - ChatManager.chatGroupInfoCanSee(player, text); - } - } -} diff --git a/src/engine/net/client/ClientMessagePump.java b/src/engine/net/client/ClientMessagePump.java index d674c05b..50f576ae 100644 --- a/src/engine/net/client/ClientMessagePump.java +++ b/src/engine/net/client/ClientMessagePump.java @@ -763,6 +763,235 @@ public class ClientMessagePump implements NetMsgHandler { } + private static void loot(LootMsg msg, ClientConnection origin) throws MsgSendException { + + PlayerCharacter player = SessionManager.getPlayerCharacter(origin); + if (player == null) + return; + + if (!player.isAlive()) + return; + + Item item = msg.getItem(); + + if (item == null) + return; + + if (item.lootLock.tryLock()) { + try { + Item itemRet = null; + // get current owner + int targetType = msg.getTargetType(); + int targetID = msg.getTargetID(); + + if (targetType == GameObjectType.PlayerCharacter.ordinal() || targetType == GameObjectType.Mob.ordinal() || targetType == GameObjectType.Corpse.ordinal()) { + } else { //needed for getting contracts for some reason + targetType = msg.getSourceID2(); + targetID = msg.getUnknown01(); + } + + //can't loot while flying + if (player.getAltitude() > 0) + return; + + AbstractCharacter tar = null; + Corpse corpse = null; + + if (targetType == GameObjectType.PlayerCharacter.ordinal() || targetType == GameObjectType.Mob.ordinal()) { + + if (targetType == GameObjectType.PlayerCharacter.ordinal()) { + tar = PlayerCharacter.getFromCache(targetID); + + if (tar == null) + return; + + if (player.getObjectUUID() != tar.getObjectUUID() && ((PlayerCharacter) tar).isInSafeZone()) + return; + + } else if (targetType == GameObjectType.NPC.ordinal()) + tar = NPC.getFromCache(targetID); + else if (targetType == GameObjectType.Mob.ordinal()) + tar = Mob.getFromCache(targetID); + if (tar == null) + return; + + if (tar.equals(player)) { + ErrorPopupMsg.sendErrorMsg(player, "Cannot loot this item."); + return; + } + + + if (player.getLoc().distanceSquared2D(tar.getLoc()) > sqr(MBServerStatics.LOOT_RANGE)) { + ErrorPopupMsg.sendErrorMsg(player, "You are too far away to loot this corpse."); + + Logger.info(player.getFirstName() + " tried looting at " + player.getLoc().distance2D(tar.getLoc()) + " distance."); + return; + } + + //can't loot from someone who is alive. + if (AbstractWorldObject.IsAbstractCharacter(tar)) { + if (tar.isAlive()) + return; + // Logger.error("WorldServer.loot", "Looting from live player"); + } + + if (!GroupManager.goldSplit(player, item, origin, tar)) { + + if (tar.getCharItemManager() != null) { + + itemRet = tar.getCharItemManager().lootItemFromMe(item, player, origin); + + //Take equipment off mob + if (tar.getObjectType() == GameObjectType.Mob && itemRet != null) { + Mob mobTarget = (Mob) tar; + + if (item != null && item.getObjectType() == GameObjectType.MobLoot) { + + for (MobEquipment equip : mobTarget.getEquip().values()) { + + TransferItemFromEquipToInventoryMsg back = new TransferItemFromEquipToInventoryMsg(mobTarget, equip.getSlot()); + DispatchMessage.dispatchMsgToInterestArea(mobTarget, back, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); + + LootMsg lootMsg = new LootMsg(0, 0, tar.getObjectType().ordinal(), tar.getObjectUUID(), equip); + Dispatch dispatch = Dispatch.borrow(player, lootMsg); + DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); + break; + } + } + } + } + + } + } else if (targetType == GameObjectType.Corpse.ordinal()) { + corpse = Corpse.getCorpse(targetID); + if (corpse == null) + return; + + if (player.getLoc().distanceSquared2D(corpse.getLoc()) > sqr(MBServerStatics.LOOT_RANGE)) { + ErrorPopupMsg.sendErrorMsg(player, "You are too far away to loot this corpse."); + + Logger.info(player.getFirstName() + " tried looting at " + player.getLoc().distance2D(corpse.getLoc()) + " distance."); + return; + } + + + //can't loot other players in safe zone. + if (corpse.getBelongsToType() == GameObjectType.PlayerCharacter.ordinal()) { + + if (player.getObjectUUID() == corpse.getBelongsToID()) + itemRet = corpse.lootItem(item, player); + else if (!GroupManager.goldSplit(player, item, origin, corpse)) { + itemRet = corpse.lootItem(item, player); + + } + + if (itemRet == null) + return; + + + if (item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD)) { + // this is done to prevent the temporary goldItem item + // (from the mob) from appearing in player's inventory. + // It also updates the goldItem quantity display + UpdateGoldMsg updateTargetGold = null; + + + if (corpse != null) + updateTargetGold = new UpdateGoldMsg(corpse); + + updateTargetGold.configure(); + DispatchMessage.dispatchMsgToInterestArea(corpse, updateTargetGold, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); + + UpdateGoldMsg ugm = new UpdateGoldMsg(player); + ugm.configure(); + Dispatch dispatch = Dispatch.borrow(player, ugm); + DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); + + // respond back loot message. Try sending to everyone. + + } else { + + DispatchMessage.dispatchMsgToInterestArea(corpse, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, true); + + + //player.getCharItemManager().updateInventory(); + } + + //TODO send group loot message if player is grouped and visible + Group group = GroupManager.getGroup(player); + + if (group != null && group.getSplitGold() && (item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD) == false)) { + String name = item.getName(); + String text = player.getFirstName() + " has looted " + name + '.'; + ChatManager.chatGroupInfoCanSee(player, text); + } + + return; + } + + + } else + return; + + + if (itemRet == null) { + return; + } + + if (item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD)) { + // this is done to prevent the temporary goldItem item + // (from the mob) from appearing in player's inventory. + // It also updates the goldItem quantity display + UpdateGoldMsg updateTargetGold = null; + + if (tar != null) + updateTargetGold = new UpdateGoldMsg(tar); + else if (corpse != null) + updateTargetGold = new UpdateGoldMsg(corpse); + + updateTargetGold.configure(); + DispatchMessage.dispatchMsgToInterestArea(tar, updateTargetGold, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); + + UpdateGoldMsg ugm = new UpdateGoldMsg(player); + ugm.configure(); + Dispatch dispatch = Dispatch.borrow(player, ugm); + DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); + + // respond back loot message. Try sending to everyone. + + } else { + msg.setSourceType1(0); + msg.setSourceType2(0); + msg.setSourceID1(0); + msg.setSourceID2(0); + Dispatch dispatch = Dispatch.borrow(player, msg); + //DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); + DispatchMessage.dispatchMsgToInterestArea(tar, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, true); + LootMsg newItemMsg = new LootMsg(GameObjectType.PlayerCharacter.ordinal(), player.getObjectUUID(), 0, 0, itemRet); + dispatch = Dispatch.borrow(player, newItemMsg); + DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); + + //player.getCharItemManager().updateInventory(); + } + + //TODO send group loot message if player is grouped and visible + Group group = GroupManager.getGroup(player); + + if (group != null && group.getSplitGold() && (item.getItemBase().getType().equals(engine.Enum.ItemType.GOLD) == false)) { + String name = item.getName(); + String text = player.getFirstName() + " has looted " + name + '.'; + ChatManager.chatGroupInfoCanSee(player, text); + } + } catch (Exception e) { + Logger.info(e.getMessage()); + } finally { + item.lootLock.unlock(); + } + } + + + } + // called when player types /show private static void show(ShowMsg msg, ClientConnection origin) throws MsgSendException { @@ -1758,7 +1987,7 @@ public class ClientMessagePump implements NetMsgHandler { lootWindowRequest((LootWindowRequestMsg) msg, origin); break; case MOVEOBJECTTOCONTAINER: - LootActionManager.loot((LootMsg) msg, origin); + loot((LootMsg) msg, origin); break; case SHOWCOMBATINFO: show((ShowMsg) msg, origin); From b28c157a5c6d37f42bc6d38e98e39c1bdd481c64 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 10:46:43 -0500 Subject: [PATCH 17/68] Revert "optimized deleting items" This reverts commit 0ac7a1a7fa7a2fa8c20479b807aa46120cbe2c45. --- src/engine/net/client/ClientMessagePump.java | 64 +++++++++++--------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/src/engine/net/client/ClientMessagePump.java b/src/engine/net/client/ClientMessagePump.java index 50f576ae..54cbc291 100644 --- a/src/engine/net/client/ClientMessagePump.java +++ b/src/engine/net/client/ClientMessagePump.java @@ -542,41 +542,51 @@ public class ClientMessagePump implements NetMsgHandler { } - private static void deleteItem(DeleteItemMsg msg, ClientConnection origin) { + private static void DeleteItem(DeleteItemMsg msg, ClientConnection origin) { + + CharacterItemManager itemManager = origin.getPlayerCharacter().getCharItemManager(); + int uuid = msg.getUUID(); + + PlayerCharacter sourcePlayer = origin.getPlayerCharacter(); - if (sourcePlayer == null || !sourcePlayer.isAlive()) { + + if (sourcePlayer == null) return; - } - CharacterItemManager itemManager = sourcePlayer.getCharItemManager(); - Item item = Item.getFromCache(msg.getUUID()); - if (item == null || !canDeleteItem(item, itemManager)) { + if (!sourcePlayer.isAlive()) return; - } - int value = item.getItemBase().value; - if (item.getItemBase().isRune()) { - value = 500000; - } + Item i = Item.getFromCache(msg.getUUID()); - if (sourcePlayer.getCharItemManager().getGoldInventory().getNumOfItems() + value > 10000000) { + if (i == null) return; - } - if (itemManager.delete(item)) { - itemManager.addGoldToInventory(value, false); - itemManager.updateInventory(); - Dispatch dispatch = Dispatch.borrow(sourcePlayer, msg); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); - } - } + if(i.getItemBaseID() == 7) + return; //cant delete gold + + if (!itemManager.doesCharOwnThisItem(i.getObjectUUID())) + return; - private static boolean canDeleteItem(Item item, CharacterItemManager itemManager) { - return item.getItemBaseID() != 7 && // Can't delete gold - item.getItemBaseID() != 980066 && // Can't delete conc pots - item.canDestroy && - itemManager.doesCharOwnThisItem(item.getObjectUUID()) && - itemManager.inventoryContains(item); + if (!itemManager.inventoryContains(i)) + return; + + if(i.getItemBaseID() == 980066) + return; + + if (i.canDestroy) { + int value = i.getItemBase().value; + if(i.getItemBase().isRune()) + value = 500000; + if(sourcePlayer.getCharItemManager().getGoldInventory().getNumOfItems() + value > 10000000){ + return; + } + if (itemManager.delete(i) == true) { + sourcePlayer.getCharItemManager().addGoldToInventory(value,false); + sourcePlayer.getCharItemManager().updateInventory(); + Dispatch dispatch = Dispatch.borrow(sourcePlayer, msg); + DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); + } + } } private static void ackBankWindowOpened(AckBankWindowOpenedMsg msg, ClientConnection origin) { @@ -1969,7 +1979,7 @@ public class ClientMessagePump implements NetMsgHandler { TransferItemFromInventoryToEquip((TransferItemFromInventoryToEquipMsg) msg, origin); break; case DELETEOBJECT: - deleteItem((DeleteItemMsg) msg, origin); + DeleteItem((DeleteItemMsg) msg, origin); break; case VIEWRESOURCES: ViewResourcesMessage((ViewResourcesMessage) msg, origin); From f8e99a84b17ef30a9609d5a96a0a490fecbea1dc Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 11:01:28 -0500 Subject: [PATCH 18/68] optimized ManageCityAssetMsgHandler --- .../handlers/ManageCityAssetMsgHandler.java | 259 ++++++------------ 1 file changed, 91 insertions(+), 168 deletions(-) diff --git a/src/engine/net/client/handlers/ManageCityAssetMsgHandler.java b/src/engine/net/client/handlers/ManageCityAssetMsgHandler.java index 0fe3c58d..54e3469b 100644 --- a/src/engine/net/client/handlers/ManageCityAssetMsgHandler.java +++ b/src/engine/net/client/handlers/ManageCityAssetMsgHandler.java @@ -62,7 +62,6 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler { Building building; msg = (ManageCityAssetsMsg) baseMsg; - player = SessionManager.getPlayerCharacter(origin); if (player == null) @@ -72,34 +71,21 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler { if (building == null) { if (msg.actionType == 14) { - Zone zone = ZoneManager.findSmallestZone(player.getLoc()); - if (!zone.isPlayerCity()) { ErrorPopupMsg.sendErrorMsg(player, "Unable to find city to command."); return true; } - City city = City.GetCityFromCache(zone.getPlayerCityUUID()); - - if (city == null) { - ErrorPopupMsg.sendErrorMsg(player, "Unable to find city to command."); - return true; - } - - if (!city.getGuild().equals(player.getGuild())) { + if (city == null || !city.getGuild().equals(player.getGuild()) || + (!GuildStatusController.isInnerCouncil(player.getGuildStatus()) && + !GuildStatusController.isGuildLeader(player.getGuildStatus()))) { ErrorPopupMsg.sendErrorMsg(player, "You are not in the correct guild to command this city."); return true; } - - if (!GuildStatusController.isInnerCouncil(player.getGuildStatus()) && !GuildStatusController.isGuildLeader(player.getGuildStatus())) { - ErrorPopupMsg.sendErrorMsg(player, "You must be an Inner Council or Guild leader to access city commands."); - return true; - } ManageCityAssetsMsg mca = new ManageCityAssetsMsg(player, building); mca.actionType = 15; - Dispatch dispatch = Dispatch.borrow(player, mca); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); + DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, mca), DispatchChannel.SECONDARY); } return true; } @@ -111,181 +97,118 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler { outMsg.setTargetType(building.getObjectType().ordinal()); outMsg.setTargetID(building.getObjectUUID()); outMsg.setAssetName(building.getName()); - Dispatch dispatch = Dispatch.borrow(player, outMsg); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); + DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, outMsg), DispatchChannel.SECONDARY); return true; } - if (msg.actionType == 2 || msg.actionType == 22) { - - if (building.getBlueprint() != null && building.getBlueprint().getBuildingGroup() == engine.Enum.BuildingGroup.BANESTONE) { - - outMsg.actionType = 18; - outMsg.setTargetType(building.getObjectType().ordinal()); - outMsg.setTargetID(building.getObjectUUID()); - - } else if (BuildingManager.playerCanManage(player, building)) { //TODO allow Friends list. - configWindowState(player, building, outMsg); - outMsg.actionType = 3; - outMsg.setTargetType(building.getObjectType().ordinal()); - outMsg.setTargetID(building.getObjectUUID()); - outMsg.setTargetType3(building.getObjectType().ordinal()); - outMsg.setTargetID3(building.getObjectUUID()); - outMsg.setUnknown54(1); - - } else { - - if (building.getBlueprintUUID() != 0) - switch (building.getBlueprint().getBuildingGroup()) { - case SHRINE: - if (building.getRank() == -1) { - if (!Bounds.collide(player.getLoc(), building)) { - ErrorPopupMsg.sendErrorPopup(player, 64); - return true; - } - + switch (msg.actionType) { + case 2: + case 22: + if (building.getBlueprint() != null && building.getBlueprint().getBuildingGroup() == engine.Enum.BuildingGroup.BANESTONE) { + outMsg.actionType = 18; + outMsg.setTargetType(building.getObjectType().ordinal()); + outMsg.setTargetID(building.getObjectUUID()); + } else if (BuildingManager.playerCanManage(player, building)) { + configWindowState(player, building, outMsg); + outMsg.actionType = 3; + outMsg.setTargetType(building.getObjectType().ordinal()); + outMsg.setTargetID(building.getObjectUUID()); + outMsg.setTargetType3(building.getObjectType().ordinal()); + outMsg.setTargetID3(building.getObjectUUID()); + outMsg.setUnknown54(1); + } else { + // Handle other cases + if (building.getRank() == -1) { + if (!Bounds.collide(player.getLoc(), building)) { + ErrorPopupMsg.sendErrorPopup(player, 64); + return true; + } + switch (building.getBlueprint().getBuildingGroup()) { + case SHRINE: Shrine shrine = Shrine.shrinesByBuildingUUID.get(building.getObjectUUID()); - - if (shrine == null) - return true; - - if (shrine.getFavors() == 0) { + if (shrine == null || shrine.getFavors() == 0) { ErrorPopupMsg.sendErrorPopup(player, 166); // There is no more favor in this shrine to loot return true; } - - BuildingManager.lootBuilding(player, building); - return true; - } - break; - case WAREHOUSE: - //TODO check - if (building.getRank() == -1) { - if (!Bounds.collide(player.getLoc(), building)) { - ErrorPopupMsg.sendErrorPopup(player, 64); - return true; - } - + break; + case WAREHOUSE: Warehouse warehouse = Warehouse.warehouseByBuildingUUID.get(building.getObjectUUID()); - - if (warehouse == null) - return true; - - if (warehouse.isEmpty()) { + if (warehouse == null || warehouse.isEmpty()) { ErrorPopupMsg.sendErrorPopup(player, 167); // no more resources. return true; } - - BuildingManager.lootBuilding(player, building); - return true; - } + break; + } + } + AbstractCharacter owner = building.getOwner(); + if (owner == null) { + msg.actionType = 4; + DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, msg), DispatchChannel.SECONDARY); + } else { + outMsg.actionType = 4; + outMsg.setTargetType(building.getObjectType().ordinal()); + outMsg.setTargetID(building.getObjectUUID()); + outMsg.setAssetName(building.getName()); } - - if (building.getRank() == -1) - return true; - - AbstractCharacter owner = building.getOwner(); - - //no owner, send building info - if (owner == null) { - msg.actionType = 4; - - Dispatch dispatch = Dispatch.borrow(player, msg); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); - return true; } - outMsg.actionType = 4; + DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, outMsg), DispatchChannel.SECONDARY); + return true; + case 13: + outMsg.actionType = 13; + DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, outMsg), DispatchChannel.SECONDARY); + return true; + case 5: + building.setName(msg.getAssetName()); + configWindowState(player, building, outMsg); + outMsg.actionType = 3; outMsg.setTargetType(building.getObjectType().ordinal()); outMsg.setTargetID(building.getObjectUUID()); - outMsg.setAssetName(building.getName()); - - } - Dispatch dispatch = Dispatch.borrow(player, outMsg); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); - return true; + outMsg.setTargetType3(GameObjectType.Building.ordinal()); + outMsg.setTargetID3(building.getObjectUUID()); + outMsg.setAssetName1(building.getName()); + outMsg.setUnknown54(1); + DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, outMsg), DispatchChannel.SECONDARY); + return true; + case 14: + ManageCityAssetsMsg mca = new ManageCityAssetsMsg(player, building); + mca.actionType = 15; + DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, mca), DispatchChannel.SECONDARY); + return true; + case 20: + // Handle case 20 + return handleCase20(player, outMsg, building, msg, origin); + default: + return true; } + } - if (msg.actionType == 13) { - outMsg.actionType = 13; - Dispatch dispatch = Dispatch.borrow(player, outMsg); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); + private boolean handleCase20(PlayerCharacter player, ManageCityAssetsMsg outMsg, Building building, ManageCityAssetsMsg msg, ClientConnection origin) throws MsgSendException { + Zone baneZone = building.getParentZone(); + if (baneZone == null) return true; - } - - - //Rename Building. - - if (msg.actionType == 5) { - - //TODO we need to check names before allowing - building.setName(msg.getAssetName()); - configWindowState(player, building, outMsg); - - outMsg.actionType = 3; - outMsg.setTargetType(building.getObjectType().ordinal()); - outMsg.setTargetID(building.getObjectUUID()); - outMsg.setTargetType3(GameObjectType.Building.ordinal()); - outMsg.setTargetID3(building.getObjectUUID()); - outMsg.setAssetName1(building.getName()); - outMsg.setUnknown54(1); - - Dispatch dispatch = Dispatch.borrow(player, outMsg); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); - + City banedCity = City.getCity(baneZone.getPlayerCityUUID()); + if (banedCity == null) return true; - - //TOL, update city name also - //TODO update city and zone in database - //TODO update city map data in game server - } - - if (msg.actionType == 14) { - ManageCityAssetsMsg mca = new ManageCityAssetsMsg(player, building); - mca.actionType = 15; - Dispatch dispatch = Dispatch.borrow(player, mca); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); + Bane bane = banedCity.getBane(); + if (bane == null || bane.getLiveDate() != null || player.getGuild() != banedCity.getGuild() || !GuildStatusController.isInnerCouncil(player.getGuildStatus())) return true; - } - - if (msg.actionType == 20) { - - Zone baneZone = building.getParentZone(); - - if (baneZone == null) - return true; - - City banedCity = City.getCity(baneZone.getPlayerCityUUID()); - - if (banedCity == null) - return true; - - Bane bane = banedCity.getBane(); - - if (bane == null || bane.getLiveDate() != null || player.getGuild() != banedCity.getGuild() || GuildStatusController.isInnerCouncil(player.getGuildStatus()) == false) - return true; - - int baneHour = msg.getBaneHour(); - - if (baneHour < 16 || baneHour > 24) { - PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); - return true; - } - - DateTime baneLive = new DateTime(bane.getPlacementDate()); - baneLive = baneHour == 24 ? baneLive.plusDays(3) : baneLive.plusDays(2); - baneLive = baneHour == 24 ? baneLive.hourOfDay().setCopy(0) : baneLive.hourOfDay().setCopy(baneHour); - baneLive = baneLive.minuteOfHour().setCopy(0); - baneLive = baneLive.secondOfMinute().setCopy(1); - bane.setLiveDate(baneLive); - outMsg.actionType = 18; - - Dispatch dispatch = Dispatch.borrow(player, outMsg); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); + int baneHour = msg.getBaneHour(); + if (baneHour < 16 || baneHour > 24) { + PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); return true; } + DateTime baneLive = new DateTime(bane.getPlacementDate()); + baneLive = baneHour == 24 ? baneLive.plusDays(3) : baneLive.plusDays(2); + baneLive = baneHour == 24 ? baneLive.hourOfDay().setCopy(0) : baneLive.hourOfDay().setCopy(baneHour); + baneLive = baneLive.minuteOfHour().setCopy(0); + baneLive = baneLive.secondOfMinute().setCopy(1); + bane.setLiveDate(baneLive); + outMsg.actionType = 18; + DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, outMsg), DispatchChannel.SECONDARY); return true; } + public void configWindowState(PlayerCharacter player, Building building, ManageCityAssetsMsg manageCityAssetsMsg) { // Tests to turn on upgrade button if a building is not From c792e49fdcf726956bf177bf4c2ed3b6ed414a41 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 11:14:24 -0500 Subject: [PATCH 19/68] added 30 second delay to Enrollment Officer --- src/engine/net/client/msg/VendorDialogMsg.java | 10 ++++++++++ src/engine/objects/PlayerCharacter.java | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/engine/net/client/msg/VendorDialogMsg.java b/src/engine/net/client/msg/VendorDialogMsg.java index 25442367..49bb8978 100644 --- a/src/engine/net/client/msg/VendorDialogMsg.java +++ b/src/engine/net/client/msg/VendorDialogMsg.java @@ -137,10 +137,20 @@ public class VendorDialogMsg extends ClientNetMsg { } if(contract.getObjectUUID() == 1502040){ + if(!playerCharacter.getTimestamps().containsKey("lastBoxChange")) + playerCharacter.getTimestamps().put("lastBoxChange",System.currentTimeMillis() - 1000); + + if(playerCharacter.getTimeStamp("lastBoxChange") + 30000L > System.currentTimeMillis()) { + return; + } + if(playerCharacter.isBoxed == false) { ChatManager.chatSystemInfo(playerCharacter, "You Are Already The Active Character."); return; } + + playerCharacter.getTimestamps().put("lastBoxChange",System.currentTimeMillis()); + playerCharacter.isBoxed = false; playerCharacter.removeEffectBySource(Enum.EffectSourceType.DeathShroud,50,true); ChatManager.chatSystemInfo(playerCharacter, "Promoting To Active Duty"); diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index f9aff3f3..01bcc626 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -177,6 +177,8 @@ public class PlayerCharacter extends AbstractCharacter { public float ZergMultiplier = 1.0f; public int mineAppliedID = 0; + + public long lastBoxChange = System.currentTimeMillis(); /** * No Id Constructor */ From 353d211a043c4290da1884cda67e3ea2e43cac61 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 11:15:38 -0500 Subject: [PATCH 20/68] PC cleanup --- src/engine/objects/PlayerCharacter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 01bcc626..c4e9abe2 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -178,7 +178,6 @@ public class PlayerCharacter extends AbstractCharacter { public float ZergMultiplier = 1.0f; public int mineAppliedID = 0; - public long lastBoxChange = System.currentTimeMillis(); /** * No Id Constructor */ From a11b590573f4e2a6843074a46903d25cf8370cdd Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 11:26:02 -0500 Subject: [PATCH 21/68] revert deposit change --- src/engine/objects/Warehouse.java | 158 ++++++++++++++++++++++++++---- 1 file changed, 140 insertions(+), 18 deletions(-) diff --git a/src/engine/objects/Warehouse.java b/src/engine/objects/Warehouse.java index 813df7a8..e1df816d 100644 --- a/src/engine/objects/Warehouse.java +++ b/src/engine/objects/Warehouse.java @@ -289,48 +289,170 @@ public class Warehouse extends AbstractWorldObject { } public synchronized boolean deposit(PlayerCharacter pc, Item resource, int amount, boolean removeFromInventory, boolean transaction) { + ClientConnection origin = pc.getClientConnection(); - if (origin == null || amount < 0 || resource == null) { - if (amount < 0) Logger.info(pc.getFirstName() + " Attempting to Dupe!!!!!!"); + if (origin == null) + return false; + + if (amount < 0) { + Logger.info(pc.getFirstName() + " Attempting to Dupe!!!!!!"); return false; } ItemBase ib = resource.getItemBase(); - if (ib == null) return false; - Integer currentResourceAmount = this.resources.get(ib); - if (currentResourceAmount == null) return false; + if (ib == null) + return false; + + if (this.resources.get(ib) == null) + return false; CharacterItemManager itemMan = pc.getCharItemManager(); - if (itemMan == null || !itemMan.doesCharOwnThisItem(resource.getObjectUUID())) return false; + + if (itemMan == null) + return false; + if (itemMan.getGoldTrading() > 0) { ErrorPopupMsg.sendErrorPopup(pc, 195); return false; } - if (!resource.validForInventory(origin, pc, itemMan) || resource.getNumOfItems() < amount) return false; - int newAmount = currentResourceAmount + amount; - Integer maxResourceAmount = Warehouse.getMaxResources().get(ib.getUUID()); - if (newAmount > (maxResourceAmount != null ? maxResourceAmount : Integer.MAX_VALUE)) { - // ChatManager.chatSystemInfo(pc, "The Warehouse is at its maximum for this type of resource."); + if (!itemMan.doesCharOwnThisItem(resource.getObjectUUID())) + return false; + + if (!resource.validForInventory(origin, pc, itemMan)) + return false; + + if (resource.getNumOfItems() < amount) + return false; + + int oldAmount = resources.get(ib); + + int newAmount = oldAmount + amount; + + if (newAmount > Warehouse.getMaxResources().get(ib.getUUID())) { + //ChatManager.chatSystemInfo(pc, "The Warehouse is at it's maximum for this type of resource."); return false; } + if (removeFromInventory) { - if (!removeFromInventory(itemMan, ib, amount, pc)) return false; - } + if (ib.getUUID() == 7) { + + if (itemMan.getGoldInventory().getNumOfItems() - amount < 0) + return false; + + if (itemMan.getGoldInventory().getNumOfItems() - amount > MBServerStatics.PLAYER_GOLD_LIMIT) + return false; + + if (!itemMan.modifyInventoryGold(-amount)) { + //ChatManager.chatSystemError(pc, "You do not have this Gold."); + return false; + } + + UpdateGoldMsg ugm = new UpdateGoldMsg(pc); + ugm.configure(); + Dispatch dispatch = Dispatch.borrow(pc, ugm); + DispatchMessage.dispatchMsgDispatch(dispatch, engine.Enum.DispatchChannel.SECONDARY); + + itemMan.updateInventory(); + } else { + itemMan.delete(resource); + itemMan.updateInventory(); + } + } itemMan.updateInventory(); - if (!updateDatabase(ib.getUUID(), newAmount)) return false; + int itemID = ib.getUUID(); + boolean worked = false; + switch (itemID) { + case 7: + worked = DbManager.WarehouseQueries.updateGold(this, newAmount); + break; + case 1580000: + worked = DbManager.WarehouseQueries.updateStone(this, newAmount); + break; + case 1580001: + worked = DbManager.WarehouseQueries.updateTruesteel(this, newAmount); + break; + case 1580002: + worked = DbManager.WarehouseQueries.updateIron(this, newAmount); + break; + case 1580003: + worked = DbManager.WarehouseQueries.updateAdamant(this, newAmount); + break; + case 1580004: + worked = DbManager.WarehouseQueries.updateLumber(this, newAmount); + break; + case 1580005: + worked = DbManager.WarehouseQueries.updateOak(this, newAmount); + break; + case 1580006: + worked = DbManager.WarehouseQueries.updateBronzewood(this, newAmount); + break; + case 1580007: + worked = DbManager.WarehouseQueries.updateMandrake(this, newAmount); + break; + case 1580008: + worked = DbManager.WarehouseQueries.updateCoal(this, newAmount); + break; + case 1580009: + worked = DbManager.WarehouseQueries.updateAgate(this, newAmount); + break; + case 1580010: + worked = DbManager.WarehouseQueries.updateDiamond(this, newAmount); + break; + case 1580011: + worked = DbManager.WarehouseQueries.updateOnyx(this, newAmount); + break; + case 1580012: + worked = DbManager.WarehouseQueries.updateAzoth(this, newAmount); + break; + case 1580013: + worked = DbManager.WarehouseQueries.updateOrichalk(this, newAmount); + break; + case 1580014: + worked = DbManager.WarehouseQueries.updateAntimony(this, newAmount); + break; + case 1580015: + worked = DbManager.WarehouseQueries.updateSulfur(this, newAmount); + break; + case 1580016: + worked = DbManager.WarehouseQueries.updateQuicksilver(this, newAmount); + break; + case 1580017: + worked = DbManager.WarehouseQueries.updateGalvor(this, newAmount); + break; + case 1580018: + worked = DbManager.WarehouseQueries.updateWormwood(this, newAmount); + break; + case 1580019: + worked = DbManager.WarehouseQueries.updateObsidian(this, newAmount); + break; + case 1580020: + worked = DbManager.WarehouseQueries.updateBloodstone(this, newAmount); + break; + case 1580021: + worked = DbManager.WarehouseQueries.updateMithril(this, newAmount); + break; + } - this.resources.put(ib, newAmount); + if (!worked) + return false; + + resources.put(ib, newAmount); - if (transaction) { - Resource resourceType = getResourceType(resource); + Resource resourceType; + + if (resource.getItemBase().getType().equals(engine.Enum.ItemType.GOLD)) + resourceType = Resource.GOLD; + else + resourceType = Resource.valueOf(resource.getItemBase().getName().toUpperCase()); + + if (transaction) this.AddTransactionToWarehouse(pc.getObjectType(), pc.getObjectUUID(), TransactionType.DEPOSIT, resourceType, amount); - } return true; } From 023057668ac30d201208d17da174ae198f40911b Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 13:34:03 -0500 Subject: [PATCH 22/68] attempted warehouse delay issue resolution --- .../db/handlers/dbWarehouseHandler.java | 4 +- src/engine/objects/CharacterItemManager.java | 4 ++ src/engine/objects/PlayerCharacter.java | 17 ++++++ src/engine/objects/Warehouse.java | 56 ++++++++++--------- 4 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/engine/db/handlers/dbWarehouseHandler.java b/src/engine/db/handlers/dbWarehouseHandler.java index 677e67eb..8d410a58 100644 --- a/src/engine/db/handlers/dbWarehouseHandler.java +++ b/src/engine/db/handlers/dbWarehouseHandler.java @@ -45,7 +45,7 @@ public class dbWarehouseHandler extends dbHandlerBase { list.add(building); break; case "warehouse": - Warehouse warehouse = new Warehouse(rs); + Warehouse warehouse = new Warehouse(rs, depositQueItem); DbManager.addToCache(warehouse); list.add(warehouse); break; @@ -543,7 +543,7 @@ public class dbWarehouseHandler extends dbHandlerBase { ResultSet rs = preparedStatement.executeQuery(); while (rs.next()) { - warehouse = new Warehouse(rs); + warehouse = new Warehouse(rs, depositQueItem); warehouse.runAfterLoad(); warehouse.loadAllTransactions(); } diff --git a/src/engine/objects/CharacterItemManager.java b/src/engine/objects/CharacterItemManager.java index 80c8950b..d33531b9 100644 --- a/src/engine/objects/CharacterItemManager.java +++ b/src/engine/objects/CharacterItemManager.java @@ -70,6 +70,8 @@ public class CharacterItemManager { */ private byte equipVer = (byte) 0; + public boolean updateLock = false; + public CharacterItemManager(AbstractCharacter ac) { super(); this.absCharacter = ac; @@ -2286,6 +2288,8 @@ public class CharacterItemManager { if (this.absCharacter.getObjectType().equals(GameObjectType.PlayerCharacter) == false) return; + if(this.updateLock) + return; PlayerCharacter pc = (PlayerCharacter) this.absCharacter; UpdateInventoryMsg updateInventoryMsg = new UpdateInventoryMsg(inventory, this.getBank(), this.getGoldInventory(), add); diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index c4e9abe2..31ff999c 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -178,6 +178,9 @@ public class PlayerCharacter extends AbstractCharacter { public float ZergMultiplier = 1.0f; public int mineAppliedID = 0; + public boolean depositingWarehouse = false; + public Building warehouseBuilding; + /** * No Id Constructor */ @@ -4885,6 +4888,20 @@ public class PlayerCharacter extends AbstractCharacter { this.updateLock.writeLock().unlock(); } } + if(this.depositingWarehouse){ + long sinceLast = System.currentTimeMillis() - this.getTimestamps().get("lastDepositWarehouse"); + if(sinceLast > 1000) { + this.depositingWarehouse = false; + ViewResourcesMessage vrm = new ViewResourcesMessage(this); + vrm.setGuild(this.getGuild()); + vrm.setWarehouseBuilding(this.warehouseBuilding); + vrm.configure(); + Dispatch dispatch = Dispatch.borrow(this, vrm); + DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); + this.charItemManager.updateLock = false; + this.charItemManager.updateInventory(); + } + } } public static boolean checkIfBoxed(PlayerCharacter player){ diff --git a/src/engine/objects/Warehouse.java b/src/engine/objects/Warehouse.java index e1df816d..5db69727 100644 --- a/src/engine/objects/Warehouse.java +++ b/src/engine/objects/Warehouse.java @@ -128,42 +128,44 @@ public class Warehouse extends AbstractWorldObject { } public static void warehouseDeposit(MerchantMsg msg, PlayerCharacter player, NPC npc, ClientConnection origin) { - Item resource = Item.getFromCache(msg.getItemID()); - if (resource == null) { + Building warehouseBuilding = npc.getBuilding(); + if (warehouseBuilding == null) { return; } - int depositAmount = msg.getAmount(); - CharacterItemManager itemMan = player.getCharItemManager(); + player.getTimestamps().put("lastDepositWarehouse", System.currentTimeMillis()); + player.depositingWarehouse = true; + player.warehouseBuilding = warehouseBuilding; + player.getCharItemManager().updateLock = true; + Item resource = Item.getFromCache(msg.getItemID()); - if (!itemMan.doesCharOwnThisItem(resource.getObjectUUID())) { - return; - } + if (resource == null) { + return; + } - Building warehouseBuilding = npc.getBuilding(); - if (warehouseBuilding == null) { - return; - } + int depositAmount = msg.getAmount(); + CharacterItemManager itemMan = player.getCharItemManager(); - Warehouse warehouse = warehouseByBuildingUUID.get(warehouseBuilding.getObjectUUID()); - if (warehouse == null) { - return; - } + if (!itemMan.doesCharOwnThisItem(resource.getObjectUUID())) { + return; + } - if (!warehouse.deposit(player, resource, depositAmount, true, true)) { - // Optional: Uncomment these lines for debugging/logging purposes. - // ChatManager.chatGuildError(player, "Failed to deposit " + resource.getItemBase().getName() + "."); - // Logger.debug("OpenWindow", player.getName() + " Failed to deposit Item with ID " + resource.getObjectUUID() + " from Warehouse With ID = " + warehouseBuilding.getObjectUUID()); - return; - } + Warehouse warehouse = warehouseByBuildingUUID.get(warehouseBuilding.getObjectUUID()); + if (warehouse == null) { + return; + } - ViewResourcesMessage vrm = new ViewResourcesMessage(player); - vrm.setGuild(player.getGuild()); - vrm.setWarehouseBuilding(warehouseBuilding); - vrm.configure(); - Dispatch dispatch = Dispatch.borrow(player, vrm); - DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); + if (!warehouse.deposit(player, resource, depositAmount, true, true)) { + return; + } + + //ViewResourcesMessage vrm = new ViewResourcesMessage(player); + //vrm.setGuild(player.getGuild()); + //vrm.setWarehouseBuilding(warehouseBuilding); + //vrm.configure(); + //Dispatch dispatch = Dispatch.borrow(player, vrm); + //DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); } public static void warehouseWithdraw(MerchantMsg msg, PlayerCharacter player, NPC npc, ClientConnection origin) { From b7ebb728e2a0e0e964f6d3b89d356a0a0e56d0c8 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 13:35:49 -0500 Subject: [PATCH 23/68] attempted warehouse delay issue resolution --- src/engine/db/handlers/dbWarehouseHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/db/handlers/dbWarehouseHandler.java b/src/engine/db/handlers/dbWarehouseHandler.java index 8d410a58..677e67eb 100644 --- a/src/engine/db/handlers/dbWarehouseHandler.java +++ b/src/engine/db/handlers/dbWarehouseHandler.java @@ -45,7 +45,7 @@ public class dbWarehouseHandler extends dbHandlerBase { list.add(building); break; case "warehouse": - Warehouse warehouse = new Warehouse(rs, depositQueItem); + Warehouse warehouse = new Warehouse(rs); DbManager.addToCache(warehouse); list.add(warehouse); break; @@ -543,7 +543,7 @@ public class dbWarehouseHandler extends dbHandlerBase { ResultSet rs = preparedStatement.executeQuery(); while (rs.next()) { - warehouse = new Warehouse(rs, depositQueItem); + warehouse = new Warehouse(rs); warehouse.runAfterLoad(); warehouse.loadAllTransactions(); } From 2ca51d6a836d6d6c507922969159b3c03ca686d1 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 14:07:30 -0500 Subject: [PATCH 24/68] merchant resource stacking --- src/engine/net/client/ClientMessagePump.java | 36 +++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/engine/net/client/ClientMessagePump.java b/src/engine/net/client/ClientMessagePump.java index 54cbc291..3398eeb0 100644 --- a/src/engine/net/client/ClientMessagePump.java +++ b/src/engine/net/client/ClientMessagePump.java @@ -1464,11 +1464,37 @@ public class ClientMessagePump implements NetMsgHandler { ChatManager.chatSystemError(sourcePlayer, "Failed To Buy Item"); return; } - buy = Item.createItemForPlayer(sourcePlayer, ib); - if (buy != null) { - me.transferEnchants(buy); - itemMan.addItemToInventory(buy); - //itemMan.updateInventory(); + if(me.getItemBase().getType().equals(ItemType.RESOURCE)){ + boolean stacked = false; + for(Item item : itemMan.getInventory()){ + int itemID = item.getItemBaseID(); + int meID = me.getItemBase().getUUID(); + if(itemID == meID){ + int maxStack = Warehouse.maxResources.get(meID); + if(maxStack > item.getNumOfItems() + 1){ + item.setNumOfItems(item.getNumOfItems() + 1); + stacked = true; + itemMan.updateInventory(); + item.updateDatabase(); + break; + } + } + } + if(!stacked){ + buy = Item.createItemForPlayer(sourcePlayer, ib); + if (buy != null) { + me.transferEnchants(buy); + itemMan.addItemToInventory(buy); + //itemMan.updateInventory(); + } + } + }else { + buy = Item.createItemForPlayer(sourcePlayer, ib); + if (buy != null) { + me.transferEnchants(buy); + itemMan.addItemToInventory(buy); + //itemMan.updateInventory(); + } } } } From 366815f1f95cc805b3a30d2c8fb0975f11aecf59 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 14:11:29 -0500 Subject: [PATCH 25/68] databse update for stacked resources --- src/engine/db/handlers/dbItemHandler.java | 20 ++++++++++++++++++++ src/engine/net/client/ClientMessagePump.java | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/engine/db/handlers/dbItemHandler.java b/src/engine/db/handlers/dbItemHandler.java index 2fc9b64e..4cd9f336 100644 --- a/src/engine/db/handlers/dbItemHandler.java +++ b/src/engine/db/handlers/dbItemHandler.java @@ -504,4 +504,24 @@ public class dbItemHandler extends dbHandlerBase { return false; } } + + public boolean UPDATE_NUM_ITEMS(final Item item, int newValue, int oldValue) { + + if (item.getItemBase().getType().equals(ItemType.GOLD)) + return false; + + try (Connection connection = DbManager.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_item` SET `item_numberOfItems`=? WHERE `UID`=?")) { + + preparedStatement.setInt(1, newValue); + preparedStatement.setLong(2, item.getObjectUUID()); + + return (preparedStatement.executeUpdate() > 0); + + } catch (SQLException e) { + Logger.error(e); + return false; + } + + } } diff --git a/src/engine/net/client/ClientMessagePump.java b/src/engine/net/client/ClientMessagePump.java index 3398eeb0..f1121716 100644 --- a/src/engine/net/client/ClientMessagePump.java +++ b/src/engine/net/client/ClientMessagePump.java @@ -1475,7 +1475,7 @@ public class ClientMessagePump implements NetMsgHandler { item.setNumOfItems(item.getNumOfItems() + 1); stacked = true; itemMan.updateInventory(); - item.updateDatabase(); + DbManager.ItemQueries.UPDATE_NUM_ITEMS(item,item.getNumOfItems(),0); break; } } From 85077a5e56bf05fd4bdc2711081ca58da6f2eaab Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 14:22:06 -0500 Subject: [PATCH 26/68] databse update for stacked resources --- src/engine/net/client/ClientMessagePump.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/engine/net/client/ClientMessagePump.java b/src/engine/net/client/ClientMessagePump.java index f1121716..10d3a935 100644 --- a/src/engine/net/client/ClientMessagePump.java +++ b/src/engine/net/client/ClientMessagePump.java @@ -1470,7 +1470,9 @@ public class ClientMessagePump implements NetMsgHandler { int itemID = item.getItemBaseID(); int meID = me.getItemBase().getUUID(); if(itemID == meID){ - int maxStack = Warehouse.maxResources.get(meID); + if(Warehouse.maxResources.isEmpty()) + Warehouse.getMaxResources(); + int maxStack = Warehouse.maxResources.get(itemID); if(maxStack > item.getNumOfItems() + 1){ item.setNumOfItems(item.getNumOfItems() + 1); stacked = true; From 1359417b408675a5ad431a774cc08bdedd476749 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 14:23:16 -0500 Subject: [PATCH 27/68] databse update for stacked resources --- src/engine/net/client/ClientMessagePump.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/net/client/ClientMessagePump.java b/src/engine/net/client/ClientMessagePump.java index 10d3a935..60dbd91d 100644 --- a/src/engine/net/client/ClientMessagePump.java +++ b/src/engine/net/client/ClientMessagePump.java @@ -1464,7 +1464,7 @@ public class ClientMessagePump implements NetMsgHandler { ChatManager.chatSystemError(sourcePlayer, "Failed To Buy Item"); return; } - if(me.getItemBase().getType().equals(ItemType.RESOURCE)){ + if(me.getItemBase().getType().equals(ItemType.RESOURCE) && npc.getContractID() == 900){ boolean stacked = false; for(Item item : itemMan.getInventory()){ int itemID = item.getItemBaseID(); From f7e6307d663781968afd81765f217ecea578b55d Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 21:19:53 -0500 Subject: [PATCH 28/68] Mine optimization --- src/engine/workthreads/MineThread.java | 42 ++++++++++++++------------ 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/engine/workthreads/MineThread.java b/src/engine/workthreads/MineThread.java index 281e21f0..fc7197f0 100644 --- a/src/engine/workthreads/MineThread.java +++ b/src/engine/workthreads/MineThread.java @@ -23,43 +23,45 @@ public class MineThread implements Runnable { @Override public void run() { LocalDateTime nextPulse = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0); - while (true){ - if(LocalDateTime.now().isAfter(nextPulse)) { - for (Mine mine : Mine.getMines()) { + while (true) { + LocalDateTime now = LocalDateTime.now(); - if(nextPulse.getHour() == 2 && nextPulse.getMinute() == 0){ + if (now.isAfter(nextPulse)) { + for (Mine mine : Mine.getMines()) { + // Reset mine at 4:00 AM + if (nextPulse.getHour() == 4 && nextPulse.getMinute() == 0) { mine.wasClaimed = false; mine.hasProduced = false; - } - Building mineTower = BuildingManager.getBuilding(mine.getBuildingID()); - if (mineTower == null) + Building mineTower = BuildingManager.getBuilding(mine.getBuildingID()); + if (mineTower == null) { continue; + } - int minute = 0; - if (mine.firstThirty == false) - minute = 30; - - LocalDateTime openTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(minute).withSecond(0); + int minute = mine.firstThirty ? 0 : 30; + LocalDateTime openTime = now.withHour(mine.liveTime).withMinute(minute).withSecond(0).withNano(0); LocalDateTime closeTime = openTime.plusMinutes(29); - //current time is after start time and before close time, open mine window - if (LocalDateTime.now().isAfter(openTime.minusMinutes(1)) && !mine.wasClaimed && !mine.wasOpened) { + if (!mine.wasClaimed && !mine.wasOpened && now.isAfter(openTime.minusMinutes(1))) { mineWindowOpen(mine); continue; } - if (mine.isActive) { - - if (LocalDateTime.now().isAfter(closeTime) && mineTower.getRank() > 0) - mineWindowClose(mine); //mine was never knocked down, close window - if (LocalDateTime.now().isAfter(closeTime) && mineTower.getRank() < 1 && mine.lastClaimer != null) - mineWindowClose(mine); //mine was knocked down and was claimed, close window + if (mine.isActive && now.isAfter(closeTime)) { + if (mineTower.getRank() > 0 || (mineTower.getRank() < 1 && mine.lastClaimer != null)) { + mineWindowClose(mine); + } } } nextPulse = nextPulse.plusMinutes(30); } + + try { + Thread.sleep(1000); // Avoid busy-waiting + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } } } From b6a9a0c813a9e05ada62007cc1c70e87513b4f24 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 20 May 2024 21:26:39 -0500 Subject: [PATCH 29/68] detection of using /tar --- src/engine/net/client/ClientMessagePump.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/engine/net/client/ClientMessagePump.java b/src/engine/net/client/ClientMessagePump.java index 60dbd91d..ec4ab4ed 100644 --- a/src/engine/net/client/ClientMessagePump.java +++ b/src/engine/net/client/ClientMessagePump.java @@ -148,6 +148,12 @@ public class ClientMessagePump implements NetMsgHandler { pc.setActive(true); pc.setLastTarget(GameObjectType.values()[msg.getTargetType()], msg.getTargetID()); + + if(!pc.getTimestamps().containsKey("lastTab")) + pc.getTimestamps().put("lastTab",System.currentTimeMillis()); + + if(System.currentTimeMillis() - pc.getTimestamps().get("lastTab") < 100) + Logger.error("USE OF /TAR SUSPECTED BY PLAYER: " + pc.getName()); } private static void social(SocialMsg msg, ClientConnection origin) throws MsgSendException { From 5e84ee8b117bbc75b235cc847df3c33bf49cef36 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 14:16:03 -0500 Subject: [PATCH 30/68] pet run/walk determined by owner --- src/engine/mobileAI/MobAI.java | 36 +++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index a44722a7..d75ce99f 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -428,22 +428,30 @@ public class MobAI { mob.updateLocation(); } - boolean combatState = mob.isCombat(); - mob.setCombat(mob.combatTarget != null); - if(combatState != mob.isCombat()){ - //send message to update combat state - UpdateStateMsg rwss = new UpdateStateMsg(); - rwss.setPlayer(mob); - DispatchMessage.sendToAllInRange(mob, rwss); - } + if(!mob.isPet()) { + boolean combatState = mob.isCombat(); + mob.setCombat(mob.combatTarget != null); + if (combatState != mob.isCombat()) { + //send message to update combat state + UpdateStateMsg rwss = new UpdateStateMsg(); + rwss.setPlayer(mob); + DispatchMessage.sendToAllInRange(mob, rwss); + } - boolean walking = mob.isWalk(); - mob.setWalkMode(mob.combatTarget == null); - if(walking != mob.isWalk()){ - //send message to update run/walk state - MovementManager.sendRWSSMsg(mob); + boolean walking = mob.isWalk(); + mob.setWalkMode(mob.combatTarget == null); + if (walking != mob.isWalk()) { + //send message to update run/walk state + MovementManager.sendRWSSMsg(mob); + } + }else { + boolean walking = mob.isWalk(); + mob.setWalkMode(mob.guardCaptain.isWalk()); + if (walking != mob.isWalk()) { + //send message to update run/walk state + MovementManager.sendRWSSMsg(mob); + } } - switch (mob.behaviourType) { case GuardCaptain: GuardCaptainLogic(mob); From 77f2e413c9f9a2ddee305e04c8826bbd2653f523 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 14:20:33 -0500 Subject: [PATCH 31/68] Mine time and cap changes --- src/engine/objects/Mine.java | 44 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index 25d181f4..77dddbdd 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -120,13 +120,13 @@ public class Mine extends AbstractGameObject { public static void SetTimes(){ try { - EuroMines.get(0).liveTime = 20; - EuroMines.get(1).liveTime = 20; + EuroMines.get(0).liveTime = 19; + EuroMines.get(1).liveTime = 19; EuroMines.get(2).liveTime = 20; EuroMines.get(3).liveTime = 20; - EuroMines.get(4).liveTime = 20; - EuroMines.get(5).liveTime = 20; - EuroMines.get(6).liveTime = 20; + EuroMines.get(4).liveTime = 21; + EuroMines.get(5).liveTime = 21; + EuroMines.get(6).liveTime = 22; }catch(Exception e){ } @@ -150,19 +150,19 @@ public class Mine extends AbstractGameObject { } try{ AmericaMines.get(0).liveTime = 1; - AmericaMines.get(1).liveTime = 1; - AmericaMines.get(2).liveTime = 1; - AmericaMines.get(3).liveTime = 2; - AmericaMines.get(4).liveTime = 2; - AmericaMines.get(5).liveTime = 2; - AmericaMines.get(6).liveTime = 2; - AmericaMines.get(7).liveTime = 2; - AmericaMines.get(8).liveTime = 2; - AmericaMines.get(9).liveTime = 2; - AmericaMines.get(10).liveTime = 3; - AmericaMines.get(11).liveTime = 3; - AmericaMines.get(12).liveTime = 3; - AmericaMines.get(13).liveTime = 3; + AmericaMines.get(1).liveTime = 2; + AmericaMines.get(2).liveTime = 2; + AmericaMines.get(3).liveTime = 3; + AmericaMines.get(4).liveTime = 3; + AmericaMines.get(5).liveTime = 3; + AmericaMines.get(6).liveTime = 3; + AmericaMines.get(7).liveTime = 3; + AmericaMines.get(8).liveTime = 3; + AmericaMines.get(9).liveTime = 3; + AmericaMines.get(10).liveTime = 4; + AmericaMines.get(11).liveTime = 4; + AmericaMines.get(12).liveTime = 4; + AmericaMines.get(13).liveTime = 5; }catch(Exception e){ } @@ -174,10 +174,10 @@ public class Mine extends AbstractGameObject { mine.capSize = 3; break; case 2: - mine.capSize = 5; + mine.capSize = 3; break; case 3: - mine.capSize = 10; + mine.capSize = 3; break; case 4: mine.capSize = 3; @@ -204,7 +204,7 @@ public class Mine extends AbstractGameObject { mine.capSize = 5; break; case 3: - mine.capSize = 10; + mine.capSize = 5; break; case 4: mine.capSize = 3; @@ -232,7 +232,7 @@ public class Mine extends AbstractGameObject { mine.capSize = 5; break; case 3: - mine.capSize = 10; + mine.capSize = 5; break; case 4: mine.capSize = 3; From f80d50f95e5e457c24e9d4fb0e8d20d6c2f1ff89 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 14:23:59 -0500 Subject: [PATCH 32/68] buildings cannot be deleted if the city is under siege --- src/engine/net/client/handlers/DestroyBuildingHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/net/client/handlers/DestroyBuildingHandler.java b/src/engine/net/client/handlers/DestroyBuildingHandler.java index 18ce4d05..d25f40cf 100644 --- a/src/engine/net/client/handlers/DestroyBuildingHandler.java +++ b/src/engine/net/client/handlers/DestroyBuildingHandler.java @@ -62,7 +62,7 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler { if (city != null) bane = city.getBane(); - if (bane != null && bane.getSiegePhase() == Enum.SiegePhase.WAR) { + if (bane != null) { ErrorPopupMsg.sendErrorPopup(pc, 171); return true; } From 58916c35c7b1a5a9dbdbd98c2f7b8e9626b1bf74 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 14:26:57 -0500 Subject: [PATCH 33/68] shrines can be destroyed --- src/engine/net/client/handlers/DestroyBuildingHandler.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/engine/net/client/handlers/DestroyBuildingHandler.java b/src/engine/net/client/handlers/DestroyBuildingHandler.java index d25f40cf..df80727a 100644 --- a/src/engine/net/client/handlers/DestroyBuildingHandler.java +++ b/src/engine/net/client/handlers/DestroyBuildingHandler.java @@ -71,9 +71,11 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler { if (blueprint.getBuildingGroup() == BuildingGroup.TOL) return true; - // Can't destroy a shrine - if (blueprint.getBuildingGroup() == BuildingGroup.SHRINE) + // destorying a shrine will yield a rubble pile for looting + if (blueprint.getBuildingGroup() == BuildingGroup.SHRINE) { + building.modifyHealth(-building.getHealth(), origin.getPlayerCharacter()); return true; + } // Cannot destroy mines outside of normal mine mechanics From b46eb8639da10b5901d2cf981aa2bf6617b51b3a Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 14:34:17 -0500 Subject: [PATCH 34/68] capturing city will cede all buildinsg to conquerer --- src/engine/objects/Bane.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/engine/objects/Bane.java b/src/engine/objects/Bane.java index f7f23751..ed564cd9 100644 --- a/src/engine/objects/Bane.java +++ b/src/engine/objects/Bane.java @@ -607,6 +607,10 @@ public final class Bane { DispatchMessage.dispatchMsgToAll(msg); } + for(AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(this.getCity().loc,1500,MBServerStatics.MASK_BUILDING)){ + Building building = (Building)awo; + if(building.setOwner(this.getOwner())); + } break; case DESTROY: From fa5cdae17e4cf42b028e1f8aaf089fd711f37ace Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 16:11:35 -0500 Subject: [PATCH 35/68] shrine delete button causes rubble pile --- src/engine/net/client/handlers/DestroyBuildingHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/net/client/handlers/DestroyBuildingHandler.java b/src/engine/net/client/handlers/DestroyBuildingHandler.java index df80727a..bf97f9f5 100644 --- a/src/engine/net/client/handlers/DestroyBuildingHandler.java +++ b/src/engine/net/client/handlers/DestroyBuildingHandler.java @@ -74,6 +74,7 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler { // destorying a shrine will yield a rubble pile for looting if (blueprint.getBuildingGroup() == BuildingGroup.SHRINE) { building.modifyHealth(-building.getHealth(), origin.getPlayerCharacter()); + building.destroyOrDerank(origin.getPlayerCharacter()); return true; } From 6d16eccc24beb873a8af89a1092ae90e7db2793e Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 16:41:28 -0500 Subject: [PATCH 36/68] shrines can be looted once destroyed --- .../net/client/handlers/ManageCityAssetMsgHandler.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/engine/net/client/handlers/ManageCityAssetMsgHandler.java b/src/engine/net/client/handlers/ManageCityAssetMsgHandler.java index 54e3469b..7ba982c1 100644 --- a/src/engine/net/client/handlers/ManageCityAssetMsgHandler.java +++ b/src/engine/net/client/handlers/ManageCityAssetMsgHandler.java @@ -5,6 +5,7 @@ import engine.Enum.DispatchChannel; import engine.Enum.GameObjectType; import engine.exception.MsgSendException; import engine.gameManager.BuildingManager; +import engine.gameManager.DbManager; import engine.gameManager.SessionManager; import engine.gameManager.ZoneManager; import engine.math.Bounds; @@ -130,6 +131,14 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler { ErrorPopupMsg.sendErrorPopup(player, 166); // There is no more favor in this shrine to loot return true; } + //loot elan stones + MobLoot elanStones = new MobLoot(player,ItemBase.getItemBase(1705032),1,false); + Item promotedItem = elanStones.promoteToItem(player); + promotedItem.setNumOfItems(shrine.getFavors()); + player.getCharItemManager().addItemToInventory(promotedItem); + DbManager.ItemQueries.UPDATE_NUM_ITEMS(promotedItem,promotedItem.getNumOfItems(),1); + player.getCharItemManager().updateInventory(); + shrine.setFavors(0); break; case WAREHOUSE: Warehouse warehouse = Warehouse.warehouseByBuildingUUID.get(building.getObjectUUID()); From fb1d6a3248b8955c7fbab4da82044d01322a6336 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 17:01:23 -0500 Subject: [PATCH 37/68] auto update NPC slot location and reload on mesh change for buildings --- src/engine/objects/Building.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/engine/objects/Building.java b/src/engine/objects/Building.java index e7728433..71c883da 100644 --- a/src/engine/objects/Building.java +++ b/src/engine/objects/Building.java @@ -12,6 +12,7 @@ package engine.objects; import engine.Enum; import engine.Enum.*; import engine.InterestManagement.HeightMap; +import engine.InterestManagement.InterestManager; import engine.InterestManagement.RealmMap; import engine.InterestManagement.WorldGrid; import engine.db.archive.CityRecord; @@ -394,7 +395,7 @@ public class Building extends AbstractWorldObject { this.rank = newRank; // New rank means new mesh - + int oldMeshID = this.meshUUID; newMeshUUID = this.getBlueprint().getMeshForRank(this.rank); this.meshUUID = newMeshUUID; @@ -428,6 +429,15 @@ public class Building extends AbstractWorldObject { BuildingManager.cleanupHirelings(this); this.isDeranking.compareAndSet(true, false); + + if(oldMeshID != this.meshUUID) { + //move NPCs to new slot locations if the mesh was changed and force reload them + int index = 0; + for (AbstractCharacter hireling : this.hirelings.keySet()) { + hireling.setLoc(BuildingManager._slotLocations.get(newMeshUUID).get(index).getLocation()); + InterestManager.reloadCharacter(hireling); + } + } } public final int getOwnerUUID() { From 915f182d79682ecf6256a214a82352de3a3afbc9 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 17:12:35 -0500 Subject: [PATCH 38/68] level cap increased to 80 --- src/engine/objects/PlayerCharacter.java | 2 +- src/engine/server/MBServerStatics.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 31ff999c..ac0eb21f 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -4633,7 +4633,7 @@ public class PlayerCharacter extends AbstractCharacter { tmpLevel = targetLevel; - tmpLevel = (short) Math.min(tmpLevel, 75); + tmpLevel = (short) Math.min(tmpLevel, MBServerStatics.LEVELCAP); while (this.level < tmpLevel) { grantXP(Experience.getBaseExperience(tmpLevel) - this.exp); diff --git a/src/engine/server/MBServerStatics.java b/src/engine/server/MBServerStatics.java index 80338e63..6e387800 100644 --- a/src/engine/server/MBServerStatics.java +++ b/src/engine/server/MBServerStatics.java @@ -357,7 +357,7 @@ public class MBServerStatics { public static final int COMBAT_SEND_DODGE = 20; public static final int COMBAT_SEND_BLOCK = 21; public static final int COMBAT_SEND_PARRY = 22; - public static final short LEVELCAP = 75; + public static final short LEVELCAP = 80; public static final int LEVEL_CON_WHITE = 7; public static final int RESPAWN_TIMER = 90 * 1000; public static final int DESPAWN_TIMER = 12 * 1000; From 7c3632590510c94e80f427e4093a00d1a3f8259f Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 17:20:18 -0500 Subject: [PATCH 39/68] level cap increased to 80 Experience altered --- src/engine/objects/Experience.java | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/engine/objects/Experience.java b/src/engine/objects/Experience.java index 3d33c68d..87f71950 100644 --- a/src/engine/objects/Experience.java +++ b/src/engine/objects/Experience.java @@ -117,6 +117,11 @@ public class Experience { 159932666, // Level 74 169707808, // Level 75 179921247, // Level 76 + 190548651, // Level 77 + 201590020, // Level 78 + 213045354, // Level 79 + 224914653, // Level 80 + 237197917 // Level 81 }; @@ -214,9 +219,21 @@ public class Experience { 235166.21f, // Level 72 246039.34f, // Level 73 257240.58f, // Level 74 - 1 // 268774.71 //Level 75 + 268765.03f, // Level 75 + 280612.69f, // Level 76 + 292783.56f, // Level 77 + 305277.64f, // Level 78 + 318094.93f, // Level 79 + 1, // Level 80 - }; + + + + + + + +}; // Used to calcuate the amount of experience a monster grants in the // following formula // expGranted = a(moblevel)^2 + b(moblevel) + c From 34ec123702372eaf3aa3ed3d8db0fc4393531c6a Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 17:28:57 -0500 Subject: [PATCH 40/68] level cap increased to 80 Experience altered --- src/engine/objects/Experience.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/objects/Experience.java b/src/engine/objects/Experience.java index 87f71950..62561060 100644 --- a/src/engine/objects/Experience.java +++ b/src/engine/objects/Experience.java @@ -285,8 +285,8 @@ public class Experience { if (level < 1) level = 1; - if (level > 75) - level = 75; + if (level > MBServerStatics.LEVELCAP) + level = MBServerStatics.LEVELCAP; return MaxExpPerLevel[level]; } From ba2084ceb038d0824312743a4cfe505482a433c4 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 17:40:52 -0500 Subject: [PATCH 41/68] level 80 characters get a 5th disc rune --- src/engine/net/client/msg/ApplyRuneMsg.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/engine/net/client/msg/ApplyRuneMsg.java b/src/engine/net/client/msg/ApplyRuneMsg.java index f62d4df6..e2ebb0dd 100644 --- a/src/engine/net/client/msg/ApplyRuneMsg.java +++ b/src/engine/net/client/msg/ApplyRuneMsg.java @@ -306,6 +306,8 @@ public class ApplyRuneMsg extends ClientNetMsg { } //if discipline, check number applied if (isDiscipline(runeID)) { + if(playerCharacter.getLevel() == 80) + discCount -= 1; // level 80 characters get an extra disc rune if (playerCharacter.getLevel() < 70) { if (discCount > 2) { return false; From ffd65b3641de84f9f3ad3d4287cb79a10ab4708c Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 17:42:19 -0500 Subject: [PATCH 42/68] mob range min set to 6 --- src/engine/mobileAI/MobAI.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index d75ce99f..29fec4ef 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -741,7 +741,10 @@ public class MobAI { return; } } - float rangeSquared = mob.getRange() * mob.getRange(); + float range = mob.getRange(); + if(range < 6) + range = 6; + float rangeSquared = range * range; float distanceSquared = mob.getLoc().distanceSquared2D(mob.getCombatTarget().getLoc()); if(mob.isMoving() && distanceSquared < rangeSquared - 50) { From c2c946165c38e13da3e708481df2991d0cc840d4 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 20:11:03 -0500 Subject: [PATCH 43/68] scaling XP gains for groups --- src/engine/objects/Experience.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/engine/objects/Experience.java b/src/engine/objects/Experience.java index 62561060..653a2ac1 100644 --- a/src/engine/objects/Experience.java +++ b/src/engine/objects/Experience.java @@ -9,6 +9,7 @@ package engine.objects; +import engine.Enum; import engine.Enum.TargetColor; import engine.gameManager.ZoneManager; import engine.math.Vector3fImmutable; @@ -410,6 +411,8 @@ public class Experience { // Process XP for this member + grantedExperience *= (1/giveEXPTo.size()+0.9); + penalty = getGroupMemberPenalty(leadership, playerCharacter, giveEXPTo, highestLevel); @@ -441,6 +444,9 @@ public class Experience { grantedExperience = 1; // Grant the player the EXP + if(!(playerCharacter.level > 74 && mob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))) + return; + playerCharacter.grantXP((int) Math.floor(grantedExperience)); } From c9dcb82c452f0f57d37708729304c28504ac44b4 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 20:12:03 -0500 Subject: [PATCH 44/68] removed leadership cap --- src/engine/objects/Experience.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/objects/Experience.java b/src/engine/objects/Experience.java index 653a2ac1..677de2ab 100644 --- a/src/engine/objects/Experience.java +++ b/src/engine/objects/Experience.java @@ -372,8 +372,8 @@ public class Experience { if (leaderskill != null) leadership = leaderskill.getNumTrains(); - if (leadership > 90) - leadership = 90; // leadership caps at 90% + //if (leadership > 90) + // leadership = 90; // leadership caps at 90% } // Check every group member for distance to see if they get xp From f1e8384af0643192758b777d9e00d11feb95f6c3 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 20:19:19 -0500 Subject: [PATCH 45/68] mines will start again --- src/engine/workthreads/MineThread.java | 41 +++++++++++--------------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/src/engine/workthreads/MineThread.java b/src/engine/workthreads/MineThread.java index fc7197f0..266fa1d7 100644 --- a/src/engine/workthreads/MineThread.java +++ b/src/engine/workthreads/MineThread.java @@ -23,45 +23,38 @@ public class MineThread implements Runnable { @Override public void run() { LocalDateTime nextPulse = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0); - while (true) { - LocalDateTime now = LocalDateTime.now(); - - if (now.isAfter(nextPulse)) { + while (true){ + if(LocalDateTime.now().isAfter(nextPulse)) { for (Mine mine : Mine.getMines()) { - // Reset mine at 4:00 AM - if (nextPulse.getHour() == 4 && nextPulse.getMinute() == 0) { - mine.wasClaimed = false; - mine.hasProduced = false; - } Building mineTower = BuildingManager.getBuilding(mine.getBuildingID()); - if (mineTower == null) { + + if (mineTower == null) continue; - } - int minute = mine.firstThirty ? 0 : 30; - LocalDateTime openTime = now.withHour(mine.liveTime).withMinute(minute).withSecond(0).withNano(0); + int minute = 0; + if (mine.firstThirty == false) + minute = 30; + + LocalDateTime openTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(minute).withSecond(0); LocalDateTime closeTime = openTime.plusMinutes(29); - if (!mine.wasClaimed && !mine.wasOpened && now.isAfter(openTime.minusMinutes(1))) { + //current time is after start time and before close time, open mine window + if (LocalDateTime.now().isAfter(openTime.minusMinutes(1)) && !mine.wasClaimed && !mine.wasOpened) { mineWindowOpen(mine); continue; } + if (mine.isActive) { + + if (LocalDateTime.now().isAfter(closeTime) && mineTower.getRank() > 0) + mineWindowClose(mine); //mine was never knocked down, close window - if (mine.isActive && now.isAfter(closeTime)) { - if (mineTower.getRank() > 0 || (mineTower.getRank() < 1 && mine.lastClaimer != null)) { - mineWindowClose(mine); - } + if (LocalDateTime.now().isAfter(closeTime) && mineTower.getRank() < 1 && mine.lastClaimer != null) + mineWindowClose(mine); //mine was knocked down and was claimed, close window } } nextPulse = nextPulse.plusMinutes(30); } - - try { - Thread.sleep(1000); // Avoid busy-waiting - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } } } From b66e1c1f938e9fb3cbb74f5229969fe867ef3431 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 20:20:35 -0500 Subject: [PATCH 46/68] setlevel command goes to 80 now --- src/engine/devcmd/cmds/SetLevelCmd.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/engine/devcmd/cmds/SetLevelCmd.java b/src/engine/devcmd/cmds/SetLevelCmd.java index 47be4ff6..df3e2ee2 100644 --- a/src/engine/devcmd/cmds/SetLevelCmd.java +++ b/src/engine/devcmd/cmds/SetLevelCmd.java @@ -14,6 +14,7 @@ import engine.devcmd.AbstractDevCmd; import engine.gameManager.ChatManager; import engine.objects.AbstractGameObject; import engine.objects.PlayerCharacter; +import engine.server.MBServerStatics; public class SetLevelCmd extends AbstractDevCmd { @@ -46,7 +47,7 @@ public class SetLevelCmd extends AbstractDevCmd { this.sendUsage(pc); return; } - if (level < 1 || level > 75) { + if (level < 1 || level > MBServerStatics.LEVELCAP) { this.sendHelp(pc); return; } @@ -62,7 +63,7 @@ public class SetLevelCmd extends AbstractDevCmd { @Override protected String _getHelpString() { - return "Sets your character's level to 'amount'. 'amount' must be between 1-75"; + return "Sets your character's level to 'amount'. 'amount' must be between 1-" + MBServerStatics.LEVELCAP; } @Override From 0d7beb5a5a3bb16a506d0acdc07096906cb04f57 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 20:43:21 -0500 Subject: [PATCH 47/68] PVP experience only after level 75 --- src/engine/objects/Experience.java | 13 +++++++++---- src/engine/objects/PlayerCharacter.java | 8 ++++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/engine/objects/Experience.java b/src/engine/objects/Experience.java index 677de2ab..31bd4ab0 100644 --- a/src/engine/objects/Experience.java +++ b/src/engine/objects/Experience.java @@ -444,10 +444,12 @@ public class Experience { grantedExperience = 1; // Grant the player the EXP - if(!(playerCharacter.level > 74 && mob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))) - return; + if(mob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) + playerCharacter.grantXP((int) Math.floor(grantedExperience), true); + else + playerCharacter.grantXP((int) Math.floor(grantedExperience),false); + - playerCharacter.grantXP((int) Math.floor(grantedExperience)); } } else { // Give EXP to a single character @@ -471,7 +473,10 @@ public class Experience { grantedExperience *= .6; // Grant XP - killer.grantXP((int) Math.floor(grantedExperience)); + if(mob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) + killer.grantXP((int) Math.floor(grantedExperience), true); + else + killer.grantXP((int) Math.floor(grantedExperience),false); } } } diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index ac0eb21f..8271ee7c 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -2916,7 +2916,11 @@ public class PlayerCharacter extends AbstractCharacter { return endSpeed; } - public synchronized void grantXP(int xp) { + public synchronized void grantXP(int xp, boolean fromPVP) { + + if(this.level > 75 && !fromPVP){ + return; + } if(GroupManager.getGroup(this) == null) xp *= 2; @@ -4636,7 +4640,7 @@ public class PlayerCharacter extends AbstractCharacter { tmpLevel = (short) Math.min(tmpLevel, MBServerStatics.LEVELCAP); while (this.level < tmpLevel) { - grantXP(Experience.getBaseExperience(tmpLevel) - this.exp); + grantXP(Experience.getBaseExperience(tmpLevel) - this.exp, false); } } From 5f16b400929ea566126c0ef43a5fdd8122e86f3f Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 21:20:19 -0500 Subject: [PATCH 48/68] PVP experience only after level 75 --- .../net/client/msg/VendorDialogMsg.java | 4 +-- src/engine/objects/Experience.java | 3 +- src/engine/objects/PlayerCharacter.java | 31 +++++++++---------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/engine/net/client/msg/VendorDialogMsg.java b/src/engine/net/client/msg/VendorDialogMsg.java index 49bb8978..11014670 100644 --- a/src/engine/net/client/msg/VendorDialogMsg.java +++ b/src/engine/net/client/msg/VendorDialogMsg.java @@ -161,12 +161,12 @@ public class VendorDialogMsg extends ClientNetMsg { } playerCharacter.isBoxed = false; playerCharacter.title = CharacterTitle.NONE; - InterestManager.reloadCharacter(playerCharacter); + InterestManager.setObjectDirty(playerCharacter); playerCharacter.removeEffectBySource(Enum.EffectSourceType.DeathShroud,50,true); for(PlayerCharacter box : currentBoxes) { box.isBoxed = true; box.title = CharacterTitle.BOX; - InterestManager.reloadCharacter(box); + InterestManager.setObjectDirty(box); } } Dispatch dispatch = Dispatch.borrow(playerCharacter, msg); diff --git a/src/engine/objects/Experience.java b/src/engine/objects/Experience.java index 31bd4ab0..9f454817 100644 --- a/src/engine/objects/Experience.java +++ b/src/engine/objects/Experience.java @@ -460,7 +460,8 @@ public class Experience { return; // Get XP and adjust for Mob Level with world xp modifier taken into account - grantedExperience = (double) LOOTMANAGER.NORMAL_EXP_RATE * maxXPPerKill(killer.getLevel()); + float mdofier = LOOTMANAGER.NORMAL_EXP_RATE; + grantedExperience = maxXPPerKill(killer.getLevel()); grantedExperience *= getConMod(killer, mob); // Modify for hotzone diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 8271ee7c..e9da5652 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -1827,20 +1827,18 @@ public class PlayerCharacter extends AbstractCharacter { //see if we shold grant xp to attacker boolean doPVPEXP = false; long lastKill = att.getLastKillOfTarget(this.getObjectUUID()); - if ((System.currentTimeMillis() - lastKill) > MBServerStatics.PLAYER_KILL_XP_TIMER) - if (attacker.getLevel() > 39 && this.getLevel() > 39) { - Guild aN = null; - Guild tN = null; - if (attacker.getGuild() != null) - aN = attacker.getGuild().getNation(); - if (this.getGuild() != null) - tN = this.getGuild().getNation(); - if (aN == null || tN == null || aN.isEmptyGuild() || Guild.sameGuild(aN, tN) || this.isDeathShroud()) { - //skip giving xp if same guild or attacker is errant, or target is in death shroud. - } else { - doPVPEXP = true; - } - } + + Guild aN = null; + Guild tN = null; + if (attacker.getGuild() != null) + aN = attacker.getGuild().getNation(); + if (this.getGuild() != null) + tN = this.getGuild().getNation(); + + if (aN != null || tN != null || !aN.equals(tN) || !this.isDeathShroud()) { + doPVPEXP = true; + } + //apply death shroud to non safeholds. Zone zone = ZoneManager.findSmallestZone(this.getLoc()); @@ -2926,8 +2924,9 @@ public class PlayerCharacter extends AbstractCharacter { xp *= 2; // Stop players from getting experience past the cap - if (this.exp + xp >= Experience.getBaseExperience(MBServerStatics.LEVELCAP)) - xp = Experience.getBaseExperience(MBServerStatics.LEVELCAP) - this.exp + 1; + int levelCap = MBServerStatics.LEVELCAP; + if (this.exp + xp >= Experience.getBaseExperience(levelCap)) + xp = Experience.getBaseExperience(levelCap) - this.exp + 1; if (xp == 0) xp = 1; From 4ca81b019b875cc5637bfcac34eeee17de627ad5 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 21:39:23 -0500 Subject: [PATCH 49/68] everyone gets an extra disc --- src/engine/net/client/msg/ApplyRuneMsg.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/net/client/msg/ApplyRuneMsg.java b/src/engine/net/client/msg/ApplyRuneMsg.java index e2ebb0dd..defde65a 100644 --- a/src/engine/net/client/msg/ApplyRuneMsg.java +++ b/src/engine/net/client/msg/ApplyRuneMsg.java @@ -306,7 +306,7 @@ public class ApplyRuneMsg extends ClientNetMsg { } //if discipline, check number applied if (isDiscipline(runeID)) { - if(playerCharacter.getLevel() == 80) + //if(playerCharacter.getLevel() == 80) discCount -= 1; // level 80 characters get an extra disc rune if (playerCharacter.getLevel() < 70) { if (discCount > 2) { From a660457883e4da9e6dbec1bf9a49e00de8e21baa Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 21 May 2024 21:49:05 -0500 Subject: [PATCH 50/68] cannot get XP from the same character in PVP more than once per reboot --- src/engine/objects/Experience.java | 3 ++- src/engine/objects/PlayerCharacter.java | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/engine/objects/Experience.java b/src/engine/objects/Experience.java index 9f454817..2d6915dd 100644 --- a/src/engine/objects/Experience.java +++ b/src/engine/objects/Experience.java @@ -475,7 +475,8 @@ public class Experience { // Grant XP if(mob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) - killer.grantXP((int) Math.floor(grantedExperience), true); + if(((PlayerCharacter)mob).pvpDeaths.contains(killer.getObjectUUID()) == false) + killer.grantXP((int) Math.floor(grantedExperience), true); else killer.grantXP((int) Math.floor(grantedExperience),false); } diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index e9da5652..009095a2 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -181,6 +181,8 @@ public class PlayerCharacter extends AbstractCharacter { public boolean depositingWarehouse = false; public Building warehouseBuilding; + public ArrayList killedCharacters = new ArrayList<>(); + /** * No Id Constructor */ From 1d703b08a285f45d967a5e955cf4578222e78a90 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 22 May 2024 06:43:51 -0500 Subject: [PATCH 51/68] xp and range fix --- src/engine/gameManager/CombatManager.java | 2 +- src/engine/objects/Experience.java | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/engine/gameManager/CombatManager.java b/src/engine/gameManager/CombatManager.java index 709ff575..c1f7b3a3 100644 --- a/src/engine/gameManager/CombatManager.java +++ b/src/engine/gameManager/CombatManager.java @@ -1278,7 +1278,7 @@ public enum CombatManager { if(ac.getObjectType().equals(GameObjectType.PlayerCharacter)){ range += ((PlayerCharacter)ac).getCharacterHeight() * 0.5f; if(ac.isMoving()){ - range += ac.getSpeed(); + range += ((PlayerCharacter) ac).getCharacterHeight(); } } diff --git a/src/engine/objects/Experience.java b/src/engine/objects/Experience.java index 2d6915dd..07c9e709 100644 --- a/src/engine/objects/Experience.java +++ b/src/engine/objects/Experience.java @@ -11,6 +11,7 @@ package engine.objects; import engine.Enum; import engine.Enum.TargetColor; +import engine.gameManager.LootManager; import engine.gameManager.ZoneManager; import engine.math.Vector3fImmutable; import engine.server.MBServerStatics; @@ -443,13 +444,14 @@ public class Experience { if (grantedExperience == 0) grantedExperience = 1; + grantedExperience *= LootManager.NORMAL_EXP_RATE; // Grant the player the EXP - if(mob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) - playerCharacter.grantXP((int) Math.floor(grantedExperience), true); - else - playerCharacter.grantXP((int) Math.floor(grantedExperience),false); - - + if(mob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { + if (((PlayerCharacter) mob).pvpDeaths.contains(killer.getObjectUUID()) == false) + playerCharacter.grantXP((int) Math.floor(grantedExperience), true); + }else { + playerCharacter.grantXP((int) Math.floor(grantedExperience), false); + } } } else { // Give EXP to a single character @@ -474,11 +476,12 @@ public class Experience { grantedExperience *= .6; // Grant XP - if(mob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) - if(((PlayerCharacter)mob).pvpDeaths.contains(killer.getObjectUUID()) == false) + if(mob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { + if (((PlayerCharacter) mob).pvpDeaths.contains(killer.getObjectUUID()) == false) killer.grantXP((int) Math.floor(grantedExperience), true); - else - killer.grantXP((int) Math.floor(grantedExperience),false); + }else { + killer.grantXP((int) Math.floor(grantedExperience), false); + } } } } From 8ab2805e394f4e933f865e91858a049dac0fd64d Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 22 May 2024 06:45:32 -0500 Subject: [PATCH 52/68] xp and range fix --- 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 009095a2..9ddb8231 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -2920,10 +2920,12 @@ public class PlayerCharacter extends AbstractCharacter { if(this.level > 75 && !fromPVP){ return; + } else{ + xp *= 2; } if(GroupManager.getGroup(this) == null) - xp *= 2; + xp *= 1.9f; // Stop players from getting experience past the cap int levelCap = MBServerStatics.LEVELCAP; From 47503de7485913fd1e07395b0ae620100b2fa19d Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 22 May 2024 20:23:19 -0500 Subject: [PATCH 53/68] system to open and close mines --- src/engine/workthreads/MineThread.java | 98 +++++++++++++++++++------- 1 file changed, 71 insertions(+), 27 deletions(-) diff --git a/src/engine/workthreads/MineThread.java b/src/engine/workthreads/MineThread.java index 266fa1d7..f0d32e5d 100644 --- a/src/engine/workthreads/MineThread.java +++ b/src/engine/workthreads/MineThread.java @@ -22,40 +22,84 @@ public class MineThread implements Runnable { } @Override public void run() { - LocalDateTime nextPulse = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0); - while (true){ - if(LocalDateTime.now().isAfter(nextPulse)) { - for (Mine mine : Mine.getMines()) { + //LocalDateTime nextPulse = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0); + while (true) { + for (Mine mine : Mine.getMines()) { + + if(mine.wasClaimed) + continue; + LocalDateTime now = LocalDateTime.now(); + int minute = 0; + if (!mine.firstThirty) + minute = 30; + + LocalDateTime openTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(minute).withSecond(0); + LocalDateTime closeTime = openTime.plusMinutes(30); + + if (now.isAfter(openTime)) { + mineWindowOpen(mine); + continue; // mine has not opened today yet, and it is now after the time it should have, open the mine + } - Building mineTower = BuildingManager.getBuilding(mine.getBuildingID()); + if(now.isAfter(closeTime) && BuildingManager.getBuilding(mine.getBuildingID()).getRank() == 1) { + mineWindowClose(mine); + continue; // mine was never knocked down, close it + } - if (mineTower == null) - continue; + if(now.isAfter(closeTime) && mine.lastClaimer == null){ + if(mine.firstThirty){ + mine.firstThirty = false; + }else{ + mine.firstThirty = true; + mine.liveTime += 1; + } + continue; // roll over to the next 30-minute window, mine was knocked down and not claimed + } - int minute = 0; - if (mine.firstThirty == false) - minute = 30; + mineWindowClose(mine); // finished checking parameters, close the mine + } + } - LocalDateTime openTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(minute).withSecond(0); - LocalDateTime closeTime = openTime.plusMinutes(29); - //current time is after start time and before close time, open mine window - if (LocalDateTime.now().isAfter(openTime.minusMinutes(1)) && !mine.wasClaimed && !mine.wasOpened) { - mineWindowOpen(mine); - continue; - } - if (mine.isActive) { - if (LocalDateTime.now().isAfter(closeTime) && mineTower.getRank() > 0) - mineWindowClose(mine); //mine was never knocked down, close window - if (LocalDateTime.now().isAfter(closeTime) && mineTower.getRank() < 1 && mine.lastClaimer != null) - mineWindowClose(mine); //mine was knocked down and was claimed, close window - } - } - nextPulse = nextPulse.plusMinutes(30); - } - } + + + + + + // if(LocalDateTime.now().isAfter(nextPulse)) { + // for (Mine mine : Mine.getMines()) { + + // Building mineTower = BuildingManager.getBuilding(mine.getBuildingID()); + + // if (mineTower == null) + // continue; + + // int minute = 0; + // if (mine.firstThirty == false) + // minute = 30; + + // LocalDateTime openTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(minute).withSecond(0); + // LocalDateTime closeTime = openTime.plusMinutes(29); + + //current time is after start time and before close time, open mine window + // if (LocalDateTime.now().isAfter(openTime.minusMinutes(1)) && !mine.wasClaimed && !mine.wasOpened) { + // mineWindowOpen(mine); + // continue; + // } + // if (mine.isActive) { +// + // if (LocalDateTime.now().isAfter(closeTime) && mineTower.getRank() > 0) + // mineWindowClose(mine); //mine was never knocked down, close window +// + // if (LocalDateTime.now().isAfter(closeTime) && mineTower.getRank() < 1 && mine.lastClaimer != null) + // mineWindowClose(mine); //mine was knocked down and was claimed, close window + // } + // } + // nextPulse = nextPulse.plusMinutes(30); + // } + //} } public static void mineWindowOpen(Mine mine) { From 4734f23805c8b139483ec7df2691086da2c39871 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 22 May 2024 20:27:27 -0500 Subject: [PATCH 54/68] check if mines are active before spamming them to open --- src/engine/workthreads/MineThread.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/workthreads/MineThread.java b/src/engine/workthreads/MineThread.java index f0d32e5d..f0e1f424 100644 --- a/src/engine/workthreads/MineThread.java +++ b/src/engine/workthreads/MineThread.java @@ -36,17 +36,17 @@ public class MineThread implements Runnable { LocalDateTime openTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(minute).withSecond(0); LocalDateTime closeTime = openTime.plusMinutes(30); - if (now.isAfter(openTime)) { + if (now.isAfter(openTime) && !mine.isActive) { mineWindowOpen(mine); continue; // mine has not opened today yet, and it is now after the time it should have, open the mine } - if(now.isAfter(closeTime) && BuildingManager.getBuilding(mine.getBuildingID()).getRank() == 1) { + if(now.isAfter(closeTime) && BuildingManager.getBuilding(mine.getBuildingID()).getRank() == 1 && mine.isActive) { mineWindowClose(mine); continue; // mine was never knocked down, close it } - if(now.isAfter(closeTime) && mine.lastClaimer == null){ + if(now.isAfter(closeTime) && mine.lastClaimer == null && mine.isActive){ if(mine.firstThirty){ mine.firstThirty = false; }else{ From c90378e3f0103885d2186ed25640600170519918 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 22 May 2024 20:33:03 -0500 Subject: [PATCH 55/68] delay mine checks to 1 minute intervals --- src/engine/workthreads/MineThread.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/engine/workthreads/MineThread.java b/src/engine/workthreads/MineThread.java index f0e1f424..48c8756b 100644 --- a/src/engine/workthreads/MineThread.java +++ b/src/engine/workthreads/MineThread.java @@ -22,18 +22,23 @@ public class MineThread implements Runnable { } @Override public void run() { - //LocalDateTime nextPulse = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0); + LocalDateTime nextPulse = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0); while (true) { + + LocalDateTime now = LocalDateTime.now(); + if(now.isBefore(nextPulse)) + break; + nextPulse = nextPulse.plusMinutes(1); for (Mine mine : Mine.getMines()) { if(mine.wasClaimed) continue; - LocalDateTime now = LocalDateTime.now(); + int minute = 0; if (!mine.firstThirty) minute = 30; - LocalDateTime openTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(minute).withSecond(0); + LocalDateTime openTime = now.withHour(mine.liveTime).withMinute(minute).withSecond(0); LocalDateTime closeTime = openTime.plusMinutes(30); if (now.isAfter(openTime) && !mine.isActive) { From 3aac2410b0232b4bf198f60dd9440025ced00e75 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 23 May 2024 17:56:54 -0500 Subject: [PATCH 56/68] new mines system --- src/engine/objects/Mine.java | 142 ++----------------------- src/engine/workthreads/MineThread.java | 130 +++++++++------------- 2 files changed, 56 insertions(+), 216 deletions(-) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index 77dddbdd..c2baf564 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -16,17 +16,14 @@ import engine.net.ByteBufferWriter; import engine.net.client.msg.ErrorPopupMsg; import engine.server.MBServerStatics; import engine.workthreads.ZergMechanicThread; -import org.joda.time.DateTime; import org.pmw.tinylog.Logger; import java.net.UnknownHostException; import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.Time; import java.time.LocalDateTime; import java.util.*; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ThreadLocalRandom; import static engine.gameManager.DbManager.MineQueries; import static engine.gameManager.DbManager.getObject; @@ -60,7 +57,8 @@ public class Mine extends AbstractGameObject { public boolean hasProduced = false; - public int liveTime; + public int liveHour; + public int liveMinute; public Boolean firstThirty = true; public static ArrayList ChinaMines = new ArrayList<>(); @@ -115,57 +113,12 @@ public class Mine extends AbstractGameObject { this.production = Resource.valueOf(rs.getString("mine_resource")); this.lastClaimer = null; + this.liveHour = rs.getInt("mineLiveHour"); + this.liveMinute = rs.getInt("mineLiveMinute"); } } public static void SetTimes(){ - try { - EuroMines.get(0).liveTime = 19; - EuroMines.get(1).liveTime = 19; - EuroMines.get(2).liveTime = 20; - EuroMines.get(3).liveTime = 20; - EuroMines.get(4).liveTime = 21; - EuroMines.get(5).liveTime = 21; - EuroMines.get(6).liveTime = 22; - }catch(Exception e){ - - } - try{ - ChinaMines.get(0).liveTime = 11; - ChinaMines.get(1).liveTime = 11; - ChinaMines.get(2).liveTime = 11; - ChinaMines.get(3).liveTime = 12; - ChinaMines.get(4).liveTime = 12; - ChinaMines.get(5).liveTime = 12; - ChinaMines.get(6).liveTime = 12; - ChinaMines.get(7).liveTime = 12; - ChinaMines.get(8).liveTime = 12; - ChinaMines.get(9).liveTime = 12; - ChinaMines.get(10).liveTime = 13; - ChinaMines.get(11).liveTime = 13; - ChinaMines.get(12).liveTime = 13; - ChinaMines.get(13).liveTime = 13; - }catch(Exception e){ - - } - try{ - AmericaMines.get(0).liveTime = 1; - AmericaMines.get(1).liveTime = 2; - AmericaMines.get(2).liveTime = 2; - AmericaMines.get(3).liveTime = 3; - AmericaMines.get(4).liveTime = 3; - AmericaMines.get(5).liveTime = 3; - AmericaMines.get(6).liveTime = 3; - AmericaMines.get(7).liveTime = 3; - AmericaMines.get(8).liveTime = 3; - AmericaMines.get(9).liveTime = 3; - AmericaMines.get(10).liveTime = 4; - AmericaMines.get(11).liveTime = 4; - AmericaMines.get(12).liveTime = 4; - AmericaMines.get(13).liveTime = 5; - }catch(Exception e){ - - } int count = 1; for(Mine mine : EuroMines){ @@ -306,89 +259,8 @@ public class Mine extends AbstractGameObject { //mine.mineType = MineProduction.LUMBER; } - try { - ChinaMines.add(serverMines.get(0)); - ChinaMines.add(serverMines.get(3)); - ChinaMines.add(serverMines.get(6)); - ChinaMines.add(serverMines.get(9)); - ChinaMines.add(serverMines.get(12)); - ChinaMines.add(serverMines.get(15)); - ChinaMines.add(serverMines.get(18)); - ChinaMines.add(serverMines.get(21)); - ChinaMines.add(serverMines.get(23)); - ChinaMines.add(serverMines.get(25)); - ChinaMines.add(serverMines.get(27)); - ChinaMines.add(serverMines.get(29)); - ChinaMines.add(serverMines.get(31)); - ChinaMines.add(serverMines.get(33)); - }catch(Exception e){ - - } - try{ - AmericaMines.add(serverMines.get(1)); - AmericaMines.add(serverMines.get(4)); - AmericaMines.add(serverMines.get(7)); - AmericaMines.add(serverMines.get(10)); - AmericaMines.add(serverMines.get(13)); - AmericaMines.add(serverMines.get(16)); - AmericaMines.add(serverMines.get(19)); - AmericaMines.add(serverMines.get(22)); - AmericaMines.add(serverMines.get(24)); - AmericaMines.add(serverMines.get(26)); - AmericaMines.add(serverMines.get(28)); - AmericaMines.add(serverMines.get(30)); - AmericaMines.add(serverMines.get(32)); - AmericaMines.add(serverMines.get(34)); - }catch(Exception e){ - - } - try{ - EuroMines.add(serverMines.get(2)); - EuroMines.add(serverMines.get(5)); - EuroMines.add(serverMines.get(8)); - EuroMines.add(serverMines.get(11)); - EuroMines.add(serverMines.get(14)); - EuroMines.add(serverMines.get(17)); - EuroMines.add(serverMines.get(20)); - }catch(Exception e){ - - } - - - SetTimes(); - for(Mine mine : EuroMines){ - if(EuroMines.indexOf(mine) %2 == 0 ){ - mine.firstThirty = true; - } else{ - mine.firstThirty = false; - } - } - for(Mine mine : AmericaMines){ - if(AmericaMines.indexOf(mine) %2 == 0 ){ - mine.firstThirty = true; - } else{ - mine.firstThirty = false; - } - } - for(Mine mine : ChinaMines){ - if(ChinaMines.indexOf(mine) %2 == 0 ){ - mine.firstThirty = true; - } else{ - mine.firstThirty = false; - } - } - } catch (Exception e) { - e.printStackTrace(); - } + }catch(Exception e) { - for(Mine mine : Mine.getMines()){ - int minute = 0; - if (mine.firstThirty == false) - minute = 30; - LocalDateTime openTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(minute).withSecond(0); - LocalDateTime closeTime = openTime.plusMinutes(30); - if(LocalDateTime.now().isAfter(closeTime)) - mine.wasOpened = true; } } @@ -423,10 +295,10 @@ public class Mine extends AbstractGameObject { LocalDateTime mineOpenTime;// = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0); if(mine.firstThirty == true){ - mineOpenTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(0).withSecond(0).withNano(0); + mineOpenTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(0).withSecond(0).withNano(0); } else{ - mineOpenTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(30).withSecond(0).withNano(0); + mineOpenTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(30).withSecond(0).withNano(0); } LocalDateTime mineCloseTime = mineOpenTime.plusMinutes(30); diff --git a/src/engine/workthreads/MineThread.java b/src/engine/workthreads/MineThread.java index 48c8756b..8c953cc9 100644 --- a/src/engine/workthreads/MineThread.java +++ b/src/engine/workthreads/MineThread.java @@ -15,6 +15,8 @@ import engine.objects.PlayerCharacter; import org.pmw.tinylog.Logger; import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; public class MineThread implements Runnable { public MineThread(){ @@ -22,89 +24,12 @@ public class MineThread implements Runnable { } @Override public void run() { - LocalDateTime nextPulse = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0); + LocalDateTime nextPulse = LocalDateTime.now().withMinute(59).minusHours(1); while (true) { - - LocalDateTime now = LocalDateTime.now(); - if(now.isBefore(nextPulse)) - break; - nextPulse = nextPulse.plusMinutes(1); - for (Mine mine : Mine.getMines()) { - - if(mine.wasClaimed) - continue; - - int minute = 0; - if (!mine.firstThirty) - minute = 30; - - LocalDateTime openTime = now.withHour(mine.liveTime).withMinute(minute).withSecond(0); - LocalDateTime closeTime = openTime.plusMinutes(30); - - if (now.isAfter(openTime) && !mine.isActive) { - mineWindowOpen(mine); - continue; // mine has not opened today yet, and it is now after the time it should have, open the mine - } - - if(now.isAfter(closeTime) && BuildingManager.getBuilding(mine.getBuildingID()).getRank() == 1 && mine.isActive) { - mineWindowClose(mine); - continue; // mine was never knocked down, close it - } - - if(now.isAfter(closeTime) && mine.lastClaimer == null && mine.isActive){ - if(mine.firstThirty){ - mine.firstThirty = false; - }else{ - mine.firstThirty = true; - mine.liveTime += 1; - } - continue; // roll over to the next 30-minute window, mine was knocked down and not claimed - } - - mineWindowClose(mine); // finished checking parameters, close the mine - } + if(LocalDateTime.now().isAfter(nextPulse)); + processMineWindows(); + nextPulse = nextPulse.plusMinutes(30); } - - - - - - - - - - // if(LocalDateTime.now().isAfter(nextPulse)) { - // for (Mine mine : Mine.getMines()) { - - // Building mineTower = BuildingManager.getBuilding(mine.getBuildingID()); - - // if (mineTower == null) - // continue; - - // int minute = 0; - // if (mine.firstThirty == false) - // minute = 30; - - // LocalDateTime openTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(minute).withSecond(0); - // LocalDateTime closeTime = openTime.plusMinutes(29); - - //current time is after start time and before close time, open mine window - // if (LocalDateTime.now().isAfter(openTime.minusMinutes(1)) && !mine.wasClaimed && !mine.wasOpened) { - // mineWindowOpen(mine); - // continue; - // } - // if (mine.isActive) { -// - // if (LocalDateTime.now().isAfter(closeTime) && mineTower.getRank() > 0) - // mineWindowClose(mine); //mine was never knocked down, close window -// - // if (LocalDateTime.now().isAfter(closeTime) && mineTower.getRank() < 1 && mine.lastClaimer != null) - // mineWindowClose(mine); //mine was knocked down and was claimed, close window - // } - // } - // nextPulse = nextPulse.plusMinutes(30); - // } - //} } public static void mineWindowOpen(Mine mine) { @@ -181,4 +106,47 @@ public class MineThread implements Runnable { mine.wasClaimed = true; return true; } + + public static void processMineWindows(){ + for (Mine mine : Mine.getMines()) { + Building tower = BuildingManager.getBuildingFromCache(mine.getBuildingID()); + if(tower == null) + continue; + LocalDateTime liveTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(mine.liveMinute).minusMinutes(1); + ZonedDateTime localizedTime = convertCSTToLocalTime(liveTime); + if(!mine.isActive) { + if (ZonedDateTime.now().isAfter(localizedTime)) { + mineWindowOpen(mine); + // mine has not opened today yet, and it is now after the time it should have, open the mine + } + }else{ + //mine is active right now + if (ZonedDateTime.now().isBefore(localizedTime.plusMinutes(30))){ + continue; // window is not over yet + } + + if(tower.getRank() == 1){ + //mine was not knocked down, close the window + mineWindowClose(mine); + }else{ + if(mine.lastClaimer != null) + mineWindowClose(mine); //has a claimer, close the window + } + } + } + } + public static ZonedDateTime convertCSTToLocalTime(LocalDateTime cstDateTime) { + // Define the CST time zone (Central Standard Time) + ZoneId cstZoneId = ZoneId.of("America/Chicago"); // CST is represented by America/Chicago + // Define the system's default time zone + ZoneId localZoneId = ZoneId.systemDefault(); + + // Create a ZonedDateTime object for CST + ZonedDateTime cstZonedDateTime = ZonedDateTime.of(cstDateTime, cstZoneId); + + // Convert CST to the local time zone + ZonedDateTime localZonedDateTime = cstZonedDateTime.withZoneSameInstant(localZoneId); + + return localZonedDateTime; + } } From 6e7633828fe4fef9314b929b038e6c2929496ea5 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 23 May 2024 18:01:02 -0500 Subject: [PATCH 57/68] new mines system --- src/engine/workthreads/MineThread.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/workthreads/MineThread.java b/src/engine/workthreads/MineThread.java index 8c953cc9..5aa88a34 100644 --- a/src/engine/workthreads/MineThread.java +++ b/src/engine/workthreads/MineThread.java @@ -114,7 +114,7 @@ public class MineThread implements Runnable { continue; LocalDateTime liveTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(mine.liveMinute).minusMinutes(1); ZonedDateTime localizedTime = convertCSTToLocalTime(liveTime); - if(!mine.isActive) { + if(!mine.isActive && !mine.wasOpened) { if (ZonedDateTime.now().isAfter(localizedTime)) { mineWindowOpen(mine); // mine has not opened today yet, and it is now after the time it should have, open the mine From ffcaf0e063673771e0f94be0e9d5ff22a248298d Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 23 May 2024 18:01:59 -0500 Subject: [PATCH 58/68] new mines system --- src/engine/workthreads/MineThread.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/engine/workthreads/MineThread.java b/src/engine/workthreads/MineThread.java index 5aa88a34..1b7396fd 100644 --- a/src/engine/workthreads/MineThread.java +++ b/src/engine/workthreads/MineThread.java @@ -26,9 +26,10 @@ public class MineThread implements Runnable { public void run() { LocalDateTime nextPulse = LocalDateTime.now().withMinute(59).minusHours(1); while (true) { - if(LocalDateTime.now().isAfter(nextPulse)); - processMineWindows(); - nextPulse = nextPulse.plusMinutes(30); + if(LocalDateTime.now().isAfter(nextPulse)) { + processMineWindows(); + nextPulse = nextPulse.plusMinutes(30); + } } } From 270301c35b2d29a8b69596afd6fd66ca7d641952 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 23 May 2024 18:07:39 -0500 Subject: [PATCH 59/68] new mines system --- src/engine/workthreads/MineThread.java | 39 +++++--------------------- 1 file changed, 7 insertions(+), 32 deletions(-) diff --git a/src/engine/workthreads/MineThread.java b/src/engine/workthreads/MineThread.java index 1b7396fd..9cdfd17a 100644 --- a/src/engine/workthreads/MineThread.java +++ b/src/engine/workthreads/MineThread.java @@ -13,10 +13,7 @@ import engine.objects.Guild; import engine.objects.Mine; import engine.objects.PlayerCharacter; import org.pmw.tinylog.Logger; - import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.ZonedDateTime; public class MineThread implements Runnable { public MineThread(){ @@ -113,41 +110,19 @@ public class MineThread implements Runnable { Building tower = BuildingManager.getBuildingFromCache(mine.getBuildingID()); if(tower == null) continue; - LocalDateTime liveTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(mine.liveMinute).minusMinutes(1); - ZonedDateTime localizedTime = convertCSTToLocalTime(liveTime); + LocalDateTime liveTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(mine.liveMinute).minusMinutes(1).plusHours(5); if(!mine.isActive && !mine.wasOpened) { - if (ZonedDateTime.now().isAfter(localizedTime)) { + if (LocalDateTime.now().isAfter(liveTime)) { mineWindowOpen(mine); // mine has not opened today yet, and it is now after the time it should have, open the mine } - }else{ + } //mine is active right now - if (ZonedDateTime.now().isBefore(localizedTime.plusMinutes(30))){ - continue; // window is not over yet - } + if (LocalDateTime.now().isBefore(liveTime.plusMinutes(30))) + continue; // window is not over yet - if(tower.getRank() == 1){ - //mine was not knocked down, close the window - mineWindowClose(mine); - }else{ - if(mine.lastClaimer != null) - mineWindowClose(mine); //has a claimer, close the window - } - } + if(tower.getRank() == 1 || mine.lastClaimer != null) + mineWindowClose(mine); } } - public static ZonedDateTime convertCSTToLocalTime(LocalDateTime cstDateTime) { - // Define the CST time zone (Central Standard Time) - ZoneId cstZoneId = ZoneId.of("America/Chicago"); // CST is represented by America/Chicago - // Define the system's default time zone - ZoneId localZoneId = ZoneId.systemDefault(); - - // Create a ZonedDateTime object for CST - ZonedDateTime cstZonedDateTime = ZonedDateTime.of(cstDateTime, cstZoneId); - - // Convert CST to the local time zone - ZonedDateTime localZonedDateTime = cstZonedDateTime.withZoneSameInstant(localZoneId); - - return localZonedDateTime; - } } From bd5061a7e86d3ebac4a1bdbcf87d1224ad21b52d Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 23 May 2024 18:14:17 -0500 Subject: [PATCH 60/68] new mines system --- src/engine/objects/Mine.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index c2baf564..7e73f855 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -295,10 +295,10 @@ public class Mine extends AbstractGameObject { LocalDateTime mineOpenTime;// = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0); if(mine.firstThirty == true){ - mineOpenTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(0).withSecond(0).withNano(0); + mineOpenTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(0).withSecond(0).withNano(0).plusHours(5); } else{ - mineOpenTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(30).withSecond(0).withNano(0); + mineOpenTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(30).withSecond(0).withNano(0).plusHours(5); } LocalDateTime mineCloseTime = mineOpenTime.plusMinutes(30); From ba9238a49a3f5aa9a3e2794cc9999106e6cde56a Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Thu, 23 May 2024 19:16:23 -0500 Subject: [PATCH 61/68] new mines system --- src/engine/objects/Mine.java | 117 ++++++++--------------------------- 1 file changed, 25 insertions(+), 92 deletions(-) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index 7e73f855..334c847c 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -115,95 +115,18 @@ public class Mine extends AbstractGameObject { this.lastClaimer = null; this.liveHour = rs.getInt("mineLiveHour"); this.liveMinute = rs.getInt("mineLiveMinute"); - } - } - - public static void SetTimes(){ - - int count = 1; - for(Mine mine : EuroMines){ - switch(count){ - case 1: - mine.capSize = 3; - break; - case 2: - mine.capSize = 3; - break; - case 3: - mine.capSize = 3; - break; - case 4: - mine.capSize = 3; - break; - } - count ++; - if(count == 5) - count = 1; - if(BuildingManager.getBuilding(mine.buildingID) != null) { - Building mineTower = BuildingManager.getBuilding(mine.buildingID); - if (mineTower != null) { - mineTower.setMaxHitPoints(5000 * mine.capSize); - mineTower.setCurrentHitPoints((float) 5000 * mine.capSize); - } - } - } - - for(Mine mine : ChinaMines){ - switch(count){ - case 1: - mine.capSize = 3; - break; - case 2: - mine.capSize = 5; - break; - case 3: - mine.capSize = 5; - break; - case 4: - mine.capSize = 3; - break; - } - count ++; - if(count == 5) - count = 1; - - if(BuildingManager.getBuilding(mine.buildingID) != null) { - Building mineTower = BuildingManager.getBuilding(mine.buildingID); - if (mineTower != null) { - mineTower.setMaxHitPoints(5000 * mine.capSize); - mineTower.setCurrentHitPoints((float) 5000 * mine.capSize); - } - } - } - - for(Mine mine : AmericaMines){ - switch(count){ - case 1: - mine.capSize = 3; - break; - case 2: - mine.capSize = 5; - break; - case 3: - mine.capSize = 5; - break; - case 4: - mine.capSize = 3; - break; - } - count ++; - if(count == 5) - count = 1; + this.capSize = rs.getInt("capSize"); - if(BuildingManager.getBuilding(mine.buildingID) != null) { - Building mineTower = BuildingManager.getBuilding(mine.buildingID); + if(BuildingManager.getBuilding(this.buildingID) != null) { + Building mineTower = BuildingManager.getBuilding(this.buildingID); if (mineTower != null) { - mineTower.setMaxHitPoints(5000 * mine.capSize); - mineTower.setCurrentHitPoints((float) 5000 * mine.capSize); + mineTower.setMaxHitPoints(5000 * this.capSize); + mineTower.setCurrentHitPoints((float) 5000 * this.capSize); } } } } + public static void releaseMineClaims(PlayerCharacter playerCharacter) { if (playerCharacter == null) @@ -272,20 +195,30 @@ public class Mine extends AbstractGameObject { return Mine.towerMap.get(towerID); } + public static String getMineNationality(int time){ + switch(time){ + case 7: + case 8: + case 9: + return "CN"; + case 14: + case 15: + case 16: + return "EU"; + case 20: + case 21: + case 22: + return "NA"; + default: + return "Unknown"; + } + } public static void serializeForClientMsg(Mine mine, ByteBufferWriter writer) { writer.putInt(mine.getObjectType().ordinal()); writer.putInt(mine.getObjectUUID()); writer.putInt(mine.getObjectUUID()); //actually a hash of mine writer.putString(mine.mineType.name); - if(ChinaMines.contains((mine))) { - writer.putString("Chinese" + " {" + mine.capSize + " Man}"); - } else if(AmericaMines.contains(mine)){ - writer.putString("American" + " {" + mine.capSize + " Man}"); - } else if(EuroMines.contains(mine)){ - writer.putString("European" + " {" + mine.capSize + " Man}"); - }else{ - writer.putString("Unknown" + " {" + mine.capSize + " Man}"); - } + writer.putString(Mine.getMineNationality(mine.liveHour) + " {" + mine.capSize + " Man}"); writer.putInt(mine.production.hash); writer.putInt(mine.getModifiedProductionAmount()); writer.putInt(mine.getModifiedProductionAmount()); //TODO calculate range penalty here From 918a797f3464c3c378b1efd7b3c0832a337abf55 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 25 May 2024 22:13:14 -0500 Subject: [PATCH 62/68] timezone updated --- src/engine/objects/Mine.java | 4 ++-- src/engine/workthreads/MineThread.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index 334c847c..42f96bff 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -228,10 +228,10 @@ public class Mine extends AbstractGameObject { LocalDateTime mineOpenTime;// = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0); if(mine.firstThirty == true){ - mineOpenTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(0).withSecond(0).withNano(0).plusHours(5); + mineOpenTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(0).withSecond(0).withNano(0); } else{ - mineOpenTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(30).withSecond(0).withNano(0).plusHours(5); + mineOpenTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(30).withSecond(0).withNano(0); } LocalDateTime mineCloseTime = mineOpenTime.plusMinutes(30); diff --git a/src/engine/workthreads/MineThread.java b/src/engine/workthreads/MineThread.java index 9cdfd17a..1cd254d0 100644 --- a/src/engine/workthreads/MineThread.java +++ b/src/engine/workthreads/MineThread.java @@ -110,7 +110,7 @@ public class MineThread implements Runnable { Building tower = BuildingManager.getBuildingFromCache(mine.getBuildingID()); if(tower == null) continue; - LocalDateTime liveTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(mine.liveMinute).minusMinutes(1).plusHours(5); + LocalDateTime liveTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(mine.liveMinute).minusMinutes(1); if(!mine.isActive && !mine.wasOpened) { if (LocalDateTime.now().isAfter(liveTime)) { mineWindowOpen(mine); From 3bcda38bb71be704489f5dec344593e4e3d331cb Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 25 May 2024 22:29:31 -0500 Subject: [PATCH 63/68] destroy and remove form cache and DB all buildinsg within city when its being destroyed --- src/engine/workthreads/DestroyCityThread.java | 37 ++++--------------- 1 file changed, 8 insertions(+), 29 deletions(-) diff --git a/src/engine/workthreads/DestroyCityThread.java b/src/engine/workthreads/DestroyCityThread.java index aeb46a6c..c42741fa 100644 --- a/src/engine/workthreads/DestroyCityThread.java +++ b/src/engine/workthreads/DestroyCityThread.java @@ -19,6 +19,7 @@ package engine.workthreads; */ import engine.Enum; +import engine.gameManager.BuildingManager; import engine.gameManager.DbManager; import engine.gameManager.GuildManager; import engine.gameManager.ZoneManager; @@ -53,7 +54,6 @@ public class DestroyCityThread implements Runnable { // Member variable assignment cityZone = city.getParent(); - newParent = cityZone.getParent(); formerGuild = city.getTOL().getGuild(); // Former guild loses it's tree! @@ -99,36 +99,15 @@ public class DestroyCityThread implements Runnable { if (cityBuilding.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.BANESTONE)) continue; - // All buildings are moved to a location relative - // to their new parent zone - - localCoords = ZoneManager.worldToLocal(cityBuilding.getLoc(), newParent); - - DbManager.BuildingQueries.MOVE_BUILDING(cityBuilding.getObjectUUID(), newParent.getObjectUUID(), localCoords.x, localCoords.y, localCoords.z); - - // All buildings are re-parented to a zone one node - // higher in the tree (continent) as we will be - // deleting the city zone very shortly. - - if (cityBuilding.getParentZoneID() != newParent.getParentZoneID()) - cityBuilding.setParentZone(newParent); - - // No longer a tree, no longer any protection contract! - - cityBuilding.setProtectionState(Enum.ProtectionState.NONE); - - // Destroy all remaining city assets - - if ((cityBuilding.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.BARRACK) - || (cityBuilding.getBlueprint().isWallPiece()) - || (cityBuilding.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.SHRINE) - || (cityBuilding.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.TOL) - || (cityBuilding.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.SPIRE) - || (cityBuilding.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.WAREHOUSE)) { - + //destroy all buildings if we are destroying the city itself if (cityBuilding.getRank() != -1) cityBuilding.setRank(-1); - } + + if(BuildingManager.getBuildingFromCache(cityBuilding.getObjectUUID()) != null){ + cityBuilding.removeFromCache(); + DbManager.BuildingQueries.DELETE_FROM_DATABASE(cityBuilding); + } + } if (city.getRealm() != null) From b1b2912092ed90c5fc0089228f22ae1338f799c0 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 26 May 2024 16:36:40 -0500 Subject: [PATCH 64/68] yet another attempt at mines --- src/engine/workthreads/MineThread.java | 40 +++++++++++++++++--------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/engine/workthreads/MineThread.java b/src/engine/workthreads/MineThread.java index 1cd254d0..d4d59ca9 100644 --- a/src/engine/workthreads/MineThread.java +++ b/src/engine/workthreads/MineThread.java @@ -16,16 +16,16 @@ import org.pmw.tinylog.Logger; import java.time.LocalDateTime; public class MineThread implements Runnable { + public static LocalDateTime nextPulse; public MineThread(){ } @Override public void run() { - LocalDateTime nextPulse = LocalDateTime.now().withMinute(59).minusHours(1); + nextPulse = LocalDateTime.now().withMinute(0); while (true) { if(LocalDateTime.now().isAfter(nextPulse)) { processMineWindows(); - nextPulse = nextPulse.plusMinutes(30); } } } @@ -108,21 +108,35 @@ public class MineThread implements Runnable { public static void processMineWindows(){ for (Mine mine : Mine.getMines()) { Building tower = BuildingManager.getBuildingFromCache(mine.getBuildingID()); + //if the tower comes back null, skip this mine if(tower == null) continue; - LocalDateTime liveTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(mine.liveMinute).minusMinutes(1); - if(!mine.isActive && !mine.wasOpened) { - if (LocalDateTime.now().isAfter(liveTime)) { - mineWindowOpen(mine); - // mine has not opened today yet, and it is now after the time it should have, open the mine - } + + //log the current time right now + LocalDateTime currentTime = LocalDateTime.now().plusMinutes(1); + + //check if this mine needs to open + LocalDateTime openTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(mine.liveMinute).withSecond(0).withNano(0); + if(currentTime.isAfter(openTime) && !mine.wasOpened){ + mineWindowOpen(mine); //hour and minute match, time to open the window + continue; } - //mine is active right now - if (LocalDateTime.now().isBefore(liveTime.plusMinutes(30))) - continue; // window is not over yet - if(tower.getRank() == 1 || mine.lastClaimer != null) - mineWindowClose(mine); + //check to see if the window shoul dbe closing now + if(currentTime.isAfter(openTime.plusMinutes(29))) { + //check to see if the tower was destoryed + boolean towerDestroyed = tower.getRank() < 1; + if(towerDestroyed){ + //check if a valid claimer exists to close the window and claim the mine since the tower was destroyed + if(mine.lastClaimer != null) + mineWindowClose(mine); + }else{ + //tower was not destroyed, mine window closes + mineWindowClose(mine); + } + + } } + nextPulse = nextPulse.plusMinutes(30); } } From a2da8f386108bd397fc725f8a03addcb2e15d802 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 26 May 2024 16:42:13 -0500 Subject: [PATCH 65/68] yet another attempt at mines --- src/engine/objects/Mine.java | 2 +- src/engine/objects/MineProduction.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index 42f96bff..94ddc3c7 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -218,7 +218,7 @@ public class Mine extends AbstractGameObject { writer.putInt(mine.getObjectUUID()); writer.putInt(mine.getObjectUUID()); //actually a hash of mine writer.putString(mine.mineType.name); - writer.putString(Mine.getMineNationality(mine.liveHour) + " {" + mine.capSize + " Man}"); + writer.putString(Mine.getMineNationality(mine.liveHour) + " " + mine.capSize + " Man "); writer.putInt(mine.production.hash); writer.putInt(mine.getModifiedProductionAmount()); writer.putInt(mine.getModifiedProductionAmount()); //TODO calculate range penalty here diff --git a/src/engine/objects/MineProduction.java b/src/engine/objects/MineProduction.java index a74e2fe7..a103c0a4 100644 --- a/src/engine/objects/MineProduction.java +++ b/src/engine/objects/MineProduction.java @@ -13,7 +13,7 @@ import java.util.HashMap; public enum MineProduction { - LUMBER("Universal Mine", new HashMap<>(), Resource.WORMWOOD, 1618637196, 1663491950), + LUMBER("Lumber Mine", new HashMap<>(), Resource.WORMWOOD, 1618637196, 1663491950), ORE("Ore Mine", new HashMap<>(), Resource.OBSIDIAN, 518103023, -788976428), GOLD("Gold Mine", new HashMap<>(), Resource.GALVOR, -662193002, -1227205358), MAGIC("Magic Mine", new HashMap<>(), Resource.BLOODSTONE, 504746863, -1753567069), From 917fddceeb6d1f7ea375e1e99cf8b063a4461022 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 26 May 2024 20:01:06 -0500 Subject: [PATCH 66/68] yet another attempt at mines --- src/engine/objects/Mine.java | 58 +++++++++++++++++++++----- src/engine/workthreads/MineThread.java | 13 ++++-- 2 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index 94ddc3c7..f172bba1 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -19,6 +19,7 @@ import engine.workthreads.ZergMechanicThread; import org.pmw.tinylog.Logger; import java.net.UnknownHostException; +import java.nio.charset.StandardCharsets; import java.sql.ResultSet; import java.sql.SQLException; import java.time.LocalDateTime; @@ -226,21 +227,16 @@ public class Mine extends AbstractGameObject { // Errant mines are currently open. Set time to now. - LocalDateTime mineOpenTime;// = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0); - if(mine.firstThirty == true){ - mineOpenTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(0).withSecond(0).withNano(0); - } - else{ - mineOpenTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(30).withSecond(0).withNano(0); - } + LocalDateTime mineOpenTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(mine.liveMinute); LocalDateTime mineCloseTime = mineOpenTime.plusMinutes(30); - if(LocalDateTime.now().isAfter(mineCloseTime)){ + if(LocalDateTime.now().isAfter(mineCloseTime) && mine.isActive == false){ mineOpenTime = mineOpenTime.plusDays(1); mineCloseTime = mineCloseTime.plusDays(1); } writer.putLocalDateTime(mineOpenTime); writer.putLocalDateTime(mineCloseTime); + writer.put(mine.isActive ? (byte) 0x01 : (byte) 0x00); Building mineTower = BuildingManager.getBuilding(mine.buildingID); @@ -250,9 +246,51 @@ public class Mine extends AbstractGameObject { writer.putInt(mine.isExpansion() ? mine.mineType.xpacHash : mine.mineType.hash); - writer.putString(mine.guildName); - GuildTag._serializeForDisplay(mine.guildTag, writer); writer.putString(mine.nationName); + GuildTag._serializeForDisplay(mine.guildTag, writer); + + boolean isPM = false; + if(mineOpenTime.getHour() > 11) + isPM = true; + + int hourOpen = mineOpenTime.getHour(); + int minuteOpen = mineOpenTime.getMinute(); + int hourClose = mineCloseTime.getHour(); + int minuteClose = mineCloseTime.getMinute(); + + if(isPM){ + hourOpen -= 12; + hourClose -= 12; + } + String timeString = hourOpen + ":"; + if(minuteOpen == 0){ + timeString += "00 "; + }else{ + timeString += "30 "; + } + + if(isPM){ + timeString += "PM "; + }else{ + timeString += "AM "; + } + + timeString += " to "; + + timeString += hourClose + ":"; + + if(minuteClose == 0){ + timeString += "00 "; + }else{ + timeString += "30 "; + } + + if(isPM){ + timeString += "PM CST"; + }else{ + timeString += "AM CST"; + } + writer.putString(timeString); GuildTag._serializeForDisplay(mine.nationTag, writer); } diff --git a/src/engine/workthreads/MineThread.java b/src/engine/workthreads/MineThread.java index d4d59ca9..84db8207 100644 --- a/src/engine/workthreads/MineThread.java +++ b/src/engine/workthreads/MineThread.java @@ -22,7 +22,7 @@ public class MineThread implements Runnable { } @Override public void run() { - nextPulse = LocalDateTime.now().withMinute(0); + nextPulse = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0); while (true) { if(LocalDateTime.now().isAfter(nextPulse)) { processMineWindows(); @@ -33,7 +33,6 @@ public class MineThread implements Runnable { public static void mineWindowOpen(Mine mine) { mine.setActive(true); - ChatManager.chatSystemChannel(mine.getParentZone().getName() + "'s Mine is now Active!"); Logger.info(mine.getParentZone().getName() + "'s Mine is now Active!"); } @@ -119,20 +118,26 @@ public class MineThread implements Runnable { LocalDateTime openTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(mine.liveMinute).withSecond(0).withNano(0); if(currentTime.isAfter(openTime) && !mine.wasOpened){ mineWindowOpen(mine); //hour and minute match, time to open the window + ChatManager.chatSystemChannel(mine.getParentZone().getName() + " " + mine.getMineType() + "MINE is now vulnerable to attack!"); continue; } //check to see if the window shoul dbe closing now - if(currentTime.isAfter(openTime.plusMinutes(29))) { + if(currentTime.isAfter(openTime.plusMinutes(29)) && mine.isActive) { //check to see if the tower was destoryed boolean towerDestroyed = tower.getRank() < 1; if(towerDestroyed){ //check if a valid claimer exists to close the window and claim the mine since the tower was destroyed - if(mine.lastClaimer != null) + if(mine.lastClaimer != null) { mineWindowClose(mine); + ChatManager.chatSystemChannel("The fight for " + mine.getParentZone().getName() + " " + mine.getMineType() + " MINE has concluded. " + mine.lastClaimer.getName() + " has seized it in the name of " + mine.lastClaimer.getGuild().getNation()); + }else{ + ChatManager.chatSystemChannel("The " + mine.getParentZone().getName() + " " + mine.getMineType() + " MINE is still unclaimed. The battle continues."); + } }else{ //tower was not destroyed, mine window closes mineWindowClose(mine); + ChatManager.chatSystemChannel(tower.getGuild().getNation().getName() + " has successfully defended the " + mine.getParentZone().getName() + " " + mine.getMineType() + " MINE, and retains their claim."); } } From a9f006936b552366236528c8c709c959bf949599 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 26 May 2024 20:05:28 -0500 Subject: [PATCH 67/68] yet another attempt at mines --- src/engine/workthreads/MineThread.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/workthreads/MineThread.java b/src/engine/workthreads/MineThread.java index 84db8207..ea0e3bf6 100644 --- a/src/engine/workthreads/MineThread.java +++ b/src/engine/workthreads/MineThread.java @@ -116,7 +116,7 @@ public class MineThread implements Runnable { //check if this mine needs to open LocalDateTime openTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(mine.liveMinute).withSecond(0).withNano(0); - if(currentTime.isAfter(openTime) && !mine.wasOpened){ + if(currentTime.isAfter(openTime) && currentTime.isBefore(openTime.plusMinutes(30)) && !mine.wasOpened){ mineWindowOpen(mine); //hour and minute match, time to open the window ChatManager.chatSystemChannel(mine.getParentZone().getName() + " " + mine.getMineType() + "MINE is now vulnerable to attack!"); continue; From 75b68c0a8c1eeb826bf3ade927c78b1b33cc4b77 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 26 May 2024 22:43:03 -0500 Subject: [PATCH 68/68] disc spawn timers corrected --- src/engine/server/world/WorldServer.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/engine/server/world/WorldServer.java b/src/engine/server/world/WorldServer.java index 48c8dbd1..3d5e80f6 100644 --- a/src/engine/server/world/WorldServer.java +++ b/src/engine/server/world/WorldServer.java @@ -251,11 +251,11 @@ public class WorldServer { if(LocalDateTime.now().isAfter(nextDiscSpawn)) { switch (LocalDateTime.now().getHour()) { case 0: - case 4: - case 8: - case 12: - case 16: - case 20: + case 3: + case 7: + case 11: + case 15: + case 19: for (Mob dropper : Mob.disciplineDroppers) { if (!dropper.isAlive()) { Zone.respawnQue.add(dropper);