diff --git a/src/main/java/emu/grasscutter/game/combine/CombineManger.java b/src/main/java/emu/grasscutter/game/combine/CombineManger.java index 20b2e9a4b..295efeb88 100644 --- a/src/main/java/emu/grasscutter/game/combine/CombineManger.java +++ b/src/main/java/emu/grasscutter/game/combine/CombineManger.java @@ -81,7 +81,7 @@ public class CombineManger extends BaseGameSystem { List material = new ArrayList<>(combineData.getMaterialItems()); material.add(new ItemParamData(202, combineData.getScoinCost())); - boolean success = player.getInventory().payItems(material.toArray(new ItemParamData[0]), count, ActionReason.Combine); + boolean success = player.getInventory().payItems(material, count, ActionReason.Combine); // abort if not enough material if (!success) { diff --git a/src/main/java/emu/grasscutter/game/inventory/Inventory.java b/src/main/java/emu/grasscutter/game/inventory/Inventory.java index 23a833edb..7a7c7fc19 100644 --- a/src/main/java/emu/grasscutter/game/inventory/Inventory.java +++ b/src/main/java/emu/grasscutter/game/inventory/Inventory.java @@ -293,6 +293,29 @@ public class Inventory extends BasePlayerManager implements Iterable { } } + private GameItem payVirtualItem(int itemId, int count) { + switch (itemId) { + case 201 -> // Primogem + player.setPrimogems(player.getPrimogems() - count); + case 202 -> // Mora + player.setMora(player.getMora() - count); + case 203 -> // Genesis Crystals + player.setCrystals(player.getCrystals() - count); + case 106 -> // Resin + player.getResinManager().useResin(count); + case 107 -> // LegendaryKey + player.useLegendaryKey(count); + case 204 -> // Home Coin + player.setHomeCoin(player.getHomeCoin() - count); + default -> { + var gameItem = getInventoryTab(ItemType.ITEM_MATERIAL).getItemById(itemId); + removeItem(gameItem, count); + return gameItem; + } + } + return null; + } + private int getVirtualItemCount(int itemId) { switch (itemId) { case 201: // Primogem @@ -313,47 +336,33 @@ public class Inventory extends BasePlayerManager implements Iterable { } } - public boolean payItem(int id, int count) { - return payItem(new ItemParamData(id, count)); + public synchronized boolean payItem(int id, int count) { + if (this.getVirtualItemCount(id) < count) + return false; + this.payVirtualItem(id, count); + return true; } public boolean payItem(ItemParamData costItem) { - return payItems(new ItemParamData[] {costItem}, 1, null); + return this.payItem(costItem.getId(), costItem.getCount()); } public boolean payItems(ItemParamData[] costItems) { - return payItems(costItems, 1, null); + return this.payItems(costItems, 1, null); } public boolean payItems(ItemParamData[] costItems, int quantity) { - return payItems(costItems, quantity, null); + return this.payItems(costItems, quantity, null); } public synchronized boolean payItems(ItemParamData[] costItems, int quantity, ActionReason reason) { // Make sure player has requisite items - for (ItemParamData cost : costItems) { - if (getVirtualItemCount(cost.getId()) < (cost.getCount() * quantity)) { + for (ItemParamData cost : costItems) + if (this.getVirtualItemCount(cost.getId()) < (cost.getCount() * quantity)) return false; - } - } // All costs are satisfied, now remove them all for (ItemParamData cost : costItems) { - switch (cost.getId()) { - case 201 -> // Primogem - player.setPrimogems(player.getPrimogems() - (cost.getCount() * quantity)); - case 202 -> // Mora - player.setMora(player.getMora() - (cost.getCount() * quantity)); - case 203 -> // Genesis Crystals - player.setCrystals(player.getCrystals() - (cost.getCount() * quantity)); - case 106 -> // Resin - player.getResinManager().useResin(cost.getCount() * quantity); - case 107 -> // LegendaryKey - player.useLegendaryKey(cost.getCount() * quantity); - case 204 -> // Home Coin - player.setHomeCoin(player.getHomeCoin() - (cost.getCount() * quantity)); - default -> - removeItem(getInventoryTab(ItemType.ITEM_MATERIAL).getItemById(cost.getId()), cost.getCount() * quantity); - } + this.payVirtualItem(cost.getId(), cost.getCount() * quantity); } if (reason != null) { // Do we need these? @@ -363,6 +372,24 @@ public class Inventory extends BasePlayerManager implements Iterable { return true; } + public boolean payItems(Iterable costItems) { + return this.payItems(costItems, 1, null); + } + + public boolean payItems(Iterable costItems, int quantity) { + return this.payItems(costItems, quantity, null); + } + + public synchronized boolean payItems(Iterable costItems, int quantity, ActionReason reason) { + // Make sure player has requisite items + for (ItemParamData cost : costItems) + if (getVirtualItemCount(cost.getId()) < (cost.getCount() * quantity)) + return false; + // All costs are satisfied, now remove them all + costItems.forEach(cost -> this.payVirtualItem(cost.getId(), cost.getCount() * quantity)); + return true; + } + public void removeItems(List items) { // TODO Bulk delete for (GameItem item : items) { diff --git a/src/main/java/emu/grasscutter/game/managers/CookingManager.java b/src/main/java/emu/grasscutter/game/managers/CookingManager.java index f6abcd193..0aba25a8c 100644 --- a/src/main/java/emu/grasscutter/game/managers/CookingManager.java +++ b/src/main/java/emu/grasscutter/game/managers/CookingManager.java @@ -97,7 +97,7 @@ public class CookingManager extends BasePlayerManager { int proficiency = this.player.getUnlockedRecipies().getOrDefault(recipeId, 0); // Try consuming materials. - boolean success = player.getInventory().payItems(recipeData.getInputVec().toArray(new ItemParamData[0]), count, ActionReason.Cook); + boolean success = player.getInventory().payItems(recipeData.getInputVec(), count, ActionReason.Cook); if (!success) { this.player.sendPacket(new PacketPlayerCookRsp(Retcode.RET_FAIL)); } diff --git a/src/main/java/emu/grasscutter/game/managers/FurnitureManager.java b/src/main/java/emu/grasscutter/game/managers/FurnitureManager.java index ce83e0289..f2078f55e 100644 --- a/src/main/java/emu/grasscutter/game/managers/FurnitureManager.java +++ b/src/main/java/emu/grasscutter/game/managers/FurnitureManager.java @@ -71,7 +71,7 @@ public class FurnitureManager extends BasePlayerManager { } // pay items first - if (!player.getInventory().payItems(makeData.getMaterialItems().toArray(new ItemParamData[0]))) { + if (!player.getInventory().payItems(makeData.getMaterialItems())) { player.getSession().send(new PacketFurnitureMakeStartRsp(Retcode.RET_HOME_FURNITURE_COUNT_NOT_ENOUGH_VALUE, null)); return; } diff --git a/src/main/java/emu/grasscutter/game/managers/forging/ForgingManager.java b/src/main/java/emu/grasscutter/game/managers/forging/ForgingManager.java index f597a1b2a..9fd8f82a5 100644 --- a/src/main/java/emu/grasscutter/game/managers/forging/ForgingManager.java +++ b/src/main/java/emu/grasscutter/game/managers/forging/ForgingManager.java @@ -157,7 +157,7 @@ public class ForgingManager extends BasePlayerManager { List material = new ArrayList<>(forgeData.getMaterialItems()); material.add(new ItemParamData(202, forgeData.getScoinCost())); - boolean success = player.getInventory().payItems(material.toArray(new ItemParamData[0]), req.getForgeCount(), ActionReason.ForgeCost); + boolean success = player.getInventory().payItems(material, req.getForgeCount(), ActionReason.ForgeCost); if (!success) { this.player.sendPacket(new PacketForgeStartRsp(Retcode.RET_FORGE_POINT_NOT_ENOUGH)); //ToDo: Probably the wrong return code. diff --git a/src/main/java/emu/grasscutter/game/systems/InventorySystem.java b/src/main/java/emu/grasscutter/game/systems/InventorySystem.java index fbea95715..b5e377a42 100644 --- a/src/main/java/emu/grasscutter/game/systems/InventorySystem.java +++ b/src/main/java/emu/grasscutter/game/systems/InventorySystem.java @@ -122,7 +122,7 @@ public class InventorySystem extends BaseGameSystem { // Confirm payment of materials and mora (assume food relics are payable afterwards) payList.add(new ItemParamData(202, moraCost)); - if (!player.getInventory().payItems(payList.toArray(new ItemParamData[0]))) { + if (!player.getInventory().payItems(payList)) { return; } @@ -297,7 +297,7 @@ public class InventorySystem extends BaseGameSystem { // Confirm payment of materials and mora (assume food weapons are payable afterwards) payList.add(new ItemParamData(202, moraCost)); - if (!player.getInventory().payItems(payList.toArray(new ItemParamData[0]))) { + if (!player.getInventory().payItems(payList)) { return; } player.getInventory().removeItems(foodWeapons); @@ -692,7 +692,7 @@ public class InventorySystem extends BaseGameSystem { if (proudSkill.getCoinCost() > 0) { costs.add(new ItemParamData(202, proudSkill.getCoinCost())); } - if (!player.getInventory().payItems(costs.toArray(new ItemParamData[0]))) { + if (!player.getInventory().payItems(costs)) { return; } diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerBuyGoodsReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerBuyGoodsReq.java index 2b645cc11..e76fc49b8 100644 --- a/src/main/java/emu/grasscutter/server/packet/recv/HandlerBuyGoodsReq.java +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerBuyGoodsReq.java @@ -61,7 +61,7 @@ public class HandlerBuyGoodsReq extends PacketHandler { costs.add(new ItemParamData(202, sg.getScoin())); costs.add(new ItemParamData(201, sg.getHcoin())); costs.add(new ItemParamData(203, sg.getMcoin())); - if (!session.getPlayer().getInventory().payItems(costs.toArray(new ItemParamData[0]), buyGoodsReq.getBuyCount())) { + if (!session.getPlayer().getInventory().payItems(costs, buyGoodsReq.getBuyCount())) { return; }