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)