diff --git a/Common/Data/Excel/EquipmentConfigExcel.cs b/Common/Data/Excel/EquipmentConfigExcel.cs index 39bb0223..09fe7759 100644 --- a/Common/Data/Excel/EquipmentConfigExcel.cs +++ b/Common/Data/Excel/EquipmentConfigExcel.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using static EggLink.DanhengServer.Data.Excel.AvatarPromotionConfigExcel; namespace EggLink.DanhengServer.Data.Excel { @@ -15,7 +16,8 @@ namespace EggLink.DanhengServer.Data.Excel public int EquipmentID { get; set; } public bool Release { get; set; } public int ExpType { get; set; } - + public int MaxPromotion { get; set; } = 0; + public int MaxRank { get; set; } = 0; [JsonConverter(typeof(StringEnumConverter))] public RarityEnum Rarity { get; set; } = 0; public override int GetId() diff --git a/Common/Data/Excel/EquipmentPromotionConfigExcel.cs b/Common/Data/Excel/EquipmentPromotionConfigExcel.cs index b74b8253..7fc2f32f 100644 --- a/Common/Data/Excel/EquipmentPromotionConfigExcel.cs +++ b/Common/Data/Excel/EquipmentPromotionConfigExcel.cs @@ -12,7 +12,8 @@ namespace EggLink.DanhengServer.Data.Excel public int EquipmentID { get; set; } public int Promotion { get; set; } public int MaxLevel { get; set; } - + public int WorldLevelRequire { get; set; } + public List PromotionCostList { get; set; } = []; public override int GetId() { return EquipmentID * 10 + Promotion; @@ -22,5 +23,10 @@ namespace EggLink.DanhengServer.Data.Excel { GameData.EquipmentPromotionConfigData.Add(GetId(), this); } + public class ItemParam + { + public int ItemID; + public int ItemNum; + } } } diff --git a/GameServer/Game/Inventory/InventoryManager.cs b/GameServer/Game/Inventory/InventoryManager.cs index 8d817b57..a650682d 100644 --- a/GameServer/Game/Inventory/InventoryManager.cs +++ b/GameServer/Game/Inventory/InventoryManager.cs @@ -216,17 +216,44 @@ namespace EggLink.DanhengServer.Game.Inventory return item; } - public void RemoveItem(int itemId, int count, int uniqueId = 0) + public List RemoveItems(List<(int itemId, int count, int uniqueId)> items, bool sync = true) + { + List removedItems = new List(); + foreach (var item in items) + { + var removedItem = RemoveItem(item.itemId, item.count, item.uniqueId, sync: false); + if (removedItem != null) + { + removedItems.Add(removedItem); + } + } + if (sync && removedItems.Count > 0) + { + Player.SendPacket(new PacketPlayerSyncScNotify(removedItems)); + } + DatabaseHelper.Instance?.UpdateInstance(Data); + return removedItems; + } + + public ItemData? RemoveItem(int itemId, int count, int uniqueId = 0, bool sync = true) { GameData.ItemConfigData.TryGetValue(itemId, out var itemConfig); - if (itemConfig == null) return; + if (itemConfig == null) + { + return null; + } + ItemData? itemData = null; + switch (itemConfig.ItemMainType) { case ItemMainTypeEnum.Material: case ItemMainTypeEnum.Mission: var item = Data.MaterialItems.Find(x => x.ItemId == itemId); - if (item == null) return; + if (item == null) + { + return null; + } item.Count -= count; if (item.Count <= 0) { @@ -240,32 +267,53 @@ namespace EggLink.DanhengServer.Game.Inventory { case 1: Player.Data.Hcoin -= count; + itemData = new ItemData { ItemId = itemId, Count = count }; break; case 2: Player.Data.Scoin -= count; + itemData = new ItemData { ItemId = itemId, Count = count }; break; case 3: Player.Data.Mcoin -= count; + itemData = new ItemData { ItemId = itemId, Count = count }; break; case 32: Player.Data.TalentPoints -= count; + itemData = new ItemData { ItemId = itemId, Count = count }; break; } - Player.SendPacket(new PacketPlayerSyncScNotify(Player.ToProto())); + if (sync && itemData != null) + { + Player.SendPacket(new PacketPlayerSyncScNotify(itemData)); + } break; case ItemMainTypeEnum.Equipment: var equipment = Data.EquipmentItems.Find(x => x.UniqueId == uniqueId); - if (equipment == null) return; + if (equipment == null) + { + return null; + } Data.EquipmentItems.Remove(equipment); equipment.Count = 0; itemData = equipment; break; + case ItemMainTypeEnum.Relic: + var relic = Data.RelicItems.Find(x => x.UniqueId == uniqueId); + if (relic == null) + { + return null; + } + Data.RelicItems.Remove(relic); + relic.Count = 0; + itemData = relic; + break; } - if (itemData != null) + if (itemData != null && sync) { Player.SendPacket(new PacketPlayerSyncScNotify(itemData)); } DatabaseHelper.Instance?.UpdateInstance(Data); + return itemData; } public ItemData? GetItem(int itemId) @@ -430,52 +478,55 @@ namespace EggLink.DanhengServer.Game.Inventory public List SellItem(ItemCostData costData) { - List items = []; - Dictionary ItemMap = []; + List items = new List(); + Dictionary itemMap = new Dictionary(); + List<(int itemId, int count, int uniqueId)> removeItems = new List<(int itemId, int count, int uniqueId)>(); + foreach (var cost in costData.ItemList) { if (cost.EquipmentUniqueId != 0) // equipment { var itemData = Data.EquipmentItems.Find(x => x.UniqueId == cost.EquipmentUniqueId); if (itemData == null) continue; - RemoveItem(itemData.ItemId, 1, (int)cost.EquipmentUniqueId); + removeItems.Add((itemData.ItemId, 1, (int)cost.EquipmentUniqueId)); GameData.ItemConfigData.TryGetValue(itemData.ItemId, out var itemConfig); if (itemConfig == null) continue; foreach (var returnItem in itemConfig.ReturnItemIDList) // return items { - if (!ItemMap.ContainsKey(returnItem.ItemID)) + if (!itemMap.ContainsKey(returnItem.ItemID)) { - ItemMap[returnItem.ItemID] = 0; + itemMap[returnItem.ItemID] = 0; } - ItemMap[returnItem.ItemID] += returnItem.ItemNum; + itemMap[returnItem.ItemID] += returnItem.ItemNum; } } else if (cost.RelicUniqueId != 0) // relic { var itemData = Data.RelicItems.Find(x => x.UniqueId == cost.RelicUniqueId); if (itemData == null) continue; - RemoveItem(itemData.ItemId, 1, (int)cost.RelicUniqueId); + removeItems.Add((itemData.ItemId, 1, (int)cost.RelicUniqueId)); GameData.ItemConfigData.TryGetValue(itemData.ItemId, out var itemConfig); if (itemConfig == null) continue; foreach (var returnItem in itemConfig.ReturnItemIDList) // return items { - if (!ItemMap.ContainsKey(returnItem.ItemID)) + if (!itemMap.ContainsKey(returnItem.ItemID)) { - ItemMap[returnItem.ItemID] = 0; + itemMap[returnItem.ItemID] = 0; } - ItemMap[returnItem.ItemID] += returnItem.ItemNum; + itemMap[returnItem.ItemID] += returnItem.ItemNum; } } else { - RemoveItem((int)cost.PileItem.ItemId, (int)cost.PileItem.ItemNum); + removeItems.Add(((int)cost.PileItem.ItemId, (int)cost.PileItem.ItemNum, 0)); } } - foreach (var itemInfo in ItemMap) + var removedItems = RemoveItems(removeItems); + + foreach (var itemInfo in itemMap) { var item = AddItem(itemInfo.Key, itemInfo.Value, false); - if (item != null) { items.Add(item); @@ -765,7 +816,7 @@ namespace EggLink.DanhengServer.Game.Inventory if (avatarData == null || avatarData.Excel == null || avatarData.Promotion >= avatarData.Excel.MaxPromotion) return false; // Get promotion data - Data.Excel.AvatarPromotionConfigExcel promotion = GameData.AvatarPromotionConfigData.Values.FirstOrDefault(x => x.AvatarID == avatarId && x.Promotion == avatarData.Promotion + 1)!; + Data.Excel.AvatarPromotionConfigExcel promotion = GameData.AvatarPromotionConfigData.Values.FirstOrDefault(x => x.AvatarID == avatarId && x.Promotion == avatarData.Promotion)!; // Sanity check if ((promotion == null) || avatarData.Level < promotion.MaxLevel || Player.Data.Level < promotion.PlayerLevelRequire || Player.Data.WorldLevel < promotion.WorldLevelRequire) { @@ -784,7 +835,30 @@ namespace EggLink.DanhengServer.Game.Inventory Player.SendPacket(new PacketPlayerSyncScNotify(avatarData)); return true; } + public bool PromoteEquipment(int equipmentUniqueId) + { + var equipmentData = Player.InventoryManager!.Data.EquipmentItems.FirstOrDefault(x => x.UniqueId == equipmentUniqueId); + if (equipmentData == null || equipmentData.Promotion >= GameData.EquipmentConfigData[equipmentData.ItemId].MaxPromotion) return false; + var promotionConfig = GameData.EquipmentPromotionConfigData.Values + .FirstOrDefault(x => x.EquipmentID == equipmentData.ItemId && x.Promotion == equipmentData.Promotion); + + if (promotionConfig == null || equipmentData.Level < promotionConfig.MaxLevel || Player.Data.WorldLevel < promotionConfig.WorldLevelRequire) + { + return false; + } + + foreach (var cost in promotionConfig.PromotionCostList) + { + Player.InventoryManager!.RemoveItem(cost.ItemID, cost.ItemNum); + } + + equipmentData.Promotion++; + DatabaseHelper.Instance!.UpdateInstance(Player.InventoryManager.Data); + Player.SendPacket(new PacketPlayerSyncScNotify(equipmentData)); + + return true; + } public List LevelUpRelic(int uniqueId, ItemCostData costData) { var relicItem = Data.RelicItems.Find(x => x.UniqueId == uniqueId); diff --git a/GameServer/Server/Packet/Recv/Avatar/HandlerPromoteEquipmentCsReq.cs b/GameServer/Server/Packet/Recv/Avatar/HandlerPromoteEquipmentCsReq.cs new file mode 100644 index 00000000..7bc38858 --- /dev/null +++ b/GameServer/Server/Packet/Recv/Avatar/HandlerPromoteEquipmentCsReq.cs @@ -0,0 +1,22 @@ +using EggLink.DanhengServer.Proto; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Server.Packet.Recv.Avatar +{ + [Opcode(CmdIds.PromoteEquipmentCsReq)] + public class HandlerPromoteEquipmentCsReq : Handler + { + public override void OnHandle(Connection connection, byte[] header, byte[] data) + { + var req = PromoteEquipmentCsReq.Parser.ParseFrom(data); + + connection.Player!.InventoryManager!.PromoteEquipment((int)req.EquipmentUniqueId); + + connection.SendPacket(CmdIds.PromoteEquipmentScRsp); + } + } +}