Add item spawn menu

Fix game over bug
Start adding more implementation for jewels
This commit is contained in:
2026-02-11 15:25:20 -08:00
parent 8ce38c3c13
commit 230b47061d
32 changed files with 1215 additions and 358 deletions

View File

@@ -1,6 +1,5 @@
[gd_scene load_steps=21 format=3 uid="uid://dlj8qdg1c5048"]
[gd_scene load_steps=21 format=3 uid="uid://cbxw70qa7gifp"]
[ext_resource type="Script" uid="uid://bi1xopts68paw" path="res://src/ui/inventory_menu/InventoryMenu.cs" id="1_b6rkr"]
[ext_resource type="PackedScene" uid="uid://c005nd0m2eim" path="res://src/ui/inventory_menu/ItemSlot.tscn" id="4_aiji3"]
[ext_resource type="LabelSettings" uid="uid://wc363u5t1yi2" path="res://src/ui/label_settings/HeadingFont.tres" id="4_l0byb"]
[ext_resource type="LabelSettings" uid="uid://cuuo43x72xcsc" path="res://src/ui/label_settings/MainTextBold.tres" id="7_vyrxm"]
@@ -8,6 +7,345 @@
[ext_resource type="Theme" uid="uid://daxuhpmyxwxck" path="res://src/ui/inventory_menu/InventoryDialogueSelectionStyle.tres" id="8_khyvo"]
[ext_resource type="LabelSettings" uid="uid://bgnwcs434ppkf" path="res://src/ui/label_settings/EbrimaText.tres" id="8_ldqki"]
[sub_resource type="CSharpScript" id="CSharpScript_xwkpe"]
script/source = "using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Zennysoft.Ma.Adapter;
namespace Zennysoft.Game.Ma;
[Meta(typeof(IAutoNode))]
public partial class InventoryMenu : Control, IInventoryMenu
{
public override void _Notification(int what) => this.Notify(what);
[Node] public VBoxContainer ItemsPage { get; set; }
[Node] public Label ATKValue { get; set; }
[Node] public Label ATKBonusLabel { get; set; }
[Node] public Label DEFValue { get; set; }
[Node] public Label DEFBonusLabel { get; set; }
[Node] public Button UseButton { get; set; }
[Node] public Button ThrowButton { get; set; }
[Node] public Button DropButton { get; set; }
[Node] public Label ItemDescriptionTitle { get; set; }
[Node] public Label UseItemPrompt { get; set; }
[Node] public Label ItemEffectLabel { get; set; }
[Node] public ItemSlot ItemSlot1 { get; set; }
[Node] public ItemSlot ItemSlot2 { get; set; }
[Node] public ItemSlot ItemSlot3 { get; set; }
[Node] public ItemSlot ItemSlot4 { get; set; }
[Node] public ItemSlot ItemSlot5 { get; set; }
[Node] public ItemSlot ItemSlot6 { get; set; }
[Node] public ItemSlot ItemSlot7 { get; set; }
[Node] public ItemSlot ItemSlot8 { get; set; }
[Node] public ItemSlot ItemSlot9 { get; set; }
[Node] public ItemSlot ItemSlot10 { get; set; }
[Node] public ItemSlot ItemSlot11 { get; set; }
[Node] public ItemSlot ItemSlot12 { get; set; }
[Node] public ItemSlot ItemSlot13 { get; set; }
[Node] public ItemSlot ItemSlot14 { get; set; }
[Node] public ItemSlot ItemSlot15 { get; set; }
[Node] public ItemSlot ItemSlot16 { get; set; }
[Node] public ItemSlot ItemSlot17 { get; set; }
[Node] public ItemSlot ItemSlot18 { get; set; }
[Node] public ItemSlot ItemSlot19 { get; set; }
[Node] public ItemSlot ItemSlot20 { get; set; }
[Dependency] private IPlayer _player => this.DependOn<IPlayer>();
[Dependency] private IGame _game => this.DependOn<IGame>();
[Dependency] private IGameRepo _gameRepo => this.DependOn<IGameRepo>();
private List<IItemSlot> ItemSlots;
private string ITEM_SLOT_SCENE = \"res://src/ui/inventory_menu/ItemSlot.tscn\";
private IItemSlot _currentlySelectedItem = null;
private bool _enableMenuSound = false;
public void OnResolved()
{
ItemSlots = [ItemSlot1, ItemSlot2, ItemSlot3, ItemSlot4, ItemSlot5, ItemSlot6, ItemSlot7, ItemSlot8, ItemSlot9, ItemSlot10, ItemSlot11, ItemSlot12, ItemSlot13, ItemSlot14, ItemSlot15, ItemSlot16, ItemSlot17, ItemSlot18, ItemSlot19, ItemSlot20];
_currentlySelectedItem = ItemSlot1;
foreach (var item in ItemSlots)
{
item.ItemPressed += Item_Pressed;
}
_player.AttackComponent.CurrentAttack.Sync += Attack_Sync;
_player.AttackComponent.MaximumAttack.Sync += Attack_Sync;
_player.DefenseComponent.CurrentDefense.Sync += Defense_Sync;
_player.DefenseComponent.MaximumDefense.Sync += Defense_Sync;
_player.EquipmentComponent.EquipmentChanged += EquipmentComponent_EquipmentChanged;
_player.Inventory.InventoryChanged += Inventory_InventoryChanged;
UseButton.Pressed += UseButtonPressed;
ThrowButton.Pressed += ThrowButtonPressed;
DropButton.Pressed += DropButtonPressed;
UseButton.FocusEntered += ActionButtonFocusChanged;
ThrowButton.FocusEntered += ActionButtonFocusChanged;
DropButton.FocusEntered += ActionButtonFocusChanged;
VisibilityChanged += InventoryMenu_VisibilityChanged;
SetProcessUnhandledInput(false);
}
private void ActionButtonFocusChanged()
{
if (!_enableMenuSound)
SfxDatabase.Instance.Play(SoundEffect.MoveUI);
}
public override void _UnhandledInput(InputEvent @event)
{
if (!Visible)
return;
if ((!Input.IsActionJustPressed(GameInputs.UiUp) && Input.IsActionPressed(GameInputs.UiUp)) || (!Input.IsActionJustPressed(GameInputs.UiDown) && Input.IsActionPressed(GameInputs.UiDown)))
AcceptEvent();
if (Input.IsActionJustPressed(GameInputs.UiCancel) && (UseItemPrompt.Visible))
{
SfxDatabase.Instance.Play(SoundEffect.CancelUI);
AcceptEvent();
HideUserActionPrompt();
}
else if (Input.IsActionJustPressed(GameInputs.UiCancel))
{
SfxDatabase.Instance.Play(SoundEffect.CancelUI);
AcceptEvent();
_gameRepo.CloseInventory();
}
if (Input.IsActionJustPressed(GameInputs.InventorySort))
{
var isChanged = _player.Inventory.Sort(_player.EquipmentComponent.EquippedWeapon.Value, _player.EquipmentComponent.EquippedArmor.Value, _player.EquipmentComponent.EquippedAccessory.Value, _player.EquipmentComponent.EquippedAmmo.Value);
if (!isChanged)
return;
SfxDatabase.Instance.Play(SoundEffect.SortInventory);
Inventory_InventoryChanged();
Item_ItemExitFocus(_currentlySelectedItem);
_currentlySelectedItem = ItemSlot1;
_currentlySelectedItem.GrabFocus();
}
}
private void InventoryMenu_VisibilityChanged()
{
if (Visible)
{
SetProcessUnhandledInput(true);
SfxDatabase.Instance.Play(SoundEffect.OpenInventory);
_currentlySelectedItem.GrabFocus();
_enableMenuSound = true;
}
else
{
SetProcessUnhandledInput(false);
SfxDatabase.Instance.Play(SoundEffect.CancelUI);
_enableMenuSound = false;
}
}
private void Item_ItemExitFocus(IItemSlot itemSlot)
{
ItemDescriptionTitle.Text = string.Empty;
ItemEffectLabel.Text = string.Empty;
}
private void Item_FocusEntered(IItemSlot itemSlot)
{
if (itemSlot.Item.Value == null)
return;
if (_enableMenuSound)
SfxDatabase.Instance.Play(SoundEffect.MoveUI);
ItemDescriptionTitle.Text = $\"{itemSlot.Item.Value.ItemName}\";
ItemEffectLabel.Text = $\"{itemSlot.Item.Value.Description}\";
_currentlySelectedItem = itemSlot;
AcceptEvent();
}
private void Item_Pressed(IItemSlot item) => DisplayUserActionPrompt(item.Item.Value);
private async void Inventory_InventoryChanged()
{
foreach (var slot in ItemSlots)
{
slot.Visible = false;
}
var itemsToDisplay = _player.Inventory.Items;
for (var i = 0; i < itemsToDisplay.Count; i++)
{
ItemSlots[i].Item.OnNext(itemsToDisplay[i]);
ItemSlots[i].Visible = true;
}
if (!_player.Inventory.Items.Contains(_currentlySelectedItem.Item.Value))
{
_currentlySelectedItem.Item.OnNext(null);
var elementToSelect = Mathf.Max(0, ItemSlots.IndexOf(_currentlySelectedItem) - 1);
_currentlySelectedItem = ItemSlots.ElementAt(elementToSelect);
_currentlySelectedItem.GrabFocus();
}
}
private void Attack_Sync(int obj) => ATKValue.Text = $\"{_player.AttackComponent.CurrentAttack.Value}/{_player.AttackComponent.MaximumAttack.Value}\";
private void Defense_Sync(int obj) => DEFValue.Text = $\"{_player.DefenseComponent.CurrentDefense.Value}/{_player.DefenseComponent.MaximumDefense.Value}\";
private void EquipmentComponent_EquipmentChanged(EquipableItem equipableItem)
{
ATKBonusLabel.Text = $\"{_player.EquipmentComponent.BonusAttack:+0;-#;\\\\.\\\\.\\\\.}\";
DEFBonusLabel.Text = $\"{_player.EquipmentComponent.BonusDefense:+0;-#;\\\\.\\\\.\\\\.}\";
}
private async void UseButtonPressed()
{
UseButton.Disabled = true;
if (_currentlySelectedItem.Item.Value is EquipableItem equipable)
await EquipOrUnequipItem(equipable);
else if (_currentlySelectedItem.Item.Value is Plastique plastique)
SetItem();
else if (_currentlySelectedItem.Item.Value is Jewel jewel)
AugmentEquipment(jewel);
else
await _game.UseItem(_currentlySelectedItem.Item.Value);
UseButton.Disabled = false;
HideUserActionPrompt();
await ShowInventoryInfo();
await ToSignal(GetTree().CreateTimer(1f), \"timeout\");
}
private async void SetItem()
{
_game.SetItem(_currentlySelectedItem.Item.Value);
_player.Inventory.Remove(_currentlySelectedItem.Item.Value);
HideUserActionPrompt();
await ShowInventoryInfo();
_gameRepo.CloseInventory();
}
private async void ThrowButtonPressed()
{
_game.ThrowItem(_currentlySelectedItem.Item.Value);
_player.Inventory.Remove(_currentlySelectedItem.Item.Value);
HideUserActionPrompt();
await ShowInventoryInfo();
_gameRepo.CloseInventory();
}
private async void DropButtonPressed()
{
_game.DropItem(_currentlySelectedItem.Item.Value);
_player.Inventory.Remove(_currentlySelectedItem.Item.Value);
HideUserActionPrompt();
await ShowInventoryInfo();
_gameRepo.CloseInventory();
}
private void AugmentEquipment(Jewel jewel)
{
DisplayUserActionPrompt(jewel);
foreach (var item in ItemSlots)
{
item.Disabled = item.Item.Value is not Weapon && item.Item.Value is not Armor && item.Item.Value is not Accessory;
}
}
private void DisplayUserActionPrompt(InventoryItem item)
{
SfxDatabase.Instance.Play(SoundEffect.SelectUI);
ItemDescriptionTitle.Hide();
ItemEffectLabel.Hide();
UseItemPrompt.Show();
UseButton.Show();
ThrowButton.Show();
DropButton.Show();
if (item is EquipableItem equipable)
{
var isItemEquipped = _player.EquipmentComponent.IsItemEquipped(equipable);
UseButton.Text = isItemEquipped ? \"Unequip\" : \"Equip\";
UseButton.Disabled = equipable.Glued;
ThrowButton.Disabled = isItemEquipped;
ThrowButton.FocusMode = isItemEquipped ? FocusModeEnum.None : FocusModeEnum.All;
DropButton.Disabled = isItemEquipped;
DropButton.FocusMode = isItemEquipped ? FocusModeEnum.None : FocusModeEnum.All;
UseButton.GrabFocus();
if (!_player.CanEquipState && isItemEquipped)
UseButton.Disabled = true;
}
else if (item is Plastique plastique)
{
UseButton.Text = \"Set\";
}
else
{
UseButton.Text = \"Use\";
}
_enableMenuSound = false;
}
private void HideUserActionPrompt()
{
UseItemPrompt.Hide();
UseButton.Hide();
ThrowButton.Hide();
DropButton.Hide();
UseButton.ReleaseFocus();
ThrowButton.ReleaseFocus();
DropButton.ReleaseFocus();
_currentlySelectedItem.GrabFocus();
_enableMenuSound = true;
}
private async Task EquipOrUnequipItem(EquipableItem equipable)
{
if (_player.EquipmentComponent.IsItemEquipped(equipable))
{
SfxDatabase.Instance.Play(SoundEffect.Unequip);
ItemEffectLabel.Text = $\"{equipable.GetType().Name} unequipped.\";
_player.Unequip(equipable);
}
else
{
SfxDatabase.Instance.Play(SoundEffect.Equip);
var itemSlot = _currentlySelectedItem;
ItemEffectLabel.Text = $\"{equipable.GetType().Name} equipped.\";
_player.Equip(equipable);
_currentlySelectedItem = itemSlot;
}
}
private async Task ShowInventoryInfo()
{
ItemDescriptionTitle.Show();
ItemEffectLabel.Show();
}
private enum InventoryPageNumber
{
FirstPage,
SecondPage
}
}
"
[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_unikd"]
blend_mode = 4
@@ -47,7 +385,7 @@ grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
mouse_filter = 2
script = ExtResource("1_b6rkr")
script = SubResource("CSharpScript_xwkpe")
[node name="BG" type="ColorRect" parent="."]
material = SubResource("CanvasItemMaterial_unikd")