From e15d91bfd8b06fcd5decb00b7974275ea5dc687a Mon Sep 17 00:00:00 2001 From: Melledy <121644117+Melledy@users.noreply.github.com> Date: Wed, 8 Nov 2023 16:20:24 -0800 Subject: [PATCH] Implement return items when leveling up avatars/relics/light cones --- .../java/emu/lunarcore/data/GameDepot.java | 5 + .../data/excel/AvatarExpItemExcel.java | 16 +++ .../data/excel/EquipmentExpItemExcel.java | 16 +++ .../data/excel/RelicExpItemExcel.java | 16 +++ .../game/inventory/InventoryService.java | 109 ++++++++++++++---- 5 files changed, 139 insertions(+), 23 deletions(-) diff --git a/src/main/java/emu/lunarcore/data/GameDepot.java b/src/main/java/emu/lunarcore/data/GameDepot.java index b0a3dc5..50c3c38 100644 --- a/src/main/java/emu/lunarcore/data/GameDepot.java +++ b/src/main/java/emu/lunarcore/data/GameDepot.java @@ -12,6 +12,11 @@ import lombok.Getter; // Game data that is parsed by the server goes here public class GameDepot { + // Exp + @Getter private static List avatarExpExcels = new ArrayList<>(); + @Getter private static List equipmentExpExcels = new ArrayList<>(); + @Getter private static List relicExpExcels = new ArrayList<>(); + // Relics private static Int2ObjectMap> relicMainAffixDepot = new Int2ObjectOpenHashMap<>(); private static Int2ObjectMap> relicSubAffixDepot = new Int2ObjectOpenHashMap<>(); diff --git a/src/main/java/emu/lunarcore/data/excel/AvatarExpItemExcel.java b/src/main/java/emu/lunarcore/data/excel/AvatarExpItemExcel.java index 0a5653e..ae8d9ff 100644 --- a/src/main/java/emu/lunarcore/data/excel/AvatarExpItemExcel.java +++ b/src/main/java/emu/lunarcore/data/excel/AvatarExpItemExcel.java @@ -1,9 +1,13 @@ package emu.lunarcore.data.excel; +import java.util.Comparator; + import emu.lunarcore.data.GameData; +import emu.lunarcore.data.GameDepot; import emu.lunarcore.data.GameResource; import emu.lunarcore.data.ResourceType; import emu.lunarcore.data.ResourceType.LoadPriority; + import lombok.Getter; @Getter @@ -19,9 +23,21 @@ public class AvatarExpItemExcel extends GameResource { @Override public void onLoad() { + // Set exp for this item ItemExcel excel = GameData.getItemExcelMap().get(ItemID); if (excel == null) return; excel.setAvatarExp(Exp); + + // Add to game depot + if (Exp > 0) { + GameDepot.getAvatarExpExcels().add(this); + GameDepot.getAvatarExpExcels().sort(new Comparator() { + @Override + public int compare(AvatarExpItemExcel o1, AvatarExpItemExcel o2) { + return o2.getExp() - o1.getExp(); + } + }); + } } } diff --git a/src/main/java/emu/lunarcore/data/excel/EquipmentExpItemExcel.java b/src/main/java/emu/lunarcore/data/excel/EquipmentExpItemExcel.java index 1066f94..7cadd6b 100644 --- a/src/main/java/emu/lunarcore/data/excel/EquipmentExpItemExcel.java +++ b/src/main/java/emu/lunarcore/data/excel/EquipmentExpItemExcel.java @@ -1,9 +1,13 @@ package emu.lunarcore.data.excel; +import java.util.Comparator; + import emu.lunarcore.data.GameData; +import emu.lunarcore.data.GameDepot; import emu.lunarcore.data.GameResource; import emu.lunarcore.data.ResourceType; import emu.lunarcore.data.ResourceType.LoadPriority; +import emu.lunarcore.game.inventory.ItemRarity; import lombok.Getter; @Getter @@ -20,10 +24,22 @@ public class EquipmentExpItemExcel extends GameResource { @Override public void onLoad() { + // Set exp for this item ItemExcel excel = GameData.getItemExcelMap().get(ItemID); if (excel == null) return; excel.setEquipmentExp(ExpProvide); excel.setExpCost(CoinCost); + + // Add to game depot + if (ExpProvide > 0) { + GameDepot.getEquipmentExpExcels().add(this); + GameDepot.getEquipmentExpExcels().sort(new Comparator() { + @Override + public int compare(EquipmentExpItemExcel o1, EquipmentExpItemExcel o2) { + return o2.getExpProvide() - o1.getExpProvide(); + } + }); + } } } diff --git a/src/main/java/emu/lunarcore/data/excel/RelicExpItemExcel.java b/src/main/java/emu/lunarcore/data/excel/RelicExpItemExcel.java index ba3d297..21498dc 100644 --- a/src/main/java/emu/lunarcore/data/excel/RelicExpItemExcel.java +++ b/src/main/java/emu/lunarcore/data/excel/RelicExpItemExcel.java @@ -1,9 +1,13 @@ package emu.lunarcore.data.excel; +import java.util.Comparator; + import emu.lunarcore.data.GameData; +import emu.lunarcore.data.GameDepot; import emu.lunarcore.data.GameResource; import emu.lunarcore.data.ResourceType; import emu.lunarcore.data.ResourceType.LoadPriority; +import emu.lunarcore.game.inventory.ItemRarity; import lombok.Getter; @Getter @@ -20,10 +24,22 @@ public class RelicExpItemExcel extends GameResource { @Override public void onLoad() { + // Set exp for this item ItemExcel excel = GameData.getItemExcelMap().get(ItemID); if (excel == null) return; excel.setRelicExp(ExpProvide); excel.setExpCost(CoinCost); + + // Add to game depot + if (ExpProvide > 0 && excel.getRarity() != ItemRarity.SuperRare) { + GameDepot.getRelicExpExcels().add(this); + GameDepot.getRelicExpExcels().sort(new Comparator() { + @Override + public int compare(RelicExpItemExcel o1, RelicExpItemExcel o2) { + return o2.getExpProvide() - o1.getExpProvide(); + } + }); + } } } diff --git a/src/main/java/emu/lunarcore/game/inventory/InventoryService.java b/src/main/java/emu/lunarcore/game/inventory/InventoryService.java index 0897a23..c9415ab 100644 --- a/src/main/java/emu/lunarcore/game/inventory/InventoryService.java +++ b/src/main/java/emu/lunarcore/game/inventory/InventoryService.java @@ -5,6 +5,7 @@ import java.util.Collection; import java.util.List; import emu.lunarcore.data.GameData; +import emu.lunarcore.data.GameDepot; import emu.lunarcore.data.common.ItemParam; import emu.lunarcore.data.excel.*; import emu.lunarcore.data.excel.ItemComposeExcel.FormulaType; @@ -15,6 +16,8 @@ import emu.lunarcore.server.game.GameServer; import emu.lunarcore.server.packet.BasePacket; import emu.lunarcore.server.packet.CmdId; import emu.lunarcore.server.packet.send.*; + +import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; public class InventoryService extends BaseGameService { @@ -34,18 +37,18 @@ public class InventoryService extends BaseGameService { if (promoteData == null) return; // Exp gain - int expGain = 0; + int amount = 0; // Verify items for (ItemParam param : items) { GameItem item = player.getInventory().getItemByParam(param); if (item == null || item.getExcel().getAvatarExp() == 0 || item.getCount() < param.getCount()) return; - expGain += item.getExcel().getAvatarExp() * param.getCount(); + amount += item.getExcel().getAvatarExp() * param.getCount(); } // Verify credits - int cost = expGain / 10; + int cost = amount / 10; if (player.getScoin() < cost) { player.sendPacket(new PacketAvatarExpUpScRsp()); return; @@ -61,11 +64,11 @@ public class InventoryService extends BaseGameService { int exp = avatar.getExp(); int reqExp = GameData.getAvatarExpRequired(avatar.getExcel().getExpGroup(), level); - while (expGain > 0 && reqExp > 0 && level < maxLevel) { + while (amount > 0 && reqExp > 0 && level < maxLevel) { // Do calculations - int toGain = Math.min(expGain, reqExp - exp); + int toGain = Math.min(amount, reqExp - exp); exp += toGain; - expGain -= toGain; + amount -= toGain; // Level up if (exp >= reqExp) { // Exp @@ -83,8 +86,28 @@ public class InventoryService extends BaseGameService { avatar.save(); player.save(); - // TODO add back leftover exp - List returnItems = new ArrayList<>(); + // Calculate leftover exp + Int2IntMap leftoverItems = new Int2IntOpenHashMap(); + + while (GameDepot.getAvatarExpExcels().size() > 0) { + int oldAmount = amount; + for (var expExcel : GameDepot.getAvatarExpExcels()) { + if (amount >= expExcel.getExp()) { + leftoverItems.put(expExcel.getItemID(), leftoverItems.get(expExcel.getItemID()) + 1); + amount -= expExcel.getExp(); + break; + } + } + if (oldAmount == amount) break; + } + + // Create leftover exp items + List returnItems = leftoverItems.int2IntEntrySet() + .stream() + .map(e -> new GameItem(e.getIntKey(), e.getIntValue())) + .toList(); + + player.getInventory().addItems(returnItems); // Send packets player.sendPacket(new PacketPlayerSyncScNotify(avatar)); @@ -246,7 +269,7 @@ public class InventoryService extends BaseGameService { // Exp gain int cost = 0; - int expGain = 0; + int amount = 0; // Verify items for (ItemParam param : items) { @@ -258,7 +281,7 @@ public class InventoryService extends BaseGameService { } if (item.getExcel().getEquipmentExp() > 0) { - expGain += item.getExcel().getEquipmentExp() * param.getCount(); + amount += item.getExcel().getEquipmentExp() * param.getCount(); cost += item.getExcel().getEquipmentExpCost() * param.getCount(); } } @@ -279,11 +302,11 @@ public class InventoryService extends BaseGameService { int exp = equip.getExp(); int reqExp = GameData.getEquipmentExpRequired(equip.getExcel().getEquipmentExcel().getExpType(), level); - while (expGain > 0 && reqExp > 0 && level < maxLevel) { + while (amount > 0 && reqExp > 0 && level < maxLevel) { // Do calculations - int toGain = Math.min(expGain, reqExp - exp); + int toGain = Math.min(amount, reqExp - exp); exp += toGain; - expGain -= toGain; + amount -= toGain; // Level up if (exp >= reqExp) { // Exp @@ -301,8 +324,28 @@ public class InventoryService extends BaseGameService { equip.save(); player.save(); - // TODO add back leftover exp - List returnItems = new ArrayList<>(); + // Calculate leftover exp + Int2IntMap leftoverItems = new Int2IntOpenHashMap(); + + while (GameDepot.getEquipmentExpExcels().size() > 0) { + int oldAmount = amount; + for (var expExcel : GameDepot.getEquipmentExpExcels()) { + if (amount >= expExcel.getExpProvide()) { + leftoverItems.put(expExcel.getItemID(), leftoverItems.get(expExcel.getItemID()) + 1); + amount -= expExcel.getExpProvide(); + break; + } + } + if (oldAmount == amount) break; + } + + // Create leftover exp items + List returnItems = leftoverItems.int2IntEntrySet() + .stream() + .map(e -> new GameItem(e.getIntKey(), e.getIntValue())) + .toList(); + + player.getInventory().addItems(returnItems); // Send packets player.sendPacket(new PacketPlayerSyncScNotify(equip)); @@ -398,7 +441,7 @@ public class InventoryService extends BaseGameService { // Exp gain int cost = 0; - int expGain = 0; + int amount = 0; // Verify items for (ItemParam param : items) { @@ -409,12 +452,12 @@ public class InventoryService extends BaseGameService { } if (item.getExcel().getRelicExp() > 0) { - expGain += item.getExcel().getRelicExp() * param.getCount(); + amount += item.getExcel().getRelicExp() * param.getCount(); cost += item.getExcel().getRelicExpCost() * param.getCount(); } if (item.getTotalExp() > 0) { - expGain += (int) Math.floor(item.getTotalExp() * 0.80D); + amount += (int) Math.floor(item.getTotalExp() * 0.80D); } } @@ -436,12 +479,12 @@ public class InventoryService extends BaseGameService { int upgrades = 0; int reqExp = GameData.getRelicExpRequired(equip.getExcel().getRelicExcel().getExpType(), level); - while (expGain > 0 && reqExp > 0 && level < maxLevel) { + while (amount > 0 && reqExp > 0 && level < maxLevel) { // Do calculations - int toGain = Math.min(expGain, reqExp - exp); + int toGain = Math.min(amount, reqExp - exp); exp += toGain; totalExp += toGain; - expGain -= toGain; + amount -= toGain; // Level up if (exp >= reqExp) { // Exp @@ -469,8 +512,28 @@ public class InventoryService extends BaseGameService { equip.save(); player.save(); - // TODO add back leftover exp - List returnItems = new ArrayList<>(); + // Calculate leftover exp + Int2IntMap leftoverItems = new Int2IntOpenHashMap(); + + while (GameDepot.getRelicExpExcels().size() > 0) { + int oldAmount = amount; + for (var expExcel : GameDepot.getRelicExpExcels()) { + if (amount >= expExcel.getExpProvide()) { + leftoverItems.put(expExcel.getItemID(), leftoverItems.get(expExcel.getItemID()) + 1); + amount -= expExcel.getExpProvide(); + break; + } + } + if (oldAmount == amount) break; + } + + // Create leftover exp items + List returnItems = leftoverItems.int2IntEntrySet() + .stream() + .map(e -> new GameItem(e.getIntKey(), e.getIntValue())) + .toList(); + + player.getInventory().addItems(returnItems); // Send packets player.sendPacket(new PacketPlayerSyncScNotify(equip));