diff --git a/Zennysoft.Game.Ma.Implementation/Equipment/Tags/ItemTag.cs b/Zennysoft.Game.Ma.Implementation/Equipment/Tags/ItemTag.cs index 052615bf..19aca5eb 100644 --- a/Zennysoft.Game.Ma.Implementation/Equipment/Tags/ItemTag.cs +++ b/Zennysoft.Game.Ma.Implementation/Equipment/Tags/ItemTag.cs @@ -4,5 +4,21 @@ public enum ItemTag { None, BreaksOnChange, - MysteryItem -} + MysteryItem, + DamagesPlayer, + ContainsRestorative, + ContainsWeapon, + ContainsArmor, + ContainsBox, + RandomSpell, + ContainsAccessory, + DropTo1HPAndGainRareItem, + TradeOneRandomItem, + TradeAllRandomItems, + ContainsUnobtainedItem, + ContainsBasicItem, + RestrictUnequip, + UnequipAllItems, + EjectAllItems, + UseAllItems +} \ No newline at end of file diff --git a/Zennysoft.Game.Ma.Implementation/Player/IPlayer.cs b/Zennysoft.Game.Ma.Implementation/Player/IPlayer.cs index cfddcf29..6f241b40 100644 --- a/Zennysoft.Game.Ma.Implementation/Player/IPlayer.cs +++ b/Zennysoft.Game.Ma.Implementation/Player/IPlayer.cs @@ -44,6 +44,8 @@ public interface IPlayer : IKillable, ICharacterBody3D public void SetHealthTimerStatus(bool isActive); + public bool CanEquipState { get; set; } + public event Action PlayerDied; public delegate InventoryItem RerollItem(InventoryItem item); } diff --git a/Zennysoft.Game.Ma/src/game/Game.cs b/Zennysoft.Game.Ma/src/game/Game.cs index f6815338..7530eb06 100644 --- a/Zennysoft.Game.Ma/src/game/Game.cs +++ b/Zennysoft.Game.Ma/src/game/Game.cs @@ -69,7 +69,6 @@ public partial class Game : Node3D, IGame public QuestData QuestData { get; private set; } private EffectService _effectService; - private ItemReroller _itemReroller; private IInstantiator _instantiator; private IPlayer _player; @@ -88,7 +87,6 @@ public partial class Game : Node3D, IGame QuestData = new QuestData(); RescuedItems = new RescuedItemDatabase(); ItemDatabase = ItemDatabase.Instance; - _itemReroller = new ItemReroller(ItemDatabase); GameChunk = new SaveChunk( (chunk) => @@ -212,10 +210,13 @@ public partial class Game : Node3D, IGame public async Task UseItem(InventoryItem item) { if (item.ItemTag == ItemTag.MysteryItem) - item = _itemReroller.RerollItem(item, _player.Inventory); + _effectService.RerollItem(item); switch (item) { + case BoxItem boxItem: + EnactBoxItemEffects(boxItem); + break; case ConsumableItem consumableItem: EnactConsumableItemEffects(consumableItem); break; @@ -428,6 +429,16 @@ public partial class Game : Node3D, IGame private void FinishedLoadingSaveFile() => EmitSignal(SignalName.SaveFileLoaded); + private void EnactBoxItemEffects(BoxItem boxItem) + { + switch (boxItem.ItemTag) + { + case ItemTag.DamagesPlayer: + _effectService.DamagesPlayer(boxItem.Stats.DamageToPlayer); + break; + } + } + private void EnactConsumableItemEffects(ConsumableItem consumableItem) { if (_player.HealthComponent.AtFullHealth && consumableItem.RaiseHPAmount > 0) @@ -519,7 +530,7 @@ public partial class Game : Node3D, IGame _effectService.ChangeAffinity(throwableItem); break; case ThrowableItemTag.WarpToExitIfFound: - _effectService.WarpToExit(_player); + _effectService.WarpToExit(); GameRepo.CloseInventory(); break; } diff --git a/Zennysoft.Game.Ma/src/items/EffectService.cs b/Zennysoft.Game.Ma/src/items/EffectService.cs index 2a31352b..c634b5a4 100644 --- a/Zennysoft.Game.Ma/src/items/EffectService.cs +++ b/Zennysoft.Game.Ma/src/items/EffectService.cs @@ -226,13 +226,90 @@ public class EffectService throwableItem.SetCount(throwableItem.Count + 1); } - public void WarpToExit(IPlayer player) + public void WarpToExit() { var exitRoom = _game.CurrentFloor.Rooms.OfType().Single(); if (exitRoom.PlayerDiscoveredRoom) { SfxDatabase.Instance.Play(SoundEffect.TeleportToExit); - player.TeleportPlayer((exitRoom.PlayerSpawn.Rotation, exitRoom.PlayerSpawn.Position)); + _player.TeleportPlayer((exitRoom.PlayerSpawn.Rotation, exitRoom.PlayerSpawn.Position)); } } + + public void DamagesPlayer(int damage) + { + _player.TakeDamage(new AttackData(damage, ElementType.None, true, true)); + } + + public void RerollItem(InventoryItem itemToReroll) + { + var itemReroller = new ItemReroller(ItemDatabase.Instance); + itemReroller.RerollItem(itemToReroll, _player.Inventory); + } + + public void GetRandomItemOfType(T itemToExclude = null) + where T : InventoryItem + { + _player.Inventory.TryAdd(ItemDatabase.Instance.PickItem(itemToExclude)); + } + + public void RandomSpell() + { + throw new NotImplementedException("Spells not implemented yet."); + } + + public void DropTo1HPAndGainRareItem() + where T : InventoryItem + { + _player.HealthComponent.SetCurrentHealth(1); + _player.Inventory.TryAdd(ItemDatabase.Instance.PickRareItem()); + } + + public void TradeRandomItem(BoxItem box) + { + if (_player.Inventory.Items.Count == 1) + return; + + var tradableItems = _player.Inventory.Items.Where(x => x != box).ToList(); + + var rng = new RandomNumberGenerator(); + rng.Randomize(); + var randomIndex = rng.RandiRange(0, _player.Inventory.Items.Count - 1); + var randomItem = tradableItems[randomIndex]; + if (randomItem is EquipableItem equipableItem) + { + if (_player.EquipmentComponent.IsItemEquipped(equipableItem)) + _player.Unequip(equipableItem); + } + _player.Inventory.Remove(randomItem); + + GetRandomItemOfType(box); + } + + public void TradeAllRandomItems(BoxItem box) + { + var tradableItems = _player.Inventory.Items.Where(x => x != box); + foreach (var item in tradableItems) + TradeRandomItem(box); + } + + public void GetUnobtainedItem() + { + var pickableItems = ItemDatabase.Instance.Items.Except(_player.Inventory.Items).ToList(); + var rng = new RandomNumberGenerator(); + rng.Randomize(); + var randomIndex = rng.RandiRange(0, pickableItems.Count - 1); + var selectedItem = pickableItems[randomIndex]; + + if (selectedItem is ThrowableItem throwableItem) + throwableItem.SetCount(rng.RandiRange(throwableItem.Stats.MinimumCount, throwableItem.Stats.MaximumCount)); + + _player.Inventory.TryAdd(selectedItem); + } + + public void GetBasicItem() + where T : InventoryItem + { + _player.Inventory.TryAdd(ItemDatabase.Instance.PickBasicItem()); + } } diff --git a/Zennysoft.Game.Ma/src/items/ItemDatabase.cs b/Zennysoft.Game.Ma/src/items/ItemDatabase.cs index 552d857e..fe3f4b00 100644 --- a/Zennysoft.Game.Ma/src/items/ItemDatabase.cs +++ b/Zennysoft.Game.Ma/src/items/ItemDatabase.cs @@ -18,12 +18,31 @@ public class ItemDatabase public T PickItem(T itemToExclude = null) where T : InventoryItem + { + var itemsToSelectFrom = Items; + return PickItemInternal(itemsToSelectFrom, itemToExclude); + } + + public T PickRareItem(T itemToExclude = null) + where T : InventoryItem + { + var getRareItems = Items.Where(x => x.SpawnRate < 0.1f); + return PickItemInternal(getRareItems, itemToExclude); + } + + public T PickBasicItem(T itemToExclude = null) + where T : InventoryItem + { + var getBasicItems = Items.Where(x => x.SpawnRate > 0.5f); + return PickItemInternal(getBasicItems, itemToExclude); + } + + private T PickItemInternal(IEnumerable itemsToSelectFrom, T itemToExclude = null) + where T : InventoryItem { var rng = new RandomNumberGenerator(); rng.Randomize(); - var itemsToSelectFrom = Items; - if (itemToExclude is not null) itemsToSelectFrom = [.. itemsToSelectFrom.OfType().Where(x => x.ItemName != itemToExclude.ItemName)]; diff --git a/Zennysoft.Game.Ma/src/items/ItemReroller.cs b/Zennysoft.Game.Ma/src/items/ItemReroller.cs index dacb4b34..82522d47 100644 --- a/Zennysoft.Game.Ma/src/items/ItemReroller.cs +++ b/Zennysoft.Game.Ma/src/items/ItemReroller.cs @@ -27,6 +27,21 @@ public class ItemReroller return rolledItem; } + public InventoryItem RerollItemToAny(InventoryItem itemToReroll, IInventory inventory, bool insertIntoInventory = true) + { + var currentIndex = inventory.Items.IndexOf(itemToReroll); + + if (insertIntoInventory) + inventory.Remove(itemToReroll); + + var rolledItem = _database.PickItem(itemToReroll); + + if (insertIntoInventory) + inventory.TryInsert(rolledItem, currentIndex); + + return rolledItem; + } + private Weapon RerollItemInternal(Weapon itemToReroll) => _database.PickItem(itemToReroll); private Armor RerollItemInternal(Armor itemToReroll) => _database.PickItem(itemToReroll); private Accessory RerollItemInternal(Accessory itemToReroll) => _database.PickItem(itemToReroll); diff --git a/Zennysoft.Game.Ma/src/items/accessory/BoxItemStats.cs b/Zennysoft.Game.Ma/src/items/accessory/BoxItemStats.cs new file mode 100644 index 00000000..97678da0 --- /dev/null +++ b/Zennysoft.Game.Ma/src/items/accessory/BoxItemStats.cs @@ -0,0 +1,12 @@ +using Chickensoft.Introspection; +using Godot; + +namespace Zennysoft.Game.Ma; + +[GlobalClass] +[Meta, Id("box_item_stat_type")] +public partial class BoxItemStats : InventoryItemStats +{ + [Export] + public int DamageToPlayer { get; set; } = 10; +} \ No newline at end of file diff --git a/Zennysoft.Game.Ma/src/items/accessory/BoxItemStats.cs.uid b/Zennysoft.Game.Ma/src/items/accessory/BoxItemStats.cs.uid new file mode 100644 index 00000000..983ba3a4 --- /dev/null +++ b/Zennysoft.Game.Ma/src/items/accessory/BoxItemStats.cs.uid @@ -0,0 +1 @@ +uid://vuavr681au06 diff --git a/Zennysoft.Game.Ma/src/items/assetts/plastique.glb b/Zennysoft.Game.Ma/src/items/assets/plastique.glb similarity index 100% rename from Zennysoft.Game.Ma/src/items/assetts/plastique.glb rename to Zennysoft.Game.Ma/src/items/assets/plastique.glb diff --git a/Zennysoft.Game.Ma/src/items/assetts/plastique.glb.import b/Zennysoft.Game.Ma/src/items/assets/plastique.glb.import similarity index 76% rename from Zennysoft.Game.Ma/src/items/assetts/plastique.glb.import rename to Zennysoft.Game.Ma/src/items/assets/plastique.glb.import index adadba16..bf6f66da 100644 --- a/Zennysoft.Game.Ma/src/items/assetts/plastique.glb.import +++ b/Zennysoft.Game.Ma/src/items/assets/plastique.glb.import @@ -4,12 +4,12 @@ importer="scene" importer_version=1 type="PackedScene" uid="uid://dkpgrhj14phdd" -path="res://.godot/imported/plastique.glb-38f4438846eaa3d64b225272714c5d02.scn" +path="res://.godot/imported/plastique.glb-5845ad959844e1ca0c9791ff0287bc66.scn" [deps] -source_file="res://src/items/assetts/plastique.glb" -dest_files=["res://.godot/imported/plastique.glb-38f4438846eaa3d64b225272714c5d02.scn"] +source_file="res://src/items/assets/plastique.glb" +dest_files=["res://.godot/imported/plastique.glb-5845ad959844e1ca0c9791ff0287bc66.scn"] [params] diff --git a/Zennysoft.Game.Ma/src/items/assetts/plastique_plastique.png b/Zennysoft.Game.Ma/src/items/assets/plastique_plastique.png similarity index 100% rename from Zennysoft.Game.Ma/src/items/assetts/plastique_plastique.png rename to Zennysoft.Game.Ma/src/items/assets/plastique_plastique.png diff --git a/Zennysoft.Game.Ma/src/items/assetts/plastique_plastique.png.import b/Zennysoft.Game.Ma/src/items/assets/plastique_plastique.png.import similarity index 71% rename from Zennysoft.Game.Ma/src/items/assetts/plastique_plastique.png.import rename to Zennysoft.Game.Ma/src/items/assets/plastique_plastique.png.import index fd86913f..efb51d7d 100644 --- a/Zennysoft.Game.Ma/src/items/assetts/plastique_plastique.png.import +++ b/Zennysoft.Game.Ma/src/items/assets/plastique_plastique.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://dkqs4x4pi18on" -path="res://.godot/imported/plastique_plastique.png-3ad121f0468f0ec1d61934d8a0e41cb7.ctex" +path="res://.godot/imported/plastique_plastique.png-06bcea5737da44088a0bd794735523f0.ctex" metadata={ "vram_texture": false } @@ -13,8 +13,8 @@ generator_parameters={ [deps] -source_file="res://src/items/assetts/plastique_plastique.png" -dest_files=["res://.godot/imported/plastique_plastique.png-3ad121f0468f0ec1d61934d8a0e41cb7.ctex"] +source_file="res://src/items/assets/plastique_plastique.png" +dest_files=["res://.godot/imported/plastique_plastique.png-06bcea5737da44088a0bd794735523f0.ctex"] [params] diff --git a/Zennysoft.Game.Ma/src/items/box/BoxItem.cs b/Zennysoft.Game.Ma/src/items/box/BoxItem.cs new file mode 100644 index 00000000..8498e062 --- /dev/null +++ b/Zennysoft.Game.Ma/src/items/box/BoxItem.cs @@ -0,0 +1,37 @@ +using Chickensoft.AutoInject; +using Chickensoft.Introspection; +using Chickensoft.Serialization; +using Godot; +using Zennysoft.Game.Ma; +using Zennysoft.Ma.Adapter; + +[Meta(typeof(IAutoNode)), Id("box_item")] +public partial class BoxItem : InventoryItem +{ + public override void _Notification(int what) => this.Notify(what); + + [Node] private Sprite3D _sprite { get; set; } + + [Export] + [Save("box_stats")] + public BoxItemStats Stats { get; set; } = new BoxItemStats(); + + public override string ItemName => Stats.Name; + + public override string Description => Stats.Description; + + public override float SpawnRate => Stats.SpawnRate; + + public override int ThrowDamage => Stats.ThrowDamage; + + public override float ThrowSpeed => Stats.ThrowSpeed; + + public override ItemTag ItemTag => Stats.ItemTag; + + public override Texture2D GetTexture() => Stats.Texture; + + public void OnReady() + { + _sprite.Texture = Stats.Texture; + } +} diff --git a/Zennysoft.Game.Ma/src/items/box/BoxItem.cs.uid b/Zennysoft.Game.Ma/src/items/box/BoxItem.cs.uid new file mode 100644 index 00000000..44834dfd --- /dev/null +++ b/Zennysoft.Game.Ma/src/items/box/BoxItem.cs.uid @@ -0,0 +1 @@ +uid://cqqqj4hgywst4 diff --git a/Zennysoft.Game.Ma/src/items/box/BoxItem.tscn b/Zennysoft.Game.Ma/src/items/box/BoxItem.tscn index 750753f5..9525e4f9 100644 --- a/Zennysoft.Game.Ma/src/items/box/BoxItem.tscn +++ b/Zennysoft.Game.Ma/src/items/box/BoxItem.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=5 format=3 uid="uid://bguomljidwgto"] -[ext_resource type="Script" path="res://src/items/box/BoxItem.cs" id="1_holk0"] +[ext_resource type="Script" uid="uid://cqqqj4hgywst4" path="res://src/items/box/BoxItem.cs" id="1_holk0"] [ext_resource type="Texture2D" uid="uid://bg47n2tmintm0" path="res://src/items/consumable/textures/past self remnant.PNG" id="2_holk0"] [sub_resource type="CylinderShape3D" id="CylinderShape3D_x6u08"] @@ -17,7 +17,6 @@ axis_lock_angular_x = true axis_lock_angular_y = true axis_lock_angular_z = true script = ExtResource("1_holk0") -Stats = null [node name="CollisionShape3D" type="CollisionShape3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.00908482, 0) diff --git a/Zennysoft.Game.Ma/src/items/box/resources/EmptyPromise.tres b/Zennysoft.Game.Ma/src/items/box/resources/EmptyPromise.tres new file mode 100644 index 00000000..a11a0f37 --- /dev/null +++ b/Zennysoft.Game.Ma/src/items/box/resources/EmptyPromise.tres @@ -0,0 +1,25 @@ +[gd_resource type="Resource" script_class="BoxItemStats" load_steps=3 format=3 uid="uid://cgkorwblwr12t"] + +[ext_resource type="Texture2D" uid="uid://bg47n2tmintm0" path="res://src/items/consumable/textures/past self remnant.PNG" id="1_650jj"] +[ext_resource type="Script" uid="uid://vuavr681au06" path="res://src/items/accessory/BoxItemStats.cs" id="1_i336w"] + +[resource] +script = ExtResource("1_i336w") +Name = "Empty Promise" +Description = "An empty box." +SpawnRate = 0.5 +BonusAttack = 0 +BonusDefense = 0 +BonusLuck = 0.05 +BonusHP = 0 +BonusVT = 0 +AeolicResistance = 0 +TelluricResistance = 0 +HydricResistance = 0 +IgneousResistance = 0 +FerrumResistance = 0 +ThrowSpeed = 12.0 +ThrowDamage = 5 +ItemTag = 0 +Texture = ExtResource("1_650jj") +metadata/_custom_type_script = "uid://vuavr681au06" diff --git a/Zennysoft.Game.Ma/src/items/misc/SetItem.tscn b/Zennysoft.Game.Ma/src/items/misc/SetItem.tscn index 996c4cbb..e74cd286 100644 --- a/Zennysoft.Game.Ma/src/items/misc/SetItem.tscn +++ b/Zennysoft.Game.Ma/src/items/misc/SetItem.tscn @@ -2,7 +2,7 @@ [ext_resource type="Script" uid="uid://da8mhruqpgh6r" path="res://src/items/misc/SetItem.cs" id="1_m8dyi"] [ext_resource type="AudioStream" uid="uid://bjcersd5id8ee" path="res://src/audio/sfx/ITEM_PLASTIQUETIMER.ogg" id="2_kgxna"] -[ext_resource type="Texture2D" uid="uid://dkqs4x4pi18on" path="res://src/items/assetts/plastique_plastique.png" id="2_m8dyi"] +[ext_resource type="Texture2D" uid="uid://dkqs4x4pi18on" path="res://src/items/assets/plastique_plastique.png" id="2_m8dyi"] [sub_resource type="Animation" id="Animation_eat5q"] length = 0.001 diff --git a/Zennysoft.Game.Ma/src/items/weapons/Weapon.cs b/Zennysoft.Game.Ma/src/items/weapons/Weapon.cs index 3fb74188..9af40d03 100644 --- a/Zennysoft.Game.Ma/src/items/weapons/Weapon.cs +++ b/Zennysoft.Game.Ma/src/items/weapons/Weapon.cs @@ -1,9 +1,7 @@ using Chickensoft.AutoInject; -using Chickensoft.GodotNodeInterfaces; using Chickensoft.Introspection; using Chickensoft.Serialization; using Godot; -using System; using Zennysoft.Ma.Adapter; using Zennysoft.Ma.Adapter.Entity; diff --git a/Zennysoft.Game.Ma/src/map/dungeon/floors/Special Floors/00. Altar.tscn b/Zennysoft.Game.Ma/src/map/dungeon/floors/Special Floors/00. Altar.tscn index 5904cff5..4c95facd 100644 --- a/Zennysoft.Game.Ma/src/map/dungeon/floors/Special Floors/00. Altar.tscn +++ b/Zennysoft.Game.Ma/src/map/dungeon/floors/Special Floors/00. Altar.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=18 format=3 uid="uid://dl6h1djc27ddl"] +[gd_scene load_steps=19 format=3 uid="uid://dl6h1djc27ddl"] [ext_resource type="Script" uid="uid://c1nhqlem1ew3m" path="res://src/map/dungeon/code/Altar.cs" id="1_5jip8"] [ext_resource type="Resource" uid="uid://bqnfw6r4085yv" path="res://src/dialog/Altar.dialogue" id="2_7xfp0"] [ext_resource type="PackedScene" uid="uid://co0fmuno2pjc7" path="res://src/map/dungeon/models/Special Floors & Rooms/Altar/02_ALTAR_FLOOR_ZER0_VER.1.glb" id="2_xpi6o"] +[ext_resource type="PackedScene" uid="uid://bdygmhgk4k0qh" path="res://src/items/box/BoxItem.tscn" id="6_rrmfo"] [ext_resource type="Shader" uid="uid://c4a68uhm5o2h4" path="res://src/map/map shaders/Altar Sky Environment.gdshader" id="27_lb4gb"] [ext_resource type="AudioStream" uid="uid://c4ud110da8efp" path="res://src/audio/AMB/amb_wind_loop_altar.wav" id="28_je2oh"] @@ -212,3 +213,5 @@ collision_mask = 64 [node name="CollisionShape3D" type="CollisionShape3D" parent="NoExitArea"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 72.5243, -2.06593, -2.02953) shape = SubResource("BoxShape3D_tp2pi") + +[node name="Box Item" parent="." instance=ExtResource("6_rrmfo")] diff --git a/Zennysoft.Game.Ma/src/player/Player.cs b/Zennysoft.Game.Ma/src/player/Player.cs index a53ffebb..a492f91a 100644 --- a/Zennysoft.Game.Ma/src/player/Player.cs +++ b/Zennysoft.Game.Ma/src/player/Player.cs @@ -94,6 +94,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide #endregion + public bool CanEquipState { get; set; } = true; private bool flipAttack = false; diff --git a/Zennysoft.Game.Ma/src/player/Player.tscn b/Zennysoft.Game.Ma/src/player/Player.tscn index 9991d769..2a7a8389 100644 --- a/Zennysoft.Game.Ma/src/player/Player.tscn +++ b/Zennysoft.Game.Ma/src/player/Player.tscn @@ -411,7 +411,7 @@ tracks/0/loop_wrap = true tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), -"update": 0, +"update": 1, "values": [&"default"] } tracks/1/type = "value" diff --git a/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.cs b/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.cs index d7caeda8..380172f2 100644 --- a/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.cs +++ b/Zennysoft.Game.Ma/src/ui/inventory_menu/InventoryMenu.cs @@ -62,144 +62,144 @@ public partial class InventoryMenu : Control, IInventoryMenu public override void _EnterTree() { - SetProcessInput(false); + SetProcessInput(false); + SetProcessUnhandledInput(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; - item.ItemEnterFocus += Item_FocusEntered; - item.ItemExitFocus += Item_ItemExitFocus; - } + 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; + item.ItemEnterFocus += Item_FocusEntered; + item.ItemExitFocus += Item_ItemExitFocus; + } - _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; + _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.Pressed += UseButtonPressed; + ThrowButton.Pressed += ThrowButtonPressed; + DropButton.Pressed += DropButtonPressed; - UseButton.FocusEntered += ActionButtonFocusChanged; - ThrowButton.FocusEntered += ActionButtonFocusChanged; - DropButton.FocusEntered += ActionButtonFocusChanged; + UseButton.FocusEntered += ActionButtonFocusChanged; + ThrowButton.FocusEntered += ActionButtonFocusChanged; + DropButton.FocusEntered += ActionButtonFocusChanged; - VisibilityChanged += InventoryMenu_VisibilityChanged; + VisibilityChanged += InventoryMenu_VisibilityChanged; } private void ActionButtonFocusChanged() { - if (!_enableMenuSound) - SfxDatabase.Instance.Play(SoundEffect.MoveUI); + 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.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.UiCancel) && (UseButton.HasFocus() || DropButton.HasFocus() || ThrowButton.HasFocus())) - { - 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); + if (!isChanged) + return; - if (Input.IsActionJustPressed(GameInputs.InventorySort)) - { - var isChanged = _player.Inventory.Sort(_player.EquipmentComponent.EquippedWeapon.Value, _player.EquipmentComponent.EquippedArmor.Value, _player.EquipmentComponent.EquippedAccessory.Value); - if (!isChanged) - return; - - SfxDatabase.Instance.Play(SoundEffect.SortInventory); - Inventory_InventoryChanged(); - foreach (var slot in ItemSlots) - slot.SetItemStyle(); - Item_ItemExitFocus(_currentlySelectedItem); - _currentlySelectedItem = ItemSlot1; - _currentlySelectedItem.GrabFocus(); - } + SfxDatabase.Instance.Play(SoundEffect.SortInventory); + Inventory_InventoryChanged(); + foreach (var slot in ItemSlots) + slot.SetItemStyle(); + Item_ItemExitFocus(_currentlySelectedItem); + _currentlySelectedItem = ItemSlot1; + _currentlySelectedItem.GrabFocus(); + } } private void InventoryMenu_VisibilityChanged() { - if (Visible) - { - SfxDatabase.Instance.Play(SoundEffect.OpenInventory); - _currentlySelectedItem.GrabFocus(); - _enableMenuSound = true; - } - else - { - SfxDatabase.Instance.Play(SoundEffect.CancelUI); - _enableMenuSound = false; - } + 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; - itemSlot.IsSelected = false; - itemSlot.SetItemStyle(); + ItemDescriptionTitle.Text = string.Empty; + ItemEffectLabel.Text = string.Empty; + itemSlot.IsSelected = false; + itemSlot.SetItemStyle(); } private void Item_FocusEntered(IItemSlot itemSlot) { - if (itemSlot.Item.Value == null) - return; + if (itemSlot.Item.Value == null) + return; - if (_enableMenuSound) - SfxDatabase.Instance.Play(SoundEffect.MoveUI); + if (_enableMenuSound) + SfxDatabase.Instance.Play(SoundEffect.MoveUI); - ItemDescriptionTitle.Text = $"{itemSlot.Item.Value.ItemName}"; - ItemEffectLabel.Text = $"{itemSlot.Item.Value.Description}"; - _currentlySelectedItem = itemSlot; - itemSlot.IsSelected = true; - itemSlot.SetItemStyle(); - AcceptEvent(); + ItemDescriptionTitle.Text = $"{itemSlot.Item.Value.ItemName}"; + ItemEffectLabel.Text = $"{itemSlot.Item.Value.Description}"; + _currentlySelectedItem = itemSlot; + itemSlot.IsSelected = true; + itemSlot.SetItemStyle(); + AcceptEvent(); } private void Item_Pressed(InventoryItem item) => DisplayUserActionPrompt(item); private async void Inventory_InventoryChanged() { - foreach (var slot in ItemSlots) - { - slot.Visible = false; - slot.SetItemStyle(); - } + foreach (var slot in ItemSlots) + { + slot.Visible = false; + slot.SetItemStyle(); + } - var itemsToDisplay = _player.Inventory.Items; - for (var i = 0; i < itemsToDisplay.Count; i++) - { - ItemSlots[i].Item.OnNext(itemsToDisplay[i]); - ItemSlots[i].Visible = true; - } + 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(); - } + 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}"; @@ -207,125 +207,128 @@ public partial class InventoryMenu : Control, IInventoryMenu private void EquipmentComponent_EquipmentChanged(EquipableItem equipableItem) { - ATKBonusLabel.Text = $"{_player.EquipmentComponent.BonusAttack:+0;-#;\\.\\.\\.}"; - DEFBonusLabel.Text = $"{_player.EquipmentComponent.BonusDefense:+0;-#;\\.\\.\\.}"; + 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 - await _game.UseItem(_currentlySelectedItem.Item.Value); - UseButton.Disabled = false; + UseButton.Disabled = true; + if (_currentlySelectedItem.Item.Value is EquipableItem equipable) + await EquipOrUnequipItem(equipable); + else if (_currentlySelectedItem.Item.Value is Plastique plastique) + SetItem(); + else + await _game.UseItem(_currentlySelectedItem.Item.Value); + UseButton.Disabled = false; - HideUserActionPrompt(); - await ShowInventoryInfo(); - await ToSignal(GetTree().CreateTimer(1f), "timeout"); + 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(); + _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(); + _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(); + _game.DropItem(_currentlySelectedItem.Item.Value); + _player.Inventory.Remove(_currentlySelectedItem.Item.Value); + HideUserActionPrompt(); + await ShowInventoryInfo(); } private void DisplayUserActionPrompt(InventoryItem item) { - SfxDatabase.Instance.Play(SoundEffect.SelectUI); - ItemDescriptionTitle.Hide(); - ItemEffectLabel.Hide(); - UseItemPrompt.Show(); - UseButton.Show(); - ThrowButton.Show(); - DropButton.Show(); + 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"; - ThrowButton.Disabled = isItemEquipped; - ThrowButton.FocusMode = isItemEquipped ? FocusModeEnum.None : FocusModeEnum.All; - DropButton.Disabled = isItemEquipped; - DropButton.FocusMode = isItemEquipped ? FocusModeEnum.None : FocusModeEnum.All; - } - else if (item is Plastique plastique) - { - UseButton.Text = "Set"; - } - else - { - UseButton.Text = "Use"; - } + if (item is EquipableItem equipable) + { + var isItemEquipped = _player.EquipmentComponent.IsItemEquipped(equipable); + UseButton.Text = isItemEquipped ? "Unequip" : "Equip"; + ThrowButton.Disabled = isItemEquipped; + ThrowButton.FocusMode = isItemEquipped ? FocusModeEnum.None : FocusModeEnum.All; + DropButton.Disabled = isItemEquipped; + DropButton.FocusMode = isItemEquipped ? FocusModeEnum.None : FocusModeEnum.All; - UseButton.GrabFocus(); - _enableMenuSound = false; + 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; + 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; - } + 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(); + ItemDescriptionTitle.Show(); + ItemEffectLabel.Show(); } private enum InventoryPageNumber { - FirstPage, - SecondPage + FirstPage, + SecondPage } } diff --git a/Zennysoft.Game.Ma/src/ui/pause_menu/PauseDebugMenu.cs b/Zennysoft.Game.Ma/src/ui/pause_menu/PauseDebugMenu.cs index f3c085b9..9f59ee77 100644 --- a/Zennysoft.Game.Ma/src/ui/pause_menu/PauseDebugMenu.cs +++ b/Zennysoft.Game.Ma/src/ui/pause_menu/PauseDebugMenu.cs @@ -101,7 +101,7 @@ public partial class PauseDebugMenu : Control, IDebugMenu { var enemyToSpawn = _spawnableEnemies.ElementAt((int)index); var loadedEnemy = GD.Load(enemyToSpawn).Instantiate(); - AddChild(loadedEnemy); + _game.AddChild(loadedEnemy); loadedEnemy.GlobalPosition = new Vector3(_player.GlobalPosition.X, _player.GlobalPosition.Y + 1, _player.GlobalPosition.Z) + (-_player.GlobalBasis.Z * 2); } @@ -109,7 +109,7 @@ public partial class PauseDebugMenu : Control, IDebugMenu { var itemToSpawn = _spawnableItems.ElementAt((int)index); var duplicated = itemToSpawn.Duplicate((int)DuplicateFlags.UseInstantiation) as Node3D; - AddChild(duplicated); + _game.AddChild(duplicated); duplicated.GlobalPosition = new Vector3(_player.GlobalPosition.X, _player.GlobalPosition.Y + 1, _player.GlobalPosition.Z) + (-_player.GlobalBasis.Z * 2); }