Will need to finetune enemy navigation agent placement depending on if they're now too high/low to sit in the navigation region
230 lines
7.7 KiB
C#
230 lines
7.7 KiB
C#
using Chickensoft.AutoInject;
|
|
using Chickensoft.Introspection;
|
|
using Godot;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Zennysoft.Game.Ma;
|
|
using Zennysoft.Ma.Adapter;
|
|
|
|
[Meta(typeof(IAutoNode))]
|
|
public partial class InventoryMenu : Control, IInventoryMenu
|
|
{
|
|
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 ItemType { get; set; }
|
|
|
|
[Node] public Label ItemParameter { get; set; }
|
|
|
|
[Node] public Label ItemFlavor { get; set; }
|
|
|
|
[Node] public Label ItemStats { get; set; }
|
|
|
|
[Node] public Label ItemAugment { get; set; }
|
|
|
|
[Node] public TextureRect ItemAugmentTexture { get; set; }
|
|
|
|
[Node] public ActionPanel ActionPanel { get; set; }
|
|
|
|
[Node] public VBoxContainer Inventory { get; set; }
|
|
|
|
[Node] public Control MenuPanel { get; set; }
|
|
|
|
[Node] public AugmentableItemsMenu AugmentMenu { get; set; }
|
|
|
|
[Node] public Label PlayerATKLabel { get; set; }
|
|
|
|
[Node] public Label PlayerDEFLabel { get; set; }
|
|
|
|
[Node] public Label StatusLabel { get; set; }
|
|
|
|
private List<IItemSlot> ItemSlots;
|
|
|
|
private IItemSlot _currentlySelected;
|
|
|
|
public void OnResolved()
|
|
{
|
|
ItemSlots = [.. Inventory.GetChildren().OfType<IItemSlot>()];
|
|
ItemSlots.ForEach(x => x.ItemPressed += ItemPressed);
|
|
ItemSlots.ForEach(x => x.ItemSelected += ItemSelected);
|
|
VisibilityChanged += ResetInventoryState;
|
|
ActionPanel.ActionPanelClosing += ActionPanel_ActionPanelClosing;
|
|
ActionPanel.ReturnToGameAction += ActionPanel_ReturnToGameAction;
|
|
ActionPanel.AugmentMenuRequested += ActionPanel_AugmentMenuRequested;
|
|
AugmentMenu.AugmentMenuClosing += AugmentMenu_AugmentMenuClosing;
|
|
_player.EquipmentComponent.EquipmentChanged += EquipmentChanged;
|
|
_player.AttackComponent.CurrentAttack.Changed += AttackChanged;
|
|
_player.AttackComponent.MaximumAttack.Changed += AttackChanged;
|
|
_player.DefenseComponent.CurrentDefense.Changed += DefenseChanged;
|
|
_player.DefenseComponent.MaximumDefense.Changed += DefenseChanged;
|
|
ClearDescriptionBox();
|
|
AttackChanged(0);
|
|
DefenseChanged(0);
|
|
StatusLabel.Text = string.Empty;
|
|
Hide();
|
|
}
|
|
|
|
private void AttackChanged(int obj) => PlayerATKLabel.Text = $"{_player.AttackComponent.CurrentAttack.Value:D2}/{_player.AttackComponent.MaximumAttack.Value:D2}+{_player.EquipmentComponent.BonusAttack}";
|
|
|
|
private void DefenseChanged(int obj) => PlayerDEFLabel.Text = $"{_player.DefenseComponent.CurrentDefense.Value:D2}/{_player.DefenseComponent.MaximumDefense.Value:D2}+{_player.EquipmentComponent.BonusDefense}";
|
|
|
|
public override void _Input(InputEvent @event)
|
|
{
|
|
var validSelectableItems = _player.Inventory.Items.ToList();
|
|
|
|
if (Input.IsActionJustPressed(GameInputs.MoveUp) && _currentlySelected != null && _currentlySelected.Item.Value != validSelectableItems.First())
|
|
SfxDatabase.Instance.Play(SoundEffect.MoveUI);
|
|
if (Input.IsActionJustPressed(GameInputs.MoveDown) && _currentlySelected != null && _currentlySelected.Item.Value != validSelectableItems.Last())
|
|
SfxDatabase.Instance.Play(SoundEffect.MoveUI);
|
|
if (Input.IsActionJustPressed(GameInputs.Interact))
|
|
SfxDatabase.Instance.Play(SoundEffect.CancelUI);
|
|
}
|
|
|
|
private void ActionPanel_AugmentMenuRequested()
|
|
{
|
|
ReleaseFocus();
|
|
ItemSlots.ForEach(x => x.ItemPressed -= ItemPressed);
|
|
ItemSlots.ForEach(x => x.ItemSelected -= ItemSelected);
|
|
MenuPanel.Hide();
|
|
SetProcessInput(false);
|
|
AugmentMenu.SetProcessInput(true);
|
|
AugmentMenu.OpenAugmentMenu(_currentlySelected.Item.Value as IAugmentItem);
|
|
}
|
|
|
|
private void ActionPanel_ReturnToGameAction()
|
|
{
|
|
_gameRepo.CloseInventory();
|
|
}
|
|
|
|
private void ItemPressed(IItemSlot selectedItem)
|
|
{
|
|
SetProcessInput(false);
|
|
ActionPanel.SetProcessInput(true);
|
|
ActionPanel.ShowPanel(selectedItem.Item.Value);
|
|
ActionPanel.FocusActionPanel();
|
|
SfxDatabase.Instance.Play(SoundEffect.SelectUI);
|
|
}
|
|
|
|
private void ItemSelected(IItemSlot selectedItem)
|
|
{
|
|
_currentlySelected = selectedItem;
|
|
ItemName.Text = selectedItem.Item.Value.ItemName;
|
|
ItemType.Text = SetItemTypeName(selectedItem.Item.Value);
|
|
ItemParameter.Text = GetItemParameterText(selectedItem.Item.Value);
|
|
ItemParameter.Visible = !string.IsNullOrEmpty(ItemParameter.Text);
|
|
ItemFlavor.Text = selectedItem.Item.Value.FlavorText;
|
|
ItemFlavor.Visible = !string.IsNullOrEmpty(ItemFlavor.Text);
|
|
ItemStats.Text = selectedItem.Item.Value.StatDescription;
|
|
ItemStats.Visible = !string.IsNullOrEmpty(ItemStats.Text);
|
|
ItemAugmentTexture.Texture = null;
|
|
ItemAugment.Text = GetAugmentText(selectedItem.Item.Value);
|
|
}
|
|
|
|
private void ResetInventoryState()
|
|
{
|
|
var inventory = _player.Inventory.Items;
|
|
ItemSlots.ForEach(x => x.SetEmpty());
|
|
ClearDescriptionBox();
|
|
|
|
for (var i = 0; i < inventory.Count; i++)
|
|
ItemSlots[i].SetItemToSlot(inventory[i]);
|
|
|
|
if (_currentlySelected != null && !inventory.Contains(_currentlySelected.Item.Value))
|
|
_currentlySelected = null;
|
|
|
|
if (_currentlySelected == null && inventory.Count > 0)
|
|
_currentlySelected = ItemSlots.FirstOrDefault(x => x.Item.Value == inventory.First());
|
|
|
|
if (inventory.Count > 0)
|
|
_currentlySelected.FocusItem();
|
|
ActionPanel.Hide();
|
|
}
|
|
|
|
private void ClearDescriptionBox()
|
|
{
|
|
ItemName.Text = string.Empty;
|
|
ItemType.Text = string.Empty;
|
|
ItemParameter.Text = string.Empty;
|
|
ItemStats.Text = string.Empty;
|
|
ItemFlavor.Text = string.Empty;
|
|
ItemAugment.Text = string.Empty;
|
|
ItemAugmentTexture.Texture = null;
|
|
}
|
|
|
|
private void ActionPanel_ActionPanelClosing()
|
|
{
|
|
ActionPanel.Hide();
|
|
SetProcessInput(true);
|
|
ActionPanel.SetProcessInput(false);
|
|
if (_player.Inventory.Items.Any() && !_player.Inventory.Items.Contains(_currentlySelected.Item.Value))
|
|
_currentlySelected = null;
|
|
ResetInventoryState();
|
|
}
|
|
|
|
private void AugmentMenu_AugmentMenuClosing()
|
|
{
|
|
ItemSlots.ForEach(x => x.ItemPressed += ItemPressed);
|
|
ItemSlots.ForEach(x => x.ItemSelected += ItemSelected);
|
|
MenuPanel.Show();
|
|
SetProcessInput(true);
|
|
AugmentMenu.SetProcessInput(false);
|
|
AugmentMenu.Hide();
|
|
ResetInventoryState();
|
|
}
|
|
|
|
private void EquipmentChanged(IEquipableItem obj)
|
|
{
|
|
AttackChanged(0);
|
|
DefenseChanged(0);
|
|
}
|
|
|
|
private static string GetItemParameterText(IBaseInventoryItem item)
|
|
{
|
|
if (item is Weapon potentiallyProjectile && (potentiallyProjectile.WeaponTag == WeaponTag.KineticProjectile || potentiallyProjectile.WeaponTag == WeaponTag.ElementalProjectile))
|
|
return string.Empty;
|
|
|
|
return item switch
|
|
{
|
|
Weapon weapon => $"ATK: {(weapon.ItemTag == ItemTag.MysteryItem ? "???" : weapon.BonusAttack)}",
|
|
Armor armor => $"DEF: {(armor.ItemTag == ItemTag.MysteryItem ? "???" : armor.BonusDefense)}",
|
|
_ => string.Empty,
|
|
};
|
|
}
|
|
|
|
private string GetAugmentText(IBaseInventoryItem item)
|
|
{
|
|
if (item is IAugmentableItem augmentable && augmentable.Augment != null)
|
|
{
|
|
ItemAugmentTexture.Texture = augmentable.Augment.AugmentTexture;
|
|
return $"{augmentable.Augment.AugmentName}{System.Environment.NewLine}{augmentable.Augment.AugmentDescription}";
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
|
|
private static string SetItemTypeName(IBaseInventoryItem item)
|
|
{
|
|
return item switch
|
|
{
|
|
Weapon => "Weapon",
|
|
Armor => "Armor",
|
|
Accessory => "Mask",
|
|
Ammo => "Ammo",
|
|
BoxItem => "Box",
|
|
ConsumableItem => "Restorative",
|
|
EffectItem => "Spell",
|
|
Jewel => "Jewel",
|
|
Plastique => "Explosive",
|
|
ThrowableItem => "Dice",
|
|
_ => "Unknown item type.",
|
|
};
|
|
}
|
|
}
|