diff --git a/src/enemy/Enemy.cs b/src/enemy/Enemy.cs index 96be209c..0c83cc99 100644 --- a/src/enemy/Enemy.cs +++ b/src/enemy/Enemy.cs @@ -140,7 +140,7 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide .Handle((in EnemyLogic.Output.HitByPlayer output) => { if (GameRepo.PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.WeaponTags.Contains(WeaponTag.SelfDamage)) - GameRepo.PlayerData.CurrentHP.OnNext(GameRepo.PlayerData.CurrentHP.Value - 5); + GameRepo.PlayerData.SetCurrentHP(GameRepo.PlayerData.CurrentHP.Value - 5); }); this.Provide(); @@ -185,7 +185,7 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide var roll = rng.Randf(); if (roll <= GameRepo.PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.Luck) isCriticalHit = true; - var damage = DamageCalculator.CalculatePlayerDamage(GameRepo.PlayerData.CurrentAttack.Value + GameRepo.PlayerData.BonusAttack.Value, EnemyStatResource, GameRepo.PlayerData.Inventory.EquippedWeapon.Value.WeaponStats, isCriticalHit); + var damage = DamageCalculator.CalculatePlayerDamage(GameRepo.PlayerData.CurrentAttack.Value + GameRepo.PlayerData.BonusAttack, EnemyStatResource, GameRepo.PlayerData.Inventory.EquippedWeapon.Value.WeaponStats, isCriticalHit); GD.Print($"Enemy Hit for {damage} damage."); EnemyLogic.Input(new EnemyLogic.Input.HitByPlayer(damage)); } diff --git a/src/inventory_menu/InventoryMenu.cs b/src/inventory_menu/InventoryMenu.cs index 43258c19..2dffeea8 100644 --- a/src/inventory_menu/InventoryMenu.cs +++ b/src/inventory_menu/InventoryMenu.cs @@ -68,6 +68,65 @@ public partial class InventoryMenu : Control, IInventoryMenu DropButton.Pressed += DropButtonPressed; } + public void OnResolved() + { + GameRepo.PlayerData.CurrentHP.Sync += CurrentHP_Sync; + GameRepo.PlayerData.MaximumHP.Sync += MaximumHP_Sync; + GameRepo.PlayerData.CurrentVT.Sync += CurrentVT_Sync; + GameRepo.PlayerData.MaximumVT.Sync += MaximumVT_Sync; + GameRepo.PlayerData.CurrentAttack.Sync += CurrentAttack_Sync; + GameRepo.PlayerData.MaxAttack.Sync += MaxAttack_Sync; + GameRepo.PlayerData.CurrentDefense.Sync += CurrentDefense_Sync; + GameRepo.PlayerData.MaxDefense.Sync += MaxDefense_Sync; + GameRepo.PlayerData.CurrentExp.Sync += CurrentExp_Sync; + GameRepo.PlayerData.ExpToNextLevel.Sync += ExpToNextLevel_Sync; + GameRepo.PlayerData.CurrentLevel.Sync += CurrentLevel_Sync; + GameRepo.PlayerData.Inventory.EquippedWeapon.Sync += EquippedWeapon_Sync; + GameRepo.PlayerData.Inventory.EquippedArmor.Sync += EquippedArmor_Sync; + GameRepo.PlayerData.Inventory.EquippedAccessory.Sync += EquippedAccessory_Sync; + } + + private void EquippedAccessory_Sync(Accessory obj) + { + ATKBonusLabel.Text = GameRepo.PlayerData.BonusAttack != 0 ? $"{GameRepo.PlayerData.BonusAttack:+0;-#}" : "..."; + DEFBonusLabel.Text = GameRepo.PlayerData.BonusDefense != 0 ? $"{GameRepo.PlayerData.BonusDefense:+0;-#}" : "..."; + } + + private void EquippedArmor_Sync(Armor obj) + { + ATKBonusLabel.Text = GameRepo.PlayerData.BonusAttack != 0 ? $"{GameRepo.PlayerData.BonusAttack:+0;-#}" : "..."; + DEFBonusLabel.Text = GameRepo.PlayerData.BonusDefense != 0 ? $"{GameRepo.PlayerData.BonusDefense:+0;-#}" : "..."; + } + + private void EquippedWeapon_Sync(Weapon obj) + { + ATKBonusLabel.Text = GameRepo.PlayerData.BonusAttack != 0 ? $"{GameRepo.PlayerData.BonusAttack:+0;-#}" : "..."; + DEFBonusLabel.Text = GameRepo.PlayerData.BonusDefense != 0 ? $"{GameRepo.PlayerData.BonusDefense:+0;-#}" : "..."; + } + + private void CurrentLevel_Sync(int obj) => CurrentLevelLabel.Text = $"Level {obj:D2}"; + + private void ExpToNextLevel_Sync(int obj) => EXPValue.Text = $"{GameRepo.PlayerData.CurrentExp.Value}/{obj}"; + + // TODO: Change font style when EXP Bonus effect is active + private void CurrentExp_Sync(int obj) => EXPValue.Text = $"{obj}/{GameRepo.PlayerData.ExpToNextLevel.Value}"; + + private void MaxDefense_Sync(int obj) => DEFValue.Text = $"{GameRepo.PlayerData.CurrentDefense.Value}/{obj}"; + + private void CurrentDefense_Sync(int obj) => DEFValue.Text = $"{obj}/{GameRepo.PlayerData.MaxDefense.Value}"; + + private void MaxAttack_Sync(int obj) => ATKValue.Text = $"{GameRepo.PlayerData.CurrentAttack.Value}/{obj}"; + + private void CurrentAttack_Sync(int obj) => ATKValue.Text = $"{obj}/{GameRepo.PlayerData.MaxAttack.Value}"; + + private void MaximumVT_Sync(int obj) => VTValue.Text = $"{GameRepo.PlayerData.CurrentVT.Value}/{obj}"; + + private void CurrentVT_Sync(int obj) => VTValue.Text = $"{obj}/{GameRepo.PlayerData.MaximumVT.Value}"; + + private void MaximumHP_Sync(int obj) => HPValue.Text = $"{GameRepo.PlayerData.CurrentHP.Value}/{obj}"; + + private void CurrentHP_Sync(int obj) => HPValue.Text = $"{obj}/{GameRepo.PlayerData.MaximumHP.Value}"; + public async Task RedrawInventory() { await HideUserActionPrompt(); @@ -131,39 +190,6 @@ public partial class InventoryMenu : Control, IInventoryMenu { FloorLabel.Text = $"Level {GameRepo.CurrentFloor:D2}"; - var currentLevel = GameRepo.PlayerData.CurrentLevel.Value; - CurrentLevelLabel.Text = $"Level {currentLevel:D2}"; - - var currentHP = GameRepo.PlayerData.CurrentHP.Value; - var maxHP = GameRepo.PlayerData.MaximumHP.Value; - - HPValue.Text = $"{currentHP}/{maxHP}"; - - var currentVT = GameRepo.PlayerData.CurrentVT.Value; - var maxVT = GameRepo.PlayerData.MaximumVT.Value; - - VTValue.Text = $"{currentVT}/{maxVT}"; - - var currentAttack = GameRepo.PlayerData.CurrentAttack.Value; - var maxAttack = GameRepo.PlayerData.MaxAttack.Value; - - ATKValue.Text = $"{currentAttack}/{maxAttack}"; - - var currentDefense = GameRepo.PlayerData.CurrentDefense.Value; - var maxDefense = GameRepo.PlayerData.MaxDefense.Value; - DEFValue.Text = $"{currentDefense}/{maxDefense}"; - - var atkBonus = GameRepo.PlayerData.BonusAttack.Value; - var defBonus = GameRepo.PlayerData.BonusDefense.Value; - - ATKBonusLabel.Text = atkBonus != 0 ? $"{atkBonus:+0;-#}" : "..."; - DEFBonusLabel.Text = defBonus != 0 ? $"{defBonus:+0;-#}" : "..."; - - // TODO: Change font style when EXP Bonus effect is active - var currentExp = GameRepo.PlayerData.CurrentExp.Value; - var expToNextLevel = GameRepo.PlayerData.ExpToNextLevel.Value; - EXPValue.Text = $"{currentExp}/{expToNextLevel}"; - if (ItemSlots.Any()) { var item = ItemSlots.ElementAt(_currentIndex).Item; @@ -223,7 +249,7 @@ public partial class InventoryMenu : Control, IInventoryMenu { var inventory = GameRepo.PlayerData.Inventory; var numberOfItemsToDisplay = _currentPageNumber == InventoryPageNumber.FirstPage ? Mathf.Min(inventory.Items.Count, _itemsPerPage) : Mathf.Min(inventory.Items.Count - _itemsPerPage, _itemsPerPage); - var indexToStart = _currentPageNumber == InventoryPageNumber.FirstPage ? 0 : _itemsPerPage - 1; + var indexToStart = _currentPageNumber == InventoryPageNumber.FirstPage ? 0 : _itemsPerPage; ForwardArrow.Text = ""; BackArrow.Text = ""; @@ -294,38 +320,24 @@ public partial class InventoryMenu : Control, IInventoryMenu GameRepo.PlayerData.Inventory.Equip(equipableItem); itemSlot.SetEquippedSelectedItemStyle(); } - - UpdateStatBonusInfo(); } } - private void UpdateStatBonusInfo() - { - var atkBonus = GameRepo.PlayerData.BonusAttack.Value; - ATKBonusLabel.Text = atkBonus != 0 ? $"{atkBonus:+0;-#}" : "..."; - var defBonus = GameRepo.PlayerData.BonusDefense.Value; - DEFBonusLabel.Text = defBonus != 0 ? $"{defBonus:+0;-#}" : "..."; - - HPValue.Text = $"{GameRepo.PlayerData.CurrentHP.Value}/{GameRepo.PlayerData.MaximumHP.Value}"; - VTValue.Text = $"{GameRepo.PlayerData.CurrentVT.Value}/{GameRepo.PlayerData.MaximumVT.Value}"; - } - private async void UseButtonPressed() { var currentItem = ItemSlots[_currentIndex].Item; if (currentItem is IEquipable) await EquipOrUnequipItem(); - if (currentItem is ConsumableItem consumable) + else if (currentItem is ConsumableItem consumable) { - EmitSignal(SignalName.ClosedMenu); consumable.Use(); + if (_currentIndex >= ItemSlots.Length - 1) + _currentIndex--; + if (_currentIndex <= 0) + _currentIndex = 0; + EmitSignal(SignalName.ClosedMenu); } - if (_currentIndex >= ItemSlots.Length - 1) - _currentIndex--; - if (_currentIndex <= 0) - _currentIndex = 0; - // TODO: Replace with animation player (for visual effects/sound effects?) await ToSignal(GetTree().CreateTimer(0.25f), "timeout"); await RedrawInventory(); diff --git a/src/items/InventoryItem.cs b/src/items/InventoryItem.cs index 71b6156f..f0014739 100644 --- a/src/items/InventoryItem.cs +++ b/src/items/InventoryItem.cs @@ -5,6 +5,7 @@ namespace GameJamDungeon { public interface IInventoryItem : INode3D { + public Guid ID { get; } public IGameRepo GameRepo { get; } public InventoryItemStats Info { get; } diff --git a/src/items/accessory/Accessory.cs b/src/items/accessory/Accessory.cs index b8ee323b..abde8e63 100644 --- a/src/items/accessory/Accessory.cs +++ b/src/items/accessory/Accessory.cs @@ -22,6 +22,8 @@ public partial class Accessory : Node3D, IInventoryItem, IEquipable [Node] public Area3D Pickup { get; set; } = default!; + public Guid ID => Guid.NewGuid(); + public void OnReady() { Sprite.Texture = AccessoryInfo.Texture; diff --git a/src/items/armor/Armor.cs b/src/items/armor/Armor.cs index b462724f..be73a940 100644 --- a/src/items/armor/Armor.cs +++ b/src/items/armor/Armor.cs @@ -20,6 +20,8 @@ public partial class Armor : Node3D, IInventoryItem, IEquipable [Node] public Area3D Pickup { get; set; } = default!; + public Guid ID => Guid.NewGuid(); + public void OnReady() { Sprite.Texture = ArmorStats.Texture; diff --git a/src/items/consumable/ConsumableItem.cs b/src/items/consumable/ConsumableItem.cs index acdb4e58..e93f230d 100644 --- a/src/items/consumable/ConsumableItem.cs +++ b/src/items/consumable/ConsumableItem.cs @@ -21,6 +21,8 @@ public partial class ConsumableItem : Node3D, IInventoryItem [Node] public Area3D Pickup { get; set; } = default!; + public Guid ID => Guid.NewGuid(); + public void OnReady() { Sprite.Texture = ConsumableItemInfo.Texture; @@ -45,28 +47,28 @@ public partial class ConsumableItem : Node3D, IInventoryItem { if (GameRepo.PlayerData.CurrentHP == GameRepo.PlayerData.MaximumHP) { - GameRepo.PlayerData.MaximumHP.OnNext(GameRepo.PlayerData.MaximumHP.Value + ConsumableItemInfo.RaiseHPAmount); - GameRepo.PlayerData.CurrentHP.OnNext(GameRepo.PlayerData.MaximumHP.Value); + GameRepo.PlayerData.SetMaximumHP(GameRepo.PlayerData.MaximumHP.Value + ConsumableItemInfo.RaiseHPAmount); + GameRepo.PlayerData.SetCurrentHP(GameRepo.PlayerData.MaximumHP.Value); } } private void HealHP() { - GameRepo.PlayerData.CurrentHP.OnNext(GameRepo.PlayerData.CurrentHP.Value + ConsumableItemInfo.HealHPAmount); + GameRepo.PlayerData.SetCurrentHP(GameRepo.PlayerData.CurrentHP.Value + ConsumableItemInfo.HealHPAmount); } private void RaiseVT() { if (GameRepo.PlayerData.CurrentVT == GameRepo.PlayerData.MaximumVT) { - GameRepo.PlayerData.MaximumVT.OnNext(GameRepo.PlayerData.MaximumVT.Value + ConsumableItemInfo.RaiseVTAmount); - GameRepo.PlayerData.CurrentVT.OnNext(GameRepo.PlayerData.MaximumVT.Value); + GameRepo.PlayerData.SetMaximumVT(GameRepo.PlayerData.MaximumVT.Value + ConsumableItemInfo.RaiseVTAmount); + GameRepo.PlayerData.SetCurrentVT(GameRepo.PlayerData.MaximumVT.Value); } } private void HealVT() { - GameRepo.PlayerData.CurrentVT.OnNext(GameRepo.PlayerData.CurrentVT.Value + ConsumableItemInfo.HealVTAmount); + GameRepo.PlayerData.SetCurrentVT(GameRepo.PlayerData.CurrentVT.Value + ConsumableItemInfo.HealVTAmount); } public void Throw() diff --git a/src/items/throwable/ThrowableItem.cs b/src/items/throwable/ThrowableItem.cs index 28b6dca8..0e324154 100644 --- a/src/items/throwable/ThrowableItem.cs +++ b/src/items/throwable/ThrowableItem.cs @@ -21,6 +21,8 @@ public partial class ThrowableItem : Node3D, IInventoryItem public int Count { get; } + public Guid ID => Guid.NewGuid(); + [Export] public ThrowableItemStats ThrowableItemInfo { get; set; } diff --git a/src/items/weapons/Weapon.cs b/src/items/weapons/Weapon.cs index f9e1a5a3..46f30150 100644 --- a/src/items/weapons/Weapon.cs +++ b/src/items/weapons/Weapon.cs @@ -20,6 +20,8 @@ public partial class Weapon : Node3D, IInventoryItem, IEquipable [Node] public Area3D Pickup { get; set; } = default!; + public Guid ID => Guid.NewGuid(); + public void OnReady() { Sprite.Texture = WeaponStats.Texture; diff --git a/src/player/Player.cs b/src/player/Player.cs index b25f13cc..4cce6941 100644 --- a/src/player/Player.cs +++ b/src/player/Player.cs @@ -2,6 +2,7 @@ using Chickensoft.Collections; using Chickensoft.GodotNodeInterfaces; using Chickensoft.Introspection; +using Chickensoft.LogicBlocks; using Chickensoft.SaveFileBuilder; using Godot; @@ -70,22 +71,21 @@ namespace GameJamDungeon StateMachine = PlayerLogic, Velocity = Velocity, Inventory = new Inventory(), - CurrentHP = new AutoProp(PlayerStatResource.CurrentHP), - MaximumHP = new AutoProp(PlayerStatResource.MaximumHP), - CurrentVT = new AutoProp(PlayerStatResource.CurrentVT), - MaximumVT = new AutoProp(PlayerStatResource.MaximumVT), - CurrentAttack = new AutoProp(PlayerStatResource.CurrentAttack), - MaxAttack = new AutoProp(PlayerStatResource.MaxAttack), - CurrentDefense = new AutoProp(PlayerStatResource.CurrentDefense), - MaxDefense = new AutoProp(PlayerStatResource.MaxDefense), - CurrentExp = new AutoProp(PlayerStatResource.CurrentExp), - ExpToNextLevel = new AutoProp(PlayerStatResource.ExpToNextLevel), - CurrentLevel = new AutoProp(PlayerStatResource.CurrentLevel), - BonusAttack = new AutoProp(PlayerStatResource.BonusAttack), - BonusDefense = new AutoProp(PlayerStatResource.BonusDefense), - Luck = new AutoProp(PlayerStatResource.Luck) }; + PlayerData.SetCurrentHP(PlayerStatResource.CurrentHP); + PlayerData.SetMaximumHP(PlayerStatResource.MaximumHP); + PlayerData.SetCurrentVT(PlayerStatResource.CurrentVT); + PlayerData.SetMaximumVT(PlayerStatResource.MaximumVT); + PlayerData.SetCurrentAttack(PlayerStatResource.CurrentAttack); + PlayerData.SetMaxAttack(PlayerStatResource.MaxAttack); + PlayerData.SetCurrentDefense(PlayerStatResource.CurrentDefense); + PlayerData.SetMaxDefense(PlayerStatResource.MaxDefense); + PlayerData.SetCurrentExp(PlayerStatResource.CurrentExp); + PlayerData.SetCurrentLevel(PlayerStatResource.CurrentLevel); + PlayerData.SetExpToNextLevel(PlayerStatResource.ExpToNextLevel); + PlayerData.SetLuck(PlayerStatResource.Luck); + PlayerLogic = new PlayerLogic(); PlayerLogic.Set(this as IPlayer); PlayerLogic.Set(Settings); @@ -93,10 +93,7 @@ namespace GameJamDungeon 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; } @@ -130,6 +127,13 @@ namespace GameJamDungeon CollisionDetector.AreaEntered += OnEnemyHitBoxEntered; } + private void Inventory_AccessoryUnequipped(Accessory unequippedAccessory) + { + PlayerData.SetMaximumHP(PlayerData.MaximumHP.Value - unequippedAccessory.AccessoryInfo.MaxHPUp); + PlayerData.SetMaximumVT(PlayerData.MaximumVT.Value - unequippedAccessory.AccessoryInfo.MaxVTUp); + PlayerData.SetLuck(PlayerData.Luck.Value - unequippedAccessory.AccessoryInfo.LUCKUp); + } + public void OnReady() { SetPhysicsProcess(true); @@ -213,39 +217,16 @@ namespace GameJamDungeon private void OnHealthTimerTimeout() { if (PlayerData.CurrentVT.Value > 0) - PlayerData.CurrentVT.OnNext(PlayerData.CurrentVT.Value - 1); + PlayerData.SetCurrentVT(PlayerData.CurrentVT.Value - 1); else - PlayerData.CurrentHP.OnNext(PlayerData.CurrentHP.Value - 1); + PlayerData.SetCurrentHP(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); + PlayerData.SetMaximumHP(PlayerData.MaximumHP.Value + equippedItem.AccessoryInfo.MaxHPUp); + PlayerData.SetMaximumVT(PlayerData.MaximumVT.Value + equippedItem.AccessoryInfo.MaxVTUp); + PlayerData.SetLuck(PlayerData.Luck.Value + equippedItem.AccessoryInfo.LUCKUp); } private void OnEnemyHitBoxEntered(Area3D area) @@ -259,8 +240,8 @@ namespace GameJamDungeon 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)); + var damage = DamageCalculator.CalculateEnemyDamage(PlayerData.CurrentDefense.Value + PlayerData.BonusDefense, enemy.EnemyStatResource, GameRepo.PlayerData.Inventory.EquippedArmor.Value.ArmorStats, isCriticalHit); + PlayerData.SetCurrentHP(PlayerData.CurrentHP.Value - Mathf.RoundToInt(damage)); GD.Print($"Player hit for {damage} damage."); } } diff --git a/src/player/PlayerData.cs b/src/player/PlayerData.cs index 0f228110..d14f7a44 100644 --- a/src/player/PlayerData.cs +++ b/src/player/PlayerData.cs @@ -17,32 +17,100 @@ namespace GameJamDungeon [Save("inventory")] public required Inventory Inventory { get; init; } [Save("currentHP")] - public required AutoProp CurrentHP { get; init; } + public IAutoProp CurrentHP => _currentHP; [Save("maximumHP")] - public required AutoProp MaximumHP { get; init; } + public IAutoProp MaximumHP => _maximumHP; [Save("currentVT")] - public required AutoProp CurrentVT { get; init; } + public IAutoProp CurrentVT => _currentVT; [Save("maximumVT")] - public required AutoProp MaximumVT { get; init; } + public IAutoProp MaximumVT => _maximumVT; [Save("currentExp")] - public required AutoProp CurrentExp { get; init; } - [Save("expToNextLevel")] - public required AutoProp ExpToNextLevel { get; init; } + public IAutoProp CurrentExp => _currentExp; [Save("currentLevel")] - public required AutoProp CurrentLevel { get; init; } + public IAutoProp CurrentLevel => _currentLevel; [Save("currentAttack")] - public required AutoProp CurrentAttack { get; init; } + public IAutoProp CurrentAttack => _currentAttack; [Save("currentDefense")] - public required AutoProp CurrentDefense { get; init; } + public IAutoProp CurrentDefense => _currentDefense; [Save("maxAttack")] - public required AutoProp MaxAttack { get; init; } + public IAutoProp MaxAttack => _maxAttack; [Save("maxDefense")] - public required AutoProp MaxDefense { get; init; } - [Save("bonusAttack")] - public required AutoProp BonusAttack { get; init; } - [Save("bonusDefense")] - public required AutoProp BonusDefense { get; init; } + public IAutoProp MaxDefense => _maxDefense; + public int BonusAttack => Inventory.EquippedWeapon.Value.WeaponStats.Damage + Inventory.EquippedAccessory.Value.AccessoryInfo.ATKUp; + public int BonusDefense => Inventory.EquippedArmor.Value.ArmorStats.Defense + Inventory.EquippedAccessory.Value.AccessoryInfo.DEFUp; + [Save("expToNextLevel")] + public IAutoProp ExpToNextLevel => _expToNextLevel; [Save("luck")] - public required AutoProp Luck { get; init; } + public IAutoProp 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(int newValue) + { + var clampedValue = Mathf.Clamp(newValue, 0, ExpToNextLevel.Value); + _currentExp.OnNext(clampedValue); + } + 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 SetCurrentDefense(int newValue) + { + var clampedValue = Mathf.Clamp(newValue, 0, MaxDefense.Value); + _currentDefense.OnNext(clampedValue); + } + public void SetMaxAttack(int newValue) + { + _maxAttack.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 _currentHP = new(int.MaxValue); + private readonly AutoProp _maximumHP = new(int.MaxValue); + private readonly AutoProp _currentVT = new(int.MaxValue); + private readonly AutoProp _maximumVT = new(int.MaxValue); + private readonly AutoProp _currentExp = new(int.MaxValue); + private readonly AutoProp _currentLevel = new(int.MaxValue); + private readonly AutoProp _currentAttack = new(int.MaxValue); + private readonly AutoProp _currentDefense = new(int.MaxValue); + private readonly AutoProp _maxAttack = new(int.MaxValue); + private readonly AutoProp _maxDefense = new(int.MaxValue); + private readonly AutoProp _bonusAttack = new(int.MaxValue); + private readonly AutoProp _bonusDefense = new(int.MaxValue); + private readonly AutoProp _expToNextLevel = new(int.MaxValue); + private readonly AutoProp _luck = new(double.MaxValue); } } diff --git a/src/ui/player_ui/PlayerInfoUI.cs b/src/ui/player_ui/PlayerInfoUI.cs index 2a57effc..2c469577 100644 --- a/src/ui/player_ui/PlayerInfoUI.cs +++ b/src/ui/player_ui/PlayerInfoUI.cs @@ -67,9 +67,14 @@ public partial class PlayerInfoUI : Control, IPlayerInfoUI HPNumber.Text = $"{obj}/{GameRepo.PlayerData.MaximumHP.Value}"; } - public void DisplayInventoryFullMessage(string rejectedItemName) + public async void DisplayInventoryFullMessage(string rejectedItemName) { var newLabel = new Label() { Text = $"Could not pick up {rejectedItemName}.", LabelSettings = _labelSettings }; PlayerInfo.AddChild(newLabel); + + GetTree().CreateTimer(5f).Timeout += () => + { + PlayerInfo.RemoveChild(newLabel); + }; } }