Implement inventory system with item management and pickup functionality

This commit is contained in:
2025-10-13 18:29:50 +02:00
parent ce3596efaa
commit 56ffa8e126
10 changed files with 156 additions and 0 deletions

View File

@@ -27,6 +27,8 @@ public class WeaponSystem : ISystem
if (input.IsFiring && weapon.CooldownTimer <= 0f)
{
// Check for ammo if applicable
var context = new EffectContext { World = world, Owner = entity };
foreach (var effect in weapon.OnFireEffects) effect.Execute(context);

View File

@@ -0,0 +1,11 @@
using GameCore.ECS;
using GameCore.Events.Interfaces;
using GameCore.Inventory;
namespace GameCore.Events;
public readonly struct AddItemToInventoryEvent(Entity target, Item item) : IEvent
{
public readonly Entity Target = target;
public readonly Item Item = item;
}

View File

@@ -0,0 +1,7 @@
using GameCore.Events.Interfaces;
namespace GameCore.Events;
public readonly struct PlayerJumpEvent : IEvent
{
}

View File

@@ -0,0 +1,46 @@
using GameCore.ECS.Interfaces;
namespace GameCore.Inventory;
public class InventoryComponent : IComponent
{
private readonly Dictionary<string, Item> _items = new();
public bool AddItem(Item itemToAdd)
{
if (_items.TryGetValue(itemToAdd.ItemId, out var exisitingItem))
{
exisitingItem.Quantity += itemToAdd.Quantity;
_items[itemToAdd.ItemId] = exisitingItem;
}
else
{
_items.Add(itemToAdd.ItemId, itemToAdd);
}
return true;
}
public bool RemoveItem(string itemId, int quantity)
{
if (!_items.TryGetValue(itemId, out var existingItem) || existingItem.Quantity < quantity) return false;
existingItem.Quantity -= quantity;
if (existingItem.Quantity <= 0)
_items.Remove(itemId);
else
_items[itemId] = existingItem;
return true;
}
public int GetItemCount(string itemId)
{
return _items.TryGetValue(itemId, out var existingItem) ? existingItem.Quantity : 0;
}
public bool HasItem(string itemId, int quantity = 1)
{
return GetItemCount(itemId) >= quantity;
}
}

View File

@@ -0,0 +1,26 @@
using GameCore.ECS;
using GameCore.ECS.Interfaces;
using GameCore.Events;
namespace GameCore.Inventory;
public class InventorySystem : ISystem
{
private readonly World _world;
public InventorySystem(World world)
{
_world = world;
_world.Subscribe<AddItemToInventoryEvent>(OnAddItem);
}
public void Update(World world, float deltaTime)
{
}
private void OnAddItem(AddItemToInventoryEvent e)
{
var inventory = _world.GetComponent<InventoryComponent>(e.Target);
inventory?.AddItem(e.Item);
}
}

View File

@@ -0,0 +1,7 @@
namespace GameCore.Inventory;
public struct Item(string itemId, int quantity)
{
public string ItemId { get; set; } = itemId;
public int Quantity { get; set; } = quantity;
}

View File

@@ -0,0 +1,10 @@
using GameCore.ECS.Interfaces;
namespace GameCore.Inventory;
public class PickupComponent : IComponent
{
public string ItemId { get; set; }
public int Quantity { get; set; } = 1;
public bool IsInstantUse { get; set; } = false;
}

View File

@@ -0,0 +1,36 @@
using GameCore.Combat;
using GameCore.ECS;
using GameCore.ECS.Interfaces;
using GameCore.Events;
using GameCore.Physics;
using GameCore.Player;
namespace GameCore.Inventory;
public class PickupSystem : ISystem
{
public void Update(World world, float deltaTime)
{
var entitiesWithCollisions = world.GetEntitiesWith<CollisionEventComponent>();
var withCollisions = entitiesWithCollisions.ToList();
foreach (var entity in withCollisions)
{
if (world.GetComponent<PlayerComponent>(entity) == null) return;
var collision = world.GetComponent<CollisionEventComponent>(entity);
if (collision == null) continue;
var pickup = world.GetComponent<PickupComponent>(entity);
var inventory = world.GetComponent<InventoryComponent>(entity);
if (pickup == null || inventory == null) continue;
var item = new Item(pickup.ItemId, pickup.Quantity);
// In the future, handle IsInstantUse items here
world.PublishEvent(new AddItemToInventoryEvent(entity, item));
world.AddComponent(collision.OtherEntity, new DeathComponent());
}
foreach (var entity in withCollisions) world.RemoveComponent<CollisionEventComponent>(entity);
}
}

View File

@@ -1,6 +1,7 @@
using GameCore.Attributes;
using GameCore.ECS;
using GameCore.ECS.Interfaces;
using GameCore.Events;
using GameCore.Input;
using GameCore.Physics;
using Attribute = GameCore.Attributes.Attribute;
@@ -26,6 +27,7 @@ public class JumpSystem : ISystem
{
var jumpHeight = attributes.GetValue(Attribute.JumpHeight);
velocity.DesiredVelocity.Y = (float)System.Math.Sqrt(2f * world.Config.GravityStrength * jumpHeight);
world.PublishEvent(new PlayerJumpEvent());
}
}
}

View File

@@ -0,0 +1,9 @@
using GameCore.ECS;
using GameCore.ECS.Interfaces;
namespace GameCore.Physics;
public class CollisionEventComponent(Entity otherEntity) : IComponent
{
public readonly Entity OtherEntity = otherEntity;
}