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

@@ -7,7 +7,7 @@ public partial class AppLogic
public partial record State
{
[Meta]
public partial record MainMenu : State, IGet<Input.NewGame>, IGet<Input.EnemyViewerOpened>
public partial record MainMenu : State, IGet<Input.NewGame>, IGet<Input.LoadGame>, IGet<Input.EnemyViewerOpened>
{
public MainMenu()
{
@@ -16,6 +16,7 @@ public partial class AppLogic
public Transition On(in Input.NewGame input) => To<GameStarted>();
public Transition On(in Input.EnemyViewerOpened input) => To<EnemyViewer>();
public Transition On(in Input.LoadGame input) => To<LoadingSaveFile>();
}
}
}

View File

@@ -0,0 +1,11 @@
namespace Zennysoft.Ma.Adapter;
public enum ElementType
{
None,
Aeolic,
Telluric,
Hydric,
Igneous,
Ferrum
}

View File

@@ -0,0 +1,26 @@
using Chickensoft.Collections;
namespace Zennysoft.Ma.Adapter;
public interface IAttackComponent
{
public IAutoProp<int> CurrentAttack { get; }
public IAutoProp<int> MaximumAttack { get; }
public IAutoProp<int> BonusAttack { get; }
public int TotalAttack { get; }
public void Restore(int restoreAmount);
public void Reduce(int reduceAmount);
public void SetAttack(int attack);
public void RaiseMaximumAttack(int raiseAmount);
public void RaiseBonusAttack(int raiseAmount);
public void ResetBonusAttack();
}

View File

@@ -0,0 +1,26 @@
using Chickensoft.Collections;
namespace Zennysoft.Ma.Adapter;
public interface IDefenseComponent
{
public IAutoProp<int> CurrentDefense { get; }
public IAutoProp<int> MaximumDefense { get; }
public IAutoProp<int> BonusDefense { get; }
public int TotalDefense { get; }
public void Restore(int restoreAmount);
public void Reduce(int reduceAmount);
public void SetDefense(int attack);
public void RaiseMaximumDefense(int raiseAmount);
public void RaiseBonusDefense(int raiseAmount);
public void ResetBonusDefense();
}

View File

@@ -0,0 +1,16 @@
using Chickensoft.Collections;
using Zennysoft.Ma.Adapter;
namespace Zennysoft.Ma.Adapter;
public interface IEquipmentComponent
{
public IAutoProp<EquipableItem> EquippedWeapon { get; }
public IAutoProp<EquipableItem> EquippedArmor { get; }
public IAutoProp<EquipableItem> EquippedAccessory { get; }
public void Equip(EquipableItem equipable);
public void Unequip(EquipableItem equipable);
}

View File

@@ -0,0 +1,18 @@
using Chickensoft.Collections;
namespace Zennysoft.Ma.Adapter;
public interface IExperiencePointsComponent
{
public IAutoProp<int> CurrentExp { get; }
public IAutoProp<int> ExpToNextLevel { get; }
public IAutoProp<double> ExpGainRate { get; }
public IAutoProp<int> Level { get; }
public void Gain(int baseExpGain);
public void LevelUp();
}

View File

@@ -0,0 +1,26 @@
using Chickensoft.Collections;
using Chickensoft.Serialization;
namespace Zennysoft.Ma.Adapter;
public interface IHealthComponent
{
[Save("current_hp")]
public IAutoProp<int> CurrentHP { get; }
[Save("maximum_hp")]
public IAutoProp<int> MaximumHP { get; }
public event Action? HealthReachedZero;
public event Action? DamageTaken;
public bool AtFullHealth { get; }
public void Heal(int healAmount);
public void Damage(int damageAmount);
public void SetHealth(int health);
public void RaiseMaximumHP(int raiseAmount);
}

View File

@@ -0,0 +1,10 @@
using Chickensoft.Collections;
namespace Zennysoft.Ma.Adapter;
public interface ILuckComponent
{
public IAutoProp<int> Luck { get; }
public void SetLuck(int value);
}

View File

@@ -0,0 +1,20 @@
using Chickensoft.Collections;
namespace Zennysoft.Ma.Adapter;
public interface IVTComponent
{
public IAutoProp<int> CurrentVT { get; }
public IAutoProp<int> MaximumVT { get; }
public bool AtFullVT { get; }
public void Restore(int restoreAmount);
public void Reduce(int reduceAmount);
public void SetVT(int vt);
public void RaiseMaximumVT(int raiseAmount);
}

View File

@@ -1,11 +1,10 @@
using Godot;
using Chickensoft.GodotNodeInterfaces;
using System.Collections.Immutable;
using Zennysoft.Game.Implementation.Components;
using Zennysoft.Game.Ma;
namespace Zennysoft.Ma.Adapter.Entity
{
public interface IEnemy
public interface IEnemy : ICharacterBody3D
{
public void Activate();
@@ -17,19 +16,15 @@ namespace Zennysoft.Ma.Adapter.Entity
public void ReturnToDefaultState();
public void TakeDamage(int damage);
public void SetTarget(Vector3 targetPosition);
public void SetEnemyPosition(Vector3 position);
public void LookAtTarget(Vector3 target);
public IDungeonRoom GetCurrentRoom(ImmutableList<IDungeonRoom> dungeonRooms);
public AttackComponent AttackComponent { get; }
public void MoveEnemyToNewRoom(IDungeonRoom newRoom);
public DefenseComponent DefenseComponent { get; }
public IHealthComponent HealthComponent { get; }
public IAttackComponent AttackComponent { get; }
public IDefenseComponent DefenseComponent { get; }
public int InitialHP { get; }

View File

@@ -1,18 +0,0 @@
using Chickensoft.Introspection;
using Chickensoft.Serialization;
using Zennysoft.Game.Ma;
namespace Zennysoft.Ma.Adapter;
[Meta, Id("game_data")]
public partial record GameData
{
[Save("player_data")]
public required PlayerData PlayerData { get; init; }
[Save("map_data")]
public required MapData MapData { get; init; }
[Save("rescued_items")]
public required RescuedItemDatabase RescuedItems { get; init; }
}

View File

@@ -1,6 +1,7 @@
using Chickensoft.Collections;
using Godot;
using Zennysoft.Game.Abstractions;
using Zennysoft.Game.Implementation;
namespace Zennysoft.Ma.Adapter;

View File

@@ -19,11 +19,13 @@ public partial class GameState
public Transition On(in Input.ContinueGame input)
{
Output(new Output.InitializeGame());
Output(new Output.LoadGameFromFile());
return To<InGame>();
}
public Transition On(in Input.LoadGame input)
{
Output(new Output.InitializeGame());
Output(new Output.LoadGameFromFile());
return To<InGame>();
}

View File

@@ -1,4 +1,6 @@
namespace Zennysoft.Ma.Adapter;
using Zennysoft.Game.Implementation;
namespace Zennysoft.Ma.Adapter;
public interface IInventory
{

View File

@@ -1,6 +1,7 @@
using Chickensoft.Introspection;
using Chickensoft.Serialization;
using Zennysoft.Game.Abstractions;
using Zennysoft.Game.Implementation;
namespace Zennysoft.Ma.Adapter;

View File

@@ -22,3 +22,24 @@ public partial class BoxItemTagEnumContext : JsonSerializerContext;
[JsonSerializable(typeof(ElementType))]
public partial class ElementTypeEnumContext : JsonSerializerContext;
[JsonSerializable(typeof(IHealthComponent))]
public partial class HealthComponentContext : JsonSerializerContext;
[JsonSerializable(typeof(IVTComponent))]
public partial class VTComponentContext : JsonSerializerContext;
[JsonSerializable(typeof(IAttackComponent))]
public partial class AttackComponentContext : JsonSerializerContext;
[JsonSerializable(typeof(IDefenseComponent))]
public partial class DefenseComponentContext : JsonSerializerContext;
[JsonSerializable(typeof(IExperiencePointsComponent))]
public partial class ExperiencePointsComponentContext : JsonSerializerContext;
[JsonSerializable(typeof(ILuckComponent))]
public partial class LuckComponentContext : JsonSerializerContext;
[JsonSerializable(typeof(IEquipmentComponent))]
public partial class EquipmentComponentContext : JsonSerializerContext;

View File

@@ -1,9 +1,7 @@
using SimpleInjector;
using System.IO.Abstractions;
using Zennysoft.Game.Abstractions;
using Zennysoft.Game.Abstractions.Entity;
using Zennysoft.Game.Implementation;
using Zennysoft.Ma.Adapter.Entity;
namespace Zennysoft.Ma.Adapter;
@@ -12,8 +10,8 @@ public class Module
public static void Bootstrap(Container container)
{
container.RegisterSingleton<IFileSystem, FileSystem>();
container.RegisterSingleton<ISaveFileManager<GameData>, SaveFileManager<GameData>>();
container.RegisterSingleton<IMaSaveFileManager<GameData>, MaSaveFileManager<GameData>>();
container.RegisterSingleton<ISaveFileManager, SaveFileManager>();
container.RegisterSingleton<IMaSaveFileManager, MaSaveFileManager>();
container.RegisterSingleton<IGameRepo, GameRepo>();
container.RegisterSingleton<IGameState, GameState>();
container.RegisterSingleton<IDimmableAudioStreamPlayer, DimmableAudioStreamPlayer>();

View File

@@ -1,57 +1,39 @@
using Chickensoft.Collections;
using Godot;
using Godot;
using Zennysoft.Game.Abstractions;
using Zennysoft.Game.Implementation.Components;
namespace Zennysoft.Ma.Adapter;
public interface IPlayer : IKillable
{
public void InitializePlayerState();
public void Activate();
public void Deactivate();
public void Attack();
public void TakeDamage(Damage damage);
public void Knockback(float impulse);
public void LevelUp();
public void Move(float delta);
public void TeleportPlayer(Transform3D newTransform);
public void SetHealthTimerStatus(bool isActive);
public IInventory Inventory { get; }
public Vector3 CurrentPosition { get; }
public Basis CurrentBasis { get; }
public AutoProp<EquipableItem> EquippedWeapon { get; }
public IHealthComponent HealthComponent { get; }
public AutoProp<EquipableItem> EquippedArmor { get; }
public IVTComponent VTComponent { get; }
public AutoProp<EquipableItem> EquippedAccessory { get; }
public IAttackComponent AttackComponent { get; }
public void Equip(EquipableItem equipable);
public IDefenseComponent DefenseComponent { get; }
public void Unequip(EquipableItem equipable);
public IExperiencePointsComponent ExperiencePointsComponent { get; }
public HealthComponent HealthComponent { get; }
public ILuckComponent LuckComponent { get; }
public VTComponent VTComponent { get; }
public AttackComponent AttackComponent { get; }
public DefenseComponent DefenseComponent { get; }
public ExperiencePointsComponent ExperiencePointsComponent { get; }
public LuckComponent LuckComponent { get; }
public IEquipmentComponent EquipmentComponent { get; }
}

View File

@@ -1,17 +0,0 @@
using Chickensoft.Introspection;
using Chickensoft.Serialization;
using Zennysoft.Ma.Adapter;
namespace Zennysoft.Game.Ma;
[Meta, Id("player_data")]
public partial record PlayerData
{
[Save("player_inventory")]
public required IInventory Inventory { get; init; }
}
[Meta, Id("map_data")]
public partial record MapData
{
}

View File

@@ -4,28 +4,28 @@ using Zennysoft.Game.Abstractions;
namespace Zennysoft.Ma.Adapter;
public interface IMaSaveFileManager<T>
public interface IMaSaveFileManager
{
Task Save(T gameData);
Task Save<T>(T gameData);
Task<T?> Load();
Task<object?> Load();
}
public sealed class MaSaveFileManager<T> : IMaSaveFileManager<T>
public sealed class MaSaveFileManager : IMaSaveFileManager
{
private readonly ISaveFileManager<T> _saveFileManager;
private readonly ISaveFileManager _saveFileManager;
private ImmutableList<IJsonTypeInfoResolver> _converters;
public MaSaveFileManager(ISaveFileManager<T> saveFileManager)
public MaSaveFileManager(ISaveFileManager saveFileManager)
{
_saveFileManager = saveFileManager;
_converters = [WeaponTagEnumContext.Default, ItemTagEnumContext.Default, ElementTypeEnumContext.Default, AccessoryTagEnumContext.Default, ThrowableItemTagEnumContext.Default, UsableItemTagEnumContext.Default, BoxItemTagEnumContext.Default];
_converters = [HealthComponentContext.Default, WeaponTagEnumContext.Default, ItemTagEnumContext.Default, ElementTypeEnumContext.Default, AccessoryTagEnumContext.Default, ThrowableItemTagEnumContext.Default, UsableItemTagEnumContext.Default, BoxItemTagEnumContext.Default];
}
public async Task Save(T gameData)
public async Task Save<T>(T gameData)
{
await _saveFileManager.WriteToFile(gameData, [.. _converters]);
}
public async Task<T?> Load() => await _saveFileManager.ReadFromFile([.. _converters]);
public async Task<object?> Load() => await _saveFileManager.ReadFromFile([.. _converters]);
}

View File

@@ -1,5 +1,6 @@
using Chickensoft.Introspection;
using Chickensoft.LogicBlocks;
using Zennysoft.Game.Implementation;
namespace Zennysoft.Ma.Adapter;

View File

@@ -1,4 +1,5 @@
using Zennysoft.Game.Ma;
using Zennysoft.Game.Implementation;
using Zennysoft.Game.Ma;
namespace Zennysoft.Ma.Adapter;
public partial class InGameUILogic

View File

@@ -7,9 +7,9 @@
</PropertyGroup>
<ItemGroup>
<Compile Remove="Game\state\states\**" />
<EmbeddedResource Remove="Game\state\states\**" />
<None Remove="Game\state\states\**" />
<Compile Remove="Game\state\states\**" />
<EmbeddedResource Remove="Game\state\states\**" />
<None Remove="Game\state\states\**" />
</ItemGroup>
<ItemGroup>
@@ -29,7 +29,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Actions\" />
<Folder Include="Actions\" />
</ItemGroup>
</Project>