diff --git a/Campofinale/Commands/Handlers/CommandAdd.cs b/Campofinale/Commands/Handlers/CommandAdd.cs index 8cb9fb3..e8337c1 100644 --- a/Campofinale/Commands/Handlers/CommandAdd.cs +++ b/Campofinale/Commands/Handlers/CommandAdd.cs @@ -28,15 +28,12 @@ public static class CommandAdd case "item": Item item=target.inventoryManager.AddItem(args[1], int.Parse(args[2])); message = $"Item {args[1]} was added to {target.nickname}"; - - target.Send(new PacketScItemBagScopeModify(target, item)); break; case "weapon": Item wep = target.inventoryManager.AddWeapon(args[1], Convert.ToUInt64(args[2])); message = $"Weapon {args[1]} was added to {target.nickname}"; - target.Send(new PacketScItemBagScopeModify(target, wep)); break; case "char": @@ -77,7 +74,7 @@ public static class CommandAdd return; } - target.inventoryManager.Save(); + CommandManager.SendMessage(sender, $"{message}."); } catch (Exception err) diff --git a/Campofinale/Database/Database.cs b/Campofinale/Database/Database.cs index 91b655f..21e0196 100644 --- a/Campofinale/Database/Database.cs +++ b/Campofinale/Database/Database.cs @@ -43,6 +43,7 @@ namespace Campofinale.Database public Dictionary> bitsets = new(); public PlayerSafeZoneInfo savedSafeZone = new(); public Gender gender = Gender.GenFemale; + public Dictionary bag = new(); } public class Account { @@ -144,6 +145,7 @@ namespace Campofinale.Database bitsets=player.bitsetManager.bitsets, savedSafeZone = player.savedSaveZone, gender=player.gender, + bag=player.inventoryManager.items.bag }; UpsertPlayerData(data); } diff --git a/Campofinale/Database/DatabaseManager.cs b/Campofinale/Database/DatabaseManager.cs index a267ddd..ba4f8f0 100644 --- a/Campofinale/Database/DatabaseManager.cs +++ b/Campofinale/Database/DatabaseManager.cs @@ -9,6 +9,7 @@ using MongoDB.Bson.IO; using MongoDB.Bson; using System.Reflection; using static Campofinale.Game.Factory.FactoryNode; +using Campofinale.Game.Inventory; namespace Campofinale.Database { @@ -68,6 +69,8 @@ namespace Campofinale.Database { BsonSerializer.RegisterSerializer(typeof(Dictionary), new CustomDictionarySerializer()); BsonSerializer.RegisterSerializer(typeof(Dictionary>), new CustomDictionarySerializer>()); + BsonSerializer.RegisterSerializer(typeof(Dictionary), new CustomDictionarySerializer()); + RegisterSubclasses(); Logger.Print("Connecting to MongoDB..."); try diff --git a/Campofinale/Game/Inventory/InventoryList.cs b/Campofinale/Game/Inventory/InventoryList.cs index e7d4fa5..77aaa4c 100644 --- a/Campofinale/Game/Inventory/InventoryList.cs +++ b/Campofinale/Game/Inventory/InventoryList.cs @@ -1,4 +1,5 @@ -using Campofinale.Packets.Sc; +using Campofinale.Database; +using Campofinale.Packets.Sc; using System; using System.Collections.Generic; using System.Linq; @@ -142,7 +143,27 @@ namespace Campofinale.Game.Inventory return null; } + public List FindAll(Predicate match, FindType findType = FindType.Items) + { + switch (findType) + { + case FindType.Items: + return items.FindAll(match); + break; + case FindType.FactoryDepots: + //TODO + break; + case FindType.Bag: + var itemB = bag.Values.ToList().FindAll(match); + if (itemB != null) + { + return itemB; + } + break; + } + return null; + } /// ///Add an item to the inventory (or increment it's amount if it's not an instance type, else add a new one or add to bag if it's a Factory item /// @@ -156,6 +177,7 @@ namespace Campofinale.Game.Inventory if (item.InstanceType()) { items.Add(item); + DatabaseManager.db.UpsertItem(item); return item; } else @@ -164,17 +186,92 @@ namespace Campofinale.Game.Inventory if (exist != null) { exist.amount += item.amount; + DatabaseManager.db.UpsertItem(exist); return exist; } else { items.Add(item); + DatabaseManager.db.UpsertItem(item); return item; } } } + /// + /// Get the item amount from all depots + /// + /// + /// + public int GetItemAmount(string id) + { + int amt = 0; + Item item=Find(i=>i.id==id); + if (item != null) + { + amt += item.amount; + } + List bagItems = FindAll(i=>i.id==id,FindType.Bag); + foreach (Item bagItem in bagItems) + { + amt += bagItem.amount; + } + + return amt; + } + public void Remove(Item item) + { + if (items.Remove(item)) + { + this.player.Send(new PacketScItemBagScopeModify(this.player, item)); + DatabaseManager.db.DeleteItem(item); + } + else if (RemoveFromBag(item)) + { + UpdateBagInventoryPacket(); + } + } - + private bool RemoveFromBag(Item item) + { + for (int i = 0; i < maxBagSize; i++) + { + Item bagItem = null; + if (bag.ContainsKey(i)) + { + bagItem = bag[i]; + if (bagItem.guid == item.guid) + { + bag.Remove(i); + return true; + } + } + } + return false; + } + /// + /// Move item from bag grid to another position + /// + /// + /// + public void MoveBagItem(int fromGrid, int toGrid) + { + Item item1 = bag[fromGrid]; + Item item2 = null; + if (bag.ContainsKey(toGrid)) + { + item2 = bag[toGrid]; + } + bag[toGrid] = item1; + if (item2 != null) + { + bag[fromGrid] = item2; + } + else + { + bag.Remove(fromGrid); + } + UpdateBagInventoryPacket(); + } } } diff --git a/Campofinale/Game/Inventory/InventoryManager.cs b/Campofinale/Game/Inventory/InventoryManager.cs index 03851f3..87b1780 100644 --- a/Campofinale/Game/Inventory/InventoryManager.cs +++ b/Campofinale/Game/Inventory/InventoryManager.cs @@ -5,6 +5,7 @@ using Google.Protobuf.Collections; using System; using System.Collections.Generic; using System.Linq; +using System.Reflection.Metadata; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; @@ -135,11 +136,47 @@ namespace Campofinale.Game.Inventory item.amount -= amt; if(item.amount <= 0) { - items.items.Remove(item); - DatabaseManager.db.DeleteItem(item); + items.Remove(item); + } + else + { + this.owner.Send(new PacketScItemBagScopeModify(this.owner, item)); + items.UpdateBagInventoryPacket(); + } + } + + public bool ConsumeItem(string id, int amt) + { + Item item=items.FindInAll(i=>i.id== id); + if (item != null) + { + if(item.amount >= amt) + { + item.amount -= amt; + + if(item.amount < 1) + { + items.Remove(item); + } + else + { + this.owner.Send(new PacketScItemBagScopeModify(this.owner, item)); + items.UpdateBagInventoryPacket(); + } + return true; + } + else + { + int toConsume = amt - item.amount; + item.amount = 0; + items.Remove(item); + return ConsumeItem(id, toConsume); + } + } + else + { + return false; } - - this.owner.Send(new PacketScItemBagScopeModify(this.owner, item)); } public bool ConsumeItems(MapField costItemId2Count) { @@ -159,16 +196,8 @@ namespace Campofinale.Game.Inventory bool found = true; foreach (ItemInfo item in items) { - Item i= GetItemById(item.ResId); - if (i != null) - { - if(i.amount < item.ResCount) - { - found = false; - break; - } - } - else + int amount = this.items.GetItemAmount(item.ResId); + if(amount < item.ResCount) { found = false; break; @@ -176,14 +205,7 @@ namespace Campofinale.Game.Inventory } foreach (ItemInfo item in items) { - Item i = GetItemById(item.ResId); - if (i != null) - { - if (i.amount >= item.ResCount) - { - RemoveItem(i,item.ResCount); - } - } + ConsumeItem(item.ResId, item.ResCount); } return found; } @@ -199,5 +221,29 @@ namespace Campofinale.Game.Inventory return dir; } + + public void DropItemsBag(CsItemBagAbandonInBag req) + { + if(req.TargetObjectId == 0) + { + foreach (var i in req.GridCut) + { + Item item = items.bag[i.Key]; + item.amount -= i.Value; + if(item.amount <= 0) + { + items.bag.Remove(i.Key); + } + owner.sceneManager.CreateDrop(owner.position, new RewardTable.ItemBundle() + { + count=i.Value, + id=item.id, + }); + + } + + } + items.UpdateBagInventoryPacket(); + } } } diff --git a/Campofinale/Packets/Cs/HandleCsCharPotentialUnlock.cs b/Campofinale/Packets/Cs/HandleCsCharPotentialUnlock.cs index c51f230..943ae7e 100644 --- a/Campofinale/Packets/Cs/HandleCsCharPotentialUnlock.cs +++ b/Campofinale/Packets/Cs/HandleCsCharPotentialUnlock.cs @@ -26,6 +26,7 @@ namespace Campofinale.Packets.Cs if (character != null) { character.potential=req.Level; + //TODO consume Item ID ScCharPotentialUnlock unlock = new() diff --git a/Campofinale/Packets/Cs/HandleCsItemBagAbandonInBag.cs b/Campofinale/Packets/Cs/HandleCsItemBagAbandonInBag.cs new file mode 100644 index 0000000..990c527 --- /dev/null +++ b/Campofinale/Packets/Cs/HandleCsItemBagAbandonInBag.cs @@ -0,0 +1,27 @@ +using Campofinale.Network; +using Campofinale.Packets.Sc; +using Campofinale.Protocol; +using Google.Protobuf; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace Campofinale.Packets.Cs +{ + public class HandleCsItemBagAbandonInBag + { + + [Server.Handler(CsMsgId.CsItemBagAbandonInBag)] + public static void Handle(Player session, CsMsgId cmdId, Packet packet) + { + CsItemBagAbandonInBag req = packet.DecodeBody(); + session.inventoryManager.DropItemsBag(req); + } + + } +} diff --git a/Campofinale/Packets/Cs/HandleCsItemBagMoveInBag.cs b/Campofinale/Packets/Cs/HandleCsItemBagMoveInBag.cs new file mode 100644 index 0000000..6860e58 --- /dev/null +++ b/Campofinale/Packets/Cs/HandleCsItemBagMoveInBag.cs @@ -0,0 +1,27 @@ +using Campofinale.Network; +using Campofinale.Packets.Sc; +using Campofinale.Protocol; +using Google.Protobuf; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace Campofinale.Packets.Cs +{ + public class HandleCsItemBagMoveInBag + { + + [Server.Handler(CsMsgId.CsItemBagMoveInBag)] + public static void Handle(Player session, CsMsgId cmdId, Packet packet) + { + CsItemBagMoveInBag req = packet.DecodeBody(); + session.inventoryManager.items.MoveBagItem(req.FromGrid, req.ToGrid); + } + + } +} diff --git a/Campofinale/Packets/Sc/PacketScItemBagScopeSync.cs b/Campofinale/Packets/Sc/PacketScItemBagScopeSync.cs index 7cd2dfc..d226aba 100644 --- a/Campofinale/Packets/Sc/PacketScItemBagScopeSync.cs +++ b/Campofinale/Packets/Sc/PacketScItemBagScopeSync.cs @@ -114,6 +114,7 @@ namespace Campofinale.Packets.Sc proto.Bag = null; } proto.Depot.Add(i, new ScdItemDepot()); + if(proto.Bag!=null) foreach (var item in client.inventoryManager.items.bag) { proto.Bag.Grids.Add(new ScdItemGrid() diff --git a/Campofinale/Player.cs b/Campofinale/Player.cs index afc1eef..258b4bb 100644 --- a/Campofinale/Player.cs +++ b/Campofinale/Player.cs @@ -163,9 +163,11 @@ namespace Campofinale curStamina = data.curStamina; nextRecoverTime=data.nextRecoverTime; if (data.gender > 0) gender = data.gender; + LoadCharacters(); mails = DatabaseManager.db.LoadMails(roleId); inventoryManager.Load(); + if (data.bag != null) inventoryManager.items.bag = data.bag; spaceshipManager.Load(); if (data.scenes != null) {