diff --git a/src/engine/gameManager/MaintenanceManager.java b/src/engine/gameManager/MaintenanceManager.java index c657b124..fcd76dee 100644 --- a/src/engine/gameManager/MaintenanceManager.java +++ b/src/engine/gameManager/MaintenanceManager.java @@ -17,6 +17,8 @@ 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 { @@ -29,303 +31,113 @@ public enum MaintenanceManager { } - 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 + public static void dailyMaintenance() { - for (Building building : maintList) { - if(derankList.contains(building) == false) - setMaintDateTime(building, LocalDateTime.now().plusDays(7)); - else - setMaintDateTime(building, LocalDateTime.now().plusDays(1)); + Logger.info("Maintenance has started"); - } - // Derak or destroy buildings that did not - // have funds available. + // Run maintenance on player buildings - for (Building building : derankList) - building.destroyOrDerank(null); + if (ConfigManager.MB_WORLD_MAINTENANCE.getValue().equalsIgnoreCase("true")) + processMaintenance(); + else + Logger.info("Maintenance Costings: DISABLED"); - Logger.info("Structures: " + buildingList.size() + " Maint: " + maintList.size() + " Derank: " + derankList.size()); + Logger.info("Maintenance has completed!"); } - // 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; + public static void processMaintenance() { - // No maintenance on NPC owned buildings (Cache loaded) + //create list of all cities + ConcurrentHashMap worldCities = DbManager.getMap(Enum.GameObjectType.City); - if (building.getProtectionState() == Enum.ProtectionState.NPC) - continue; + //loop all cities + for (AbstractGameObject ago : worldCities.values()) { + if (ago.getObjectType().equals(Enum.GameObjectType.City)) { + City city = (City) ago; + if(city == null) + continue; - // No maintenance on constructing meshes + Building tol = city.getTOL(); + if(tol == null) + continue; - 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; + if(tol.maintDateTime.toLocalDate().equals(LocalDateTime.now().toLocalDate())){ + // today is maintenance day + processTolMaintenance(tol, city.getWarehouse()); + } } - - // 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; - } - - // 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; - } - // Add building to maintenance queue - - maintList.add(building); } - - 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; - } - - 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(); - } - - 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; + public static void processTolMaintenance(Building tol, Warehouse warehouse){ + //create the required resource maintenance list + HashMap maintCosts = new HashMap<>(); + maintCosts.put(7,3000000); + if(tol.getRank() == 8){ + maintCosts.put(1580000,3000);//stone + maintCosts.put(1580004,3000);//lumber + maintCosts.put(1580017,5);//galvor + maintCosts.put(1580018,5);//wormwood + }else { + //not r8, only need to process gold value and we're done + int maintenanceDue = maintCosts.get(7); + int strongboxGold = tol.getStrongboxValue(); + if (strongboxGold > 0) { + if (strongboxGold > maintenanceDue) { + //enough gold in strongbox to cover all of maintenance + maintenanceDue = 0; + strongboxGold -= maintenanceDue; + tol.setStrongboxValue(strongboxGold); //update strongbox value + setMaintDateTime(tol, tol.maintDateTime.plusDays(7)); //maintenance paid, set next maintenance date for 1 week from today + return; //maintenance is paid, all done + } else { + maintenanceDue -= strongboxGold; + strongboxGold = 0; + } } - - // 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; - + //now we need to take the remaining maintenance from the warehouse + int warehouseGold = 0; + if (warehouse != null) { + warehouseGold = warehouse.getResources().get(ItemBase.getItemBase(7)); } - } - // 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 - } - - // 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); + if (warehouseGold >= maintenanceDue) { + //we have enough gold to process maintenance + tol.setStrongboxValue(strongboxGold); //update the strongbox now that we are sure maintenance is being paid + warehouseGold -= maintenanceDue; + warehouse.getResources().put(ItemBase.getItemBase(7),warehouseGold); + DbManager.WarehouseQueries.updateGold(warehouse, warehouseGold); + setMaintDateTime(tol, tol.maintDateTime.plusDays(7)); //maintenance paid, set next maintenance date for 1 week from today + //maintenance is paid, all done } else { - Logger.error("gold update failed for warehouse of UUID:" + warehouse.getObjectUUID()); - return true; + //failed maintenance, derank asset + HandleMaintenanceDerank(tol); //handle derank or potential destruction of the city } + 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; - } - - // 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; - } - - // 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; + //handle r8 ToL maintenance here after the fact + HashMap updatedValues = new HashMap<>(); + Boolean success = true; + for(Integer ibId : maintCosts.keySet()){ + if (warehouse != null) { + int resourceCount = warehouse.getResources().get(ItemBase.getItemBase(ibId)); + if(resourceCount < maintCosts.get(ibId)) + success = false; + }else{ + success = false; + } } + if(success = true){ + //determined there is enough of each resourceType to withdraw maintenance - 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()); + }else{ + HandleMaintenanceDerank(tol);//handle derank or potential destruction of the city } - return true; } - public static void dailyMaintenance() { + public static void HandleMaintenanceDerank(Building tol){ + setMaintDateTime(tol, tol.maintDateTime.plusDays(1)); //failed to pay maintenance, set next date for tomorrow - 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!"); } }