From cf6f684f5eaf54f33de9716feb33e3720581fac7 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 2 Jun 2024 15:50:21 -0500 Subject: [PATCH 01/18] FIRST AFTER ROLLBACK: reintroduce mines --- src/engine/devcmd/cmds/MineActiveCmd.java | 6 +- src/engine/objects/Mine.java | 322 +++++++--------------- src/engine/server/world/WorldServer.java | 15 +- src/engine/workthreads/MineThread.java | 140 ---------- 4 files changed, 108 insertions(+), 375 deletions(-) delete mode 100644 src/engine/workthreads/MineThread.java diff --git a/src/engine/devcmd/cmds/MineActiveCmd.java b/src/engine/devcmd/cmds/MineActiveCmd.java index 1113cffa..b66a01bc 100644 --- a/src/engine/devcmd/cmds/MineActiveCmd.java +++ b/src/engine/devcmd/cmds/MineActiveCmd.java @@ -12,12 +12,10 @@ package engine.devcmd.cmds; import engine.devcmd.AbstractDevCmd; import engine.gameManager.BuildingManager; -import engine.gameManager.SimulationManager; import engine.objects.AbstractGameObject; import engine.objects.Building; import engine.objects.Mine; import engine.objects.PlayerCharacter; -import engine.workthreads.MineThread; /** * @@ -42,10 +40,10 @@ public class MineActiveCmd extends AbstractDevCmd { String trigger = args[0]; switch (trigger) { case "true": - MineThread.mineWindowOpen(mine); + Mine.mineWindowOpen(mine); break; case "false": - MineThread.mineWindowClose(mine); + Mine.mineWindowClose(mine); break; default: this.sendUsage(pcSender); diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index 1b65dedf..300ec1b7 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -11,9 +11,13 @@ package engine.objects; import engine.Enum; import engine.InterestManagement.WorldGrid; +import engine.db.archive.DataWarehouse; +import engine.db.archive.MineRecord; import engine.gameManager.*; import engine.net.ByteBufferWriter; +import engine.net.DispatchMessage; import engine.net.client.msg.ErrorPopupMsg; +import engine.net.client.msg.chat.ChatSystemMsg; import engine.server.MBServerStatics; import engine.workthreads.ZergMechanicThread; import org.joda.time.DateTime; @@ -68,6 +72,9 @@ public class Mine extends AbstractGameObject { public static ArrayList AmericaMines = new ArrayList<>(); public boolean wasOpened = false; + + public int liveHour; + public int liveMinute; /** * ResultSet Constructor */ @@ -115,140 +122,9 @@ public class Mine extends AbstractGameObject { this.production = Resource.valueOf(rs.getString("mine_resource")); this.lastClaimer = null; - } - } - - 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; - }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 = 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; - }catch(Exception e){ - - } - - int count = 1; - for(Mine mine : EuroMines){ - switch(count){ - case 1: - mine.capSize = 3; - break; - case 2: - mine.capSize = 5; - break; - case 3: - mine.capSize = 10; - 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 = 10; - 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 = 10; - 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); - } - } + this.liveHour = rs.getInt("mineLiveHour"); + this.liveMinute = rs.getInt("mineLiveMinute"); + this.capSize = rs.getInt("capSize"); } } public static void releaseMineClaims(PlayerCharacter playerCharacter) { @@ -292,8 +168,6 @@ public class Mine extends AbstractGameObject { public static void loadAllMines() { - try { - //Load mine resources MineProduction.addResources(); @@ -305,91 +179,6 @@ public class Mine extends AbstractGameObject { Mine.towerMap.put(mine.buildingID, mine); //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(); - } - - 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; - } } /* @@ -834,4 +623,95 @@ public class Mine extends AbstractGameObject { } return true; } + + public static void mineWindowOpen(Mine mine) { + mine.setActive(true); + Logger.info(mine.getParentZone().getName() + "'s Mine is now Active!"); + } + public static boolean mineWindowClose(Mine mine) { + // No need to end the window of a mine which never opened. + if (mine.isActive == false) + return false; + Building mineBuilding = BuildingManager.getBuildingFromCache(mine.getBuildingID()); + if (mineBuilding == null) { + Logger.debug("Null mine building for Mine " + mine.getObjectUUID() + " Building " + mine.getBuildingID()); + return false; + } + for(Integer id : mine._playerMemory ){ + PlayerCharacter.getPlayerCharacter(id).ZergMultiplier = 1.0f; + } + for(Integer id : mine._recentMemory.keySet()){ + PlayerCharacter.getPlayerCharacter(id).ZergMultiplier = 1.0f; + } + // Mine building still stands; nothing to do. + // We can early exit here. + if (mineBuilding.getRank() > 0) { + mine.setActive(false); + mine.lastClaimer = null; + return true; + } + // This mine does not have a valid claimer + // we will therefore set it to errant + // and keep the window open. + if (!Mine.validateClaimer(mine.lastClaimer)) { + mine.lastClaimer = null; + mine.updateGuildOwner(null); + mine.setActive(true); + return false; + } + //Update ownership to map + mine.guildName = mine.getOwningGuild().getName(); + mine.guildTag = mine.getOwningGuild().getGuildTag(); + Guild nation = mine.getOwningGuild().getNation(); + mine.nationName = nation.getName(); + mine.nationTag = nation.getGuildTag(); + mineBuilding.rebuildMine(mine.capSize * 5000); + WorldGrid.updateObject(mineBuilding); + ChatSystemMsg chatMsg = new ChatSystemMsg(null, mine.lastClaimer.getName() + " has claimed the mine in " + mine.getParentZone().getName() + " for " + mine.getOwningGuild().getName() + ". The mine is no longer active."); + chatMsg.setMessageType(10); + chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); + DispatchMessage.dispatchMsgToAll(chatMsg); + // Warehouse this claim event + MineRecord mineRecord = MineRecord.borrow(mine, mine.lastClaimer, Enum.RecordEventType.CAPTURE); + DataWarehouse.pushToWarehouse(mineRecord); + mineBuilding.setRank(mineBuilding.getRank()); + mine.lastClaimer = null; + mine.setActive(false); + mine.wasClaimed = true; + return true; + } + public static void processMineWindows(){ + LocalDateTime currentTime = LocalDateTime.now(); + for (Mine mine : Mine.getMines()) { + Building tower = BuildingManager.getBuildingFromCache(mine.getBuildingID()); + //if the tower comes back null, skip this mine + if(tower == null) + continue; + //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) && 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; + } + //check to see if the window shoul dbe closing now + 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) { + 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."); + } + } + } + } } diff --git a/src/engine/server/world/WorldServer.java b/src/engine/server/world/WorldServer.java index 48c8dbd1..9579e470 100644 --- a/src/engine/server/world/WorldServer.java +++ b/src/engine/server/world/WorldServer.java @@ -210,6 +210,7 @@ public class WorldServer { LocalDateTime nextHourlyJobTime = LocalDateTime.now().withMinute(0).withSecond(0).plusHours(0); LocalDateTime nextWareHousePushTime = LocalDateTime.now(); LocalDateTime nextDiscSpawn = LocalDateTime.now().withMinute(0).withSecond(0).plusHours(1); + LocalDateTime minePulse = LocalDateTime.now().withMinute(0).withSecond(0).plusHours(0); // Begin execution of main game loop @@ -266,6 +267,10 @@ public class WorldServer { } nextDiscSpawn = nextDiscSpawn.plusHours(1); } + if(LocalDateTime.now().isAfter(minePulse)) { + Mine.processMineWindows(); + minePulse = minePulse.plusMinutes(30); + } ThreadUtils.sleep(50); } } @@ -545,16 +550,6 @@ public class WorldServer { Logger.info("Running garbage collection..."); System.gc(); - Logger.info("Starting Mine Thread..."); - Thread mineThread = new Thread(new MineThread()); - mineThread.setName("mine thread"); - mineThread.start(); - - //Logger.info("Starting Power Thread..."); - //Thread powerThread = new Thread(new PowersThread()); - //powerThread.setName("power thread"); - //powerThread.start(); - return true; } diff --git a/src/engine/workthreads/MineThread.java b/src/engine/workthreads/MineThread.java deleted file mode 100644 index 281e21f0..00000000 --- a/src/engine/workthreads/MineThread.java +++ /dev/null @@ -1,140 +0,0 @@ -package engine.workthreads; - -import engine.Enum; -import engine.InterestManagement.WorldGrid; -import engine.db.archive.DataWarehouse; -import engine.db.archive.MineRecord; -import engine.gameManager.BuildingManager; -import engine.gameManager.ChatManager; -import engine.net.DispatchMessage; -import engine.net.client.msg.chat.ChatSystemMsg; -import engine.objects.Building; -import engine.objects.Guild; -import engine.objects.Mine; -import engine.objects.PlayerCharacter; -import org.pmw.tinylog.Logger; - -import java.time.LocalDateTime; - -public class MineThread implements Runnable { - public MineThread(){ - - } - @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()) { - - if(nextPulse.getHour() == 2 && nextPulse.getMinute() == 0){ - mine.wasClaimed = false; - mine.hasProduced = false; - - } - 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) { - - mine.setActive(true); - ChatManager.chatSystemChannel(mine.getParentZone().getName() + "'s Mine is now Active!"); - Logger.info(mine.getParentZone().getName() + "'s Mine is now Active!"); - } - - public static boolean mineWindowClose(Mine mine) { - - // No need to end the window of a mine which never opened. - - if (mine.isActive == false) - return false; - - Building mineBuilding = BuildingManager.getBuildingFromCache(mine.getBuildingID()); - - if (mineBuilding == null) { - Logger.debug("Null mine building for Mine " + mine.getObjectUUID() + " Building " + mine.getBuildingID()); - return false; - } - - for(Integer id : mine._playerMemory ){ - PlayerCharacter.getPlayerCharacter(id).ZergMultiplier = 1.0f; - } - for(Integer id : mine._recentMemory.keySet()){ - PlayerCharacter.getPlayerCharacter(id).ZergMultiplier = 1.0f; - } - // Mine building still stands; nothing to do. - // We can early exit here. - - if (mineBuilding.getRank() > 0) { - mine.setActive(false); - mine.lastClaimer = null; - return true; - } - - // This mine does not have a valid claimer - // we will therefore set it to errant - // and keep the window open. - - if (!Mine.validateClaimer(mine.lastClaimer)) { - mine.lastClaimer = null; - mine.updateGuildOwner(null); - mine.setActive(true); - return false; - } - - //Update ownership to map - - mine.guildName = mine.getOwningGuild().getName(); - mine.guildTag = mine.getOwningGuild().getGuildTag(); - Guild nation = mine.getOwningGuild().getNation(); - mine.nationName = nation.getName(); - mine.nationTag = nation.getGuildTag(); - - mineBuilding.rebuildMine(mine.capSize * 5000); - WorldGrid.updateObject(mineBuilding); - - ChatSystemMsg chatMsg = new ChatSystemMsg(null, mine.lastClaimer.getName() + " has claimed the mine in " + mine.getParentZone().getName() + " for " + mine.getOwningGuild().getName() + ". The mine is no longer active."); - chatMsg.setMessageType(10); - chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); - DispatchMessage.dispatchMsgToAll(chatMsg); - - // Warehouse this claim event - - MineRecord mineRecord = MineRecord.borrow(mine, mine.lastClaimer, Enum.RecordEventType.CAPTURE); - DataWarehouse.pushToWarehouse(mineRecord); - - mineBuilding.setRank(mineBuilding.getRank()); - mine.lastClaimer = null; - mine.setActive(false); - mine.wasClaimed = true; - return true; - } -} From f4346b97f7a80c158935a12e8297fe2ce2657828 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 2 Jun 2024 15:58:26 -0500 Subject: [PATCH 02/18] SECOND AFTER ROLLBACK: serialize MineTimes correctly --- src/engine/objects/Mine.java | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index 300ec1b7..62f882dc 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -63,10 +63,6 @@ public class Mine extends AbstractGameObject { public HashMap> dividedPlayers; public boolean hasProduced = false; - - public int liveTime; - public Boolean firstThirty = true; - public static ArrayList ChinaMines = new ArrayList<>(); public static ArrayList EuroMines = new ArrayList<>(); public static ArrayList AmericaMines = new ArrayList<>(); @@ -177,7 +173,6 @@ public class Mine extends AbstractGameObject { for (Mine mine : serverMines) { Mine.mineMap.put(mine, mine.buildingID); Mine.towerMap.put(mine.buildingID, mine); - //mine.mineType = MineProduction.LUMBER; } } @@ -194,15 +189,7 @@ public class Mine extends AbstractGameObject { 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.capSize + " Man "); writer.putInt(mine.production.hash); writer.putInt(mine.getModifiedProductionAmount()); writer.putInt(mine.getModifiedProductionAmount()); //TODO calculate range penalty here @@ -210,13 +197,7 @@ 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.liveTime).withMinute(0).withSecond(0).withNano(0); - } - else{ - mineOpenTime = LocalDateTime.now().withHour(mine.liveTime).withMinute(30).withSecond(0).withNano(0); - } + LocalDateTime mineOpenTime = LocalDateTime.now().withHour(mine.liveHour).withMinute(mine.liveMinute).withSecond(0).withNano(0); LocalDateTime mineCloseTime = mineOpenTime.plusMinutes(30); if(LocalDateTime.now().isAfter(mineCloseTime)){ From 45eb0776d61dea0509dbe4e34fb0c4f7b74c12b6 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 2 Jun 2024 16:24:55 -0500 Subject: [PATCH 03/18] THIRD AFTER ROLLBACK: contract and rune and glass drop rates adjusted properly --- src/engine/gameManager/LootManager.java | 38 ++++++++++++------------- src/engine/objects/Mob.java | 7 +++++ 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index b0cc259b..d467c448 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -122,20 +122,16 @@ public enum LootManager { 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(mob.contractCounter >= 250){ + MobLoot extraLoot = rollForContract(bse.genTable, mob); + if (extraLoot != null) + mob.getCharItemManager().addItemToInventory(extraLoot); + } + if(mob.runeCounter >= 250){ + MobLoot extraLoot = rollForRune(bse.genTable, mob); + if (extraLoot != null) + mob.getCharItemManager().addItemToInventory(extraLoot); + } break; case "ITEM": GenerateInventoryDrop(mob, bse); @@ -566,7 +562,7 @@ public enum LootManager { if (_itemTables.containsKey(itemTableId) == false) return null; - ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, ThreadLocalRandom.current().nextInt(1,321)); + ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, ThreadLocalRandom.current().nextInt(75,321)); if (tableRow == null) return null; @@ -576,8 +572,10 @@ public enum LootManager { return null; MobLoot outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false); - if(outItem != null) + if(outItem != null) { + mob.contractCounter = 0; return outItem; + } return null; } public static MobLoot rollForRune(int table, Mob mob){ @@ -593,7 +591,7 @@ public enum LootManager { if (_itemTables.containsKey(itemTableId) == false) return null; - ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, ThreadLocalRandom.current().nextInt(1,321)); + ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, ThreadLocalRandom.current().nextInt(75,321)); if (tableRow == null) return null; @@ -603,12 +601,14 @@ public enum LootManager { return null; MobLoot outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false); - if(outItem != null) + if(outItem != null) { + mob.runeCounter = 0; return outItem; + } return null; } public static MobLoot rollForGlass( Mob mob){ - ItemTableEntry tableRow = ItemTableEntry.rollTable(126, ThreadLocalRandom.current().nextInt(1,321)); + ItemTableEntry tableRow = ItemTableEntry.rollTable(126, ThreadLocalRandom.current().nextInt(220,321)); if (tableRow == null) return null; diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index 928c5e56..0371dff4 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -36,6 +36,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.locks.ReentrantReadWriteLock; import static engine.gameManager.NPCManager._runeSetMap; @@ -85,6 +86,9 @@ public class Mob extends AbstractIntelligenceAgent { public boolean dropper = false; + public int contractCounter = 0; + public int runeCounter = 0; + // New Mobile constructor. Fill in the blanks and then call // PERSIST. public Mob() { @@ -167,6 +171,9 @@ public class Mob extends AbstractIntelligenceAgent { //this.setResists(Resists.getResists(rs.getInt("mob_spawnType"))); setResistsForMob(this); + + this.contractCounter = ThreadLocalRandom.current().nextInt(250); + this.runeCounter = ThreadLocalRandom.current().nextInt(250); } catch (Exception e) { Logger.error(e + " " + this.dbID); } From 737da1bf14e10955ba91d6feef3b05d4292515cb Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 2 Jun 2024 21:55:31 -0500 Subject: [PATCH 04/18] FOURTH AFTER ROLLBACK: error catching for attempt ot upgrade warehouses --- src/engine/net/client/handlers/UpgradeAssetMsgHandler.java | 2 ++ src/engine/net/client/msg/ManageCityAssetsMsg.java | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/engine/net/client/handlers/UpgradeAssetMsgHandler.java b/src/engine/net/client/handlers/UpgradeAssetMsgHandler.java index 3638c2ec..255c71d5 100644 --- a/src/engine/net/client/handlers/UpgradeAssetMsgHandler.java +++ b/src/engine/net/client/handlers/UpgradeAssetMsgHandler.java @@ -66,6 +66,8 @@ public class UpgradeAssetMsgHandler extends AbstractClientMsgHandler { Logger.error("Attempt to upgrade null building by " + player.getName()); return true; } + if(buildingToRank.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.WAREHOUSE)) + return true; // Early exit for building that is already ranking diff --git a/src/engine/net/client/msg/ManageCityAssetsMsg.java b/src/engine/net/client/msg/ManageCityAssetsMsg.java index 473082b2..1e45f2e2 100644 --- a/src/engine/net/client/msg/ManageCityAssetsMsg.java +++ b/src/engine/net/client/msg/ManageCityAssetsMsg.java @@ -9,6 +9,7 @@ package engine.net.client.msg; +import engine.Enum; import engine.Enum.*; import engine.gameManager.BuildingManager; import engine.gameManager.ZoneManager; @@ -531,7 +532,10 @@ public class ManageCityAssetsMsg extends ClientNetMsg { else if (building.getRank() == building.getBlueprint().getMaxRank()) this.upgradeCost = Integer.MAX_VALUE; else - this.upgradeCost = building.getBlueprint().getRankCost(Math.min(building.getRank() + 1, 7)); + if(building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.WAREHOUSE)) + this.upgradeCost = Integer.MAX_VALUE; + else + this.upgradeCost = building.getBlueprint().getRankCost(Math.min(building.getRank() + 1, 7)); writer.putInt(this.upgradeCost); } else From 1798a8f17058dc9e1fc6989756a83e872cd4b163 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sun, 2 Jun 2024 22:02:19 -0500 Subject: [PATCH 05/18] FIFTH AFTER ROLLBACK: mob rune and contract work updated correctly --- src/engine/gameManager/LootManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index d467c448..35cf7fa3 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -99,7 +99,8 @@ public enum LootManager { } private static void RunBootySet(ArrayList entries, Mob mob) { - +mob.runeCounter++; +mob.contractCounter++; float dropRate = NORMAL_DROP_RATE; //roll the geenric world drop table if(mob.parentZone.getSafeZone() == 0) { From 8ccdbf8cc9b7365614e7fc1433041f6bb07d966a Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Jun 2024 19:25:54 -0500 Subject: [PATCH 06/18] SIXTH AFTER ROLLBACK: mob rune and contract drop annouces local --- src/engine/gameManager/LootManager.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index 35cf7fa3..2d40858f 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -14,6 +14,7 @@ import engine.net.DispatchMessage; import engine.net.client.msg.ErrorPopupMsg; import engine.net.client.msg.chat.ChatSystemMsg; import engine.objects.*; +import engine.server.MBServerStatics; import org.pmw.tinylog.Logger; import java.util.ArrayList; @@ -99,8 +100,8 @@ public enum LootManager { } private static void RunBootySet(ArrayList entries, Mob mob) { -mob.runeCounter++; -mob.contractCounter++; + mob.runeCounter++; + mob.contractCounter++; float dropRate = NORMAL_DROP_RATE; //roll the geenric world drop table if(mob.parentZone.getSafeZone() == 0) { @@ -123,12 +124,12 @@ mob.contractCounter++; case "LOOT": if (ThreadLocalRandom.current().nextInt(1, 100 + 1) < (bse.dropChance * dropRate)) GenerateLootDrop(mob, bse.genTable); //generate normal loot drop - if(mob.contractCounter >= 250){ + if(mob.contractCounter * dropRate >= 250){ MobLoot extraLoot = rollForContract(bse.genTable, mob); if (extraLoot != null) mob.getCharItemManager().addItemToInventory(extraLoot); } - if(mob.runeCounter >= 250){ + if(mob.runeCounter * dropRate >= 250){ MobLoot extraLoot = rollForRune(bse.genTable, mob); if (extraLoot != null) mob.getCharItemManager().addItemToInventory(extraLoot); @@ -575,6 +576,10 @@ mob.contractCounter++; MobLoot outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false); if(outItem != null) { mob.contractCounter = 0; + ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " looks like he found something special"); + chatMsg.setMessageType(10); + chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); + DispatchMessage.dispatchMsgToInterestArea(mob,chatMsg, Enum.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE,false,false); return outItem; } return null; @@ -604,6 +609,10 @@ mob.contractCounter++; MobLoot outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false); if(outItem != null) { mob.runeCounter = 0; + ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " looks like he found something special"); + chatMsg.setMessageType(10); + chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); + DispatchMessage.dispatchMsgToInterestArea(mob,chatMsg, Enum.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE,false,false); return outItem; } return null; From 6d68d048b01e78d17cadf83ceb37fbc8a8ba1147 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Jun 2024 19:47:23 -0500 Subject: [PATCH 07/18] catch process mine window logic --- src/engine/objects/Mine.java | 56 +++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index 62f882dc..ae62a95e 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -661,37 +661,41 @@ public class Mine extends AbstractGameObject { mine.wasClaimed = true; return true; } - public static void processMineWindows(){ + public static void processMineWindows() { LocalDateTime currentTime = LocalDateTime.now(); for (Mine mine : Mine.getMines()) { - Building tower = BuildingManager.getBuildingFromCache(mine.getBuildingID()); - //if the tower comes back null, skip this mine - if(tower == null) - continue; - //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) && 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; - } - //check to see if the window shoul dbe closing now - 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) { + try { + Building tower = BuildingManager.getBuildingFromCache(mine.getBuildingID()); + //if the tower comes back null, skip this mine + if (tower == null) + continue; + //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) && 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; + } + //check to see if the window shoul dbe closing now + 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) { + 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("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."); + ChatManager.chatSystemChannel(tower.getGuild().getNation().getName() + " has successfully defended the " + mine.getParentZone().getName() + " " + mine.getMineType() + " MINE, and retains their claim."); } - }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."); } + } catch (Exception ex) { + Logger.error("Mine Failed: " + mine.getObjectUUID() + " " + ex.getMessage()); } } } From 0f7ef9f56b8b6270eb75075f92fe31e9441f1024 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Mon, 3 Jun 2024 19:51:06 -0500 Subject: [PATCH 08/18] city data msg catch --- src/engine/net/client/msg/CityDataMsg.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/engine/net/client/msg/CityDataMsg.java b/src/engine/net/client/msg/CityDataMsg.java index f5f679e7..5e571e9f 100644 --- a/src/engine/net/client/msg/CityDataMsg.java +++ b/src/engine/net/client/msg/CityDataMsg.java @@ -87,7 +87,11 @@ public class CityDataMsg extends ClientNetMsg { temp.putInt(cityList.size()); for (City city : cityList) - City.serializeForClientMsg(city, temp); + try { + City.serializeForClientMsg(city, temp); + }catch(Exception e){ + continue; + } temp.put((byte) 0); // PAD // Serialize runegates From 6151a9e650111c845bd941affdfbd333405b41a1 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Tue, 4 Jun 2024 08:56:06 -0500 Subject: [PATCH 09/18] mine close crash bug --- src/engine/objects/Mine.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index ae62a95e..6fe62123 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -634,12 +634,12 @@ public class Mine extends AbstractGameObject { // This mine does not have a valid claimer // we will therefore set it to errant // and keep the window open. - if (!Mine.validateClaimer(mine.lastClaimer)) { - mine.lastClaimer = null; - mine.updateGuildOwner(null); - mine.setActive(true); - return false; - } + //if (!Mine.validateClaimer(mine.lastClaimer)) { + // mine.lastClaimer = null; + // mine.updateGuildOwner(null); + // mine.setActive(true); + // return false; + //} //Update ownership to map mine.guildName = mine.getOwningGuild().getName(); mine.guildTag = mine.getOwningGuild().getGuildTag(); From b255b1c9f45222b6059934df9a53037e4cb2a4c6 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 5 Jun 2024 10:41:14 -0500 Subject: [PATCH 10/18] rune and contract drop rate --- src/engine/gameManager/LootManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index 2d40858f..796b3526 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -575,7 +575,7 @@ public enum LootManager { MobLoot outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false); if(outItem != null) { - mob.contractCounter = 0; + mob.contractCounter = ThreadLocalRandom.current().nextInt(200); ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " looks like he found something special"); chatMsg.setMessageType(10); chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); @@ -608,7 +608,7 @@ public enum LootManager { MobLoot outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false); if(outItem != null) { - mob.runeCounter = 0; + mob.runeCounter = ThreadLocalRandom.current().nextInt(200); ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " looks like he found something special"); chatMsg.setMessageType(10); chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); From f30a02a6d5e165a1f820ee300b17ad6132ef70c9 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 5 Jun 2024 10:56:27 -0500 Subject: [PATCH 11/18] updated maintenance system --- .../gameManager/MaintenanceManager.java | 461 +++++++----------- 1 file changed, 170 insertions(+), 291 deletions(-) diff --git a/src/engine/gameManager/MaintenanceManager.java b/src/engine/gameManager/MaintenanceManager.java index c657b124..5a3a8505 100644 --- a/src/engine/gameManager/MaintenanceManager.java +++ b/src/engine/gameManager/MaintenanceManager.java @@ -5,327 +5,206 @@ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // Magicbane Emulator Project © 2013 - 2022 // www.magicbane.com - package engine.gameManager; - // Defines static methods which comprise the magicbane // building maintenance system. - import engine.Enum; import engine.objects.*; import org.pmw.tinylog.Logger; - import java.time.LocalDateTime; import java.util.ArrayList; - +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; public enum MaintenanceManager { - MAINTENANCEMANAGER; - public static void setMaintDateTime(Building building, LocalDateTime maintDate) { - building.maintDateTime = maintDate; DbManager.BuildingQueries.updateMaintDate(building); - } - - public static void processBuildingMaintenance() { - - ArrayList buildingList; - ArrayList maintList; - ArrayList derankList = new ArrayList<>(); - - Logger.info("Starting Maintenance on Player Buildings"); - - // Build list of buildings to apply maintenance on. - - buildingList = new ArrayList(DbManager.getList(Enum.GameObjectType.City)); - maintList = buildMaintList(buildingList); - - // Deduct upkeep and build list of buildings - // which did not have funds available - - for (Building building : maintList) { - - if (chargeUpkeep(building) == false) - derankList.add(building); - } - // Reset maintenance dates for these buildings - - for (Building building : maintList) { - if(derankList.contains(building) == false) - setMaintDateTime(building, LocalDateTime.now().plusDays(7)); - else - setMaintDateTime(building, LocalDateTime.now().plusDays(1)); - + public static void dailyMaintenance() { + Logger.info("Maintenance has started"); + // Run maintenance on player buildings + if (ConfigManager.MB_WORLD_MAINTENANCE.getValue().equalsIgnoreCase("true")) + processMaintenance(); + else + Logger.info("Maintenance Costings: DISABLED"); + Logger.info("Maintenance has completed!"); + } + public static void processMaintenance() { + //create list of all cities + ConcurrentHashMap worldCities = DbManager.getMap(Enum.GameObjectType.City); + //loop all cities + for (AbstractGameObject ago : worldCities.values()) { + if (ago.getObjectType().equals(Enum.GameObjectType.City)) { + City city = (City) ago; + if(city == null || !city.getParent().isPlayerCity()) + continue; + Building tol = city.getTOL(); + if(tol == null) + continue; + LocalDateTime maintenanceDueDate = tol.maintDateTime.withHour(1).withMinute(0).withSecond(0); + LocalDateTime now = LocalDateTime.now(); + if(now.isAfter(maintenanceDueDate)) + processTolMaintenance(tol, city.getWarehouse()); + } } - // Derak or destroy buildings that did not - // have funds available. - - for (Building building : derankList) - building.destroyOrDerank(null); - - Logger.info("Structures: " + buildingList.size() + " Maint: " + maintList.size() + " Derank: " + derankList.size()); } - - // Iterate over all buildings in game and apply exclusion rules - // returning a list of building for which maintenance is due. - - private static ArrayList buildMaintList(ArrayList buildingList) { - - ArrayList maintList = new ArrayList<>(); - - for (AbstractGameObject gameObject : buildingList) { - - Building building = ((City)gameObject).getTOL();//(Building) gameObject; - - if(building == null) - continue; - - // No maintenance on NPC owned buildings (Cache loaded) - - if (building.getProtectionState() == Enum.ProtectionState.NPC) - continue; - - // No maintenance on constructing meshes - - if (building.getRank() < 1) - continue; - - // No Maintenance on furniture - - if (building.parentBuildingID != 0) - continue; - - // No Blueprint? - - if (building.getBlueprint() == null) { - Logger.error("Blueprint missing for uuid: " + building.getObjectUUID()); - continue; + public static void processTolMaintenance(Building tol, Warehouse warehouse){ + if(tol == null) + return; + if(tol.getRank() == 8) + handleR8(tol,warehouse); + else + handleNormal(tol,warehouse); + } + public static void handleNormal(Building tol, Warehouse warehouse){ + //handle r7 and lower ToL maintenance + int goldDue = 3000000; + //enough on strongbox alone to pay + if (tol.getStrongboxValue() >= goldDue) { + tol.maintDateTime = LocalDateTime.now().plusDays(7); + if(DbManager.BuildingQueries.updateMaintDate(tol)) { + tol.setStrongboxValue(tol.getStrongboxValue() - goldDue); } - - // No maintenance on banestones omfg - - if (building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.BANESTONE)) - continue; - - // no maintenance on Mines omfg - - if (building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.MINE)) - continue; - - // Null Maintenance date? - - if (building.maintDateTime == null) { - Logger.error("Null maint date for building UUID: " + building.getObjectUUID()); - continue; + return; + } + int newStrongboxValue = tol.getStrongboxValue(); + int newWarehouseGold = 0; + if(warehouse != null && warehouse.getResources().get(ItemBase.getItemBase(7)) != null) { + newWarehouseGold = warehouse.getResources().get(ItemBase.getItemBase(7)); + } else{ + //wasnt enough on strongbox and gold in warehouse is empty + tol.maintDateTime = LocalDateTime.now().plusDays(1); + if(DbManager.BuildingQueries.updateMaintDate(tol)) { + tol.destroyOrDerank(null); } - - // Maintenance date is in the future - - if (building.maintDateTime.isAfter(LocalDateTime.now())) - continue; - - - //no maintenance if day of week doesnt match - if (LocalDateTime.now().getDayOfWeek().ordinal() != building.maintDateTime.getDayOfWeek().ordinal()) { - continue; + return; + } + //some on strongbox to pay + if (tol.getStrongboxValue() > 0) { + newStrongboxValue = 0; + goldDue -= tol.getStrongboxValue(); + } + if(newWarehouseGold < goldDue){ + //not enough gold to pay, you miss maintenance + tol.maintDateTime = LocalDateTime.now().plusDays(1); + if(DbManager.BuildingQueries.updateMaintDate(tol)) { + tol.destroyOrDerank(null); } - // Add building to maintenance queue - - maintList.add(building); + return; } - - return maintList; - } - - // Method removes the appropriate amount of gold/resources from - // a building according to it's maintenance schedule. True/False - // is returned indicating if the building had enough funds to cover. - - public static boolean chargeUpkeep(Building building) { - - City city = null; - Warehouse warehouse = null; - int maintCost = 0; - int overDraft = 0; - boolean hasFunds = false; - boolean hasResources = false; - int resourceValue = 0; - - city = building.getCity(); - - if (city != null) - warehouse = city.getWarehouse(); - - // Cache maintenance cost value - - //maintCost = building.getMaintCost(); - maintCost = 3000000; - - // Something went wrong. Missing buildinggroup from switch? - - if (maintCost == 0) { - Logger.error("chargeUpkeep", "Error retrieving rankcost for " + building.getName() + " uuid:" + building.getObjectUUID() + "buildinggroup:" + building.getBlueprint().getBuildingGroup().name()); - // check if there is enough gold on the building - return true; + newWarehouseGold -= goldDue; + tol.maintDateTime = LocalDateTime.now().plusDays(7); + if(DbManager.BuildingQueries.updateMaintDate(tol) && DbManager.WarehouseQueries.updateGold(warehouse,newWarehouseGold)) { + warehouse.getResources().put(ItemBase.getItemBase(7), newWarehouseGold); + tol.setStrongboxValue(newStrongboxValue); } - - if (building.getStrongboxValue() >= maintCost) - hasFunds = true; - - // If we cannot cover with just the strongbox - // see if there is a warehouse that will cover - // the overdraft for us. - - - if (hasFunds == false && (building.assetIsProtected() || building.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.WAREHOUSE)) { - overDraft = maintCost - building.getStrongboxValue(); + } + public static void handleR8(Building tol, Warehouse warehouse){ + //handle r8 ToL maintenance + //cannot pay r8 maintenance without a warehouse + if(warehouse == null && DbManager.BuildingQueries.updateMaintDate(tol)) { + tol.destroyOrDerank(null); + tol.maintDateTime = LocalDateTime.now().plusDays(1); + return; } - - if ((overDraft > 0)) - if ((building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.SHRINE) == false) && - (warehouse != null) && building.assetIsProtected() == true && - (warehouse.getResources().get(ItemBase.GOLD_ITEM_BASE)) >= overDraft) { - hasFunds = true; + //handle resource processing + int goldDue = 3000000; + int galvorDue = 5; + int wormwoodDue = 5; + int stoneDue = 5000; + int lumberDue = 5000; + int goldStrongBox = tol.getStrongboxValue(); + int goldWarehouse = 0; + int galvorWarehouse; + int wormwoodWarehouse; + int stoneWarehouse; + int lumberWarehouse; + if(warehouse.getResources().get(Warehouse.galvorIB) != null) { + galvorWarehouse = warehouse.getResources().get(Warehouse.galvorIB); + }else { + tol.maintDateTime = LocalDateTime.now().plusDays(1); + if(DbManager.BuildingQueries.updateMaintDate(tol)) { + tol.destroyOrDerank(null); } - - // If this is an R8 tree, validate that we can - // cover the resources required - - if (building.getRank() == 8) { - - hasResources = true; - - if (warehouse == null) - hasResources = false; - else { - - resourceValue = warehouse.getResources().get(Warehouse.stoneIB); - - if (resourceValue < 1500) - hasResources = false; - - resourceValue = warehouse.getResources().get(Warehouse.lumberIB); - - if (resourceValue < 1500) - hasResources = false; - - resourceValue = warehouse.getResources().get(Warehouse.galvorIB); - - if (resourceValue < 5) - hasResources = false; - - resourceValue = warehouse.getResources().get(Warehouse.wormwoodIB); - - if (resourceValue < 5) - hasResources = false; - + return; + } + if(warehouse.getResources().get(Warehouse.stoneIB) != null) { + stoneWarehouse = warehouse.getResources().get(Warehouse.stoneIB); + }else { + tol.maintDateTime = LocalDateTime.now().plusDays(1); + if(DbManager.BuildingQueries.updateMaintDate(tol)) { + tol.destroyOrDerank(null); } + return; } - // Validation completed but has failed. We can derank - // the target building and early exit - - if ((hasFunds == false) || - ((building.getRank() == 8) && !hasResources)) { - - // Add cash back to strongbox for lost rank if the building isn't being destroyed - // and it's not an R8 deranking - - //if ((building.getRank() > 1) && (building.getRank() < 8)) { - // building.setStrongboxValue(building.getStrongboxValue() + building.getBlueprint().getRankCost(Math.min(building.getRank(), 7))); - //} - - return false; // Early exit for having failed to meet maintenance + if(warehouse.getResources().get(Warehouse.wormwoodIB) != null) { + wormwoodWarehouse = warehouse.getResources().get(Warehouse.wormwoodIB); + }else { + tol.maintDateTime = LocalDateTime.now().plusDays(1); + if(DbManager.BuildingQueries.updateMaintDate(tol)) { + tol.destroyOrDerank(null); + } + return; } - - // Remove cash and resources - - // withdraw what we can from the building - - building.setStrongboxValue(building.getStrongboxValue() - (maintCost - overDraft)); - - // withdraw overdraft from the whorehouse - - if (overDraft > 0) { - - resourceValue = warehouse.getResources().get(Warehouse.goldIB); - - if (DbManager.WarehouseQueries.updateGold(warehouse, resourceValue - overDraft) == true) { - warehouse.getResources().put(Warehouse.goldIB, resourceValue - overDraft); - warehouse.AddTransactionToWarehouse(Enum.GameObjectType.Building, building.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Resource.GOLD, overDraft); - } else { - Logger.error("gold update failed for warehouse of UUID:" + warehouse.getObjectUUID()); - return true; + if(warehouse.getResources().get(Warehouse.lumberIB) != null) { + lumberWarehouse = warehouse.getResources().get(Warehouse.lumberIB); + }else { + tol.maintDateTime = LocalDateTime.now().plusDays(1); + if(DbManager.BuildingQueries.updateMaintDate(tol)) { + tol.destroyOrDerank(null); } + return; } - - // Early exit as we're done if we're not an R8 tree - - if (building.getRank() < 8) - return true; - - // Now for the resources if it's an R8 tree - - // Withdraw Stone - - resourceValue = warehouse.getResources().get(Warehouse.stoneIB); - - if (DbManager.WarehouseQueries.updateStone(warehouse, resourceValue - 1500) == true) { - warehouse.getResources().put(Warehouse.stoneIB, resourceValue - 1500); - warehouse.AddTransactionToWarehouse(Enum.GameObjectType.Building, building.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Resource.STONE, 1500); - } else { - Logger.error("stone update failed for warehouse of UUID:" + warehouse.getObjectUUID()); - return true; + boolean canPay = true; + if(goldStrongBox >= goldDue){ + goldStrongBox -= goldDue; + goldDue = 0; } - - // Withdraw Lumber - - resourceValue = warehouse.getResources().get(Warehouse.lumberIB); - - if (DbManager.WarehouseQueries.updateLumber(warehouse, resourceValue - 1500) == true) { - warehouse.getResources().put(Warehouse.lumberIB, resourceValue - 1500); - warehouse.AddTransactionToWarehouse(Enum.GameObjectType.Building, building.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Resource.LUMBER, 1500); - } else { - Logger.error("lumber update failed for warehouse of UUID:" + warehouse.getObjectUUID()); - return true; + if (tol.getStrongboxValue() > 0) { + goldStrongBox = 0; + goldDue -= tol.getStrongboxValue(); } - - // Withdraw Galvor - - resourceValue = warehouse.getResources().get(Warehouse.galvorIB); - - if (DbManager.WarehouseQueries.updateGalvor(warehouse, resourceValue - 5) == true) { - warehouse.getResources().put(Warehouse.galvorIB, resourceValue - 5); - warehouse.AddTransactionToWarehouse(Enum.GameObjectType.Building, building.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Resource.GALVOR, 5); - } else { - Logger.error("galvor update failed for warehouse of UUID:" + warehouse.getObjectUUID()); - return true; + if(warehouse.getResources().get(Warehouse.goldIB) != null) { + goldWarehouse = warehouse.getResources().get(Warehouse.goldIB); + }else if(goldDue > 0){ + tol.maintDateTime = LocalDateTime.now().plusDays(1); + if(DbManager.BuildingQueries.updateMaintDate(tol)) { + tol.destroyOrDerank(null); + } + return; } - - resourceValue = warehouse.getResources().get(Warehouse.wormwoodIB); - - if (DbManager.WarehouseQueries.updateWormwood(warehouse, resourceValue - 5) == true) { - warehouse.getResources().put(Warehouse.wormwoodIB, resourceValue - 5); - warehouse.AddTransactionToWarehouse(Enum.GameObjectType.Building, building.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Resource.WORMWOOD, 5); - } else { - Logger.error("wyrmwood update failed for warehouse of UUID:" + warehouse.getObjectUUID()); + if(wormwoodDue > wormwoodWarehouse) + canPay = false; + if(galvorDue > galvorWarehouse) + canPay = false; + if(lumberDue > lumberWarehouse) + canPay = false; + if(stoneDue > stoneWarehouse) + canPay = false; + if(goldDue > goldWarehouse) + canPay = false; + if(!canPay){ + tol.maintDateTime = LocalDateTime.now().plusDays(1); + if(DbManager.BuildingQueries.updateMaintDate(tol)) { + tol.destroyOrDerank(null); + } + return; + } + tol.setStrongboxValue(goldStrongBox); + if(DbManager.WarehouseQueries.updateGold(warehouse,goldWarehouse - goldDue)){ + if(DbManager.WarehouseQueries.updateStone(warehouse,stoneWarehouse - stoneDue)){ + if(DbManager.WarehouseQueries.updateLumber(warehouse,lumberWarehouse - lumberDue)){ + if(DbManager.WarehouseQueries.updateGalvor(warehouse,galvorWarehouse - galvorDue)){ + if(DbManager.WarehouseQueries.updateWormwood(warehouse,wormwoodWarehouse - wormwoodDue)){ + tol.maintDateTime = LocalDateTime.now().plusDays(1); + if(DbManager.BuildingQueries.updateMaintDate(tol)) { + return; + } + } + } + } + } } - - return true; - } - - public static void dailyMaintenance() { - - Logger.info("Maintenance has started"); - - // Run maintenance on player buildings - - if (ConfigManager.MB_WORLD_MAINTENANCE.getValue().equalsIgnoreCase("true")) - processBuildingMaintenance(); - else - Logger.info("Maintenance Costings: DISABLED"); - - Logger.info("Maintenance has completed!"); } -} +} \ No newline at end of file From d733afef58f338f96c78937ddf96b12133683ec9 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 5 Jun 2024 18:56:16 -0500 Subject: [PATCH 12/18] drop rates adjusted again --- src/engine/gameManager/LootManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index 796b3526..ef00efec 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -124,12 +124,12 @@ public enum LootManager { case "LOOT": if (ThreadLocalRandom.current().nextInt(1, 100 + 1) < (bse.dropChance * dropRate)) GenerateLootDrop(mob, bse.genTable); //generate normal loot drop - if(mob.contractCounter * dropRate >= 250){ + if(ThreadLocalRandom.current().nextInt(2500) < 10 * dropRate){ MobLoot extraLoot = rollForContract(bse.genTable, mob); if (extraLoot != null) mob.getCharItemManager().addItemToInventory(extraLoot); } - if(mob.runeCounter * dropRate >= 250){ + if(ThreadLocalRandom.current().nextInt(2500) < 10 * dropRate){ MobLoot extraLoot = rollForRune(bse.genTable, mob); if (extraLoot != null) mob.getCharItemManager().addItemToInventory(extraLoot); From 4b1ab35a362154f431d7925b38fcb372cccc0701 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 5 Jun 2024 19:02:28 -0500 Subject: [PATCH 13/18] drop rates adjusted again again --- src/engine/gameManager/LootManager.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index ef00efec..5346995a 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -124,15 +124,19 @@ public enum LootManager { case "LOOT": if (ThreadLocalRandom.current().nextInt(1, 100 + 1) < (bse.dropChance * dropRate)) GenerateLootDrop(mob, bse.genTable); //generate normal loot drop - if(ThreadLocalRandom.current().nextInt(2500) < 10 * dropRate){ + if(!hasExtraRolled && ThreadLocalRandom.current().nextInt(2500) < 10 * dropRate){ MobLoot extraLoot = rollForContract(bse.genTable, mob); - if (extraLoot != null) + if (extraLoot != null) { mob.getCharItemManager().addItemToInventory(extraLoot); + hasExtraRolled = true; + } } - if(ThreadLocalRandom.current().nextInt(2500) < 10 * dropRate){ + if(!hasExtraRolled && ThreadLocalRandom.current().nextInt(2500) < 10 * dropRate){ MobLoot extraLoot = rollForRune(bse.genTable, mob); - if (extraLoot != null) + if (extraLoot != null) { mob.getCharItemManager().addItemToInventory(extraLoot); + hasExtraRolled = true; + } } break; case "ITEM": From 6e26a8cfcf10e1f2b67b916aae6018d457138d96 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 5 Jun 2024 19:20:03 -0500 Subject: [PATCH 14/18] drop rates adjusted again again third time --- src/engine/gameManager/LootManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index 5346995a..b443974a 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -124,14 +124,14 @@ public enum LootManager { case "LOOT": if (ThreadLocalRandom.current().nextInt(1, 100 + 1) < (bse.dropChance * dropRate)) GenerateLootDrop(mob, bse.genTable); //generate normal loot drop - if(!hasExtraRolled && ThreadLocalRandom.current().nextInt(2500) < 10 * dropRate){ + if(!hasExtraRolled && ThreadLocalRandom.current().nextInt(1,5000) < 10 * dropRate){ MobLoot extraLoot = rollForContract(bse.genTable, mob); if (extraLoot != null) { mob.getCharItemManager().addItemToInventory(extraLoot); hasExtraRolled = true; } } - if(!hasExtraRolled && ThreadLocalRandom.current().nextInt(2500) < 10 * dropRate){ + if(!hasExtraRolled && ThreadLocalRandom.current().nextInt(1,5000) < 10 * dropRate){ MobLoot extraLoot = rollForRune(bse.genTable, mob); if (extraLoot != null) { mob.getCharItemManager().addItemToInventory(extraLoot); From 90facabc7b4c6438957bc64036560dac5a7bf56f Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 5 Jun 2024 19:45:59 -0500 Subject: [PATCH 15/18] drop rates adjusted again again third time --- src/engine/gameManager/LootManager.java | 10 +++++----- src/engine/objects/Mob.java | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index b443974a..42fe1deb 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -115,7 +115,6 @@ public enum LootManager { } // Iterate all entries in this bootySet and process accordingly - boolean hasExtraRolled = false; for (BootySetEntry bse : entries) { switch (bse.bootyType) { case "GOLD": @@ -124,18 +123,18 @@ public enum LootManager { case "LOOT": if (ThreadLocalRandom.current().nextInt(1, 100 + 1) < (bse.dropChance * dropRate)) GenerateLootDrop(mob, bse.genTable); //generate normal loot drop - if(!hasExtraRolled && ThreadLocalRandom.current().nextInt(1,5000) < 10 * dropRate){ + if(!mob.hasExtraRolled && ThreadLocalRandom.current().nextInt(1,5000) < 10 * dropRate){ + mob.hasExtraRolled = true; MobLoot extraLoot = rollForContract(bse.genTable, mob); if (extraLoot != null) { mob.getCharItemManager().addItemToInventory(extraLoot); - hasExtraRolled = true; } } - if(!hasExtraRolled && ThreadLocalRandom.current().nextInt(1,5000) < 10 * dropRate){ + if(!mob.hasExtraRolled && ThreadLocalRandom.current().nextInt(1,5000) < 10 * dropRate){ + mob.hasExtraRolled = true; MobLoot extraLoot = rollForRune(bse.genTable, mob); if (extraLoot != null) { mob.getCharItemManager().addItemToInventory(extraLoot); - hasExtraRolled = true; } } break; @@ -191,6 +190,7 @@ public enum LootManager { mob.getCharItemManager().addItemToInventory(specialDrop); mob.setResists(new Resists("Dropper")); } + mob.hasExtraRolled = false; } public static MobLoot getGenTableItem(int genTableID, AbstractCharacter mob) { diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index 0371dff4..aea4a3f6 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -88,6 +88,7 @@ public class Mob extends AbstractIntelligenceAgent { public int contractCounter = 0; public int runeCounter = 0; + public boolean hasExtraRolled = false; // New Mobile constructor. Fill in the blanks and then call // PERSIST. From c32600811269d561a1d648729ea070b536ac2b0c Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Wed, 5 Jun 2024 19:51:14 -0500 Subject: [PATCH 16/18] drop rates adjusted again again third time --- src/engine/gameManager/LootManager.java | 7 ++----- src/engine/objects/Mob.java | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/engine/gameManager/LootManager.java b/src/engine/gameManager/LootManager.java index 42fe1deb..ddb69f8e 100644 --- a/src/engine/gameManager/LootManager.java +++ b/src/engine/gameManager/LootManager.java @@ -123,15 +123,13 @@ public enum LootManager { case "LOOT": if (ThreadLocalRandom.current().nextInt(1, 100 + 1) < (bse.dropChance * dropRate)) GenerateLootDrop(mob, bse.genTable); //generate normal loot drop - if(!mob.hasExtraRolled && ThreadLocalRandom.current().nextInt(1,5000) < 10 * dropRate){ - mob.hasExtraRolled = true; + if(ThreadLocalRandom.current().nextInt(1,250) == 100){ MobLoot extraLoot = rollForContract(bse.genTable, mob); if (extraLoot != null) { mob.getCharItemManager().addItemToInventory(extraLoot); } } - if(!mob.hasExtraRolled && ThreadLocalRandom.current().nextInt(1,5000) < 10 * dropRate){ - mob.hasExtraRolled = true; + if(ThreadLocalRandom.current().nextInt(1,250) == 100){ MobLoot extraLoot = rollForRune(bse.genTable, mob); if (extraLoot != null) { mob.getCharItemManager().addItemToInventory(extraLoot); @@ -190,7 +188,6 @@ public enum LootManager { mob.getCharItemManager().addItemToInventory(specialDrop); mob.setResists(new Resists("Dropper")); } - mob.hasExtraRolled = false; } public static MobLoot getGenTableItem(int genTableID, AbstractCharacter mob) { diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index aea4a3f6..0371dff4 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -88,7 +88,6 @@ public class Mob extends AbstractIntelligenceAgent { public int contractCounter = 0; public int runeCounter = 0; - public boolean hasExtraRolled = false; // New Mobile constructor. Fill in the blanks and then call // PERSIST. From c14cc98ca204677049f3bfe8b001aaa6bee27e98 Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 8 Jun 2024 18:58:46 -0500 Subject: [PATCH 17/18] mines reset claimability at 3am CST --- src/engine/workthreads/HourlyJobThread.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/engine/workthreads/HourlyJobThread.java b/src/engine/workthreads/HourlyJobThread.java index 866c1000..22930324 100644 --- a/src/engine/workthreads/HourlyJobThread.java +++ b/src/engine/workthreads/HourlyJobThread.java @@ -94,12 +94,11 @@ public class HourlyJobThread implements Runnable { // This will reset at 1am after the last mine // window closes. - if (LocalDateTime.now().getHour() == MINE_LATE_WINDOW + 1) { + if (LocalDateTime.now().getHour() == 3) { for (Mine mine : Mine.getMines()) { - - if (mine.wasClaimed == true) - mine.wasClaimed = false; + mine.wasClaimed = false; + mine.hasProduced = false; } } From 3c23a070dfb981f794268d1b0cff0a9e08b622ab Mon Sep 17 00:00:00 2001 From: FatBoy-DOTC Date: Sat, 8 Jun 2024 19:03:11 -0500 Subject: [PATCH 18/18] glass repairable for 3x base repair costs --- src/engine/net/client/ClientMessagePump.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/engine/net/client/ClientMessagePump.java b/src/engine/net/client/ClientMessagePump.java index a7864bcb..1f7659bf 100644 --- a/src/engine/net/client/ClientMessagePump.java +++ b/src/engine/net/client/ClientMessagePump.java @@ -1660,8 +1660,8 @@ public class ClientMessagePump implements NetMsgHandler { if (toRepair == null) return; - if (toRepair.getItemBase().isGlass()) - return; + //if (toRepair.getItemBase().isGlass()) + // return; //make sure item is in player's inventory or equipment if (!itemMan.inventoryContains(toRepair) && !itemMan.equippedContains(toRepair)) @@ -1683,6 +1683,12 @@ public class ClientMessagePump implements NetMsgHandler { } //TODO get cost to repair int cost = (int) ((max - dur) * 80.1); + + //glass costs 3x as much to repair + if (toRepair.getItemBase().isGlass()){ + cost *= 3; + } + Building b = (!npc.isStatic()) ? npc.getBuilding() : null; if (b != null)