bag saving, grid move and drop

This commit is contained in:
AlessandroCH 2025-03-11 20:11:05 +01:00
parent 2e1b633682
commit ed0d4252a7
10 changed files with 231 additions and 28 deletions

View File

@ -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)

View File

@ -43,6 +43,7 @@ namespace Campofinale.Database
public Dictionary<int, List<int>> bitsets = new();
public PlayerSafeZoneInfo savedSafeZone = new();
public Gender gender = Gender.GenFemale;
public Dictionary<int, Item> 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);
}

View File

@ -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<int, ulong>), new CustomDictionarySerializer<int, ulong>());
BsonSerializer.RegisterSerializer(typeof(Dictionary<int, List<int>>), new CustomDictionarySerializer<int, List<int>>());
BsonSerializer.RegisterSerializer(typeof(Dictionary<int, Item>), new CustomDictionarySerializer<int, Item>());
RegisterSubclasses<FComponent>();
Logger.Print("Connecting to MongoDB...");
try

View File

@ -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<Item> FindAll(Predicate<Item> 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;
}
///<summary>
///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
///</summary>
@ -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;
}
}
}
/// <summary>
/// Get the item amount from all depots
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public int GetItemAmount(string id)
{
int amt = 0;
Item item=Find(i=>i.id==id);
if (item != null)
{
amt += item.amount;
}
List<Item> 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;
}
/// <summary>
/// Move item from bag grid to another position
/// </summary>
/// <param name="fromGrid"></param>
/// <param name="toGrid"></param>
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();
}
}
}

View File

@ -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();
}
}
this.owner.Send(new PacketScItemBagScopeModify(this.owner, item));
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;
}
}
public bool ConsumeItems(MapField<string, ulong> 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();
}
}
}

View File

@ -26,6 +26,7 @@ namespace Campofinale.Packets.Cs
if (character != null)
{
character.potential=req.Level;
//TODO consume Item ID
ScCharPotentialUnlock unlock = new()

View File

@ -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<CsItemBagAbandonInBag>();
session.inventoryManager.DropItemsBag(req);
}
}
}

View File

@ -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<CsItemBagMoveInBag>();
session.inventoryManager.items.MoveBagItem(req.FromGrid, req.ToGrid);
}
}
}

View File

@ -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()

View File

@ -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)
{