Refactor more stuff (Audio mostly)
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
namespace Zennysoft.Game.Abstractions;
|
||||||
|
|
||||||
|
public interface IDimmableAudioStreamPlayer
|
||||||
|
{
|
||||||
|
/// <summary>Fade this dimmable audio stream track in.</summary>
|
||||||
|
public void FadeIn();
|
||||||
|
/// <summary>Fade this dimmable audio stream track out.</summary>
|
||||||
|
public void FadeOut();
|
||||||
|
|
||||||
|
public void Play(float fromPosition = 0);
|
||||||
|
|
||||||
|
public void Stop();
|
||||||
|
}
|
||||||
6
Zennysoft.Game.Abstractions/Entity/IKillable.cs
Normal file
6
Zennysoft.Game.Abstractions/Entity/IKillable.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Zennysoft.Game.Abstractions;
|
||||||
|
|
||||||
|
public interface IKillable
|
||||||
|
{
|
||||||
|
public void Die();
|
||||||
|
}
|
||||||
6
Zennysoft.Game.Abstractions/Pickups/IHealthPack.cs
Normal file
6
Zennysoft.Game.Abstractions/Pickups/IHealthPack.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Zennysoft.Game.Abstractions;
|
||||||
|
|
||||||
|
public interface IHealthPack
|
||||||
|
{
|
||||||
|
public double RestoreAmount { get; }
|
||||||
|
}
|
||||||
@@ -1,18 +1,10 @@
|
|||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Implementation;
|
||||||
|
|
||||||
using Chickensoft.GodotNodeInterfaces;
|
using Chickensoft.GodotNodeInterfaces;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using Zennysoft.Game.Abstractions;
|
||||||
|
|
||||||
public interface IDimmableAudioStreamPlayer : IAudioStreamPlayer
|
public partial class DimmableAudioStreamPlayer : AudioStreamPlayer, IDimmableAudioStreamPlayer
|
||||||
{
|
|
||||||
/// <summary>Fade this dimmable audio stream track in.</summary>
|
|
||||||
public void FadeIn();
|
|
||||||
/// <summary>Fade this dimmable audio stream track out.</summary>
|
|
||||||
public void FadeOut();
|
|
||||||
}
|
|
||||||
|
|
||||||
public partial class DimmableAudioStreamPlayer :
|
|
||||||
AudioStreamPlayer, IDimmableAudioStreamPlayer
|
|
||||||
{
|
{
|
||||||
#region Constants
|
#region Constants
|
||||||
// -60 to -80 is considered inaudible for decibels.
|
// -60 to -80 is considered inaudible for decibels.
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Chickensoft.GodotNodeInterfaces" Version="2.4.0" />
|
||||||
<PackageReference Include="Chickensoft.Introspection" Version="2.2.0" />
|
<PackageReference Include="Chickensoft.Introspection" Version="2.2.0" />
|
||||||
<PackageReference Include="Chickensoft.Introspection.Generator" Version="2.2.0" />
|
<PackageReference Include="Chickensoft.Introspection.Generator" Version="2.2.0" />
|
||||||
<PackageReference Include="Chickensoft.Serialization.Godot" Version="0.7.6" />
|
<PackageReference Include="Chickensoft.Serialization.Godot" Version="0.7.6" />
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
public partial class InGameAudioLogic
|
public partial class InGameAudioLogic
|
||||||
{
|
{
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Chickensoft.LogicBlocks;
|
using Chickensoft.LogicBlocks;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
public partial class InGameAudioLogic
|
public partial class InGameAudioLogic
|
||||||
{
|
{
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Chickensoft.LogicBlocks;
|
using Chickensoft.LogicBlocks;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
public interface IInGameAudioLogic : ILogicBlock<InGameAudioLogic.State>;
|
public interface IInGameAudioLogic : ILogicBlock<InGameAudioLogic.State>;
|
||||||
|
|
||||||
[Meta]
|
[Meta]
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
public partial class InGameAudioLogic
|
public partial class InGameAudioLogic
|
||||||
{
|
{
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Zennysoft.Ma.Adapter;
|
using Zennysoft.Game.Abstractions;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
public partial class InGameAudioLogic
|
public partial class InGameAudioLogic
|
||||||
{
|
{
|
||||||
@@ -53,15 +53,15 @@ public partial class InGameAudioLogic
|
|||||||
|
|
||||||
private void OnPlayerAttackWall() => Output(new Output.PlayPlayerAttackWallSound());
|
private void OnPlayerAttackWall() => Output(new Output.PlayPlayerAttackWallSound());
|
||||||
|
|
||||||
private void OnRestorativePickedUp(Restorative restorative) => Output(new Output.PlayHealingItemSound());
|
private void OnRestorativePickedUp(IHealthPack restorative) => Output(new Output.PlayHealingItemSound());
|
||||||
|
|
||||||
private void OnMenuBackedOut() => Output(new Output.PlayMenuBackSound());
|
private void OnMenuBackedOut() => Output(new Output.PlayMenuBackSound());
|
||||||
|
|
||||||
private void OnHealingItemConsumed(ConsumableItemStats stats) => Output(new Output.PlayHealingItemSound());
|
private void OnHealingItemConsumed(InventoryItem stats) => Output(new Output.PlayHealingItemSound());
|
||||||
|
|
||||||
private void OnInventorySorted() => Output(new Output.PlayInventorySortedSound());
|
private void OnInventorySorted() => Output(new Output.PlayInventorySortedSound());
|
||||||
|
|
||||||
private void OnEquippedItem(EquipableItem equipableItem) => Output(new Output.PlayEquipSound());
|
private void OnEquippedItem(InventoryItem equipableItem) => Output(new Output.PlayEquipSound());
|
||||||
|
|
||||||
private void OnOverworldEntered() => Output(new Output.PlayOverworldMusic());
|
private void OnOverworldEntered() => Output(new Output.PlayOverworldMusic());
|
||||||
|
|
||||||
36
Zennysoft.Game.Ma.Implementation/Game/IGameEventRepo.cs
Normal file
36
Zennysoft.Game.Ma.Implementation/Game/IGameEventRepo.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using Zennysoft.Game.Abstractions;
|
||||||
|
|
||||||
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
public interface IGameEventDepot : IDisposable
|
||||||
|
{
|
||||||
|
event Action? OverworldEntered;
|
||||||
|
public void OnOverworldEntered();
|
||||||
|
|
||||||
|
event Action? DungeonAThemeAreaEntered;
|
||||||
|
public void OnDungeonAThemeAreaEntered();
|
||||||
|
|
||||||
|
event Action? DungeonBThemeAreaEntered;
|
||||||
|
public void OnDungeonBThemeAreaEntered();
|
||||||
|
|
||||||
|
event Action? DungeonCThemeAreaEntered;
|
||||||
|
public void OnDungeonCThemeAreaEntered();
|
||||||
|
|
||||||
|
event Action? TeleportEntered;
|
||||||
|
public void OnTeleportEntered();
|
||||||
|
|
||||||
|
event Action? MenuScrolled;
|
||||||
|
public void OnMenuScrolled();
|
||||||
|
|
||||||
|
event Action? MenuBackedOut;
|
||||||
|
public void OnMenuBackedOut();
|
||||||
|
|
||||||
|
event Action? InventorySorted;
|
||||||
|
public void OnInventorySorted();
|
||||||
|
|
||||||
|
event Action<InventoryItem>? HealingItemConsumed;
|
||||||
|
public void OnHealingItemConsumed(InventoryItem item);
|
||||||
|
|
||||||
|
event Action<IHealthPack>? RestorativePickedUp;
|
||||||
|
public void OnRestorativePickedUp(IHealthPack restorative);
|
||||||
|
}
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Chickensoft.Serialization;
|
using Chickensoft.Serialization;
|
||||||
using Zennysoft.Ma.Adapter;
|
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
[Meta, Id("equipable_item")]
|
[Meta, Id("equipable_item")]
|
||||||
public abstract partial class EquipableItem : InventoryItem
|
public abstract partial class EquipableItem : InventoryItem
|
||||||
@@ -12,7 +12,8 @@ public class Module
|
|||||||
container.RegisterSingleton<IFileSystem, FileSystem>();
|
container.RegisterSingleton<IFileSystem, FileSystem>();
|
||||||
container.RegisterSingleton<ISaveFileManager<GameData>, SaveFileManager<GameData>>();
|
container.RegisterSingleton<ISaveFileManager<GameData>, SaveFileManager<GameData>>();
|
||||||
container.RegisterSingleton<IMaSaveFileManager<GameData>, MaSaveFileManager<GameData>>();
|
container.RegisterSingleton<IMaSaveFileManager<GameData>, MaSaveFileManager<GameData>>();
|
||||||
container.Register<IGameRepo, GameRepo>(Lifestyle.Singleton);
|
container.RegisterSingleton<IGameRepo, GameRepo>();
|
||||||
container.Register<IGameLogic, GameLogic>(Lifestyle.Singleton);
|
container.RegisterSingleton<IGameLogic, GameLogic>();
|
||||||
|
container.RegisterSingleton<IDimmableAudioStreamPlayer, DimmableAudioStreamPlayer>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
using Chickensoft.AutoInject;
|
using Chickensoft.Collections;
|
||||||
using Chickensoft.Collections;
|
|
||||||
using Chickensoft.SaveFileBuilder;
|
|
||||||
using Godot;
|
using Godot;
|
||||||
using Zennysoft.Game.Abstractions;
|
using Zennysoft.Game.Abstractions;
|
||||||
using Zennysoft.Ma.Adapter;
|
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
public interface IPlayer : IKillable, IProvide<ISaveChunk<PlayerData>>
|
public interface IPlayer : IKillable
|
||||||
{
|
{
|
||||||
public void Attack();
|
public void Attack();
|
||||||
|
|
||||||
@@ -25,8 +22,6 @@ public interface IPlayer : IKillable, IProvide<ISaveChunk<PlayerData>>
|
|||||||
|
|
||||||
public void TeleportPlayer(Transform3D newTransform);
|
public void TeleportPlayer(Transform3D newTransform);
|
||||||
|
|
||||||
public IDungeonRoom GetCurrentRoom();
|
|
||||||
|
|
||||||
public void HealHP(int amount);
|
public void HealHP(int amount);
|
||||||
|
|
||||||
public void RaiseHP(int amount);
|
public void RaiseHP(int amount);
|
||||||
@@ -53,11 +48,11 @@ public interface IPlayer : IKillable, IProvide<ISaveChunk<PlayerData>>
|
|||||||
|
|
||||||
public Basis CurrentBasis { get; }
|
public Basis CurrentBasis { get; }
|
||||||
|
|
||||||
public IAutoProp<Weapon> EquippedWeapon { get; }
|
public IAutoProp<EquipableItem> EquippedWeapon { get; }
|
||||||
|
|
||||||
public IAutoProp<Armor> EquippedArmor { get; }
|
public IAutoProp<EquipableItem> EquippedArmor { get; }
|
||||||
|
|
||||||
public IAutoProp<Accessory> EquippedAccessory { get; }
|
public IAutoProp<EquipableItem> EquippedAccessory { get; }
|
||||||
|
|
||||||
public void Equip(EquipableItem equipable);
|
public void Equip(EquipableItem equipable);
|
||||||
|
|
||||||
118
Zennysoft.Game.Ma.Implementation/Player/PlayerStatController.cs
Normal file
118
Zennysoft.Game.Ma.Implementation/Player/PlayerStatController.cs
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
|
using Chickensoft.Collections;
|
||||||
|
using Godot;
|
||||||
|
using Zennysoft.Game.Ma;
|
||||||
|
|
||||||
|
public class PlayerStatController
|
||||||
|
{
|
||||||
|
public void Init(PlayerStats playerStats)
|
||||||
|
{
|
||||||
|
_currentHP.OnNext(playerStats.CurrentHP);
|
||||||
|
_maximumHP.OnNext(playerStats.MaximumHP);
|
||||||
|
_currentVT.OnNext(playerStats.CurrentVT);
|
||||||
|
_maximumVT.OnNext(playerStats.MaximumVT);
|
||||||
|
_currentExp.OnNext(playerStats.CurrentExp);
|
||||||
|
_currentLevel.OnNext(playerStats.CurrentLevel);
|
||||||
|
_currentAttack.OnNext(playerStats.CurrentAttack);
|
||||||
|
_bonusAttack.OnNext(playerStats.BonusAttack);
|
||||||
|
_maxAttack.OnNext(playerStats.MaxAttack);
|
||||||
|
_currentDefense.OnNext(playerStats.CurrentDefense);
|
||||||
|
_bonusDefense.OnNext(playerStats.BonusDefense);
|
||||||
|
_maxDefense.OnNext(playerStats.MaxDefense);
|
||||||
|
_expToNextLevel.OnNext(playerStats.ExpToNextLevel);
|
||||||
|
_luck.OnNext(playerStats.Luck);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAutoProp<int> CurrentHP => _currentHP;
|
||||||
|
public IAutoProp<int> MaximumHP => _maximumHP;
|
||||||
|
public IAutoProp<int> CurrentVT => _currentVT;
|
||||||
|
public IAutoProp<int> MaximumVT => _maximumVT;
|
||||||
|
public IAutoProp<int> CurrentAttack => _currentAttack;
|
||||||
|
public IAutoProp<int> MaxAttack => _maxAttack;
|
||||||
|
public IAutoProp<int> BonusAttack => _bonusAttack;
|
||||||
|
public IAutoProp<int> CurrentDefense => _currentDefense;
|
||||||
|
public IAutoProp<int> MaxDefense => _maxDefense;
|
||||||
|
public IAutoProp<int> BonusDefense => _bonusDefense;
|
||||||
|
public IAutoProp<double> CurrentExp => _currentExp;
|
||||||
|
public IAutoProp<int> ExpToNextLevel => _expToNextLevel;
|
||||||
|
public IAutoProp<int> CurrentLevel => _currentLevel;
|
||||||
|
public IAutoProp<double> Luck => _luck;
|
||||||
|
|
||||||
|
public void SetCurrentHP(int newValue)
|
||||||
|
{
|
||||||
|
var clampedValue = Mathf.Clamp(newValue, 0, MaximumHP.Value);
|
||||||
|
_currentHP.OnNext(clampedValue);
|
||||||
|
}
|
||||||
|
public void SetMaximumHP(int newValue)
|
||||||
|
{
|
||||||
|
_maximumHP.OnNext(newValue);
|
||||||
|
}
|
||||||
|
public void SetCurrentVT(int newValue)
|
||||||
|
{
|
||||||
|
var clampedValue = Mathf.Clamp(newValue, 0, MaximumVT.Value);
|
||||||
|
_currentVT.OnNext(clampedValue);
|
||||||
|
}
|
||||||
|
public void SetMaximumVT(int newValue)
|
||||||
|
{
|
||||||
|
_maximumVT.OnNext(newValue);
|
||||||
|
}
|
||||||
|
public void SetCurrentExp(double newValue)
|
||||||
|
{
|
||||||
|
_currentExp.OnNext(newValue);
|
||||||
|
}
|
||||||
|
public void SetCurrentLevel(int newValue)
|
||||||
|
{
|
||||||
|
_currentLevel.OnNext(newValue);
|
||||||
|
}
|
||||||
|
public void SetCurrentAttack(int newValue)
|
||||||
|
{
|
||||||
|
var clampedValue = Mathf.Clamp(newValue, 0, MaxAttack.Value);
|
||||||
|
_currentAttack.OnNext(clampedValue);
|
||||||
|
}
|
||||||
|
public void SetBonusAttack(int newValue)
|
||||||
|
{
|
||||||
|
_bonusAttack.OnNext(newValue);
|
||||||
|
}
|
||||||
|
public void SetMaxAttack(int newValue)
|
||||||
|
{
|
||||||
|
_maxAttack.OnNext(newValue);
|
||||||
|
}
|
||||||
|
public void SetCurrentDefense(int newValue)
|
||||||
|
{
|
||||||
|
var clampedValue = Mathf.Clamp(newValue, 0, MaxDefense.Value);
|
||||||
|
_currentDefense.OnNext(clampedValue);
|
||||||
|
}
|
||||||
|
public void SetBonusDefense(int newValue)
|
||||||
|
{
|
||||||
|
_bonusDefense.OnNext(newValue);
|
||||||
|
}
|
||||||
|
public void SetMaxDefense(int newValue)
|
||||||
|
{
|
||||||
|
_maxDefense.OnNext(newValue);
|
||||||
|
}
|
||||||
|
public void SetExpToNextLevel(int newValue)
|
||||||
|
{
|
||||||
|
_expToNextLevel.OnNext(newValue);
|
||||||
|
}
|
||||||
|
public void SetLuck(double newValue)
|
||||||
|
{
|
||||||
|
var clampedValue = Mathf.Clamp(newValue, 0, 1.0);
|
||||||
|
_luck.OnNext(clampedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly AutoProp<int> _currentHP = new(-1);
|
||||||
|
private readonly AutoProp<int> _maximumHP = new(-1);
|
||||||
|
private readonly AutoProp<int> _currentVT = new(-1);
|
||||||
|
private readonly AutoProp<int> _maximumVT = new(-1);
|
||||||
|
private readonly AutoProp<double> _currentExp = new(-1);
|
||||||
|
private readonly AutoProp<int> _currentLevel = new(-1);
|
||||||
|
private readonly AutoProp<int> _currentAttack = new(-1);
|
||||||
|
private readonly AutoProp<int> _bonusAttack = new(-1);
|
||||||
|
private readonly AutoProp<int> _maxAttack = new(-1);
|
||||||
|
private readonly AutoProp<int> _currentDefense = new(-1);
|
||||||
|
private readonly AutoProp<int> _bonusDefense = new(-1);
|
||||||
|
private readonly AutoProp<int> _maxDefense = new(-1);
|
||||||
|
private readonly AutoProp<int> _expToNextLevel = new(-1);
|
||||||
|
private readonly AutoProp<double> _luck = new(-1);
|
||||||
|
}
|
||||||
@@ -37,116 +37,3 @@ public partial record PlayerStats
|
|||||||
[Save("luck")]
|
[Save("luck")]
|
||||||
public double Luck { get; init; }
|
public double Luck { get; init; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PlayerStatController
|
|
||||||
{
|
|
||||||
public void Init(PlayerStats playerStats)
|
|
||||||
{
|
|
||||||
_currentHP.OnNext(playerStats.CurrentHP);
|
|
||||||
_maximumHP.OnNext(playerStats.MaximumHP);
|
|
||||||
_currentVT.OnNext(playerStats.CurrentVT);
|
|
||||||
_maximumVT.OnNext(playerStats.MaximumVT);
|
|
||||||
_currentExp.OnNext(playerStats.CurrentExp);
|
|
||||||
_currentLevel.OnNext(playerStats.CurrentLevel);
|
|
||||||
_currentAttack.OnNext(playerStats.CurrentAttack);
|
|
||||||
_bonusAttack.OnNext(playerStats.BonusAttack);
|
|
||||||
_maxAttack.OnNext(playerStats.MaxAttack);
|
|
||||||
_currentDefense.OnNext(playerStats.CurrentDefense);
|
|
||||||
_bonusDefense.OnNext(playerStats.BonusDefense);
|
|
||||||
_maxDefense.OnNext(playerStats.MaxDefense);
|
|
||||||
_expToNextLevel.OnNext(playerStats.ExpToNextLevel);
|
|
||||||
_luck.OnNext(playerStats.Luck);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IAutoProp<int> CurrentHP => _currentHP;
|
|
||||||
public IAutoProp<int> MaximumHP => _maximumHP;
|
|
||||||
public IAutoProp<int> CurrentVT => _currentVT;
|
|
||||||
public IAutoProp<int> MaximumVT => _maximumVT;
|
|
||||||
public IAutoProp<int> CurrentAttack => _currentAttack;
|
|
||||||
public IAutoProp<int> MaxAttack => _maxAttack;
|
|
||||||
public IAutoProp<int> BonusAttack => _bonusAttack;
|
|
||||||
public IAutoProp<int> CurrentDefense => _currentDefense;
|
|
||||||
public IAutoProp<int> MaxDefense => _maxDefense;
|
|
||||||
public IAutoProp<int> BonusDefense => _bonusDefense;
|
|
||||||
public IAutoProp<double> CurrentExp => _currentExp;
|
|
||||||
public IAutoProp<int> ExpToNextLevel => _expToNextLevel;
|
|
||||||
public IAutoProp<int> CurrentLevel => _currentLevel;
|
|
||||||
public IAutoProp<double> Luck => _luck;
|
|
||||||
|
|
||||||
public void SetCurrentHP(int newValue)
|
|
||||||
{
|
|
||||||
var clampedValue = Mathf.Clamp(newValue, 0, MaximumHP.Value);
|
|
||||||
_currentHP.OnNext(clampedValue);
|
|
||||||
}
|
|
||||||
public void SetMaximumHP(int newValue)
|
|
||||||
{
|
|
||||||
_maximumHP.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetCurrentVT(int newValue)
|
|
||||||
{
|
|
||||||
var clampedValue = Mathf.Clamp(newValue, 0, MaximumVT.Value);
|
|
||||||
_currentVT.OnNext(clampedValue);
|
|
||||||
}
|
|
||||||
public void SetMaximumVT(int newValue)
|
|
||||||
{
|
|
||||||
_maximumVT.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetCurrentExp(double newValue)
|
|
||||||
{
|
|
||||||
_currentExp.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetCurrentLevel(int newValue)
|
|
||||||
{
|
|
||||||
_currentLevel.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetCurrentAttack(int newValue)
|
|
||||||
{
|
|
||||||
var clampedValue = Mathf.Clamp(newValue, 0, MaxAttack.Value);
|
|
||||||
_currentAttack.OnNext(clampedValue);
|
|
||||||
}
|
|
||||||
public void SetBonusAttack(int newValue)
|
|
||||||
{
|
|
||||||
_bonusAttack.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetMaxAttack(int newValue)
|
|
||||||
{
|
|
||||||
_maxAttack.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetCurrentDefense(int newValue)
|
|
||||||
{
|
|
||||||
var clampedValue = Mathf.Clamp(newValue, 0, MaxDefense.Value);
|
|
||||||
_currentDefense.OnNext(clampedValue);
|
|
||||||
}
|
|
||||||
public void SetBonusDefense(int newValue)
|
|
||||||
{
|
|
||||||
_bonusDefense.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetMaxDefense(int newValue)
|
|
||||||
{
|
|
||||||
_maxDefense.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetExpToNextLevel(int newValue)
|
|
||||||
{
|
|
||||||
_expToNextLevel.OnNext(newValue);
|
|
||||||
}
|
|
||||||
public void SetLuck(double newValue)
|
|
||||||
{
|
|
||||||
var clampedValue = Mathf.Clamp(newValue, 0, 1.0);
|
|
||||||
_luck.OnNext(clampedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly AutoProp<int> _currentHP = new(-1);
|
|
||||||
private readonly AutoProp<int> _maximumHP = new(-1);
|
|
||||||
private readonly AutoProp<int> _currentVT = new(-1);
|
|
||||||
private readonly AutoProp<int> _maximumVT = new(-1);
|
|
||||||
private readonly AutoProp<double> _currentExp = new(-1);
|
|
||||||
private readonly AutoProp<int> _currentLevel = new(-1);
|
|
||||||
private readonly AutoProp<int> _currentAttack = new(-1);
|
|
||||||
private readonly AutoProp<int> _bonusAttack = new(-1);
|
|
||||||
private readonly AutoProp<int> _maxAttack = new(-1);
|
|
||||||
private readonly AutoProp<int> _currentDefense = new(-1);
|
|
||||||
private readonly AutoProp<int> _bonusDefense = new(-1);
|
|
||||||
private readonly AutoProp<int> _maxDefense = new(-1);
|
|
||||||
private readonly AutoProp<int> _expToNextLevel = new(-1);
|
|
||||||
private readonly AutoProp<double> _luck = new(-1);
|
|
||||||
}
|
|
||||||
|
|||||||
7
Zennysoft.Game.Ma/src/audio/BGMPlayer.cs
Normal file
7
Zennysoft.Game.Ma/src/audio/BGMPlayer.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
using Zennysoft.Game.Implementation;
|
||||||
|
|
||||||
|
namespace Zennsoft.Game.Ma;
|
||||||
|
|
||||||
|
public partial class BGMPlayer : DimmableAudioStreamPlayer
|
||||||
|
{
|
||||||
|
}
|
||||||
1
Zennysoft.Game.Ma/src/audio/BGMPlayer.cs.uid
Normal file
1
Zennysoft.Game.Ma/src/audio/BGMPlayer.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://d2usinntpmcry
|
||||||
@@ -4,6 +4,7 @@ using Chickensoft.Introspection;
|
|||||||
using Godot;
|
using Godot;
|
||||||
using Zennysoft.Game.Abstractions;
|
using Zennysoft.Game.Abstractions;
|
||||||
using Zennysoft.Ma.Adapter;
|
using Zennysoft.Ma.Adapter;
|
||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
@@ -55,85 +56,85 @@ public partial class InGameAudio : Node
|
|||||||
|
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
InGameAudioLogic = new InGameAudioLogic();
|
InGameAudioLogic = new InGameAudioLogic();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnResolved()
|
public void OnResolved()
|
||||||
{
|
{
|
||||||
InGameAudioLogic.Set(AppRepo);
|
InGameAudioLogic.Set(AppRepo);
|
||||||
InGameAudioLogic.Set(GameEventDepot);
|
InGameAudioLogic.Set(GameEventDepot);
|
||||||
InGameAudioLogic.Set(Player);
|
InGameAudioLogic.Set(Player);
|
||||||
InGameAudioLogic.Set(GameRepo);
|
InGameAudioLogic.Set(GameRepo);
|
||||||
|
|
||||||
InGameAudioBinding = InGameAudioLogic.Bind();
|
InGameAudioBinding = InGameAudioLogic.Bind();
|
||||||
|
|
||||||
InGameAudioBinding
|
InGameAudioBinding
|
||||||
.Handle((in InGameAudioLogic.Output.PlayOverworldMusic _) => StartOverworldMusic())
|
.Handle((in InGameAudioLogic.Output.PlayOverworldMusic _) => StartOverworldMusic())
|
||||||
.Handle((in InGameAudioLogic.Output.PlayDungeonThemeAMusic _) => StartDungeonThemeA())
|
.Handle((in InGameAudioLogic.Output.PlayDungeonThemeAMusic _) => StartDungeonThemeA())
|
||||||
.Handle((in InGameAudioLogic.Output.PlayMenuScrollSound _) => PlayMenuScrollSound())
|
.Handle((in InGameAudioLogic.Output.PlayMenuScrollSound _) => PlayMenuScrollSound())
|
||||||
.Handle((in InGameAudioLogic.Output.PlayEquipSound _) => PlayEquipSound())
|
.Handle((in InGameAudioLogic.Output.PlayEquipSound _) => PlayEquipSound())
|
||||||
.Handle((in InGameAudioLogic.Output.PlayMenuBackSound _) => PlayMenuBackSound())
|
.Handle((in InGameAudioLogic.Output.PlayMenuBackSound _) => PlayMenuBackSound())
|
||||||
.Handle((in InGameAudioLogic.Output.PlayInventorySortedSound _) => PlayInventorySortedSound())
|
.Handle((in InGameAudioLogic.Output.PlayInventorySortedSound _) => PlayInventorySortedSound())
|
||||||
.Handle((in InGameAudioLogic.Output.PlayHealingItemSound _) => PlayHealingItemSound())
|
.Handle((in InGameAudioLogic.Output.PlayHealingItemSound _) => PlayHealingItemSound())
|
||||||
.Handle((in InGameAudioLogic.Output.PlayTeleportSound _) => PlayTeleportSound())
|
.Handle((in InGameAudioLogic.Output.PlayTeleportSound _) => PlayTeleportSound())
|
||||||
.Handle((in InGameAudioLogic.Output.PlayPlayerAttackSound _) => { PlayerAttackSFX.Stop(); PlayerAttackSFX.Play(); })
|
.Handle((in InGameAudioLogic.Output.PlayPlayerAttackSound _) => { PlayerAttackSFX.Stop(); PlayerAttackSFX.Play(); })
|
||||||
.Handle((in InGameAudioLogic.Output.PlayPlayerAttackWallSound _) => { PlayerAttackWallSFX.Stop(); PlayerAttackWallSFX.Play(); });
|
.Handle((in InGameAudioLogic.Output.PlayPlayerAttackWallSound _) => { PlayerAttackWallSFX.Stop(); PlayerAttackWallSFX.Play(); });
|
||||||
|
|
||||||
InGameAudioLogic.Start();
|
InGameAudioLogic.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnExitTree()
|
public void OnExitTree()
|
||||||
{
|
{
|
||||||
InGameAudioLogic.Stop();
|
InGameAudioLogic.Stop();
|
||||||
InGameAudioBinding.Dispose();
|
InGameAudioBinding.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartOverworldMusic()
|
private void StartOverworldMusic()
|
||||||
{
|
{
|
||||||
OverworldBgm.Stop();
|
OverworldBgm.Stop();
|
||||||
OverworldBgm.FadeIn();
|
OverworldBgm.FadeIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartDungeonThemeA()
|
private void StartDungeonThemeA()
|
||||||
{
|
{
|
||||||
OverworldBgm.FadeOut();
|
OverworldBgm.FadeOut();
|
||||||
DungeonThemeABgm.Stop();
|
DungeonThemeABgm.Stop();
|
||||||
DungeonThemeABgm.FadeIn();
|
DungeonThemeABgm.FadeIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PlayMenuScrollSound()
|
private void PlayMenuScrollSound()
|
||||||
{
|
{
|
||||||
MenuScrollSFX.Stop();
|
MenuScrollSFX.Stop();
|
||||||
MenuScrollSFX.Play();
|
MenuScrollSFX.Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PlayEquipSound()
|
private void PlayEquipSound()
|
||||||
{
|
{
|
||||||
EquipSFX.Stop();
|
EquipSFX.Stop();
|
||||||
EquipSFX.Play();
|
EquipSFX.Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PlayMenuBackSound()
|
private void PlayMenuBackSound()
|
||||||
{
|
{
|
||||||
MenuBackSFX.Stop();
|
MenuBackSFX.Stop();
|
||||||
MenuBackSFX.Play();
|
MenuBackSFX.Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PlayInventorySortedSound()
|
private void PlayInventorySortedSound()
|
||||||
{
|
{
|
||||||
InventorySortedSFX.Stop();
|
InventorySortedSFX.Stop();
|
||||||
InventorySortedSFX.Play();
|
InventorySortedSFX.Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PlayHealingItemSound()
|
private void PlayHealingItemSound()
|
||||||
{
|
{
|
||||||
HealingItemSFX.Stop();
|
HealingItemSFX.Stop();
|
||||||
HealingItemSFX.Play();
|
HealingItemSFX.Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PlayTeleportSound()
|
private void PlayTeleportSound()
|
||||||
{
|
{
|
||||||
TeleportSFX.Stop();
|
TeleportSFX.Stop();
|
||||||
TeleportSFX.Play();
|
TeleportSFX.Play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
[ext_resource type="Script" uid="uid://2mnouyn1jcqs" path="res://src/audio/InGameAudio.cs" id="1_gpmcr"]
|
[ext_resource type="Script" uid="uid://2mnouyn1jcqs" path="res://src/audio/InGameAudio.cs" id="1_gpmcr"]
|
||||||
[ext_resource type="AudioStream" uid="uid://dfu0fksb6slhx" path="res://src/audio/music/droney.mp3" id="2_8hfyr"]
|
[ext_resource type="AudioStream" uid="uid://dfu0fksb6slhx" path="res://src/audio/music/droney.mp3" id="2_8hfyr"]
|
||||||
[ext_resource type="Script" uid="uid://br4e8xfwd73if" path="res://src/audio/DimmableAudioStreamPlayer.cs" id="2_857rw"]
|
|
||||||
[ext_resource type="AudioStream" uid="uid://d2jrktp06xsba" path="res://src/audio/music/crossing-the-gate.mp3" id="3_wbmd6"]
|
[ext_resource type="AudioStream" uid="uid://d2jrktp06xsba" path="res://src/audio/music/crossing-the-gate.mp3" id="3_wbmd6"]
|
||||||
|
[ext_resource type="Script" path="res://src/audio/BGMPlayer.cs" id="3_wtvpb"]
|
||||||
[ext_resource type="AudioStream" uid="uid://dn2e2hqujlia1" path="res://src/audio/music/tar-winds.mp3" id="4_surnl"]
|
[ext_resource type="AudioStream" uid="uid://dn2e2hqujlia1" path="res://src/audio/music/tar-winds.mp3" id="4_surnl"]
|
||||||
[ext_resource type="AudioStream" uid="uid://t3g04u722f2k" path="res://src/audio/music/useless immune system-1.mp3" id="6_agr3r"]
|
[ext_resource type="AudioStream" uid="uid://t3g04u722f2k" path="res://src/audio/music/useless immune system-1.mp3" id="6_agr3r"]
|
||||||
[ext_resource type="AudioStream" uid="uid://cn8cugshq3o8k" path="res://src/audio/sfx/PlayerHitWallSFX.wav" id="7_8vh2f"]
|
[ext_resource type="AudioStream" uid="uid://cn8cugshq3o8k" path="res://src/audio/sfx/PlayerHitWallSFX.wav" id="7_8vh2f"]
|
||||||
@@ -19,84 +19,88 @@
|
|||||||
process_mode = 3
|
process_mode = 3
|
||||||
script = ExtResource("1_gpmcr")
|
script = ExtResource("1_gpmcr")
|
||||||
|
|
||||||
[node name="MenuBgm" type="AudioStreamPlayer" parent="."]
|
[node name="BGM" type="Node" parent="."]
|
||||||
|
|
||||||
|
[node name="MenuBgm" type="AudioStreamPlayer" parent="BGM"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
stream = ExtResource("2_8hfyr")
|
stream = ExtResource("2_8hfyr")
|
||||||
parameters/looping = true
|
parameters/looping = true
|
||||||
script = ExtResource("2_857rw")
|
script = ExtResource("3_wtvpb")
|
||||||
|
|
||||||
[node name="OverworldBgm" type="AudioStreamPlayer" parent="."]
|
[node name="OverworldBgm" type="AudioStreamPlayer" parent="BGM"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
stream = ExtResource("3_wbmd6")
|
stream = ExtResource("3_wbmd6")
|
||||||
volume_db = -15.0
|
volume_db = -15.0
|
||||||
parameters/looping = true
|
parameters/looping = true
|
||||||
script = ExtResource("2_857rw")
|
script = ExtResource("3_wtvpb")
|
||||||
|
|
||||||
[node name="DungeonThemeABgm" type="AudioStreamPlayer" parent="."]
|
[node name="DungeonThemeABgm" type="AudioStreamPlayer" parent="BGM"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
stream = ExtResource("4_surnl")
|
stream = ExtResource("4_surnl")
|
||||||
volume_db = -15.0
|
volume_db = -15.0
|
||||||
parameters/looping = true
|
parameters/looping = true
|
||||||
script = ExtResource("2_857rw")
|
script = ExtResource("3_wtvpb")
|
||||||
|
|
||||||
[node name="DungeonThemeBBgm" type="AudioStreamPlayer" parent="."]
|
[node name="DungeonThemeBBgm" type="AudioStreamPlayer" parent="BGM"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
stream = ExtResource("6_agr3r")
|
stream = ExtResource("6_agr3r")
|
||||||
volume_db = -15.0
|
volume_db = -15.0
|
||||||
parameters/looping = true
|
parameters/looping = true
|
||||||
script = ExtResource("2_857rw")
|
script = ExtResource("3_wtvpb")
|
||||||
|
|
||||||
[node name="DungeonThemeCBgm" type="AudioStreamPlayer" parent="."]
|
[node name="DungeonThemeCBgm" type="AudioStreamPlayer" parent="BGM"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
volume_db = -15.0
|
volume_db = -15.0
|
||||||
script = ExtResource("2_857rw")
|
script = ExtResource("3_wtvpb")
|
||||||
|
|
||||||
[node name="Title_Bgm" type="AudioStreamPlayer" parent="."]
|
[node name="Title_Bgm" type="AudioStreamPlayer" parent="BGM"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
volume_db = -15.0
|
volume_db = -15.0
|
||||||
script = ExtResource("2_857rw")
|
script = ExtResource("3_wtvpb")
|
||||||
|
|
||||||
[node name="PlayerAttackSFX" type="AudioStreamPlayer" parent="."]
|
[node name="SFX" type="Node" parent="."]
|
||||||
|
|
||||||
|
[node name="PlayerAttackSFX" type="AudioStreamPlayer" parent="SFX"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
stream = ExtResource("7_wtvpb")
|
stream = ExtResource("7_wtvpb")
|
||||||
volume_db = -5.0
|
volume_db = -5.0
|
||||||
|
|
||||||
[node name="PlayerAttackWallSFX" type="AudioStreamPlayer" parent="."]
|
[node name="PlayerAttackWallSFX" type="AudioStreamPlayer" parent="SFX"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
stream = ExtResource("7_8vh2f")
|
stream = ExtResource("7_8vh2f")
|
||||||
volume_db = -5.0
|
volume_db = -5.0
|
||||||
|
|
||||||
[node name="MenuScrollSFX" type="AudioStreamPlayer" parent="."]
|
[node name="MenuScrollSFX" type="AudioStreamPlayer" parent="SFX"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
stream = ExtResource("7_777nl")
|
stream = ExtResource("7_777nl")
|
||||||
volume_db = -10.0
|
volume_db = -10.0
|
||||||
|
|
||||||
[node name="MenuBackSFX" type="AudioStreamPlayer" parent="."]
|
[node name="MenuBackSFX" type="AudioStreamPlayer" parent="SFX"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
stream = ExtResource("8_1xcgo")
|
stream = ExtResource("8_1xcgo")
|
||||||
volume_db = -10.0
|
volume_db = -10.0
|
||||||
|
|
||||||
[node name="EquipSFX" type="AudioStreamPlayer" parent="."]
|
[node name="EquipSFX" type="AudioStreamPlayer" parent="SFX"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
stream = ExtResource("8_kwybb")
|
stream = ExtResource("8_kwybb")
|
||||||
volume_db = -10.0
|
volume_db = -10.0
|
||||||
|
|
||||||
[node name="HealSFX" type="AudioStreamPlayer" parent="."]
|
[node name="HealSFX" type="AudioStreamPlayer" parent="SFX"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
stream = ExtResource("10_3lcw5")
|
stream = ExtResource("10_3lcw5")
|
||||||
volume_db = -10.0
|
volume_db = -10.0
|
||||||
|
|
||||||
[node name="TeleportSFX" type="AudioStreamPlayer" parent="."]
|
[node name="TeleportSFX" type="AudioStreamPlayer" parent="SFX"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
stream = ExtResource("11_offhc")
|
stream = ExtResource("11_offhc")
|
||||||
volume_db = -18.0
|
volume_db = -18.0
|
||||||
|
|
||||||
[node name="InventorySortedSFX" type="AudioStreamPlayer" parent="."]
|
[node name="InventorySortedSFX" type="AudioStreamPlayer" parent="SFX"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
stream = ExtResource("12_wprjr")
|
stream = ExtResource("12_wprjr")
|
||||||
volume_db = -15.0
|
volume_db = -15.0
|
||||||
|
|
||||||
[node name="HealingItemSFX" type="AudioStreamPlayer" parent="."]
|
[node name="HealingItemSFX" type="AudioStreamPlayer" parent="SFX"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
stream = ExtResource("10_3lcw5")
|
stream = ExtResource("10_3lcw5")
|
||||||
volume_db = -15.0
|
volume_db = -15.0
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
|||||||
_enemyModelView.PlayHitAnimation();
|
_enemyModelView.PlayHitAnimation();
|
||||||
_enemyLogic.Input(new EnemyLogic.Input.Alerted());
|
_enemyLogic.Input(new EnemyLogic.Input.Alerted());
|
||||||
|
|
||||||
if (_player.EquippedWeapon.Value.WeaponTag == WeaponTag.SelfDamage)
|
if (((Weapon)_player.EquippedWeapon.Value).WeaponTag == WeaponTag.SelfDamage)
|
||||||
_player.Stats.SetCurrentHP(_player.Stats.CurrentHP.Value - 5);
|
_player.Stats.SetCurrentHP(_player.Stats.CurrentHP.Value - 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Godot;
|
using Godot;
|
||||||
|
using Zennysoft.Game.Abstractions;
|
||||||
using Zennysoft.Ma.Adapter;
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Chickensoft.AutoInject;
|
using Chickensoft.AutoInject;
|
||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
|
|||||||
@@ -53,8 +53,6 @@ public partial class Game : Node3D, IGame
|
|||||||
|
|
||||||
[Node] private IPauseMenu PauseMenu { get; set; } = default!;
|
[Node] private IPauseMenu PauseMenu { get; set; } = default!;
|
||||||
|
|
||||||
[Node] private InGameAudio InGameAudio { get; set; } = default!;
|
|
||||||
|
|
||||||
[Node] private Timer DoubleEXPTimer { get; set; } = default!;
|
[Node] private Timer DoubleEXPTimer { get; set; } = default!;
|
||||||
|
|
||||||
[Node] private IPlayer Player { get; set; } = default!;
|
[Node] private IPlayer Player { get; set; } = default!;
|
||||||
@@ -218,7 +216,7 @@ public partial class Game : Node3D, IGame
|
|||||||
|
|
||||||
DoubleEXPTimer.Timeout += DoubleEXPTimer_Timeout;
|
DoubleEXPTimer.Timeout += DoubleEXPTimer_Timeout;
|
||||||
|
|
||||||
_effectService = new EffectService(this, Player);
|
_effectService = new EffectService(this, Player, Map);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadExistingGame()
|
public void LoadExistingGame()
|
||||||
@@ -401,8 +399,8 @@ public partial class Game : Node3D, IGame
|
|||||||
GameLogic.Input(new GameLogic.Input.SaveGame());
|
GameLogic.Input(new GameLogic.Input.SaveGame());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GameEventDepot_RestorativePickedUp(Restorative obj)
|
private void GameEventDepot_RestorativePickedUp(IHealthPack obj)
|
||||||
=> Player.Stats.SetCurrentVT(Player.Stats.CurrentVT.Value + obj.VTRestoreAmount);
|
=> Player.Stats.SetCurrentVT(Player.Stats.CurrentVT.Value + (int)obj.RestoreAmount);
|
||||||
|
|
||||||
private void SetPauseMode(bool isPaused)
|
private void SetPauseMode(bool isPaused)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,43 +1,8 @@
|
|||||||
using Godot;
|
using Godot;
|
||||||
using System;
|
using System;
|
||||||
|
using Zennysoft.Game.Abstractions;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
public interface IGameEventDepot : IDisposable
|
|
||||||
{
|
|
||||||
event Action? OverworldEntered;
|
|
||||||
public void OnOverworldEntered();
|
|
||||||
|
|
||||||
event Action? DungeonAThemeAreaEntered;
|
|
||||||
public void OnDungeonAThemeAreaEntered();
|
|
||||||
|
|
||||||
event Action? DungeonBThemeAreaEntered;
|
|
||||||
public void OnDungeonBThemeAreaEntered();
|
|
||||||
|
|
||||||
event Action? DungeonCThemeAreaEntered;
|
|
||||||
public void OnDungeonCThemeAreaEntered();
|
|
||||||
|
|
||||||
event Action? TeleportEntered;
|
|
||||||
public void OnTeleportEntered();
|
|
||||||
|
|
||||||
event Action? MenuScrolled;
|
|
||||||
public void OnMenuScrolled();
|
|
||||||
|
|
||||||
event Action? MenuBackedOut;
|
|
||||||
public void OnMenuBackedOut();
|
|
||||||
|
|
||||||
event Action? InventorySorted;
|
|
||||||
public void OnInventorySorted();
|
|
||||||
|
|
||||||
event Action<ConsumableItemStats>? HealingItemConsumed;
|
|
||||||
public void OnHealingItemConsumed(ConsumableItemStats item);
|
|
||||||
|
|
||||||
event Action<Vector3, EnemyStatResource>? EnemyDefeated;
|
|
||||||
public void OnEnemyDefeated(Vector3 position, EnemyStatResource enemyStatResource);
|
|
||||||
|
|
||||||
event Action<Restorative>? RestorativePickedUp;
|
|
||||||
public void OnRestorativePickedUp(Restorative restorative);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GameEventDepot : IGameEventDepot
|
public class GameEventDepot : IGameEventDepot
|
||||||
{
|
{
|
||||||
@@ -52,10 +17,8 @@ public class GameEventDepot : IGameEventDepot
|
|||||||
public event Action? MenuScrolled;
|
public event Action? MenuScrolled;
|
||||||
public event Action? MenuBackedOut;
|
public event Action? MenuBackedOut;
|
||||||
public event Action? InventorySorted;
|
public event Action? InventorySorted;
|
||||||
public event Action<ConsumableItemStats>? HealingItemConsumed;
|
public event Action<InventoryItem>? HealingItemConsumed;
|
||||||
public event Action<Restorative>? RestorativePickedUp;
|
public event Action<IHealthPack>? RestorativePickedUp;
|
||||||
|
|
||||||
public event Action<Vector3, EnemyStatResource>? EnemyDefeated;
|
|
||||||
|
|
||||||
public void OnOverworldEntered() => OverworldEntered?.Invoke();
|
public void OnOverworldEntered() => OverworldEntered?.Invoke();
|
||||||
public void OnDungeonAThemeAreaEntered() => DungeonAThemeAreaEntered?.Invoke();
|
public void OnDungeonAThemeAreaEntered() => DungeonAThemeAreaEntered?.Invoke();
|
||||||
@@ -68,10 +31,8 @@ public class GameEventDepot : IGameEventDepot
|
|||||||
public void OnMenuBackedOut() => MenuBackedOut?.Invoke();
|
public void OnMenuBackedOut() => MenuBackedOut?.Invoke();
|
||||||
|
|
||||||
public void OnInventorySorted() => InventorySorted?.Invoke();
|
public void OnInventorySorted() => InventorySorted?.Invoke();
|
||||||
public void OnHealingItemConsumed(ConsumableItemStats item) => HealingItemConsumed?.Invoke(item);
|
public void OnHealingItemConsumed(InventoryItem item) => HealingItemConsumed?.Invoke(item);
|
||||||
public void OnRestorativePickedUp(Restorative restorative) => RestorativePickedUp?.Invoke(restorative);
|
public void OnRestorativePickedUp(IHealthPack restorative) => RestorativePickedUp?.Invoke(restorative);
|
||||||
|
|
||||||
public void OnEnemyDefeated(Vector3 position, EnemyStatResource enemyStatResource) => EnemyDefeated?.Invoke(position, enemyStatResource);
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -89,9 +89,8 @@ public partial class InventoryMenu : Control, IInventoryMenu
|
|||||||
Player.Stats.CurrentExp.Sync += CurrentExp_Sync;
|
Player.Stats.CurrentExp.Sync += CurrentExp_Sync;
|
||||||
Player.Stats.ExpToNextLevel.Sync += ExpToNextLevel_Sync;
|
Player.Stats.ExpToNextLevel.Sync += ExpToNextLevel_Sync;
|
||||||
Player.Stats.CurrentLevel.Sync += CurrentLevel_Sync;
|
Player.Stats.CurrentLevel.Sync += CurrentLevel_Sync;
|
||||||
Player.EquippedWeapon.Sync += EquippedWeapon_Sync;
|
Player.Stats.BonusAttack.Changed += BonusAttack_Sync;
|
||||||
Player.EquippedArmor.Sync += EquippedArmor_Sync;
|
Player.Stats.BonusDefense.Changed += BonusDefense_Sync;
|
||||||
Player.EquippedAccessory.Sync += EquippedAccessory_Sync;
|
|
||||||
|
|
||||||
SetProcessInput(false);
|
SetProcessInput(false);
|
||||||
}
|
}
|
||||||
@@ -107,22 +106,16 @@ public partial class InventoryMenu : Control, IInventoryMenu
|
|||||||
SetProcessInput(true);
|
SetProcessInput(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EquippedAccessory_Sync(Accessory obj)
|
private void BonusAttack_Sync(int bonus)
|
||||||
{
|
{
|
||||||
ATKBonusLabel.Text = $"{Player.Stats.BonusAttack.Value:+0;-#;\\.\\.\\.}";
|
ATKBonusLabel.Text = $"{bonus:+0;-#;\\.\\.\\.}";
|
||||||
DEFBonusLabel.Text = $"{Player.Stats.BonusDefense.Value:+0;-#;\\.\\.\\.}";
|
DEFBonusLabel.Text = $"{Player.Stats.BonusDefense.Value:+0;-#;\\.\\.\\.}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EquippedArmor_Sync(Armor obj)
|
private void BonusDefense_Sync(int bonus)
|
||||||
{
|
{
|
||||||
ATKBonusLabel.Text = $"{Player.Stats.BonusAttack.Value:+0;-#;\\.\\.\\.}";
|
ATKBonusLabel.Text = $"{Player.Stats.BonusAttack.Value:+0;-#;\\.\\.\\.}";
|
||||||
DEFBonusLabel.Text = $"{Player.Stats.BonusDefense.Value:+0;-#;\\.\\.\\.}";
|
DEFBonusLabel.Text = $"{bonus:+0;-#;\\.\\.\\.}";
|
||||||
}
|
|
||||||
|
|
||||||
private void EquippedWeapon_Sync(Weapon obj)
|
|
||||||
{
|
|
||||||
ATKBonusLabel.Text = $"{Player.Stats.BonusAttack.Value:+0;-#;\\.\\.\\.}";
|
|
||||||
DEFBonusLabel.Text = $"{Player.Stats.BonusDefense.Value:+0;-#;\\.\\.\\.}";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CurrentLevel_Sync(int obj) => CurrentLevelLabel.Text = $"Level {obj:D2}";
|
private void CurrentLevel_Sync(int obj) => CurrentLevelLabel.Text = $"Level {obj:D2}";
|
||||||
|
|||||||
@@ -41,77 +41,47 @@ public partial class ItemSlot : HBoxContainer, IItemSlot
|
|||||||
public void OnReady()
|
public void OnReady()
|
||||||
{
|
{
|
||||||
ItemName.Text = Item.ItemName;
|
ItemName.Text = Item.ItemName;
|
||||||
//EquipBonus.Text = "...";
|
|
||||||
ItemTexture.Texture = Item.GetTexture();
|
ItemTexture.Texture = Item.GetTexture();
|
||||||
Player.EquippedWeapon.Sync += EquippedWeapon_Sync;
|
Player.EquippedWeapon.Sync += EquipableItem_Sync;
|
||||||
Player.EquippedArmor.Sync += EquippedArmor_Sync;
|
Player.EquippedArmor.Sync += EquipableItem_Sync;
|
||||||
Player.EquippedAccessory.Sync += EquippedAccessory_Sync;
|
Player.EquippedAccessory.Sync += EquipableItem_Sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EquippedWeapon_Sync(Weapon obj)
|
private void EquipableItem_Sync(EquipableItem obj)
|
||||||
{
|
{
|
||||||
if (Item is Weapon weapon && weapon == obj)
|
if (Item is EquipableItem equipableItem && equipableItem == obj)
|
||||||
{
|
{
|
||||||
//EquipBonus.Text = $"{obj.WeaponStats.Damage:+0;-#;\\.\\.\\.}";
|
|
||||||
SetEquippedSelectedItemStyle();
|
SetEquippedSelectedItemStyle();
|
||||||
}
|
}
|
||||||
if (Item is Weapon unequippedItem && unequippedItem != obj)
|
if (Item is EquipableItem unequippedItem && unequippedItem != obj)
|
||||||
{
|
{
|
||||||
//EquipBonus.Text = $"...";
|
|
||||||
SetItemStyle();
|
SetItemStyle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EquippedArmor_Sync(Armor obj)
|
|
||||||
{
|
|
||||||
if (Item is Armor armor && armor == obj)
|
|
||||||
{
|
|
||||||
//EquipBonus.Text = $"{obj.ArmorStats.Defense:+0;-#;\\.\\.\\.}";
|
|
||||||
SetEquippedSelectedItemStyle();
|
|
||||||
}
|
|
||||||
if (Item is Armor unequippedItem && unequippedItem != obj)
|
|
||||||
{
|
|
||||||
//EquipBonus.Text = $"...";
|
|
||||||
SetItemStyle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EquippedAccessory_Sync(Accessory obj)
|
|
||||||
{
|
|
||||||
if (Item is Accessory accessory && accessory == obj)
|
|
||||||
SetEquippedSelectedItemStyle();
|
|
||||||
if (Item is Accessory unequippedItem && unequippedItem != obj)
|
|
||||||
SetItemStyle();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetItemStyle()
|
public void SetItemStyle()
|
||||||
{
|
{
|
||||||
ItemName.LabelSettings = ItemFont;
|
ItemName.LabelSettings = ItemFont;
|
||||||
//EquipBonus.LabelSettings = ItemFont;
|
|
||||||
}
|
}
|
||||||
public void SetSelectedItemStyle()
|
public void SetSelectedItemStyle()
|
||||||
{
|
{
|
||||||
if (Item is EquipableItem equipableItem && equipableItem.IsEquipped)
|
if (Item is EquipableItem equipableItem && equipableItem.IsEquipped)
|
||||||
{
|
{
|
||||||
ItemName.LabelSettings = SelectedEquippedItemFont;
|
ItemName.LabelSettings = SelectedEquippedItemFont;
|
||||||
//EquipBonus.LabelSettings = EquippedItemFont;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ItemName.LabelSettings = SelectedItemFont;
|
ItemName.LabelSettings = SelectedItemFont;
|
||||||
//EquipBonus.LabelSettings = SelectedItemFont;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void SetEquippedItemStyle()
|
public void SetEquippedItemStyle()
|
||||||
{
|
{
|
||||||
ItemName.LabelSettings = EquippedItemFont;
|
ItemName.LabelSettings = EquippedItemFont;
|
||||||
//EquipBonus.LabelSettings = EquippedItemFont;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetEquippedSelectedItemStyle()
|
public void SetEquippedSelectedItemStyle()
|
||||||
{
|
{
|
||||||
ItemName.LabelSettings = SelectedEquippedItemFont;
|
ItemName.LabelSettings = SelectedEquippedItemFont;
|
||||||
//EquipBonus.LabelSettings = EquippedItemFont;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public InventoryItem Item { get; set; } = default!;
|
public InventoryItem Item { get; set; } = default!;
|
||||||
|
|||||||
@@ -9,18 +9,20 @@ public class EffectService
|
|||||||
{
|
{
|
||||||
private readonly IGame _game;
|
private readonly IGame _game;
|
||||||
private readonly IPlayer _player;
|
private readonly IPlayer _player;
|
||||||
|
private readonly IMap _map;
|
||||||
|
|
||||||
public EffectService(IGame game, IPlayer player)
|
public EffectService(IGame game, IPlayer player, IMap map)
|
||||||
{
|
{
|
||||||
_game = game;
|
_game = game;
|
||||||
_player = player;
|
_player = player;
|
||||||
|
_map = map;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TeleportEnemiesToCurrentRoom()
|
public void TeleportEnemiesToCurrentRoom()
|
||||||
{
|
{
|
||||||
var currentFloor = _game.CurrentFloor;
|
var currentFloor = _game.CurrentFloor;
|
||||||
var rooms = currentFloor.Rooms;
|
var rooms = currentFloor.Rooms;
|
||||||
var currentRoom = _player.GetCurrentRoom();
|
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||||
|
|
||||||
if (currentRoom is not MonsterRoom)
|
if (currentRoom is not MonsterRoom)
|
||||||
return;
|
return;
|
||||||
@@ -44,7 +46,7 @@ public class EffectService
|
|||||||
|
|
||||||
public void KillHalfEnemiesInRoom()
|
public void KillHalfEnemiesInRoom()
|
||||||
{
|
{
|
||||||
var currentRoom = _player.GetCurrentRoom();
|
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||||
if (currentRoom is not MonsterRoom)
|
if (currentRoom is not MonsterRoom)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -57,7 +59,7 @@ public class EffectService
|
|||||||
|
|
||||||
public void TurnAllEnemiesInRoomIntoHealingItem()
|
public void TurnAllEnemiesInRoomIntoHealingItem()
|
||||||
{
|
{
|
||||||
var currentRoom = _player.GetCurrentRoom();
|
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||||
foreach (var enemy in currentEnemies)
|
foreach (var enemy in currentEnemies)
|
||||||
{
|
{
|
||||||
@@ -83,7 +85,7 @@ public class EffectService
|
|||||||
|
|
||||||
public void HealAllEnemiesAndPlayerInRoomToFull()
|
public void HealAllEnemiesAndPlayerInRoomToFull()
|
||||||
{
|
{
|
||||||
var currentRoom = _player.GetCurrentRoom();
|
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||||
foreach (var enemy in currentEnemies)
|
foreach (var enemy in currentEnemies)
|
||||||
enemy.SetCurrentHP(enemy.GetMaximumHP());
|
enemy.SetCurrentHP(enemy.GetMaximumHP());
|
||||||
@@ -92,7 +94,7 @@ public class EffectService
|
|||||||
|
|
||||||
public void AbsorbHPFromAllEnemiesInRoom()
|
public void AbsorbHPFromAllEnemiesInRoom()
|
||||||
{
|
{
|
||||||
var currentRoom = _player.GetCurrentRoom();
|
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||||
var hpToAbsorb = 0.0;
|
var hpToAbsorb = 0.0;
|
||||||
foreach (var enemy in currentEnemies)
|
foreach (var enemy in currentEnemies)
|
||||||
@@ -103,7 +105,7 @@ public class EffectService
|
|||||||
|
|
||||||
public void DealElementalDamageToAllEnemiesInRoom(ElementType elementType)
|
public void DealElementalDamageToAllEnemiesInRoom(ElementType elementType)
|
||||||
{
|
{
|
||||||
var currentRoom = _player.GetCurrentRoom();
|
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||||
foreach (var enemy in currentEnemies)
|
foreach (var enemy in currentEnemies)
|
||||||
enemy.TakeDamage(20, elementType);
|
enemy.TakeDamage(20, elementType);
|
||||||
@@ -133,7 +135,7 @@ public class EffectService
|
|||||||
if (_player.EquippedWeapon.Value.ItemName == string.Empty)
|
if (_player.EquippedWeapon.Value.ItemName == string.Empty)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var currentWeapon = _player.EquippedWeapon.Value;
|
var currentWeapon = (Weapon)_player.EquippedWeapon.Value;
|
||||||
currentWeapon.IncreaseWeaponAttack(1);
|
currentWeapon.IncreaseWeaponAttack(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +144,7 @@ public class EffectService
|
|||||||
if (_player.EquippedArmor.Value.ItemName == string.Empty)
|
if (_player.EquippedArmor.Value.ItemName == string.Empty)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var currentArmor = _player.EquippedArmor.Value;
|
var currentArmor = (Armor)_player.EquippedArmor.Value;
|
||||||
currentArmor.IncreaseArmorDefense(1);
|
currentArmor.IncreaseArmorDefense(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
using Chickensoft.AutoInject;
|
using Chickensoft.AutoInject;
|
||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using Zennysoft.Game.Abstractions;
|
||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
[Meta(typeof(IAutoNode))]
|
[Meta(typeof(IAutoNode))]
|
||||||
public partial class Restorative : Node3D
|
public partial class Restorative : Node3D, IHealthPack
|
||||||
{
|
{
|
||||||
public override void _Notification(int what) => this.Notify(what);
|
public override void _Notification(int what) => this.Notify(what);
|
||||||
|
|
||||||
@@ -13,7 +15,7 @@ public partial class Restorative : Node3D
|
|||||||
|
|
||||||
[Node] public Area3D Pickup { get; set; } = default!;
|
[Node] public Area3D Pickup { get; set; } = default!;
|
||||||
|
|
||||||
public int VTRestoreAmount => 4;
|
public double RestoreAmount => 4;
|
||||||
|
|
||||||
public void OnReady()
|
public void OnReady()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,15 +11,17 @@ namespace Zennysoft.Game.Ma;
|
|||||||
|
|
||||||
public interface IMap : INode3D, IProvide<ISaveChunk<MapData>>
|
public interface IMap : INode3D, IProvide<ISaveChunk<MapData>>
|
||||||
{
|
{
|
||||||
public void LoadMap();
|
void LoadMap();
|
||||||
|
|
||||||
public List<string> FloorScenes { get; }
|
List<string> FloorScenes { get; }
|
||||||
|
|
||||||
public IDungeonFloor CurrentFloor { get; }
|
IDungeonFloor CurrentFloor { get; }
|
||||||
|
|
||||||
public void SpawnNextFloor();
|
void SpawnNextFloor();
|
||||||
|
|
||||||
public Transform3D GetPlayerSpawnPosition();
|
Transform3D GetPlayerSpawnPosition();
|
||||||
|
|
||||||
|
IDungeonRoom GetPlayersCurrentRoom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -95,6 +97,13 @@ public partial class Map : Node3D, IMap
|
|||||||
Game.NextFloorLoaded();
|
Game.NextFloorLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IDungeonRoom GetPlayersCurrentRoom()
|
||||||
|
{
|
||||||
|
var rooms = CurrentFloor.Rooms;
|
||||||
|
var playersRoom = rooms.SingleOrDefault(x => x.IsPlayerInRoom);
|
||||||
|
return playersRoom;
|
||||||
|
}
|
||||||
|
|
||||||
public Transform3D GetPlayerSpawnPosition() => CurrentFloor.GetPlayerSpawnPoint();
|
public Transform3D GetPlayerSpawnPosition() => CurrentFloor.GetPlayerSpawnPoint();
|
||||||
|
|
||||||
private void LoadFloor()
|
private void LoadFloor()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Chickensoft.AutoInject;
|
using Chickensoft.AutoInject;
|
||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Godot;
|
using Godot;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Chickensoft.AutoInject;
|
using Chickensoft.AutoInject;
|
||||||
using Chickensoft.Collections;
|
using Chickensoft.Collections;
|
||||||
using Chickensoft.GodotNodeInterfaces;
|
using Chickensoft.GodotNodeInterfaces;
|
||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
@@ -13,7 +13,7 @@ using Zennysoft.Ma.Adapter;
|
|||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
[Meta(typeof(IAutoNode))]
|
[Meta(typeof(IAutoNode))]
|
||||||
public partial class Player : CharacterBody3D, IPlayer
|
public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<PlayerData>>
|
||||||
{
|
{
|
||||||
#region Dependency Injection
|
#region Dependency Injection
|
||||||
public override void _Notification(int what) => this.Notify(what);
|
public override void _Notification(int what) => this.Notify(what);
|
||||||
@@ -36,14 +36,14 @@ public partial class Player : CharacterBody3D, IPlayer
|
|||||||
|
|
||||||
public IInventory Inventory { get; private set; } = default!;
|
public IInventory Inventory { get; private set; } = default!;
|
||||||
|
|
||||||
public IAutoProp<Weapon> EquippedWeapon => _equippedWeapon;
|
public IAutoProp<EquipableItem> EquippedWeapon => _equippedWeapon;
|
||||||
private AutoProp<Weapon> _equippedWeapon { get; set; } = new AutoProp<Weapon>(new Weapon());
|
private AutoProp<EquipableItem> _equippedWeapon { get; set; } = new AutoProp<EquipableItem>(new Weapon());
|
||||||
|
|
||||||
public IAutoProp<Armor> EquippedArmor => _equippedArmor;
|
public IAutoProp<EquipableItem> EquippedArmor => _equippedArmor;
|
||||||
private AutoProp<Armor> _equippedArmor { get; set; } = new AutoProp<Armor>(new Armor());
|
private AutoProp<EquipableItem> _equippedArmor { get; set; } = new AutoProp<EquipableItem>(new Armor());
|
||||||
|
|
||||||
public IAutoProp<Accessory> EquippedAccessory => _equippedAccessory;
|
public IAutoProp<EquipableItem> EquippedAccessory => _equippedAccessory;
|
||||||
private AutoProp<Accessory> _equippedAccessory { get; set; } = new AutoProp<Accessory>(new Accessory());
|
private AutoProp<EquipableItem> _equippedAccessory { get; set; } = new AutoProp<EquipableItem>(new Accessory());
|
||||||
|
|
||||||
private PlayerLogic.Settings Settings { get; set; } = default!;
|
private PlayerLogic.Settings Settings { get; set; } = default!;
|
||||||
|
|
||||||
@@ -106,513 +106,506 @@ public partial class Player : CharacterBody3D, IPlayer
|
|||||||
#region Initialization
|
#region Initialization
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
AnimationPlayer.AnimationFinished += OnAnimationFinished;
|
AnimationPlayer.AnimationFinished += OnAnimationFinished;
|
||||||
_expToNextLevel = new Dictionary<int, int>
|
_expToNextLevel = new Dictionary<int, int>
|
||||||
{
|
{
|
||||||
{ 2, 12 },
|
{ 2, 12 },
|
||||||
{ 3, 39 },
|
{ 3, 39 },
|
||||||
{ 4, 87 },
|
{ 4, 87 },
|
||||||
{ 5, 162 },
|
{ 5, 162 },
|
||||||
{ 6, 270 },
|
{ 6, 270 },
|
||||||
{ 7, 417 },
|
{ 7, 417 },
|
||||||
{ 8, 609 }
|
{ 8, 609 }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
var container = new SimpleInjector.Container();
|
var container = new SimpleInjector.Container();
|
||||||
container.Register<IPlayerLogic, PlayerLogic>(Lifestyle.Singleton);
|
container.Register<IPlayerLogic, PlayerLogic>(Lifestyle.Singleton);
|
||||||
container.Verify();
|
container.Verify();
|
||||||
|
|
||||||
Settings = new PlayerLogic.Settings() { RotationSpeed = PlayerStatResource.RotationSpeed, MoveSpeed = PlayerStatResource.MoveSpeed, Acceleration = PlayerStatResource.Acceleration };
|
Settings = new PlayerLogic.Settings() { RotationSpeed = PlayerStatResource.RotationSpeed, MoveSpeed = PlayerStatResource.MoveSpeed, Acceleration = PlayerStatResource.Acceleration };
|
||||||
Stats = new PlayerStatController();
|
Stats = new PlayerStatController();
|
||||||
Stats.Init(
|
Stats.Init(
|
||||||
new PlayerStats
|
new PlayerStats
|
||||||
{
|
{
|
||||||
CurrentHP = PlayerStatResource.CurrentHP,
|
CurrentHP = PlayerStatResource.CurrentHP,
|
||||||
MaximumHP = PlayerStatResource.MaximumHP,
|
MaximumHP = PlayerStatResource.MaximumHP,
|
||||||
CurrentVT = PlayerStatResource.CurrentVT,
|
CurrentVT = PlayerStatResource.CurrentVT,
|
||||||
MaximumVT = PlayerStatResource.MaximumVT,
|
MaximumVT = PlayerStatResource.MaximumVT,
|
||||||
CurrentAttack = PlayerStatResource.CurrentAttack,
|
CurrentAttack = PlayerStatResource.CurrentAttack,
|
||||||
BonusAttack = PlayerStatResource.BonusAttack,
|
BonusAttack = PlayerStatResource.BonusAttack,
|
||||||
MaxAttack = PlayerStatResource.MaxAttack,
|
MaxAttack = PlayerStatResource.MaxAttack,
|
||||||
CurrentDefense = PlayerStatResource.CurrentDefense,
|
CurrentDefense = PlayerStatResource.CurrentDefense,
|
||||||
BonusDefense = PlayerStatResource.BonusDefense,
|
BonusDefense = PlayerStatResource.BonusDefense,
|
||||||
MaxDefense = PlayerStatResource.MaxDefense,
|
MaxDefense = PlayerStatResource.MaxDefense,
|
||||||
CurrentExp = PlayerStatResource.CurrentExp,
|
CurrentExp = PlayerStatResource.CurrentExp,
|
||||||
CurrentLevel = PlayerStatResource.CurrentLevel,
|
CurrentLevel = PlayerStatResource.CurrentLevel,
|
||||||
ExpToNextLevel = PlayerStatResource.ExpToNextLevel,
|
ExpToNextLevel = PlayerStatResource.ExpToNextLevel,
|
||||||
Luck = PlayerStatResource.Luck
|
Luck = PlayerStatResource.Luck
|
||||||
});
|
});
|
||||||
|
|
||||||
Inventory = new Inventory();
|
Inventory = new Inventory();
|
||||||
|
|
||||||
PlayerLogic = container.GetInstance<IPlayerLogic>();
|
PlayerLogic = container.GetInstance<IPlayerLogic>();
|
||||||
PlayerLogic.Set(this as IPlayer);
|
PlayerLogic.Set(this as IPlayer);
|
||||||
PlayerLogic.Set(Settings);
|
PlayerLogic.Set(Settings);
|
||||||
PlayerLogic.Set(Stats);
|
PlayerLogic.Set(Stats);
|
||||||
PlayerLogic.Set(_gameRepo);
|
PlayerLogic.Set(_gameRepo);
|
||||||
|
|
||||||
var defaultWeapon = new Weapon();
|
var defaultWeapon = new Weapon();
|
||||||
defaultWeapon.Stats = _defaultWeapon;
|
defaultWeapon.Stats = _defaultWeapon;
|
||||||
var defaultArmor = new Armor();
|
var defaultArmor = new Armor();
|
||||||
defaultArmor.Stats = _defaultArmor;
|
defaultArmor.Stats = _defaultArmor;
|
||||||
Inventory.TryAdd(defaultWeapon);
|
Inventory.TryAdd(defaultWeapon);
|
||||||
Inventory.TryAdd(defaultArmor);
|
Inventory.TryAdd(defaultArmor);
|
||||||
|
|
||||||
EquippedWeapon.Sync += EquippedWeapon_Sync;
|
EquippedWeapon.Sync += EquippedWeapon_Sync;
|
||||||
EquippedArmor.Sync += EquippedArmor_Sync;
|
EquippedArmor.Sync += EquippedArmor_Sync;
|
||||||
EquippedAccessory.Sync += EquippedAccessory_Sync;
|
EquippedAccessory.Sync += EquippedAccessory_Sync;
|
||||||
Stats.CurrentHP.Sync += CurrentHP_Sync;
|
Stats.CurrentHP.Sync += CurrentHP_Sync;
|
||||||
Stats.CurrentExp.Sync += CurrentEXP_Sync;
|
Stats.CurrentExp.Sync += CurrentEXP_Sync;
|
||||||
|
|
||||||
Equip(defaultWeapon);
|
Equip(defaultWeapon);
|
||||||
Equip(defaultArmor);
|
Equip(defaultArmor);
|
||||||
|
|
||||||
HealthTimer.WaitTime = _healthTimerWaitTime;
|
HealthTimer.WaitTime = _healthTimerWaitTime;
|
||||||
HealthTimer.Timeout += OnHealthTimerTimeout;
|
HealthTimer.Timeout += OnHealthTimerTimeout;
|
||||||
Hitbox.AreaEntered += Hitbox_AreaEntered;
|
Hitbox.AreaEntered += Hitbox_AreaEntered;
|
||||||
CollisionDetector.AreaEntered += CollisionDetector_AreaEntered;
|
CollisionDetector.AreaEntered += CollisionDetector_AreaEntered;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnResolved()
|
public void OnResolved()
|
||||||
{
|
{
|
||||||
PlayerChunk = new SaveChunk<PlayerData>(
|
PlayerChunk = new SaveChunk<PlayerData>(
|
||||||
onSave: (chunk) => new PlayerData()
|
onSave: (chunk) => new PlayerData()
|
||||||
{
|
{
|
||||||
PlayerStats = new PlayerStats()
|
PlayerStats = new PlayerStats()
|
||||||
{
|
{
|
||||||
CurrentHP = Stats.CurrentHP.Value,
|
CurrentHP = Stats.CurrentHP.Value,
|
||||||
MaximumHP = Stats.MaximumHP.Value,
|
MaximumHP = Stats.MaximumHP.Value,
|
||||||
CurrentVT = Stats.CurrentVT.Value,
|
CurrentVT = Stats.CurrentVT.Value,
|
||||||
MaximumVT = Stats.MaximumVT.Value,
|
MaximumVT = Stats.MaximumVT.Value,
|
||||||
CurrentAttack = Stats.CurrentAttack.Value,
|
CurrentAttack = Stats.CurrentAttack.Value,
|
||||||
BonusAttack = Stats.BonusAttack.Value,
|
BonusAttack = Stats.BonusAttack.Value,
|
||||||
MaxAttack = Stats.MaxAttack.Value,
|
MaxAttack = Stats.MaxAttack.Value,
|
||||||
CurrentDefense = Stats.CurrentDefense.Value,
|
CurrentDefense = Stats.CurrentDefense.Value,
|
||||||
BonusDefense = Stats.BonusDefense.Value,
|
BonusDefense = Stats.BonusDefense.Value,
|
||||||
MaxDefense = Stats.MaxDefense.Value,
|
MaxDefense = Stats.MaxDefense.Value,
|
||||||
CurrentExp = Stats.CurrentExp.Value,
|
CurrentExp = Stats.CurrentExp.Value,
|
||||||
CurrentLevel = Stats.CurrentLevel.Value,
|
CurrentLevel = Stats.CurrentLevel.Value,
|
||||||
ExpToNextLevel = Stats.ExpToNextLevel.Value,
|
ExpToNextLevel = Stats.ExpToNextLevel.Value,
|
||||||
Luck = Stats.Luck.Value
|
Luck = Stats.Luck.Value
|
||||||
},
|
},
|
||||||
Inventory = Inventory
|
Inventory = Inventory
|
||||||
},
|
},
|
||||||
onLoad: (chunk, data) =>
|
onLoad: (chunk, data) =>
|
||||||
{
|
{
|
||||||
Stats.Init(data.PlayerStats);
|
Stats.Init(data.PlayerStats);
|
||||||
Inventory = data.Inventory;
|
Inventory = data.Inventory;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
PlayerBinding = PlayerLogic.Bind();
|
PlayerBinding = PlayerLogic.Bind();
|
||||||
|
|
||||||
PlayerBinding
|
PlayerBinding
|
||||||
.Handle((in PlayerLogic.Output.Animations.Attack output) =>
|
.Handle((in PlayerLogic.Output.Animations.Attack output) =>
|
||||||
{
|
{
|
||||||
if (PlayerIsHittingGeometry())
|
if (PlayerIsHittingGeometry())
|
||||||
{
|
{
|
||||||
AnimationPlayer.Play("hit_wall");
|
AnimationPlayer.Play("hit_wall");
|
||||||
_gameRepo.OnPlayerAttackedWall();
|
_gameRepo.OnPlayerAttackedWall();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var attackSpeed = EquippedWeapon.Value.AttackSpeed;
|
var attackSpeed = ((Weapon)EquippedWeapon.Value).AttackSpeed;
|
||||||
AnimationPlayer.SetSpeedScale((float)attackSpeed);
|
AnimationPlayer.SetSpeedScale((float)attackSpeed);
|
||||||
AnimationPlayer.Play("attack");
|
AnimationPlayer.Play("attack");
|
||||||
_gameRepo.OnPlayerAttack();
|
_gameRepo.OnPlayerAttack();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.Handle((in PlayerLogic.Output.ThrowItem output) =>
|
.Handle((in PlayerLogic.Output.ThrowItem output) =>
|
||||||
{
|
{
|
||||||
})
|
})
|
||||||
.Handle((in PlayerLogic.Output.Move output) =>
|
.Handle((in PlayerLogic.Output.Move output) =>
|
||||||
{
|
{
|
||||||
Move(output.delta);
|
Move(output.delta);
|
||||||
});
|
});
|
||||||
|
|
||||||
GameChunk.AddChunk(PlayerChunk);
|
GameChunk.AddChunk(PlayerChunk);
|
||||||
|
|
||||||
PlayerLogic.Start();
|
PlayerLogic.Start();
|
||||||
this.Provide();
|
this.Provide();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnReady()
|
public void OnReady()
|
||||||
{
|
{
|
||||||
SetPhysicsProcess(true);
|
SetPhysicsProcess(true);
|
||||||
SwordSlashAnimation.Position = GetViewport().GetVisibleRect().Size / 2;
|
SwordSlashAnimation.Position = GetViewport().GetVisibleRect().Size / 2;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public void Attack()
|
public void Attack()
|
||||||
{
|
{
|
||||||
PlayerLogic.Input(new PlayerLogic.Input.Attack());
|
PlayerLogic.Input(new PlayerLogic.Input.Attack());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PlayerPause()
|
public void PlayerPause()
|
||||||
{
|
{
|
||||||
Game.TogglePause();
|
Game.TogglePause();
|
||||||
}
|
|
||||||
|
|
||||||
public IDungeonRoom GetCurrentRoom()
|
|
||||||
{
|
|
||||||
var rooms = Game.CurrentFloor.Rooms;
|
|
||||||
var playersRoom = rooms.SingleOrDefault(x => x.IsPlayerInRoom);
|
|
||||||
return playersRoom;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RaiseHP(int amountToRaise)
|
public void RaiseHP(int amountToRaise)
|
||||||
{
|
{
|
||||||
Stats.SetMaximumHP(Stats.MaximumHP.Value + amountToRaise);
|
Stats.SetMaximumHP(Stats.MaximumHP.Value + amountToRaise);
|
||||||
Stats.SetCurrentHP(Stats.MaximumHP.Value);
|
Stats.SetCurrentHP(Stats.MaximumHP.Value);
|
||||||
_gameRepo.AnnounceMessageInInventory($"{amountToRaise}MAXHP Up.");
|
_gameRepo.AnnounceMessageInInventory($"{amountToRaise}MAXHP Up.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HealHP(int amountToRestore)
|
public void HealHP(int amountToRestore)
|
||||||
{
|
{
|
||||||
Stats.SetCurrentHP(Stats.CurrentHP.Value + amountToRestore);
|
Stats.SetCurrentHP(Stats.CurrentHP.Value + amountToRestore);
|
||||||
var raiseString = amountToRestore == 1000 ? "MAX" : $"{amountToRestore}";
|
var raiseString = amountToRestore == 1000 ? "MAX" : $"{amountToRestore}";
|
||||||
_gameRepo.AnnounceMessageInInventory($"{raiseString}HP Restored.");
|
_gameRepo.AnnounceMessageInInventory($"{raiseString}HP Restored.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RaiseVT(int amountToRaise)
|
public void RaiseVT(int amountToRaise)
|
||||||
{
|
{
|
||||||
if (Stats.CurrentVT == Stats.MaximumVT)
|
if (Stats.CurrentVT == Stats.MaximumVT)
|
||||||
{
|
{
|
||||||
Stats.SetMaximumVT(Stats.MaximumVT.Value + amountToRaise);
|
Stats.SetMaximumVT(Stats.MaximumVT.Value + amountToRaise);
|
||||||
Stats.SetCurrentVT(Stats.MaximumVT.Value);
|
Stats.SetCurrentVT(Stats.MaximumVT.Value);
|
||||||
_gameRepo.AnnounceMessageInInventory($"{amountToRaise}MAXVT Up.");
|
_gameRepo.AnnounceMessageInInventory($"{amountToRaise}MAXVT Up.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HealVT(int amountToRestore)
|
public void HealVT(int amountToRestore)
|
||||||
{
|
{
|
||||||
Stats.SetCurrentVT(Stats.CurrentVT.Value + amountToRestore);
|
Stats.SetCurrentVT(Stats.CurrentVT.Value + amountToRestore);
|
||||||
var raiseString = amountToRestore == 1000 ? "MAX" : $"{amountToRestore}";
|
var raiseString = amountToRestore == 1000 ? "MAX" : $"{amountToRestore}";
|
||||||
_gameRepo.AnnounceMessageInInventory($"{raiseString}VT Restored.");
|
_gameRepo.AnnounceMessageInInventory($"{raiseString}VT Restored.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyBonusAttack(int amount)
|
public void ModifyBonusAttack(int amount)
|
||||||
{
|
{
|
||||||
Stats.SetBonusAttack(Stats.BonusAttack.Value + amount);
|
Stats.SetBonusAttack(Stats.BonusAttack.Value + amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyBonusDefense(int amount)
|
public void ModifyBonusDefense(int amount)
|
||||||
{
|
{
|
||||||
Stats.SetBonusDefense(Stats.BonusDefense.Value + amount);
|
Stats.SetBonusDefense(Stats.BonusDefense.Value + amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyMaximumHP(int amount)
|
public void ModifyMaximumHP(int amount)
|
||||||
{
|
{
|
||||||
Stats.SetMaximumHP(Stats.MaximumHP.Value + amount);
|
Stats.SetMaximumHP(Stats.MaximumHP.Value + amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyMaximumVT(int amount)
|
public void ModifyMaximumVT(int amount)
|
||||||
{
|
{
|
||||||
Stats.SetMaximumVT(Stats.MaximumVT.Value + amount);
|
Stats.SetMaximumVT(Stats.MaximumVT.Value + amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyBonusLuck(double amount)
|
public void ModifyBonusLuck(double amount)
|
||||||
{
|
{
|
||||||
Stats.SetLuck(Stats.Luck.Value + amount);
|
Stats.SetLuck(Stats.Luck.Value + amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Move(float delta)
|
public void Move(float delta)
|
||||||
{
|
{
|
||||||
var rawInput = GlobalInputVector;
|
var rawInput = GlobalInputVector;
|
||||||
var strafeLeftInput = LeftStrafeInputVector;
|
var strafeLeftInput = LeftStrafeInputVector;
|
||||||
var strafeRightInput = RightStrafeInputVector;
|
var strafeRightInput = RightStrafeInputVector;
|
||||||
|
|
||||||
var transform = Transform;
|
var transform = Transform;
|
||||||
transform.Basis = new Basis(Vector3.Up, Settings.RotationSpeed * -rawInput.X * delta) * transform.Basis;
|
transform.Basis = new Basis(Vector3.Up, Settings.RotationSpeed * -rawInput.X * delta) * transform.Basis;
|
||||||
var moveDirection = new Vector3(strafeRightInput - strafeLeftInput, 0, rawInput.Z).Normalized();
|
var moveDirection = new Vector3(strafeRightInput - strafeLeftInput, 0, rawInput.Z).Normalized();
|
||||||
var velocity = Basis * moveDirection * Settings.MoveSpeed * Settings.Acceleration;
|
var velocity = Basis * moveDirection * Settings.MoveSpeed * Settings.Acceleration;
|
||||||
_knockbackStrength = _knockbackStrength * 0.9f;
|
_knockbackStrength = _knockbackStrength * 0.9f;
|
||||||
Transform = Transform with { Basis = transform.Basis };
|
Transform = Transform with { Basis = transform.Basis };
|
||||||
Velocity = velocity + (_knockbackDirection * _knockbackStrength);
|
Velocity = velocity + (_knockbackDirection * _knockbackStrength);
|
||||||
MoveAndSlide();
|
MoveAndSlide();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TeleportPlayer(Transform3D newTransform)
|
public void TeleportPlayer(Transform3D newTransform)
|
||||||
{
|
{
|
||||||
Transform = newTransform;
|
Transform = newTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TakeDamage(double damage, ElementType elementType, bool isCriticalHit = false)
|
public void TakeDamage(double damage, ElementType elementType, bool isCriticalHit = false)
|
||||||
{
|
{
|
||||||
if (Stats.CurrentHP.Value > 0)
|
if (Stats.CurrentHP.Value > 0)
|
||||||
{
|
{
|
||||||
damage = CalculateDefenseResistance(damage);
|
damage = CalculateDefenseResistance(damage);
|
||||||
if (isCriticalHit)
|
if (isCriticalHit)
|
||||||
damage *= 2;
|
damage *= 2;
|
||||||
Stats.SetCurrentHP(Stats.CurrentHP.Value - (int)damage);
|
Stats.SetCurrentHP(Stats.CurrentHP.Value - (int)damage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Knockback(float impulse)
|
public void Knockback(float impulse)
|
||||||
{
|
{
|
||||||
_knockbackStrength = impulse;
|
_knockbackStrength = impulse;
|
||||||
_knockbackDirection = GlobalBasis.Z.Normalized();
|
_knockbackDirection = GlobalBasis.Z.Normalized();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GainExp(double expGained)
|
public void GainExp(double expGained)
|
||||||
{
|
{
|
||||||
Stats.SetCurrentExp(Stats.CurrentExp.Value + expGained);
|
Stats.SetCurrentExp(Stats.CurrentExp.Value + expGained);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LevelUp()
|
public void LevelUp()
|
||||||
{
|
{
|
||||||
var nextLevel = Stats.CurrentLevel.Value + 1;
|
var nextLevel = Stats.CurrentLevel.Value + 1;
|
||||||
var expToNextLevel = _expToNextLevel[nextLevel];
|
var expToNextLevel = _expToNextLevel[nextLevel];
|
||||||
var newCurrentExp = Mathf.Max(Stats.CurrentExp.Value - Stats.ExpToNextLevel.Value, 0);
|
var newCurrentExp = Mathf.Max(Stats.CurrentExp.Value - Stats.ExpToNextLevel.Value, 0);
|
||||||
Stats.SetCurrentLevel(nextLevel);
|
Stats.SetCurrentLevel(nextLevel);
|
||||||
Stats.SetExpToNextLevel(expToNextLevel);
|
Stats.SetExpToNextLevel(expToNextLevel);
|
||||||
Stats.SetCurrentExp(newCurrentExp);
|
Stats.SetCurrentExp(newCurrentExp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Die() => PlayerLogic.Input(new PlayerLogic.Input.Die());
|
public void Die() => PlayerLogic.Input(new PlayerLogic.Input.Die());
|
||||||
|
|
||||||
public override void _UnhandledInput(InputEvent @event)
|
public override void _UnhandledInput(InputEvent @event)
|
||||||
{
|
{
|
||||||
if (@event.IsActionPressed(GameInputs.Pause))
|
if (@event.IsActionPressed(GameInputs.Pause))
|
||||||
PlayerPause();
|
PlayerPause();
|
||||||
|
|
||||||
if (@event.IsActionPressed(GameInputs.Attack))
|
if (@event.IsActionPressed(GameInputs.Attack))
|
||||||
Attack();
|
Attack();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnPhysicsProcess(double delta)
|
public void OnPhysicsProcess(double delta)
|
||||||
{
|
{
|
||||||
PlayerLogic.Input(new PlayerLogic.Input.PhysicsTick(delta));
|
PlayerLogic.Input(new PlayerLogic.Input.PhysicsTick(delta));
|
||||||
PlayerLogic.Input(new PlayerLogic.Input.Moved(GlobalPosition, GlobalTransform));
|
PlayerLogic.Input(new PlayerLogic.Input.Moved(GlobalPosition, GlobalTransform));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Equip(EquipableItem equipable)
|
public void Equip(EquipableItem equipable)
|
||||||
{
|
{
|
||||||
if (equipable is Weapon weapon)
|
if (equipable is Weapon weapon)
|
||||||
{
|
{
|
||||||
Unequip(_equippedWeapon.Value);
|
Unequip(_equippedWeapon.Value);
|
||||||
weapon.IsEquipped = true;
|
weapon.IsEquipped = true;
|
||||||
_equippedWeapon.OnNext(weapon);
|
_equippedWeapon.OnNext(weapon);
|
||||||
}
|
}
|
||||||
else if (equipable is Armor armor)
|
else if (equipable is Armor armor)
|
||||||
{
|
{
|
||||||
Unequip(_equippedArmor.Value);
|
Unequip(_equippedArmor.Value);
|
||||||
armor.IsEquipped = true;
|
armor.IsEquipped = true;
|
||||||
_equippedArmor.OnNext(armor);
|
_equippedArmor.OnNext(armor);
|
||||||
}
|
}
|
||||||
else if (equipable is Accessory accessory)
|
else if (equipable is Accessory accessory)
|
||||||
{
|
{
|
||||||
Unequip(_equippedAccessory.Value);
|
Unequip(_equippedAccessory.Value);
|
||||||
accessory.IsEquipped = true;
|
accessory.IsEquipped = true;
|
||||||
_equippedAccessory.OnNext(accessory);
|
_equippedAccessory.OnNext(accessory);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw new NotImplementedException("Item type is not supported.");
|
throw new NotImplementedException("Item type is not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Unequip(EquipableItem equipable)
|
public void Unequip(EquipableItem equipable)
|
||||||
{
|
{
|
||||||
if (equipable is Weapon weapon)
|
if (equipable is Weapon weapon)
|
||||||
{
|
{
|
||||||
weapon.IsEquipped = false;
|
weapon.IsEquipped = false;
|
||||||
ModifyBonusAttack(-weapon.Damage);
|
ModifyBonusAttack(-weapon.Damage);
|
||||||
_equippedWeapon.OnNext(new Weapon());
|
_equippedWeapon.OnNext(new Weapon());
|
||||||
}
|
}
|
||||||
else if (equipable is Armor armor)
|
else if (equipable is Armor armor)
|
||||||
{
|
{
|
||||||
armor.IsEquipped = false;
|
armor.IsEquipped = false;
|
||||||
ModifyBonusDefense(-armor.Defense);
|
ModifyBonusDefense(-armor.Defense);
|
||||||
_equippedArmor.OnNext(new Armor());
|
_equippedArmor.OnNext(new Armor());
|
||||||
}
|
}
|
||||||
else if (equipable is Accessory accessory)
|
else if (equipable is Accessory accessory)
|
||||||
{
|
{
|
||||||
accessory.IsEquipped = false;
|
accessory.IsEquipped = false;
|
||||||
ModifyMaximumHP(-accessory.MaxHPUp);
|
ModifyMaximumHP(-accessory.MaxHPUp);
|
||||||
ModifyMaximumVT(-accessory.MaxVTUp);
|
ModifyMaximumVT(-accessory.MaxVTUp);
|
||||||
ModifyBonusAttack(-accessory.ATKUp);
|
ModifyBonusAttack(-accessory.ATKUp);
|
||||||
ModifyBonusDefense(-accessory.DEFUp);
|
ModifyBonusDefense(-accessory.DEFUp);
|
||||||
ModifyBonusLuck(-accessory.LuckUp);
|
ModifyBonusLuck(-accessory.LuckUp);
|
||||||
_equippedAccessory.OnNext(new Accessory());
|
_equippedAccessory.OnNext(new Accessory());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw new NotImplementedException("Item type is not supported.");
|
throw new NotImplementedException("Item type is not supported.");
|
||||||
|
|
||||||
if (equipable.ItemTag == ItemTag.BreaksOnChange)
|
if (equipable.ItemTag == ItemTag.BreaksOnChange)
|
||||||
Inventory.Remove(equipable);
|
Inventory.Remove(equipable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Vector3 GlobalInputVector
|
private static Vector3 GlobalInputVector
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var rawInput = Input.GetVector(GameInputs.MoveLeft, GameInputs.MoveRight, GameInputs.MoveUp, GameInputs.MoveDown);
|
var rawInput = Input.GetVector(GameInputs.MoveLeft, GameInputs.MoveRight, GameInputs.MoveUp, GameInputs.MoveDown);
|
||||||
var input = new Vector3
|
var input = new Vector3
|
||||||
{
|
{
|
||||||
X = rawInput.X,
|
X = rawInput.X,
|
||||||
Z = rawInput.Y
|
Z = rawInput.Y
|
||||||
};
|
};
|
||||||
return input with { Y = 0f };
|
return input with { Y = 0f };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float LeftStrafeInputVector
|
private static float LeftStrafeInputVector
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Input.GetActionStrength(GameInputs.StrafeLeft);
|
return Input.GetActionStrength(GameInputs.StrafeLeft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float RightStrafeInputVector
|
private static float RightStrafeInputVector
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Input.GetActionStrength(GameInputs.StrafeRight);
|
return Input.GetActionStrength(GameInputs.StrafeRight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThrowItem()
|
private void ThrowItem()
|
||||||
{
|
{
|
||||||
var itemScene = GD.Load<PackedScene>("res://src/items/throwable/ThrowableItem.tscn");
|
var itemScene = GD.Load<PackedScene>("res://src/items/throwable/ThrowableItem.tscn");
|
||||||
var throwItem = itemScene.Instantiate<ThrowableItem>();
|
var throwItem = itemScene.Instantiate<ThrowableItem>();
|
||||||
GetTree().Root.AddChildEx(throwItem);
|
GetTree().Root.AddChildEx(throwItem);
|
||||||
throwItem.GlobalPosition = CurrentPosition + new Vector3(0, 3.5f, 0);
|
throwItem.GlobalPosition = CurrentPosition + new Vector3(0, 3.5f, 0);
|
||||||
throwItem.GlobalRotation = GlobalRotation;
|
throwItem.GlobalRotation = GlobalRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAnimationFinished(StringName animation)
|
private void OnAnimationFinished(StringName animation)
|
||||||
{
|
{
|
||||||
PlayerLogic.Input(new PlayerLogic.Input.AttackAnimationFinished());
|
PlayerLogic.Input(new PlayerLogic.Input.AttackAnimationFinished());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnExitTree()
|
private void OnExitTree()
|
||||||
{
|
{
|
||||||
PlayerLogic.Stop();
|
PlayerLogic.Stop();
|
||||||
PlayerBinding.Dispose();
|
PlayerBinding.Dispose();
|
||||||
AnimationPlayer.AnimationFinished -= OnAnimationFinished;
|
AnimationPlayer.AnimationFinished -= OnAnimationFinished;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPlayerPositionUpdated(Vector3 globalPosition) => GlobalPosition = globalPosition;
|
private void OnPlayerPositionUpdated(Vector3 globalPosition) => GlobalPosition = globalPosition;
|
||||||
|
|
||||||
private void OnHealthTimerTimeout()
|
private void OnHealthTimerTimeout()
|
||||||
{
|
{
|
||||||
if (Stats.CurrentHP.Value <= 0)
|
if (Stats.CurrentHP.Value <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Stats.CurrentVT.Value > 0)
|
if (Stats.CurrentVT.Value > 0)
|
||||||
{
|
{
|
||||||
if (EquippedAccessory.Value.AccessoryTag == AccessoryTag.HalfVTConsumption)
|
if (((Accessory)EquippedAccessory.Value).AccessoryTag == AccessoryTag.HalfVTConsumption)
|
||||||
{
|
{
|
||||||
reduceOnTick = !reduceOnTick;
|
reduceOnTick = !reduceOnTick;
|
||||||
}
|
}
|
||||||
Stats.SetCurrentHP(Stats.CurrentHP.Value + 1);
|
Stats.SetCurrentHP(Stats.CurrentHP.Value + 1);
|
||||||
if (reduceOnTick)
|
if (reduceOnTick)
|
||||||
Stats.SetCurrentVT(Stats.CurrentVT.Value - 1);
|
Stats.SetCurrentVT(Stats.CurrentVT.Value - 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Stats.SetCurrentHP(Stats.CurrentHP.Value - 1);
|
Stats.SetCurrentHP(Stats.CurrentHP.Value - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EquippedWeapon_Sync(Weapon obj)
|
private void EquippedWeapon_Sync(EquipableItem obj)
|
||||||
{
|
{
|
||||||
ModifyBonusAttack(obj.Damage);
|
ModifyBonusAttack(((Weapon)obj).Damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EquippedArmor_Sync(Armor obj)
|
private void EquippedArmor_Sync(EquipableItem obj)
|
||||||
{
|
{
|
||||||
ModifyBonusDefense(obj.Defense);
|
ModifyBonusDefense(((Armor)obj).Defense);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EquippedAccessory_Sync(Accessory accessory)
|
private void EquippedAccessory_Sync(EquipableItem accessory)
|
||||||
{
|
{
|
||||||
ModifyMaximumHP(accessory.MaxHPUp);
|
ModifyMaximumHP(((Accessory)accessory).MaxHPUp);
|
||||||
ModifyMaximumVT(accessory.MaxVTUp);
|
ModifyMaximumVT(((Accessory)accessory).MaxVTUp);
|
||||||
ModifyBonusAttack(accessory.ATKUp);
|
ModifyBonusAttack(((Accessory)accessory).ATKUp);
|
||||||
ModifyBonusDefense(accessory.DEFUp);
|
ModifyBonusDefense(((Accessory)accessory).DEFUp);
|
||||||
ModifyBonusLuck(accessory.LuckUp);
|
ModifyBonusLuck(((Accessory)accessory).LuckUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CurrentHP_Sync(int newHealth)
|
private void CurrentHP_Sync(int newHealth)
|
||||||
{
|
{
|
||||||
if (newHealth <= 0)
|
if (newHealth <= 0)
|
||||||
Die();
|
Die();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CurrentEXP_Sync(double newExp)
|
private void CurrentEXP_Sync(double newExp)
|
||||||
{
|
{
|
||||||
if (Stats.CurrentExp.Value >= Stats.ExpToNextLevel.Value)
|
if (Stats.CurrentExp.Value >= Stats.ExpToNextLevel.Value)
|
||||||
LevelUp();
|
LevelUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
private double CalculateDefenseResistance(double incomingDamage)
|
private double CalculateDefenseResistance(double incomingDamage)
|
||||||
{
|
{
|
||||||
return Mathf.Max(incomingDamage - Stats.CurrentDefense.Value - Stats.BonusDefense.Value, 0.0);
|
return Mathf.Max(incomingDamage - Stats.CurrentDefense.Value - Stats.BonusDefense.Value, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Hitbox_AreaEntered(Area3D area)
|
private void Hitbox_AreaEntered(Area3D area)
|
||||||
{
|
{
|
||||||
var target = area.GetOwner();
|
var target = area.GetOwner();
|
||||||
if (target is IEnemy enemy)
|
if (target is IEnemy enemy)
|
||||||
HitEnemy(enemy);
|
HitEnemy(enemy);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HitEnemy(IEnemy enemy)
|
private void HitEnemy(IEnemy enemy)
|
||||||
{
|
{
|
||||||
var attackValue = Stats.CurrentAttack.Value + Stats.BonusAttack.Value;
|
var attackValue = Stats.CurrentAttack.Value + Stats.BonusAttack.Value;
|
||||||
var ignoreElementalResistance = EquippedWeapon.Value.WeaponTag == WeaponTag.IgnoreAffinity;
|
var ignoreElementalResistance = ((Weapon)EquippedWeapon.Value).WeaponTag == WeaponTag.IgnoreAffinity;
|
||||||
var isCriticalHit = BattleExtensions.IsCriticalHit(Stats.Luck.Value);
|
var isCriticalHit = BattleExtensions.IsCriticalHit(Stats.Luck.Value);
|
||||||
var element = EquippedWeapon.Value.WeaponElement;
|
var element = ((Weapon)EquippedWeapon.Value).WeaponElement;
|
||||||
|
|
||||||
enemy.TakeDamage(
|
enemy.TakeDamage(
|
||||||
attackValue * EquippedWeapon.Value.ElementalDamageBonus,
|
attackValue * ((Weapon)EquippedWeapon.Value).ElementalDamageBonus,
|
||||||
element,
|
element,
|
||||||
isCriticalHit,
|
isCriticalHit,
|
||||||
false,
|
false,
|
||||||
ignoreElementalResistance);
|
ignoreElementalResistance);
|
||||||
|
|
||||||
if (EquippedWeapon.Value.WeaponTag == WeaponTag.Knockback)
|
if (((Weapon)EquippedWeapon.Value).WeaponTag == WeaponTag.Knockback)
|
||||||
enemy.Knockback(0.3f, -CurrentBasis.Z.Normalized());
|
enemy.Knockback(0.3f, -CurrentBasis.Z.Normalized());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CollisionDetector_AreaEntered(Area3D area)
|
private void CollisionDetector_AreaEntered(Area3D area)
|
||||||
{
|
{
|
||||||
if (area.GetParent() is InventoryItem inventoryItem)
|
if (area.GetParent() is InventoryItem inventoryItem)
|
||||||
{
|
{
|
||||||
var isAdded = Inventory.TryAdd(inventoryItem);
|
var isAdded = Inventory.TryAdd(inventoryItem);
|
||||||
if (isAdded)
|
if (isAdded)
|
||||||
{
|
{
|
||||||
_gameRepo.AnnounceMessageOnMainScreen($"{inventoryItem.ItemName} picked up.");
|
_gameRepo.AnnounceMessageOnMainScreen($"{inventoryItem.ItemName} picked up.");
|
||||||
inventoryItem.QueueFree();
|
inventoryItem.QueueFree();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_gameRepo.AnnounceMessageOnMainScreen($"Could not pick up {inventoryItem.ItemName}.");
|
_gameRepo.AnnounceMessageOnMainScreen($"Could not pick up {inventoryItem.ItemName}.");
|
||||||
}
|
}
|
||||||
if (area.GetParent() is DroppedItem droppedItem)
|
if (area.GetParent() is DroppedItem droppedItem)
|
||||||
{
|
{
|
||||||
var isAdded = Inventory.TryAdd(droppedItem.Item);
|
var isAdded = Inventory.TryAdd(droppedItem.Item);
|
||||||
if (isAdded)
|
if (isAdded)
|
||||||
{
|
{
|
||||||
_gameRepo.AnnounceMessageOnMainScreen($"{droppedItem.Item.ItemName} picked up.");
|
_gameRepo.AnnounceMessageOnMainScreen($"{droppedItem.Item.ItemName} picked up.");
|
||||||
droppedItem.QueueFree();
|
droppedItem.QueueFree();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_gameRepo.AnnounceMessageOnMainScreen($"Could not pick up {droppedItem.Item.ItemName}.");
|
_gameRepo.AnnounceMessageOnMainScreen($"Could not pick up {droppedItem.Item.ItemName}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool PlayerIsHittingGeometry()
|
private bool PlayerIsHittingGeometry()
|
||||||
{
|
{
|
||||||
var collisions = WallCheck.GetCollidingBodies();
|
var collisions = WallCheck.GetCollidingBodies();
|
||||||
return collisions.Count > 0;
|
return collisions.Count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WallCheck_BodyEntered(Node body)
|
private void WallCheck_BodyEntered(Node body)
|
||||||
{
|
{
|
||||||
PlayerLogic.Input(new PlayerLogic.Input.AttackAnimationFinished());
|
PlayerLogic.Input(new PlayerLogic.Input.AttackAnimationFinished());
|
||||||
GD.Print("Hit wall");
|
GD.Print("Hit wall");
|
||||||
AnimationPlayer.Stop();
|
AnimationPlayer.Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
|||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Abstractions;
|
||||||
|
|
||||||
public interface IKillable
|
public interface IKillable
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using Chickensoft.AutoInject;
|
|||||||
using Chickensoft.GodotNodeInterfaces;
|
using Chickensoft.GodotNodeInterfaces;
|
||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user