[Stats] 캐릭터 스탯 시스템 구현
- 6가지 기본 스탯 추가 (STR, DEX, INT, VIT, WIS, SPI) - 스탯 수정자 시스템 (Flat, PercentAdd, PercentMult) - 파생 스탯 계산 (체력/마나/대미지/회복력) - 스킬 효과에 스탯 기반 대미지/회복량 적용 - 마나 비용 체크 및 소모 로직 추가
This commit is contained in:
113
Assets/Scripts/Stats/CharacterStat.cs
Normal file
113
Assets/Scripts/Stats/CharacterStat.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Colosseum.Stats
|
||||
{
|
||||
/// <summary>
|
||||
/// 개별 스탯 클래스. 기본값과 수정자를 관리하고 최종 값을 계산.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class CharacterStat
|
||||
{
|
||||
[UnityEngine.Tooltip("기본 값")]
|
||||
[UnityEngine.SerializeField] private float baseValue = 10f;
|
||||
|
||||
private readonly List<StatModifier> modifiers = new List<StatModifier>();
|
||||
private bool isDirty = true;
|
||||
private float cachedValue;
|
||||
|
||||
public float BaseValue
|
||||
{
|
||||
get => baseValue;
|
||||
set
|
||||
{
|
||||
baseValue = value;
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
public CharacterStat() { }
|
||||
|
||||
public CharacterStat(float baseValue)
|
||||
{
|
||||
this.baseValue = baseValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 최종 스탯 값. 수정자 적용 후 계산.
|
||||
/// </summary>
|
||||
public float FinalValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!isDirty) return cachedValue;
|
||||
|
||||
float finalValue = baseValue;
|
||||
|
||||
// 1. Flat 수정자 적용
|
||||
for (int i = 0; i < modifiers.Count; i++)
|
||||
{
|
||||
if (modifiers[i].Type == StatModType.Flat)
|
||||
finalValue += modifiers[i].Value;
|
||||
}
|
||||
|
||||
// 2. PercentAdd 수정자 적용 (합산 후 곱셈)
|
||||
float percentAdd = 0f;
|
||||
for (int i = 0; i < modifiers.Count; i++)
|
||||
{
|
||||
if (modifiers[i].Type == StatModType.PercentAdd)
|
||||
percentAdd += modifiers[i].Value;
|
||||
}
|
||||
finalValue *= (1f + percentAdd);
|
||||
|
||||
// 3. PercentMult 수정자 적용 (개별 곱셈)
|
||||
for (int i = 0; i < modifiers.Count; i++)
|
||||
{
|
||||
if (modifiers[i].Type == StatModType.PercentMult)
|
||||
finalValue *= modifiers[i].Value;
|
||||
}
|
||||
|
||||
cachedValue = finalValue;
|
||||
isDirty = false;
|
||||
return cachedValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 수정자 추가
|
||||
/// </summary>
|
||||
public void AddModifier(StatModifier modifier)
|
||||
{
|
||||
modifiers.Add(modifier);
|
||||
isDirty = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 수정자 제거
|
||||
/// </summary>
|
||||
public bool RemoveModifier(StatModifier modifier)
|
||||
{
|
||||
bool removed = modifiers.Remove(modifier);
|
||||
if (removed) isDirty = true;
|
||||
return removed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 특정 출처의 모든 수정자 제거
|
||||
/// </summary>
|
||||
public void RemoveAllModifiersFromSource(object source)
|
||||
{
|
||||
modifiers.RemoveAll(m => m.Source == source);
|
||||
isDirty = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 모든 수정자 제거
|
||||
/// </summary>
|
||||
public void ClearModifiers()
|
||||
{
|
||||
modifiers.Clear();
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user