Massive refactor (inventory menu still a little broken but its Good Enough)

This commit is contained in:
2024-09-12 02:24:14 -07:00
parent 149c8d9571
commit b4662a0c7b
94 changed files with 1066 additions and 825 deletions

View File

@@ -9,12 +9,8 @@ namespace GameJamDungeon
{
public interface IPlayer : ICharacterBody3D, IKillable
{
PlayerStatInfo PlayerStatInfo { get; }
PlayerLogic PlayerLogic { get; }
PlayerData PlayerData { get; }
public Vector3 GetGlobalInputVector();
public float GetLeftStrafeInputVector();
@@ -38,27 +34,13 @@ namespace GameJamDungeon
[Dependency]
public ISaveChunk<GameData> GameChunk => this.DependOn<ISaveChunk<GameData>>();
/// <summary>Rotation speed (quaternions?/sec).</summary>
[Export(PropertyHint.Range, "0, 100, 0.1")]
public float RotationSpeed { get; set; } = 12.0f;
/// <summary>Player speed (meters/sec).</summary>
[Export(PropertyHint.Range, "0, 100, 0.1")]
public float MoveSpeed { get; set; } = 8f;
/// <summary>Player speed (meters^2/sec).</summary>
[Export(PropertyHint.Range, "0, 100, 0.1")]
public float Acceleration { get; set; } = 4f;
[Export]
public PlayerStatInfo PlayerStatInfo { get; set; }
public PlayerStatResource PlayerStatResource { get; set; } = default!;
public PlayerLogic.Settings Settings { get; set; } = default!;
public PlayerLogic PlayerLogic { get; set; } = default!;
public PlayerData PlayerData { get; set; } = default!;
public PlayerLogic.IBinding PlayerBinding { get; set; } = default!;
[Node] public IAnimationPlayer AnimationPlayer { get; set; } = default!;
@@ -69,14 +51,10 @@ namespace GameJamDungeon
[Node] public Timer HealthTimer { get; set; } = default!;
[Node] public Label HPNumber { get; set; } = default!;
[Node] public Label VTNumber { get; set; } = default!;
[Node] public Label LevelNumber { get; set; } = default!;
[Node] public IArea3D CollisionDetector { get; set; } = default!;
private PlayerData PlayerData { get; set; } = default!;
public void Initialize()
{
AnimationPlayer.AnimationFinished += OnAnimationFinished;
@@ -84,7 +62,29 @@ namespace GameJamDungeon
public void Setup()
{
Settings = new PlayerLogic.Settings() { RotationSpeed = RotationSpeed, MoveSpeed = MoveSpeed, Acceleration = Acceleration };
Settings = new PlayerLogic.Settings() { RotationSpeed = PlayerStatResource.RotationSpeed, MoveSpeed = PlayerStatResource.MoveSpeed, Acceleration = PlayerStatResource.Acceleration };
PlayerData = new PlayerData()
{
GlobalTransform = GlobalTransform,
StateMachine = PlayerLogic,
Velocity = Velocity,
Inventory = new Inventory(),
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),
MaxAttack = new AutoProp<int>(PlayerStatResource.MaxAttack),
CurrentDefense = new AutoProp<int>(PlayerStatResource.CurrentDefense),
MaxDefense = new AutoProp<int>(PlayerStatResource.MaxDefense),
CurrentExp = new AutoProp<int>(PlayerStatResource.CurrentExp),
ExpToNextLevel = new AutoProp<int>(PlayerStatResource.ExpToNextLevel),
CurrentLevel = new AutoProp<int>(PlayerStatResource.CurrentLevel),
BonusAttack = new AutoProp<int>(PlayerStatResource.BonusAttack),
BonusDefense = new AutoProp<int>(PlayerStatResource.BonusDefense),
Luck = new AutoProp<double>(PlayerStatResource.Luck)
};
PlayerLogic = new PlayerLogic();
PlayerLogic.Set(this as IPlayer);
@@ -92,6 +92,12 @@ namespace GameJamDungeon
PlayerLogic.Set(AppRepo);
PlayerLogic.Set(GameRepo);
PlayerLogic.Set(PlayerData);
PlayerData.Inventory.EquippedWeapon.Sync += EquippedWeapon_Sync;
PlayerData.Inventory.EquippedArmor.Sync += EquippedArmor_Sync;
PlayerData.Inventory.EquippedAccessory.Sync += EquippedAccessory_Sync;
PlayerData.CurrentHP.Sync += CurrentHP_Sync;
}
public void OnResolved()
@@ -106,9 +112,8 @@ namespace GameJamDungeon
})
.Handle((in PlayerLogic.Output.Animations.Attack output) =>
{
var weaponInfo = GameRepo.EquippedWeapon.Value.WeaponInfo;
var attackSpeed = (float)weaponInfo.AttackSpeed;
AnimationPlayer.SetSpeedScale(attackSpeed);
var attackSpeed = PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.AttackSpeed;
AnimationPlayer.SetSpeedScale((float)attackSpeed);
AnimationPlayer.Play("attack");
})
.Handle((in PlayerLogic.Output.ThrowItem output) =>
@@ -117,11 +122,10 @@ namespace GameJamDungeon
this.Provide();
PlayerLogic.Start();
GameRepo.SetPlayerData(PlayerData);
SwordSlashAnimation.Position = GetViewport().GetVisibleRect().Size / 2;
GlobalPosition = GameRepo.PlayerGlobalPosition.Value;
GameRepo.SetPlayerStatInfo(PlayerStatInfo);
GameRepo.PlayerGlobalPosition.Sync += PlayerGlobalPosition_Sync;
HealthTimer.Timeout += OnHealthTimerTimeout;
CollisionDetector.AreaEntered += OnEnemyHitBoxEntered;
}
@@ -142,26 +146,6 @@ namespace GameJamDungeon
Settings.MoveSpeed /= 4;
}
private void OnEnemyHitBoxEntered(Area3D area)
{
if (area is IHitbox hitBox)
{
if (GameRepo.PlayerStatInfo.Value.CurrentHP > 0)
{
var enemy = hitBox.GetParent<IEnemy>();
var isCriticalHit = false;
var rng = new RandomNumberGenerator();
rng.Randomize();
var roll = rng.Randf();
if (roll <= enemy.EnemyStatInfo.Luck)
isCriticalHit = true;
var damage = DamageCalculator.CalculateEnemyDamage(PlayerStatInfo, enemy.EnemyStatInfo, GameRepo.EquippedArmor.Value.ArmorInfo, isCriticalHit);
GameRepo.PlayerStatInfo.Value.CurrentHP = GameRepo.PlayerStatInfo.Value.CurrentHP - damage;
GD.Print($"Player hit for {damage} damage.");
}
}
}
public void OnPhysicsProcess(double delta)
{
PlayerLogic.Input(new PlayerLogic.Input.PhysicsTick(delta));
@@ -171,13 +155,6 @@ namespace GameJamDungeon
PlayerLogic.Input(new PlayerLogic.Input.Moved(GlobalPosition));
}
public override void _Process(double delta)
{
OnHPChanged(GameRepo.PlayerStatInfo.Value.CurrentHP);
OnVTChanged(GameRepo.PlayerStatInfo.Value.CurrentVT);
OnLevelChanged(GameRepo.PlayerStatInfo.Value.CurrentLevel);
}
public Vector3 GetGlobalInputVector()
{
var rawInput = Input.GetVector(GameInputs.MoveLeft, GameInputs.MoveRight, GameInputs.MoveUp, GameInputs.MoveDown);
@@ -226,35 +203,72 @@ namespace GameJamDungeon
public void Kill() => PlayerLogic.Input(new PlayerLogic.Input.Killed());
private void OnHPChanged(double newHP)
private void PlayerGlobalPosition_Sync(Vector3 newPlayerPosition)
{
HPNumber.Text = $"{Mathf.RoundToInt(newHP)}/{PlayerStatInfo.MaximumHP}";
if (newHP <= 0.0)
{
PlayerLogic.Input(new PlayerLogic.Input.Killed());
HealthTimer.Stop();
}
}
private void OnVTChanged(int newVT)
{
VTNumber.Text = $"{newVT}/{PlayerStatInfo.MaximumVT}";
}
private void OnLevelChanged(int newLevel)
{
LevelNumber.Text = $"{newLevel}";
GlobalPosition = newPlayerPosition;
}
private void OnPlayerPositionUpdated(Vector3 globalPosition) => GlobalPosition = globalPosition;
private void OnHealthTimerTimeout()
{
if (GameRepo.PlayerStatInfo.Value.CurrentVT > 0)
GameRepo.PlayerStatInfo.Value.CurrentVT = GameRepo.PlayerStatInfo.Value.CurrentVT - 1;
if (PlayerData.CurrentVT.Value > 0)
PlayerData.CurrentVT.OnNext(PlayerData.CurrentVT.Value - 1);
else
GameRepo.PlayerStatInfo.Value.CurrentHP = GameRepo.PlayerStatInfo.Value.CurrentHP - 1;
PlayerData.CurrentHP.OnNext(PlayerData.CurrentHP.Value - 1);
}
private void EquippedAccessory_Sync(Accessory equippedItem)
{
PlayerData.BonusAttack.OnNext(PlayerData.BonusAttack.Value - PlayerData.Inventory.EquippedAccessory.Value.AccessoryInfo.ATKUp);
PlayerData.BonusDefense.OnNext(PlayerData.BonusDefense.Value - PlayerData.Inventory.EquippedAccessory.Value.AccessoryInfo.DEFUp);
PlayerData.MaximumHP.OnNext(PlayerData.MaximumHP.Value - PlayerData.Inventory.EquippedAccessory.Value.AccessoryInfo.MaxHPUp);
PlayerData.MaximumVT.OnNext(PlayerData.MaximumVT.Value - PlayerData.Inventory.EquippedAccessory.Value.AccessoryInfo.MaxVTUp);
PlayerData.Luck.OnNext(PlayerData.Luck.Value - PlayerData.Inventory.EquippedAccessory.Value.AccessoryInfo.LUCKUp);
PlayerData.BonusAttack.OnNext(PlayerData.BonusAttack.Value + equippedItem.AccessoryInfo.ATKUp);
PlayerData.BonusDefense.OnNext(PlayerData.BonusDefense.Value + equippedItem.AccessoryInfo.DEFUp);
PlayerData.MaximumHP.OnNext(PlayerData.MaximumHP.Value + equippedItem.AccessoryInfo.MaxHPUp);
PlayerData.MaximumVT.OnNext(PlayerData.MaximumVT.Value + equippedItem.AccessoryInfo.MaxVTUp);
PlayerData.Luck.OnNext(PlayerData.Luck.Value + equippedItem.AccessoryInfo.LUCKUp);
PlayerData.Inventory.Equip(equippedItem);
}
private void EquippedArmor_Sync(Armor equippedItem)
{
PlayerData.BonusDefense.OnNext(PlayerData.BonusDefense.Value - PlayerData.Inventory.EquippedArmor.Value.ArmorStats.Defense);
PlayerData.BonusDefense.OnNext(PlayerData.BonusDefense.Value + equippedItem.ArmorStats.Defense);
PlayerData.Inventory.Equip(equippedItem);
}
private void EquippedWeapon_Sync(Weapon equippedItem)
{
PlayerData.BonusAttack.OnNext(PlayerData.BonusAttack.Value - PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.Damage);
PlayerData.BonusAttack.OnNext(PlayerData.BonusAttack.Value + equippedItem.WeaponStats.Damage);
PlayerData.Inventory.Equip(equippedItem);
}
private void OnEnemyHitBoxEntered(Area3D area)
{
if (area is IHitbox hitBox)
{
var enemy = hitBox.GetParent<IEnemy>();
var isCriticalHit = false;
var rng = new RandomNumberGenerator();
rng.Randomize();
var roll = rng.Randf();
if (roll <= enemy.EnemyStatResource.Luck)
isCriticalHit = true;
var damage = DamageCalculator.CalculateEnemyDamage(PlayerData.CurrentDefense.Value + PlayerData.BonusDefense.Value, enemy.EnemyStatResource, GameRepo.PlayerData.Inventory.EquippedArmor.Value.ArmorStats, isCriticalHit);
PlayerData.CurrentHP.OnNext(PlayerData.CurrentHP.Value - Mathf.RoundToInt(damage));
GD.Print($"Player hit for {damage} damage.");
}
}
private void CurrentHP_Sync(int newHealth)
{
if (newHealth <= 0)
Kill();
}
}
}