Inventory management focused game written in Godot / C#
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
1.9 KiB

public partial class ItemManager : Node
{
public Dictionary<uint, Item> TrackedItems { get; } = [];
public override void _Ready()
{
var items = GetParent().FindChildren("*", "res://objects/Item.cs", owned: false).Cast<Item>();
foreach (var item in items) Add(item);
}
public void Add(Item item)
{
if (item.Manager != null) throw new ArgumentException(
$"Item '{item.GetPath()}' is already part of another scene");
// Generate a random, unused id for this item.
uint id; do { id = Randi(); } while (TrackedItems.ContainsKey(id));
TrackedItems.Add(id, item);
item.Manager = this;
item.TrackingId = id;
}
public void Remove(Item item)
{
if (item.Manager != this) throw new ArgumentException(
$"Item '{item.GetPath()}' is not part of this scene");
TrackedItems.Remove(item.TrackingId);
item.Manager = null;
item.TrackingId = 0;
}
// FIXME: This should be fixed in 4.3 and thus not required anymore?
// FIXME: Don't actually rely on item path, use its TrackingId.
// https://github.com/godotengine/godot/issues/85883
internal enum RequestFunc { RequestPickup, RequestPlace, RequestThrow }
internal enum AcceptFunc { AcceptPickup, AcceptPlace, AcceptThrow }
[Rpc(RpcMode.AnyPeer)]
internal void RelayRequest(NodePath itemPath, RequestFunc func, Godot.Collections.Array args)
{
var item = this.GetNodeOrThrow<Item>(itemPath);
var callable = new Callable(item, func.ToString());
callable.Call(args.ToArray());
}
[Rpc(CallLocal = true)]
internal void RelayAccept(NodePath itemPath, AcceptFunc func, Godot.Collections.Array args)
{
var item = this.GetNodeOrThrow<Item>(itemPath);
if (GetMultiplayerAuthority() != item.GetMultiplayerAuthority())
throw new InvalidOperationException(
$"Item {item.GetPath()} not owned by correct player");
var callable = new Callable(item, func.ToString());
callable.Call(args.ToArray());
}
}