diff --git a/src/NosCore.Data/Enumerations/I18N/LanguageKey.cs b/src/NosCore.Data/Enumerations/I18N/LanguageKey.cs index 5a5a7bbbc..0a50dafcb 100644 --- a/src/NosCore.Data/Enumerations/I18N/LanguageKey.cs +++ b/src/NosCore.Data/Enumerations/I18N/LanguageKey.cs @@ -2,18 +2,18 @@ // | \| |/__\ /' _/ / _//__\| _ \ __| // | | ' | \/ |`._`.| \_| \/ | v / _| // |_|\__|\__/ |___/ \__/\__/|_|_\___| -// +// // Copyright (C) 2019 - NosCore -// +// // NosCore is a free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program. If not, see . @@ -166,7 +166,8 @@ public enum LogLanguageKey CHARACTER_SELECTION_FAILED, ALREADY_CONNECTED, PACKET_HANDLING_ERROR, - MFA_INCORRECT + MFA_INCORRECT, + UPGRADE_PACKET_SLOT2_NULL } [SuppressMessage("ReSharper", "InconsistentNaming")] diff --git a/src/NosCore.GameObject/Services/InventoryService/IInventoryService.cs b/src/NosCore.GameObject/Services/InventoryService/IInventoryService.cs index 63ecdd33c..51bc06f67 100644 --- a/src/NosCore.GameObject/Services/InventoryService/IInventoryService.cs +++ b/src/NosCore.GameObject/Services/InventoryService/IInventoryService.cs @@ -2,18 +2,18 @@ // | \| |/__\ /' _/ / _//__\| _ \ __| // | | ' | \/ |`._`.| \_| \/ | v / _| // |_|\__|\__/ |___/ \__/\__/|_|_\___| -// +// // Copyright (C) 2019 - NosCore -// +// // NosCore is a free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program. If not, see . @@ -29,19 +29,28 @@ public interface IInventoryService : IDictionary Dictionary Expensions { get; set; } List? AddItemToPocket(InventoryItemInstance newItem); + List? AddItemToPocket(InventoryItemInstance newItem, NoscorePocketType? type); List? AddItemToPocket(InventoryItemInstance newItem, NoscorePocketType? type, short? slot); bool CanAddItem(short itemVnum); + int CountItem(int itemVNum); + int CountItemInAnPocket(NoscorePocketType inv); + InventoryItemInstance? DeleteById(Guid id); + InventoryItemInstance? DeleteFromTypeAndSlot(NoscorePocketType type, short slot); + InventoryItemInstance? LoadByItemInstanceId(Guid id); + InventoryItemInstance? LoadBySlotAndType(short slot, NoscorePocketType type); + List LoadByVNumAndAmount(short vnum, short amount); + InventoryItemInstance? MoveInPocket(short sourceSlot, NoscorePocketType sourceType, NoscorePocketType targetType); @@ -52,6 +61,9 @@ bool TryMoveItem(NoscorePocketType sourcetype, short sourceSlot, short amount, s out InventoryItemInstance? sourcePocket, out InventoryItemInstance? destinationPocket); bool EnoughPlace(List itemInstances, NoscorePocketType type); + InventoryItemInstance? RemoveItemAmountFromInventory(short amount, Guid id); + + List RemoveItemAmountFromInventory(short amount, short vnum); } } \ No newline at end of file diff --git a/src/NosCore.GameObject/Services/InventoryService/InventoryService.cs b/src/NosCore.GameObject/Services/InventoryService/InventoryService.cs index 2e555bba4..33473084b 100644 --- a/src/NosCore.GameObject/Services/InventoryService/InventoryService.cs +++ b/src/NosCore.GameObject/Services/InventoryService/InventoryService.cs @@ -2,18 +2,18 @@ // | \| |/__\ /' _/ / _//__\| _ \ __| // | | ' | \/ |`._`.| \_| \/ | v / _| // |_|\__|\__/ |___/ \__/\__/|_|_\___| -// +// // Copyright (C) 2019 - NosCore -// +// // NosCore is a free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program. If not, see . @@ -84,6 +84,25 @@ private byte GetMaxSlot(NoscorePocketType pocket) return retItem; } + public List LoadByVNumAndAmount(short vnum, short amount) + { + var result = new List(); + if (CountItem(vnum) < amount) + { + return result; + } + foreach (var item in this.Select(s => s.Value).OrderByDescending(o => o.Slot).Where(w => w.ItemInstance!.ItemVNum == vnum).ToList()) + { + result.Add(item); + amount -= item.ItemInstance!.Amount; + if (amount <= 0) + { + break; + } + } + return result; + } + public bool CanAddItem(short itemVnum) { var type = _items.Find(item => item.VNum == itemVnum)?.Type; @@ -369,6 +388,7 @@ public bool TryMoveItem(NoscorePocketType sourcetype, short sourceSlot, short am case null when sourcePocket.ItemInstance.Amount == amount: sourcePocket.Slot = destinationSlot; break; + case null: var itemDest = (IItemInstance)sourcePocket.ItemInstance.Clone(); sourcePocket.ItemInstance.Amount -= amount; @@ -384,6 +404,7 @@ public bool TryMoveItem(NoscorePocketType sourcetype, short sourceSlot, short am ItemInstanceId = itemDest.Id }, sourcetype, destinationSlot); break; + default: if ((destinationPocket.ItemInstance?.ItemVNum == sourcePocket.ItemInstance.ItemVNum) && ((sourcePocket.ItemInstance.Item!.Type == NoscorePocketType.Main) || @@ -486,6 +507,23 @@ public bool EnoughPlace(List itemInstances, NoscorePocketType typ return null; } + public List RemoveItemAmountFromInventory(short amount, short vnum) + { + var result = new List(); + if (CountItem(vnum) < amount) + { + return result; + } + while (amount != 0) + { + var item = this.OrderByDescending(o => o.Value.Slot).Where(w => w.Value.ItemInstance!.ItemVNum == vnum).FirstOrDefault(); + var removedItem = RemoveItemAmountFromInventory(amount, item.Key); + amount -= removedItem != null ? amount : (short)(item.Value.ItemInstance!.Amount + amount); + result.Add(removedItem); + } + return result; + } + private short? GetFreeSlot(NoscorePocketType type) { var itemInstanceSlotsByType = this.Select(s => s.Value).Where(i => i.Type == type).OrderBy(i => i.Slot) diff --git a/src/NosCore.GameObject/Services/ItemGenerationService/ItemGenerationService.cs b/src/NosCore.GameObject/Services/ItemGenerationService/ItemGenerationService.cs index 1135f1e1d..1ac40de0c 100644 --- a/src/NosCore.GameObject/Services/ItemGenerationService/ItemGenerationService.cs +++ b/src/NosCore.GameObject/Services/ItemGenerationService/ItemGenerationService.cs @@ -2,18 +2,18 @@ // | \| |/__\ /' _/ / _//__\| _ \ __| // | | ' | \/ |`._`.| \_| \/ | v / _| // |_|\__|\__/ |___/ \__/\__/|_|_\___| -// +// // Copyright (C) 2019 - NosCore -// +// // NosCore is a free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program. If not, see . @@ -37,6 +37,7 @@ public class ItemGenerationService : IItemGenerationService private readonly IEventLoaderService>? _runner; private readonly List _items; private readonly ILogger _logger; + public ItemGenerationService(List items, ILogger logger) { _items = items; @@ -126,6 +127,7 @@ public IItemInstance Generate(short itemToCreateVNum, short amount, sbyte rare, Design = design, Upgrade = upgrade }; + case ItemType.Box: return new BoxInstance(itemToCreate) { @@ -133,13 +135,39 @@ public IItemInstance Generate(short itemToCreateVNum, short amount, sbyte rare, Upgrade = upgrade, Design = design }; + default: var wear = new WearableInstance(itemToCreate, _logger) { Amount = amount, Rare = rare, Upgrade = upgrade, - Design = design + Design = design, + Ammo = itemToCreate.MaximumAmmo, + Cellon = itemToCreate.CellonLvl, + CloseDefence = itemToCreate.CloseDefence, + Concentrate = itemToCreate.Concentrate, + CriticalLuckRate = itemToCreate.CriticalLuckRate, + CriticalRate = itemToCreate.CriticalRate, + DamageMaximum = itemToCreate.DamageMaximum, + DamageMinimum = itemToCreate.DamageMinimum, + DarkElement = itemToCreate.DarkElement, + DarkResistance = itemToCreate.DarkResistance, + DefenceDodge = itemToCreate.DefenceDodge, + DistanceDefence = itemToCreate.DistanceDefence, + DistanceDefenceDodge = itemToCreate.DistanceDefenceDodge, + ElementRate = itemToCreate.ElementRate, + FireElement = itemToCreate.FireElement, + FireResistance = itemToCreate.FireResistance, + HitRate = itemToCreate.HitRate, + Hp = itemToCreate.Hp, + LightElement = itemToCreate.LightElement, + LightResistance = itemToCreate.LightResistance, + MagicDefence = itemToCreate.MagicDefence, + MaxElementRate = itemToCreate.MaxElementRate, + Mp = itemToCreate.Mp, + WaterElement = itemToCreate.WaterElement, + WaterResistance = itemToCreate.WaterResistance }; if (wear.Rare > 0) { diff --git a/src/NosCore.GameObject/Services/NRunService/Handlers/ProbabilityUIHandler.cs b/src/NosCore.GameObject/Services/NRunService/Handlers/ProbabilityUIHandler.cs new file mode 100644 index 000000000..2c7667f5f --- /dev/null +++ b/src/NosCore.GameObject/Services/NRunService/Handlers/ProbabilityUIHandler.cs @@ -0,0 +1,27 @@ +using NosCore.GameObject.ComponentEntities.Interfaces; +using NosCore.GameObject.Networking.ClientSession; +using NosCore.Packets.ClientPackets.Npcs; +using NosCore.Packets.Enumerations; +using NosCore.Packets.ServerPackets.UI; +using System; +using System.Threading.Tasks; + +namespace NosCore.GameObject.Services.NRunService.Handlers +{ + public class ProbabilityUIHandler : INrunEventHandler + { + public bool Condition(Tuple datas) + { + return datas.Item2.Runner == NrunRunnerType.ProbabilityUIs; + } + + public Task ExecuteAsync(RequestData> requestData) + { + return requestData.ClientSession.SendPacketAsync( + new WopenPacket + { + Type = (WindowType)(requestData.Data.Item2.Type ?? 0) + }); + } + } +} \ No newline at end of file diff --git a/src/NosCore.GameObject/Services/UpgradeService/SumUpgradeService/ISumUpgradeService.cs b/src/NosCore.GameObject/Services/UpgradeService/SumUpgradeService/ISumUpgradeService.cs new file mode 100644 index 000000000..5d4972d10 --- /dev/null +++ b/src/NosCore.GameObject/Services/UpgradeService/SumUpgradeService/ISumUpgradeService.cs @@ -0,0 +1,32 @@ +// __ _ __ __ ___ __ ___ ___ +// | \| |/__\ /' _/ / _//__\| _ \ __| +// | | ' | \/ |`._`.| \_| \/ | v / _| +// |_|\__|\__/ |___/ \__/\__/|_|_\___| +// +// Copyright (C) 2019 - NosCore +// +// NosCore is a free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using NosCore.GameObject.Networking.ClientSession; +using NosCore.GameObject.Services.InventoryService; +using NosCore.Packets.Interfaces; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace NosCore.GameObject.Services.UpgradeService +{ + public interface ISumUpgradeService + { + Task> SumItemInstanceAsync(ClientSession session, InventoryItemInstance? sourceSlot, InventoryItemInstance? targetSlot); + } +} \ No newline at end of file diff --git a/src/NosCore.GameObject/Services/UpgradeService/SumUpgradeService/SumUpgradeService.cs b/src/NosCore.GameObject/Services/UpgradeService/SumUpgradeService/SumUpgradeService.cs new file mode 100644 index 000000000..207e90076 --- /dev/null +++ b/src/NosCore.GameObject/Services/UpgradeService/SumUpgradeService/SumUpgradeService.cs @@ -0,0 +1,157 @@ +// __ _ __ __ ___ __ ___ ___ +// | \| |/__\ /' _/ / _//__\| _ \ __| +// | | ' | \/ |`._`.| \_| \/ | v / _| +// |_|\__|\__/ |___/ \__/\__/|_|_\___| +// +// Copyright (C) 2019 - NosCore +// +// NosCore is a free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using NosCore.Algorithm.SumService; +using NosCore.Core.I18N; +using NosCore.Data.Enumerations.I18N; +using NosCore.GameObject.ComponentEntities.Extensions; +using NosCore.GameObject.Networking.ClientSession; +using NosCore.GameObject.Networking.Group; +using NosCore.GameObject.Services.InventoryService; +using NosCore.GameObject.Services.ItemGenerationService.Item; +using NosCore.Packets.ClientPackets.Inventory; +using NosCore.Packets.Enumerations; +using NosCore.Packets.Interfaces; +using NosCore.Packets.ServerPackets.Chats; +using NosCore.Packets.ServerPackets.Shop; +using NosCore.Packets.ServerPackets.UI; +using NosCore.Shared.Helpers; +using Serilog; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace NosCore.GameObject.Services.UpgradeService +{ + public class SumUpgradeService : UpgradeService, ISumUpgradeService + { + private readonly ISumService _sumService; + private const short SandVNum = 1027; + + public SumUpgradeService(ILogger logger, ISumService sumService) : base(logger) + { + _sumService = sumService; + } + + public async Task> SumItemInstanceAsync(ClientSession session, InventoryItemInstance? sourceSlot, InventoryItemInstance? targetSlot) + { + var result = new List(); + if (sourceSlot == null || targetSlot == null || sourceSlot.ItemInstance is not WearableInstance sourceWearableInstance || targetSlot.ItemInstance is not WearableInstance targetWearableInstance) + { + _logger.Error(LogLanguage.Instance.GetMessageFromKey(LogLanguageKey.UPGRADE_PACKET_SLOT2_NULL)); + return result; + } + + if (sourceSlot.ItemInstance!.Upgrade + targetSlot.ItemInstance!.Upgrade > 5) + { + result.Add(new InfoiPacket + { + Message = Game18NConstString.CombinationNumExceeded + }); + return result; + } + + var levelSum = (byte)(sourceSlot.ItemInstance.Upgrade + targetSlot.ItemInstance.Upgrade); + var sandCost = _sumService.GetSandCost(levelSum); + var didSucess = RandomHelper.Instance.RandomNumber() < _sumService.GetSuccessRate(levelSum); + if (!didSucess) + { + session.Character.InventoryService.RemoveItemAmountFromInventory(1, sourceSlot.ItemInstanceId); + result.AddRange(new IPacket[] { + new GuriPacket + { + Type = GuriPacketType.AfterSumming, + Argument = 1, + SecondArgument = 0, + EntityId = session.Character.CharacterId, + Value = 1332 + }, + new MsgiPacket + { + Message = Game18NConstString.CombinationFailed + }, + new Sayi2Packet + { + Message = Game18NConstString.CombinationItemsDisappeared, + Type = SayColorType.Purple + } + }); + } + else + { + sourceWearableInstance.DarkResistance = (short)((sourceWearableInstance.DarkResistance ?? 0) + (targetWearableInstance.DarkResistance ?? 0)); + sourceWearableInstance.LightResistance = (short)((sourceWearableInstance.LightResistance ?? 0) + (targetWearableInstance.LightResistance ?? 0)); + sourceWearableInstance.FireResistance = (short)((sourceWearableInstance.FireResistance ?? 0) + (targetWearableInstance.FireResistance ?? 0)); + sourceWearableInstance.WaterResistance = (short)((sourceWearableInstance.WaterResistance ?? 0) + (targetWearableInstance.WaterResistance ?? 0)); + sourceSlot.ItemInstance.Upgrade += (byte)(targetSlot.ItemInstance.Upgrade + 1); + + result.AddRange(new IPacket[] { + new GuriPacket + { + Type = GuriPacketType.AfterSumming, + Argument = 1, + SecondArgument = 0, + EntityId = session.Character.CharacterId, + Value = 1324 + }, + new PdtiPacket + { + Unknow = 10, + ItemVnum = sourceSlot.ItemInstance.ItemVNum, + RecipeAmount = 1, + Unknow3 = 27, + ItemUpgrade = sourceSlot.ItemInstance.Upgrade, + Unknow4 = 0 + }, + new MsgiPacket + { + Message = Game18NConstString.CombinationSuccessful + }, + new Sayi2Packet + { + Message = Game18NConstString.CombinationSuccessful, + Type = SayColorType.Green + } + }); + } + + result.AddRange(new IPacket[] { + sourceSlot.GeneratePocketChange(PocketType.Equipment, sourceSlot.Slot), + ((InventoryItemInstance?)null).GeneratePocketChange(PocketType.Equipment, targetSlot.Slot), + new ShopEndPacket + { + Type = ShopEndPacketType.CloseSubWindow + } + }); + result.AddRange(session.Character.InventoryService.LoadByVNumAndAmount(SandVNum, (short)sandCost).Select(s => s.GeneratePocketChange(PocketType.Main, s!.Slot))); + + session.Character.InventoryService.RemoveItemAmountFromInventory((short)sandCost, SandVNum); + session.Character.InventoryService.DeleteById(targetSlot.ItemInstanceId); + await session.Character.RemoveGoldAsync(_sumService.GetPrice(levelSum)); + await session.Character.MapInstance.SendPacketAsync(new GuriPacket + { + Type = GuriPacketType.Unknow, + Argument = 1, + SecondArgument = 0, + EntityId = session.Character.CharacterId + }); + return result; + } + } +} \ No newline at end of file diff --git a/src/NosCore.GameObject/Services/UpgradeService/UpgradeService.cs b/src/NosCore.GameObject/Services/UpgradeService/UpgradeService.cs new file mode 100644 index 000000000..73f1f6ff6 --- /dev/null +++ b/src/NosCore.GameObject/Services/UpgradeService/UpgradeService.cs @@ -0,0 +1,33 @@ +// __ _ __ __ ___ __ ___ ___ +// | \| |/__\ /' _/ / _//__\| _ \ __| +// | | ' | \/ |`._`.| \_| \/ | v / _| +// |_|\__|\__/ |___/ \__/\__/|_|_\___| +// +// Copyright (C) 2019 - NosCore +// +// NosCore is a free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Serilog; + +namespace NosCore.GameObject.Services.UpgradeService +{ + public class UpgradeService + { + protected readonly ILogger _logger; + + public UpgradeService(ILogger logger) + { + _logger = logger; + } + } +} \ No newline at end of file diff --git a/src/NosCore.PacketHandlers/Command/CreateItemPacketHandler.cs b/src/NosCore.PacketHandlers/Command/CreateItemPacketHandler.cs index 632689da9..2d5e32992 100644 --- a/src/NosCore.PacketHandlers/Command/CreateItemPacketHandler.cs +++ b/src/NosCore.PacketHandlers/Command/CreateItemPacketHandler.cs @@ -2,18 +2,18 @@ // | \| |/__\ /' _/ / _//__\| _ \ __| // | | ' | \/ |`._`.| \_| \/ | v / _| // |_|\__|\__/ |___/ \__/\__/|_|_\___| -// +// // Copyright (C) 2019 - NosCore -// +// // NosCore is a free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program. If not, see . @@ -36,6 +36,7 @@ using Serilog; using System.Collections.Generic; using System.Threading.Tasks; + //TODO stop using obsolete #pragma warning disable 618 @@ -155,13 +156,15 @@ await session.SendPacketAsync(new MsgiPacket case EquipmentType.SecondaryWeapon: wearable.SetRarityPoint(); break; + case EquipmentType.Boots: case EquipmentType.Gloves: - wearable.FireResistance = (short)(wearable.Item.FireResistance * upgrade); - wearable.DarkResistance = (short)(wearable.Item.DarkResistance * upgrade); - wearable.LightResistance = (short)(wearable.Item.LightResistance * upgrade); - wearable.WaterResistance = (short)(wearable.Item.WaterResistance * upgrade); + wearable.FireResistance = (short)(wearable.Item.FireResistance * (upgrade + 1)); + wearable.DarkResistance = (short)(wearable.Item.DarkResistance * (upgrade + 1)); + wearable.LightResistance = (short)(wearable.Item.LightResistance * (upgrade + 1)); + wearable.WaterResistance = (short)(wearable.Item.WaterResistance * (upgrade + 1)); break; + default: _logger.Debug( LogLanguage.Instance.GetMessageFromKey(LogLanguageKey.NO_SPECIAL_PROPERTIES_WEARABLE)); diff --git a/src/NosCore.PacketHandlers/Upgrades/UpgradePacketHandler.cs b/src/NosCore.PacketHandlers/Upgrades/UpgradePacketHandler.cs new file mode 100644 index 000000000..b4e00a48e --- /dev/null +++ b/src/NosCore.PacketHandlers/Upgrades/UpgradePacketHandler.cs @@ -0,0 +1,63 @@ +// __ _ __ __ ___ __ ___ ___ +// | \| |/__\ /' _/ / _//__\| _ \ __| +// | | ' | \/ |`._`.| \_| \/ | v / _| +// |_|\__|\__/ |___/ \__/\__/|_|_\___| +// +// Copyright (C) 2019 - NosCore +// +// NosCore is a free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using NosCore.Data.Enumerations; +using NosCore.GameObject; +using NosCore.GameObject.Networking.ClientSession; +using NosCore.Packets.ClientPackets.Player; +using Serilog; +using System.Threading.Tasks; +using NosCore.Packets.Enumerations; +using NosCore.GameObject.Services.UpgradeService; +using NosCore.Core.I18N; +using NosCore.Data.Enumerations.I18N; + +namespace NosCore.PacketHandlers.Upgrades +{ + public class UpgradePacketHandler : PacketHandler, IWorldPacketHandler + { + private readonly ILogger _logger; + private readonly ISumUpgradeService _sumUpgradeService; + + public UpgradePacketHandler(ILogger logger, ISumUpgradeService sumUpgradeService) + { + _logger = logger; + _sumUpgradeService = sumUpgradeService; + } + + public override async Task ExecuteAsync(UpgradePacket upgradePacket, ClientSession session) + { + switch (upgradePacket.UpgradeType) + { + case UpgradePacketType.SumResistance: + if (upgradePacket.Slot2 == null) + { + _logger.Error(LogLanguage.Instance.GetMessageFromKey(LogLanguageKey.UPGRADE_PACKET_SLOT2_NULL)); + return; + } + + var sourceSlot = session.Character.InventoryService.LoadBySlotAndType(upgradePacket.Slot, (NoscorePocketType)upgradePacket.InventoryType); + var targetSlot = session.Character.InventoryService.LoadBySlotAndType((byte)upgradePacket.Slot2, (NoscorePocketType)upgradePacket.InventoryType); + + await session.SendPacketsAsync(await _sumUpgradeService.SumItemInstanceAsync(session, sourceSlot, targetSlot)); + break; + } + } + } +} \ No newline at end of file diff --git a/test/NosCore.GameObject.Tests/Services/InventoryService/InventoryServiceTests.cs b/test/NosCore.GameObject.Tests/Services/InventoryService/InventoryServiceTests.cs index ed18d899e..51273c0f8 100644 --- a/test/NosCore.GameObject.Tests/Services/InventoryService/InventoryServiceTests.cs +++ b/test/NosCore.GameObject.Tests/Services/InventoryService/InventoryServiceTests.cs @@ -2,18 +2,18 @@ // | \| |/__\ /' _/ / _//__\| _ \ __| // | | ' | \/ |`._`.| \_| \/ | v / _| // |_|\__|\__/ |___/ \__/\__/|_|_\___| -// +// // Copyright (C) 2019 - NosCore -// +// // NosCore is a free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program. If not, see . @@ -52,6 +52,7 @@ public void Setup() { new Item {Type = NoscorePocketType.Main, VNum = 1012}, new Item {Type = NoscorePocketType.Main, VNum = 1013}, + new Item {Type = NoscorePocketType.Etc, VNum = 1027}, new Item {Type = NoscorePocketType.Equipment, VNum = 1, ItemType = ItemType.Weapon}, new Item {Type = NoscorePocketType.Equipment, VNum = 2, ItemType = ItemType.Weapon}, new Item {Type = NoscorePocketType.Equipment, VNum = 912, ItemType = ItemType.Specialist}, @@ -219,7 +220,62 @@ public void MoveHalfSlotAndMergeThemWithOverflow() Assert.IsTrue((destinationItem?.ItemInstance?.Amount == 999) && (destinationItem.Slot == 1)); } - //TODO RemoveItemAmountFromInventory + [TestMethod] + public void RemoveItemAmountFromInventoryByGuidWithoutRemove() + { + var item = Inventory!.AddItemToPocket(InventoryItemInstance.Create(_itemProvider!.Create(1027, 999), 0))!.First(); + Inventory!.RemoveItemAmountFromInventory(499, item.ItemInstanceId); + Assert.IsTrue(item.ItemInstance?.Amount == 500); + } + + [TestMethod] + public void RemoveItemAmountFromInventoryByGuidWithRemove() + { + var item = Inventory!.AddItemToPocket(InventoryItemInstance.Create(_itemProvider!.Create(1027, 999), 0))!.First(); + Inventory!.RemoveItemAmountFromInventory(999, item.ItemInstanceId); + Assert.IsTrue(Inventory.LoadBySlotAndType(item.Slot, NoscorePocketType.Etc) == null); + } + + [TestMethod] + public void RemoveItemAmountFromInventoryByVNum() + { + var itemSlot0 = Inventory!.AddItemToPocket(InventoryItemInstance.Create(_itemProvider!.Create(1027, 5), 0), NoscorePocketType.Etc, 0)!.First(); + var itemSlot1 = Inventory!.AddItemToPocket(InventoryItemInstance.Create(_itemProvider!.Create(1027, 3), 0), NoscorePocketType.Etc, 1)!.First(); + var itemSlot2 = Inventory!.AddItemToPocket(InventoryItemInstance.Create(_itemProvider!.Create(1027, 10), 0), NoscorePocketType.Etc, 2)!.First(); + Inventory!.RemoveItemAmountFromInventory(15, 1027); + Assert.IsTrue(Inventory.LoadBySlotAndType(itemSlot2.Slot, NoscorePocketType.Etc)?.ItemInstance == null); + Assert.IsTrue(Inventory.LoadBySlotAndType(itemSlot1.Slot, NoscorePocketType.Etc)?.ItemInstance == null); + Assert.IsTrue(Inventory.LoadBySlotAndType(itemSlot0.Slot, NoscorePocketType.Etc)?.ItemInstance?.Amount == 3); + } + + [TestMethod] + public void RemoveItemAmountFromInventoryByVNumWithoutItemOrAmount() + { + Assert.IsTrue(Inventory?.RemoveItemAmountFromInventory(15, 1027).Count == 0); + Assert.IsTrue(Inventory?.RemoveItemAmountFromInventory(0, 1027).Count == 0); + Inventory?.AddItemToPocket(InventoryItemInstance.Create(_itemProvider!.Create(1027, 10), 0), NoscorePocketType.Etc, 0)?.First(); + Assert.IsTrue(Inventory?.RemoveItemAmountFromInventory(15, 1027).Count == 0); + } + + [TestMethod] + public void LoadByVNumAndAmount() + { + Inventory?.AddItemToPocket(InventoryItemInstance.Create(_itemProvider!.Create(1027, 5), 0), NoscorePocketType.Etc, 0)?.First(); + Inventory?.AddItemToPocket(InventoryItemInstance.Create(_itemProvider!.Create(1027, 3), 0), NoscorePocketType.Etc, 1)?.First(); + Assert.IsTrue(Inventory?.LoadByVNumAndAmount(1027, 3).Count == 1); + Assert.IsTrue(Inventory?.LoadByVNumAndAmount(1027, 6).Count == 2); + } + + [TestMethod] + public void LoadByVNumAndAmountWithoutItemOrAmount() + { + Assert.IsTrue(Inventory?.LoadByVNumAndAmount(1027, 3).Count == 0); + Inventory?.AddItemToPocket(InventoryItemInstance.Create(_itemProvider!.Create(1027, 5), 0), NoscorePocketType.Etc, 0)?.First(); + Assert.IsTrue(Inventory?.LoadByVNumAndAmount(1027, 3).Count == 1); + Assert.IsTrue(Inventory?.LoadByVNumAndAmount(1027, 6).Count == 0); + Inventory?.AddItemToPocket(InventoryItemInstance.Create(_itemProvider!.Create(1027, 10), 0), NoscorePocketType.Etc, 1)?.First(); + Assert.IsTrue(Inventory?.LoadByVNumAndAmount(1027, 12).Count == 2); + } //TODO EnoughPlace diff --git a/test/NosCore.PacketHandlers.Tests/Upgrades/UpgradePacketHandlerTests.cs b/test/NosCore.PacketHandlers.Tests/Upgrades/UpgradePacketHandlerTests.cs new file mode 100644 index 000000000..3ef8cf6b3 --- /dev/null +++ b/test/NosCore.PacketHandlers.Tests/Upgrades/UpgradePacketHandlerTests.cs @@ -0,0 +1,91 @@ +// __ _ __ __ ___ __ ___ ___ +// | \| |/__\ /' _/ / _//__\| _ \ __| +// | | ' | \/ |`._`.| \_| \/ | v / _| +// |_|\__|\__/ |___/ \__/\__/|_|_\___| +// +// Copyright (C) 2019 - NosCore +// +// NosCore is a free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using NosCore.Core; +using NosCore.Data.Enumerations; +using NosCore.GameObject.Networking.ClientSession; +using NosCore.GameObject.Services.EventLoaderService; +using NosCore.GameObject.Services.InventoryService; +using NosCore.GameObject.Services.ItemGenerationService; +using NosCore.GameObject.Services.UpgradeService; +using NosCore.PacketHandlers.Upgrades; +using NosCore.Packets.ClientPackets.Player; +using NosCore.Packets.Enumerations; +using NosCore.Tests.Shared; +using Serilog; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using NosCore.Data.StaticEntities; +using NosCore.GameObject.Services.ItemGenerationService.Item; +using NosCore.Packets.ClientPackets.Inventory; +using NosCore.GameObject; +using NosCore.Data.Enumerations.Items; +using NosCore.Algorithm.SumService; + +namespace NosCore.PacketHandlers.Tests.Upgrades +{ + [TestClass] + public class UpgradePacketHandlerTests + { + private static readonly ILogger Logger = new Mock().Object; + private ItemGenerationService? _itemProvider; + private ISumUpgradeService? _sumUpgradeService; + private ClientSession? _session; + private UpgradePacketHandler? _upgradePacketHandler; + + [TestInitialize] + public async Task SetupAsync() + { + SystemTime.Freeze(); + await TestHelpers.ResetAsync().ConfigureAwait(false); + var items = new List + { + new Item {Type = NoscorePocketType.Etc, VNum = 1027}, + new Item {Type = NoscorePocketType.Equipment, VNum = 71, ItemType = ItemType.Fashion, LightResistance = 2}, + }; + _itemProvider = new ItemGenerationService(items, new EventLoaderService, IUseItemEventHandler>(new List>>()), Logger); + _sumUpgradeService = new SumUpgradeService(Logger, new SumService()); + _session = await TestHelpers.Instance.GenerateSessionAsync().ConfigureAwait(false); + _upgradePacketHandler = new UpgradePacketHandler(Logger, _sumUpgradeService); + } + + [TestMethod] + public async Task Test_UpgradePacketSum1Async() + { + _session!.Character.InventoryService!.AddItemToPocket(InventoryItemInstance.Create(_itemProvider!.Create(1027, 999), 0)); + var glove = _session!.Character.InventoryService!.AddItemToPocket(InventoryItemInstance.Create(_itemProvider!.Create(71, 1, 0, 0), 0))![0]; + _session!.Character.InventoryService!.AddItemToPocket(InventoryItemInstance.Create(_itemProvider!.Create(71, 1, 0, 0), 0)); + await _upgradePacketHandler!.ExecuteAsync(new UpgradePacket + { + UpgradeType = UpgradePacketType.SumResistance, + Slot = 0, + Slot2 = 1, + InventoryType = PocketType.Equipment + }, _session).ConfigureAwait(false); + Assert.IsTrue((_session.Character.InventoryService.Count == 2) && + (_session.Character.InventoryService!.CountItem(1027) == 994) && + (glove.ItemInstance is WearableInstance wearableInstance) && + wearableInstance.LightResistance == 4 && + wearableInstance.Upgrade == 1); + } + } +} \ No newline at end of file diff --git a/test/NosCore.Tests.Shared/TestHelpers.cs b/test/NosCore.Tests.Shared/TestHelpers.cs index d8133a4c4..40de0ec35 100644 --- a/test/NosCore.Tests.Shared/TestHelpers.cs +++ b/test/NosCore.Tests.Shared/TestHelpers.cs @@ -2,18 +2,18 @@ // | \| |/__\ /' _/ / _//__\| _ \ __| // | | ' | \/ |`._`.| \_| \/ | v / _| // |_|\__|\__/ |___/ \__/\__/|_|_\___| -// +// // Copyright (C) 2019 - NosCore -// +// // NosCore is a free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program. If not, see . @@ -271,7 +271,6 @@ public void InitDatabase() .ConstructUsing(src => new GameObject.MapNpc(GenerateItemProvider(), _logger, TestHelpers.Instance.DistanceCalculator)); TypeAdapterConfig.NewConfig() .ConstructUsing(src => new GameObject.MapMonster(_logger, TestHelpers.Instance.DistanceCalculator)); - } public async Task GenerateSessionAsync(List? packetHandlers = null)