Add stackable items
This commit is contained in:
@@ -29,8 +29,8 @@ general/balloon_path="res://src/ui/dialogue/Balloon.tscn"
|
||||
|
||||
[display]
|
||||
|
||||
window/size/viewport_width=1280
|
||||
window/size/viewport_height=960
|
||||
window/size/viewport_width=1920
|
||||
window/size/viewport_height=1080
|
||||
|
||||
[dotnet]
|
||||
|
||||
|
||||
@@ -57,86 +57,86 @@ public partial class InGameAudio : Node
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
InGameAudioLogic = new InGameAudioLogic();
|
||||
InGameAudioLogic = new InGameAudioLogic();
|
||||
}
|
||||
|
||||
public void OnResolved()
|
||||
{
|
||||
InGameAudioLogic.Set(AppRepo);
|
||||
InGameAudioLogic.Set(GameEventDepot);
|
||||
InGameAudioLogic.Set(Player);
|
||||
InGameAudioLogic.Set(GameRepo);
|
||||
InGameAudioLogic.Set(AppRepo);
|
||||
InGameAudioLogic.Set(GameEventDepot);
|
||||
InGameAudioLogic.Set(Player);
|
||||
InGameAudioLogic.Set(GameRepo);
|
||||
|
||||
InGameAudioBinding = InGameAudioLogic.Bind();
|
||||
InGameAudioBinding = InGameAudioLogic.Bind();
|
||||
|
||||
InGameAudioBinding
|
||||
.Handle((in InGameAudioLogic.Output.PlayOverworldMusic _) => StartOverworldMusic())
|
||||
.Handle((in InGameAudioLogic.Output.PlayDungeonThemeAMusic _) => StartDungeonThemeA())
|
||||
.Handle((in InGameAudioLogic.Output.PlayMenuScrollSound _) => PlayMenuScrollSound())
|
||||
.Handle((in InGameAudioLogic.Output.PlayEquipSound _) => PlayEquipSound())
|
||||
.Handle((in InGameAudioLogic.Output.PlayMenuBackSound _) => PlayMenuBackSound())
|
||||
.Handle((in InGameAudioLogic.Output.PlayInventorySortedSound _) => PlayInventorySortedSound())
|
||||
.Handle((in InGameAudioLogic.Output.PlayHealingItemSound _) => PlayHealingItemSound())
|
||||
.Handle((in InGameAudioLogic.Output.PlayTeleportSound _) => PlayTeleportSound())
|
||||
.Handle((in InGameAudioLogic.Output.PlayPlayerAttackSound _) => { PlayerAttackSFX.Stop(); PlayerAttackSFX.Play(); })
|
||||
.Handle((in InGameAudioLogic.Output.PlayPlayerAttackWallSound _) => { PlayerAttackWallSFX.Stop(); PlayerAttackWallSFX.Play(); })
|
||||
.Handle((in InGameAudioLogic.Output.PlayPlayerAttackEnemySound _) => { PlayerAttackEnemySFX.Stop(); PlayerAttackEnemySFX.Play(); });
|
||||
InGameAudioBinding
|
||||
.Handle((in InGameAudioLogic.Output.PlayOverworldMusic _) => StartOverworldMusic())
|
||||
.Handle((in InGameAudioLogic.Output.PlayDungeonThemeAMusic _) => StartDungeonThemeA())
|
||||
.Handle((in InGameAudioLogic.Output.PlayMenuScrollSound _) => PlayMenuScrollSound())
|
||||
.Handle((in InGameAudioLogic.Output.PlayEquipSound _) => PlayEquipSound())
|
||||
.Handle((in InGameAudioLogic.Output.PlayMenuBackSound _) => PlayMenuBackSound())
|
||||
.Handle((in InGameAudioLogic.Output.PlayInventorySortedSound _) => PlayInventorySortedSound())
|
||||
.Handle((in InGameAudioLogic.Output.PlayHealingItemSound _) => PlayHealingItemSound())
|
||||
.Handle((in InGameAudioLogic.Output.PlayTeleportSound _) => PlayTeleportSound())
|
||||
.Handle((in InGameAudioLogic.Output.PlayPlayerAttackSound _) => { PlayerAttackSFX.Stop(); PlayerAttackSFX.Play(); })
|
||||
.Handle((in InGameAudioLogic.Output.PlayPlayerAttackWallSound _) => { PlayerAttackWallSFX.Stop(); PlayerAttackWallSFX.Play(); })
|
||||
.Handle((in InGameAudioLogic.Output.PlayPlayerAttackEnemySound _) => { PlayerAttackEnemySFX.Stop(); PlayerAttackEnemySFX.Play(); });
|
||||
|
||||
InGameAudioLogic.Start();
|
||||
InGameAudioLogic.Start();
|
||||
}
|
||||
|
||||
public void OnExitTree()
|
||||
{
|
||||
InGameAudioLogic.Stop();
|
||||
InGameAudioBinding.Dispose();
|
||||
InGameAudioLogic.Stop();
|
||||
InGameAudioBinding.Dispose();
|
||||
}
|
||||
|
||||
private void StartOverworldMusic()
|
||||
{
|
||||
OverworldBgm.Stop();
|
||||
OverworldBgm.FadeIn();
|
||||
OverworldBgm.Stop();
|
||||
OverworldBgm.FadeIn();
|
||||
}
|
||||
|
||||
private void StartDungeonThemeA()
|
||||
{
|
||||
OverworldBgm.FadeOut();
|
||||
DungeonThemeABgm.Stop();
|
||||
DungeonThemeABgm.FadeIn();
|
||||
OverworldBgm.FadeOut();
|
||||
DungeonThemeABgm.Stop();
|
||||
DungeonThemeABgm.FadeIn();
|
||||
}
|
||||
|
||||
private void PlayMenuScrollSound()
|
||||
{
|
||||
MenuScrollSFX.Stop();
|
||||
MenuScrollSFX.Play();
|
||||
MenuScrollSFX.Stop();
|
||||
MenuScrollSFX.Play();
|
||||
}
|
||||
|
||||
private void PlayEquipSound()
|
||||
{
|
||||
EquipSFX.Stop();
|
||||
EquipSFX.Play();
|
||||
EquipSFX.Stop();
|
||||
EquipSFX.Play();
|
||||
}
|
||||
|
||||
private void PlayMenuBackSound()
|
||||
{
|
||||
MenuBackSFX.Stop();
|
||||
MenuBackSFX.Play();
|
||||
MenuBackSFX.Stop();
|
||||
MenuBackSFX.Play();
|
||||
}
|
||||
|
||||
private void PlayInventorySortedSound()
|
||||
{
|
||||
InventorySortedSFX.Stop();
|
||||
InventorySortedSFX.Play();
|
||||
InventorySortedSFX.Stop();
|
||||
InventorySortedSFX.Play();
|
||||
}
|
||||
|
||||
private void PlayHealingItemSound()
|
||||
{
|
||||
HealingItemSFX.Stop();
|
||||
HealingItemSFX.Play();
|
||||
HealingItemSFX.Stop();
|
||||
HealingItemSFX.Play();
|
||||
}
|
||||
|
||||
private void PlayTeleportSound()
|
||||
{
|
||||
TeleportSFX.Stop();
|
||||
TeleportSFX.Play();
|
||||
TeleportSFX.Stop();
|
||||
TeleportSFX.Play();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=15 format=3 uid="uid://b16ejcwanod72"]
|
||||
[gd_scene load_steps=16 format=3 uid="uid://b16ejcwanod72"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://2mnouyn1jcqs" path="res://src/audio/InGameAudio.cs" id="1_gpmcr"]
|
||||
[ext_resource type="AudioStream" uid="uid://dfu0fksb6slhx" path="res://src/audio/music/droney.mp3" id="2_8hfyr"]
|
||||
@@ -11,6 +11,7 @@
|
||||
[ext_resource type="AudioStream" uid="uid://d1mlduwauechv" path="res://src/audio/sfx/PlayerAttackSFX.wav" id="7_wtvpb"]
|
||||
[ext_resource type="AudioStream" uid="uid://r1tryiit38i8" path="res://src/audio/sfx/MenuBackSFX.ogg" id="8_1xcgo"]
|
||||
[ext_resource type="AudioStream" uid="uid://bjj61s8q2gwb8" path="res://src/audio/sfx/EquipSFX.ogg" id="8_kwybb"]
|
||||
[ext_resource type="AudioStream" uid="uid://4u8f1tpgs08b" path="res://src/audio/sfx/PlayerHitEnemySFX.wav" id="9_hertr"]
|
||||
[ext_resource type="AudioStream" uid="uid://myx4s8lmarc2" path="res://src/audio/sfx/HealSFX.ogg" id="10_3lcw5"]
|
||||
[ext_resource type="AudioStream" uid="uid://dci08kmwsu6k1" path="res://src/audio/sfx/ExitSFX.ogg" id="11_offhc"]
|
||||
[ext_resource type="AudioStream" uid="uid://d3sn7c614uj2n" path="res://src/audio/sfx/SortSFX.ogg" id="12_wprjr"]
|
||||
@@ -70,6 +71,11 @@ unique_name_in_owner = true
|
||||
stream = ExtResource("7_8vh2f")
|
||||
volume_db = -5.0
|
||||
|
||||
[node name="PlayerAttackEnemySFX" type="AudioStreamPlayer" parent="SFX"]
|
||||
unique_name_in_owner = true
|
||||
stream = ExtResource("9_hertr")
|
||||
volume_db = -5.0
|
||||
|
||||
[node name="MenuScrollSFX" type="AudioStreamPlayer" parent="SFX"]
|
||||
unique_name_in_owner = true
|
||||
stream = ExtResource("7_777nl")
|
||||
|
||||
BIN
Zennysoft.Game.Ma/src/audio/sfx/PlayerHitEnemySFX.wav
Normal file
BIN
Zennysoft.Game.Ma/src/audio/sfx/PlayerHitEnemySFX.wav
Normal file
Binary file not shown.
24
Zennysoft.Game.Ma/src/audio/sfx/PlayerHitEnemySFX.wav.import
Normal file
24
Zennysoft.Game.Ma/src/audio/sfx/PlayerHitEnemySFX.wav.import
Normal file
@@ -0,0 +1,24 @@
|
||||
[remap]
|
||||
|
||||
importer="wav"
|
||||
type="AudioStreamWAV"
|
||||
uid="uid://4u8f1tpgs08b"
|
||||
path="res://.godot/imported/PlayerHitEnemySFX.wav-7235df5e0b579a1c2793d138bb462425.sample"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://src/audio/sfx/PlayerHitEnemySFX.wav"
|
||||
dest_files=["res://.godot/imported/PlayerHitEnemySFX.wav-7235df5e0b579a1c2793d138bb462425.sample"]
|
||||
|
||||
[params]
|
||||
|
||||
force/8_bit=false
|
||||
force/mono=false
|
||||
force/max_rate=false
|
||||
force/max_rate_hz=44100
|
||||
edit/trim=false
|
||||
edit/normalize=false
|
||||
edit/loop_mode=0
|
||||
edit/loop_begin=0
|
||||
edit/loop_end=-1
|
||||
compress/mode=2
|
||||
@@ -320,8 +320,12 @@ public partial class Game : Node3D, IGame
|
||||
Player.HealVT(throwableItem.HealVTAmount);
|
||||
}
|
||||
|
||||
await ToSignal(GetTree().CreateTimer(1f), "timeout");
|
||||
GameRepo.RemoveItemFromInventory(item);
|
||||
await ToSignal(GetTree().CreateTimer(0.3f), "timeout");
|
||||
|
||||
if (item is IStackable stackableItem && stackableItem.Count > 1)
|
||||
stackableItem.SetCount(stackableItem.Count - 1);
|
||||
else
|
||||
GameRepo.RemoveItemFromInventory(item);
|
||||
}
|
||||
|
||||
public void DropItem(InventoryItem item)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
[gd_resource type="LabelSettings" load_steps=2 format=3 uid="uid://bl5xpqyq8vjtv"]
|
||||
|
||||
[sub_resource type="SystemFont" id="SystemFont_1ibjc"]
|
||||
[ext_resource type="FontFile" uid="uid://dit3vylt7hmmx" path="res://src/ui/fonts/FT88-Regular.ttf" id="1_1lnq2"]
|
||||
|
||||
[resource]
|
||||
font = SubResource("SystemFont_1ibjc")
|
||||
font = ExtResource("1_1lnq2")
|
||||
font_size = 30
|
||||
|
||||
@@ -2,6 +2,7 @@ using Chickensoft.AutoInject;
|
||||
using Chickensoft.GodotNodeInterfaces;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using Zennysoft.Game.Abstractions;
|
||||
using Zennysoft.Ma.Adapter;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
@@ -32,6 +33,8 @@ public partial class ItemSlot : HBoxContainer, IItemSlot
|
||||
|
||||
[Node] public Label ItemName { get; set; } = default!;
|
||||
|
||||
[Node] public Label ItemCount { get; set; } = default!;
|
||||
|
||||
private static LabelSettings ItemFont => GD.Load<LabelSettings>("res://src/ui/label_settings/MainTextRegular.tres");
|
||||
private static LabelSettings SelectedItemFont => GD.Load<LabelSettings>("res://src/ui/label_settings/MainTextFontItalicized.tres");
|
||||
private static LabelSettings EquippedItemFont => GD.Load<LabelSettings>("res://src/ui/label_settings/MainTextFontEquipped.tres");
|
||||
@@ -45,6 +48,12 @@ public partial class ItemSlot : HBoxContainer, IItemSlot
|
||||
Player.EquippedWeapon.Sync += EquipableItem_Sync;
|
||||
Player.EquippedArmor.Sync += EquipableItem_Sync;
|
||||
Player.EquippedAccessory.Sync += EquipableItem_Sync;
|
||||
|
||||
if (Item is IStackable stackableItem)
|
||||
{
|
||||
ItemCount.Text = $"{stackableItem.Count:D2}";
|
||||
ItemCount.Visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void EquipableItem_Sync(EquipableItem obj)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
[gd_scene load_steps=6 format=3 uid="uid://c005nd0m2eim"]
|
||||
[gd_scene load_steps=7 format=3 uid="uid://c005nd0m2eim"]
|
||||
|
||||
[ext_resource type="Script" path="res://src/inventory_menu/ItemSlot.cs" id="1_yttxt"]
|
||||
[ext_resource type="Script" uid="uid://cglxk7v8hpesn" path="res://src/inventory_menu/ItemSlot.cs" id="1_yttxt"]
|
||||
[ext_resource type="Texture2D" uid="uid://0r1dws4ajhdx" path="res://src/items/accessory/textures/MASK 01.PNG" id="2_7kdbd"]
|
||||
[ext_resource type="Script" path="res://src/inventory_menu/ItemLabel.cs" id="3_xlgl0"]
|
||||
[ext_resource type="Script" uid="uid://b0rrpkpsfdga8" path="res://src/inventory_menu/ItemLabel.cs" id="3_xlgl0"]
|
||||
[ext_resource type="FontFile" uid="uid://bohbd123672ea" path="res://src/ui/fonts/FT88-Italic.ttf" id="4_vcxwm"]
|
||||
[ext_resource type="LabelSettings" uid="uid://bl5xpqyq8vjtv" path="res://src/inventory_menu/InventoryLabelSettings.tres" id="5_a7hko"]
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_lgjx0"]
|
||||
font = ExtResource("4_vcxwm")
|
||||
@@ -39,3 +40,10 @@ label_settings = SubResource("LabelSettings_lgjx0")
|
||||
vertical_alignment = 1
|
||||
autowrap_mode = 2
|
||||
script = ExtResource("3_xlgl0")
|
||||
|
||||
[node name="ItemCount" type="Label" parent="."]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
text = "x99"
|
||||
label_settings = ExtResource("5_a7hko")
|
||||
|
||||
@@ -4,6 +4,7 @@ using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Zennysoft.Game.Abstractions;
|
||||
using Zennysoft.Ma.Adapter;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
@@ -52,6 +53,16 @@ public partial class Inventory : Node, IInventory
|
||||
var consumables = listToSort.Where(x => x is ConsumableItem).OrderBy(x => x as ConsumableItem, new ConsumableComparer());
|
||||
var throwables = listToSort.Where(x => x is ThrowableItem).OrderBy(x => x as ThrowableItem, new ThrowableComparer());
|
||||
Items = [.. equippedItems, .. weapons, .. armor, .. accessories, .. consumables, .. throwables];
|
||||
|
||||
var stackableItems = Items.OfType<IStackable>();
|
||||
var itemsToStack = stackableItems.GroupBy(x => ((InventoryItem)x).ItemName).Where(x => x.Count() > 1);
|
||||
foreach (var itemStack in itemsToStack)
|
||||
{
|
||||
var firstItem = itemStack.First();
|
||||
firstItem.SetCount(itemStack.Count());
|
||||
var itemsToRemove = itemStack.Except([firstItem]).Cast<InventoryItem>();
|
||||
Items = [.. Items.Except(itemsToRemove)];
|
||||
}
|
||||
}
|
||||
|
||||
public class WeaponComparer : IComparer<Weapon>
|
||||
|
||||
@@ -35,5 +35,6 @@ public partial class EffectItem : InventoryItem
|
||||
[Export]
|
||||
[Save("effect_item_stats")]
|
||||
public EffectItemStats Stats { get; set; } = new EffectItemStats();
|
||||
|
||||
public override Texture2D GetTexture() => Stats.Texture;
|
||||
}
|
||||
|
||||
@@ -2,12 +2,13 @@ using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
using Zennysoft.Game.Abstractions;
|
||||
using Zennysoft.Ma.Adapter;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
[Meta(typeof(IAutoNode)), Id("throwable_item")]
|
||||
public partial class ThrowableItem : InventoryItem
|
||||
public partial class ThrowableItem : InventoryItem, IStackable
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
@@ -40,10 +41,14 @@ public partial class ThrowableItem : InventoryItem
|
||||
|
||||
public void SetDescription(string description) => Stats.Description = description;
|
||||
|
||||
public int Count { get; }
|
||||
[Save("throwable_item_count")]
|
||||
public int Count { get; private set; } = 1;
|
||||
|
||||
[Export]
|
||||
[Save("throwable_item_stats")]
|
||||
public ThrowableItemStats Stats { get; set; }
|
||||
|
||||
public override Texture2D GetTexture() => Stats.Texture;
|
||||
|
||||
public void SetCount(int count) => Count = count;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using System.Collections.Immutable;
|
||||
@@ -22,9 +22,9 @@ public partial class Floor0 : Node3D, IDungeonFloor
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
Show();
|
||||
Exit.AreaEntered += Exit_AreaEntered;
|
||||
FloorIsLoaded = true;
|
||||
Show();
|
||||
Exit.AreaEntered += Exit_AreaEntered;
|
||||
FloorIsLoaded = true;
|
||||
}
|
||||
|
||||
private void Exit_AreaEntered(Area3D area) => ExitReached();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=63 format=4 uid="uid://dl6h1djc27ddl"]
|
||||
[gd_scene load_steps=64 format=4 uid="uid://dl6h1djc27ddl"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c1nhqlem1ew3m" path="res://src/map/dungeon/code/Floor0.cs" id="1_db2o3"]
|
||||
[ext_resource type="Texture2D" uid="uid://b27ksiyfefb33" path="res://src/map/dungeon/models/Set A/02. Altar/02_ALTAR_FLOOR_ZER0_VER_outside_desert.png" id="2_xh2ej"]
|
||||
@@ -17,6 +17,7 @@
|
||||
[ext_resource type="Texture2D" uid="uid://cururtxtgylxf" path="res://src/map/dungeon/models/Set A/02. Altar/02_ALTAR_FLOOR_ZER0_VER_COLUMN.jpg" id="15_ojbcg"]
|
||||
[ext_resource type="PackedScene" uid="uid://1fl6s352e2ej" path="res://src/items/throwable/ThrowableItem.tscn" id="16_db2o3"]
|
||||
[ext_resource type="Resource" uid="uid://qqg0gdcb8fwg" path="res://src/items/throwable/resources/SpellSignKnowledge.tres" id="17_ntxe5"]
|
||||
[ext_resource type="Resource" uid="uid://bph8c6by4s047" path="res://src/items/throwable/resources/GeomanticDice.tres" id="18_ntxe5"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_3ubi4"]
|
||||
shading_mode = 0
|
||||
@@ -902,3 +903,19 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.00384, 1.80761, 11.3571)
|
||||
[node name="ThrowableItem" parent="." instance=ExtResource("16_db2o3")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.78811, -3.32789, 0)
|
||||
Stats = ExtResource("17_ntxe5")
|
||||
|
||||
[node name="ThrowableItem2" parent="." instance=ExtResource("16_db2o3")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.78811, -3.32789, 0)
|
||||
Stats = ExtResource("17_ntxe5")
|
||||
|
||||
[node name="ThrowableItem3" parent="." instance=ExtResource("16_db2o3")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.78811, -3.32789, 0)
|
||||
Stats = ExtResource("17_ntxe5")
|
||||
|
||||
[node name="ThrowableItem4" parent="." instance=ExtResource("16_db2o3")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.78811, -3.32789, 0)
|
||||
Stats = ExtResource("17_ntxe5")
|
||||
|
||||
[node name="DifferentThrowable" parent="." instance=ExtResource("16_db2o3")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.2442, -2.60258, -2.96088)
|
||||
Stats = ExtResource("18_ntxe5")
|
||||
|
||||
Reference in New Issue
Block a user