From bc010a7d82ab5b3d2482e33f81cd67c422b90c8d Mon Sep 17 00:00:00 2001 From: Zenny Date: Mon, 2 Mar 2026 01:57:43 -0800 Subject: [PATCH] Started implementation of information about item used screen --- .../Player/IPlayer.cs | 2 +- Zennysoft.Game.Ma/src/game/Game.cs | 116 +++++++++++++++--- Zennysoft.Game.Ma/src/game/IGame.cs | 3 + Zennysoft.Game.Ma/src/items/EffectService.cs | 24 ++-- Zennysoft.Game.Ma/src/player/DummyPlayer.cs | 2 +- Zennysoft.Game.Ma/src/player/Player.cs | 2 +- .../src/ui/inventory_menu/InventoryMenu.cs | 34 ++++- .../src/ui/inventory_menu/InventoryMenu.tscn | 37 ++++++ 8 files changed, 182 insertions(+), 38 deletions(-) diff --git a/Zennysoft.Game.Ma.Implementation/Player/IPlayer.cs b/Zennysoft.Game.Ma.Implementation/Player/IPlayer.cs index 04a38ee29..65edb78ba 100644 --- a/Zennysoft.Game.Ma.Implementation/Player/IPlayer.cs +++ b/Zennysoft.Game.Ma.Implementation/Player/IPlayer.cs @@ -28,7 +28,7 @@ public interface IPlayer : IKillable, ICharacterBody3D public void ApplyNewAugment(IAugmentItem jewel, IAugmentableItem equipableItem); - public void IdentifyItem(IBaseInventoryItem unidentifiedItem); + public IBaseInventoryItem IdentifyItem(IBaseInventoryItem unidentifiedItem); public IInventory Inventory { get; } diff --git a/Zennysoft.Game.Ma/src/game/Game.cs b/Zennysoft.Game.Ma/src/game/Game.cs index 8840cafa3..d1a853fd0 100644 --- a/Zennysoft.Game.Ma/src/game/Game.cs +++ b/Zennysoft.Game.Ma/src/game/Game.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter.Entity; using System.Linq; +using Chickensoft.Collections; [Meta(typeof(IAutoNode))] public partial class Game : Node3D, IGame @@ -82,6 +83,8 @@ public partial class Game : Node3D, IGame [Signal] private delegate void OnLoadLevelRequestEventHandler(); + public event Action InventoryEventNotification; + public Game() { _container = new SimpleInjector.Container(); @@ -453,28 +456,43 @@ public partial class Game : Node3D, IGame { case ItemTag.DamagesPlayer: _effectService.DamagesPlayer(boxItem.Stats.DamageToPlayer); + InventoryEventNotification.Invoke($"{boxItem.Stats.DamageToPlayer} damage done to self."); GameRepo.CloseInventory(); break; case ItemTag.ContainsAccessory: - _player.Inventory.TryAdd(_effectService.GetRandomItemOfType()); + var accessory = _effectService.GetRandomItemOfType(); + _player.Inventory.TryAdd(accessory); + InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {accessory}."); break; case ItemTag.ContainsArmor: - _player.Inventory.TryAdd(_effectService.GetRandomItemOfType()); + var armor = _effectService.GetRandomItemOfType(); + _player.Inventory.TryAdd(armor); + InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {armor}."); break; case ItemTag.ContainsWeapon: - _player.Inventory.TryAdd(_effectService.GetRandomItemOfType()); + var weapon = _effectService.GetRandomItemOfType(); + _player.Inventory.TryAdd(weapon); + InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {weapon}."); break; case ItemTag.ContainsBox: - _player.Inventory.TryAdd(_effectService.GetRandomItemOfType()); + var box = _effectService.GetRandomItemOfType(); + _player.Inventory.TryAdd(box); + InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {box}."); break; case ItemTag.RandomSpell: - _player.Inventory.TryAdd(_effectService.GetRandomItemOfType()); + var effectItem = _effectService.GetRandomItemOfType(); + _player.Inventory.TryAdd(effectItem); + InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {effectItem}."); break; case ItemTag.ContainsRestorative: - _player.Inventory.TryAdd(_effectService.GetRandomItemOfType()); + var restorative = _effectService.GetRandomItemOfType(); + _player.Inventory.TryAdd(restorative); + InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {restorative}."); break; case ItemTag.DropTo1HPAndGainRareItem: - _effectService.DropTo1HPAndGainRareItem(); + var rareItem = _effectService.DropTo1HPAndGainRareItem(); + _player.Inventory.TryAdd(rareItem); + InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {rareItem} but cost dear life."); break; case ItemTag.TradeOneRandomItem: var itemsWithoutBox = _player.Inventory.Items.Where(x => x != boxItem).ToList(); @@ -485,6 +503,7 @@ public partial class Game : Node3D, IGame _player.Inventory.Remove(randomItem); var newItem = _effectService.GetRandomItemOfType(); _player.Inventory.TryAdd(newItem); + InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {newItem}."); break; case ItemTag.TradeAllRandomItems: var newInventory = _effectService.TradeAllRandomItems(boxItem); @@ -492,20 +511,26 @@ public partial class Game : Node3D, IGame _player.Inventory.TryAdd(boxItem); foreach (var item in newInventory) _player.Inventory.TryAdd(item); + InventoryEventNotification.Invoke($"All items replaced."); break; case ItemTag.ContainsUnobtainedItem: - _effectService.GetUnobtainedItem(); + var unobtainedItem = _effectService.GetUnobtainedItem(); + _player.Inventory.TryAdd(unobtainedItem); + InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {unobtainedItem}."); break; case ItemTag.ContainsBasicItem: - _effectService.GetBasicItem(); + var basicItem = _effectService.GetBasicItem(); + InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {basicItem}."); break; case ItemTag.UnequipAllItems: _player.Unequip(_player.EquipmentComponent.EquippedWeapon.Value); _player.Unequip(_player.EquipmentComponent.EquippedArmor.Value); _player.Unequip(_player.EquipmentComponent.EquippedAccessory.Value); + InventoryEventNotification.Invoke($"Equipment status reset."); break; case ItemTag.RestrictUnequip: _effectService.GlueAllEquipment(_player); + InventoryEventNotification.Invoke($"Currently equipped items have become unmovable."); break; case ItemTag.EjectAllItems: _player.EquipmentComponent.EquippedWeapon.Value.Glued = false; @@ -519,6 +544,7 @@ public partial class Game : Node3D, IGame foreach (var item in _player.Inventory.Items.ToList()) ThrowItem(item); _player.Inventory.Items.Clear(); + InventoryEventNotification.Invoke($"All items have been ejected from inventory."); GameRepo.CloseInventory(); break; } @@ -528,24 +554,28 @@ public partial class Game : Node3D, IGame { if (_player.HealthComponent.AtFullHealth && consumableItem.RaiseHPAmount > 0) { - _player.HealthComponent.RaiseMaximumHP(consumableItem.RaiseHPAmount); + _player.HealthComponent.RaiseMaximumHP(consumableItem.RaiseHPAmount, true); SfxDatabase.Instance.Play(SoundEffect.IncreaseStat); + InventoryEventNotification.Invoke($"Raised maximum HP by {consumableItem.RaiseHPAmount}."); } - if (_player.VTComponent.AtFullVT && consumableItem.RaiseVTAmount > 0) + else if (_player.VTComponent.AtFullVT && consumableItem.RaiseVTAmount > 0) { - _player.VTComponent.RaiseMaximumVT(consumableItem.RaiseVTAmount); + _player.VTComponent.RaiseMaximumVT(consumableItem.RaiseVTAmount, true); SfxDatabase.Instance.Play(SoundEffect.IncreaseStat); + InventoryEventNotification.Invoke($"Raised maximum VT by {consumableItem.RaiseVTAmount}."); } - - if (consumableItem.HealHPAmount > 0) + else if (consumableItem.HealHPAmount > 0) { + var currentHP = _player.HealthComponent.CurrentHP; _player.HealthComponent.Heal(consumableItem.HealHPAmount); SfxDatabase.Instance.Play(SoundEffect.HealHP); + InventoryEventNotification.Invoke($"Restored {consumableItem.HealHPAmount} HP."); } - if (consumableItem.HealVTAmount > 0) + else if (consumableItem.HealVTAmount > 0) { _player.VTComponent.Restore(consumableItem.HealVTAmount); SfxDatabase.Instance.Play(SoundEffect.HealVT); + InventoryEventNotification.Invoke($"Restored {consumableItem.HealVTAmount} VT."); } } @@ -555,114 +585,160 @@ public partial class Game : Node3D, IGame { case UsableItemTag.TeleportAllEnemiesToRoom: _effectService.TeleportEnemiesToCurrentRoom(GetTree().GetNodesInGroup("enemy").OfType().ToList()); + SfxDatabase.Instance.Play(SoundEffect.RecallEnemies); + InventoryEventNotification.Invoke($"All enemies have been summoned."); GameRepo.CloseInventory(); _player.PlaySpellFX(SpellFXEnum.DivinityRecall); - SfxDatabase.Instance.Play(SoundEffect.RecallEnemies); break; case UsableItemTag.KillHalfEnemiesInRoom: _effectService.KillHalfEnemiesInRoom(); + InventoryEventNotification.Invoke($"The balance has been achieved."); GameRepo.CloseInventory(); break; case UsableItemTag.TurnAllEnemiesIntoHealingItem: _effectService.TurnAllEnemiesInRoomIntoHealingItem(); + InventoryEventNotification.Invoke($"Enemies in current room have been converted."); GameRepo.CloseInventory(); break; case UsableItemTag.HealsAllInRoomToMaxHP: _effectService.HealAllEnemiesAndPlayerInRoomToFull(); + InventoryEventNotification.Invoke($"All present have been renewed."); GameRepo.CloseInventory(); break; case UsableItemTag.AbsorbHPFromAllEnemiesInRoom: - _effectService.AbsorbHPFromAllEnemiesInRoom(); + var hpAbsorbed = _effectService.AbsorbHPFromAllEnemiesInRoom(); + if (hpAbsorbed == 0) + { + InventoryEventNotification.Invoke($"No enemies present to absorb from or invalid location."); + GameRepo.CloseInventory(); + return; + } + _player.HealthComponent.Heal(hpAbsorbed); + InventoryEventNotification.Invoke($"Enemies have surrendered {hpAbsorbed} to you."); GameRepo.CloseInventory(); + _player.PlaySpellFX(SpellFXEnum.Kyuuketsuki); break; + case UsableItemTag.DealElementalDamageToAllEnemiesInRoom: _effectService.DealElementalDamageToAllEnemiesInRoom(effectItem.Stats.ElementalDamageType); + InventoryEventNotification.Invoke($"All enemies present have taken {effectItem.Stats.ElementalDamageType} to you."); GameRepo.CloseInventory(); break; case UsableItemTag.SwapHPAndVT: _effectService.SwapHPandVT(); + InventoryEventNotification.Invoke($"HP and VT have been traded."); GameRepo.CloseInventory(); break; case UsableItemTag.RaiseCurrentWeaponAttack: + if (string.IsNullOrEmpty(_player.EquipmentComponent.EquippedWeapon.Value.ItemName)) + return; _effectService.RaiseCurrentWeaponAttack(); + InventoryEventNotification.Invoke($"{_player.EquipmentComponent.EquippedWeapon.Value}'s attack has risen by 1."); break; case UsableItemTag.RaiseCurrentDefenseArmor: + if (string.IsNullOrEmpty(_player.EquipmentComponent.EquippedArmor.Value.ItemName)) + return; _effectService.RaiseCurrentArmorDefense(); + InventoryEventNotification.Invoke($"{_player.EquipmentComponent.EquippedArmor.Value}'s defense has risen by 1."); break; case UsableItemTag.RaiseLevel: _effectService.RaiseLevel(); + InventoryEventNotification.Invoke($"Level increased to {_player.ExperiencePointsComponent.Level.Value}"); break; case UsableItemTag.LowerLevel: _effectService.LowerLevel(); + InventoryEventNotification.Invoke($"Level decreased to {_player.ExperiencePointsComponent.Level.Value}"); break; case UsableItemTag.LowerCurrentDefenseArmor: + if (string.IsNullOrEmpty(_player.EquipmentComponent.EquippedArmor.Value.ItemName)) + return; _effectService.LowerCurrentArmorDefense(); + InventoryEventNotification.Invoke($"{_player.EquipmentComponent.EquippedArmor.Value}'s defense has been lowered by 1."); break; case UsableItemTag.RandomEffect: _effectService.RandomEffect(); break; case UsableItemTag.DoubleExp: _effectService.DoubleExp(); + InventoryEventNotification.Invoke($"EXP Rate has been doubled."); GameRepo.CloseInventory(); _player.PlaySpellFX(SpellFXEnum.AnBradan); break; case UsableItemTag.TeleportToRandomLocation: _effectService.TeleportToRandomRoom(_player); + InventoryEventNotification.Invoke($"Moving to a different room."); GameRepo.CloseInventory(); break; case UsableItemTag.WarpToExitIfFound: - _effectService.WarpToExit(); + var warpedToExit = _effectService.WarpToExit(); + if (warpedToExit) + InventoryEventNotification.Invoke($"Moved to exit room."); + else + InventoryEventNotification.Invoke($"Unable to locate exit room."); GameRepo.CloseInventory(); break; case UsableItemTag.IncreaseAttack: _player.AttackComponent.RaiseMaximumAttack(effectItem.Stats.BonusAttack); SfxDatabase.Instance.Play(SoundEffect.IncreaseStat); + InventoryEventNotification.Invoke($"Attack has permanently risen to {_player.AttackComponent.CurrentAttack.Value}."); break; case UsableItemTag.IncreaseDefense: _player.DefenseComponent.RaiseMaximumDefense(effectItem.Stats.BonusDefense); SfxDatabase.Instance.Play(SoundEffect.IncreaseStat); + InventoryEventNotification.Invoke($"Defense has permanently risen to {_player.DefenseComponent.CurrentDefense.Value}."); break; + case UsableItemTag.IncreaseLuck: _player.LuckComponent.IncreaseLuck(effectItem.Stats.BonusLuck); SfxDatabase.Instance.Play(SoundEffect.IncreaseStat); + InventoryEventNotification.Invoke($"Luck increased."); break; case UsableItemTag.DecreaseAttack: _player.AttackComponent.Reduce(effectItem.Stats.BonusAttack); SfxDatabase.Instance.Play(SoundEffect.DecreaseStat); + InventoryEventNotification.Invoke($"Attack has been lowered to {_player.AttackComponent.CurrentAttack.Value}."); break; case UsableItemTag.DecreaseDefense: _player.DefenseComponent.Reduce(effectItem.Stats.BonusDefense); SfxDatabase.Instance.Play(SoundEffect.DecreaseStat); + InventoryEventNotification.Invoke($"Defense has been lowered to {_player.DefenseComponent.CurrentDefense.Value}."); break; case UsableItemTag.DecreaseLuck: _player.LuckComponent.DecreaseLuck(effectItem.Stats.BonusLuck); SfxDatabase.Instance.Play(SoundEffect.DecreaseStat); + InventoryEventNotification.Invoke($"Luck decreased."); break; case UsableItemTag.DecreaseAllStats: _player.AttackComponent.Reduce(effectItem.Stats.BonusAttack); _player.DefenseComponent.Reduce(effectItem.Stats.BonusDefense); _player.LuckComponent.DecreaseLuck(effectItem.Stats.BonusLuck); SfxDatabase.Instance.Play(SoundEffect.DecreaseStat); + InventoryEventNotification.Invoke($"All stats have been lowered."); break; case UsableItemTag.MeltAllEquipment: _effectService.MeltAllEquipment(_player); SfxDatabase.Instance.Play(SoundEffect.DecreaseStat); + InventoryEventNotification.Invoke($"All equipped items have dissolved."); break; case UsableItemTag.GlueAllEquipment: _effectService.GlueAllEquipment(_player); SfxDatabase.Instance.Play(SoundEffect.DecreaseStat); + InventoryEventNotification.Invoke($"All equipped items have become sticky."); break; case UsableItemTag.RestoreStats: _effectService.RestoreParameters(_player); SfxDatabase.Instance.Play(SoundEffect.IncreaseStat); + InventoryEventNotification.Invoke($"All stats have been restored."); break; case UsableItemTag.LowerTargetTo1HP: _player.HealthComponent.SetCurrentHealth(1); SfxDatabase.Instance.Play(SoundEffect.DecreaseStat); + InventoryEventNotification.Invoke($"HP has been reduced to 1."); break; case UsableItemTag.DoubleStackedItems: var stackableItems = _player.Inventory.Items.OfType().ToList(); stackableItems.ForEach(x => x.Count.OnNext(x.Count.Value * 2)); + InventoryEventNotification.Invoke($"Items with inventory count have been doubled."); break; case UsableItemTag.IdentifyRandomItem: var unidentifiedItems = _player.Inventory.Items.Where(x => x.ItemTag == ItemTag.MysteryItem).ToList(); @@ -671,7 +747,9 @@ public partial class Game : Node3D, IGame var rng = new RandomNumberGenerator(); rng.Randomize(); var index = rng.RandiRange(0, unidentifiedItems.Count - 1); - _player.IdentifyItem(unidentifiedItems[index]); + var itemToIdentify = unidentifiedItems[index]; + var identifiedItem = _player.IdentifyItem(itemToIdentify); + InventoryEventNotification.Invoke($"{itemToIdentify} identified to be {identifiedItem.ItemName}."); break; } _player.EquipmentComponent.UpdateEquipment(_player.EquipmentComponent.EquippedWeapon.Value); diff --git a/Zennysoft.Game.Ma/src/game/IGame.cs b/Zennysoft.Game.Ma/src/game/IGame.cs index 017a7ca52..560c36cf6 100644 --- a/Zennysoft.Game.Ma/src/game/IGame.cs +++ b/Zennysoft.Game.Ma/src/game/IGame.cs @@ -2,6 +2,7 @@ namespace Zennysoft.Game.Ma; using Chickensoft.AutoInject; +using Chickensoft.Collections; using Chickensoft.GodotNodeInterfaces; using Chickensoft.SaveFileBuilder; using System; @@ -43,4 +44,6 @@ public interface IGame : IProvide, IProvide, IProvide public event Action GameExitRequested; public event Action GameLoaded; + + public event Action InventoryEventNotification; } diff --git a/Zennysoft.Game.Ma/src/items/EffectService.cs b/Zennysoft.Game.Ma/src/items/EffectService.cs index 122944ed8..26c7183b5 100644 --- a/Zennysoft.Game.Ma/src/items/EffectService.cs +++ b/Zennysoft.Game.Ma/src/items/EffectService.cs @@ -88,12 +88,12 @@ public class EffectService SfxDatabase.Instance.Play(SoundEffect.HealHP); } - public void AbsorbHPFromAllEnemiesInRoom() + public int AbsorbHPFromAllEnemiesInRoom() { var currentRoom = _map.GetPlayersCurrentRoom(); if (currentRoom is not MonsterRoom) - return; + return 0; var currentEnemies = currentRoom.EnemiesInRoom; var hpToAbsorb = 0.0; @@ -104,9 +104,7 @@ public class EffectService hpToAbsorb += absorbAmount; enemy.OnAbsorb(); } - _player.HealthComponent.Heal((int)hpToAbsorb); - _player.PlaySpellFX(SpellFXEnum.Kyuuketsuki); - GD.Print("HP to absorb: " + hpToAbsorb); + return (int)hpToAbsorb; } public void DealElementalDamageToAllEnemiesInRoom(ElementType elementType) @@ -306,7 +304,7 @@ public class EffectService SfxDatabase.Instance.Play(SoundEffect.TeleportToRandomRoom); } - public void WarpToExit() + public bool WarpToExit() { var exitRoom = _game.CurrentFloor.Rooms.OfType().Single(); if (exitRoom.PlayerDiscoveredRoom) @@ -314,7 +312,9 @@ public class EffectService SfxDatabase.Instance.Play(SoundEffect.TeleportToExit); var exitPoint = exitRoom.PlayerSpawn.GlobalPosition; _player.TeleportPlayer((exitRoom.PlayerSpawn.Rotation, new Vector3(exitPoint.X, _player.GlobalPosition.Y, exitPoint.Z))); + return true; } + return false; } public void DamagesPlayer(int damage) @@ -341,11 +341,11 @@ public class EffectService _game.UseItem(item); } - public void DropTo1HPAndGainRareItem() + public T DropTo1HPAndGainRareItem() where T : IBaseInventoryItem { _player.HealthComponent.SetCurrentHealth(1); - _player.Inventory.TryAdd(ItemDatabase.Instance.PickRareItem()); + return ItemDatabase.Instance.PickRareItem(); } public void TradeRandomItem(BoxItem box) @@ -373,7 +373,7 @@ public class EffectService return newInventory; } - public void GetUnobtainedItem() + public IBaseInventoryItem GetUnobtainedItem() { var pickableItems = ItemDatabase.Instance.Items.Except(_player.Inventory.Items).ToList(); var rng = new RandomNumberGenerator(); @@ -384,12 +384,12 @@ public class EffectService if (selectedItem is ThrowableItem throwableItem) throwableItem.SetCount(rng.RandiRange(throwableItem.Stats.MinimumCount, throwableItem.Stats.MaximumCount)); - _player.Inventory.TryAdd(selectedItem); + return selectedItem; } - public void GetBasicItem() + public T GetBasicItem() where T : IBaseInventoryItem { - _player.Inventory.TryAdd(ItemDatabase.Instance.PickBasicItem()); + return ItemDatabase.Instance.PickBasicItem(); } } diff --git a/Zennysoft.Game.Ma/src/player/DummyPlayer.cs b/Zennysoft.Game.Ma/src/player/DummyPlayer.cs index 4d6fd9f04..71e8aa328 100644 --- a/Zennysoft.Game.Ma/src/player/DummyPlayer.cs +++ b/Zennysoft.Game.Ma/src/player/DummyPlayer.cs @@ -29,7 +29,6 @@ public partial class DummyPlayer : CharacterBody3D, IPlayer public void Deactivate() => throw new NotImplementedException(); public void Die() => throw new NotImplementedException(); public void Equip(IEquipableItem equipable) => throw new NotImplementedException(); - public void IdentifyItem(IBaseInventoryItem unidentifiedItem) => throw new NotImplementedException(); public void Knockback(float impulse) => throw new NotImplementedException(); public void LevelUp() => throw new NotImplementedException(); public void ModifyHealthTimerSpeed(float newModifier) => throw new NotImplementedException(); @@ -40,4 +39,5 @@ public partial class DummyPlayer : CharacterBody3D, IPlayer public void TakeDamage(AttackData damage) => throw new NotImplementedException(); public void TeleportPlayer((Vector3 Rotation, Vector3 Position) newTransform) => throw new NotImplementedException(); public void Unequip(IEquipableItem equipable) => throw new NotImplementedException(); + public IBaseInventoryItem IdentifyItem(IBaseInventoryItem unidentifiedItem) => throw new NotImplementedException(); } diff --git a/Zennysoft.Game.Ma/src/player/Player.cs b/Zennysoft.Game.Ma/src/player/Player.cs index f4f8da2d8..6928ca704 100644 --- a/Zennysoft.Game.Ma/src/player/Player.cs +++ b/Zennysoft.Game.Ma/src/player/Player.cs @@ -273,7 +273,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide public void PlayJumpScareAnimation() => PlayerFXAnimations.Play("jump_scare"); - public void IdentifyItem(IBaseInventoryItem unidentifiedItem) => _itemReroller.RerollItem(unidentifiedItem, Inventory); + public IBaseInventoryItem IdentifyItem(IBaseInventoryItem unidentifiedItem) => _itemReroller.RerollItem(unidentifiedItem, Inventory); public int TotalAttack => AttackComponent.CurrentAttack.Value + EquipmentComponent.BonusAttack; diff --git a/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.cs b/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.cs index e97c4ef38..24c5d9fa1 100644 --- a/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.cs +++ b/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.cs @@ -45,10 +45,16 @@ public partial class InventoryMenu : Control, IInventoryMenu [Node] public Label StatusLabel { get; set; } + [Node] public PanelContainer ItemActionResultContainer { get; set; } + + [Node] public Label ItemActionResultLabel { get; set; } + private List ItemSlots; private IItemSlot _currentlySelected; + private bool _blocking = false; + public void OnResolved() { ItemSlots = [.. Inventory.GetChildren().OfType()]; @@ -68,13 +74,11 @@ public partial class InventoryMenu : Control, IInventoryMenu AttackChanged(0); DefenseChanged(0); StatusLabel.Text = string.Empty; + ItemActionResultLabel.Text = string.Empty; + _game.InventoryEventNotification += InventoryEventNotification_Changed; Hide(); } - private void AttackChanged(int obj) => PlayerATKLabel.Text = $"{_player.AttackComponent.CurrentAttack.Value:D2}/{_player.AttackComponent.MaximumAttack.Value:D2}+{_player.EquipmentComponent.BonusAttack}"; - - private void DefenseChanged(int obj) => PlayerDEFLabel.Text = $"{_player.DefenseComponent.CurrentDefense.Value:D2}/{_player.DefenseComponent.MaximumDefense.Value:D2}+{_player.EquipmentComponent.BonusDefense}"; - public override void _Input(InputEvent @event) { var validSelectableItems = _player.Inventory.Items.ToList(); @@ -98,6 +102,9 @@ public partial class InventoryMenu : Control, IInventoryMenu private void ActionPanel_AugmentMenuRequested() { + if (_blocking) + return; + ReleaseFocus(); ItemSlots.ForEach(x => x.ItemPressed -= ItemPressed); ItemSlots.ForEach(x => x.ItemSelected -= ItemSelected); @@ -114,6 +121,9 @@ public partial class InventoryMenu : Control, IInventoryMenu private void ItemPressed(IItemSlot selectedItem) { + if (_blocking) + return; + SetProcessInput(false); ActionPanel.SetProcessInput(true); ActionPanel.ShowPanel(selectedItem.Item.Value); @@ -156,6 +166,22 @@ public partial class InventoryMenu : Control, IInventoryMenu ActionPanel.Hide(); } + private async void InventoryEventNotification_Changed(string obj) + { + _blocking = true; + ItemActionResultContainer.Show(); + ItemActionResultContainer.GrabFocus(); + ItemActionResultLabel.Text = obj; + await ToSignal(GetTree().CreateTimer(2f), "timeout"); + ItemActionResultContainer.Hide(); + ItemActionResultLabel.Text = string.Empty; + _blocking = false; + } + + private void AttackChanged(int obj) => PlayerATKLabel.Text = $"{_player.AttackComponent.CurrentAttack.Value:D2}/{_player.AttackComponent.MaximumAttack.Value:D2}+{_player.EquipmentComponent.BonusAttack}"; + + private void DefenseChanged(int obj) => PlayerDEFLabel.Text = $"{_player.DefenseComponent.CurrentDefense.Value:D2}/{_player.DefenseComponent.MaximumDefense.Value:D2}+{_player.EquipmentComponent.BonusDefense}"; + private void ClearDescriptionBox() { ItemName.Text = string.Empty; diff --git a/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.tscn b/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.tscn index aa116a76f..2651629b2 100644 --- a/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.tscn +++ b/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.tscn @@ -436,6 +436,43 @@ layout_mode = 2 [node name="ItemSlot20" parent="Panel/MarginContainer/PanelContainer/MenuPanel/InventoryList/Panel/MarginContainer2/Inventory" instance=ExtResource("6_unikd")] layout_mode = 2 +[node name="ItemActionResultContainer" type="PanelContainer" parent="Panel/MarginContainer/PanelContainer/MenuPanel"] +unique_name_in_owner = true +visible = false +custom_minimum_size = Vector2(200, 250) +layout_mode = 2 +offset_top = 775.0 +offset_right = 574.0 +offset_bottom = 1025.0 +focus_mode = 2 + +[node name="ItemActionResultPanel" type="Panel" parent="Panel/MarginContainer/PanelContainer/MenuPanel/ItemActionResultContainer"] +layout_mode = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_cq2sk") + +[node name="MarginContainer" type="MarginContainer" parent="Panel/MarginContainer/PanelContainer/MenuPanel/ItemActionResultContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 5 +theme_override_constants/margin_top = 5 +theme_override_constants/margin_right = 5 +theme_override_constants/margin_bottom = 5 + +[node name="ReferenceRect" type="ReferenceRect" parent="Panel/MarginContainer/PanelContainer/MenuPanel/ItemActionResultContainer/MarginContainer"] +layout_mode = 2 +border_color = Color(1, 1, 1, 1) +border_width = 2.0 +editor_only = false + +[node name="ItemActionResultLabel" type="Label" parent="Panel/MarginContainer/PanelContainer/MenuPanel/ItemActionResultContainer/MarginContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(275, 125) +layout_mode = 2 +text = "Mask of the Goddess of Suffering And Long Text Equipped." +label_settings = ExtResource("7_we8a6") +horizontal_alignment = 1 +vertical_alignment = 1 +autowrap_mode = 2 + [node name="AugmentMenu" parent="." instance=ExtResource("6_xwkpe")] unique_name_in_owner = true visible = false