Add inventory menu

pull/43/head
John Montagu, the 4th Earl of Sandvich 2024-08-21 16:20:35 -07:00
parent ddccda70ef
commit 2501e2a807
Signed by: sandvich
GPG Key ID: 9A39BE37E602B22D
14 changed files with 498 additions and 77 deletions

View File

@ -36,9 +36,9 @@
[ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="27_mndpv"] [ext_resource type="Script" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="27_mndpv"]
[ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="28_6gq8l"] [ext_resource type="Script" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="28_6gq8l"]
[ext_resource type="Script" path="res://Items/PlayerInventory.cs" id="30_y2wmw"] [ext_resource type="Script" path="res://Items/PlayerInventory.cs" id="30_y2wmw"]
[ext_resource type="PackedScene" uid="uid://cgg0sfm2qeiwn" path="res://Items/Weapons/Bow.tscn" id="31_mofvy"] [ext_resource type="Resource" uid="uid://cl7jvdu2lnv2d" path="res://Items/Weapons/Sword.tres" id="33_3qyfl"]
[ext_resource type="PackedScene" uid="uid://dvqap2uhcah63" path="res://Items/Weapons/Sword.tscn" id="31_ql4as"] [ext_resource type="Resource" uid="uid://cjsh0dcgbfn77" path="res://Items/Weapons/Bow.tres" id="34_70ron"]
[ext_resource type="PackedScene" uid="uid://5y1acxl4j4n7" path="res://Items/Weapons/Pugio.tscn" id="32_6ffmm"] [ext_resource type="Resource" uid="uid://iqe6rgnb3jur" path="res://Items/Weapons/Pugio.tres" id="35_4pap1"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_h78y7"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_h78y7"]
shader = ExtResource("2_ngsgt") shader = ExtResource("2_ngsgt")
@ -836,35 +836,14 @@ horizontal_alignment = 1
[node name="Inventory" type="Node2D" parent="." node_paths=PackedStringArray("Hotbar")] [node name="Inventory" type="Node2D" parent="." node_paths=PackedStringArray("Hotbar")]
y_sort_enabled = true y_sort_enabled = true
script = ExtResource("30_y2wmw") script = ExtResource("30_y2wmw")
Hotbar = [NodePath("Sword"), NodePath("Bow"), NodePath("Pugio")] Hotbar = [null, null, null]
Items = Array[Object]([ExtResource("33_3qyfl"), ExtResource("34_70ron"), ExtResource("35_4pap1")])
InventoryMap = { InventoryMap = {
"equip_1": 0, "equip_1": 0,
"equip_2": 1, "equip_2": 1,
"equip_3": 2 "equip_3": 2
} }
[node name="Bow" parent="Inventory" node_paths=PackedStringArray("StateMachine") instance=ExtResource("31_mofvy")]
visible = false
StateMachine = NodePath("StateMachine")
[node name="Sword" parent="Inventory" node_paths=PackedStringArray("Hitbox", "AnimationPlayer", "ParryParticles", "StateMachine", "Anchor", "HandAnchor") instance=ExtResource("31_ql4as")]
visible = false
Hitbox = NodePath("Hitbox")
AnimationPlayer = NodePath("AnimationPlayer")
ParryParticles = NodePath("Anchor/Node2D/Sprite2D/ParryParticles")
StateMachine = NodePath("State")
Anchor = NodePath("Anchor")
HandAnchor = NodePath("Anchor/Node2D/Sprite2D/Hand")
[node name="Pugio" parent="Inventory" node_paths=PackedStringArray("Hitbox", "AnimationPlayer", "ParryParticles", "StateMachine", "Anchor", "HandAnchor") instance=ExtResource("32_6ffmm")]
visible = false
Hitbox = NodePath("Hitbox")
AnimationPlayer = NodePath("AnimationPlayer")
ParryParticles = NodePath("Anchor/Node2D/Sprite2D/ParryParticles")
StateMachine = NodePath("State")
Anchor = NodePath("Anchor")
HandAnchor = NodePath("Anchor/Node2D/Sprite2D/Hand")
[node name="Hurtbox" parent="." node_paths=PackedStringArray("InvincibilityTimer") instance=ExtResource("9_avyu4")] [node name="Hurtbox" parent="." node_paths=PackedStringArray("InvincibilityTimer") instance=ExtResource("9_avyu4")]
visible = false visible = false
InvincibilityTimer = NodePath("Timer") InvincibilityTimer = NodePath("Timer")

View File

@ -36,6 +36,9 @@ public partial class EventBus : Node
[Signal] [Signal]
public delegate void PlayerStunEventHandler(); public delegate void PlayerStunEventHandler();
[Signal]
public delegate void PlayerOpenInventoryEventHandler(Items.Inventory inventory);
[Signal] [Signal]
public delegate void RegisteredBossEventHandler(Characters.Boss boss); public delegate void RegisteredBossEventHandler(Characters.Boss boss);

View File

@ -69,6 +69,7 @@ public partial class Inventory : Node2D, IItemCollection<ItemMetadata>
// instantiating a new array will prevent characters from // instantiating a new array will prevent characters from
// sharing inventories // sharing inventories
Hotbar = new(); Hotbar = new();
Hotbar.Resize(HotbarCapacity);
} }
if (Items is null) if (Items is null)
@ -154,6 +155,35 @@ public partial class Inventory : Node2D, IItemCollection<ItemMetadata>
return item; return item;
} }
public Item SetHotbarIndexToItem(int index, ItemMetadata metadata)
{
var oldItem = Hotbar[index];
Item newItem = null;
if (IsInstanceValid(oldItem))
{
oldItem?.QueueFree();
}
if (metadata is not null)
{
newItem = metadata.Instance.Instantiate<Item>();
AddChild(newItem);
Hotbar[index] = newItem;
}
if (SelectedIndex == index)
{
// equip item if the hotbar index we are setting is selected
EquipIndex(index);
}
var bus = Events.EventBus.Instance;
bus.EmitSignal(Events.EventBus.SignalName.PlayerInventoryUpdate, this);
return newItem;
}
public Item AddItem(Item item) public Item AddItem(Item item)
{ {
if (Hotbar.Count >= HotbarCapacity) if (Hotbar.Count >= HotbarCapacity)

View File

@ -23,17 +23,14 @@ public abstract partial class PlayerState : CharacterState
{ {
if (@event.IsActionPressed("equip_1")) if (@event.IsActionPressed("equip_1"))
{ {
//inventory.SelectedItem = inventory.GetItemByMap("equip_1");
inventory.SelectedIndex = 0; inventory.SelectedIndex = 0;
} }
else if (@event.IsActionPressed("equip_2")) else if (@event.IsActionPressed("equip_2"))
{ {
//inventory.SelectedItem = inventory.GetItemByMap("equip_2");
inventory.SelectedIndex = 1; inventory.SelectedIndex = 1;
} }
else if (@event.IsActionPressed("equip_3")) else if (@event.IsActionPressed("equip_3"))
{ {
//inventory.SelectedItem = inventory.GetItemByMap("equip_3");
inventory.SelectedIndex = 2; inventory.SelectedIndex = 2;
} }
else if (@event.IsActionPressed("next_item")) else if (@event.IsActionPressed("next_item"))
@ -58,6 +55,13 @@ public abstract partial class PlayerState : CharacterState
return MaxLevelState; return MaxLevelState;
} }
} }
if (@event.IsActionPressed("inventory"))
{
var bus = Events.EventBus.Instance;
bus.EmitSignal(Events.EventBus.SignalName.PlayerOpenInventory,
player.Inventory);
}
} }
return base.UnhandledInput(@event); return base.UnhandledInput(@event);

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=14 format=3 uid="uid://c271rdjhd1gfo"] [gd_scene load_steps=15 format=3 uid="uid://c271rdjhd1gfo"]
[ext_resource type="Script" path="res://UI/UIController.cs" id="2_b4b6l"] [ext_resource type="Script" path="res://UI/UIController.cs" id="2_b4b6l"]
[ext_resource type="PackedScene" uid="uid://bxo553hblp6nf" path="res://UI/HealthBar.tscn" id="3_j1j6h"] [ext_resource type="PackedScene" uid="uid://bxo553hblp6nf" path="res://UI/HealthBar.tscn" id="3_j1j6h"]
@ -9,6 +9,7 @@
[ext_resource type="PackedScene" uid="uid://d3q1yu3n7cqfj" path="res://UI/SceneTransition.tscn" id="6_j0nhv"] [ext_resource type="PackedScene" uid="uid://d3q1yu3n7cqfj" path="res://UI/SceneTransition.tscn" id="6_j0nhv"]
[ext_resource type="PackedScene" uid="uid://cyggkyqosjk36" path="res://UI/Inventory/ShopMenu.tscn" id="8_ep3ae"] [ext_resource type="PackedScene" uid="uid://cyggkyqosjk36" path="res://UI/Inventory/ShopMenu.tscn" id="8_ep3ae"]
[ext_resource type="PackedScene" uid="uid://2afbrf8asy2a" path="res://UI/PostProcessing/Vignette.tscn" id="9_p1ubd"] [ext_resource type="PackedScene" uid="uid://2afbrf8asy2a" path="res://UI/PostProcessing/Vignette.tscn" id="9_p1ubd"]
[ext_resource type="PackedScene" uid="uid://bg51duwdtyl8w" path="res://UI/Inventory/InventoryMenu.tscn" id="10_5m8qa"]
[ext_resource type="PackedScene" uid="uid://b1wsryv4bn0cn" path="res://UI/PostProcessing/StunEffect.tscn" id="10_646ma"] [ext_resource type="PackedScene" uid="uid://b1wsryv4bn0cn" path="res://UI/PostProcessing/StunEffect.tscn" id="10_646ma"]
[ext_resource type="Shader" path="res://Shaders/Grayscale.gdshader" id="11_w4gn1"] [ext_resource type="Shader" path="res://Shaders/Grayscale.gdshader" id="11_w4gn1"]
[ext_resource type="Texture2D" uid="uid://bw052v8ikfget" path="res://icon.svg" id="12_tyv35"] [ext_resource type="Texture2D" uid="uid://bw052v8ikfget" path="res://icon.svg" id="12_tyv35"]
@ -22,11 +23,17 @@ process_mode = 3
[node name="PostProcessing" type="CanvasLayer" parent="."] [node name="PostProcessing" type="CanvasLayer" parent="."]
[node name="Vignette" parent="PostProcessing" instance=ExtResource("9_p1ubd")] [node name="CanvasLayer" type="CanvasLayer" parent="PostProcessing"]
[node name="StunEffect" parent="PostProcessing" instance=ExtResource("10_646ma")] [node name="Vignette" parent="PostProcessing/CanvasLayer" instance=ExtResource("9_p1ubd")]
[node name="Sprite2D" type="TextureRect" parent="PostProcessing"] [node name="CanvasLayer2" type="CanvasLayer" parent="PostProcessing"]
[node name="StunEffect" parent="PostProcessing/CanvasLayer2" instance=ExtResource("10_646ma")]
[node name="CanvasLayer3" type="CanvasLayer" parent="PostProcessing"]
[node name="Sprite2D" type="TextureRect" parent="PostProcessing/CanvasLayer3"]
visible = false visible = false
material = SubResource("ShaderMaterial_kbd61") material = SubResource("ShaderMaterial_kbd61")
anchors_preset = 3 anchors_preset = 3
@ -53,6 +60,7 @@ stretch_shrink = 3
disable_3d = true disable_3d = true
transparent_bg = true transparent_bg = true
handle_input_locally = false handle_input_locally = false
snap_2d_transforms_to_pixel = true
size = Vector2i(640, 360) size = Vector2i(640, 360)
render_target_update_mode = 4 render_target_update_mode = 4
@ -126,6 +134,12 @@ visible = false
layout_mode = 2 layout_mode = 2
_inventoryGrid = NodePath("PanelContainer/VBoxContainer/ScrollContainer/InventoryGrid") _inventoryGrid = NodePath("PanelContainer/VBoxContainer/ScrollContainer/InventoryGrid")
[node name="InventoryMenu" parent="SubViewportContainer/UIViewport/MainUILayer/Main/BoxContainer" node_paths=PackedStringArray("_inventoryGrid") instance=ExtResource("10_5m8qa")]
unique_name_in_owner = true
visible = false
layout_mode = 2
_inventoryGrid = NodePath("PanelContainer/VBoxContainer/ScrollContainer/InventoryGrid")
[node name="Bottom" type="HBoxContainer" parent="SubViewportContainer/UIViewport/MainUILayer/Main"] [node name="Bottom" type="HBoxContainer" parent="SubViewportContainer/UIViewport/MainUILayer/Main"]
layout_mode = 1 layout_mode = 1
anchors_preset = 12 anchors_preset = 12

View File

@ -0,0 +1,74 @@
using Godot;
namespace SupaLidlGame.UI.Inventory;
public abstract partial class BaseMenu : Control, IModal
{
[Export]
protected InventoryGrid _inventoryGrid;
protected Button _focusButtonOnSelect { get; set; }
protected InventorySlot _selected;
public abstract void ShowModal();
public abstract void HideModal();
public bool IsPlayingAnimation => GetNode<AnimationPlayer>("%AnimationPlayer").IsPlaying();
public async void Close()
{
var animPlayer = GetNode<AnimationPlayer>("%AnimationPlayer");
animPlayer.Play("close");
await ToSignal(animPlayer, AnimationPlayer.SignalName.AnimationFinished);
HideModal();
}
public override void _Ready()
{
var onSlotFocused = (InventorySlot slot) =>
{
if (slot.Item is not null)
{
SetTooltipItem(slot);
}
};
var onSlotUnfocused = (InventorySlot slot) =>
{
SetTooltipItem(_selected);
};
var onSlotSelected = (InventorySlot slot) =>
{
_selected = slot;
SetTooltipItem(slot);
//GetNode<ItemTooltip>("%ActionButton").GrabFocus();
_focusButtonOnSelect.GrabFocus();
};
_inventoryGrid.Connect(InventoryGrid.SignalName.SlotFocused,
Callable.From(onSlotFocused));
_inventoryGrid.Connect(InventoryGrid.SignalName.SlotUnfocused,
Callable.From(onSlotUnfocused));
_inventoryGrid.Connect(InventoryGrid.SignalName.SlotSelected,
Callable.From(onSlotSelected));
}
protected virtual void SetTooltipItem(InventorySlot slot)
{
GetNode<ItemTooltip>("%ItemTooltip").Item = slot?.Item;
}
public abstract void OnButtonPress(Button button);
public override void _UnhandledInput(InputEvent @event)
{
if (@event.IsActionPressed("ui_cancel"))
{
AcceptEvent();
Close();
}
}
}

View File

@ -0,0 +1,206 @@
[gd_scene load_steps=13 format=3 uid="uid://7blvai53i2a0"]
[ext_resource type="Shader" path="res://Shaders/WipeXY.gdshader" id="2_y0ues"]
[ext_resource type="StyleBox" path="res://UI/Themes/Panel.tres" id="3_6elnp"]
[ext_resource type="FontFile" uid="uid://cgwa8bjiyv534" path="res://Assets/Fonts/alagard.ttf" id="4_68gcu"]
[ext_resource type="PackedScene" uid="uid://chmokkxsy5vas" path="res://UI/Inventory/InventoryGrid.tscn" id="5_u7ajr"]
[ext_resource type="PackedScene" uid="uid://baawkwo8aiwbu" path="res://UI/Inventory/ShopSlot.tscn" id="6_onxvb"]
[ext_resource type="PackedScene" uid="uid://bsheehtfcdwhh" path="res://UI/Inventory/ItemTooltip.tscn" id="7_nphc3"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_gm1xk"]
bg_color = Color(0, 0, 0, 0.784314)
border_width_left = 16
border_width_top = 16
border_width_right = 16
border_width_bottom = 16
border_color = Color(0.145098, 0.145098, 0.145098, 0)
border_blend = true
corner_radius_top_left = 16
corner_radius_top_right = 16
corner_radius_bottom_right = 16
corner_radius_bottom_left = 16
[sub_resource type="ShaderMaterial" id="ShaderMaterial_2hdh3"]
shader = ExtResource("2_y0ues")
shader_parameter/x_amount = 1.0
shader_parameter/y_amount = 0.5
[sub_resource type="Animation" id="Animation_yj24f"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(1, 1, 1, 1)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("PanelContainer:material:shader_parameter/y_amount")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.5]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("PanelContainer:material:shader_parameter/x_amount")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [1.0]
}
[sub_resource type="Animation" id="Animation_tm2as"]
resource_name = "close"
length = 0.5
step = 0.05
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.4),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 0)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("PanelContainer:material:shader_parameter/y_amount")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.1),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [0.5, 1.0]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("PanelContainer:material:shader_parameter/x_amount")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0.05, 0.15),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [1.0, 0.5]
}
[sub_resource type="Animation" id="Animation_fgj27"]
resource_name = "open"
length = 0.5
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.3),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 1)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("PanelContainer:material:shader_parameter/y_amount")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.5),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [1.0, 0.5]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("PanelContainer:material:shader_parameter/x_amount")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.3),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [0.5, 1.0]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_0glcp"]
_data = {
"RESET": SubResource("Animation_yj24f"),
"close": SubResource("Animation_tm2as"),
"open": SubResource("Animation_fgj27")
}
[node name="Panel" type="PanelContainer"]
anchors_preset = 6
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_left = -236.0
offset_top = -175.5
offset_bottom = 175.5
grow_horizontal = 0
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_gm1xk")
[node name="PanelContainer" type="PanelContainer" parent="."]
material = SubResource("ShaderMaterial_2hdh3")
layout_mode = 2
theme_override_styles/panel = ExtResource("3_6elnp")
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer"]
layout_mode = 2
[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer/VBoxContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
theme_override_fonts/font = ExtResource("4_68gcu")
text = "Snus Dealer"
[node name="ScrollContainer" type="ScrollContainer" parent="PanelContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
follow_focus = true
horizontal_scroll_mode = 0
[node name="InventoryGrid" parent="PanelContainer/VBoxContainer/ScrollContainer" instance=ExtResource("5_u7ajr")]
layout_mode = 2
size_flags_vertical = 3
_slotScene = ExtResource("6_onxvb")
[node name="ItemTooltip" parent="PanelContainer/VBoxContainer" instance=ExtResource("7_nphc3")]
unique_name_in_owner = true
layout_mode = 2
[node name="HBoxContainer2" type="HBoxContainer" parent="PanelContainer/VBoxContainer"]
layout_mode = 2
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
unique_name_in_owner = true
libraries = {
"": SubResource("AnimationLibrary_0glcp")
}

View File

@ -1,10 +1,8 @@
[gd_scene load_steps=4 format=3 uid="uid://sfs8dpfitpdu"] [gd_scene load_steps=3 format=3 uid="uid://sfs8dpfitpdu"]
[ext_resource type="Script" path="res://UI/Inventory/Hotbar.cs" id="1_2sak2"] [ext_resource type="Script" path="res://UI/Inventory/Hotbar.cs" id="1_2sak2"]
[ext_resource type="PackedScene" uid="uid://dmvu2hjyrwc1y" path="res://UI/Inventory/HotbarSlot.tscn" id="2_3axfe"] [ext_resource type="PackedScene" uid="uid://dmvu2hjyrwc1y" path="res://UI/Inventory/HotbarSlot.tscn" id="2_3axfe"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_6jbma"]
[node name="Hotbar" type="GridContainer" node_paths=PackedStringArray("_slots")] [node name="Hotbar" type="GridContainer" node_paths=PackedStringArray("_slots")]
anchors_preset = 1 anchors_preset = 1
anchor_left = 1.0 anchor_left = 1.0
@ -19,12 +17,9 @@ _slots = [NodePath("InventorySlot"), NodePath("InventorySlot2"), NodePath("Inven
[node name="InventorySlot" parent="." instance=ExtResource("2_3axfe")] [node name="InventorySlot" parent="." instance=ExtResource("2_3axfe")]
layout_mode = 2 layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxEmpty_6jbma")
[node name="InventorySlot2" parent="." instance=ExtResource("2_3axfe")] [node name="InventorySlot2" parent="." instance=ExtResource("2_3axfe")]
layout_mode = 2 layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxEmpty_6jbma")
[node name="InventorySlot3" parent="." instance=ExtResource("2_3axfe")] [node name="InventorySlot3" parent="." instance=ExtResource("2_3axfe")]
layout_mode = 2 layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxEmpty_6jbma")

View File

@ -6,14 +6,14 @@ namespace SupaLidlGame.UI.Inventory;
public partial class InventoryGrid : GridContainer public partial class InventoryGrid : GridContainer
{ {
private SupaLidlGame.Items.IItemCollection _source; private Items.IItemCollection _source;
[Export] [Export]
private PackedScene _slotScene; private PackedScene _slotScene;
public ButtonGroup ButtonGroup { get; private set; } public ButtonGroup ButtonGroup { get; private set; }
public SupaLidlGame.Items.IItemCollection Source public Items.IItemCollection Source
{ {
get => _source; get => _source;
set set

View File

@ -0,0 +1,81 @@
using Godot;
using System.Collections.Generic;
namespace SupaLidlGame.UI.Inventory;
public partial class InventoryMenu : BaseMenu, IModal
{
private Items.Inventory _source;
public Items.Inventory Source
{
get => _source;
set
{
_source = value;
_inventoryGrid.Source = value;
}
}
public override void ShowModal()
{
Show();
var animPlayer = GetNode<AnimationPlayer>("%AnimationPlayer");
animPlayer.Play("open");
}
public override void HideModal()
{
Hide();
_source = null;
}
public override void _Ready()
{
base._Ready();
_focusButtonOnSelect = GetNode<Button>("%SlotButton1");
foreach (Node node in GetTree().GetNodesInGroup("SlotButtons"))
{
var button = node as Button;
var onButtonPress = () =>
{
OnButtonPress(button);
};
var onButtonInput = (InputEvent @event) =>
{
if (@event.IsActionPressed("ui_cancel"))
{
GetViewport().SetInputAsHandled();
_selected?.GrabFocus();
}
};
button.Connect(Button.SignalName.Pressed, Callable.From(onButtonPress));
}
}
protected override void SetTooltipItem(InventorySlot slot)
{
base.SetTooltipItem(slot);
if (slot == _selected)
{
GetTree().SetGroup("SlotButtons", "disabled", false);
}
else
{
GetTree().SetGroup("SlotButtons", "disabled", true);
}
}
public override void OnButtonPress(Button button)
{
int slot = button.GetMeta("slot").AsInt32();
GD.Print("Equipping item at slot " + slot);
Source.SetHotbarIndexToItem(slot, _selected.Item);
}
}

View File

@ -0,0 +1,38 @@
[gd_scene load_steps=4 format=3 uid="uid://bg51duwdtyl8w"]
[ext_resource type="PackedScene" uid="uid://7blvai53i2a0" path="res://UI/Inventory/BaseMenu.tscn" id="1_55ohh"]
[ext_resource type="Script" path="res://UI/Inventory/InventoryMenu.cs" id="2_25pbk"]
[ext_resource type="Theme" uid="uid://cksjbu3vrup5" path="res://UI/Themes/supalidl.tres" id="2_jvsju"]
[node name="Panel" node_paths=PackedStringArray("_inventoryGrid") instance=ExtResource("1_55ohh")]
script = ExtResource("2_25pbk")
_inventoryGrid = NodePath("PanelContainer/VBoxContainer/ScrollContainer/InventoryGrid")
[node name="HBoxContainer" parent="PanelContainer/VBoxContainer" index="0"]
visible = false
[node name="SlotButton1" type="Button" parent="PanelContainer/VBoxContainer/HBoxContainer2" index="0" groups=["SlotButtons"]]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme = ExtResource("2_jvsju")
text = "Slot 1"
metadata/slot = 0
[node name="SlotButton2" type="Button" parent="PanelContainer/VBoxContainer/HBoxContainer2" index="1" groups=["SlotButtons"]]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme = ExtResource("2_jvsju")
text = "Slot 2
"
metadata/slot = 1
[node name="SlotButton3" type="Button" parent="PanelContainer/VBoxContainer/HBoxContainer2" index="2" groups=["SlotButtons"]]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme = ExtResource("2_jvsju")
text = "Slot 3
"
metadata/slot = 2

View File

@ -5,6 +5,9 @@ namespace SupaLidlGame.UI.Inventory;
public partial class ItemTooltip : Control public partial class ItemTooltip : Control
{ {
[Export]
public Button ActionButton { get; set; }
private ItemMetadata _item; private ItemMetadata _item;
public ItemMetadata Item public ItemMetadata Item

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
namespace SupaLidlGame.UI.Inventory; namespace SupaLidlGame.UI.Inventory;
public partial class ShopMenu : Control, IModal public partial class ShopMenu : BaseMenu, IModal
{ {
private Items.IItemCollection<Items.ShopEntry> _source; private Items.IItemCollection<Items.ShopEntry> _source;
@ -17,53 +17,24 @@ public partial class ShopMenu : Control, IModal
} }
} }
[Export] public override void ShowModal()
private InventoryGrid _inventoryGrid;
private InventorySlot _selected;
public void ShowModal()
{ {
Show(); Show();
var animPlayer = GetNode<AnimationPlayer>("%AnimationPlayer"); var animPlayer = GetNode<AnimationPlayer>("%AnimationPlayer");
animPlayer.Play("open"); animPlayer.Play("open");
} }
public void HideModal() public override void HideModal()
{ {
Hide(); Hide();
_source = null; _source = null;
} }
public async void Close()
{
var animPlayer = GetNode<AnimationPlayer>("%AnimationPlayer");
animPlayer.Play("close");
await ToSignal(animPlayer, AnimationPlayer.SignalName.AnimationFinished);
HideModal();
}
public override void _Ready() public override void _Ready()
{ {
_inventoryGrid.SlotFocused += (InventorySlot slot) => base._Ready();
{
if (slot.Item is not null)
{
SetTooltipItem(slot);
}
};
_inventoryGrid.SlotUnfocused += (InventorySlot slot) => _focusButtonOnSelect = GetNode<Button>("%BuyButton");
{
SetTooltipItem(_selected);
};
_inventoryGrid.SlotSelected += (InventorySlot slot) =>
{
_selected = slot;
SetTooltipItem(slot);
GetNode<Button>("%BuyButton").GrabFocus();
};
GetNode<Button>("%BuyButton").GuiInput += (InputEvent @event) => GetNode<Button>("%BuyButton").GuiInput += (InputEvent @event) =>
{ {
@ -75,9 +46,9 @@ public partial class ShopMenu : Control, IModal
}; };
} }
private void SetTooltipItem(InventorySlot slot) protected override void SetTooltipItem(InventorySlot slot)
{ {
GetNode<ItemTooltip>("%ItemTooltip").Item = slot?.Item; base.SetTooltipItem(slot);
if (slot == _selected) if (slot == _selected)
{ {
@ -89,6 +60,11 @@ public partial class ShopMenu : Control, IModal
} }
} }
public override void OnButtonPress(Button button)
{
throw new System.NotImplementedException("Not yet implemented.");
}
public override void _UnhandledInput(InputEvent @event) public override void _UnhandledInput(InputEvent @event)
{ {
if (@event.IsActionPressed("ui_cancel")) if (@event.IsActionPressed("ui_cancel"))

View File

@ -22,5 +22,23 @@ public partial class UIController : Control
shopMenu.Source = shop; shopMenu.Source = shop;
shopMenu.ShowModal(); shopMenu.ShowModal();
}; };
Events.EventBus.Instance.PlayerOpenInventory += (Items.Inventory inventory) =>
{
var inventoryMenu = GetNode<Inventory.InventoryMenu>("%InventoryMenu");
if (!inventoryMenu.IsPlayingAnimation)
{
inventoryMenu.Source = inventory;
if (inventoryMenu.Visible)
{
inventoryMenu.Close();
}
else
{
inventoryMenu.ShowModal();
}
}
};
} }
} }