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();

View File

@@ -1,10 +1,8 @@
[gd_scene load_steps=62 format=4 uid="uid://cfecvvav8kkp6"]
[gd_scene load_steps=60 format=4 uid="uid://cfecvvav8kkp6"]
[ext_resource type="Script" uid="uid://yxmiqy7i0t7r" path="res://src/player/Player.cs" id="1_xcol5"]
[ext_resource type="Script" uid="uid://s6ku2kyc4rbk" path="res://src/player/PlayerStatResource.cs" id="2_ebyyx"]
[ext_resource type="Script" uid="uid://6edayafleq8y" path="res://src/hitbox/Hitbox.cs" id="2_lb3qc"]
[ext_resource type="Script" uid="uid://s6ku2kyc4rbk" path="res://src/player/PlayerStatResource.cs" id="2_xq68d"]
[ext_resource type="Resource" uid="uid://bpdbuf0k0exb5" path="res://src/items/weapons/resources/Swan Sword Odette.tres" id="3_es4xk"]
[ext_resource type="Resource" uid="uid://ce2vfa2t3io67" path="res://src/items/armor/resources/AtonersAdornments.tres" id="4_bj1ma"]
[ext_resource type="Texture2D" uid="uid://c6r3dhnkuw22w" path="res://src/vfx/hit_effects/FIRE_STRIKE_1.0.png" id="5_wr6lo"]
[ext_resource type="Texture2D" uid="uid://m6xsyhnt67sh" path="res://src/player/dont_look_in_here/tendomaya_body0_tex00.png" id="6_es4xk"]
[ext_resource type="Texture2D" uid="uid://b5qjlbcesth53" path="res://src/vfx/Weapon Strikes/NON ELEMENTAL SLASH.png" id="6_p34sl"]
@@ -12,25 +10,26 @@
[ext_resource type="Texture2D" uid="uid://qxq1jjr1cojo" path="res://src/player/dont_look_in_here/tendomaya_face10_tex00.png" id="7_g183x"]
[ext_resource type="Texture2D" uid="uid://brr8uow0xte2o" path="res://src/player/dont_look_in_here/tendomaya_face20_tex00.png" id="8_ojh85"]
[sub_resource type="Resource" id="Resource_btp2w"]
script = ExtResource("2_xq68d")
[sub_resource type="Resource" id="Resource_bj1ma"]
script = ExtResource("2_ebyyx")
RotationSpeed = 1.5
MoveSpeed = 8.0
Acceleration = 1.0
CurrentHP = 100
MoveSpeed = 4.0
Acceleration = 2.0
CurrentHP = 1
MaximumHP = 100
CurrentVT = 0
MaximumVT = 90
CurrentVT = 1
MaximumVT = 100
CurrentExp = 0
ExpToNextLevel = 10
ExpToNextLevel = 12
CurrentLevel = 1
CurrentAttack = 8
CurrentAttack = 10
BonusAttack = 0
MaxAttack = 8
CurrentDefense = 1
MaxAttack = 10
CurrentDefense = 10
BonusDefense = 0
MaxDefense = 1
Luck = 0.05
MaxDefense = 10
Luck = 0.1
metadata/_custom_type_script = "uid://s6ku2kyc4rbk"
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_dw45s"]
radius = 1.0
@@ -490,9 +489,7 @@ height = 1.6909
collision_layer = 806
collision_mask = 775
script = ExtResource("1_xcol5")
PlayerStatResource = SubResource("Resource_btp2w")
_defaultWeapon = ExtResource("3_es4xk")
_defaultArmor = ExtResource("4_bj1ma")
_playerStatResource = SubResource("Resource_bj1ma")
[node name="PlayerGeometryCollision" type="CollisionShape3D" parent="."]
transform = Transform3D(-0.0242402, 0, 0.999706, 0, 1, 0, -0.999706, 0, -0.0242402, 0, 1.06447, -0.153069)

View File

@@ -17,11 +17,11 @@ public partial class PlayerStatResource : Resource
[Export(PropertyHint.Range, "0, 100, 0.1")]
public float Acceleration { get; set; } = 4f;
[Export] public int CurrentHP { get; set; }
[Export] public int MaximumHP { get; set; }
[Export(PropertyHint.Range, "1, 200, 1")] public int CurrentHP { get; set; }
[Export(PropertyHint.Range, "1, 200, 1")] public int MaximumHP { get; set; }
[Export] public int CurrentVT { get; set; }
[Export] public int MaximumVT { get; set; }
[Export(PropertyHint.Range, "1, 200, 1")] public int CurrentVT { get; set; }
[Export(PropertyHint.Range, "1, 200, 1")] public int MaximumVT { get; set; }
[Export] public int CurrentExp { get; set; }
[Export] public int ExpToNextLevel { get; set; }