From d6f938160721f468b728f0dc9f087b68083d2da2 Mon Sep 17 00:00:00 2001 From: Kyle873 Date: Sun, 22 Dec 2024 04:22:45 -0500 Subject: [PATCH] handle more edge cases in equip leveling as well as using boost modules --- .../Inventory/IncreaseEquipmentExp.cs | 91 ++++++++++++++++--- EpinelPS/Utils/MathUtils.cs | 15 +++ 2 files changed, 93 insertions(+), 13 deletions(-) create mode 100644 EpinelPS/Utils/MathUtils.cs diff --git a/EpinelPS/LobbyServer/Inventory/IncreaseEquipmentExp.cs b/EpinelPS/LobbyServer/Inventory/IncreaseEquipmentExp.cs index 0591d1d..4a4e74c 100644 --- a/EpinelPS/LobbyServer/Inventory/IncreaseEquipmentExp.cs +++ b/EpinelPS/LobbyServer/Inventory/IncreaseEquipmentExp.cs @@ -7,6 +7,13 @@ namespace EpinelPS.LobbyServer.Inventory [PacketPath("/inventory/increaseexpequipment")] public class IncreaseEquipmentExp : LobbyMsgHandler { + readonly Dictionary boostExpTable = new Dictionary + { + { 7010001, 100 }, + { 7010002, 1000 }, + { 7010003, 8000 } + }; + protected override async Task HandleAsync() { var req = await ReadData(); @@ -14,15 +21,16 @@ namespace EpinelPS.LobbyServer.Inventory var response = new ResIncreaseExpEquip(); var destItem = user.Items.FirstOrDefault(x => x.Isn == req.Isn); int goldCost = 0; + int modules = 0; foreach (var srcItem in req.ItemList) { var item = user.Items.FirstOrDefault(x => x.Isn == srcItem.Isn); item.Count -= srcItem.Count; - goldCost += AddExp(srcItem, destItem).exp; - - // TODO: boost modules. for now, excess exp gets scrapped + (int addedExp, int addedModules) = AddExp(srcItem, destItem); + goldCost += addedExp; + modules += addedModules; response.Items.Add(NetUtils.ToNet(item)); } @@ -30,9 +38,25 @@ namespace EpinelPS.LobbyServer.Inventory response.Currency = new NetUserCurrencyData { Type = (int)CurrencyType.Gold, - Value = user.GetCurrencyVal(CurrencyType.Gold) - goldCost + Value = user.GetCurrencyVal(CurrencyType.Gold) - MathUtils.Clamp(goldCost, 0, CalcTotalExp(destItem)) }; + // TODO + if (modules > 0) + { + (int t1, int t2, int t3) = CalcModules(modules); + + if (t1 > 0) + { + } + if (t2 > 0) + { + } + if (t3 > 0) + { + } + } + // we NEED to make sure the target item itself is in the delta list, or the UI won't update! response.Items.Add(NetUtils.ToNet(destItem)); @@ -43,24 +67,43 @@ namespace EpinelPS.LobbyServer.Inventory (int exp, int modules) AddExp(NetItemData srcItem, ItemData destItem) { + int[] maxLevel = { 0, 0, 3, 3, 4, 4, 5, 5, 5, 5 }; var srcEquipRecord = GameData.Instance.itemEquipTable.Values.FirstOrDefault(x => x.id == srcItem.Tid); var destEquipRecord = GameData.Instance.itemEquipTable.Values.FirstOrDefault(x => x.id == destItem.ItemType); - var levelRecord = GameData.Instance.ItemEquipGradeExpTable.Values.FirstOrDefault(x => x.grade_core_id == srcEquipRecord.grade_core_id); - int[] maxLevel = { 0, 0, 3, 3, 4, 4, 5, 5, 5, 5 }; int[] expNextTable = GameData.Instance.itemEquipExpTable.Values - .Where(x => x.item_rare == destEquipRecord.item_rare) - .Select(x => x.exp) - .OrderBy(x => x) // order from lowest to highest - .ToArray(); - int exp = levelRecord.exp * srcItem.Count; + .Where(x => x.item_rare == destEquipRecord.item_rare) + .Select(x => x.exp) + .OrderBy(x => x) // order from lowest to highest + .ToArray(); + int exp = 0; int modules = 0; - destItem.Exp += exp * srcItem.Count; + if (srcEquipRecord != null) + { + var levelRecord = GameData.Instance.ItemEquipGradeExpTable.Values.FirstOrDefault(x => x.grade_core_id == srcEquipRecord.grade_core_id); + + exp = srcItem.Count * levelRecord.exp; + + destItem.Exp += exp; + } + else // if the record is null, boost modules are being used + { + foreach (var entry in boostExpTable) + { + if (entry.Key == srcItem.Tid) + { + exp = srcItem.Count * entry.Value; + break; + } + } + + destItem.Exp += exp; + } // TODO: double-check this. is this a thing? // destItem.Exp += GetSourceExp(srcItem); - while (destItem.Exp >= expNextTable[destItem.Level + 1] && destItem.Level < maxLevel[destEquipRecord.grade_core_id - 1]) + while (destItem.Level < maxLevel[destEquipRecord.grade_core_id - 1] && destItem.Exp >= expNextTable[destItem.Level + 1] && destItem.Level < maxLevel[destEquipRecord.grade_core_id - 1]) { destItem.Exp -= expNextTable[destItem.Level - 1]; destItem.Level++; @@ -94,5 +137,27 @@ namespace EpinelPS.LobbyServer.Inventory return exp; } + + int CalcTotalExp(ItemData destItem) + { + int exp = 0; + var equipRecord = GameData.Instance.itemEquipTable.Values.FirstOrDefault(x => x.id == destItem.ItemType); + var levelRecord = GameData.Instance.ItemEquipGradeExpTable.Values.FirstOrDefault(x => x.grade_core_id == equipRecord.grade_core_id); + int[] expNextTable = GameData.Instance.itemEquipExpTable.Values + .Where(x => x.item_rare == equipRecord.item_rare) + .Select(x => x.exp) + .ToArray(); + + // skip the first level, it's unused + for (int i = 1; i < expNextTable.Length; i++) + { + exp += expNextTable[i]; + } + + return exp; + } + + (int t1, int t2, int t3) CalcModules(int exp) + => (exp / boostExpTable[7010001], exp / boostExpTable[7010002], exp / boostExpTable[7010003]); } } diff --git a/EpinelPS/Utils/MathUtils.cs b/EpinelPS/Utils/MathUtils.cs new file mode 100644 index 0000000..50bae1d --- /dev/null +++ b/EpinelPS/Utils/MathUtils.cs @@ -0,0 +1,15 @@ +namespace EpinelPS.Utils +{ + public class MathUtils + { + public static T Clamp(T value, T min, T max) where T : IComparable + { + if (value.CompareTo(min) < 0) + return min; + else if (value.CompareTo(max) > 0) + return max; + else + return value; + } + } +}