diff --git a/Zennysoft.Game.Abstractions/Save/ISaveFileManager.cs b/Zennysoft.Game.Abstractions/Save/ISaveFileManager.cs index b3bbe34f..a6651487 100644 --- a/Zennysoft.Game.Abstractions/Save/ISaveFileManager.cs +++ b/Zennysoft.Game.Abstractions/Save/ISaveFileManager.cs @@ -1,15 +1,14 @@ -using System.Text.Json; -using System.Text.Json.Serialization.Metadata; +using System.Text.Json.Serialization.Metadata; namespace Zennysoft.Game.Abstractions; -public interface ISaveFileManager +public interface ISaveFileManager { - public Task WriteToFile(T gameData, params IJsonTypeInfoResolver?[] resolvers); + public Task WriteToFile(T gameData, params IJsonTypeInfoResolver?[] resolvers); - public Task WriteToFile(T gameData, string filePath, params IJsonTypeInfoResolver?[] resolvers); + public Task WriteToFile(T gameData, string filePath, params IJsonTypeInfoResolver?[] resolvers); - public Task ReadFromFile(params IJsonTypeInfoResolver?[] resolvers); + public Task ReadFromFile(params IJsonTypeInfoResolver?[] resolvers); - public Task ReadFromFile(string filePath, params IJsonTypeInfoResolver?[] resolvers); + public Task ReadFromFile(string filePath, params IJsonTypeInfoResolver?[] resolvers); } diff --git a/Zennysoft.Game.Godot.Implementation/Save/SaveFileManager.cs b/Zennysoft.Game.Godot.Implementation/Save/SaveFileManager.cs index 5e4d35bc..03ea774e 100644 --- a/Zennysoft.Game.Godot.Implementation/Save/SaveFileManager.cs +++ b/Zennysoft.Game.Godot.Implementation/Save/SaveFileManager.cs @@ -9,7 +9,7 @@ using Zennysoft.Game.Abstractions; namespace Zennysoft.Game.Implementation; -public class SaveFileManager : ISaveFileManager +public class SaveFileManager : ISaveFileManager { private readonly IFileSystem _fileSystem; private readonly JsonSerializerOptions _jsonOptions; @@ -36,14 +36,14 @@ public class SaveFileManager : ISaveFileManager } - public Task ReadFromFile(params IJsonTypeInfoResolver?[] resolvers) + public Task ReadFromFile(params IJsonTypeInfoResolver?[] resolvers) { if (!_fileSystem.File.Exists(_defaultSaveLocation)) throw new FileNotFoundException(); return ReadFromFile(_defaultSaveLocation, resolvers); } - public async Task ReadFromFile(string filePath, params IJsonTypeInfoResolver?[] resolvers) + public async Task ReadFromFile(string filePath, params IJsonTypeInfoResolver?[] resolvers) { if (!_fileSystem.File.Exists(filePath)) throw new FileNotFoundException(); @@ -52,15 +52,15 @@ public class SaveFileManager : ISaveFileManager var resolver = new SerializableTypeResolver(); _jsonOptions.TypeInfoResolver = JsonTypeInfoResolver.Combine([resolver, .. resolvers]); - return JsonSerializer.Deserialize(json, _jsonOptions); + return JsonSerializer.Deserialize(json, _jsonOptions); } - public Task WriteToFile(T gameData, params IJsonTypeInfoResolver?[] resolvers) + public Task WriteToFile(T gameData, params IJsonTypeInfoResolver?[] resolvers) { return WriteToFile(gameData, _defaultSaveLocation, resolvers); } - public async Task WriteToFile(T gameData, string filePath, params IJsonTypeInfoResolver?[] resolvers) + public async Task WriteToFile(T gameData, string filePath, params IJsonTypeInfoResolver?[] resolvers) { var resolver = new SerializableTypeResolver(); _jsonOptions.TypeInfoResolver = JsonTypeInfoResolver.Combine([resolver, .. resolvers]); diff --git a/Zennysoft.Game.Ma.Implementation/App/State/States/AppLogic.State.MainMenu.cs b/Zennysoft.Game.Ma.Implementation/App/State/States/AppLogic.State.MainMenu.cs index 61213927..75be175b 100644 --- a/Zennysoft.Game.Ma.Implementation/App/State/States/AppLogic.State.MainMenu.cs +++ b/Zennysoft.Game.Ma.Implementation/App/State/States/AppLogic.State.MainMenu.cs @@ -7,7 +7,7 @@ public partial class AppLogic public partial record State { [Meta] - public partial record MainMenu : State, IGet, IGet + public partial record MainMenu : State, IGet, IGet, IGet { public MainMenu() { @@ -16,6 +16,7 @@ public partial class AppLogic public Transition On(in Input.NewGame input) => To(); public Transition On(in Input.EnemyViewerOpened input) => To(); + public Transition On(in Input.LoadGame input) => To(); } } } diff --git a/Zennysoft.Game.Godot.Implementation/Components/ElementType.cs b/Zennysoft.Game.Ma.Implementation/Components/ElementType.cs similarity index 100% rename from Zennysoft.Game.Godot.Implementation/Components/ElementType.cs rename to Zennysoft.Game.Ma.Implementation/Components/ElementType.cs diff --git a/Zennysoft.Game.Ma.Implementation/Components/IAttackComponent.cs b/Zennysoft.Game.Ma.Implementation/Components/IAttackComponent.cs new file mode 100644 index 00000000..9fd99d55 --- /dev/null +++ b/Zennysoft.Game.Ma.Implementation/Components/IAttackComponent.cs @@ -0,0 +1,26 @@ +using Chickensoft.Collections; + +namespace Zennysoft.Ma.Adapter; + +public interface IAttackComponent +{ + public IAutoProp CurrentAttack { get; } + + public IAutoProp MaximumAttack { get; } + + public IAutoProp 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(); +} diff --git a/Zennysoft.Game.Ma.Implementation/Components/IDefenseComponent.cs b/Zennysoft.Game.Ma.Implementation/Components/IDefenseComponent.cs new file mode 100644 index 00000000..153df64a --- /dev/null +++ b/Zennysoft.Game.Ma.Implementation/Components/IDefenseComponent.cs @@ -0,0 +1,26 @@ +using Chickensoft.Collections; + +namespace Zennysoft.Ma.Adapter; + +public interface IDefenseComponent +{ + public IAutoProp CurrentDefense { get; } + + public IAutoProp MaximumDefense { get; } + + public IAutoProp 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(); +} diff --git a/Zennysoft.Game.Ma.Implementation/Components/IEquipmentComponent.cs b/Zennysoft.Game.Ma.Implementation/Components/IEquipmentComponent.cs new file mode 100644 index 00000000..b74d5c82 --- /dev/null +++ b/Zennysoft.Game.Ma.Implementation/Components/IEquipmentComponent.cs @@ -0,0 +1,16 @@ +using Chickensoft.Collections; +using Zennysoft.Ma.Adapter; + +namespace Zennysoft.Ma.Adapter; +public interface IEquipmentComponent +{ + public IAutoProp EquippedWeapon { get; } + + public IAutoProp EquippedArmor { get; } + + public IAutoProp EquippedAccessory { get; } + + public void Equip(EquipableItem equipable); + + public void Unequip(EquipableItem equipable); +} diff --git a/Zennysoft.Game.Ma.Implementation/Components/IExperiencePointsComponent.cs b/Zennysoft.Game.Ma.Implementation/Components/IExperiencePointsComponent.cs new file mode 100644 index 00000000..9e6d5c5e --- /dev/null +++ b/Zennysoft.Game.Ma.Implementation/Components/IExperiencePointsComponent.cs @@ -0,0 +1,18 @@ +using Chickensoft.Collections; + +namespace Zennysoft.Ma.Adapter; + +public interface IExperiencePointsComponent +{ + public IAutoProp CurrentExp { get; } + + public IAutoProp ExpToNextLevel { get; } + + public IAutoProp ExpGainRate { get; } + + public IAutoProp Level { get; } + + public void Gain(int baseExpGain); + + public void LevelUp(); +} diff --git a/Zennysoft.Game.Ma.Implementation/Components/IHealthComponent.cs b/Zennysoft.Game.Ma.Implementation/Components/IHealthComponent.cs new file mode 100644 index 00000000..fa1f2e5b --- /dev/null +++ b/Zennysoft.Game.Ma.Implementation/Components/IHealthComponent.cs @@ -0,0 +1,26 @@ +using Chickensoft.Collections; +using Chickensoft.Serialization; + +namespace Zennysoft.Ma.Adapter; + +public interface IHealthComponent +{ + [Save("current_hp")] + public IAutoProp CurrentHP { get; } + + [Save("maximum_hp")] + public IAutoProp 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); +} diff --git a/Zennysoft.Game.Ma.Implementation/Components/LuckComponent.cs b/Zennysoft.Game.Ma.Implementation/Components/LuckComponent.cs new file mode 100644 index 00000000..d9a7318e --- /dev/null +++ b/Zennysoft.Game.Ma.Implementation/Components/LuckComponent.cs @@ -0,0 +1,10 @@ +using Chickensoft.Collections; + +namespace Zennysoft.Ma.Adapter; + +public interface ILuckComponent +{ + public IAutoProp Luck { get; } + + public void SetLuck(int value); +} diff --git a/Zennysoft.Game.Ma.Implementation/Components/VTComponent.cs b/Zennysoft.Game.Ma.Implementation/Components/VTComponent.cs new file mode 100644 index 00000000..d37efb70 --- /dev/null +++ b/Zennysoft.Game.Ma.Implementation/Components/VTComponent.cs @@ -0,0 +1,20 @@ +using Chickensoft.Collections; + +namespace Zennysoft.Ma.Adapter; + +public interface IVTComponent +{ + public IAutoProp CurrentVT { get; } + + public IAutoProp 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); +} diff --git a/Zennysoft.Game.Ma.Implementation/Entity/IEnemy.cs b/Zennysoft.Game.Ma.Implementation/Entity/IEnemy.cs index 121c46bc..00085116 100644 --- a/Zennysoft.Game.Ma.Implementation/Entity/IEnemy.cs +++ b/Zennysoft.Game.Ma.Implementation/Entity/IEnemy.cs @@ -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 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; } diff --git a/Zennysoft.Game.Ma.Implementation/Item/EquipableItem.cs b/Zennysoft.Game.Ma.Implementation/Equipment/EquipableItem.cs similarity index 100% rename from Zennysoft.Game.Ma.Implementation/Item/EquipableItem.cs rename to Zennysoft.Game.Ma.Implementation/Equipment/EquipableItem.cs diff --git a/Zennysoft.Game.Ma.Implementation/Item/InventoryItem.cs b/Zennysoft.Game.Ma.Implementation/Equipment/InventoryItem.cs similarity index 100% rename from Zennysoft.Game.Ma.Implementation/Item/InventoryItem.cs rename to Zennysoft.Game.Ma.Implementation/Equipment/InventoryItem.cs diff --git a/Zennysoft.Game.Ma.Implementation/Item/Tags/AccessoryTag.cs b/Zennysoft.Game.Ma.Implementation/Equipment/Tags/AccessoryTag.cs similarity index 100% rename from Zennysoft.Game.Ma.Implementation/Item/Tags/AccessoryTag.cs rename to Zennysoft.Game.Ma.Implementation/Equipment/Tags/AccessoryTag.cs diff --git a/Zennysoft.Game.Ma.Implementation/Item/Tags/BoxItemTag.cs b/Zennysoft.Game.Ma.Implementation/Equipment/Tags/BoxItemTag.cs similarity index 100% rename from Zennysoft.Game.Ma.Implementation/Item/Tags/BoxItemTag.cs rename to Zennysoft.Game.Ma.Implementation/Equipment/Tags/BoxItemTag.cs diff --git a/Zennysoft.Game.Ma.Implementation/Item/Tags/ItemTag.cs b/Zennysoft.Game.Ma.Implementation/Equipment/Tags/ItemTag.cs similarity index 100% rename from Zennysoft.Game.Ma.Implementation/Item/Tags/ItemTag.cs rename to Zennysoft.Game.Ma.Implementation/Equipment/Tags/ItemTag.cs diff --git a/Zennysoft.Game.Ma.Implementation/Item/Tags/ThrowableItemTag.cs b/Zennysoft.Game.Ma.Implementation/Equipment/Tags/ThrowableItemTag.cs similarity index 100% rename from Zennysoft.Game.Ma.Implementation/Item/Tags/ThrowableItemTag.cs rename to Zennysoft.Game.Ma.Implementation/Equipment/Tags/ThrowableItemTag.cs diff --git a/Zennysoft.Game.Ma.Implementation/Item/Tags/UsableItemTag.cs b/Zennysoft.Game.Ma.Implementation/Equipment/Tags/UsableItemTag.cs similarity index 100% rename from Zennysoft.Game.Ma.Implementation/Item/Tags/UsableItemTag.cs rename to Zennysoft.Game.Ma.Implementation/Equipment/Tags/UsableItemTag.cs diff --git a/Zennysoft.Game.Ma.Implementation/Item/Tags/WeaponTag.cs b/Zennysoft.Game.Ma.Implementation/Equipment/Tags/WeaponTag.cs similarity index 100% rename from Zennysoft.Game.Ma.Implementation/Item/Tags/WeaponTag.cs rename to Zennysoft.Game.Ma.Implementation/Equipment/Tags/WeaponTag.cs diff --git a/Zennysoft.Game.Ma.Implementation/Game/GameData.cs b/Zennysoft.Game.Ma.Implementation/Game/GameData.cs deleted file mode 100644 index 6f4f4f5a..00000000 --- a/Zennysoft.Game.Ma.Implementation/Game/GameData.cs +++ /dev/null @@ -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; } -} diff --git a/Zennysoft.Game.Ma.Implementation/Game/GameRepo.cs b/Zennysoft.Game.Ma.Implementation/Game/GameRepo.cs index 0b64dfcd..b2228bba 100644 --- a/Zennysoft.Game.Ma.Implementation/Game/GameRepo.cs +++ b/Zennysoft.Game.Ma.Implementation/Game/GameRepo.cs @@ -1,6 +1,7 @@ using Chickensoft.Collections; using Godot; using Zennysoft.Game.Abstractions; +using Zennysoft.Game.Implementation; namespace Zennysoft.Ma.Adapter; diff --git a/Zennysoft.Game.Ma.Implementation/Game/state/gamestates/GameState.State.MainMenu..cs b/Zennysoft.Game.Ma.Implementation/Game/state/gamestates/GameState.State.MainMenu..cs index 4fb6bd5d..2ca3b02d 100644 --- a/Zennysoft.Game.Ma.Implementation/Game/state/gamestates/GameState.State.MainMenu..cs +++ b/Zennysoft.Game.Ma.Implementation/Game/state/gamestates/GameState.State.MainMenu..cs @@ -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(); } public Transition On(in Input.LoadGame input) { + Output(new Output.InitializeGame()); Output(new Output.LoadGameFromFile()); return To(); } diff --git a/Zennysoft.Game.Ma.Implementation/Item/IInventory.cs b/Zennysoft.Game.Ma.Implementation/Item/IInventory.cs index e7ab535f..8527c091 100644 --- a/Zennysoft.Game.Ma.Implementation/Item/IInventory.cs +++ b/Zennysoft.Game.Ma.Implementation/Item/IInventory.cs @@ -1,4 +1,6 @@ -namespace Zennysoft.Ma.Adapter; +using Zennysoft.Game.Implementation; + +namespace Zennysoft.Ma.Adapter; public interface IInventory { diff --git a/Zennysoft.Game.Ma.Implementation/Item/RescuedItemDatabase.cs b/Zennysoft.Game.Ma.Implementation/Item/RescuedItemDatabase.cs index 78760722..4967ab36 100644 --- a/Zennysoft.Game.Ma.Implementation/Item/RescuedItemDatabase.cs +++ b/Zennysoft.Game.Ma.Implementation/Item/RescuedItemDatabase.cs @@ -1,6 +1,7 @@ using Chickensoft.Introspection; using Chickensoft.Serialization; using Zennysoft.Game.Abstractions; +using Zennysoft.Game.Implementation; namespace Zennysoft.Ma.Adapter; diff --git a/Zennysoft.Game.Ma.Implementation/JsonConverters/EnumConverters.cs b/Zennysoft.Game.Ma.Implementation/JsonConverters/EnumConverters.cs index 4ddb3765..251f2e40 100644 --- a/Zennysoft.Game.Ma.Implementation/JsonConverters/EnumConverters.cs +++ b/Zennysoft.Game.Ma.Implementation/JsonConverters/EnumConverters.cs @@ -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; \ No newline at end of file diff --git a/Zennysoft.Game.Ma.Implementation/Module/Module.cs b/Zennysoft.Game.Ma.Implementation/Module/Module.cs index f3bbb5c5..460634dd 100644 --- a/Zennysoft.Game.Ma.Implementation/Module/Module.cs +++ b/Zennysoft.Game.Ma.Implementation/Module/Module.cs @@ -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(); - container.RegisterSingleton, SaveFileManager>(); - container.RegisterSingleton, MaSaveFileManager>(); + container.RegisterSingleton(); + container.RegisterSingleton(); container.RegisterSingleton(); container.RegisterSingleton(); container.RegisterSingleton(); diff --git a/Zennysoft.Game.Ma.Implementation/Player/IPlayer.cs b/Zennysoft.Game.Ma.Implementation/Player/IPlayer.cs index f264599f..8f4140ee 100644 --- a/Zennysoft.Game.Ma.Implementation/Player/IPlayer.cs +++ b/Zennysoft.Game.Ma.Implementation/Player/IPlayer.cs @@ -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 EquippedWeapon { get; } + public IHealthComponent HealthComponent { get; } - public AutoProp EquippedArmor { get; } + public IVTComponent VTComponent { get; } - public AutoProp 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; } } diff --git a/Zennysoft.Game.Ma.Implementation/Player/PlayerData.cs b/Zennysoft.Game.Ma.Implementation/Player/PlayerData.cs deleted file mode 100644 index f7e2c243..00000000 --- a/Zennysoft.Game.Ma.Implementation/Player/PlayerData.cs +++ /dev/null @@ -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 -{ -} diff --git a/Zennysoft.Game.Ma.Implementation/Save/MaSaveFileManager.cs b/Zennysoft.Game.Ma.Implementation/Save/MaSaveFileManager.cs index f52522bf..df7af0d8 100644 --- a/Zennysoft.Game.Ma.Implementation/Save/MaSaveFileManager.cs +++ b/Zennysoft.Game.Ma.Implementation/Save/MaSaveFileManager.cs @@ -4,28 +4,28 @@ using Zennysoft.Game.Abstractions; namespace Zennysoft.Ma.Adapter; -public interface IMaSaveFileManager +public interface IMaSaveFileManager { - Task Save(T gameData); + Task Save(T gameData); - Task Load(); + Task Load(); } -public sealed class MaSaveFileManager : IMaSaveFileManager +public sealed class MaSaveFileManager : IMaSaveFileManager { - private readonly ISaveFileManager _saveFileManager; + private readonly ISaveFileManager _saveFileManager; private ImmutableList _converters; - public MaSaveFileManager(ISaveFileManager 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 gameData) { await _saveFileManager.WriteToFile(gameData, [.. _converters]); } - public async Task Load() => await _saveFileManager.ReadFromFile([.. _converters]); + public async Task Load() => await _saveFileManager.ReadFromFile([.. _converters]); } diff --git a/Zennysoft.Game.Ma.Implementation/UI/InGameUI/InGameUILogic.State.cs b/Zennysoft.Game.Ma.Implementation/UI/InGameUI/InGameUILogic.State.cs index 326b49ff..58410f93 100644 --- a/Zennysoft.Game.Ma.Implementation/UI/InGameUI/InGameUILogic.State.cs +++ b/Zennysoft.Game.Ma.Implementation/UI/InGameUI/InGameUILogic.State.cs @@ -1,5 +1,6 @@ using Chickensoft.Introspection; using Chickensoft.LogicBlocks; +using Zennysoft.Game.Implementation; namespace Zennysoft.Ma.Adapter; diff --git a/Zennysoft.Game.Ma.Implementation/UI/InGameUI/state/InGameUILogic.Output.cs b/Zennysoft.Game.Ma.Implementation/UI/InGameUI/state/InGameUILogic.Output.cs index 97bcb9a6..b6b12f27 100644 --- a/Zennysoft.Game.Ma.Implementation/UI/InGameUI/state/InGameUILogic.Output.cs +++ b/Zennysoft.Game.Ma.Implementation/UI/InGameUI/state/InGameUILogic.Output.cs @@ -1,4 +1,5 @@ -using Zennysoft.Game.Ma; +using Zennysoft.Game.Implementation; +using Zennysoft.Game.Ma; namespace Zennysoft.Ma.Adapter; public partial class InGameUILogic diff --git a/Zennysoft.Game.Ma.Implementation/Zennysoft.Ma.Adapter.csproj b/Zennysoft.Game.Ma.Implementation/Zennysoft.Ma.Adapter.csproj index 8aa6b266..c7d6820a 100644 --- a/Zennysoft.Game.Ma.Implementation/Zennysoft.Ma.Adapter.csproj +++ b/Zennysoft.Game.Ma.Implementation/Zennysoft.Ma.Adapter.csproj @@ -7,9 +7,9 @@ - - - + + + @@ -29,7 +29,7 @@ - + diff --git a/Zennysoft.Game.Godot.Implementation/Components/AttackComponent.cs b/Zennysoft.Game.Ma/src/Components/AttackComponent.cs similarity index 80% rename from Zennysoft.Game.Godot.Implementation/Components/AttackComponent.cs rename to Zennysoft.Game.Ma/src/Components/AttackComponent.cs index 59f0909d..9a5a9070 100644 --- a/Zennysoft.Game.Godot.Implementation/Components/AttackComponent.cs +++ b/Zennysoft.Game.Ma/src/Components/AttackComponent.cs @@ -1,9 +1,10 @@ using Chickensoft.Collections; -using Godot; +using System; +using Zennysoft.Ma.Adapter; -namespace Zennysoft.Game.Implementation.Components; +namespace Zennysoft.Game.Ma; -public class AttackComponent +public class AttackComponent : IAttackComponent { public IAutoProp CurrentAttack => _currentAttack; @@ -49,4 +50,14 @@ public class AttackComponent _maximumAttack.OnNext(raiseAmount); Restore(raiseAmount); } + + public void RaiseBonusAttack(int raiseAmount) + { + _bonusAttack.OnNext(_bonusAttack.Value + raiseAmount); + } + + public void ResetBonusAttack() + { + _bonusAttack.OnNext(0); + } } diff --git a/Zennysoft.Game.Ma/src/Components/AttackComponent.cs.uid b/Zennysoft.Game.Ma/src/Components/AttackComponent.cs.uid new file mode 100644 index 00000000..efbb8b21 --- /dev/null +++ b/Zennysoft.Game.Ma/src/Components/AttackComponent.cs.uid @@ -0,0 +1 @@ +uid://ctyq0v5nsmyv4 diff --git a/Zennysoft.Game.Godot.Implementation/Components/DefenseComponent.cs b/Zennysoft.Game.Ma/src/Components/DefenseComponent.cs similarity index 92% rename from Zennysoft.Game.Godot.Implementation/Components/DefenseComponent.cs rename to Zennysoft.Game.Ma/src/Components/DefenseComponent.cs index 1e6c501e..21470112 100644 --- a/Zennysoft.Game.Godot.Implementation/Components/DefenseComponent.cs +++ b/Zennysoft.Game.Ma/src/Components/DefenseComponent.cs @@ -1,9 +1,10 @@ using Chickensoft.Collections; -using Godot; +using System; +using Zennysoft.Ma.Adapter; -namespace Zennysoft.Game.Implementation.Components; +namespace Zennysoft.Game.Ma; -public class DefenseComponent +public class DefenseComponent : IDefenseComponent { public IAutoProp CurrentDefense => _currentDefense; diff --git a/Zennysoft.Game.Ma/src/Components/DefenseComponent.cs.uid b/Zennysoft.Game.Ma/src/Components/DefenseComponent.cs.uid new file mode 100644 index 00000000..492ab49b --- /dev/null +++ b/Zennysoft.Game.Ma/src/Components/DefenseComponent.cs.uid @@ -0,0 +1 @@ +uid://c0ynebyuj4jwe diff --git a/Zennysoft.Game.Ma/src/Components/EquipmentComponent.cs b/Zennysoft.Game.Ma/src/Components/EquipmentComponent.cs new file mode 100644 index 00000000..ce257f25 --- /dev/null +++ b/Zennysoft.Game.Ma/src/Components/EquipmentComponent.cs @@ -0,0 +1,45 @@ +using Chickensoft.Collections; +using Zennysoft.Ma.Adapter; + +namespace Zennysoft.Game.Ma; +public class EquipmentComponent : IEquipmentComponent +{ + public IAutoProp EquippedWeapon => _equippedWeapon; + + public IAutoProp EquippedArmor => _equippedArmor; + + public IAutoProp EquippedAccessory => _equippedAccessory; + + public AutoProp _equippedWeapon; + + public AutoProp _equippedArmor; + + public AutoProp _equippedAccessory; + + public EquipmentComponent() + { + _equippedWeapon = new AutoProp(new Weapon()); + _equippedArmor = new AutoProp(new Armor()); + _equippedAccessory = new AutoProp(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()); + } +} diff --git a/Zennysoft.Game.Ma/src/Components/EquipmentComponent.cs.uid b/Zennysoft.Game.Ma/src/Components/EquipmentComponent.cs.uid new file mode 100644 index 00000000..e4ae678b --- /dev/null +++ b/Zennysoft.Game.Ma/src/Components/EquipmentComponent.cs.uid @@ -0,0 +1 @@ +uid://bntwm4big7gnm diff --git a/Zennysoft.Game.Godot.Implementation/Components/ExperiencePointsComponent.cs b/Zennysoft.Game.Ma/src/Components/ExperiencePointsComponent.cs similarity index 91% rename from Zennysoft.Game.Godot.Implementation/Components/ExperiencePointsComponent.cs rename to Zennysoft.Game.Ma/src/Components/ExperiencePointsComponent.cs index a13748d5..9cf65c2f 100644 --- a/Zennysoft.Game.Godot.Implementation/Components/ExperiencePointsComponent.cs +++ b/Zennysoft.Game.Ma/src/Components/ExperiencePointsComponent.cs @@ -1,8 +1,10 @@ using Chickensoft.Collections; +using System; +using Zennysoft.Ma.Adapter; -namespace Zennysoft.Game.Implementation.Components; +namespace Zennysoft.Game.Ma; -public class ExperiencePointsComponent +public class ExperiencePointsComponent : IExperiencePointsComponent { public IAutoProp CurrentExp => _currentExp; diff --git a/Zennysoft.Game.Ma/src/Components/ExperiencePointsComponent.cs.uid b/Zennysoft.Game.Ma/src/Components/ExperiencePointsComponent.cs.uid new file mode 100644 index 00000000..7f2640ef --- /dev/null +++ b/Zennysoft.Game.Ma/src/Components/ExperiencePointsComponent.cs.uid @@ -0,0 +1 @@ +uid://dyxfogbt1th04 diff --git a/Zennysoft.Game.Godot.Implementation/Components/HealthComponent.cs b/Zennysoft.Game.Ma/src/Components/HealthComponent.cs similarity index 85% rename from Zennysoft.Game.Godot.Implementation/Components/HealthComponent.cs rename to Zennysoft.Game.Ma/src/Components/HealthComponent.cs index 9b3d6efb..fa2befe2 100644 --- a/Zennysoft.Game.Godot.Implementation/Components/HealthComponent.cs +++ b/Zennysoft.Game.Ma/src/Components/HealthComponent.cs @@ -1,11 +1,16 @@ using Chickensoft.Collections; +using Chickensoft.Serialization; +using System; +using Zennysoft.Ma.Adapter; -namespace Zennysoft.Game.Implementation.Components; +namespace Zennysoft.Game.Ma; -public class HealthComponent +public class HealthComponent : IHealthComponent { + [Save("current_hp")] public IAutoProp CurrentHP => _currentHP; + [Save("maximum_hp")] public IAutoProp MaximumHP => _maximumHP; private readonly AutoProp _currentHP; diff --git a/Zennysoft.Game.Ma/src/Components/HealthComponent.cs.uid b/Zennysoft.Game.Ma/src/Components/HealthComponent.cs.uid new file mode 100644 index 00000000..46ed5fa5 --- /dev/null +++ b/Zennysoft.Game.Ma/src/Components/HealthComponent.cs.uid @@ -0,0 +1 @@ +uid://c2e62jpounk1h diff --git a/Zennysoft.Game.Godot.Implementation/Components/LuckComponent.cs b/Zennysoft.Game.Ma/src/Components/LuckComponent.cs similarity index 72% rename from Zennysoft.Game.Godot.Implementation/Components/LuckComponent.cs rename to Zennysoft.Game.Ma/src/Components/LuckComponent.cs index ffc2ccd9..4a0294ec 100644 --- a/Zennysoft.Game.Godot.Implementation/Components/LuckComponent.cs +++ b/Zennysoft.Game.Ma/src/Components/LuckComponent.cs @@ -1,8 +1,9 @@ using Chickensoft.Collections; +using Zennysoft.Ma.Adapter; -namespace Zennysoft.Game.Implementation.Components; +namespace Zennysoft.Game.Ma; -public class LuckComponent +public class LuckComponent : ILuckComponent { public IAutoProp Luck => _luck; diff --git a/Zennysoft.Game.Ma/src/Components/LuckComponent.cs.uid b/Zennysoft.Game.Ma/src/Components/LuckComponent.cs.uid new file mode 100644 index 00000000..0d619aa2 --- /dev/null +++ b/Zennysoft.Game.Ma/src/Components/LuckComponent.cs.uid @@ -0,0 +1 @@ +uid://dfrj2surolauj diff --git a/Zennysoft.Game.Godot.Implementation/Components/VTComponent.cs b/Zennysoft.Game.Ma/src/Components/VTComponent.cs similarity index 90% rename from Zennysoft.Game.Godot.Implementation/Components/VTComponent.cs rename to Zennysoft.Game.Ma/src/Components/VTComponent.cs index 666d637a..943c9299 100644 --- a/Zennysoft.Game.Godot.Implementation/Components/VTComponent.cs +++ b/Zennysoft.Game.Ma/src/Components/VTComponent.cs @@ -1,8 +1,10 @@ using Chickensoft.Collections; +using System; +using Zennysoft.Ma.Adapter; -namespace Zennysoft.Game.Implementation.Components; +namespace Zennysoft.Game.Ma; -public class VTComponent +public class VTComponent : IVTComponent { public IAutoProp CurrentVT => _currentVT; diff --git a/Zennysoft.Game.Ma/src/Components/VTComponent.cs.uid b/Zennysoft.Game.Ma/src/Components/VTComponent.cs.uid new file mode 100644 index 00000000..e9cd339c --- /dev/null +++ b/Zennysoft.Game.Ma/src/Components/VTComponent.cs.uid @@ -0,0 +1 @@ +uid://b0tagp4amvy2v diff --git a/Zennysoft.Game.Ma/src/enemy/Enemy.cs b/Zennysoft.Game.Ma/src/enemy/Enemy.cs index 48943d6b..8a26101d 100644 --- a/Zennysoft.Game.Ma/src/enemy/Enemy.cs +++ b/Zennysoft.Game.Ma/src/enemy/Enemy.cs @@ -1,9 +1,9 @@ using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; +using System; using System.Collections.Immutable; using System.Linq; -using Zennysoft.Game.Implementation.Components; using Zennysoft.Ma.Adapter; using Zennysoft.Ma.Adapter.Entity; @@ -26,11 +26,11 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide this.DependOn(() => GetParent().GetChildren().OfType().Single()); #endregion - public HealthComponent HealthComponent { get; private set; } + public IHealthComponent HealthComponent { get; private set; } - public AttackComponent AttackComponent { get; private set; } + public IAttackComponent AttackComponent { get; private set; } - public DefenseComponent DefenseComponent { get; private set; } + public IDefenseComponent DefenseComponent { get; private set; } public virtual IEnemyModelView EnemyModelView { get; set; } = default!; @@ -118,36 +118,6 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide TargetPosition = targetPosition; - - public virtual void SetEnemyPosition(Vector3 newPosition) - { - GlobalPosition = newPosition; - - if (this is IHavePatrolBehavior patrolEnemy) - patrolEnemy.PatrolBehavior.HomePosition = GlobalPosition; - - _enemyLogic.Input(new EnemyLogic.Input.Reset()); - } - - public void LookAtTarget(Vector3 targetPosition) - { - var lookDirection = GlobalPosition - targetPosition; - if (lookDirection != GlobalPosition) - LookAt(new Vector3(lookDirection.X, GlobalPosition.Y, lookDirection.Z), Vector3.Up); - } - - public virtual void TakeDamage(int damage) - { - GD.Print($"Enemy Hit for {damage} damage."); - HealthComponent.Damage(damage); - } - - private void EnemyModelView_HitPlayer(object sender, System.EventArgs e) - { - _player.TakeDamage(new Damage(AttackComponent.TotalAttack, ElementType.None, false, false, false)); - } - public virtual void TakeHit() { _enemyLogic.Input(new EnemyLogic.Input.Alert()); @@ -181,4 +151,37 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide().ToList(); + var spawnPointsGodotCollection = new Godot.Collections.Array(spawnPoints); + var randomSpawnPoint = spawnPointsGodotCollection.PickRandom(); + + GlobalPosition = randomSpawnPoint.GlobalPosition; + + if (this is IHavePatrolBehavior patrolEnemy) + patrolEnemy.PatrolBehavior.HomePosition = GlobalPosition; + + _enemyLogic.Input(new EnemyLogic.Input.Reset()); + } + + throw new NotImplementedException($"Only {nameof(MonsterRoom)} types are currently supported."); + } + + protected void LookAtTarget(Vector3 targetPosition) + { + var lookDirection = GlobalPosition - targetPosition; + if (lookDirection != GlobalPosition) + LookAt(new Vector3(lookDirection.X, GlobalPosition.Y, lookDirection.Z), Vector3.Up); + } + + protected void SetTarget(Vector3 targetPosition) => TargetPosition = targetPosition; + + private void EnemyModelView_HitPlayer(object sender, System.EventArgs e) + { + _player.TakeDamage(new Damage(AttackComponent.TotalAttack, ElementType.None, false, false, false)); + } } diff --git a/Zennysoft.Game.Ma/src/enemy/Enemy2D.cs b/Zennysoft.Game.Ma/src/enemy/Enemy2D.cs index 68106f60..f0952303 100644 --- a/Zennysoft.Game.Ma/src/enemy/Enemy2D.cs +++ b/Zennysoft.Game.Ma/src/enemy/Enemy2D.cs @@ -18,7 +18,7 @@ public abstract partial class Enemy2D : Enemy [Node] private EnemyModelView2D _enemyModelView { get; set; } = default!; - public void OnReady() + public void OnEnterTree() { LineOfSight.BodyEntered += LineOfSight_BodyEntered; } diff --git a/Zennysoft.Game.Ma/src/enemy/behaviors/FollowBehavior.cs b/Zennysoft.Game.Ma/src/enemy/behaviors/FollowBehavior.cs index c4f822e3..c58d4d99 100644 --- a/Zennysoft.Game.Ma/src/enemy/behaviors/FollowBehavior.cs +++ b/Zennysoft.Game.Ma/src/enemy/behaviors/FollowBehavior.cs @@ -23,12 +23,16 @@ public partial class FollowBehavior : Node3D, IBehavior private NavigationAgent3D _navigationAgent; private Timer _thinkTimer; - public void Init(NavigationAgent3D navigationAgent) + public FollowBehavior() { - _navigationAgent = navigationAgent; _thinkTimer = new Timer() { WaitTime = _thinkTime }; _thinkTimer.Timeout += OnTimeout; AddChild(_thinkTimer); + } + + public void Init(NavigationAgent3D navigationAgent) + { + _navigationAgent = navigationAgent; SetPhysicsProcess(false); } diff --git a/Zennysoft.Game.Ma/src/enemy/behaviors/PatrolBehavior.cs b/Zennysoft.Game.Ma/src/enemy/behaviors/PatrolBehavior.cs index 912bd6c9..fa6fe341 100644 --- a/Zennysoft.Game.Ma/src/enemy/behaviors/PatrolBehavior.cs +++ b/Zennysoft.Game.Ma/src/enemy/behaviors/PatrolBehavior.cs @@ -28,11 +28,15 @@ public partial class PatrolBehavior : Node3D, IBehavior [Signal] public delegate void OnVelocityComputedEventHandler(Vector3 safeVelocity); - public void OnReady() + public PatrolBehavior() { _patrolTimer = new Timer() { WaitTime = _patrolTime }; _patrolTimer.Timeout += PatrolTimer_Timeout; AddChild(_patrolTimer); + } + + public void OnReady() + { SetPhysicsProcess(false); } diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/01. sproingy/Sproingy.cs b/Zennysoft.Game.Ma/src/enemy/enemy_types/01. sproingy/Sproingy.cs index cc663cde..c572acbe 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/01. sproingy/Sproingy.cs +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/01. sproingy/Sproingy.cs @@ -16,7 +16,7 @@ public partial class Sproingy : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayerB [Node] public Area3D PlayerDetector { get; set; } = default!; - public new void OnReady() + public void OnReady() { FollowBehavior.Init(NavigationAgent); PatrolBehavior.Init(NavigationAgent); diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/01. sproingy/Sproingy.tscn b/Zennysoft.Game.Ma/src/enemy/enemy_types/01. sproingy/Sproingy.tscn index 17c00cae..c8b0e2c3 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/01. sproingy/Sproingy.tscn +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/01. sproingy/Sproingy.tscn @@ -81,6 +81,8 @@ shape = SubResource("CylinderShape3D_drfkj") [node name="EnemyModelView" parent="Visual" instance=ExtResource("4_o3b7p")] unique_name_in_owner = true +_upperThreshold = 0.5 +_lowerThreshold = -0.5 [node name="Components" type="Node3D" parent="."] diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/15. ox_face/OxFace.tscn b/Zennysoft.Game.Ma/src/enemy/enemy_types/15. ox_face/OxFace.tscn index 66189910..0364edb6 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/15. ox_face/OxFace.tscn +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/15. ox_face/OxFace.tscn @@ -33,46 +33,22 @@ shape = SubResource("CapsuleShape3D_7uhtm") unique_name_in_owner = true [node name="Skeleton3D" parent="EnemyModelView/Armature" index="0"] -bones/0/position = Vector3(-0.260271, -1.05324, -1.96773) -bones/0/rotation = Quaternion(0.0915277, -0.692111, -0.0341586, 0.715149) -bones/1/rotation = Quaternion(0.0828172, 0.0642671, -0.39627, 0.91213) -bones/2/rotation = Quaternion(-0.137837, 0.137086, 0.403643, 0.894025) -bones/3/rotation = Quaternion(-0.00338816, 0.00852271, 0.0152662, 0.999842) -bones/4/rotation = Quaternion(0.037164, 0.133882, 0.101977, 0.985036) -bones/5/rotation = Quaternion(-0.0397875, -0.0104688, 0.0235613, 0.998875) +bones/0/position = Vector3(-0.260254, -1.05135, -1.96786) bones/6/rotation = Quaternion(-0.0474983, -0.294201, -0.744151, 0.597854) -bones/7/rotation = Quaternion(0.0788712, -0.0306685, -0.220772, 0.971647) -bones/8/rotation = Quaternion(-0.127286, 0.0273856, -0.425308, 0.895635) -bones/9/rotation = Quaternion(-0.0931654, 0.0493592, -0.752794, 0.649757) -bones/10/rotation = Quaternion(0.0429966, 0.0102923, 0.363547, 0.930526) -bones/11/rotation = Quaternion(-0.779773, -0.0573165, 0.0817155, 0.618054) -bones/12/rotation = Quaternion(-0.607818, -0.670503, -0.284916, 0.31592) -bones/13/rotation = Quaternion(-0.255941, 0.586097, -0.127235, 0.758153) -bones/14/rotation = Quaternion(-0.513517, -0.227335, -0.228787, 0.795157) -bones/15/rotation = Quaternion(-0.215465, 0.745342, 0.613525, -0.147065) +bones/11/rotation = Quaternion(-0.779814, -0.0573517, 0.0816353, 0.61801) +bones/15/rotation = Quaternion(-0.21544, 0.745303, 0.613567, -0.147118) bones/16/rotation = Quaternion(-0.486067, -0.16412, -0.362283, 0.778174) bones/17/rotation = Quaternion(-0.0553629, -0.0361614, 0.62832, 0.77514) -bones/18/rotation = Quaternion(-0.119289, 0.0998131, -0.0173011, 0.987678) -bones/19/position = Vector3(-0.381043, -1.19992, -1.71791) -bones/19/rotation = Quaternion(0.627663, 0.29282, 0.545153, -0.472338) -bones/20/rotation = Quaternion(-0.327815, -0.422723, -0.300673, 0.789581) -bones/21/rotation = Quaternion(-0.0604945, 0.00129838, 0.489705, 0.869786) -bones/22/rotation = Quaternion(0.156218, 0.0483037, -0.624744, 0.763516) -bones/23/rotation = Quaternion(0.123936, -0.00678731, -0.347765, 0.92933) -bones/24/rotation = Quaternion(0.427621, 0.561851, 0.530083, 0.469549) -bones/25/position = Vector3(4.82744, -12.3397, 0.183847) -bones/25/rotation = Quaternion(-0.400051, 0.463947, -0.598439, 0.516317) -bones/26/position = Vector3(-0.0233502, -1.11395, -2.01916) -bones/26/rotation = Quaternion(0.608697, -0.3155, -0.575514, -0.445793) -bones/27/rotation = Quaternion(-0.202236, 0.424675, 0.137941, 0.871622) -bones/28/rotation = Quaternion(-0.0627838, -0.00116445, -0.50126, 0.863015) -bones/29/rotation = Quaternion(0.150998, -0.0515735, 0.668372, 0.726511) -bones/31/position = Vector3(-7.29038, -6.72226, -0.133983) -bones/31/rotation = Quaternion(-0.453784, 0.542292, 0.542291, -0.453784) -bones/32/rotation = Quaternion(0.456756, 0.539878, -0.539587, -0.456893) +bones/19/position = Vector3(-0.379519, -1.19848, -1.72293) +bones/19/rotation = Quaternion(0.627358, 0.293207, 0.545673, -0.471903) +bones/20/rotation = Quaternion(-0.327492, -0.423093, -0.300135, 0.789722) +bones/21/rotation = Quaternion(-0.0604877, 0.00129843, 0.48965, 0.869818) +bones/26/position = Vector3(-0.0278308, -1.11395, -2.01914) +bones/27/rotation = Quaternion(-0.202309, 0.424634, 0.137996, 0.871616) +bones/28/rotation = Quaternion(-0.0627943, -0.00116438, -0.501344, 0.862966) [node name="BoneAttachment3D" parent="EnemyModelView/Armature/Skeleton3D" index="0"] -transform = Transform3D(-0.266252, -0.0359368, -0.963233, -0.333724, -0.934064, 0.127095, -0.904288, 0.355294, 0.236703, -1.68948, 8.20049, 4.9569) +transform = Transform3D(-0.266252, -0.0359368, -0.963233, -0.333724, -0.934064, 0.127095, -0.904288, 0.355294, 0.236703, -1.68946, 8.20239, 4.95677) [node name="Collision" type="Area3D" parent="."] collision_layer = 2048 diff --git a/Zennysoft.Game.Ma/src/game/Game.cs b/Zennysoft.Game.Ma/src/game/Game.cs index f4092328..8422012e 100644 --- a/Zennysoft.Game.Ma/src/game/Game.cs +++ b/Zennysoft.Game.Ma/src/game/Game.cs @@ -11,7 +11,6 @@ using Zennysoft.Game.Abstractions; using Zennysoft.Ma.Adapter; using System.IO; using System.Threading.Tasks; -using Zennysoft.Game.Implementation.Components; [Meta(typeof(IAutoNode))] public partial class Game : Node3D, IGame @@ -95,7 +94,8 @@ public partial class Game : Node3D, IGame PlayerData = new PlayerData() { - Inventory = _player.Inventory + Inventory = (Inventory)_player.Inventory, + HealthComponent = (HealthComponent)_player.HealthComponent, }, MapData = new MapData() { @@ -119,7 +119,7 @@ public partial class Game : Node3D, IGame public void OnResolved() { - var saveFileManager = _container.GetInstance>(); + var saveFileManager = _container.GetInstance(); SaveFile = new SaveFile( root: GameChunk, onSave: saveFileManager.Save, @@ -127,7 +127,7 @@ public partial class Game : Node3D, IGame { try { - var gameData = await saveFileManager.Load(); + var gameData = await saveFileManager.Load() as GameData; return gameData; } catch (FileNotFoundException) @@ -138,7 +138,6 @@ public partial class Game : Node3D, IGame return null; } ); - GameBinding = GameState.Bind(); GameBinding .Handle((in GameState.Output.InitializeGame _) => @@ -200,22 +199,22 @@ public partial class Game : Node3D, IGame .Handle((in GameState.Output.LoadNextFloor _) => { FloorClearMenu.FadeOut(); - _map.LoadFloor(); - if (_player.EquippedWeapon.Value.ItemTag == ItemTag.BreaksOnChange) + Task.Run(() => _map.LoadFloor()); + if (_player.EquipmentComponent.EquippedWeapon.Value.ItemTag == ItemTag.BreaksOnChange) { - var itemToDestroy = _player.EquippedWeapon.Value; + var itemToDestroy = _player.EquipmentComponent.EquippedWeapon.Value; _player.Unequip(itemToDestroy); _player.Inventory.Remove(itemToDestroy); } - if (_player.EquippedArmor.Value.ItemTag == ItemTag.BreaksOnChange) + if (_player.EquipmentComponent.EquippedArmor.Value.ItemTag == ItemTag.BreaksOnChange) { - var itemToDestroy = _player.EquippedArmor.Value; + var itemToDestroy = _player.EquipmentComponent.EquippedArmor.Value; _player.Unequip(itemToDestroy); _player.Inventory.Remove(itemToDestroy); } - if (_player.EquippedAccessory.Value.ItemTag == ItemTag.BreaksOnChange) + if (_player.EquipmentComponent.EquippedAccessory.Value.ItemTag == ItemTag.BreaksOnChange) { - var itemToDestroy = _player.EquippedAccessory.Value; + var itemToDestroy = _player.EquipmentComponent.EquippedAccessory.Value; _player.Unequip(itemToDestroy); _player.Inventory.Remove(itemToDestroy); } @@ -245,6 +244,7 @@ public partial class Game : Node3D, IGame _effectService = new EffectService(this, _player, _map); } +#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed public void OnReady() { InitializeGame(); @@ -254,22 +254,22 @@ public partial class Game : Node3D, IGame InGameUI.PlayerInfoUI.Activate(); _player.Activate(); } +#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed private void FloorClearMenu_SaveAndExit() { - //SaveFile.Save(); _player.Deactivate(); GameState.Input(new GameState.Input.ReturnToMainMenu()); InGameUI.Hide(); } private void FloorClearMenu_GoToNextFloor() => GameState.Input(new GameState.Input.LoadNextFloor()); + public void LoadExistingGame() => SaveFile.Load().ContinueWith((_) => CallDeferred(nameof(FinishedLoadingSaveFile))); public void InitializeGame() { _map.InitializeMapData(); - _player.InitializePlayerState(); } public void FloorExitReached() diff --git a/Zennysoft.Game.Ma/src/game/GameData.cs b/Zennysoft.Game.Ma/src/game/GameData.cs new file mode 100644 index 00000000..a4708476 --- /dev/null +++ b/Zennysoft.Game.Ma/src/game/GameData.cs @@ -0,0 +1,43 @@ +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; } +} + +public partial record PlayerData +{ + [Save("inventory")] + public required Inventory Inventory { get; init; } + [Save("health_component")] + public required HealthComponent HealthComponent { get; init; } + [Save("vt_component")] + public VTComponent VTComponent { get; init; } + [Save("attack_component")] + public AttackComponent AttackComponent { get; init; } + [Save("defense_component")] + public DefenseComponent DefenseComponent { get; init; } + [Save("experience_points_component")] + public ExperiencePointsComponent ExperiencePointsComponent { get; init; } + [Save("luck_component")] + public LuckComponent LuckComponent { get; init; } + [Save("equipment_component")] + public EquipmentComponent EquipmentComponent { get; init; } +} + +public partial record MapData +{ + +} diff --git a/Zennysoft.Game.Ma/src/game/IGame.cs b/Zennysoft.Game.Ma/src/game/IGame.cs index 54e3f395..3f2020db 100644 --- a/Zennysoft.Game.Ma/src/game/IGame.cs +++ b/Zennysoft.Game.Ma/src/game/IGame.cs @@ -4,8 +4,8 @@ namespace Zennysoft.Game.Ma; using Chickensoft.AutoInject; using Chickensoft.GodotNodeInterfaces; using Chickensoft.SaveFileBuilder; -using Godot; using System.Threading.Tasks; +using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter; public interface IGame : IProvide, IProvide, IProvide, IProvide, IProvide>, INode3D diff --git a/Zennysoft.Game.Ma/src/items/EffectService.cs b/Zennysoft.Game.Ma/src/items/EffectService.cs index 515b6d97..0c023090 100644 --- a/Zennysoft.Game.Ma/src/items/EffectService.cs +++ b/Zennysoft.Game.Ma/src/items/EffectService.cs @@ -3,6 +3,7 @@ using System.Linq; using System; using Zennysoft.Ma.Adapter; using Zennysoft.Ma.Adapter.Entity; +using Zennysoft.Game.Implementation; namespace Zennysoft.Game.Ma; @@ -37,12 +38,7 @@ public class EffectService var enemyList = validRooms.SelectMany(x => x.GetEnemiesInCurrentRoom()); foreach (var enemy in enemyList) - { - var spawnPoints = currentMonsterRoom.EnemySpawnPoints.GetChildren().OfType().ToList(); - var spawnPointsGodotCollection = new Godot.Collections.Array(spawnPoints); - var randomSpawnPoint = spawnPointsGodotCollection.PickRandom(); - enemy.SetEnemyPosition(randomSpawnPoint.GlobalPosition); - } + enemy.MoveEnemyToNewRoom(currentMonsterRoom); } public void KillHalfEnemiesInRoom() @@ -54,8 +50,8 @@ public class EffectService var currentMonsterRoom = (MonsterRoom)currentRoom; var enemyList = currentMonsterRoom.GetEnemiesInCurrentRoom().ToList(); var enemiesToKill = enemyList.Count / 2; - //for (var i = 0; i < enemiesToKill; i++) - // enemyList[i].Die(); + for (var i = 0; i < enemiesToKill; i++) + enemyList[i].Die(); } public void TurnAllEnemiesInRoomIntoHealingItem() @@ -68,8 +64,8 @@ public class EffectService var currentEnemies = currentRoom.EnemiesInRoom; foreach (var enemy in currentEnemies) { - //enemy.Die(); - //DropHealingItem(enemy.GetEnemyGlobalPosition()); + enemy.Die(); + DropHealingItem(enemy.GlobalPosition); } } @@ -95,9 +91,7 @@ public class EffectService if (currentRoom is not MonsterRoom) return; - var currentEnemies = currentRoom.EnemiesInRoom; - //foreach (var enemy in currentEnemies) - // enemy.SetCurrentHP(enemy.GetMaximumHP()); + currentRoom.EnemiesInRoom.ForEach(e => e.HealthComponent.SetHealth(e.HealthComponent.MaximumHP.Value)); _player.HealthComponent.SetHealth(_player.HealthComponent.MaximumHP.Value); } @@ -110,8 +104,12 @@ public class EffectService var currentEnemies = currentRoom.EnemiesInRoom; var hpToAbsorb = 0.0; - //foreach (var enemy in currentEnemies) - // hpToAbsorb += enemy.CurrentHP.Value * 0.05; + foreach (var enemy in currentEnemies) + { + var absorbAmount = enemy.HealthComponent.MaximumHP.Value * 0.05; + enemy.HealthComponent.Damage((int)absorbAmount); + hpToAbsorb += absorbAmount; + } _player.HealthComponent.Heal((int)hpToAbsorb); GD.Print("HP to absorb: " + hpToAbsorb); } @@ -127,7 +125,7 @@ public class EffectService foreach (var enemy in currentEnemies) { var damageDealt = DamageCalculator.CalculateDamage(new Damage(20, elementType, false, false, false), 10, new ElementalResistanceSet(0, 0, 0, 0, 0)); - enemy.TakeDamage(damageDealt); + enemy.HealthComponent.Damage(damageDealt); } } @@ -152,28 +150,25 @@ public class EffectService public void RaiseCurrentWeaponAttack() { - if (string.IsNullOrEmpty(_player.EquippedWeapon.Value.ItemName)) + if (string.IsNullOrEmpty(_player.EquipmentComponent.EquippedWeapon.Value.ItemName)) return; - var currentWeapon = (Weapon)_player.EquippedWeapon.Value; + var currentWeapon = (Weapon)_player.EquipmentComponent.EquippedWeapon.Value; currentWeapon.IncreaseWeaponAttack(1); - //_player.ModifyBonusAttack(1); + _player.AttackComponent.RaiseBonusAttack(1); } public void RaiseCurrentArmorDefense() { - if (string.IsNullOrEmpty(_player.EquippedArmor.Value.ItemName)) + if (string.IsNullOrEmpty(_player.EquipmentComponent.EquippedArmor.Value.ItemName)) return; - var currentArmor = (Armor)_player.EquippedArmor.Value; + var currentArmor = (Armor)_player.EquipmentComponent.EquippedArmor.Value; currentArmor.IncreaseArmorDefense(1); _player.DefenseComponent.RaiseBonusDefense(1); } - public void RaiseLevel() - { - _player.LevelUp(); - } + public void RaiseLevel() => _player.LevelUp(); public void TeleportToRandomRoom(IEnemy enemy) { @@ -189,11 +184,8 @@ public class EffectService var roomsGodotCollection = new Godot.Collections.Array(validRooms); var randomRoom = roomsGodotCollection.PickRandom(); - var spawnPoints = randomRoom.EnemySpawnPoints.GetChildren().OfType().ToList(); - var spawnPointsGodotCollection = new Godot.Collections.Array(spawnPoints); - var randomSpawnPoint = spawnPointsGodotCollection.PickRandom(); - enemy.SetEnemyPosition(randomSpawnPoint.GlobalPosition); + enemy.MoveEnemyToNewRoom(randomRoom); } public void TeleportToRandomRoom(IPlayer player) diff --git a/Zennysoft.Game.Ma/src/items/Inventory.cs b/Zennysoft.Game.Ma/src/items/Inventory.cs index 14d46dde..0cbfb56d 100644 --- a/Zennysoft.Game.Ma/src/items/Inventory.cs +++ b/Zennysoft.Game.Ma/src/items/Inventory.cs @@ -5,6 +5,7 @@ using Godot; using System.Collections.Generic; using System.Linq; using Zennysoft.Game.Abstractions; +using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; diff --git a/Zennysoft.Game.Ma/src/items/InventoryItemStats.cs b/Zennysoft.Game.Ma/src/items/InventoryItemStats.cs index a4ee0ae2..0226962e 100644 --- a/Zennysoft.Game.Ma/src/items/InventoryItemStats.cs +++ b/Zennysoft.Game.Ma/src/items/InventoryItemStats.cs @@ -1,6 +1,7 @@ using Chickensoft.Introspection; using Chickensoft.Serialization; using Godot; +using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; diff --git a/Zennysoft.Game.Ma/src/items/accessory/AccessoryStats.cs b/Zennysoft.Game.Ma/src/items/accessory/AccessoryStats.cs index b5c31cab..206d5003 100644 --- a/Zennysoft.Game.Ma/src/items/accessory/AccessoryStats.cs +++ b/Zennysoft.Game.Ma/src/items/accessory/AccessoryStats.cs @@ -1,6 +1,7 @@ using Chickensoft.Introspection; using Chickensoft.Serialization; using Godot; +using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; diff --git a/Zennysoft.Game.Ma/src/items/dropped/DroppedItem.cs b/Zennysoft.Game.Ma/src/items/dropped/DroppedItem.cs index bd71337a..a4b7435c 100644 --- a/Zennysoft.Game.Ma/src/items/dropped/DroppedItem.cs +++ b/Zennysoft.Game.Ma/src/items/dropped/DroppedItem.cs @@ -2,6 +2,7 @@ using Chickensoft.GodotNodeInterfaces; using Chickensoft.Introspection; using Godot; +using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; diff --git a/Zennysoft.Game.Ma/src/items/effect/EffectItemStats.cs b/Zennysoft.Game.Ma/src/items/effect/EffectItemStats.cs index 13889bc6..bd7fa58c 100644 --- a/Zennysoft.Game.Ma/src/items/effect/EffectItemStats.cs +++ b/Zennysoft.Game.Ma/src/items/effect/EffectItemStats.cs @@ -1,6 +1,7 @@ using Chickensoft.Introspection; using Chickensoft.Serialization; using Godot; +using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; diff --git a/Zennysoft.Game.Ma/src/items/restorative/Restorative.cs b/Zennysoft.Game.Ma/src/items/restorative/Restorative.cs index d5d0ac94..3aef1a93 100644 --- a/Zennysoft.Game.Ma/src/items/restorative/Restorative.cs +++ b/Zennysoft.Game.Ma/src/items/restorative/Restorative.cs @@ -2,7 +2,6 @@ using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; using Zennysoft.Game.Abstractions; -using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; diff --git a/Zennysoft.Game.Ma/src/items/throwable/ThrowableItem.cs b/Zennysoft.Game.Ma/src/items/throwable/ThrowableItem.cs index 98f06c38..c21b60ee 100644 --- a/Zennysoft.Game.Ma/src/items/throwable/ThrowableItem.cs +++ b/Zennysoft.Game.Ma/src/items/throwable/ThrowableItem.cs @@ -3,6 +3,7 @@ using Chickensoft.Introspection; using Chickensoft.Serialization; using Godot; using Zennysoft.Game.Abstractions; +using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; diff --git a/Zennysoft.Game.Ma/src/items/throwable/ThrowableItemStats.cs b/Zennysoft.Game.Ma/src/items/throwable/ThrowableItemStats.cs index 044fb951..120c1f6b 100644 --- a/Zennysoft.Game.Ma/src/items/throwable/ThrowableItemStats.cs +++ b/Zennysoft.Game.Ma/src/items/throwable/ThrowableItemStats.cs @@ -1,6 +1,7 @@ using Chickensoft.Introspection; using Chickensoft.Serialization; using Godot; +using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; diff --git a/Zennysoft.Game.Ma/src/items/thrown/ThrownItem.cs b/Zennysoft.Game.Ma/src/items/thrown/ThrownItem.cs index f4c897e7..e2b6e6b7 100644 --- a/Zennysoft.Game.Ma/src/items/thrown/ThrownItem.cs +++ b/Zennysoft.Game.Ma/src/items/thrown/ThrownItem.cs @@ -1,6 +1,7 @@ using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; +using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter; using Zennysoft.Ma.Adapter.Entity; @@ -108,22 +109,22 @@ public partial class ThrownItem : RigidBody3D { switch (throwableItem.ThrowableItemTag) { - //case ThrowableItemTag.LowerTargetTo1HP: - // enemy.TakeDamage(enemy.CurrentHP.Value - 1, ignoreDefense: true, ignoreElementalResistance: true); - // break; + case ThrowableItemTag.LowerTargetTo1HP: + enemy.HealthComponent.SetHealth(1); + break; case ThrowableItemTag.TeleportToRandomLocation: _effectService.TeleportToRandomRoom(enemy); break; default: var damageDealt = DamageCalculator.CalculateDamage(new Damage(throwableItem.ThrowDamage, throwableItem.ElementType, false, false, false), 10, new ElementalResistanceSet(0, 0, 0, 0, 0)); - enemy.TakeDamage(damageDealt); + enemy.HealthComponent.Damage(damageDealt); break; } } else { var damageDealt = DamageCalculator.CalculateDamage(new Damage(ItemThatIsThrown.ThrowDamage, ElementType.None, false, false, false), 10, new ElementalResistanceSet(0, 0, 0, 0, 0)); - enemy.TakeDamage(damageDealt); + enemy.HealthComponent.Damage(damageDealt); } } } \ No newline at end of file diff --git a/Zennysoft.Game.Ma/src/items/weapons/WeaponStats.cs b/Zennysoft.Game.Ma/src/items/weapons/WeaponStats.cs index 52c7e575..92b09868 100644 --- a/Zennysoft.Game.Ma/src/items/weapons/WeaponStats.cs +++ b/Zennysoft.Game.Ma/src/items/weapons/WeaponStats.cs @@ -1,6 +1,7 @@ using Chickensoft.Introspection; using Chickensoft.Serialization; using Godot; +using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; diff --git a/Zennysoft.Game.Ma/src/map/IMap.cs b/Zennysoft.Game.Ma/src/map/IMap.cs index e3543949..37c92dc0 100644 --- a/Zennysoft.Game.Ma/src/map/IMap.cs +++ b/Zennysoft.Game.Ma/src/map/IMap.cs @@ -3,9 +3,7 @@ using Chickensoft.Collections; using Chickensoft.GodotNodeInterfaces; using Chickensoft.SaveFileBuilder; using Godot; -using System.Collections.Immutable; using System.Threading.Tasks; -using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; diff --git a/Zennysoft.Game.Ma/src/map/dungeon/code/MonsterRoom.cs b/Zennysoft.Game.Ma/src/map/dungeon/code/MonsterRoom.cs index 41bb369c..526f8666 100644 --- a/Zennysoft.Game.Ma/src/map/dungeon/code/MonsterRoom.cs +++ b/Zennysoft.Game.Ma/src/map/dungeon/code/MonsterRoom.cs @@ -2,6 +2,7 @@ using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; using System.Linq; +using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; diff --git a/Zennysoft.Game.Ma/src/player/Player.cs b/Zennysoft.Game.Ma/src/player/Player.cs index 1e232d4e..2f2b6a75 100644 --- a/Zennysoft.Game.Ma/src/player/Player.cs +++ b/Zennysoft.Game.Ma/src/player/Player.cs @@ -1,12 +1,10 @@ using Chickensoft.AutoInject; -using Chickensoft.Collections; using Chickensoft.GodotNodeInterfaces; using Chickensoft.Introspection; using Chickensoft.SaveFileBuilder; using Godot; using SimpleInjector; using System; -using Zennysoft.Game.Implementation.Components; using Zennysoft.Ma.Adapter; using Zennysoft.Ma.Adapter.Entity; @@ -27,17 +25,19 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide PlayerChunk { get; set; } = default!; #endregion - public HealthComponent HealthComponent { get; private set; } + public IHealthComponent HealthComponent { get; private set; } - public VTComponent VTComponent { get; private set; } + public IVTComponent VTComponent { get; private set; } - public AttackComponent AttackComponent { get; private set; } + public IAttackComponent AttackComponent { get; private set; } - public DefenseComponent DefenseComponent { get; private set; } + public IDefenseComponent DefenseComponent { get; private set; } - public ExperiencePointsComponent ExperiencePointsComponent { get; private set; } + public IExperiencePointsComponent ExperiencePointsComponent { get; private set; } - public LuckComponent LuckComponent { get; private set; } + public ILuckComponent LuckComponent { get; private set; } + + public IEquipmentComponent EquipmentComponent { get; private set; } public Vector3 CurrentPosition => GlobalPosition; @@ -45,15 +45,6 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide EquippedWeapon => _equippedWeapon; - private AutoProp _equippedWeapon { get; set; } = new AutoProp(new Weapon()); - - public AutoProp EquippedArmor => _equippedArmor; - private AutoProp _equippedArmor { get; set; } = new AutoProp(new Armor()); - - public AutoProp EquippedAccessory => _equippedAccessory; - private AutoProp _equippedAccessory { get; set; } = new AutoProp(new Accessory()); - private PlayerLogic.Settings Settings { get; set; } = default!; private IPlayerLogic PlayerLogic { get; set; } = default!; @@ -119,14 +110,16 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide( onSave: (chunk) => new PlayerData() { - Inventory = Inventory + Inventory = (Inventory)Inventory, + HealthComponent = (HealthComponent)HealthComponent }, onLoad: (chunk, data) => { Inventory = data.Inventory; + HealthComponent = data.HealthComponent; } ); @@ -173,22 +165,18 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide Input.GetActionStrength(GameInputs.StrafeRight); + private void Attack() + { + if (PlayerIsHittingGeometry()) + { + AnimationPlayer.Play("hit_wall"); + _gameRepo.OnPlayerAttackedWall(); + } + else + { + PlayAttackAnimation(); + } + } + private void ThrowItem() { var itemScene = GD.Load("res://src/items/throwable/ThrowableItem.tscn"); @@ -376,7 +348,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide GlobalPosition = globalPosition; private void OnHealthTimerTimeout() { if (VTComponent.CurrentVT.Value > 0) { - if (((Accessory)EquippedAccessory.Value).AccessoryTag == AccessoryTag.HalfVTConsumption) + if (((Accessory)EquipmentComponent.EquippedAccessory.Value).AccessoryTag == AccessoryTag.HalfVTConsumption) reduceOnTick = !reduceOnTick; HealthComponent.Heal(1); @@ -415,21 +403,21 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide CurrentAttack { get; } - - public IAutoProp CurrentDefense { get; } - - public IAutoProp MaxAttack { get; } - - public IAutoProp MaxDefense { get; } - - public IAutoProp Luck { get; } -} diff --git a/Zennysoft.Game.Ma/src/ui/inventory_menu/IItemSlot.cs b/Zennysoft.Game.Ma/src/ui/inventory_menu/IItemSlot.cs new file mode 100644 index 00000000..c9c3199d --- /dev/null +++ b/Zennysoft.Game.Ma/src/ui/inventory_menu/IItemSlot.cs @@ -0,0 +1,18 @@ +using Chickensoft.GodotNodeInterfaces; +using Zennysoft.Game.Implementation; +using Zennysoft.Ma.Adapter; + +namespace Zennysoft.Game.Ma; + +public interface IItemSlot : IHBoxContainer +{ + public InventoryItem Item { get; set; } + + public void SetItemStyle(); + + public void SetSelectedItemStyle(); + + public void SetEquippedItemStyle(); + + public void SetEquippedSelectedItemStyle(); +} diff --git a/Zennysoft.Game.Ma/src/ui/inventory_menu/IItemSlot.cs.uid b/Zennysoft.Game.Ma/src/ui/inventory_menu/IItemSlot.cs.uid new file mode 100644 index 00000000..3d2841b9 --- /dev/null +++ b/Zennysoft.Game.Ma/src/ui/inventory_menu/IItemSlot.cs.uid @@ -0,0 +1 @@ +uid://cyit2s4ahwfqf diff --git a/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.cs b/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.cs index 81595ea7..8193019b 100644 --- a/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.cs +++ b/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.cs @@ -4,6 +4,7 @@ using Chickensoft.Introspection; using Godot; using System.Linq; using System.Threading.Tasks; +using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; @@ -344,7 +345,7 @@ public partial class InventoryMenu : Control, IInventoryMenu if (equipableItem.IsEquipped) { ItemEffectLabel.Text = $"{itemSlot.Item.GetType()} unequipped."; - Player.Unequip(equipableItem); + Player.EquipmentComponent.Unequip(equipableItem); itemSlot.SetSelectedItemStyle(); if (equipableItem.ItemTag == ItemTag.BreaksOnChange) Player.Inventory.Remove(equipableItem); @@ -352,7 +353,7 @@ public partial class InventoryMenu : Control, IInventoryMenu else { ItemEffectLabel.Text = $"{itemSlot.Item.GetType()} equipped."; - Player.Equip(equipableItem); + Player.EquipmentComponent.Equip(equipableItem); itemSlot.SetEquippedSelectedItemStyle(); } diff --git a/Zennysoft.Game.Ma/src/ui/inventory_menu/ItemSlot.cs b/Zennysoft.Game.Ma/src/ui/inventory_menu/ItemSlot.cs index f0e8e4fe..014f3824 100644 --- a/Zennysoft.Game.Ma/src/ui/inventory_menu/ItemSlot.cs +++ b/Zennysoft.Game.Ma/src/ui/inventory_menu/ItemSlot.cs @@ -1,25 +1,12 @@ using Chickensoft.AutoInject; -using Chickensoft.GodotNodeInterfaces; using Chickensoft.Introspection; using Godot; using Zennysoft.Game.Abstractions; +using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; -public interface IItemSlot : IHBoxContainer -{ - public InventoryItem Item { get; set; } - - public void SetItemStyle(); - - public void SetSelectedItemStyle(); - - public void SetEquippedItemStyle(); - - public void SetEquippedSelectedItemStyle(); -} - [Meta(typeof(IAutoNode))] public partial class ItemSlot : HBoxContainer, IItemSlot { @@ -27,8 +14,6 @@ public partial class ItemSlot : HBoxContainer, IItemSlot [Dependency] public IPlayer Player => this.DependOn(); - //[Node] public Label EquipBonus { get; set; } = default!; - [Node] public TextureRect ItemTexture { get; set; } = default!; [Node] public Label ItemName { get; set; } = default!; @@ -36,7 +21,9 @@ public partial class ItemSlot : HBoxContainer, IItemSlot [Node] public Label ItemCount { get; set; } = default!; private static LabelSettings ItemFont => GD.Load("res://src/ui/label_settings/MainTextBold.tres"); + private static LabelSettings SelectedItemFont => GD.Load("res://src/ui/label_settings/MainTextFontItalicized.tres"); + private static LabelSettings EquippedItemFont => GD.Load("res://src/ui/label_settings/MainTextFontEquipped.tres"); private static LabelSettings SelectedEquippedItemFont => GD.Load("res://src/ui/label_settings/MainTextFontSelectedEquipped.tres"); @@ -45,9 +32,9 @@ public partial class ItemSlot : HBoxContainer, IItemSlot { ItemName.Text = Item.ItemName; ItemTexture.Texture = Item.GetTexture(); - Player.EquippedWeapon.Sync += EquipableItem_Sync; - Player.EquippedArmor.Sync += EquipableItem_Sync; - Player.EquippedAccessory.Sync += EquipableItem_Sync; + Player.EquipmentComponent.EquippedWeapon.Sync += EquipableItem_Sync; + Player.EquipmentComponent.EquippedArmor.Sync += EquipableItem_Sync; + Player.EquipmentComponent.EquippedAccessory.Sync += EquipableItem_Sync; if (Item is IStackable stackableItem) { diff --git a/Zennysoft.Game.Ma/src/ui/pause_menu/PauseDebugMenu.cs b/Zennysoft.Game.Ma/src/ui/pause_menu/PauseDebugMenu.cs index 4ceb9dfd..5f482ac0 100644 --- a/Zennysoft.Game.Ma/src/ui/pause_menu/PauseDebugMenu.cs +++ b/Zennysoft.Game.Ma/src/ui/pause_menu/PauseDebugMenu.cs @@ -4,6 +4,7 @@ using Godot; using System; using System.Collections.Immutable; using System.Linq; +using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma;