Add LightFootedEffect and StatusManager for player capabilities management

This commit is contained in:
2025-12-12 22:35:39 +01:00
parent 3774fb9900
commit 1cfcd09928
11 changed files with 140 additions and 2 deletions

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: abcaa49aec2c42b49a76184f29afe8c5
timeCreated: 1765574893

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6787efe77d5b42eabca4db1f4e8f9601
timeCreated: 1765575039

View File

@@ -0,0 +1,33 @@
namespace Core.Domain.Status.Effects
{
public class LightFootedEffect : IStatusEffect
{
private float _duration;
public bool IsExpired => _duration <= 0;
public LightFootedEffect(float duration)
{
_duration = duration;
}
public void Tick(float deltaTime)
{
_duration -= deltaTime;
}
public void ModifyCapabilities(ref PlayerCapabilities caps)
{
caps.CanTriggerDecay = false;
caps.SpeedMultiplier = 1.2f;
}
public void OnApply()
{
}
public void OnRemove()
{
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3569c07e1bba489d8835de24488cfef8
timeCreated: 1765575047

View File

@@ -0,0 +1,11 @@
namespace Core.Domain.Status
{
public interface IStatusEffect
{
bool IsExpired { get; }
void Tick(float deltaTime);
void ModifyCapabilities(ref PlayerCapabilities caps);
void OnApply();
void OnRemove();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 08db161381444423960b7deec94f48c1
timeCreated: 1765574975

View File

@@ -0,0 +1,14 @@
namespace Core.Domain.Status
{
public struct PlayerCapabilities
{
public bool CanTriggerDecay;
public float SpeedMultiplier;
public static PlayerCapabilities Default => new PlayerCapabilities
{
CanTriggerDecay = true,
SpeedMultiplier = 1f
};
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6c868f630ebc4cccad39e452e03e1025
timeCreated: 1765574915

View File

@@ -0,0 +1,50 @@
using System.Collections.Generic;
namespace Core.Domain.Status
{
public class StatusManager
{
private readonly List<IStatusEffect> _activeEffects = new();
public PlayerCapabilities CurrentCapabilities { get; private set; }
public StatusManager()
{
Recalculate();
}
public void AddEffect(IStatusEffect effect)
{
_activeEffects.Add(effect);
effect.OnApply();
Recalculate();
}
public void Tick(float deltaTime)
{
for (var i = _activeEffects.Count - 1; i >= 0; i--)
{
var effect = _activeEffects[i];
effect.Tick(deltaTime);
if (!effect.IsExpired) continue;
effect.OnRemove();
_activeEffects.RemoveAt(i);
Recalculate();
}
}
private void Recalculate()
{
var caps = PlayerCapabilities.Default;
foreach (var effect in _activeEffects)
{
effect.ModifyCapabilities(ref caps);
}
CurrentCapabilities = caps;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8e8580a304be4347a63e7dc0060fdc7b
timeCreated: 1765575109

View File

@@ -1,4 +1,5 @@
using System; using System;
using Core.Domain.Status;
using KBCore.Refs; using KBCore.Refs;
using UnityEngine; using UnityEngine;
using UnityEngine.InputSystem; using UnityEngine.InputSystem;
@@ -24,6 +25,7 @@ namespace Infrastructure.Unity
private Vector2 _moveInput; private Vector2 _moveInput;
public Rigidbody Rigidbody => rb; public Rigidbody Rigidbody => rb;
public StatusManager Status { get; private set; }
private void OnEnable() private void OnEnable()
{ {
@@ -44,11 +46,17 @@ namespace Infrastructure.Unity
private void Awake() private void Awake()
{ {
_actions = new InputSystem_Actions(); _actions = new InputSystem_Actions();
Status = new StatusManager();
rb.freezeRotation = true; rb.freezeRotation = true;
rb.useGravity = true; rb.useGravity = true;
} }
private void Update()
{
Status.Tick(Time.deltaTime);
}
private void FixedUpdate() private void FixedUpdate()
{ {
HandleMovement(); HandleMovement();
@@ -57,6 +65,8 @@ namespace Infrastructure.Unity
private void HandleMovement() private void HandleMovement()
{ {
var currentSpeed = moveSpeed * Status.CurrentCapabilities.SpeedMultiplier;
var targetVelocity = Vector3.zero; var targetVelocity = Vector3.zero;
var snapAxis = Vector3.zero; var snapAxis = Vector3.zero;
@@ -64,12 +74,12 @@ namespace Infrastructure.Unity
{ {
if (Mathf.Abs(_moveInput.x) > Mathf.Abs(_moveInput.y)) if (Mathf.Abs(_moveInput.x) > Mathf.Abs(_moveInput.y))
{ {
targetVelocity = new Vector3(_moveInput.x > 0 ? moveSpeed : -moveSpeed, 0, 0); targetVelocity = new Vector3(_moveInput.x > 0 ? currentSpeed : -currentSpeed, 0, 0);
snapAxis = Vector3.forward; snapAxis = Vector3.forward;
} }
else else
{ {
targetVelocity = new Vector3(0, 0, _moveInput.y > 0 ? moveSpeed : -moveSpeed); targetVelocity = new Vector3(0, 0, _moveInput.y > 0 ? currentSpeed : -currentSpeed);
snapAxis = Vector3.right; snapAxis = Vector3.right;
} }
} }
@@ -107,6 +117,8 @@ namespace Infrastructure.Unity
private void DetectGround() private void DetectGround()
{ {
if (!Status.CurrentCapabilities.CanTriggerDecay) return;
if (Physics.Raycast(transform.position, Vector3.down, out var hit, groundCheckDistance, tileLayer)) if (Physics.Raycast(transform.position, Vector3.down, out var hit, groundCheckDistance, tileLayer))
{ {
if (hit.collider.TryGetComponent<TileViewAdapter>(out var tileAdapter)) if (hit.collider.TryGetComponent<TileViewAdapter>(out var tileAdapter))