Refactor stats

This commit is contained in:
2025-10-22 16:24:07 -07:00
parent 6ec45c4805
commit f0c4e65783
77 changed files with 565 additions and 372 deletions

View File

@@ -0,0 +1,63 @@
using Chickensoft.Collections;
using System;
using Zennysoft.Ma.Adapter;
namespace Zennysoft.Game.Ma;
public class AttackComponent : IAttackComponent
{
public IAutoProp<int> CurrentAttack => _currentAttack;
public IAutoProp<int> MaximumAttack => _maximumAttack;
public IAutoProp<int> BonusAttack => _bonusAttack;
public int TotalAttack => CurrentAttack.Value + BonusAttack.Value;
private readonly AutoProp<int> _currentAttack;
private readonly AutoProp<int> _maximumAttack;
private readonly AutoProp<int> _bonusAttack;
public AttackComponent(int attackValue)
{
_maximumAttack = new AutoProp<int>(attackValue);
_currentAttack = new AutoProp<int>(attackValue);
_bonusAttack = new AutoProp<int>(0);
}
public void Restore(int restoreAmount)
{
var cappedAmount = Math.Min(restoreAmount + _currentAttack.Value, _maximumAttack.Value);
_currentAttack.OnNext(cappedAmount);
}
public void Reduce(int reduceAmount)
{
var cappedAmount = Math.Max(_currentAttack.Value - reduceAmount, 0);
_currentAttack.OnNext(cappedAmount);
}
public void SetAttack(int attack)
{
var cappedAmount = Math.Min(attack, _maximumAttack.Value);
_currentAttack.OnNext(cappedAmount);
}
public void RaiseMaximumAttack(int raiseAmount)
{
_maximumAttack.OnNext(raiseAmount);
Restore(raiseAmount);
}
public void RaiseBonusAttack(int raiseAmount)
{
_bonusAttack.OnNext(_bonusAttack.Value + raiseAmount);
}
public void ResetBonusAttack()
{
_bonusAttack.OnNext(0);
}
}

View File

@@ -0,0 +1 @@
uid://ctyq0v5nsmyv4

View File

@@ -0,0 +1,63 @@
using Chickensoft.Collections;
using System;
using Zennysoft.Ma.Adapter;
namespace Zennysoft.Game.Ma;
public class DefenseComponent : IDefenseComponent
{
public IAutoProp<int> CurrentDefense => _currentDefense;
public IAutoProp<int> MaximumDefense => _maximumDefense;
public IAutoProp<int> BonusDefense => _bonusDefense;
private readonly AutoProp<int> _currentDefense;
private readonly AutoProp<int> _maximumDefense;
private readonly AutoProp<int> _bonusDefense;
public int TotalDefense => CurrentDefense.Value + BonusDefense.Value;
public DefenseComponent(int defenseValue)
{
_maximumDefense = new AutoProp<int>(defenseValue);
_currentDefense = new AutoProp<int>(defenseValue);
_bonusDefense = new AutoProp<int>(0);
}
public void Restore(int restoreAmount)
{
var cappedAmount = Math.Min(restoreAmount + _currentDefense.Value, _maximumDefense.Value);
_currentDefense.OnNext(cappedAmount);
}
public void Reduce(int reduceAmount)
{
var cappedAmount = Math.Max(_currentDefense.Value - reduceAmount, 0);
_currentDefense.OnNext(cappedAmount);
}
public void SetDefense(int attack)
{
var cappedAmount = Math.Min(attack, _maximumDefense.Value);
_currentDefense.OnNext(cappedAmount);
}
public void RaiseMaximumDefense(int raiseAmount)
{
_maximumDefense.OnNext(raiseAmount);
Restore(raiseAmount);
}
public void RaiseBonusDefense(int raiseAmount)
{
_bonusDefense.OnNext(_bonusDefense.Value + raiseAmount);
}
public void ResetBonusDefense()
{
_bonusDefense.OnNext(0);
}
}

View File

@@ -0,0 +1 @@
uid://c0ynebyuj4jwe

View File

@@ -0,0 +1,45 @@
using Chickensoft.Collections;
using Zennysoft.Ma.Adapter;
namespace Zennysoft.Game.Ma;
public class EquipmentComponent : IEquipmentComponent
{
public IAutoProp<EquipableItem> EquippedWeapon => _equippedWeapon;
public IAutoProp<EquipableItem> EquippedArmor => _equippedArmor;
public IAutoProp<EquipableItem> EquippedAccessory => _equippedAccessory;
public AutoProp<EquipableItem> _equippedWeapon;
public AutoProp<EquipableItem> _equippedArmor;
public AutoProp<EquipableItem> _equippedAccessory;
public EquipmentComponent()
{
_equippedWeapon = new AutoProp<EquipableItem>(new Weapon());
_equippedArmor = new AutoProp<EquipableItem>(new Armor());
_equippedAccessory = new AutoProp<EquipableItem>(new Accessory());
}
public void Equip(EquipableItem equipable)
{
if (equipable is Weapon weapon)
_equippedWeapon.OnNext(weapon);
if (equipable is Armor armor)
_equippedArmor.OnNext(armor);
if (equipable is Accessory accessory)
_equippedAccessory.OnNext(accessory);
}
public void Unequip(EquipableItem equipable)
{
if (equipable is Weapon weapon)
_equippedWeapon.OnNext(new Weapon());
if (equipable is Armor armor)
_equippedArmor.OnNext(new Armor());
if (equipable is Accessory accessory)
_equippedAccessory.OnNext(new Accessory());
}
}

View File

@@ -0,0 +1 @@
uid://bntwm4big7gnm

View File

@@ -0,0 +1,56 @@
using Chickensoft.Collections;
using System;
using Zennysoft.Ma.Adapter;
namespace Zennysoft.Game.Ma;
public class ExperiencePointsComponent : IExperiencePointsComponent
{
public IAutoProp<int> CurrentExp => _currentExp;
public IAutoProp<int> ExpToNextLevel => _expToNextLevel;
public IAutoProp<double> ExpGainRate => _expGainRate;
public IAutoProp<int> Level => _level;
private readonly AutoProp<int> _currentExp;
private readonly AutoProp<int> _expToNextLevel;
private readonly AutoProp<double> _expGainRate;
private readonly AutoProp<int> _level;
public ExperiencePointsComponent()
{
var firstLevelExpRequirement = ExpToNextLevelCalculation(1);
_expToNextLevel = new AutoProp<int>(firstLevelExpRequirement);
_currentExp = new AutoProp<int>(0);
_expGainRate = new AutoProp<double>(1.0);
_level = new AutoProp<int>(1);
}
public void Gain(int baseExpGain)
{
var modifiedExpGain = baseExpGain * _expGainRate.Value;
var newCurrentExpTotal = modifiedExpGain + _currentExp.Value;
while (modifiedExpGain + _currentExp.Value >= _expToNextLevel.Value)
LevelUp();
var cappedAmount = Math.Min(baseExpGain + _currentExp.Value, _expToNextLevel.Value);
_currentExp.OnNext(cappedAmount);
}
public void LevelUp()
{
_level.OnNext(_level.Value + 1);
var expToNextLevel = ExpToNextLevelCalculation(_level.Value);
_currentExp.OnNext(_currentExp.Value - _expToNextLevel.Value);
_expToNextLevel.OnNext(expToNextLevel);
}
private int ExpToNextLevelCalculation(int nextLevel)
{
return (int)(6.5 * nextLevel + 4.5 * Math.Pow(nextLevel, 2) + Math.Pow(nextLevel, 3));
}
}

View File

@@ -0,0 +1 @@
uid://dyxfogbt1th04

View File

@@ -0,0 +1,59 @@
using Chickensoft.Collections;
using Chickensoft.Serialization;
using System;
using Zennysoft.Ma.Adapter;
namespace Zennysoft.Game.Ma;
public class HealthComponent : IHealthComponent
{
[Save("current_hp")]
public IAutoProp<int> CurrentHP => _currentHP;
[Save("maximum_hp")]
public IAutoProp<int> MaximumHP => _maximumHP;
private readonly AutoProp<int> _currentHP;
private readonly AutoProp<int> _maximumHP;
public event Action? HealthReachedZero;
public event Action? DamageTaken;
public bool AtFullHealth => CurrentHP.Value == MaximumHP.Value;
public HealthComponent(int initialHP)
{
_maximumHP = new AutoProp<int>(initialHP);
_currentHP = new AutoProp<int>(initialHP);
}
public void Heal(int healAmount)
{
var cappedAmount = Math.Min(healAmount + _currentHP.Value, _maximumHP.Value);
_currentHP.OnNext(cappedAmount);
}
public void Damage(int damageAmount)
{
var cappedAmount = Math.Max(_currentHP.Value - damageAmount, 0);
_currentHP.OnNext(cappedAmount);
if (cappedAmount == 0)
HealthReachedZero?.Invoke();
else
DamageTaken?.Invoke();
}
public void SetHealth(int health)
{
var cappedAmount = Math.Min(health, _maximumHP.Value);
_currentHP.OnNext(cappedAmount);
}
public void RaiseMaximumHP(int raiseAmount)
{
_maximumHP.OnNext(raiseAmount);
Heal(raiseAmount);
}
}

View File

@@ -0,0 +1 @@
uid://c2e62jpounk1h

View File

@@ -0,0 +1,18 @@
using Chickensoft.Collections;
using Zennysoft.Ma.Adapter;
namespace Zennysoft.Game.Ma;
public class LuckComponent : ILuckComponent
{
public IAutoProp<int> Luck => _luck;
private AutoProp<int> _luck;
public LuckComponent(int initialLuck)
{
_luck = new AutoProp<int>(initialLuck);
}
public void SetLuck(int value) => _luck.OnNext(value);
}

View File

@@ -0,0 +1 @@
uid://dfrj2surolauj

View File

@@ -0,0 +1,48 @@
using Chickensoft.Collections;
using System;
using Zennysoft.Ma.Adapter;
namespace Zennysoft.Game.Ma;
public class VTComponent : IVTComponent
{
public IAutoProp<int> CurrentVT => _currentVT;
public IAutoProp<int> MaximumVT => _maximumVT;
private readonly AutoProp<int> _currentVT;
private readonly AutoProp<int> _maximumVT;
public bool AtFullVT => CurrentVT.Value == MaximumVT.Value;
public VTComponent(int initialVT)
{
_maximumVT = new AutoProp<int>(initialVT);
_currentVT = new AutoProp<int>(initialVT);
}
public void Restore(int restoreAmount)
{
var cappedAmount = Math.Min(restoreAmount + _currentVT.Value, _maximumVT.Value);
_currentVT.OnNext(cappedAmount);
}
public void Reduce(int reduceAmount)
{
var cappedAmount = Math.Max(_currentVT.Value - reduceAmount, 0);
_currentVT.OnNext(cappedAmount);
}
public void SetVT(int vt)
{
var cappedAmount = Math.Min(vt, _maximumVT.Value);
_currentVT.OnNext(cappedAmount);
}
public void RaiseMaximumVT(int raiseAmount)
{
_maximumVT.OnNext(raiseAmount);
Restore(raiseAmount);
}
}

View File

@@ -0,0 +1 @@
uid://b0tagp4amvy2v