Overhaul game state logic to support gameplay loop

This commit is contained in:
2025-04-30 00:43:55 -07:00
parent 78cdda97b9
commit 68c91d8f13
60 changed files with 2503 additions and 1116 deletions

View File

@@ -31,7 +31,8 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
public Vector3 CurrentPosition => GlobalPosition;
public Basis CurrentBasis => Transform.Basis;
public PlayerStatController Stats { get; set; } = default!;
public PlayerStats Stats { get; set; } = default!;
public IInventory Inventory { get; private set; } = default!;
@@ -61,12 +62,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
#region Exports
[Export]
public PlayerStatResource PlayerStatResource { get; set; } = default!;
[Export]
private WeaponStats _defaultWeapon { get; set; } = default!;
[Export]
private ArmorStats _defaultArmor { get; set; } = default!;
private PlayerStatResource _playerStatResource { get; set; } = default!;
#endregion
#region Node Dependencies
@@ -100,6 +96,32 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
#region Initialization
public void InitializePlayerState()
{
Inventory = new Inventory();
Stats = InitializePlayerStats();
SetProcessInput(false);
SetPhysicsProcess(false);
EquippedWeapon.Changed += EquippedWeapon_Sync;
EquippedArmor.Changed += EquippedArmor_Sync;
EquippedAccessory.Changed += EquippedAccessory_Sync;
Stats.CurrentHP.Changed += CurrentHP_Sync;
Stats.CurrentExp.Changed += CurrentEXP_Sync;
HealthTimer.WaitTime = _healthTimerWaitTime;
HealthTimer.Timeout += OnHealthTimerTimeout;
}
public void Setup()
{
var container = new SimpleInjector.Container();
container.Register<IPlayerLogic, PlayerLogic>(Lifestyle.Singleton);
//container.Verify();
PlayerLogic = container.GetInstance<IPlayerLogic>();
PlayerLogic.Set(this as IPlayer);
PlayerLogic.Set(Settings);
PlayerLogic.Set(Stats);
PlayerLogic.Set(_gameRepo);
_expToNextLevel = new Dictionary<int, int>
{
{ 2, 12 },
@@ -112,97 +134,38 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
};
_damageCalculator = new DamageCalculator();
Stats = new PlayerStatController();
Stats.Init(
new PlayerStats
{
CurrentHP = PlayerStatResource.CurrentHP,
MaximumHP = PlayerStatResource.MaximumHP,
CurrentVT = PlayerStatResource.CurrentVT,
MaximumVT = PlayerStatResource.MaximumVT,
CurrentAttack = PlayerStatResource.CurrentAttack,
BonusAttack = PlayerStatResource.BonusAttack,
MaxAttack = PlayerStatResource.MaxAttack,
CurrentDefense = PlayerStatResource.CurrentDefense,
BonusDefense = PlayerStatResource.BonusDefense,
MaxDefense = PlayerStatResource.MaxDefense,
CurrentExp = PlayerStatResource.CurrentExp,
CurrentLevel = PlayerStatResource.CurrentLevel,
ExpToNextLevel = PlayerStatResource.ExpToNextLevel,
Luck = PlayerStatResource.Luck
});
Inventory = new Inventory();
var defaultWeapon = new Weapon
{
Stats = _defaultWeapon
};
var defaultArmor = new Armor
{
Stats = _defaultArmor
};
Inventory.TryAdd(defaultWeapon);
Inventory.TryAdd(defaultArmor);
Equip(defaultWeapon);
Equip(defaultArmor);
EquippedWeapon.Sync += EquippedWeapon_Sync;
EquippedArmor.Sync += EquippedArmor_Sync;
EquippedAccessory.Sync += EquippedAccessory_Sync;
Stats.CurrentHP.Sync += CurrentHP_Sync;
Stats.CurrentExp.Sync += CurrentEXP_Sync;
HealthTimer.WaitTime = _healthTimerWaitTime;
HealthTimer.Timeout += OnHealthTimerTimeout;
Hitbox.AreaEntered += Hitbox_AreaEntered;
CollisionDetector.AreaEntered += CollisionDetector_AreaEntered;
AnimationPlayer.AnimationFinished += OnAnimationFinished;
}
public void Setup()
{
var container = new SimpleInjector.Container();
container.Register<IPlayerLogic, PlayerLogic>(Lifestyle.Singleton);
//container.Verify();
Settings = new PlayerLogic.Settings() { RotationSpeed = PlayerStatResource.RotationSpeed, MoveSpeed = PlayerStatResource.MoveSpeed, Acceleration = PlayerStatResource.Acceleration };
PlayerLogic = container.GetInstance<IPlayerLogic>();
PlayerLogic.Set(this as IPlayer);
PlayerLogic.Set(Settings);
PlayerLogic.Set(Stats);
PlayerLogic.Set(_gameRepo);
}
public void OnResolved()
{
Settings = new PlayerLogic.Settings() { RotationSpeed = _playerStatResource.RotationSpeed, MoveSpeed = _playerStatResource.MoveSpeed, Acceleration = _playerStatResource.Acceleration };
PlayerChunk = new SaveChunk<PlayerData>(
onSave: (chunk) => new PlayerData()
{
PlayerStats = new PlayerStats()
{
CurrentHP = Stats.CurrentHP.Value,
MaximumHP = Stats.MaximumHP.Value,
CurrentVT = Stats.CurrentVT.Value,
MaximumVT = Stats.MaximumVT.Value,
CurrentAttack = Stats.CurrentAttack.Value,
BonusAttack = Stats.BonusAttack.Value,
MaxAttack = Stats.MaxAttack.Value,
CurrentDefense = Stats.CurrentDefense.Value,
BonusDefense = Stats.BonusDefense.Value,
MaxDefense = Stats.MaxDefense.Value,
CurrentExp = Stats.CurrentExp.Value,
CurrentLevel = Stats.CurrentLevel.Value,
ExpToNextLevel = Stats.ExpToNextLevel.Value,
Luck = Stats.Luck.Value
},
PlayerStats = Stats,
Inventory = Inventory
},
onLoad: (chunk, data) =>
{
Stats.Init(data.PlayerStats);
Stats = new PlayerStats(
data.PlayerStats.CurrentHP,
data.PlayerStats.MaximumHP,
data.PlayerStats.CurrentVT,
data.PlayerStats.MaximumVT,
data.PlayerStats.CurrentAttack,
data.PlayerStats.BonusAttack,
data.PlayerStats.MaxAttack,
data.PlayerStats.CurrentDefense,
data.PlayerStats.BonusDefense,
data.PlayerStats.MaxDefense,
data.PlayerStats.CurrentExp,
data.PlayerStats.CurrentLevel,
data.PlayerStats.ExpToNextLevel,
data.PlayerStats.Luck);
Inventory = data.Inventory;
}
);
@@ -234,25 +197,29 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
PlayerLogic.Start();
this.Provide();
SetProcessInput(false);
SetPhysicsProcess(false);
}
public void OnReady()
{
SetPhysicsProcess(true);
SwordSlashAnimation.Position = GetViewport().GetVisibleRect().Size / 2;
}
#endregion
public void Activate()
{
SetProcessInput(true);
SetPhysicsProcess(true);
HealthTimer.Start();
}
public void Attack()
{
PlayerLogic.Input(new PlayerLogic.Input.Attack());
}
public void PlayerPause()
{
Game.TogglePause();
}
public void RaiseHP(int amountToRaise)
{
Stats.SetMaximumHP(Stats.MaximumHP.Value + amountToRaise);
@@ -374,17 +341,17 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
HealthTimer.WaitTime = _healthTimerWaitTime;
HealthTimer.Timeout -= OnHealthTimerTimeout;
Hitbox.AreaEntered -= Hitbox_AreaEntered;
CollisionDetector.AreaEntered -= CollisionDetector_AreaEntered;
AnimationPlayer.AnimationFinished -= OnAnimationFinished;
PlayerLogic.Input(new PlayerLogic.Input.Die());
SetProcessInput(false);
SetPhysicsProcess(false);
//Hitbox.AreaEntered -= Hitbox_AreaEntered;
//CollisionDetector.AreaEntered -= CollisionDetector_AreaEntered;
//AnimationPlayer.AnimationFinished -= OnAnimationFinished;
Game.GameOver();
}
public override void _UnhandledInput(InputEvent @event)
public override void _Input(InputEvent @event)
{
if (@event.IsActionPressed(GameInputs.Pause))
PlayerPause();
if (@event.IsActionPressed(GameInputs.Attack))
Attack();
}
@@ -637,6 +604,27 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
}
}
private PlayerStats InitializePlayerStats()
{
var playerStats = new PlayerStats(
currentHP: new AutoProp<int>(_playerStatResource.CurrentHP),
maximumHP: new AutoProp<int>(_playerStatResource.MaximumHP),
currentVT: new AutoProp<int>(_playerStatResource.CurrentVT),
maximumVT: new AutoProp<int>(_playerStatResource.MaximumVT),
currentAttack: new AutoProp<int>(_playerStatResource.CurrentAttack),
currentDefense: new AutoProp<int>(_playerStatResource.CurrentDefense),
maxAttack: new AutoProp<int>(_playerStatResource.MaxAttack),
maxDefense: new AutoProp<int>(_playerStatResource.MaxDefense),
bonusAttack: new AutoProp<int>(_playerStatResource.BonusAttack),
bonusDefense: new AutoProp<int>(_playerStatResource.BonusDefense),
currentExp: new AutoProp<double>(_playerStatResource.CurrentExp),
expToNextLevel: new AutoProp<int>(_playerStatResource.ExpToNextLevel),
currentLevel: new AutoProp<int>(_playerStatResource.CurrentLevel),
luck: new AutoProp<double>(_playerStatResource.Luck));
return playerStats;
}
private bool PlayerIsHittingGeometry()
{
var collisions = WallCheck.GetCollidingBodies();