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

@@ -25,7 +25,7 @@ namespace Zennysoft.Ma.Adapter
int incomingDamage, int incomingDamage,
double elementalResistance) double elementalResistance)
{ {
var result = incomingDamage - (int)(incomingDamage * elementalResistance); var result = incomingDamage - (int)(incomingDamage * (elementalResistance / 100));
return result; return result;
} }
} }

View File

@@ -12,6 +12,8 @@ public interface IExperiencePointsComponent : IEntityComponent
public IAutoProp<int> Level { get; } public IAutoProp<int> Level { get; }
public void ModifyExpGainRate(double newRate);
public void Gain(int baseExpGain); public void Gain(int baseExpGain);
public void LevelUp(); public void LevelUp();

View File

@@ -0,0 +1,9 @@
public class Augment
{
public JewelTags AugmentTag;
public Augment(JewelTags tag)
{
AugmentTag = tag;
}
}

View File

@@ -1,5 +1,4 @@
using Chickensoft.Collections; using Chickensoft.Introspection;
using Chickensoft.Introspection;
using Chickensoft.Serialization; using Chickensoft.Serialization;
using Zennysoft.Ma.Adapter.Entity; using Zennysoft.Ma.Adapter.Entity;
@@ -22,6 +21,8 @@ public abstract partial class EquipableItem : InventoryItem
[Save("equipment_is_glued")] [Save("equipment_is_glued")]
public bool Glued { get; set; } public bool Glued { get; set; }
public virtual Augment? Augment { get; set; }
[Save("bonus_elemental_resist_stats")] [Save("bonus_elemental_resist_stats")]
public virtual ElementalResistanceSet ElementalResistance { get; } = new ElementalResistanceSet(0, 0, 0, 0, 0, 0, 0); public virtual ElementalResistanceSet ElementalResistance { get; } = new ElementalResistanceSet(0, 0, 0, 0, 0, 0, 0);
} }

View File

@@ -110,14 +110,14 @@ public class GameRepo : IGameRepo
{ {
AnnounceMessageInInventory("Experience points temporarily doubled."); AnnounceMessageInInventory("Experience points temporarily doubled.");
DoubleExpTimeStart?.Invoke(lengthOfEffect.Seconds); DoubleExpTimeStart?.Invoke(lengthOfEffect.Seconds);
ExpRate = 2; ExpRate *= 2;
} }
public void EndDoubleExp() public void EndDoubleExp()
{ {
AnnounceMessageOnMainScreen("Experience points effect wore off."); AnnounceMessageOnMainScreen("Experience points effect wore off.");
DoubleExpTimeEnd?.Invoke(); DoubleExpTimeEnd?.Invoke();
ExpRate = 1; ExpRate /= 2;
} }
public void AnnounceMessageOnMainScreen(string message) public void AnnounceMessageOnMainScreen(string message)

View File

@@ -8,13 +8,20 @@ public partial class GameState
public partial record State public partial record State
{ {
[Meta, LogicBlock(typeof(State), Diagram = true)] [Meta, LogicBlock(typeof(State), Diagram = true)]
public partial record GameOver : State, IGet<Input.NewGame> public partial record GameOver : InGame, IGet<Input.NewGame>, IGet<Input.ExitGame>
{ {
public Transition On(in Input.NewGame input) public Transition On(in Input.NewGame input)
{ {
Output(new Output.InitializeGame()); Output(new Output.InitializeGame());
return To<InGame>(); return To<InGame>();
} }
public Transition On(in Input.ExitGame input)
{
Output(new Output.ClosePauseScreen());
Output(new Output.ExitGame());
return To<State>();
}
} }
} }
} }

View File

@@ -0,0 +1,7 @@
namespace Zennysoft.Ma.Adapter
{
public interface IAugmentItem
{
public JewelTags Augment { get; }
}
}

View File

@@ -14,6 +14,8 @@ public interface IInventory
public bool Sort(EquipableItem currentWeapon, EquipableItem currentArmor, EquipableItem currentAccessory, EquipableItem ammo); public bool Sort(EquipableItem currentWeapon, EquipableItem currentArmor, EquipableItem currentAccessory, EquipableItem ammo);
public bool AtCapacity();
public event Action<string> BroadcastMessage; public event Action<string> BroadcastMessage;
public event Action InventoryChanged; public event Action InventoryChanged;
} }

View File

@@ -26,6 +26,8 @@ public interface IPlayer : IKillable, ICharacterBody3D
public void PlayJumpScareAnimation(); public void PlayJumpScareAnimation();
//public void AugmentItem(IAugmentItem jewel, EquipableItem equipableItem);
public IInventory Inventory { get; } public IInventory Inventory { get; }
public IHealthComponent HealthComponent { get; } public IHealthComponent HealthComponent { get; }

View File

@@ -51,6 +51,7 @@ public class ExperiencePointsComponent : IExperiencePointsComponent
var cappedAmount = Math.Min(baseExpGain + _currentExp.Value, _expToNextLevel.Value); var cappedAmount = Math.Min(baseExpGain + _currentExp.Value, _expToNextLevel.Value);
_currentExp.OnNext(cappedAmount); _currentExp.OnNext(cappedAmount);
} }
public void ModifyExpGainRate(double newRate) => _expGainRate.OnNext(newRate);
public void LevelUp() public void LevelUp()
{ {

View File

@@ -69,6 +69,8 @@ public partial class Game : Node3D, IGame
public QuestData QuestData { get; private set; } public QuestData QuestData { get; private set; }
public ItemRescueMenu ItemRescueMenu { get => InGameUI.ItemRescueMenu; }
private EffectService _effectService; private EffectService _effectService;
private IInstantiator _instantiator; private IInstantiator _instantiator;

View File

@@ -32,6 +32,8 @@ public interface IGame : IProvide<IGame>, IProvide<IGameRepo>, IProvide<IPlayer>
public Task Save(); public Task Save();
public ItemRescueMenu ItemRescueMenu { get; }
public QuestData QuestData { get; } public QuestData QuestData { get; }
public event Action GameExitRequested; public event Action GameExitRequested;

View File

@@ -54,6 +54,8 @@ public partial class Inventory : Node, IInventory
return true; return true;
} }
public bool AtCapacity() => Items.Count >= _maxInventorySize;
public bool TryInsert(InventoryItem inventoryItem, int index) public bool TryInsert(InventoryItem inventoryItem, int index)
{ {
if (Items.Count >= _maxInventorySize || index >= _maxInventorySize || index < 0) if (Items.Count >= _maxInventorySize || index >= _maxInventorySize || index < 0)

View File

@@ -49,8 +49,8 @@ public partial class DroppedItem : RigidBody3D, IDroppedItem
public void RescueItem() public void RescueItem()
{ {
ContactMonitor = false; ContactMonitor = false;
Pickup.Monitorable = false; Pickup.SetDeferred(Area3D.PropertyName.Monitorable, false);
Pickup.Monitoring = false; Pickup.SetDeferred(Area3D.PropertyName.Monitoring, false);
SfxDatabase.Instance.Play(SoundEffect.Transfer); SfxDatabase.Instance.Play(SoundEffect.Transfer);
PlayRescueAnimation(); PlayRescueAnimation();
Game.RescuedItems.Items.Add(Item); Game.RescuedItems.Items.Add(Item);

View File

@@ -0,0 +1 @@
uid://xlqkn5j388il

View File

@@ -6,7 +6,7 @@ using Zennysoft.Game.Ma;
using Zennysoft.Ma.Adapter; using Zennysoft.Ma.Adapter;
[Meta(typeof(IAutoNode)), Id("jewel")] [Meta(typeof(IAutoNode)), Id("jewel")]
public partial class Jewel : InventoryItem public partial class Jewel : InventoryItem, IAugmentItem
{ {
public override void _Notification(int what) => this.Notify(what); public override void _Notification(int what) => this.Notify(what);
@@ -34,4 +34,42 @@ public partial class Jewel : InventoryItem
[Export] [Export]
[Save("jewel_stats")] [Save("jewel_stats")]
public JewelStats Stats { get; set; } = new JewelStats(); public JewelStats Stats { get; set; } = new JewelStats();
public JewelTags Augment => Stats.JewelTag;
public void ApplyAugment(Weapon weapon)
{
weapon.Augment = new Augment(Stats.JewelTag);
switch (Stats.JewelTag)
{
case JewelTags.AeolicElement:
weapon.Stats.WeaponElement = ElementType.Aeolic;
break;
}
}
public void ApplyAugment(Armor armor)
{
armor.Augment = new Augment(Stats.JewelTag);
switch (Stats.JewelTag)
{
case JewelTags.AeolicElement:
armor.Stats.AeolicResistance += 25;
break;
case JewelTags.HydricElement:
armor.Stats.HydricResistance += 25;
break;
case JewelTags.IgneousElement:
armor.Stats.IgneousResistance += 25;
break;
case JewelTags.TelluricElement:
armor.Stats.TelluricResistance += 25;
break;
}
}
public void ApplyAugment(Accessory accessory)
{
accessory.Augment = new Augment(Stats.JewelTag);
}
} }

View File

@@ -5,8 +5,9 @@
[resource] [resource]
script = ExtResource("1_cyti8") script = ExtResource("1_cyti8")
JewelTag = 7
Name = "Hydric Jewel" Name = "Hydric Jewel"
Description = "Hydric e" Description = "Add Hydric damage to Weapon or Hydric resistance to Armor."
SpawnRate = 0.5 SpawnRate = 0.5
BonusAttack = 0 BonusAttack = 0
BonusDefense = 0 BonusDefense = 0

View File

@@ -5,6 +5,7 @@
[resource] [resource]
script = ExtResource("1_6e2y5") script = ExtResource("1_6e2y5")
JewelTag = 9
Name = "Meditative Stone" Name = "Meditative Stone"
Description = "" Description = ""
SpawnRate = 0.5 SpawnRate = 0.5

View File

@@ -15,8 +15,12 @@ public partial class Overworld : SpecialFloor, IDungeonFloor
[Dependency] protected IPlayer Player => this.DependOn<IPlayer>(); [Dependency] protected IPlayer Player => this.DependOn<IPlayer>();
[Dependency] protected IGameRepo GameRepo => this.DependOn<IGameRepo>();
[Node] public Marker3D PlayerSpawnPoint { get; set; } = default!; [Node] public Marker3D PlayerSpawnPoint { get; set; } = default!;
[Node] public Area3D ItemRescueInteractZone { get; set; } = default!;
[Node] private Area3D Exit { get; set; } = default!; [Node] private Area3D Exit { get; set; } = default!;
[Node] private Area3D RestoreArea { get; set; } = default!; [Node] private Area3D RestoreArea { get; set; } = default!;
@@ -25,6 +29,8 @@ public partial class Overworld : SpecialFloor, IDungeonFloor
private Timer RestoreTimer { get; set; } private Timer RestoreTimer { get; set; }
private bool _insideItemRescueZone = false;
public override void InitializeDungeon() public override void InitializeDungeon()
{ {
Show(); Show();
@@ -37,11 +43,28 @@ public partial class Overworld : SpecialFloor, IDungeonFloor
AddChild(RestoreTimer); AddChild(RestoreTimer);
FloorIsLoaded = true; FloorIsLoaded = true;
ItemRescueInteractZone.AreaEntered += ItemRescueInteractZone_AreaEntered;
var dimmableAudio = DimmableAudio.GetChildren().OfType<IDimmableAudioStreamPlayer>(); var dimmableAudio = DimmableAudio.GetChildren().OfType<IDimmableAudioStreamPlayer>();
foreach (var dimmable in dimmableAudio) foreach (var dimmable in dimmableAudio)
dimmable.FadeIn(); dimmable.FadeIn();
} }
public void OnResolved()
{
Game.ItemRescueMenu.MenuClosing += ItemRescueMenu_MenuClosing;
}
private void ItemRescueMenu_MenuClosing()
{
GameRepo.Resume();
}
private void ItemRescueInteractZone_AreaEntered(Area3D area)
{
GameRepo.Pause();
Game.ItemRescueMenu.Show();
}
public override void FadeOutAudio() public override void FadeOutAudio()
{ {
var dimmableAudio = DimmableAudio.GetChildren().OfType<IDimmableAudioStreamPlayer>(); var dimmableAudio = DimmableAudio.GetChildren().OfType<IDimmableAudioStreamPlayer>();

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=558 format=4 uid="uid://dvnc26rebk6o0"] [gd_scene load_steps=559 format=4 uid="uid://dvnc26rebk6o0"]
[ext_resource type="Script" uid="uid://cuhfkyh3d7noa" path="res://src/map/dungeon/code/Overworld.cs" id="1_5hmt3"] [ext_resource type="Script" uid="uid://cuhfkyh3d7noa" path="res://src/map/dungeon/code/Overworld.cs" id="1_5hmt3"]
[ext_resource type="Texture2D" uid="uid://co6h8vyi11sl2" path="res://src/map/overworld/Models/Overworld_CLOUD_RINGS_INNER_63.png" id="2_g6b7b"] [ext_resource type="Texture2D" uid="uid://co6h8vyi11sl2" path="res://src/map/overworld/Models/Overworld_CLOUD_RINGS_INNER_63.png" id="2_g6b7b"]
@@ -10255,6 +10255,9 @@ shadow_mesh = SubResource("ArrayMesh_1annr")
[sub_resource type="BoxShape3D" id="BoxShape3D_q7hpd"] [sub_resource type="BoxShape3D" id="BoxShape3D_q7hpd"]
size = Vector3(2.49086, 4.52832, 1) size = Vector3(2.49086, 4.52832, 1)
[sub_resource type="BoxShape3D" id="BoxShape3D_5fm5y"]
size = Vector3(5.40659, 4.93652, 3.9856)
[node name="Overworld" type="Node3D"] [node name="Overworld" type="Node3D"]
script = ExtResource("1_5hmt3") script = ExtResource("1_5hmt3")
@@ -11204,6 +11207,15 @@ skeleton = NodePath("")
transform = Transform3D(0.943674, 0, -0.330877, 0, 1, 0, 0.330877, 0, 0.943674, -0.0489807, -0.637752, -0.318357) transform = Transform3D(0.943674, 0, -0.330877, 0, 1, 0, 0.330877, 0, 0.943674, -0.0489807, -0.637752, -0.318357)
shape = SubResource("BoxShape3D_q7hpd") shape = SubResource("BoxShape3D_q7hpd")
[node name="ItemRescueInteractZone" type="Area3D" parent="."]
unique_name_in_owner = true
collision_layer = 256
collision_mask = 256
[node name="CollisionShape3D" type="CollisionShape3D" parent="ItemRescueInteractZone"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -280.996, 2.8715, 88.7621)
shape = SubResource("BoxShape3D_5fm5y")
[editable path="Node3D/Actors/Rat"] [editable path="Node3D/Actors/Rat"]
[editable path="Node3D/Actors/Clalo"] [editable path="Node3D/Actors/Clalo"]
[editable path="Node3D/Actors/Caretaker of Saints"] [editable path="Node3D/Actors/Caretaker of Saints"]

View File

@@ -158,9 +158,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
{ {
PlayerFXAnimations.Play("RESET"); PlayerFXAnimations.Play("RESET");
foreach (var item in Inventory.Items) Inventory.Items.Clear();
Inventory.Remove(item);
HealthComponent.Reset(); HealthComponent.Reset();
VTComponent.Reset(); VTComponent.Reset();
AttackComponent.Reset(); AttackComponent.Reset();
@@ -281,6 +279,8 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
HealthComponent.RaiseMaximumHP(equipable.BonusHP, false); HealthComponent.RaiseMaximumHP(equipable.BonusHP, false);
VTComponent.RaiseMaximumVT(equipable.BonusVT, false); VTComponent.RaiseMaximumVT(equipable.BonusVT, false);
//if (equipable.Augment != null)
// Augment(equipable.Augment, equipable);
EquipmentComponent.Equip(equipable); EquipmentComponent.Equip(equipable);
SfxDatabase.Instance.Play(SoundEffect.Equip); SfxDatabase.Instance.Play(SoundEffect.Equip);
@@ -293,6 +293,9 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
HealthComponent.SetMaximumHealth(HealthComponent.MaximumHP.Value - equipable.BonusHP); HealthComponent.SetMaximumHealth(HealthComponent.MaximumHP.Value - equipable.BonusHP);
VTComponent.SetMaximumVT(VTComponent.MaximumVT.Value - equipable.BonusVT); VTComponent.SetMaximumVT(VTComponent.MaximumVT.Value - equipable.BonusVT);
//if (equipable.Augment != null)
// Deaugment(equipable.Augment);
EquipmentComponent.Unequip(equipable); EquipmentComponent.Unequip(equipable);
SfxDatabase.Instance.Play(SoundEffect.Unequip); SfxDatabase.Instance.Play(SoundEffect.Unequip);
@@ -300,6 +303,39 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
PersuaderCrosshair.Hide(); PersuaderCrosshair.Hide();
} }
//public void ApplyNewAugment(Jewel jewel, EquipableItem equipableItem)
//{
// _player.Inventory.Remove(jewel);
// jewel.ApplyAugment((dynamic)equipableItem);
// if (!_player.EquipmentComponent.IsItemEquipped(equipableItem))
// return;
// if (jewel.Stats.JewelTag == JewelTags.IncreaseEXPGain)
// _player.ExperiencePointsComponent.ModifyExpGainRate(_player.ExperiencePointsComponent.ExpGainRate.Value + 0.25f);
//}
private void Augment(IAugmentItem augment, EquipableItem equipable)
{
var jewel = augment as Jewel;
switch (augment.Augment)
{
case JewelTags.IncreaseEXPGain:
ExperiencePointsComponent.ModifyExpGainRate(ExperiencePointsComponent.ExpGainRate.Value + 0.25f);
break;
}
}
private void Deaugment(Augment augment)
{
switch (augment.AugmentTag)
{
case JewelTags.IncreaseEXPGain:
ExperiencePointsComponent.ModifyExpGainRate(ExperiencePointsComponent.ExpGainRate.Value - 0.25f);
break;
}
}
private static Vector3 GlobalInputVector private static Vector3 GlobalInputVector
{ {
get get
@@ -440,7 +476,6 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
PlayerBinding.Dispose(); PlayerBinding.Dispose();
Hitbox.AreaEntered -= Hitbox_AreaEntered; Hitbox.AreaEntered -= Hitbox_AreaEntered;
CollisionDetector.AreaEntered -= CollisionDetector_AreaEntered; CollisionDetector.AreaEntered -= CollisionDetector_AreaEntered;
HealthComponent.HealthReachedZero -= Die;
HealthTimer.Timeout -= OnHealthTimerTimeout; HealthTimer.Timeout -= OnHealthTimerTimeout;
HealthComponent.CurrentHP.Changed -= InverseHPToAttackPowerSync; HealthComponent.CurrentHP.Changed -= InverseHPToAttackPowerSync;
HealthComponent.HealthReachedZero -= Die; HealthComponent.HealthReachedZero -= Die;

View File

@@ -18,6 +18,8 @@ public partial class InGameUI : Control, IInGameUI
[Node] public IInventoryMenu InventoryMenu { get; set; } = default!; [Node] public IInventoryMenu InventoryMenu { get; set; } = default!;
[Node] public ItemRescueMenu ItemRescueMenu { get; set; } = default!;
[Node] public IPlayerInfoUI PlayerInfoUI { get; set; } = default!; [Node] public IPlayerInfoUI PlayerInfoUI { get; set; } = default!;
[Node] public InventoryMessageUI InventoryMessageUI { get; set; } = default!; [Node] public InventoryMessageUI InventoryMessageUI { get; set; } = default!;

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=11 format=3 uid="uid://b1muxus5qdbeu"] [gd_scene load_steps=12 format=3 uid="uid://b1muxus5qdbeu"]
[ext_resource type="Script" uid="uid://dlq2mkhl4pe7a" path="res://src/ui/in_game_ui/InGameUI.cs" id="1_sc13i"] [ext_resource type="Script" uid="uid://dlq2mkhl4pe7a" path="res://src/ui/in_game_ui/InGameUI.cs" id="1_sc13i"]
[ext_resource type="PackedScene" uid="uid://bwbofurcvf3yh" path="res://src/minimap/Minimap.tscn" id="2_6sfje"] [ext_resource type="PackedScene" uid="uid://bwbofurcvf3yh" path="res://src/minimap/Minimap.tscn" id="2_6sfje"]
@@ -9,6 +9,7 @@
[ext_resource type="PackedScene" uid="uid://8f3dk16nj0dn" path="res://src/menu/DebugMenu.tscn" id="7_llomk"] [ext_resource type="PackedScene" uid="uid://8f3dk16nj0dn" path="res://src/menu/DebugMenu.tscn" id="7_llomk"]
[ext_resource type="Texture2D" uid="uid://bj4p4qxb1mj3q" path="res://src/ui/player_ui/Assets/panel rough draft.png" id="7_ur8ag"] [ext_resource type="Texture2D" uid="uid://bj4p4qxb1mj3q" path="res://src/ui/player_ui/Assets/panel rough draft.png" id="7_ur8ag"]
[ext_resource type="PackedScene" uid="uid://c3e6hbctay1us" path="res://src/ui/inventory_menu/InventoryMenu2.tscn" id="9_ur8ag"] [ext_resource type="PackedScene" uid="uid://c3e6hbctay1us" path="res://src/ui/inventory_menu/InventoryMenu2.tscn" id="9_ur8ag"]
[ext_resource type="PackedScene" uid="uid://dwa7o6hkkwjg1" path="res://src/ui/inventory_menu/ItemRescueMenu.tscn" id="10_higkc"]
[sub_resource type="StyleBoxLine" id="StyleBoxLine_ur8ag"] [sub_resource type="StyleBoxLine" id="StyleBoxLine_ur8ag"]
color = Color(0.792157, 0.698039, 0.643137, 1) color = Color(0.792157, 0.698039, 0.643137, 1)
@@ -147,3 +148,8 @@ size_flags_vertical = 3
[node name="InventoryMenu" parent="." instance=ExtResource("9_ur8ag")] [node name="InventoryMenu" parent="." instance=ExtResource("9_ur8ag")]
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 1 layout_mode = 1
[node name="ItemRescueMenu" parent="." instance=ExtResource("10_higkc")]
unique_name_in_owner = true
visible = false
layout_mode = 1

View File

@@ -1,333 +0,0 @@
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 ((!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
}
}

View File

@@ -1 +0,0 @@
uid://bi1xopts68paw

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="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://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"] [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="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"] [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"] [sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_unikd"]
blend_mode = 4 blend_mode = 4
@@ -47,7 +385,7 @@ grow_vertical = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
mouse_filter = 2 mouse_filter = 2
script = ExtResource("1_b6rkr") script = SubResource("CSharpScript_xwkpe")
[node name="BG" type="ColorRect" parent="."] [node name="BG" type="ColorRect" parent="."]
material = SubResource("CanvasItemMaterial_unikd") material = SubResource("CanvasItemMaterial_unikd")

View File

@@ -38,6 +38,10 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
private IItemSlot _currentlySelected; private IItemSlot _currentlySelected;
private bool _augmentMode = false;
private Jewel _augmentingJewel;
#region ItemSlots #region ItemSlots
[Node] public IItemSlot ItemSlot01 { get; set; } [Node] public IItemSlot ItemSlot01 { get; set; }
[Node] public IItemSlot ItemSlot02 { get; set; } [Node] public IItemSlot ItemSlot02 { get; set; }
@@ -91,7 +95,7 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
slot.ItemSelected += Slot_FocusEntered; slot.ItemSelected += Slot_FocusEntered;
slot.ItemPressed += Slot_ItemPressed; slot.ItemPressed += Slot_ItemPressed;
} }
VisibilityChanged += InventoryMenu_VisibilityChanged; VisibilityChanged += ResetInventoryState;
InteractButton.Pressed += InteractButton_Pressed; InteractButton.Pressed += InteractButton_Pressed;
ThrowButton.Pressed += ThrowButton_Pressed; ThrowButton.Pressed += ThrowButton_Pressed;
DropButton.Pressed += DropButton_Pressed; DropButton.Pressed += DropButton_Pressed;
@@ -103,7 +107,12 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
if (_currentlySelected != null) if (_currentlySelected != null)
{ {
var item = _currentlySelected.Item.Value; var item = _currentlySelected.Item.Value;
if (item is EquipableItem equipable) if (_augmentMode)
{
//_player.AugmentItem(_augmentingJewel, item as EquipableItem);
ResetInventoryState();
}
else if (item is EquipableItem equipable)
{ {
if (_player.EquipmentComponent.IsItemEquipped(equipable)) if (_player.EquipmentComponent.IsItemEquipped(equipable))
_player.Unequip(equipable); _player.Unequip(equipable);
@@ -116,6 +125,11 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
} }
else if (item is Plastique plastique) else if (item is Plastique plastique)
_game.SetItem(plastique); _game.SetItem(plastique);
else if (item is Jewel jewel)
{
_augmentMode = true;
AugmentMode(jewel);
}
else else
_game.UseItem(_currentlySelected.Item.Value); _game.UseItem(_currentlySelected.Item.Value);
@@ -148,6 +162,7 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
if (ActionPanel.Visible && Input.IsActionJustPressed(GameInputs.Interact)) if (ActionPanel.Visible && Input.IsActionJustPressed(GameInputs.Interact))
{ {
CloseActionMenu(); CloseActionMenu();
_augmentMode = false;
SfxDatabase.Instance.Play(SoundEffect.CancelUI); SfxDatabase.Instance.Play(SoundEffect.CancelUI);
GetViewport().SetInputAsHandled(); GetViewport().SetInputAsHandled();
} }
@@ -175,7 +190,7 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
{ {
_player.Inventory.Sort(_player.EquipmentComponent.EquippedWeapon.Value, _player.EquipmentComponent.EquippedArmor.Value, _player.EquipmentComponent.EquippedAccessory.Value, _player.EquipmentComponent.EquippedAmmo.Value); _player.Inventory.Sort(_player.EquipmentComponent.EquippedWeapon.Value, _player.EquipmentComponent.EquippedArmor.Value, _player.EquipmentComponent.EquippedAccessory.Value, _player.EquipmentComponent.EquippedAmmo.Value);
SfxDatabase.Instance.Play(SoundEffect.SortInventory); SfxDatabase.Instance.Play(SoundEffect.SortInventory);
InventoryMenu_VisibilityChanged(); ResetInventoryState();
} }
} }
@@ -190,7 +205,14 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
ThrowButton.FocusMode = FocusModeEnum.All; ThrowButton.FocusMode = FocusModeEnum.All;
DropButton.FocusMode = FocusModeEnum.All; DropButton.FocusMode = FocusModeEnum.All;
if (item is EquipableItem equipable) if (_augmentMode)
{
InteractButton.Text = "Augment";
ThrowButton.Disabled = true;
DropButton.Disabled = true;
InteractButton.GrabFocus();
}
else if (item is EquipableItem equipable)
{ {
var itemIsEquipped = _player.EquipmentComponent.IsItemEquipped(equipable); var itemIsEquipped = _player.EquipmentComponent.IsItemEquipped(equipable);
InteractButton.Text = itemIsEquipped ? "Unequip" : "Equip"; InteractButton.Text = itemIsEquipped ? "Unequip" : "Equip";
@@ -212,6 +234,11 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
InteractButton.FocusMode = FocusModeEnum.None; InteractButton.FocusMode = FocusModeEnum.None;
ThrowButton.GrabFocus(); ThrowButton.GrabFocus();
} }
else if (item is Jewel jewel)
{
InteractButton.Text = "Augment";
InteractButton.GrabFocus();
}
else else
{ {
InteractButton.Text = "Use"; InteractButton.Text = "Use";
@@ -221,19 +248,31 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
ActionPanel.Show(); ActionPanel.Show();
} }
private void InventoryMenu_VisibilityChanged() private void ResetInventoryState()
{ {
_augmentMode = false;
foreach (var item in ItemSlots) foreach (var item in ItemSlots)
{
item.Hide(); item.Hide();
item.Disabled = true;
item.FocusMode = FocusModeEnum.None;
}
foreach (var item in ItemCountLabels) foreach (var item in ItemCountLabels)
item.Text = string.Empty; item.Text = string.Empty;
ItemName.Text = string.Empty;
ItemFlavor.Text = string.Empty;
ItemStats.Text = string.Empty;
for (var i = 0; i < _player.Inventory.Items.Count; i++) for (var i = 0; i < _player.Inventory.Items.Count; i++)
{ {
var item = _player.Inventory.Items[i]; var item = _player.Inventory.Items[i];
ItemSlots[i].Item.OnNext(item); ItemSlots[i].Item.OnNext(item);
ItemSlots[i].FocusMode = FocusModeEnum.All;
ItemSlots[i].Disabled = false;
ItemSlots[i].Show(); ItemSlots[i].Show();
ItemSlots[i].SetItemEquipmentStatus(_player.EquipmentComponent.IsItemEquipped(item)); ItemSlots[i].SetItemEquipmentStatus(_player.EquipmentComponent.IsItemEquipped(item));
if (item is IStackable stackable) if (item is IStackable stackable)
@@ -256,6 +295,25 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
ItemFlavor.Text = item.Description; ItemFlavor.Text = item.Description;
} }
private void AugmentMode(Jewel jewel)
{
_augmentingJewel = jewel;
foreach (var item in ItemSlots)
{
item.Disabled = true;
item.FocusMode = FocusModeEnum.None;
if (item.Item.Value is EquipableItem equipable && equipable.Augment == null)
{
item.Disabled = false;
item.FocusMode = FocusModeEnum.All;
}
}
var itemToSelect = ItemSlots.First(x => !x.Disabled);
itemToSelect.GrabFocus();
}
private void CloseActionMenu() private void CloseActionMenu()
{ {
_currentlySelected.GrabFocus(); _currentlySelected.GrabFocus();

View File

@@ -22,6 +22,7 @@ outline_color = Color(0, 0, 0, 1)
bg_color = Color(0, 0, 0, 0.745098) bg_color = Color(0, 0, 0, 0.745098)
[node name="InventoryMenu2" type="Control"] [node name="InventoryMenu2" type="Control"]
process_mode = 2
visible = false visible = false
layout_mode = 3 layout_mode = 3
anchors_preset = 15 anchors_preset = 15

View File

@@ -0,0 +1,203 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
using Zennysoft.Game.Implementation;
using Zennysoft.Game.Ma;
using Zennysoft.Ma.Adapter;
[Meta(typeof(IAutoNode))]
public partial class ItemRescueMenu : Control
{
public override void _Notification(int what) => this.Notify(what);
[Dependency] private IPlayer _player => this.DependOn<IPlayer>();
[Dependency] private IGame _game => this.DependOn<IGame>();
[Dependency] private IGameRepo _gameRepo => this.DependOn<IGameRepo>();
[Node] public Label ItemName { get; set; }
[Node] public Label ItemFlavor { get; set; }
[Node] public Label ItemStats { get; set; }
[Node] public Button InteractButton { get; set; }
[Node] public Button DropButton { get; set; }
[Node] public Control ActionPanel { get; set; }
private List<IItemSlot> ItemSlots;
private List<Label> ItemCountLabels;
private IItemSlot _currentlySelected;
public event Action MenuClosing;
#region ItemSlots
[Node] public IItemSlot ItemSlot01 { get; set; }
[Node] public IItemSlot ItemSlot02 { get; set; }
[Node] public IItemSlot ItemSlot03 { get; set; }
[Node] public IItemSlot ItemSlot04 { get; set; }
[Node] public IItemSlot ItemSlot05 { get; set; }
[Node] public IItemSlot ItemSlot06 { get; set; }
[Node] public IItemSlot ItemSlot07 { get; set; }
[Node] public IItemSlot ItemSlot08 { get; set; }
[Node] public IItemSlot ItemSlot09 { get; set; }
[Node] public IItemSlot ItemSlot10 { get; set; }
[Node] public Label ItemCount01 { get; set; }
[Node] public Label ItemCount02 { get; set; }
[Node] public Label ItemCount03 { get; set; }
[Node] public Label ItemCount04 { get; set; }
[Node] public Label ItemCount05 { get; set; }
[Node] public Label ItemCount06 { get; set; }
[Node] public Label ItemCount07 { get; set; }
[Node] public Label ItemCount08 { get; set; }
[Node] public Label ItemCount09 { get; set; }
[Node] public Label ItemCount10 { get; set; }
#endregion
public void OnResolved()
{
ItemSlots = [ItemSlot01, ItemSlot02, ItemSlot03, ItemSlot04, ItemSlot05, ItemSlot06, ItemSlot07, ItemSlot08, ItemSlot09, ItemSlot10];
ItemCountLabels = [ItemCount01, ItemCount02, ItemCount03, ItemCount04, ItemCount05, ItemCount06, ItemCount07, ItemCount08, ItemCount09, ItemCount10];
foreach (var slot in ItemSlots)
{
slot.ItemSelected += Slot_FocusEntered;
slot.ItemPressed += Slot_ItemPressed;
}
VisibilityChanged += ResetInventoryState;
InteractButton.Pressed += InteractButton_Pressed;
DropButton.Pressed += DropButton_Pressed;
_currentlySelected = ItemSlot01;
}
private void InteractButton_Pressed()
{
if (_currentlySelected != null)
{
_player.Inventory.PickUpItem(_currentlySelected.Item.Value);
_game.RescuedItems.Items.Remove(_currentlySelected.Item.Value);
CloseActionMenu();
ResetInventoryState();
}
}
private void DropButton_Pressed()
{
_game.RescuedItems.Items.Remove(_currentlySelected.Item.Value);
ResetInventoryState();
}
public override void _Input(InputEvent @event)
{
if (!Visible)
return;
if (Input.IsActionJustPressed(GameInputs.Inventory))
GetViewport().SetInputAsHandled();
if (ActionPanel.Visible && Input.IsActionJustPressed(GameInputs.Interact))
{
CloseActionMenu();
SfxDatabase.Instance.Play(SoundEffect.CancelUI);
GetViewport().SetInputAsHandled();
}
else if (Input.IsActionJustPressed(GameInputs.Interact))
{
Hide();
SfxDatabase.Instance.Play(SoundEffect.CancelUI);
GetViewport().SetInputAsHandled();
MenuClosing.Invoke();
}
if (!ActionPanel.Visible && Input.IsActionJustPressed(GameInputs.MoveUp))
{
if (ItemSlots.Any() && ItemSlots.First(x => x.Visible) != _currentlySelected)
SfxDatabase.Instance.Play(SoundEffect.MoveUI);
}
if (!ActionPanel.Visible && Input.IsActionJustPressed(GameInputs.MoveDown))
{
if (ItemSlots.Any() && ItemSlots.Last(x => x.Visible) != _currentlySelected)
SfxDatabase.Instance.Play(SoundEffect.MoveUI);
}
if (Input.IsActionJustPressed(GameInputs.MoveDown) && ActionPanel.Visible && InteractButton.HasFocus())
SfxDatabase.Instance.Play(SoundEffect.MoveUI);
if (Input.IsActionJustPressed(GameInputs.MoveUp) && ActionPanel.Visible && DropButton.HasFocus())
SfxDatabase.Instance.Play(SoundEffect.MoveUI);
}
private void Slot_ItemPressed(IItemSlot slot)
{
var item = slot.Item.Value;
InteractButton.Disabled = false;
DropButton.Disabled = false;
InteractButton.FocusMode = FocusModeEnum.All;
DropButton.FocusMode = FocusModeEnum.All;
ActionPanel.Show();
InteractButton.GrabFocus();
}
private void ResetInventoryState()
{
foreach (var item in ItemSlots)
{
item.Hide();
item.Disabled = true;
item.FocusMode = FocusModeEnum.None;
ItemFlavor.Text = string.Empty;
ItemName.Text = string.Empty;
ItemStats.Text = string.Empty;
}
foreach (var item in ItemCountLabels)
item.Text = string.Empty;
for (var i = 0; i < _game.RescuedItems.Items.Count; i++)
{
var item = _game.RescuedItems.Items[i];
ItemSlots[i].Item.OnNext(item);
ItemSlots[i].FocusMode = FocusModeEnum.All;
ItemSlots[i].Disabled = false;
ItemSlots[i].Show();
if (item is IStackable stackable)
ItemCountLabels[i].Text = $"x{stackable.Count.Value:D2}";
}
if (_player.Inventory.AtCapacity())
{
foreach (var item in ItemSlots)
{
item.Disabled = true;
item.FocusMode = FocusModeEnum.None;
}
}
else if (_currentlySelected != null)
_currentlySelected.GrabFocus();
else
_currentlySelected = ItemSlots.First();
}
private void Slot_FocusEntered(IItemSlot slot)
{
if (_currentlySelected.Item.Value == null)
return;
_currentlySelected = slot;
var item = slot.Item.Value;
ItemName.Text = item.ItemName;
ItemFlavor.Text = item.Description;
}
private void CloseActionMenu()
{
_currentlySelected.GrabFocus();
ActionPanel.Hide();
}
}

View File

@@ -0,0 +1 @@
uid://cterndmplud2b

View File

@@ -0,0 +1,434 @@
[gd_scene load_steps=11 format=3 uid="uid://dwa7o6hkkwjg1"]
[ext_resource type="Script" uid="uid://cterndmplud2b" path="res://src/ui/inventory_menu/ItemRescueMenu.cs" id="1_qqblc"]
[ext_resource type="FontFile" uid="uid://beh6d5lo5ihq0" path="res://src/ui/fonts/georgiai.ttf" id="2_0lwmo"]
[ext_resource type="StyleBox" uid="uid://bxuy4tnftibfq" path="res://src/options/SelectedOptionsBox.tres" id="3_5237l"]
[ext_resource type="StyleBox" uid="uid://bl15q835s4ene" path="res://src/options/UnselectedOptionsBox.tres" id="4_twupc"]
[ext_resource type="PackedScene" uid="uid://c005nd0m2eim" path="res://src/ui/inventory_menu/ItemSlot.tscn" id="5_wq0q0"]
[ext_resource type="FontFile" uid="uid://0syyay37admf" path="res://src/ui/fonts/georgiab.ttf" id="6_nl1cv"]
[ext_resource type="LabelSettings" uid="uid://b6f8ggy3ulonb" path="res://src/ui/label_settings/GeorgiaItalic.tres" id="7_1xig5"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_cq2sk"]
bg_color = Color(0, 0, 0, 0.745098)
[sub_resource type="LabelSettings" id="LabelSettings_ejvue"]
line_spacing = 1.0
font = ExtResource("2_0lwmo")
font_size = 50
outline_size = 3
outline_color = Color(0, 0, 0, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_g7ag1"]
bg_color = Color(0, 0, 0, 0.745098)
[node name="ItemRescueMenu" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_qqblc")
[node name="InventoryTitlePanel" type="Panel" parent="."]
layout_mode = 1
offset_left = 38.0
offset_top = 40.0
offset_right = 431.0
offset_bottom = 157.0
theme_override_styles/panel = SubResource("StyleBoxFlat_cq2sk")
[node name="MarginContainer" type="MarginContainer" parent="InventoryTitlePanel"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="ReferenceRect" type="ReferenceRect" parent="InventoryTitlePanel/MarginContainer"]
layout_mode = 2
border_color = Color(1, 1, 1, 1)
border_width = 2.0
editor_only = false
[node name="InventoryLabel" type="Label" parent="InventoryTitlePanel/MarginContainer/ReferenceRect"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_font_sizes/font_size = 15
text = "STORAGE"
label_settings = SubResource("LabelSettings_ejvue")
horizontal_alignment = 1
vertical_alignment = 1
[node name="ActionPanel" type="Panel" parent="."]
unique_name_in_owner = true
visible = false
layout_mode = 1
anchors_preset = -1
anchor_left = 0.107
anchor_top = 0.86
anchor_right = 0.199
anchor_bottom = 0.915
offset_left = -164.44
offset_top = -35.8
offset_right = -159.08
offset_bottom = 70.8
grow_vertical = 0
focus_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_g7ag1")
[node name="MarginContainer" type="MarginContainer" parent="ActionPanel"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 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="ActionPanel/MarginContainer"]
layout_mode = 2
border_color = Color(1, 1, 1, 1)
border_width = 2.0
editor_only = false
[node name="MarginContainer" type="MarginContainer" parent="ActionPanel/MarginContainer"]
layout_mode = 2
theme_override_constants/margin_left = 20
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="VBoxContainer" type="VBoxContainer" parent="ActionPanel/MarginContainer/MarginContainer"]
process_mode = 2
layout_mode = 2
alignment = 1
[node name="InteractButton" type="Button" parent="ActionPanel/MarginContainer/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
focus_neighbor_left = NodePath(".")
focus_neighbor_top = NodePath(".")
focus_neighbor_right = NodePath(".")
focus_neighbor_bottom = NodePath("../DropButton")
theme_override_font_sizes/font_size = 25
theme_override_styles/focus = ExtResource("3_5237l")
theme_override_styles/disabled_mirrored = ExtResource("4_twupc")
theme_override_styles/disabled = ExtResource("4_twupc")
theme_override_styles/hover_pressed_mirrored = ExtResource("4_twupc")
theme_override_styles/hover_pressed = ExtResource("4_twupc")
theme_override_styles/hover_mirrored = ExtResource("4_twupc")
theme_override_styles/hover = ExtResource("4_twupc")
theme_override_styles/pressed_mirrored = ExtResource("4_twupc")
theme_override_styles/pressed = ExtResource("4_twupc")
theme_override_styles/normal_mirrored = ExtResource("4_twupc")
theme_override_styles/normal = ExtResource("4_twupc")
text = "Take"
alignment = 0
[node name="DropButton" type="Button" parent="ActionPanel/MarginContainer/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
focus_neighbor_left = NodePath(".")
focus_neighbor_top = NodePath("../InteractButton")
focus_neighbor_right = NodePath(".")
focus_neighbor_bottom = NodePath(".")
theme_override_font_sizes/font_size = 25
theme_override_styles/focus = ExtResource("3_5237l")
theme_override_styles/disabled_mirrored = ExtResource("4_twupc")
theme_override_styles/disabled = ExtResource("4_twupc")
theme_override_styles/hover_pressed_mirrored = ExtResource("4_twupc")
theme_override_styles/hover_pressed = ExtResource("4_twupc")
theme_override_styles/hover_mirrored = ExtResource("4_twupc")
theme_override_styles/hover = ExtResource("4_twupc")
theme_override_styles/pressed_mirrored = ExtResource("4_twupc")
theme_override_styles/pressed = ExtResource("4_twupc")
theme_override_styles/normal_mirrored = ExtResource("4_twupc")
theme_override_styles/normal = ExtResource("4_twupc")
text = "Destroy"
alignment = 0
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="PanelContainer" type="PanelContainer" parent="."]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -188.0
offset_top = -275.0
offset_right = 188.0
offset_bottom = 275.0
grow_horizontal = 2
grow_vertical = 2
[node name="InventoryList" type="Panel" parent="PanelContainer"]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_cq2sk")
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer"]
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="ReferenceRect" type="ReferenceRect" parent="PanelContainer/MarginContainer"]
layout_mode = 2
border_color = Color(1, 1, 1, 1)
border_width = 2.0
editor_only = false
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer/MarginContainer"]
layout_mode = 2
theme_override_constants/margin_left = 125
theme_override_constants/margin_top = 15
theme_override_constants/margin_right = 15
theme_override_constants/margin_bottom = 15
[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer/MarginContainer/MarginContainer"]
layout_mode = 2
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 0
[node name="ItemSlot01" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer" instance=ExtResource("5_wq0q0")]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
size_flags_vertical = 0
focus_neighbor_left = NodePath(".")
focus_neighbor_right = NodePath(".")
mouse_filter = 1
[node name="ItemSlot02" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer" instance=ExtResource("5_wq0q0")]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
focus_neighbor_left = NodePath(".")
focus_neighbor_right = NodePath(".")
mouse_filter = 1
[node name="ItemSlot03" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer" instance=ExtResource("5_wq0q0")]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
focus_neighbor_left = NodePath(".")
focus_neighbor_right = NodePath(".")
mouse_filter = 1
[node name="ItemSlot04" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer" instance=ExtResource("5_wq0q0")]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
focus_neighbor_left = NodePath(".")
focus_neighbor_right = NodePath(".")
mouse_filter = 1
[node name="ItemSlot05" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer" instance=ExtResource("5_wq0q0")]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
focus_neighbor_left = NodePath(".")
focus_neighbor_right = NodePath(".")
mouse_filter = 1
[node name="ItemSlot06" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer" instance=ExtResource("5_wq0q0")]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
focus_neighbor_left = NodePath(".")
focus_neighbor_right = NodePath(".")
mouse_filter = 1
[node name="ItemSlot07" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer" instance=ExtResource("5_wq0q0")]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
focus_neighbor_left = NodePath(".")
focus_neighbor_right = NodePath(".")
mouse_filter = 1
[node name="ItemSlot08" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer" instance=ExtResource("5_wq0q0")]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
focus_neighbor_left = NodePath(".")
focus_neighbor_right = NodePath(".")
mouse_filter = 1
[node name="ItemSlot09" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer" instance=ExtResource("5_wq0q0")]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
focus_neighbor_left = NodePath(".")
focus_neighbor_right = NodePath(".")
mouse_filter = 1
[node name="ItemSlot10" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer" instance=ExtResource("5_wq0q0")]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
focus_neighbor_left = NodePath(".")
focus_neighbor_right = NodePath(".")
mouse_filter = 1
[node name="VBoxContainer2" type="VBoxContainer" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 10
theme_override_constants/separation = 0
[node name="ItemCount01" type="Label" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer2"]
unique_name_in_owner = true
custom_minimum_size = Vector2(50, 50)
layout_mode = 2
theme_override_fonts/font = ExtResource("6_nl1cv")
theme_override_font_sizes/font_size = 25
vertical_alignment = 1
[node name="ItemCount02" type="Label" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer2"]
unique_name_in_owner = true
custom_minimum_size = Vector2(50, 50)
layout_mode = 2
theme_override_fonts/font = ExtResource("6_nl1cv")
theme_override_font_sizes/font_size = 25
vertical_alignment = 1
[node name="ItemCount03" type="Label" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer2"]
unique_name_in_owner = true
custom_minimum_size = Vector2(50, 50)
layout_mode = 2
theme_override_fonts/font = ExtResource("6_nl1cv")
theme_override_font_sizes/font_size = 25
vertical_alignment = 1
[node name="ItemCount04" type="Label" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer2"]
unique_name_in_owner = true
custom_minimum_size = Vector2(50, 50)
layout_mode = 2
theme_override_fonts/font = ExtResource("6_nl1cv")
theme_override_font_sizes/font_size = 25
vertical_alignment = 1
[node name="ItemCount05" type="Label" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer2"]
unique_name_in_owner = true
custom_minimum_size = Vector2(50, 50)
layout_mode = 2
theme_override_fonts/font = ExtResource("6_nl1cv")
theme_override_font_sizes/font_size = 25
vertical_alignment = 1
[node name="ItemCount06" type="Label" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer2"]
unique_name_in_owner = true
custom_minimum_size = Vector2(50, 50)
layout_mode = 2
theme_override_fonts/font = ExtResource("6_nl1cv")
theme_override_font_sizes/font_size = 25
vertical_alignment = 1
[node name="ItemCount07" type="Label" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer2"]
unique_name_in_owner = true
custom_minimum_size = Vector2(50, 50)
layout_mode = 2
theme_override_fonts/font = ExtResource("6_nl1cv")
theme_override_font_sizes/font_size = 25
vertical_alignment = 1
[node name="ItemCount08" type="Label" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer2"]
unique_name_in_owner = true
custom_minimum_size = Vector2(50, 50)
layout_mode = 2
theme_override_fonts/font = ExtResource("6_nl1cv")
theme_override_font_sizes/font_size = 25
vertical_alignment = 1
[node name="ItemCount09" type="Label" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer2"]
unique_name_in_owner = true
custom_minimum_size = Vector2(50, 50)
layout_mode = 2
theme_override_fonts/font = ExtResource("6_nl1cv")
theme_override_font_sizes/font_size = 25
vertical_alignment = 1
[node name="ItemCount10" type="Label" parent="PanelContainer/MarginContainer/MarginContainer/HBoxContainer/VBoxContainer2"]
unique_name_in_owner = true
custom_minimum_size = Vector2(50, 50)
layout_mode = 2
theme_override_fonts/font = ExtResource("6_nl1cv")
theme_override_font_sizes/font_size = 25
vertical_alignment = 1
[node name="ItemDescriptionBox" type="Panel" parent="."]
layout_mode = 2
offset_left = 37.0
offset_top = 242.0
offset_right = 717.0
offset_bottom = 838.0
theme_override_styles/panel = SubResource("StyleBoxFlat_cq2sk")
[node name="MarginContainer" type="MarginContainer" parent="ItemDescriptionBox"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="ReferenceRect" type="ReferenceRect" parent="ItemDescriptionBox/MarginContainer"]
layout_mode = 2
border_color = Color(1, 1, 1, 1)
border_width = 2.0
editor_only = false
[node name="MarginContainer" type="MarginContainer" parent="ItemDescriptionBox/MarginContainer"]
layout_mode = 2
theme_override_constants/margin_left = 15
theme_override_constants/margin_top = 15
theme_override_constants/margin_right = 15
theme_override_constants/margin_bottom = 15
[node name="VBoxContainer" type="VBoxContainer" parent="ItemDescriptionBox/MarginContainer/MarginContainer"]
layout_mode = 2
theme_override_constants/separation = 50
[node name="ItemName" type="Label" parent="ItemDescriptionBox/MarginContainer/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
label_settings = ExtResource("7_1xig5")
[node name="ItemFlavor" type="Label" parent="ItemDescriptionBox/MarginContainer/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(500, 150)
layout_mode = 2
label_settings = ExtResource("7_1xig5")
vertical_alignment = 1
autowrap_mode = 2
[node name="ItemStats" type="Label" parent="ItemDescriptionBox/MarginContainer/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
label_settings = ExtResource("7_1xig5")