Started implementation of information about item used screen

This commit is contained in:
2026-03-02 01:57:43 -08:00
parent 46f0e78405
commit bc010a7d82
8 changed files with 182 additions and 38 deletions

View File

@@ -28,7 +28,7 @@ public interface IPlayer : IKillable, ICharacterBody3D
public void ApplyNewAugment(IAugmentItem jewel, IAugmentableItem equipableItem); public void ApplyNewAugment(IAugmentItem jewel, IAugmentableItem equipableItem);
public void IdentifyItem(IBaseInventoryItem unidentifiedItem); public IBaseInventoryItem IdentifyItem(IBaseInventoryItem unidentifiedItem);
public IInventory Inventory { get; } public IInventory Inventory { get; }

View File

@@ -13,6 +13,7 @@ using System.Threading.Tasks;
using Zennysoft.Game.Implementation; using Zennysoft.Game.Implementation;
using Zennysoft.Ma.Adapter.Entity; using Zennysoft.Ma.Adapter.Entity;
using System.Linq; using System.Linq;
using Chickensoft.Collections;
[Meta(typeof(IAutoNode))] [Meta(typeof(IAutoNode))]
public partial class Game : Node3D, IGame public partial class Game : Node3D, IGame
@@ -82,6 +83,8 @@ public partial class Game : Node3D, IGame
[Signal] private delegate void OnLoadLevelRequestEventHandler(); [Signal] private delegate void OnLoadLevelRequestEventHandler();
public event Action<string> InventoryEventNotification;
public Game() public Game()
{ {
_container = new SimpleInjector.Container(); _container = new SimpleInjector.Container();
@@ -453,28 +456,43 @@ public partial class Game : Node3D, IGame
{ {
case ItemTag.DamagesPlayer: case ItemTag.DamagesPlayer:
_effectService.DamagesPlayer(boxItem.Stats.DamageToPlayer); _effectService.DamagesPlayer(boxItem.Stats.DamageToPlayer);
InventoryEventNotification.Invoke($"{boxItem.Stats.DamageToPlayer} damage done to self.");
GameRepo.CloseInventory(); GameRepo.CloseInventory();
break; break;
case ItemTag.ContainsAccessory: case ItemTag.ContainsAccessory:
_player.Inventory.TryAdd(_effectService.GetRandomItemOfType<Accessory>()); var accessory = _effectService.GetRandomItemOfType<Accessory>();
_player.Inventory.TryAdd(accessory);
InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {accessory}.");
break; break;
case ItemTag.ContainsArmor: case ItemTag.ContainsArmor:
_player.Inventory.TryAdd(_effectService.GetRandomItemOfType<Armor>()); var armor = _effectService.GetRandomItemOfType<Armor>();
_player.Inventory.TryAdd(armor);
InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {armor}.");
break; break;
case ItemTag.ContainsWeapon: case ItemTag.ContainsWeapon:
_player.Inventory.TryAdd(_effectService.GetRandomItemOfType<Weapon>()); var weapon = _effectService.GetRandomItemOfType<Weapon>();
_player.Inventory.TryAdd(weapon);
InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {weapon}.");
break; break;
case ItemTag.ContainsBox: case ItemTag.ContainsBox:
_player.Inventory.TryAdd(_effectService.GetRandomItemOfType<BoxItem>()); var box = _effectService.GetRandomItemOfType<BoxItem>();
_player.Inventory.TryAdd(box);
InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {box}.");
break; break;
case ItemTag.RandomSpell: case ItemTag.RandomSpell:
_player.Inventory.TryAdd(_effectService.GetRandomItemOfType<EffectItem>()); var effectItem = _effectService.GetRandomItemOfType<EffectItem>();
_player.Inventory.TryAdd(effectItem);
InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {effectItem}.");
break; break;
case ItemTag.ContainsRestorative: case ItemTag.ContainsRestorative:
_player.Inventory.TryAdd(_effectService.GetRandomItemOfType<ConsumableItem>()); var restorative = _effectService.GetRandomItemOfType<ConsumableItem>();
_player.Inventory.TryAdd(restorative);
InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {restorative}.");
break; break;
case ItemTag.DropTo1HPAndGainRareItem: case ItemTag.DropTo1HPAndGainRareItem:
_effectService.DropTo1HPAndGainRareItem<IBaseInventoryItem>(); var rareItem = _effectService.DropTo1HPAndGainRareItem<IBaseInventoryItem>();
_player.Inventory.TryAdd(rareItem);
InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {rareItem} but cost dear life.");
break; break;
case ItemTag.TradeOneRandomItem: case ItemTag.TradeOneRandomItem:
var itemsWithoutBox = _player.Inventory.Items.Where(x => x != boxItem).ToList(); var itemsWithoutBox = _player.Inventory.Items.Where(x => x != boxItem).ToList();
@@ -485,6 +503,7 @@ public partial class Game : Node3D, IGame
_player.Inventory.Remove(randomItem); _player.Inventory.Remove(randomItem);
var newItem = _effectService.GetRandomItemOfType<IBaseInventoryItem>(); var newItem = _effectService.GetRandomItemOfType<IBaseInventoryItem>();
_player.Inventory.TryAdd(newItem); _player.Inventory.TryAdd(newItem);
InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {newItem}.");
break; break;
case ItemTag.TradeAllRandomItems: case ItemTag.TradeAllRandomItems:
var newInventory = _effectService.TradeAllRandomItems(boxItem); var newInventory = _effectService.TradeAllRandomItems(boxItem);
@@ -492,20 +511,26 @@ public partial class Game : Node3D, IGame
_player.Inventory.TryAdd(boxItem); _player.Inventory.TryAdd(boxItem);
foreach (var item in newInventory) foreach (var item in newInventory)
_player.Inventory.TryAdd(item); _player.Inventory.TryAdd(item);
InventoryEventNotification.Invoke($"All items replaced.");
break; break;
case ItemTag.ContainsUnobtainedItem: case ItemTag.ContainsUnobtainedItem:
_effectService.GetUnobtainedItem(); var unobtainedItem = _effectService.GetUnobtainedItem();
_player.Inventory.TryAdd(unobtainedItem);
InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {unobtainedItem}.");
break; break;
case ItemTag.ContainsBasicItem: case ItemTag.ContainsBasicItem:
_effectService.GetBasicItem<IBaseInventoryItem>(); var basicItem = _effectService.GetBasicItem<IBaseInventoryItem>();
InventoryEventNotification.Invoke($"{boxItem.ItemName} contained {basicItem}.");
break; break;
case ItemTag.UnequipAllItems: case ItemTag.UnequipAllItems:
_player.Unequip(_player.EquipmentComponent.EquippedWeapon.Value); _player.Unequip(_player.EquipmentComponent.EquippedWeapon.Value);
_player.Unequip(_player.EquipmentComponent.EquippedArmor.Value); _player.Unequip(_player.EquipmentComponent.EquippedArmor.Value);
_player.Unequip(_player.EquipmentComponent.EquippedAccessory.Value); _player.Unequip(_player.EquipmentComponent.EquippedAccessory.Value);
InventoryEventNotification.Invoke($"Equipment status reset.");
break; break;
case ItemTag.RestrictUnequip: case ItemTag.RestrictUnequip:
_effectService.GlueAllEquipment(_player); _effectService.GlueAllEquipment(_player);
InventoryEventNotification.Invoke($"Currently equipped items have become unmovable.");
break; break;
case ItemTag.EjectAllItems: case ItemTag.EjectAllItems:
_player.EquipmentComponent.EquippedWeapon.Value.Glued = false; _player.EquipmentComponent.EquippedWeapon.Value.Glued = false;
@@ -519,6 +544,7 @@ public partial class Game : Node3D, IGame
foreach (var item in _player.Inventory.Items.ToList()) foreach (var item in _player.Inventory.Items.ToList())
ThrowItem(item); ThrowItem(item);
_player.Inventory.Items.Clear(); _player.Inventory.Items.Clear();
InventoryEventNotification.Invoke($"All items have been ejected from inventory.");
GameRepo.CloseInventory(); GameRepo.CloseInventory();
break; break;
} }
@@ -528,24 +554,28 @@ public partial class Game : Node3D, IGame
{ {
if (_player.HealthComponent.AtFullHealth && consumableItem.RaiseHPAmount > 0) if (_player.HealthComponent.AtFullHealth && consumableItem.RaiseHPAmount > 0)
{ {
_player.HealthComponent.RaiseMaximumHP(consumableItem.RaiseHPAmount); _player.HealthComponent.RaiseMaximumHP(consumableItem.RaiseHPAmount, true);
SfxDatabase.Instance.Play(SoundEffect.IncreaseStat); 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); SfxDatabase.Instance.Play(SoundEffect.IncreaseStat);
InventoryEventNotification.Invoke($"Raised maximum VT by {consumableItem.RaiseVTAmount}.");
} }
else if (consumableItem.HealHPAmount > 0)
if (consumableItem.HealHPAmount > 0)
{ {
var currentHP = _player.HealthComponent.CurrentHP;
_player.HealthComponent.Heal(consumableItem.HealHPAmount); _player.HealthComponent.Heal(consumableItem.HealHPAmount);
SfxDatabase.Instance.Play(SoundEffect.HealHP); 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); _player.VTComponent.Restore(consumableItem.HealVTAmount);
SfxDatabase.Instance.Play(SoundEffect.HealVT); SfxDatabase.Instance.Play(SoundEffect.HealVT);
InventoryEventNotification.Invoke($"Restored {consumableItem.HealVTAmount} VT.");
} }
} }
@@ -555,114 +585,160 @@ public partial class Game : Node3D, IGame
{ {
case UsableItemTag.TeleportAllEnemiesToRoom: case UsableItemTag.TeleportAllEnemiesToRoom:
_effectService.TeleportEnemiesToCurrentRoom(GetTree().GetNodesInGroup("enemy").OfType<IEnemy>().ToList()); _effectService.TeleportEnemiesToCurrentRoom(GetTree().GetNodesInGroup("enemy").OfType<IEnemy>().ToList());
SfxDatabase.Instance.Play(SoundEffect.RecallEnemies);
InventoryEventNotification.Invoke($"All enemies have been summoned.");
GameRepo.CloseInventory(); GameRepo.CloseInventory();
_player.PlaySpellFX(SpellFXEnum.DivinityRecall); _player.PlaySpellFX(SpellFXEnum.DivinityRecall);
SfxDatabase.Instance.Play(SoundEffect.RecallEnemies);
break; break;
case UsableItemTag.KillHalfEnemiesInRoom: case UsableItemTag.KillHalfEnemiesInRoom:
_effectService.KillHalfEnemiesInRoom(); _effectService.KillHalfEnemiesInRoom();
InventoryEventNotification.Invoke($"The balance has been achieved.");
GameRepo.CloseInventory(); GameRepo.CloseInventory();
break; break;
case UsableItemTag.TurnAllEnemiesIntoHealingItem: case UsableItemTag.TurnAllEnemiesIntoHealingItem:
_effectService.TurnAllEnemiesInRoomIntoHealingItem(); _effectService.TurnAllEnemiesInRoomIntoHealingItem();
InventoryEventNotification.Invoke($"Enemies in current room have been converted.");
GameRepo.CloseInventory(); GameRepo.CloseInventory();
break; break;
case UsableItemTag.HealsAllInRoomToMaxHP: case UsableItemTag.HealsAllInRoomToMaxHP:
_effectService.HealAllEnemiesAndPlayerInRoomToFull(); _effectService.HealAllEnemiesAndPlayerInRoomToFull();
InventoryEventNotification.Invoke($"All present have been renewed.");
GameRepo.CloseInventory(); GameRepo.CloseInventory();
break; break;
case UsableItemTag.AbsorbHPFromAllEnemiesInRoom: 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(); GameRepo.CloseInventory();
_player.PlaySpellFX(SpellFXEnum.Kyuuketsuki);
break; break;
case UsableItemTag.DealElementalDamageToAllEnemiesInRoom: case UsableItemTag.DealElementalDamageToAllEnemiesInRoom:
_effectService.DealElementalDamageToAllEnemiesInRoom(effectItem.Stats.ElementalDamageType); _effectService.DealElementalDamageToAllEnemiesInRoom(effectItem.Stats.ElementalDamageType);
InventoryEventNotification.Invoke($"All enemies present have taken {effectItem.Stats.ElementalDamageType} to you.");
GameRepo.CloseInventory(); GameRepo.CloseInventory();
break; break;
case UsableItemTag.SwapHPAndVT: case UsableItemTag.SwapHPAndVT:
_effectService.SwapHPandVT(); _effectService.SwapHPandVT();
InventoryEventNotification.Invoke($"HP and VT have been traded.");
GameRepo.CloseInventory(); GameRepo.CloseInventory();
break; break;
case UsableItemTag.RaiseCurrentWeaponAttack: case UsableItemTag.RaiseCurrentWeaponAttack:
if (string.IsNullOrEmpty(_player.EquipmentComponent.EquippedWeapon.Value.ItemName))
return;
_effectService.RaiseCurrentWeaponAttack(); _effectService.RaiseCurrentWeaponAttack();
InventoryEventNotification.Invoke($"{_player.EquipmentComponent.EquippedWeapon.Value}'s attack has risen by 1.");
break; break;
case UsableItemTag.RaiseCurrentDefenseArmor: case UsableItemTag.RaiseCurrentDefenseArmor:
if (string.IsNullOrEmpty(_player.EquipmentComponent.EquippedArmor.Value.ItemName))
return;
_effectService.RaiseCurrentArmorDefense(); _effectService.RaiseCurrentArmorDefense();
InventoryEventNotification.Invoke($"{_player.EquipmentComponent.EquippedArmor.Value}'s defense has risen by 1.");
break; break;
case UsableItemTag.RaiseLevel: case UsableItemTag.RaiseLevel:
_effectService.RaiseLevel(); _effectService.RaiseLevel();
InventoryEventNotification.Invoke($"Level increased to {_player.ExperiencePointsComponent.Level.Value}");
break; break;
case UsableItemTag.LowerLevel: case UsableItemTag.LowerLevel:
_effectService.LowerLevel(); _effectService.LowerLevel();
InventoryEventNotification.Invoke($"Level decreased to {_player.ExperiencePointsComponent.Level.Value}");
break; break;
case UsableItemTag.LowerCurrentDefenseArmor: case UsableItemTag.LowerCurrentDefenseArmor:
if (string.IsNullOrEmpty(_player.EquipmentComponent.EquippedArmor.Value.ItemName))
return;
_effectService.LowerCurrentArmorDefense(); _effectService.LowerCurrentArmorDefense();
InventoryEventNotification.Invoke($"{_player.EquipmentComponent.EquippedArmor.Value}'s defense has been lowered by 1.");
break; break;
case UsableItemTag.RandomEffect: case UsableItemTag.RandomEffect:
_effectService.RandomEffect(); _effectService.RandomEffect();
break; break;
case UsableItemTag.DoubleExp: case UsableItemTag.DoubleExp:
_effectService.DoubleExp(); _effectService.DoubleExp();
InventoryEventNotification.Invoke($"EXP Rate has been doubled.");
GameRepo.CloseInventory(); GameRepo.CloseInventory();
_player.PlaySpellFX(SpellFXEnum.AnBradan); _player.PlaySpellFX(SpellFXEnum.AnBradan);
break; break;
case UsableItemTag.TeleportToRandomLocation: case UsableItemTag.TeleportToRandomLocation:
_effectService.TeleportToRandomRoom(_player); _effectService.TeleportToRandomRoom(_player);
InventoryEventNotification.Invoke($"Moving to a different room.");
GameRepo.CloseInventory(); GameRepo.CloseInventory();
break; break;
case UsableItemTag.WarpToExitIfFound: 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(); GameRepo.CloseInventory();
break; break;
case UsableItemTag.IncreaseAttack: case UsableItemTag.IncreaseAttack:
_player.AttackComponent.RaiseMaximumAttack(effectItem.Stats.BonusAttack); _player.AttackComponent.RaiseMaximumAttack(effectItem.Stats.BonusAttack);
SfxDatabase.Instance.Play(SoundEffect.IncreaseStat); SfxDatabase.Instance.Play(SoundEffect.IncreaseStat);
InventoryEventNotification.Invoke($"Attack has permanently risen to {_player.AttackComponent.CurrentAttack.Value}.");
break; break;
case UsableItemTag.IncreaseDefense: case UsableItemTag.IncreaseDefense:
_player.DefenseComponent.RaiseMaximumDefense(effectItem.Stats.BonusDefense); _player.DefenseComponent.RaiseMaximumDefense(effectItem.Stats.BonusDefense);
SfxDatabase.Instance.Play(SoundEffect.IncreaseStat); SfxDatabase.Instance.Play(SoundEffect.IncreaseStat);
InventoryEventNotification.Invoke($"Defense has permanently risen to {_player.DefenseComponent.CurrentDefense.Value}.");
break; break;
case UsableItemTag.IncreaseLuck: case UsableItemTag.IncreaseLuck:
_player.LuckComponent.IncreaseLuck(effectItem.Stats.BonusLuck); _player.LuckComponent.IncreaseLuck(effectItem.Stats.BonusLuck);
SfxDatabase.Instance.Play(SoundEffect.IncreaseStat); SfxDatabase.Instance.Play(SoundEffect.IncreaseStat);
InventoryEventNotification.Invoke($"Luck increased.");
break; break;
case UsableItemTag.DecreaseAttack: case UsableItemTag.DecreaseAttack:
_player.AttackComponent.Reduce(effectItem.Stats.BonusAttack); _player.AttackComponent.Reduce(effectItem.Stats.BonusAttack);
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat); SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
InventoryEventNotification.Invoke($"Attack has been lowered to {_player.AttackComponent.CurrentAttack.Value}.");
break; break;
case UsableItemTag.DecreaseDefense: case UsableItemTag.DecreaseDefense:
_player.DefenseComponent.Reduce(effectItem.Stats.BonusDefense); _player.DefenseComponent.Reduce(effectItem.Stats.BonusDefense);
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat); SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
InventoryEventNotification.Invoke($"Defense has been lowered to {_player.DefenseComponent.CurrentDefense.Value}.");
break; break;
case UsableItemTag.DecreaseLuck: case UsableItemTag.DecreaseLuck:
_player.LuckComponent.DecreaseLuck(effectItem.Stats.BonusLuck); _player.LuckComponent.DecreaseLuck(effectItem.Stats.BonusLuck);
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat); SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
InventoryEventNotification.Invoke($"Luck decreased.");
break; break;
case UsableItemTag.DecreaseAllStats: case UsableItemTag.DecreaseAllStats:
_player.AttackComponent.Reduce(effectItem.Stats.BonusAttack); _player.AttackComponent.Reduce(effectItem.Stats.BonusAttack);
_player.DefenseComponent.Reduce(effectItem.Stats.BonusDefense); _player.DefenseComponent.Reduce(effectItem.Stats.BonusDefense);
_player.LuckComponent.DecreaseLuck(effectItem.Stats.BonusLuck); _player.LuckComponent.DecreaseLuck(effectItem.Stats.BonusLuck);
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat); SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
InventoryEventNotification.Invoke($"All stats have been lowered.");
break; break;
case UsableItemTag.MeltAllEquipment: case UsableItemTag.MeltAllEquipment:
_effectService.MeltAllEquipment(_player); _effectService.MeltAllEquipment(_player);
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat); SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
InventoryEventNotification.Invoke($"All equipped items have dissolved.");
break; break;
case UsableItemTag.GlueAllEquipment: case UsableItemTag.GlueAllEquipment:
_effectService.GlueAllEquipment(_player); _effectService.GlueAllEquipment(_player);
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat); SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
InventoryEventNotification.Invoke($"All equipped items have become sticky.");
break; break;
case UsableItemTag.RestoreStats: case UsableItemTag.RestoreStats:
_effectService.RestoreParameters(_player); _effectService.RestoreParameters(_player);
SfxDatabase.Instance.Play(SoundEffect.IncreaseStat); SfxDatabase.Instance.Play(SoundEffect.IncreaseStat);
InventoryEventNotification.Invoke($"All stats have been restored.");
break; break;
case UsableItemTag.LowerTargetTo1HP: case UsableItemTag.LowerTargetTo1HP:
_player.HealthComponent.SetCurrentHealth(1); _player.HealthComponent.SetCurrentHealth(1);
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat); SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
InventoryEventNotification.Invoke($"HP has been reduced to 1.");
break; break;
case UsableItemTag.DoubleStackedItems: case UsableItemTag.DoubleStackedItems:
var stackableItems = _player.Inventory.Items.OfType<IStackable>().ToList(); var stackableItems = _player.Inventory.Items.OfType<IStackable>().ToList();
stackableItems.ForEach(x => x.Count.OnNext(x.Count.Value * 2)); stackableItems.ForEach(x => x.Count.OnNext(x.Count.Value * 2));
InventoryEventNotification.Invoke($"Items with inventory count have been doubled.");
break; break;
case UsableItemTag.IdentifyRandomItem: case UsableItemTag.IdentifyRandomItem:
var unidentifiedItems = _player.Inventory.Items.Where(x => x.ItemTag == ItemTag.MysteryItem).ToList(); 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(); var rng = new RandomNumberGenerator();
rng.Randomize(); rng.Randomize();
var index = rng.RandiRange(0, unidentifiedItems.Count - 1); 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; break;
} }
_player.EquipmentComponent.UpdateEquipment(_player.EquipmentComponent.EquippedWeapon.Value); _player.EquipmentComponent.UpdateEquipment(_player.EquipmentComponent.EquippedWeapon.Value);

View File

@@ -2,6 +2,7 @@
namespace Zennysoft.Game.Ma; namespace Zennysoft.Game.Ma;
using Chickensoft.AutoInject; using Chickensoft.AutoInject;
using Chickensoft.Collections;
using Chickensoft.GodotNodeInterfaces; using Chickensoft.GodotNodeInterfaces;
using Chickensoft.SaveFileBuilder; using Chickensoft.SaveFileBuilder;
using System; using System;
@@ -43,4 +44,6 @@ public interface IGame : IProvide<IGame>, IProvide<IGameRepo>, IProvide<IPlayer>
public event Action GameExitRequested; public event Action GameExitRequested;
public event Action GameLoaded; public event Action GameLoaded;
public event Action<string> InventoryEventNotification;
} }

View File

@@ -88,12 +88,12 @@ public class EffectService
SfxDatabase.Instance.Play(SoundEffect.HealHP); SfxDatabase.Instance.Play(SoundEffect.HealHP);
} }
public void AbsorbHPFromAllEnemiesInRoom() public int AbsorbHPFromAllEnemiesInRoom()
{ {
var currentRoom = _map.GetPlayersCurrentRoom(); var currentRoom = _map.GetPlayersCurrentRoom();
if (currentRoom is not MonsterRoom) if (currentRoom is not MonsterRoom)
return; return 0;
var currentEnemies = currentRoom.EnemiesInRoom; var currentEnemies = currentRoom.EnemiesInRoom;
var hpToAbsorb = 0.0; var hpToAbsorb = 0.0;
@@ -104,9 +104,7 @@ public class EffectService
hpToAbsorb += absorbAmount; hpToAbsorb += absorbAmount;
enemy.OnAbsorb(); enemy.OnAbsorb();
} }
_player.HealthComponent.Heal((int)hpToAbsorb); return (int)hpToAbsorb;
_player.PlaySpellFX(SpellFXEnum.Kyuuketsuki);
GD.Print("HP to absorb: " + hpToAbsorb);
} }
public void DealElementalDamageToAllEnemiesInRoom(ElementType elementType) public void DealElementalDamageToAllEnemiesInRoom(ElementType elementType)
@@ -306,7 +304,7 @@ public class EffectService
SfxDatabase.Instance.Play(SoundEffect.TeleportToRandomRoom); SfxDatabase.Instance.Play(SoundEffect.TeleportToRandomRoom);
} }
public void WarpToExit() public bool WarpToExit()
{ {
var exitRoom = _game.CurrentFloor.Rooms.OfType<ExitRoom>().Single(); var exitRoom = _game.CurrentFloor.Rooms.OfType<ExitRoom>().Single();
if (exitRoom.PlayerDiscoveredRoom) if (exitRoom.PlayerDiscoveredRoom)
@@ -314,7 +312,9 @@ public class EffectService
SfxDatabase.Instance.Play(SoundEffect.TeleportToExit); SfxDatabase.Instance.Play(SoundEffect.TeleportToExit);
var exitPoint = exitRoom.PlayerSpawn.GlobalPosition; var exitPoint = exitRoom.PlayerSpawn.GlobalPosition;
_player.TeleportPlayer((exitRoom.PlayerSpawn.Rotation, new Vector3(exitPoint.X, _player.GlobalPosition.Y, exitPoint.Z))); _player.TeleportPlayer((exitRoom.PlayerSpawn.Rotation, new Vector3(exitPoint.X, _player.GlobalPosition.Y, exitPoint.Z)));
return true;
} }
return false;
} }
public void DamagesPlayer(int damage) public void DamagesPlayer(int damage)
@@ -341,11 +341,11 @@ public class EffectService
_game.UseItem(item); _game.UseItem(item);
} }
public void DropTo1HPAndGainRareItem<T>() public T DropTo1HPAndGainRareItem<T>()
where T : IBaseInventoryItem where T : IBaseInventoryItem
{ {
_player.HealthComponent.SetCurrentHealth(1); _player.HealthComponent.SetCurrentHealth(1);
_player.Inventory.TryAdd(ItemDatabase.Instance.PickRareItem<T>()); return ItemDatabase.Instance.PickRareItem<T>();
} }
public void TradeRandomItem<T>(BoxItem box) public void TradeRandomItem<T>(BoxItem box)
@@ -373,7 +373,7 @@ public class EffectService
return newInventory; return newInventory;
} }
public void GetUnobtainedItem() public IBaseInventoryItem GetUnobtainedItem()
{ {
var pickableItems = ItemDatabase.Instance.Items.Except(_player.Inventory.Items).ToList(); var pickableItems = ItemDatabase.Instance.Items.Except(_player.Inventory.Items).ToList();
var rng = new RandomNumberGenerator(); var rng = new RandomNumberGenerator();
@@ -384,12 +384,12 @@ public class EffectService
if (selectedItem is ThrowableItem throwableItem) if (selectedItem is ThrowableItem throwableItem)
throwableItem.SetCount(rng.RandiRange(throwableItem.Stats.MinimumCount, throwableItem.Stats.MaximumCount)); throwableItem.SetCount(rng.RandiRange(throwableItem.Stats.MinimumCount, throwableItem.Stats.MaximumCount));
_player.Inventory.TryAdd(selectedItem); return selectedItem;
} }
public void GetBasicItem<T>() public T GetBasicItem<T>()
where T : IBaseInventoryItem where T : IBaseInventoryItem
{ {
_player.Inventory.TryAdd(ItemDatabase.Instance.PickBasicItem<T>()); return ItemDatabase.Instance.PickBasicItem<T>();
} }
} }

View File

@@ -29,7 +29,6 @@ public partial class DummyPlayer : CharacterBody3D, IPlayer
public void Deactivate() => throw new NotImplementedException(); public void Deactivate() => throw new NotImplementedException();
public void Die() => throw new NotImplementedException(); public void Die() => throw new NotImplementedException();
public void Equip(IEquipableItem equipable) => 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 Knockback(float impulse) => throw new NotImplementedException();
public void LevelUp() => throw new NotImplementedException(); public void LevelUp() => throw new NotImplementedException();
public void ModifyHealthTimerSpeed(float newModifier) => 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 TakeDamage(AttackData damage) => throw new NotImplementedException();
public void TeleportPlayer((Vector3 Rotation, Vector3 Position) newTransform) => throw new NotImplementedException(); public void TeleportPlayer((Vector3 Rotation, Vector3 Position) newTransform) => throw new NotImplementedException();
public void Unequip(IEquipableItem equipable) => throw new NotImplementedException(); public void Unequip(IEquipableItem equipable) => throw new NotImplementedException();
public IBaseInventoryItem IdentifyItem(IBaseInventoryItem unidentifiedItem) => throw new NotImplementedException();
} }

View File

@@ -273,7 +273,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
public void PlayJumpScareAnimation() => PlayerFXAnimations.Play("jump_scare"); 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; public int TotalAttack => AttackComponent.CurrentAttack.Value + EquipmentComponent.BonusAttack;

View File

@@ -45,10 +45,16 @@ public partial class InventoryMenu : Control, IInventoryMenu
[Node] public Label StatusLabel { get; set; } [Node] public Label StatusLabel { get; set; }
[Node] public PanelContainer ItemActionResultContainer { get; set; }
[Node] public Label ItemActionResultLabel { get; set; }
private List<IItemSlot> ItemSlots; private List<IItemSlot> ItemSlots;
private IItemSlot _currentlySelected; private IItemSlot _currentlySelected;
private bool _blocking = false;
public void OnResolved() public void OnResolved()
{ {
ItemSlots = [.. Inventory.GetChildren().OfType<IItemSlot>()]; ItemSlots = [.. Inventory.GetChildren().OfType<IItemSlot>()];
@@ -68,13 +74,11 @@ public partial class InventoryMenu : Control, IInventoryMenu
AttackChanged(0); AttackChanged(0);
DefenseChanged(0); DefenseChanged(0);
StatusLabel.Text = string.Empty; StatusLabel.Text = string.Empty;
ItemActionResultLabel.Text = string.Empty;
_game.InventoryEventNotification += InventoryEventNotification_Changed;
Hide(); 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) public override void _Input(InputEvent @event)
{ {
var validSelectableItems = _player.Inventory.Items.ToList(); var validSelectableItems = _player.Inventory.Items.ToList();
@@ -98,6 +102,9 @@ public partial class InventoryMenu : Control, IInventoryMenu
private void ActionPanel_AugmentMenuRequested() private void ActionPanel_AugmentMenuRequested()
{ {
if (_blocking)
return;
ReleaseFocus(); ReleaseFocus();
ItemSlots.ForEach(x => x.ItemPressed -= ItemPressed); ItemSlots.ForEach(x => x.ItemPressed -= ItemPressed);
ItemSlots.ForEach(x => x.ItemSelected -= ItemSelected); ItemSlots.ForEach(x => x.ItemSelected -= ItemSelected);
@@ -114,6 +121,9 @@ public partial class InventoryMenu : Control, IInventoryMenu
private void ItemPressed(IItemSlot selectedItem) private void ItemPressed(IItemSlot selectedItem)
{ {
if (_blocking)
return;
SetProcessInput(false); SetProcessInput(false);
ActionPanel.SetProcessInput(true); ActionPanel.SetProcessInput(true);
ActionPanel.ShowPanel(selectedItem.Item.Value); ActionPanel.ShowPanel(selectedItem.Item.Value);
@@ -156,6 +166,22 @@ public partial class InventoryMenu : Control, IInventoryMenu
ActionPanel.Hide(); 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() private void ClearDescriptionBox()
{ {
ItemName.Text = string.Empty; ItemName.Text = string.Empty;

View File

@@ -436,6 +436,43 @@ layout_mode = 2
[node name="ItemSlot20" parent="Panel/MarginContainer/PanelContainer/MenuPanel/InventoryList/Panel/MarginContainer2/Inventory" instance=ExtResource("6_unikd")] [node name="ItemSlot20" parent="Panel/MarginContainer/PanelContainer/MenuPanel/InventoryList/Panel/MarginContainer2/Inventory" instance=ExtResource("6_unikd")]
layout_mode = 2 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")] [node name="AugmentMenu" parent="." instance=ExtResource("6_xwkpe")]
unique_name_in_owner = true unique_name_in_owner = true
visible = false visible = false