Add attribute system with core stats and gameplay components
This commit is contained in:
31
GameCore/Attributes/Attribute.cs
Normal file
31
GameCore/Attributes/Attribute.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace GameCore.Attributes;
|
||||
|
||||
/// <summary>
|
||||
/// Defines all possible stats an entity can have.
|
||||
/// </summary>
|
||||
public enum Attribute
|
||||
{
|
||||
// Core Stats
|
||||
Health,
|
||||
MaxHealth,
|
||||
Armor,
|
||||
MoveSpeed,
|
||||
Acceleration,
|
||||
Friction,
|
||||
JumpHeight,
|
||||
|
||||
// Combat Stats
|
||||
Damage,
|
||||
AttackSpeed,
|
||||
AttackRange,
|
||||
MeleeDamage, // Multiplier
|
||||
RangedDamage, // Multiplier
|
||||
|
||||
// Progression
|
||||
Level,
|
||||
Experience,
|
||||
ExperienceToNextLevel,
|
||||
|
||||
// Misc
|
||||
Luck
|
||||
}
|
||||
42
GameCore/Attributes/AttributeComponent.cs
Normal file
42
GameCore/Attributes/AttributeComponent.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using GameCore.ECS.Interfaces;
|
||||
|
||||
namespace GameCore.Attributes;
|
||||
|
||||
/// <summary>
|
||||
/// A component that stores all gameplay-relevant stats for an entity.
|
||||
/// This design is adapted directly from the excellent CharacterAttributes class
|
||||
/// in the 'broberry' project. It's a flexible, data-driven way to manage stats.
|
||||
/// </summary>
|
||||
public class AttributeComponent : IComponent
|
||||
{
|
||||
public readonly Dictionary<Attribute, float> BaseValues = new();
|
||||
public readonly Dictionary<Attribute, float> CurrentValues = new();
|
||||
|
||||
public event Action<Attribute, float>? OnAttributeChanged;
|
||||
|
||||
public void SetBaseValue(Attribute attr, float value)
|
||||
{
|
||||
BaseValues[attr] = value;
|
||||
SetCurrentValue(attr, value);
|
||||
}
|
||||
|
||||
public float GetValue(Attribute attr)
|
||||
{
|
||||
return CurrentValues.GetValueOrDefault(attr, 0f);
|
||||
}
|
||||
|
||||
public void ModifyValue(Attribute attr, float delta)
|
||||
{
|
||||
var newValue = GetValue(attr) + delta;
|
||||
SetCurrentValue(attr, newValue);
|
||||
}
|
||||
|
||||
public void SetCurrentValue(Attribute attr, float value, bool force = false)
|
||||
{
|
||||
if (CurrentValues.TryGetValue(attr, out var oldValue) && !(System.Math.Abs(oldValue - value) > 0.001f) &&
|
||||
!force) return;
|
||||
|
||||
CurrentValues[attr] = value;
|
||||
OnAttributeChanged?.Invoke(attr, value);
|
||||
}
|
||||
}
|
||||
23
GameCore/Attributes/AttributeSystem.cs
Normal file
23
GameCore/Attributes/AttributeSystem.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using GameCore.ECS;
|
||||
using GameCore.ECS.Interfaces;
|
||||
|
||||
namespace GameCore.Attributes;
|
||||
|
||||
public class AttributeSystem : ISystem
|
||||
{
|
||||
public void Update(World world, float deltaTime)
|
||||
{
|
||||
var entities = world.GetEntitiesWith<AttributeComponent>();
|
||||
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
var attributes = world.GetComponent<AttributeComponent>(entity);
|
||||
if (attributes == null) continue;
|
||||
|
||||
var maxHealth = attributes.GetValue(Attribute.MaxHealth);
|
||||
var currentHealth = attributes.GetValue(Attribute.Health);
|
||||
|
||||
if (currentHealth > maxHealth) attributes.SetCurrentValue(Attribute.Health, maxHealth);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user