Massive refactor (inventory menu still a little broken but its Good Enough)

This commit is contained in:
2024-09-12 02:24:14 -07:00
parent 149c8d9571
commit b4662a0c7b
94 changed files with 1066 additions and 825 deletions

View File

@@ -1,37 +1,37 @@
<Project Sdk="Godot.NET.Sdk/4.4.0-dev.2"> <Project Sdk="Godot.NET.Sdk/4.4.0-dev.1">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net8.0</TargetFramework> <TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net8.0</TargetFramework>
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'ios' ">net8.0</TargetFramework> <TargetFramework Condition=" '$(GodotTargetPlatform)' == 'ios' ">net8.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading> <EnableDynamicLoading>true</EnableDynamicLoading>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Chickensoft.AutoInject" Version="2.3.0" /> <PackageReference Include="Chickensoft.AutoInject" Version="2.3.0" />
<PackageReference Include="Chickensoft.GodotNodeInterfaces" Version="2.2.23" /> <PackageReference Include="Chickensoft.GodotNodeInterfaces" Version="2.2.23" />
<PackageReference Include="Chickensoft.Introspection.Generator" Version="1.7.0" /> <PackageReference Include="Chickensoft.Introspection.Generator" Version="1.7.0" />
<PackageReference Include="Chickensoft.LogicBlocks" Version="5.6.0" /> <PackageReference Include="Chickensoft.LogicBlocks" Version="5.6.0" />
<PackageReference Include="Chickensoft.LogicBlocks.DiagramGenerator" Version="5.6.0" /> <PackageReference Include="Chickensoft.LogicBlocks.DiagramGenerator" Version="5.6.0" />
<PackageReference Include="Chickensoft.SaveFileBuilder" Version="1.1.0" /> <PackageReference Include="Chickensoft.SaveFileBuilder" Version="1.1.0" />
<PackageReference Include="GodotSharp.SourceGenerators" Version="2.4.0" /> <PackageReference Include="GodotSharp.SourceGenerators" Version="2.4.0" />
<PackageReference Include="SSH.NET" Version="2024.1.0" /> <PackageReference Include="SSH.NET" Version="2024.1.0" />
<PackageReference Include="System.IO.Abstractions" Version="21.0.29" /> <PackageReference Include="System.IO.Abstractions" Version="21.0.29" />
<PackageReference Include="Zeroconf" Version="3.6.11" /> <PackageReference Include="Zeroconf" Version="3.6.11" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="src\items\weapons\models\" /> <Folder Include="src\items\weapons\models\" />
<Folder Include="src\map\dungeon\corridor\" /> <Folder Include="src\map\dungeon\corridor\" />
<Folder Include="src\ui\dialogue\" /> <Folder Include="src\ui\dialogue\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include=".editorconfig" /> <None Include=".editorconfig" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Update="Godot.SourceGenerators" Version="4.4.0-dev.2" /> <PackageReference Update="Godot.SourceGenerators" Version="4.4.0-dev.2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Update="GodotSharp" Version="4.4.0-dev.2" /> <PackageReference Update="GodotSharp" Version="4.4.0-dev.2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Update="GodotSharpEditor" Version="4.4.0-dev.2" /> <PackageReference Update="GodotSharpEditor" Version="4.4.0-dev.2" />
</ItemGroup> </ItemGroup>
</Project> </Project>

37
GameJamDungeon.csproj.old Normal file
View File

@@ -0,0 +1,37 @@
<Project Sdk="Godot.NET.Sdk/4.4.0-dev.2">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net8.0</TargetFramework>
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'ios' ">net8.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Chickensoft.AutoInject" Version="2.3.0" />
<PackageReference Include="Chickensoft.GodotNodeInterfaces" Version="2.2.23" />
<PackageReference Include="Chickensoft.Introspection.Generator" Version="1.7.0" />
<PackageReference Include="Chickensoft.LogicBlocks" Version="5.6.0" />
<PackageReference Include="Chickensoft.LogicBlocks.DiagramGenerator" Version="5.6.0" />
<PackageReference Include="Chickensoft.SaveFileBuilder" Version="1.1.0" />
<PackageReference Include="GodotSharp.SourceGenerators" Version="2.4.0" />
<PackageReference Include="SSH.NET" Version="2024.1.0" />
<PackageReference Include="System.IO.Abstractions" Version="21.0.29" />
<PackageReference Include="Zeroconf" Version="3.6.11" />
</ItemGroup>
<ItemGroup>
<Folder Include="src\items\weapons\models\" />
<Folder Include="src\map\dungeon\corridor\" />
<Folder Include="src\ui\dialogue\" />
</ItemGroup>
<ItemGroup>
<None Include=".editorconfig" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="Godot.SourceGenerators" Version="4.4.0-dev.2" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="GodotSharp" Version="4.4.0-dev.2" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="GodotSharpEditor" Version="4.4.0-dev.2" />
</ItemGroup>
</Project>

View File

@@ -4,8 +4,6 @@ extends Node3D
signal dungeon_done_generating() signal dungeon_done_generating()
var room = %Room;
var dungeon_generator : DungeonGenerator3D : var dungeon_generator : DungeonGenerator3D :
get: get:
if is_inside_tree() and get_parent() is DungeonGenerator3D: if is_inside_tree() and get_parent() is DungeonGenerator3D:

View File

@@ -176,9 +176,7 @@ StrafeRight={
} }
Pause={ Pause={
"deadzone": 0.5, "deadzone": 0.5,
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":6,"pressure":0.0,"pressed":false,"script":null) "events": []
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
} }
[internationalization] [internationalization]

View File

@@ -2,6 +2,7 @@ using Chickensoft.AutoInject;
using Chickensoft.Collections; using Chickensoft.Collections;
using Chickensoft.GodotNodeInterfaces; using Chickensoft.GodotNodeInterfaces;
using Chickensoft.Introspection; using Chickensoft.Introspection;
using Chickensoft.LogicBlocks;
using Godot; using Godot;
using System; using System;
using System.Linq; using System.Linq;
@@ -14,7 +15,7 @@ public interface IEnemy : ICharacterBody3D
public AutoProp<double> CurrentHP { get; set; } public AutoProp<double> CurrentHP { get; set; }
public EnemyStatInfo EnemyStatInfo { get; set; } public EnemyStatResource EnemyStatResource { get; set; }
public NavigationAgent3D NavAgent { get; set; } public NavigationAgent3D NavAgent { get; set; }
@@ -39,7 +40,7 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
[Dependency] IGameRepo GameRepo => this.DependOn<IGameRepo>(); [Dependency] IGameRepo GameRepo => this.DependOn<IGameRepo>();
[Export] [Export]
public EnemyStatInfo EnemyStatInfo { get; set; } = default!; public EnemyStatResource EnemyStatResource { get; set; } = default!;
public static PackedScene CollisionDetectorScene => GD.Load<PackedScene>("res://src/enemy/CollisionDetector.tscn"); public static PackedScene CollisionDetectorScene => GD.Load<PackedScene>("res://src/enemy/CollisionDetector.tscn");
@@ -62,14 +63,14 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
public void Setup() public void Setup()
{ {
EnemyLogic = new EnemyLogic(); EnemyLogic = new EnemyLogic();
EnemyLogic.Set(EnemyStatInfo); EnemyLogic.Set(EnemyStatResource);
EnemyLogic.Set(this as IEnemy); EnemyLogic.Set(this as IEnemy);
EnemyLogic.Set(GameRepo); EnemyLogic.Set(GameRepo);
} }
public void Initialize() public void Initialize()
{ {
CurrentHP = new AutoProp<double>(EnemyStatInfo.MaximumHP); CurrentHP = new AutoProp<double>(EnemyStatResource.MaximumHP);
CurrentHP.Sync += OnHPChanged; CurrentHP.Sync += OnHPChanged;
LineOfSight.BodyEntered += LineOfSight_BodyEntered; LineOfSight.BodyEntered += LineOfSight_BodyEntered;
PatrolTimer.Timeout += OnPatrolTimeout; PatrolTimer.Timeout += OnPatrolTimeout;
@@ -138,8 +139,8 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
}) })
.Handle((in EnemyLogic.Output.HitByPlayer output) => .Handle((in EnemyLogic.Output.HitByPlayer output) =>
{ {
if (GameRepo.EquippedWeapon.Value.WeaponInfo.WeaponTags.Contains(WeaponTag.SelfDamage)) if (GameRepo.PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.WeaponTags.Contains(WeaponTag.SelfDamage))
GameRepo.PlayerStatInfo.Value.CurrentHP -= 5; GameRepo.PlayerData.CurrentHP.OnNext(GameRepo.PlayerData.CurrentHP.Value - 5);
}); });
this.Provide(); this.Provide();
@@ -182,9 +183,9 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
var rng = new RandomNumberGenerator(); var rng = new RandomNumberGenerator();
rng.Randomize(); rng.Randomize();
var roll = rng.Randf(); var roll = rng.Randf();
if (roll <= GameRepo.EquippedWeapon.Value.WeaponInfo.Luck) if (roll <= GameRepo.PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.Luck)
isCriticalHit = true; isCriticalHit = true;
var damage = DamageCalculator.CalculatePlayerDamage(hitBox.GetParent<IPlayer>().PlayerStatInfo, EnemyStatInfo, GameRepo.EquippedWeapon.Value.WeaponInfo, isCriticalHit); var damage = DamageCalculator.CalculatePlayerDamage(GameRepo.PlayerData.CurrentAttack.Value + GameRepo.PlayerData.BonusAttack.Value, EnemyStatResource, GameRepo.PlayerData.Inventory.EquippedWeapon.Value.WeaponStats, isCriticalHit);
GD.Print($"Enemy Hit for {damage} damage."); GD.Print($"Enemy Hit for {damage} damage.");
EnemyLogic.Input(new EnemyLogic.Input.HitByPlayer(damage)); EnemyLogic.Input(new EnemyLogic.Input.HitByPlayer(damage));
} }

View File

@@ -3,7 +3,7 @@
namespace GameJamDungeon namespace GameJamDungeon
{ {
[GlobalClass] [GlobalClass]
public partial class EnemyStatInfo : Resource, ICharacterStats public partial class EnemyStatResource : Resource
{ {
[Export] [Export]
public double CurrentHP { get; set; } public double CurrentHP { get; set; }

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="EnemyStatInfo" load_steps=2 format=3 uid="uid://c08wbuumw6dk5"] [gd_resource type="Resource" script_class="EnemyStatInfo" load_steps=2 format=3 uid="uid://c08wbuumw6dk5"]
[ext_resource type="Script" path="res://src/enemy/EnemyStatInfo.cs" id="1_2i74g"] [ext_resource type="Script" path="res://src/enemy/EnemyStatResource.cs" id="1_2i74g"]
[resource] [resource]
script = ExtResource("1_2i74g") script = ExtResource("1_2i74g")

View File

@@ -1,9 +1,29 @@
[gd_scene load_steps=15 format=4 uid="uid://dcgj5i52i76gj"] [gd_scene load_steps=16 format=4 uid="uid://dcgj5i52i76gj"]
[ext_resource type="Script" path="res://src/enemy/Enemy.cs" id="1_jw471"] [ext_resource type="Script" path="res://src/enemy/Enemy.cs" id="1_jw471"]
[ext_resource type="Resource" uid="uid://c08wbuumw6dk5" path="res://src/enemy/enemy_types/floating_enemy/FloatingEnemy.tres" id="2_b8sx5"] [ext_resource type="Script" path="res://src/enemy/EnemyStatResource.cs" id="2_wlf85"]
[ext_resource type="Script" path="res://src/hitbox/Hitbox.cs" id="3_erpyl"] [ext_resource type="Script" path="res://src/hitbox/Hitbox.cs" id="3_erpyl"]
[sub_resource type="Resource" id="Resource_rxw8v"]
script = ExtResource("2_wlf85")
CurrentHP = 45.0
MaximumHP = 45.0
CurrentAttack = 3
CurrentDefense = 2
MaxAttack = 3
MaxDefense = 2
Luck = 0.05
TelluricResistance = 0.0
AeolicResistance = 0.0
HydricResistance = 0.0
IgneousResistance = 0.0
FerrumResistance = 0.0
TelluricDamageBonus = 0.0
AeolicDamageBonus = 0.0
BaseHydricDamageBonus = 0.0
IgneousDamageBonus = 0.0
FerrumDamageBonus = 0.0
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_5tio6"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_5tio6"]
resource_name = "Material.001" resource_name = "Material.001"
cull_mode = 2 cull_mode = 2
@@ -155,7 +175,7 @@ collision_layer = 10
collision_mask = 9 collision_mask = 9
axis_lock_linear_y = true axis_lock_linear_y = true
script = ExtResource("1_jw471") script = ExtResource("1_jw471")
EnemyStatInfo = ExtResource("2_b8sx5") EnemyStatResource = SubResource("Resource_rxw8v")
[node name="DISSAPPEARING ENEMY" type="Node3D" parent="."] [node name="DISSAPPEARING ENEMY" type="Node3D" parent="."]

File diff suppressed because one or more lines are too long

View File

@@ -1,35 +0,0 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://cx042gptg5aew"
valid=false
[deps]
source_file="res://src/enemy/enemy_types/floating_enemy/Overworld.gltf"
[params]
nodes/root_type=""
nodes/root_name=""
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
_subresources={}
gltf/naming_version=1
gltf/embedded_image_handling=1

View File

@@ -4,15 +4,10 @@ namespace GameJamDungeon;
using Chickensoft.AutoInject; using Chickensoft.AutoInject;
using Chickensoft.GodotNodeInterfaces; using Chickensoft.GodotNodeInterfaces;
using Chickensoft.Introspection; using Chickensoft.Introspection;
using DialogueManagerRuntime;
using Godot; using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
public interface IGame : IProvide<IGameRepo>, IProvide<IGame>, INode3D public interface IGame : IProvide<IGameRepo>, IProvide<IGame>, INode3D
{ {
public void ToggleInventory();
} }
[Meta(typeof(IAutoNode))] [Meta(typeof(IAutoNode))]
@@ -34,17 +29,17 @@ public partial class Game : Node3D, IGame
[Dependency] public IAppRepo AppRepo => this.DependOn<IAppRepo>(); [Dependency] public IAppRepo AppRepo => this.DependOn<IAppRepo>();
#region Nodes
[Node] public IMap Map { get; set; } = default!; [Node] public IMap Map { get; set; } = default!;
[Node] public DialogueController DialogueController { get; set; } = default!; [Node] public InGameUI InGameUI { get; set; } = default!;
[Node] public IPauseMenu PauseMenu { get; set; } = default!;
[Node] public FloorClearMenu FloorClearMenu { get; set; } = default!; [Node] public FloorClearMenu FloorClearMenu { get; set; } = default!;
[Node] public DeathMenu DeathMenu { get; set; } = default!; [Node] public DeathMenu DeathMenu { get; set; } = default!;
[Node] public InGameUI InGameUI { get; set; } = default!; [Node] public IPauseMenu PauseMenu { get; set; } = default!;
#endregion
public void Setup() public void Setup()
{ {
@@ -53,9 +48,30 @@ public partial class Game : Node3D, IGame
GameLogic.Set(GameRepo); GameLogic.Set(GameRepo);
GameLogic.Set(AppRepo); GameLogic.Set(AppRepo);
Instantiator = new Instantiator(GetTree()); Instantiator = new Instantiator(GetTree());
}
FloorClearMenu.TransitionCompleted += OnFloorClearTransitionCompleted; private void PlayerInventory_InventoryAtCapacity(string rejectedItem)
PauseMenu.TransitionCompleted += OnPauseMenuTransitioned; {
InGameUI.PlayerInfoUI.DisplayInventoryFullMessage(rejectedItem);
}
private void OnInventoryAtCapacity(string rejectedItemName) => InGameUI.PlayerInfoUI.DisplayInventoryFullMessage(rejectedItemName);
private void InventoryMenu_CloseInventory() => GameLogic.Input(new GameLogic.Input.InventoryMenuToggle());
private void Map_DungeonFinishedGenerating()
{
GameRepo.SetPlayerGlobalPosition(Map.GetPlayerSpawnPoint());
}
private void Map_DialogueChoiceMade()
{
GameRepo.Resume();
}
private void Map_TeleportReached()
{
GameRepo.Pause();
} }
private void OnFloorClearTransitionCompleted() private void OnFloorClearTransitionCompleted()
@@ -68,12 +84,6 @@ public partial class Game : Node3D, IGame
GameLogic.Input(new GameLogic.Input.PauseMenuTransitioned()); GameLogic.Input(new GameLogic.Input.PauseMenuTransitioned());
} }
public void Exit()
{
GameLogic.Input(new GameLogic.Input.LoadNextFloor());
GameRepo.Resume();
}
public void OnResolved() public void OnResolved()
{ {
GameBinding = GameLogic.Bind(); GameBinding = GameLogic.Bind();
@@ -92,6 +102,7 @@ public partial class Game : Node3D, IGame
.Handle((in GameLogic.Output.HidePauseMenu _) => { PauseMenu.Hide(); }) .Handle((in GameLogic.Output.HidePauseMenu _) => { PauseMenu.Hide(); })
.Handle((in GameLogic.Output.ExitPauseMenu _) => { PauseMenu.FadeOut(); }) .Handle((in GameLogic.Output.ExitPauseMenu _) => { PauseMenu.FadeOut(); })
.Handle((in GameLogic.Output.ShowFloorClearMenu _) => { FloorClearMenu.Show(); FloorClearMenu.FadeIn(); }) .Handle((in GameLogic.Output.ShowFloorClearMenu _) => { FloorClearMenu.Show(); FloorClearMenu.FadeIn(); })
.Handle((in GameLogic.Output.ExitFloorClearMenu _) => { FloorClearMenu.FadeOut(); })
.Handle((in GameLogic.Output.SetInventoryMode _) => { InGameUI.ShowInventoryScreen(); }) .Handle((in GameLogic.Output.SetInventoryMode _) => { InGameUI.ShowInventoryScreen(); })
.Handle((in GameLogic.Output.HideInventory _) => { InGameUI.HideInventoryScreen(); }) .Handle((in GameLogic.Output.HideInventory _) => { InGameUI.HideInventoryScreen(); })
.Handle((in GameLogic.Output.ShowMiniMap _) => { InGameUI.ShowMiniMap(); }) .Handle((in GameLogic.Output.ShowMiniMap _) => { InGameUI.ShowMiniMap(); })
@@ -103,6 +114,14 @@ public partial class Game : Node3D, IGame
GameLogic.Input(new GameLogic.Input.Initialize()); GameLogic.Input(new GameLogic.Input.Initialize());
this.Provide(); this.Provide();
FloorClearMenu.TransitionCompleted += OnFloorClearTransitionCompleted;
PauseMenu.TransitionCompleted += OnPauseMenuTransitioned;
Map.TeleportReached += Map_TeleportReached;
Map.DialogueDecisionMade += Map_DialogueChoiceMade;
Map.DungeonFinishedGenerating += Map_DungeonFinishedGenerating;
InGameUI.InventoryMenu.ClosedMenu += InventoryMenu_CloseInventory;
GameRepo.PlayerData.Inventory.InventoryAtCapacity += PlayerInventory_InventoryAtCapacity;
} }
public void ToggleInventory() public void ToggleInventory()
@@ -143,5 +162,5 @@ public partial class Game : Node3D, IGame
GetTree().Paused = isPaused; GetTree().Paused = isPaused;
} }
public void OnStart() => GameLogic.Input(new GameLogic.Input.Start()); public void OnStart() => GameLogic.Input(new GameLogic.Input.StartGame());
} }

View File

@@ -31,7 +31,6 @@ script = ExtResource("4_f5pye")
[node name="InGameUI" parent="." instance=ExtResource("5_lxtnp")] [node name="InGameUI" parent="." instance=ExtResource("5_lxtnp")]
unique_name_in_owner = true unique_name_in_owner = true
visible = false
[node name="InGameAudio" parent="." instance=ExtResource("6_qc71l")] [node name="InGameAudio" parent="." instance=ExtResource("6_qc71l")]
@@ -47,6 +46,7 @@ visible = false
[node name="FloorClearMenu" parent="." instance=ExtResource("11_rya1n")] [node name="FloorClearMenu" parent="." instance=ExtResource("11_rya1n")]
unique_name_in_owner = true unique_name_in_owner = true
visible = false visible = false
modulate = Color(1, 1, 1, 1)
[node name="PauseMenu" parent="." instance=ExtResource("12_yev8k")] [node name="PauseMenu" parent="." instance=ExtResource("12_yev8k")]
unique_name_in_owner = true unique_name_in_owner = true

View File

@@ -4,7 +4,7 @@
{ {
public static class Input public static class Input
{ {
public readonly record struct Start; public readonly record struct StartGame;
public readonly record struct Initialize; public readonly record struct Initialize;
@@ -16,12 +16,12 @@
public readonly record struct GameOver; public readonly record struct GameOver;
public readonly record struct LoadNextFloor;
public readonly record struct FloorExitReached; public readonly record struct FloorExitReached;
public readonly record struct FloorClearTransitioned; public readonly record struct FloorClearTransitioned;
public readonly record struct GoToNextFloor;
public readonly record struct PauseButtonPressed; public readonly record struct PauseButtonPressed;
public readonly record struct PauseMenuTransitioned; public readonly record struct PauseMenuTransitioned;

View File

@@ -14,7 +14,7 @@ namespace GameJamDungeon
public readonly record struct ExitPauseMenu; public readonly record struct ExitPauseMenu;
public readonly record struct SetInventoryMode(List<IInventoryItem> Inventory); public readonly record struct SetInventoryMode();
public readonly record struct HideInventory; public readonly record struct HideInventory;
@@ -32,7 +32,7 @@ namespace GameJamDungeon
public readonly record struct ShowFloorClearMenu; public readonly record struct ShowFloorClearMenu;
public readonly record struct HideFloorClearMenu; public readonly record struct ExitFloorClearMenu;
} }
} }
} }

View File

@@ -1,6 +1,7 @@
@startuml GameLogic @startuml GameLogic
state "GameLogic State" as GameJamDungeon_GameLogic_State { state "GameLogic State" as GameJamDungeon_GameLogic_State {
state "FloorCleared" as GameJamDungeon_GameLogic_State_FloorCleared state "FloorCleared" as GameJamDungeon_GameLogic_State_FloorCleared
state "GameStarted" as GameJamDungeon_GameLogic_State_GameStarted
state "InventoryOpened" as GameJamDungeon_GameLogic_State_InventoryOpened state "InventoryOpened" as GameJamDungeon_GameLogic_State_InventoryOpened
state "MenuBackdrop" as GameJamDungeon_GameLogic_State_MenuBackdrop state "MenuBackdrop" as GameJamDungeon_GameLogic_State_MenuBackdrop
state "MinimapOpen" as GameJamDungeon_GameLogic_State_MinimapOpen state "MinimapOpen" as GameJamDungeon_GameLogic_State_MinimapOpen
@@ -10,9 +11,11 @@ state "GameLogic State" as GameJamDungeon_GameLogic_State {
state "Resuming" as GameJamDungeon_GameLogic_State_Resuming state "Resuming" as GameJamDungeon_GameLogic_State_Resuming
} }
GameJamDungeon_GameLogic_State_FloorCleared --> GameJamDungeon_GameLogic_State_FloorCleared : GoToNextFloor
GameJamDungeon_GameLogic_State_GameStarted --> GameJamDungeon_GameLogic_State_Playing : Initialize
GameJamDungeon_GameLogic_State_InventoryOpened --> GameJamDungeon_GameLogic_State_Playing : InventoryMenuToggle GameJamDungeon_GameLogic_State_InventoryOpened --> GameJamDungeon_GameLogic_State_Playing : InventoryMenuToggle
GameJamDungeon_GameLogic_State_MenuBackdrop --> GameJamDungeon_GameLogic_State_MenuBackdrop : Initialize GameJamDungeon_GameLogic_State_MenuBackdrop --> GameJamDungeon_GameLogic_State_MenuBackdrop : Initialize
GameJamDungeon_GameLogic_State_MenuBackdrop --> GameJamDungeon_GameLogic_State_Playing : Start GameJamDungeon_GameLogic_State_MenuBackdrop --> GameJamDungeon_GameLogic_State_Playing : StartGame
GameJamDungeon_GameLogic_State_MinimapOpen --> GameJamDungeon_GameLogic_State_Playing : MiniMapButtonReleased GameJamDungeon_GameLogic_State_MinimapOpen --> GameJamDungeon_GameLogic_State_Playing : MiniMapButtonReleased
GameJamDungeon_GameLogic_State_Paused --> GameJamDungeon_GameLogic_State_Resuming : PauseButtonPressed GameJamDungeon_GameLogic_State_Paused --> GameJamDungeon_GameLogic_State_Resuming : PauseButtonPressed
GameJamDungeon_GameLogic_State_Playing --> GameJamDungeon_GameLogic_State_FloorCleared : FloorExitReached GameJamDungeon_GameLogic_State_Playing --> GameJamDungeon_GameLogic_State_FloorCleared : FloorExitReached
@@ -24,14 +27,16 @@ GameJamDungeon_GameLogic_State_Resuming --> GameJamDungeon_GameLogic_State_Playi
GameJamDungeon_GameLogic_State : OnIsPaused() → SetPauseMode GameJamDungeon_GameLogic_State : OnIsPaused() → SetPauseMode
GameJamDungeon_GameLogic_State_FloorCleared : OnEnter → ShowFloorClearMenu GameJamDungeon_GameLogic_State_FloorCleared : OnEnter → ShowFloorClearMenu
GameJamDungeon_GameLogic_State_FloorCleared : OnExit → HideFloorClearMenu GameJamDungeon_GameLogic_State_FloorCleared : OnExit → ExitFloorClearMenu
GameJamDungeon_GameLogic_State_GameStarted : OnEnter → ShowFloorClearMenu
GameJamDungeon_GameLogic_State_GameStarted : OnExit → ExitFloorClearMenu
GameJamDungeon_GameLogic_State_GameStarted : OnInitialize → StartGame
GameJamDungeon_GameLogic_State_InventoryOpened : OnEnter → SetInventoryMode GameJamDungeon_GameLogic_State_InventoryOpened : OnEnter → SetInventoryMode
GameJamDungeon_GameLogic_State_InventoryOpened : OnExit → HideInventory GameJamDungeon_GameLogic_State_InventoryOpened : OnExit → HideInventory
GameJamDungeon_GameLogic_State_MinimapOpen : OnEnter → ShowMiniMap GameJamDungeon_GameLogic_State_MinimapOpen : OnEnter → ShowMiniMap
GameJamDungeon_GameLogic_State_MinimapOpen : OnExit → HideMiniMap GameJamDungeon_GameLogic_State_MinimapOpen : OnExit → HideMiniMap
GameJamDungeon_GameLogic_State_Paused : OnEnter → ShowPauseMenu GameJamDungeon_GameLogic_State_Paused : OnEnter → ShowPauseMenu
GameJamDungeon_GameLogic_State_Paused : OnExit → ExitPauseMenu GameJamDungeon_GameLogic_State_Paused : OnExit → ExitPauseMenu
GameJamDungeon_GameLogic_State_Playing : OnEnter → StartGame
GameJamDungeon_GameLogic_State_Quit : OnEnter → ShowLostScreen GameJamDungeon_GameLogic_State_Quit : OnEnter → ShowLostScreen
GameJamDungeon_GameLogic_State_Resuming : OnExit → HidePauseMenu GameJamDungeon_GameLogic_State_Resuming : OnExit → HidePauseMenu

View File

@@ -1,107 +1,57 @@
using Chickensoft.Collections; using Chickensoft.Collections;
using Godot; using Godot;
using System; using System;
using System.Collections.Generic;
namespace GameJamDungeon; namespace GameJamDungeon;
public interface IGameRepo : IDisposable public interface IGameRepo : IDisposable
{ {
public void OnGameEnded();
event Action? Ended;
AutoProp<List<IInventoryItem>> InventoryItems { get; }
IAutoProp<bool> IsInventoryScreenOpened { get; }
IAutoProp<bool> IsPaused { get; }
void Pause(); void Pause();
void Resume(); void Resume();
IAutoProp<bool> IsPaused { get; }
IAutoProp<Vector3> PlayerGlobalPosition { get; } IAutoProp<Vector3> PlayerGlobalPosition { get; }
PlayerData PlayerData { get; }
public void SetPlayerData(PlayerData playerData);
void SetPlayerGlobalPosition(Vector3 playerGlobalPosition); void SetPlayerGlobalPosition(Vector3 playerGlobalPosition);
void SetPlayerStatInfo(PlayerStatInfo playerStatInfo);
public void OnWeaponEquipped(Weapon equippedItem);
public void OnArmorEquipped(Armor equippedItem);
public void OnAccessoryEquipped(Accessory equippedItem);
public AutoProp<Weapon> EquippedWeapon { get; }
public AutoProp<Armor> EquippedArmor { get; }
public AutoProp<Accessory> EquippedAccessory { get; }
public int MaxItemSize { get; } public int MaxItemSize { get; }
public AutoProp<PlayerStatInfo> PlayerStatInfo { get; }
public bool IsItemEquipped(IEquipable item);
public void EquipItem(IEquipable item);
public void UnequipItem(IEquipable item);
public int CurrentFloor { get; set; } public int CurrentFloor { get; set; }
public void OnGameEnded();
event Action? Ended;
} }
public class GameRepo : IGameRepo public class GameRepo : IGameRepo
{ {
public event Action? Ended; public event Action? Ended;
private readonly AutoProp<List<IInventoryItem>> _inventoryItems;
private readonly AutoProp<bool> _isInventoryScreenOpened;
public AutoProp<List<IInventoryItem>> InventoryItems => _inventoryItems;
public IAutoProp<bool> IsInventoryScreenOpened => _isInventoryScreenOpened;
public IAutoProp<Vector3> PlayerGlobalPosition => _playerGlobalPosition; public IAutoProp<Vector3> PlayerGlobalPosition => _playerGlobalPosition;
private readonly AutoProp<Vector3> _playerGlobalPosition; private readonly AutoProp<Vector3> _playerGlobalPosition;
public IAutoProp<bool> IsPaused => _isPaused; public IAutoProp<bool> IsPaused => _isPaused;
private readonly AutoProp<bool> _isPaused; private readonly AutoProp<bool> _isPaused;
private AutoProp<Weapon> _equippedWeapon; public PlayerData PlayerData => _playerData;
public AutoProp<Weapon> EquippedWeapon => _equippedWeapon; private PlayerData _playerData;
private AutoProp<Armor> _equippedArmor;
public AutoProp<Armor> EquippedArmor => _equippedArmor;
private AutoProp<Accessory> _equippedAccessory;
public AutoProp<Accessory> EquippedAccessory => _equippedAccessory;
public bool IsWithinDialogueSpace { get; set; }
public int MaxItemSize => 20; public int MaxItemSize => 20;
private bool _disposedValue; private bool _disposedValue;
private AutoProp<PlayerStatInfo> _playerStatInfo; public int CurrentFloor { get; set; } = 0;
public AutoProp<PlayerStatInfo> PlayerStatInfo => _playerStatInfo;
public int CurrentFloor { get; set; } = -1;
public GameRepo() public GameRepo()
{ {
_inventoryItems = new AutoProp<List<IInventoryItem>>([]);
_isInventoryScreenOpened = new AutoProp<bool>(false);
_isPaused = new AutoProp<bool>(false); _isPaused = new AutoProp<bool>(false);
_playerGlobalPosition = new AutoProp<Vector3>(Vector3.Zero); _playerGlobalPosition = new AutoProp<Vector3>(Vector3.Zero);
_equippedWeapon = new AutoProp<Weapon>(new Weapon());
_equippedArmor = new AutoProp<Armor>(new Armor());
_equippedAccessory = new AutoProp<Accessory>(new Accessory());
_playerStatInfo = new AutoProp<PlayerStatInfo>(new PlayerStatInfo());
} }
public void Pause() public void Pause()
@@ -118,37 +68,7 @@ public class GameRepo : IGameRepo
public void SetPlayerGlobalPosition(Vector3 playerGlobalPosition) => _playerGlobalPosition.OnNext(playerGlobalPosition); public void SetPlayerGlobalPosition(Vector3 playerGlobalPosition) => _playerGlobalPosition.OnNext(playerGlobalPosition);
public void SetPlayerStatInfo(PlayerStatInfo playerStatInfo) => _playerStatInfo.OnNext(playerStatInfo); public void SetPlayerData(PlayerData playerData) => _playerData = playerData;
public void OnWeaponEquipped(Weapon equippedItem)
{
PlayerStatInfo.Value.BonusAttack -= _equippedWeapon.Value.WeaponInfo.Damage;
PlayerStatInfo.Value.BonusAttack += equippedItem.WeaponInfo.Damage;
_equippedWeapon.OnNext(equippedItem);
}
public void OnArmorEquipped(Armor equippedItem)
{
PlayerStatInfo.Value.BonusDefense -= _equippedArmor.Value.ArmorInfo.Defense;
PlayerStatInfo.Value.BonusDefense += equippedItem.ArmorInfo.Defense;
_equippedArmor.OnNext(equippedItem);
}
public void OnAccessoryEquipped(Accessory equippedItem)
{
PlayerStatInfo.Value.BonusAttack -= _equippedAccessory.Value.AccessoryInfo.ATKUp;
PlayerStatInfo.Value.BonusDefense -= _equippedAccessory.Value.AccessoryInfo.DEFUp;
PlayerStatInfo.Value.MaximumHP -= _equippedAccessory.Value.AccessoryInfo.MaxHPUp;
PlayerStatInfo.Value.MaximumVT -= _equippedAccessory.Value.AccessoryInfo.MaxVTUp;
PlayerStatInfo.Value.Luck -= _equippedAccessory.Value.AccessoryInfo.LUCKUp;
PlayerStatInfo.Value.BonusAttack += equippedItem.AccessoryInfo.ATKUp;
PlayerStatInfo.Value.BonusDefense += equippedItem.AccessoryInfo.DEFUp;
PlayerStatInfo.Value.MaximumHP += equippedItem.AccessoryInfo.MaxHPUp;
PlayerStatInfo.Value.MaximumVT += equippedItem.AccessoryInfo.MaxVTUp;
PlayerStatInfo.Value.Luck += equippedItem.AccessoryInfo.LUCKUp;
_equippedAccessory.OnNext(equippedItem);
}
public void OnGameEnded() public void OnGameEnded()
{ {
@@ -156,42 +76,6 @@ public class GameRepo : IGameRepo
Ended?.Invoke(); Ended?.Invoke();
} }
public bool IsItemEquipped(IEquipable item)
{
if (item is Weapon)
return EquippedWeapon.Value == item;
if (item is Armor)
return EquippedArmor.Value == item;
if (item is Accessory)
return EquippedAccessory.Value == item;
return false;
}
public void EquipItem(IEquipable item)
{
if (item is Weapon weapon)
OnWeaponEquipped(weapon);
if (item is Armor armor)
OnArmorEquipped(armor);
if (item is Accessory accessory)
OnAccessoryEquipped(accessory);
}
public void UnequipItem(IEquipable item)
{
if (item == EquippedWeapon.Value)
OnWeaponEquipped(new Weapon());
if (item == EquippedArmor.Value)
OnArmorEquipped(new Armor());
if (item == EquippedAccessory.Value)
OnAccessoryEquipped(new Accessory());
}
protected void Dispose(bool disposing) protected void Dispose(bool disposing)
{ {
if (!_disposedValue) if (!_disposedValue)
@@ -200,10 +84,6 @@ public class GameRepo : IGameRepo
{ {
_playerGlobalPosition.OnCompleted(); _playerGlobalPosition.OnCompleted();
_playerGlobalPosition.Dispose(); _playerGlobalPosition.Dispose();
_inventoryItems.OnCompleted();
_inventoryItems.Dispose();
_isInventoryScreenOpened.OnCompleted();
_isInventoryScreenOpened.Dispose();
_isPaused.OnCompleted(); _isPaused.OnCompleted();
_isPaused.Dispose(); _isPaused.Dispose();
} }

View File

@@ -8,12 +8,17 @@ namespace GameJamDungeon
public partial record State public partial record State
{ {
[Meta] [Meta]
public partial record FloorCleared : State public partial record FloorCleared : State, IGet<Input.GoToNextFloor>
{ {
public FloorCleared() public FloorCleared()
{ {
this.OnEnter(() => { Get<IGameRepo>().Pause(); Output(new Output.ShowFloorClearMenu()); }); this.OnEnter(() => { Get<IGameRepo>().Pause(); Output(new Output.ShowFloorClearMenu()); });
this.OnExit(() => { Output(new Output.HideFloorClearMenu()); }); this.OnExit(() => { Output(new Output.ExitFloorClearMenu()); });
}
public Transition On(in Input.GoToNextFloor input)
{
return ToSelf();
} }
} }
} }

View File

@@ -0,0 +1,27 @@
using Chickensoft.Introspection;
using Chickensoft.LogicBlocks;
namespace GameJamDungeon
{
public partial class GameLogic
{
public partial record State
{
[Meta]
public partial record GameStarted : State, IGet<Input.Initialize>
{
public GameStarted()
{
this.OnEnter(() => { Get<IGameRepo>().Pause(); Output(new Output.ShowFloorClearMenu()); });
this.OnExit(() => { Output(new Output.ExitFloorClearMenu()); });
}
public Transition On(in Input.Initialize input)
{
Output(new Output.StartGame());
return To<Playing>();
}
}
}
}
}

View File

@@ -12,7 +12,7 @@ namespace GameJamDungeon
{ {
public InventoryOpened() public InventoryOpened()
{ {
this.OnEnter(() => { Get<IGameRepo>().Pause(); Output(new Output.SetInventoryMode(Get<IGameRepo>().InventoryItems.Value)); }); this.OnEnter(() => { Get<IGameRepo>().Pause(); Output(new Output.SetInventoryMode()); });
this.OnExit(() => { Get<IGameRepo>().Resume(); Output(new Output.HideInventory()); }); this.OnExit(() => { Get<IGameRepo>().Resume(); Output(new Output.HideInventory()); });
} }
public Transition On(in Input.InventoryMenuToggle input) => To<Playing>(); public Transition On(in Input.InventoryMenuToggle input) => To<Playing>();

View File

@@ -7,7 +7,7 @@ namespace GameJamDungeon
public partial record State public partial record State
{ {
[Meta] [Meta]
public partial record MenuBackdrop : State, IGet<Input.Start>, IGet<Input.Initialize> public partial record MenuBackdrop : State, IGet<Input.StartGame>, IGet<Input.Initialize>
{ {
public MenuBackdrop() public MenuBackdrop()
{ {
@@ -15,9 +15,9 @@ namespace GameJamDungeon
OnDetach(() => Get<IAppRepo>().GameEntered -= OnGameEntered); OnDetach(() => Get<IAppRepo>().GameEntered -= OnGameEntered);
} }
public void OnGameEntered() => Input(new Input.Start()); public void OnGameEntered() => Input(new Input.StartGame());
public Transition On(in Input.Start input) => To<Playing>(); public Transition On(in Input.StartGame input) => To<Playing>();
public Transition On(in Input.Initialize input) public Transition On(in Input.Initialize input)
{ {

View File

@@ -17,8 +17,6 @@ namespace GameJamDungeon
{ {
public Playing() public Playing()
{ {
this.OnEnter(() => { Output(new Output.StartGame()); });
OnAttach(() => Get<IGameRepo>().Ended += OnEnded); OnAttach(() => Get<IGameRepo>().Ended += OnEnded);
OnDetach(() => Get<IGameRepo>().Ended -= OnEnded); OnDetach(() => Get<IGameRepo>().Ended -= OnEnded);
} }

View File

@@ -9,6 +9,8 @@ using System.Threading.Tasks;
public interface IInventoryMenu : IControl public interface IInventoryMenu : IControl
{ {
public Task RedrawInventory(); public Task RedrawInventory();
event InventoryMenu.ClosedMenuEventHandler ClosedMenu;
} }
[Meta(typeof(IAutoNode))] [Meta(typeof(IAutoNode))]
@@ -19,8 +21,8 @@ public partial class InventoryMenu : Control, IInventoryMenu
[Dependency] [Dependency]
public IGameRepo GameRepo => this.DependOn<IGameRepo>(); public IGameRepo GameRepo => this.DependOn<IGameRepo>();
[Dependency] [Signal]
public IGame Game => this.DependOn<IGame>(); public delegate void ClosedMenuEventHandler();
private InventoryPageNumber _currentPageNumber = InventoryPageNumber.FirstPage; private InventoryPageNumber _currentPageNumber = InventoryPageNumber.FirstPage;
@@ -77,12 +79,12 @@ public partial class InventoryMenu : Control, IInventoryMenu
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
public override void _UnhandledInput(InputEvent @event) public override void _UnhandledInput(InputEvent @event)
{ {
if (ItemSlots.Length == 0) if (ItemSlots.Length == 0 || GetViewport().GuiGetFocusOwner() is Button)
return; return;
var inventory = GameRepo.InventoryItems.Value; var inventory = GameRepo.PlayerData.Inventory;
if (@event.IsActionPressed(GameInputs.UiRight) && _currentPageNumber == InventoryPageNumber.FirstPage && inventory.Count > _itemsPerPage) if (@event.IsActionPressed(GameInputs.UiRight) && _currentPageNumber == InventoryPageNumber.FirstPage && inventory.Items.Count() > _itemsPerPage)
ChangeInventoryPage(InventoryPageNumber.SecondPage); ChangeInventoryPage(InventoryPageNumber.SecondPage);
if (@event.IsActionPressed(GameInputs.UiLeft) && _currentPageNumber == InventoryPageNumber.SecondPage) if (@event.IsActionPressed(GameInputs.UiLeft) && _currentPageNumber == InventoryPageNumber.SecondPage)
@@ -104,7 +106,7 @@ public partial class InventoryMenu : Control, IInventoryMenu
if (@event.IsActionPressed(GameInputs.UiAccept)) if (@event.IsActionPressed(GameInputs.UiAccept))
{ {
if (ItemSlots.Length == 0 || GetViewport().GuiGetFocusOwner() is Button) if (ItemSlots.Length == 0)
return; return;
DisplayUserActionPrompt(); DisplayUserActionPrompt();
} }
@@ -129,37 +131,37 @@ public partial class InventoryMenu : Control, IInventoryMenu
{ {
FloorLabel.Text = $"Level {GameRepo.CurrentFloor:D2}"; FloorLabel.Text = $"Level {GameRepo.CurrentFloor:D2}";
var currentLevel = GameRepo.PlayerStatInfo.Value.CurrentLevel; var currentLevel = GameRepo.PlayerData.CurrentLevel.Value;
CurrentLevelLabel.Text = $"Level {currentLevel:D2}"; CurrentLevelLabel.Text = $"Level {currentLevel:D2}";
var currentHP = GameRepo.PlayerStatInfo.Value.CurrentHP; var currentHP = GameRepo.PlayerData.CurrentHP.Value;
var maxHP = GameRepo.PlayerStatInfo.Value.MaximumHP; var maxHP = GameRepo.PlayerData.MaximumHP.Value;
HPValue.Text = $"{currentHP}/{maxHP}"; HPValue.Text = $"{currentHP}/{maxHP}";
var currentVT = GameRepo.PlayerStatInfo.Value.CurrentVT; var currentVT = GameRepo.PlayerData.CurrentVT.Value;
var maxVT = GameRepo.PlayerStatInfo.Value.MaximumVT; var maxVT = GameRepo.PlayerData.MaximumVT.Value;
VTValue.Text = $"{currentVT}/{maxVT}"; VTValue.Text = $"{currentVT}/{maxVT}";
var currentAttack = GameRepo.PlayerStatInfo.Value.CurrentAttack; var currentAttack = GameRepo.PlayerData.CurrentAttack.Value;
var maxAttack = GameRepo.PlayerStatInfo.Value.MaxAttack; var maxAttack = GameRepo.PlayerData.MaxAttack.Value;
ATKValue.Text = $"{currentAttack}/{maxAttack}"; ATKValue.Text = $"{currentAttack}/{maxAttack}";
var currentDefense = GameRepo.PlayerStatInfo.Value.CurrentDefense; var currentDefense = GameRepo.PlayerData.CurrentDefense.Value;
var maxDefense = GameRepo.PlayerStatInfo.Value.MaxDefense; var maxDefense = GameRepo.PlayerData.MaxDefense.Value;
DEFValue.Text = $"{currentDefense}/{maxDefense}"; DEFValue.Text = $"{currentDefense}/{maxDefense}";
var atkBonus = GameRepo.PlayerStatInfo.Value.BonusAttack; var atkBonus = GameRepo.PlayerData.BonusAttack.Value;
var defBonus = GameRepo.PlayerStatInfo.Value.BonusDefense; var defBonus = GameRepo.PlayerData.BonusDefense.Value;
ATKBonusLabel.Text = atkBonus != 0 ? $"{atkBonus:+0;-#}" : "..."; ATKBonusLabel.Text = atkBonus != 0 ? $"{atkBonus:+0;-#}" : "...";
DEFBonusLabel.Text = defBonus != 0 ? $"{defBonus:+0;-#}" : "..."; DEFBonusLabel.Text = defBonus != 0 ? $"{defBonus:+0;-#}" : "...";
// TODO: Change font style when EXP Bonus effect is active // TODO: Change font style when EXP Bonus effect is active
var currentExp = GameRepo.PlayerStatInfo.Value.CurrentEXP; var currentExp = GameRepo.PlayerData.CurrentExp.Value;
var expToNextLevel = GameRepo.PlayerStatInfo.Value.EXPToNextLevel; var expToNextLevel = GameRepo.PlayerData.ExpToNextLevel.Value;
EXPValue.Text = $"{currentExp}/{expToNextLevel}"; EXPValue.Text = $"{currentExp}/{expToNextLevel}";
if (ItemSlots.Any()) if (ItemSlots.Any())
@@ -183,7 +185,7 @@ public partial class InventoryMenu : Control, IInventoryMenu
if (currentItem is IEquipable equipable) if (currentItem is IEquipable equipable)
{ {
var isEquipped = GameRepo.IsItemEquipped(equipable); var isEquipped = GameRepo.PlayerData.Inventory.IsEquipped(equipable);
UseButton.Text = isEquipped ? "Unequip" : "Equip"; UseButton.Text = isEquipped ? "Unequip" : "Equip";
ThrowButton.Disabled = isEquipped ? true : false; ThrowButton.Disabled = isEquipped ? true : false;
ThrowButton.FocusMode = isEquipped ? FocusModeEnum.None : FocusModeEnum.All; ThrowButton.FocusMode = isEquipped ? FocusModeEnum.None : FocusModeEnum.All;
@@ -219,14 +221,14 @@ public partial class InventoryMenu : Control, IInventoryMenu
private void PopulateInventory() private void PopulateInventory()
{ {
var inventory = GameRepo.InventoryItems.Value; var inventory = GameRepo.PlayerData.Inventory;
var numberOfItemsToDisplay = _currentPageNumber == InventoryPageNumber.FirstPage ? Mathf.Min(inventory.Count, _itemsPerPage) : Mathf.Min(inventory.Count - _itemsPerPage, _itemsPerPage); var numberOfItemsToDisplay = _currentPageNumber == InventoryPageNumber.FirstPage ? Mathf.Min(inventory.Items.Count, _itemsPerPage) : Mathf.Min(inventory.Items.Count - _itemsPerPage, _itemsPerPage);
var indexToStart = _currentPageNumber == InventoryPageNumber.FirstPage ? 0 : _itemsPerPage - 1; var indexToStart = _currentPageNumber == InventoryPageNumber.FirstPage ? 0 : _itemsPerPage - 1;
ForwardArrow.Text = ""; ForwardArrow.Text = "";
BackArrow.Text = ""; BackArrow.Text = "";
if (_currentPageNumber == InventoryPageNumber.FirstPage && inventory.Count > _itemsPerPage) if (_currentPageNumber == InventoryPageNumber.FirstPage && inventory.Items.Count > _itemsPerPage)
{ {
ForwardArrow.Text = "►"; ForwardArrow.Text = "►";
BackArrow.Text = ""; BackArrow.Text = "";
@@ -240,20 +242,20 @@ public partial class InventoryMenu : Control, IInventoryMenu
for (var i = 0; i < numberOfItemsToDisplay; i++) for (var i = 0; i < numberOfItemsToDisplay; i++)
{ {
var item = inventory.ElementAt(i + indexToStart); var item = inventory.Items.ElementAt(i + indexToStart);
var itemScene = GD.Load<PackedScene>(ITEM_SLOT_SCENE); var itemScene = GD.Load<PackedScene>(ITEM_SLOT_SCENE);
var itemSlot = itemScene.Instantiate<IItemSlot>(); var itemSlot = itemScene.Instantiate<IItemSlot>();
itemSlot.Item = item; itemSlot.Item = item;
ItemsPage.AddChildEx(itemSlot); ItemsPage.AddChildEx(itemSlot);
if (itemSlot.Item is IEquipable equipable && GameRepo.IsItemEquipped(equipable)) if (itemSlot.Item is IEquipable equipable && GameRepo.PlayerData.Inventory.IsEquipped(equipable))
itemSlot.SetEquippedItemStyle(); itemSlot.SetEquippedItemStyle();
} }
if (ItemSlots.Any()) if (ItemSlots.Any())
{ {
ItemSlots.ElementAt(_currentIndex).SetSelectedItemStyle(); ItemSlots.ElementAt(_currentIndex).SetSelectedItemStyle();
if (ItemSlots.ElementAt(_currentIndex).Item is IEquipable equipable && GameRepo.IsItemEquipped(equipable)) if (ItemSlots.ElementAt(_currentIndex).Item is IEquipable equipable && GameRepo.PlayerData.Inventory.IsEquipped(equipable))
ItemSlots.ElementAt(_currentIndex).SetEquippedSelectedItemStyle(); ItemSlots.ElementAt(_currentIndex).SetEquippedSelectedItemStyle();
} }
} }
@@ -262,7 +264,7 @@ public partial class InventoryMenu : Control, IInventoryMenu
{ {
await ToSignal(GetTree().CreateTimer(0.1f), "timeout"); await ToSignal(GetTree().CreateTimer(0.1f), "timeout");
itemSlot.SetItemStyle(); itemSlot.SetItemStyle();
if (itemSlot.Item is IEquipable equipable && GameRepo.IsItemEquipped(equipable)) if (itemSlot.Item is IEquipable equipable && GameRepo.PlayerData.Inventory.IsEquipped(equipable))
itemSlot.SetEquippedItemStyle(); itemSlot.SetEquippedItemStyle();
} }
@@ -270,7 +272,7 @@ public partial class InventoryMenu : Control, IInventoryMenu
{ {
await ToSignal(GetTree().CreateTimer(0.1f), "timeout"); await ToSignal(GetTree().CreateTimer(0.1f), "timeout");
itemSlot.SetSelectedItemStyle(); itemSlot.SetSelectedItemStyle();
if (itemSlot.Item is IEquipable newEquipable && GameRepo.IsItemEquipped(newEquipable)) if (itemSlot.Item is IEquipable newEquipable && GameRepo.PlayerData.Inventory.IsEquipped(newEquipable))
itemSlot.SetEquippedSelectedItemStyle(); itemSlot.SetEquippedSelectedItemStyle();
ItemDescriptionTitle.Text = $"{itemSlot.Item.Info.Name}"; ItemDescriptionTitle.Text = $"{itemSlot.Item.Info.Name}";
ItemEffectLabel.Text = $"{itemSlot.Item.Info.Description}"; ItemEffectLabel.Text = $"{itemSlot.Item.Info.Description}";
@@ -282,14 +284,14 @@ public partial class InventoryMenu : Control, IInventoryMenu
await ToSignal(GetTree().CreateTimer(0.2f), "timeout"); await ToSignal(GetTree().CreateTimer(0.2f), "timeout");
if (itemSlot.Item is IEquipable equipableItem) if (itemSlot.Item is IEquipable equipableItem)
{ {
if (GameRepo.IsItemEquipped(equipableItem)) if (GameRepo.PlayerData.Inventory.IsEquipped(equipableItem))
{ {
GameRepo.UnequipItem(equipableItem); GameRepo.PlayerData.Inventory.Unequip(equipableItem);
itemSlot.SetSelectedItemStyle(); itemSlot.SetSelectedItemStyle();
} }
else else
{ {
GameRepo.EquipItem(equipableItem); GameRepo.PlayerData.Inventory.Equip(equipableItem);
itemSlot.SetEquippedSelectedItemStyle(); itemSlot.SetEquippedSelectedItemStyle();
} }
@@ -299,20 +301,13 @@ public partial class InventoryMenu : Control, IInventoryMenu
private void UpdateStatBonusInfo() private void UpdateStatBonusInfo()
{ {
var atkBonus = GameRepo.PlayerStatInfo.Value.BonusAttack; var atkBonus = GameRepo.PlayerData.BonusAttack.Value;
ATKBonusLabel.Text = atkBonus != 0 ? $"{atkBonus:+0;-#}" : "..."; ATKBonusLabel.Text = atkBonus != 0 ? $"{atkBonus:+0;-#}" : "...";
var defBonus = GameRepo.PlayerStatInfo.Value.BonusDefense; var defBonus = GameRepo.PlayerData.BonusDefense.Value;
DEFBonusLabel.Text = defBonus != 0 ? $"{defBonus:+0;-#}" : "..."; DEFBonusLabel.Text = defBonus != 0 ? $"{defBonus:+0;-#}" : "...";
var currentHP = GameRepo.PlayerStatInfo.Value.CurrentHP; HPValue.Text = $"{GameRepo.PlayerData.CurrentHP.Value}/{GameRepo.PlayerData.MaximumHP.Value}";
var maxHP = GameRepo.PlayerStatInfo.Value.MaximumHP; VTValue.Text = $"{GameRepo.PlayerData.CurrentVT.Value}/{GameRepo.PlayerData.MaximumVT.Value}";
HPValue.Text = $"{currentHP}/{maxHP}";
var currentVT = GameRepo.PlayerStatInfo.Value.CurrentVT;
var maxVT = GameRepo.PlayerStatInfo.Value.MaximumVT;
VTValue.Text = $"{currentVT}/{maxVT}";
} }
private async void UseButtonPressed() private async void UseButtonPressed()
@@ -321,7 +316,10 @@ public partial class InventoryMenu : Control, IInventoryMenu
if (currentItem is IEquipable) if (currentItem is IEquipable)
await EquipOrUnequipItem(); await EquipOrUnequipItem();
if (currentItem is ConsumableItem consumable) if (currentItem is ConsumableItem consumable)
{
EmitSignal(SignalName.ClosedMenu);
consumable.Use(); consumable.Use();
}
if (_currentIndex >= ItemSlots.Length - 1) if (_currentIndex >= ItemSlots.Length - 1)
_currentIndex--; _currentIndex--;
@@ -341,7 +339,7 @@ public partial class InventoryMenu : Control, IInventoryMenu
_currentIndex--; _currentIndex--;
if (_currentIndex <= 0) if (_currentIndex <= 0)
_currentIndex = 0; _currentIndex = 0;
Game.ToggleInventory(); EmitSignal(SignalName.ClosedMenu);
currentItem.Throw(); currentItem.Throw();
} }
@@ -354,7 +352,7 @@ public partial class InventoryMenu : Control, IInventoryMenu
if (_currentIndex <= 0) if (_currentIndex <= 0)
_currentIndex = 0; _currentIndex = 0;
Game.ToggleInventory(); EmitSignal(SignalName.ClosedMenu);
currentItem.Drop(); currentItem.Drop();
} }

View File

@@ -102,7 +102,6 @@ font_size = 80
font_color = Color(0.737255, 0.705882, 0.690196, 1) font_color = Color(0.737255, 0.705882, 0.690196, 1)
[node name="InventoryMenu" type="Control"] [node name="InventoryMenu" type="Control"]
process_mode = 2
layout_mode = 3 layout_mode = 3
anchors_preset = 15 anchors_preset = 15
anchor_right = 1.0 anchor_right = 1.0

View File

@@ -42,9 +42,9 @@ public partial class ItemSlot : HBoxContainer, IItemSlot
ItemName.Text = Item.Info.Name; ItemName.Text = Item.Info.Name;
EquipBonus.Text = "..."; EquipBonus.Text = "...";
ItemTexture.Texture = Item.Info.Texture; ItemTexture.Texture = Item.Info.Texture;
GameRepo.EquippedWeapon.Sync += EquippedWeapon_Sync; GameRepo.PlayerData.Inventory.EquippedWeapon.Sync += EquippedWeapon_Sync;
GameRepo.EquippedArmor.Sync += EquippedArmor_Sync; GameRepo.PlayerData.Inventory.EquippedArmor.Sync += EquippedArmor_Sync;
GameRepo.EquippedAccessory.Sync += EquippedAccessory_Sync; GameRepo.PlayerData.Inventory.EquippedAccessory.Sync += EquippedAccessory_Sync;
} }
private void EquippedWeapon_Sync(Weapon obj) private void EquippedWeapon_Sync(Weapon obj)

105
src/items/Inventory.cs Normal file
View File

@@ -0,0 +1,105 @@
using Chickensoft.Collections;
using Chickensoft.GodotNodeInterfaces;
using Godot;
using System;
using System.Collections.Generic;
using static GameJamDungeon.Inventory;
namespace GameJamDungeon;
public interface IInventory : INode
{
public List<IInventoryItem> Items { get; }
public IAutoProp<Weapon> EquippedWeapon { get; }
public IAutoProp<Armor> EquippedArmor { get; }
public IAutoProp<Accessory> EquippedAccessory { get; }
public bool TryAdd(IInventoryItem inventoryItem);
public void Remove(IInventoryItem inventoryItem);
public void Equip(IEquipable equipable);
public void Unequip(IEquipable equipable);
public bool IsEquipped(IEquipable equipable);
event Inventory.InventoryAtCapacityEventHandler InventoryAtCapacity;
}
public partial class Inventory : Node, IInventory
{
// TODO: Constants class with export
private const int _maxInventorySize = 20;
[Signal]
public delegate void InventoryAtCapacityEventHandler(string rejectedItemName);
public Inventory()
{
Items = [];
}
public List<IInventoryItem> Items { get; private set; }
public IAutoProp<Weapon> EquippedWeapon => _equippedWeapon;
private AutoProp<Weapon> _equippedWeapon { get; set; } = new AutoProp<Weapon>(new Weapon());
public IAutoProp<Armor> EquippedArmor => _equippedArmor;
private AutoProp<Armor> _equippedArmor { get; set; } = new AutoProp<Armor>(new Armor());
public IAutoProp<Accessory> EquippedAccessory => _equippedAccessory;
private AutoProp<Accessory> _equippedAccessory { get; set; } = new AutoProp<Accessory>(new Accessory());
public bool TryAdd(IInventoryItem inventoryItem)
{
if (Items.Count >= _maxInventorySize)
{
EmitSignal(SignalName.InventoryAtCapacity, inventoryItem.Info.Name);
return false;
}
Items.Add(inventoryItem);
return true;
}
public void Remove(IInventoryItem inventoryItem) => Items.Remove(inventoryItem);
public void Equip(IEquipable equipable)
{
if (equipable is Weapon weapon)
_equippedWeapon.OnNext(weapon);
else if (equipable is Armor armor)
_equippedArmor.OnNext(armor);
else if (equipable is Accessory accessory)
_equippedAccessory.OnNext(accessory);
else
throw new NotImplementedException("Item type is not supported.");
}
public void Unequip(IEquipable equipable)
{
if (equipable is Weapon weapon)
_equippedWeapon.OnNext(new Weapon());
else if (equipable is Armor armor)
_equippedArmor.OnNext(new Armor());
else if (equipable is Accessory accessory)
_equippedAccessory.OnNext(new Accessory());
else
throw new NotImplementedException("Item type is not supported.");
}
public bool IsEquipped(IEquipable equipable)
{
if (equipable is Weapon weapon)
return _equippedWeapon.Value.Equals(weapon);
else if (equipable is Armor armor)
return _equippedArmor.Value.Equals(armor);
else if (equipable is Accessory accessory)
return _equippedAccessory.Value.Equals(accessory);
else
throw new NotImplementedException("Item type is not supported.");
}
}

View File

@@ -1,16 +1,13 @@
using Chickensoft.AutoInject; using Chickensoft.GodotNodeInterfaces;
using Chickensoft.GodotNodeInterfaces;
using System; using System;
namespace GameJamDungeon namespace GameJamDungeon
{ {
public interface IInventoryItem : INode3D public interface IInventoryItem : INode3D
{ {
public Guid ID { get; }
public IGameRepo GameRepo { get; } public IGameRepo GameRepo { get; }
public InventoryItemInfo Info { get; } public InventoryItemStats Info { get; }
public void Throw(); public void Throw();

View File

@@ -2,7 +2,7 @@ using Godot;
using System; using System;
[GlobalClass] [GlobalClass]
public partial class InventoryItemInfo : Resource public partial class InventoryItemStats : Resource
{ {
[Export] [Export]
public string Name = string.Empty; public string Name = string.Empty;

View File

@@ -31,23 +31,23 @@ namespace GameJamDungeon
foreach (var armor in armorResources) foreach (var armor in armorResources)
{ {
var armorInfo = GD.Load<ArmorInfo>($"res://src/items/armor/resources/{armor}"); var armorInfo = GD.Load<ArmorStats>($"res://src/items/armor/resources/{armor}");
var armorScene = ArmorScene.Instantiate<Armor>(); var armorScene = ArmorScene.Instantiate<Armor>();
armorScene.ArmorInfo = armorInfo; armorScene.ArmorStats = armorInfo;
database.Add(armorScene); database.Add(armorScene);
} }
foreach (var weapon in weaponResources) foreach (var weapon in weaponResources)
{ {
var weaponInfo = GD.Load<WeaponInfo>($"res://src/items/weapons/resources/{weapon}"); var weaponInfo = GD.Load<WeaponStats>($"res://src/items/weapons/resources/{weapon}");
var weaponScene = WeaponScene.Instantiate<Weapon>(); var weaponScene = WeaponScene.Instantiate<Weapon>();
weaponScene.WeaponInfo = weaponInfo; weaponScene.WeaponStats = weaponInfo;
database.Add(weaponScene); database.Add(weaponScene);
} }
foreach (var accessory in accessoryResources) foreach (var accessory in accessoryResources)
{ {
var accessoryInfo = GD.Load<AccessoryInfo>($"res://src/items/accessory/resources/{accessory}"); var accessoryInfo = GD.Load<AccessoryStats>($"res://src/items/accessory/resources/{accessory}");
var accessoryScene = AccessoryScene.Instantiate<Accessory>(); var accessoryScene = AccessoryScene.Instantiate<Accessory>();
accessoryScene.AccessoryInfo = accessoryInfo; accessoryScene.AccessoryInfo = accessoryInfo;
database.Add(accessoryScene); database.Add(accessoryScene);
@@ -55,7 +55,7 @@ namespace GameJamDungeon
foreach (var throwable in throwableResources) foreach (var throwable in throwableResources)
{ {
var throwableItemInfo = GD.Load<ThrowableItemInfo>($"res://src/items/throwable/resources/{throwable}"); var throwableItemInfo = GD.Load<ThrowableItemStats>($"res://src/items/throwable/resources/{throwable}");
var throwableItemScene = ThrowableItemScene.Instantiate<ThrowableItem>(); var throwableItemScene = ThrowableItemScene.Instantiate<ThrowableItem>();
throwableItemScene.ThrowableItemInfo = throwableItemInfo; throwableItemScene.ThrowableItemInfo = throwableItemInfo;
database.Add(throwableItemScene); database.Add(throwableItemScene);
@@ -63,7 +63,7 @@ namespace GameJamDungeon
foreach (var consumable in consumableResources) foreach (var consumable in consumableResources)
{ {
var consumableItemInfo = GD.Load<ConsumableItemInfo>($"res://src/items/consumable/resources/{consumable}"); var consumableItemInfo = GD.Load<ConsumableItemStats>($"res://src/items/consumable/resources/{consumable}");
var consumableItemScene = ConsumableItemScene.Instantiate<ConsumableItem>(); var consumableItemScene = ConsumableItemScene.Instantiate<ConsumableItem>();
consumableItemScene.ConsumableItemInfo = consumableItemInfo; consumableItemScene.ConsumableItemInfo = consumableItemInfo;
database.Add(consumableItemScene); database.Add(consumableItemScene);

View File

@@ -1,16 +1,16 @@
[gd_scene load_steps=7 format=3 uid="uid://twrj4wixcbu7"] [gd_scene load_steps=7 format=3 uid="uid://twrj4wixcbu7"]
[ext_resource type="Script" path="res://src/items/ItemDatabase.cs" id="1_7b315"] [ext_resource type="Script" path="res://src/items/ItemDatabase.cs" id="1_7b315"]
[ext_resource type="PackedScene" uid="uid://db206brufi83s" path="res://src/items/weapons/Weapon.tscn" id="2_14w53"] [ext_resource type="PackedScene" uid="uid://db206brufi83s" path="res://src/items/weapons/Weapon.tscn" id="2_wq002"]
[ext_resource type="PackedScene" uid="uid://dorr7v1tkeiy0" path="res://src/items/armor/Armor.tscn" id="3_p6rkn"] [ext_resource type="PackedScene" uid="uid://dorr7v1tkeiy0" path="res://src/items/armor/Armor.tscn" id="3_8wlg5"]
[ext_resource type="PackedScene" uid="uid://b07srt3lckt4e" path="res://src/items/accessory/Accessory.tscn" id="4_oqm6k"] [ext_resource type="PackedScene" uid="uid://b07srt3lckt4e" path="res://src/items/accessory/Accessory.tscn" id="4_pr7ub"]
[ext_resource type="PackedScene" uid="uid://1fl6s352e2ej" path="res://src/items/throwable/ThrowableItem.tscn" id="5_l0fpl"] [ext_resource type="PackedScene" uid="uid://1fl6s352e2ej" path="res://src/items/throwable/ThrowableItem.tscn" id="5_r5y4t"]
[ext_resource type="PackedScene" uid="uid://c6w7dpk0hurj0" path="res://src/items/consumable/ConsumableItem.tscn" id="6_51k8r"] [ext_resource type="PackedScene" uid="uid://c6w7dpk0hurj0" path="res://src/items/consumable/ConsumableItem.tscn" id="6_yvger"]
[node name="ItemDatabase" type="Node"] [node name="ItemDatabase" type="Node"]
script = ExtResource("1_7b315") script = ExtResource("1_7b315")
WeaponScene = ExtResource("2_14w53") WeaponScene = ExtResource("2_wq002")
ArmorScene = ExtResource("3_p6rkn") ArmorScene = ExtResource("3_8wlg5")
AccessoryScene = ExtResource("4_oqm6k") AccessoryScene = ExtResource("4_pr7ub")
ThrowableItemScene = ExtResource("5_l0fpl") ThrowableItemScene = ExtResource("5_r5y4t")
ConsumableItemScene = ExtResource("6_51k8r") ConsumableItemScene = ExtResource("6_yvger")

View File

@@ -11,14 +11,12 @@ public partial class Accessory : Node3D, IInventoryItem, IEquipable
{ {
public override void _Notification(int what) => this.Notify(what); public override void _Notification(int what) => this.Notify(what);
public Guid ID { get; } = new Guid();
[Dependency] public IGameRepo GameRepo => this.DependOn<IGameRepo>(); [Dependency] public IGameRepo GameRepo => this.DependOn<IGameRepo>();
public InventoryItemInfo Info => AccessoryInfo; public InventoryItemStats Info => AccessoryInfo;
[Export] [Export]
public AccessoryInfo AccessoryInfo { get; set; } = new AccessoryInfo(); public AccessoryStats AccessoryInfo { get; set; } = new AccessoryStats();
[Node] public Sprite3D Sprite { get; set; } = default!; [Node] public Sprite3D Sprite { get; set; } = default!;
@@ -32,21 +30,18 @@ public partial class Accessory : Node3D, IInventoryItem, IEquipable
public void Throw() public void Throw()
{ {
GameRepo.InventoryItems.Value.Remove(this); GameRepo.PlayerData.Inventory.Remove(this);
} }
public void Drop() public void Drop()
{ {
GameRepo.InventoryItems.Value.Remove(this); GameRepo.PlayerData.Inventory.Remove(this);
} }
public void OnEntered(Node3D body) public void OnEntered(Node3D body)
{ {
if (GameRepo.InventoryItems.Value.Count() >= GameRepo.MaxItemSize) var isAdded = GameRepo.PlayerData.Inventory.TryAdd(this);
return; if (isAdded)
QueueFree();
var inventoryList = GameRepo.InventoryItems.Value.Append(this).ToList();
GameRepo.InventoryItems.OnNext(inventoryList);
QueueFree();
} }
} }

View File

@@ -4,7 +4,7 @@ using System;
namespace GameJamDungeon; namespace GameJamDungeon;
[GlobalClass] [GlobalClass]
public partial class AccessoryInfo : InventoryItemInfo public partial class AccessoryStats : InventoryItemStats
{ {
[Export] [Export]
public int ATKUp { get; set; } = 0; public int ATKUp { get; set; } = 0;

View File

@@ -1,10 +1,10 @@
[gd_resource type="Resource" script_class="AccessoryInfo" load_steps=3 format=3 uid="uid://cvkwmart5y51r"] [gd_resource type="Resource" script_class="AccessoryStats" load_steps=3 format=3 uid="uid://cvkwmart5y51r"]
[ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_578a0"] [ext_resource type="Texture2D" uid="uid://hjyk3j24o48b" path="res://src/items/accessory/textures/MASK 03.PNG" id="1_q42cv"]
[ext_resource type="Script" path="res://src/items/accessory/AccessoryInfo.cs" id="1_sjkji"] [ext_resource type="Script" path="res://src/items/accessory/AccessoryStats.cs" id="1_xqaot"]
[resource] [resource]
script = ExtResource("1_sjkji") script = ExtResource("1_xqaot")
ATKUp = 0 ATKUp = 0
DEFUp = 0 DEFUp = 0
LUCKUp = 0.15 LUCKUp = 0.15
@@ -12,6 +12,6 @@ MaxHPUp = 0
MaxVTUp = 0 MaxVTUp = 0
AccessoryTags = [] AccessoryTags = []
Name = "Mask of the Goddess of Avarice" Name = "Mask of the Goddess of Avarice"
Description = "Raises LUCK." Description = "Raises Luck"
Texture = ExtResource("1_578a0") Texture = ExtResource("1_q42cv")
SpawnRate = 0.5 SpawnRate = 0.5

View File

@@ -1,7 +1,7 @@
[gd_resource type="Resource" script_class="AccessoryInfo" load_steps=3 format=3 uid="uid://d4bcem2nup7ef"] [gd_resource type="Resource" script_class="AccessoryInfo" load_steps=3 format=3 uid="uid://d4bcem2nup7ef"]
[ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_0p1ot"] [ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_0p1ot"]
[ext_resource type="Script" path="res://src/items/accessory/AccessoryInfo.cs" id="1_vef66"] [ext_resource type="Script" path="res://src/items/accessory/AccessoryStats.cs" id="1_vef66"]
[resource] [resource]
script = ExtResource("1_vef66") script = ExtResource("1_vef66")

View File

@@ -1,7 +1,7 @@
[gd_resource type="Resource" script_class="AccessoryInfo" load_steps=3 format=3 uid="uid://bejy3lpudgawg"] [gd_resource type="Resource" script_class="AccessoryInfo" load_steps=3 format=3 uid="uid://bejy3lpudgawg"]
[ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_0k42r"] [ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_0k42r"]
[ext_resource type="Script" path="res://src/items/accessory/AccessoryInfo.cs" id="1_cgxkh"] [ext_resource type="Script" path="res://src/items/accessory/AccessoryStats.cs" id="1_cgxkh"]
[resource] [resource]
script = ExtResource("1_cgxkh") script = ExtResource("1_cgxkh")

View File

@@ -1,7 +1,7 @@
[gd_resource type="Resource" script_class="AccessoryInfo" load_steps=3 format=3 uid="uid://ddwyaxxqvk52h"] [gd_resource type="Resource" script_class="AccessoryInfo" load_steps=3 format=3 uid="uid://ddwyaxxqvk52h"]
[ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_1uw37"] [ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_1uw37"]
[ext_resource type="Script" path="res://src/items/accessory/AccessoryInfo.cs" id="1_kuyyj"] [ext_resource type="Script" path="res://src/items/accessory/AccessoryStats.cs" id="1_kuyyj"]
[resource] [resource]
script = ExtResource("1_kuyyj") script = ExtResource("1_kuyyj")

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="AccessoryInfo" load_steps=3 format=3 uid="uid://c3v6r8s8yruag"] [gd_resource type="Resource" script_class="AccessoryInfo" load_steps=3 format=3 uid="uid://c3v6r8s8yruag"]
[ext_resource type="Script" path="res://src/items/accessory/AccessoryInfo.cs" id="1_co7sc"] [ext_resource type="Script" path="res://src/items/accessory/AccessoryStats.cs" id="1_co7sc"]
[ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_uwbei"] [ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_uwbei"]
[resource] [resource]

View File

@@ -1,7 +1,7 @@
[gd_resource type="Resource" script_class="AccessoryInfo" load_steps=3 format=3 uid="uid://ct8iply3dwssv"] [gd_resource type="Resource" script_class="AccessoryInfo" load_steps=3 format=3 uid="uid://ct8iply3dwssv"]
[ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_t16cd"] [ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_t16cd"]
[ext_resource type="Script" path="res://src/items/accessory/AccessoryInfo.cs" id="1_vdb56"] [ext_resource type="Script" path="res://src/items/accessory/AccessoryStats.cs" id="1_vdb56"]
[resource] [resource]
script = ExtResource("1_vdb56") script = ExtResource("1_vdb56")

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="AccessoryInfo" load_steps=3 format=3 uid="uid://d02kuxaus43mk"] [gd_resource type="Resource" script_class="AccessoryInfo" load_steps=3 format=3 uid="uid://d02kuxaus43mk"]
[ext_resource type="Script" path="res://src/items/accessory/AccessoryInfo.cs" id="1_3iw2y"] [ext_resource type="Script" path="res://src/items/accessory/AccessoryStats.cs" id="1_3iw2y"]
[ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_vc77e"] [ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_vc77e"]
[resource] [resource]

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="AccessoryInfo" load_steps=3 format=3 uid="uid://b0bxwp55mcyyp"] [gd_resource type="Resource" script_class="AccessoryInfo" load_steps=3 format=3 uid="uid://b0bxwp55mcyyp"]
[ext_resource type="Script" path="res://src/items/accessory/AccessoryInfo.cs" id="1_0u4rq"] [ext_resource type="Script" path="res://src/items/accessory/AccessoryStats.cs" id="1_0u4rq"]
[ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_ggv41"] [ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_ggv41"]
[resource] [resource]

View File

@@ -3,25 +3,26 @@
importer="texture" importer="texture"
type="CompressedTexture2D" type="CompressedTexture2D"
uid="uid://hjyk3j24o48b" uid="uid://hjyk3j24o48b"
path="res://.godot/imported/MASK 03.PNG-9ab390330efa1f35084ad56075377b4d.ctex" path.s3tc="res://.godot/imported/MASK 03.PNG-9ab390330efa1f35084ad56075377b4d.s3tc.ctex"
metadata={ metadata={
"vram_texture": false "imported_formats": ["s3tc_bptc"],
"vram_texture": true
} }
[deps] [deps]
source_file="res://src/items/accessory/textures/MASK 03.PNG" source_file="res://src/items/accessory/textures/MASK 03.PNG"
dest_files=["res://.godot/imported/MASK 03.PNG-9ab390330efa1f35084ad56075377b4d.ctex"] dest_files=["res://.godot/imported/MASK 03.PNG-9ab390330efa1f35084ad56075377b4d.s3tc.ctex"]
[params] [params]
compress/mode=0 compress/mode=2
compress/high_quality=false compress/high_quality=false
compress/lossy_quality=0.7 compress/lossy_quality=0.7
compress/hdr_compression=1 compress/hdr_compression=1
compress/normal_map=0 compress/normal_map=0
compress/channel_pack=0 compress/channel_pack=0
mipmaps/generate=false mipmaps/generate=true
mipmaps/limit=-1 mipmaps/limit=-1
roughness/mode=0 roughness/mode=0
roughness/src_normal="" roughness/src_normal=""
@@ -31,4 +32,4 @@ process/normal_map_invert_y=false
process/hdr_as_srgb=false process/hdr_as_srgb=false
process/hdr_clamp_exposure=false process/hdr_clamp_exposure=false
process/size_limit=0 process/size_limit=0
detect_3d/compress_to=1 detect_3d/compress_to=0

View File

@@ -3,22 +3,18 @@ using Chickensoft.Introspection;
using GameJamDungeon; using GameJamDungeon;
using Godot; using Godot;
using System; using System;
using System.Collections.Generic;
using System.Linq;
[Meta(typeof(IAutoNode))] [Meta(typeof(IAutoNode))]
public partial class Armor : Node3D, IInventoryItem, IEquipable public partial class Armor : Node3D, IInventoryItem, IEquipable
{ {
public override void _Notification(int what) => this.Notify(what); public override void _Notification(int what) => this.Notify(what);
public Guid ID { get; } = new Guid();
[Dependency] public IGameRepo GameRepo => this.DependOn<IGameRepo>(); [Dependency] public IGameRepo GameRepo => this.DependOn<IGameRepo>();
public InventoryItemInfo Info => ArmorInfo; public InventoryItemStats Info => ArmorStats;
[Export] [Export]
public ArmorInfo ArmorInfo { get; set; } = new ArmorInfo(); public ArmorStats ArmorStats { get; set; } = new ArmorStats();
[Node] public Sprite3D Sprite { get; set; } = default!; [Node] public Sprite3D Sprite { get; set; } = default!;
@@ -26,27 +22,24 @@ public partial class Armor : Node3D, IInventoryItem, IEquipable
public void OnReady() public void OnReady()
{ {
Sprite.Texture = ArmorInfo.Texture; Sprite.Texture = ArmorStats.Texture;
Pickup.BodyEntered += OnEntered; Pickup.BodyEntered += OnEntered;
} }
public void Throw() public void Throw()
{ {
GameRepo.InventoryItems.Value.Remove(this); GameRepo.PlayerData.Inventory.Remove(this);
} }
public void Drop() public void Drop()
{ {
GameRepo.InventoryItems.Value.Remove(this); GameRepo.PlayerData.Inventory.Remove(this);
} }
public void OnEntered(Node3D body) public void OnEntered(Node3D body)
{ {
if (GameRepo.InventoryItems.Value.Count() >= GameRepo.MaxItemSize) var isAdded = GameRepo.PlayerData.Inventory.TryAdd(this);
return; if (isAdded)
QueueFree();
var inventoryList = GameRepo.InventoryItems.Value.Append(this).ToList();
GameRepo.InventoryItems.OnNext(inventoryList);
QueueFree();
} }
} }

View File

@@ -3,7 +3,7 @@
namespace GameJamDungeon; namespace GameJamDungeon;
[GlobalClass] [GlobalClass]
public partial class ArmorInfo : InventoryItemInfo public partial class ArmorStats : InventoryItemStats
{ {
[Export] [Export]
public int Defense { get; set; } = 0; public int Defense { get; set; } = 0;

View File

@@ -1,7 +1,7 @@
[gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://b8mjje06x6dl1"] [gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://b8mjje06x6dl1"]
[ext_resource type="Texture2D" uid="uid://dbb3x4cbo8jc1" path="res://src/items/armor/textures/ACCEPTANCE.PNG" id="1_p85jd"] [ext_resource type="Texture2D" uid="uid://dbb3x4cbo8jc1" path="res://src/items/armor/textures/ACCEPTANCE.PNG" id="1_p85jd"]
[ext_resource type="Script" path="res://src/items/armor/ArmorInfo.cs" id="1_si4wu"] [ext_resource type="Script" path="res://src/items/armor/ArmorStats.cs" id="1_si4wu"]
[resource] [resource]
script = ExtResource("1_si4wu") script = ExtResource("1_si4wu")

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://ce2vfa2t3io67"] [gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://ce2vfa2t3io67"]
[ext_resource type="Script" path="res://src/items/armor/ArmorInfo.cs" id="1_6r2bl"] [ext_resource type="Script" path="res://src/items/armor/ArmorStats.cs" id="1_6r2bl"]
[ext_resource type="Texture2D" uid="uid://ckcn67d64mgke" path="res://src/items/armor/textures/atoners adornment.PNG" id="1_588l8"] [ext_resource type="Texture2D" uid="uid://ckcn67d64mgke" path="res://src/items/armor/textures/atoners adornment.PNG" id="1_588l8"]
[resource] [resource]

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://dnu241lh47oqd"] [gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://dnu241lh47oqd"]
[ext_resource type="Script" path="res://src/items/armor/ArmorInfo.cs" id="1_0qtvf"] [ext_resource type="Script" path="res://src/items/armor/ArmorStats.cs" id="1_0qtvf"]
[ext_resource type="Texture2D" uid="uid://vvhbibkslh57" path="res://src/items/armor/textures/CEREMONIAL.PNG" id="1_s4gpg"] [ext_resource type="Texture2D" uid="uid://vvhbibkslh57" path="res://src/items/armor/textures/CEREMONIAL.PNG" id="1_s4gpg"]
[resource] [resource]

View File

@@ -1,7 +1,7 @@
[gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://4s7wjsb7eb6e"] [gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://4s7wjsb7eb6e"]
[ext_resource type="Texture2D" uid="uid://381ddynsa3gc" path="res://src/items/armor/textures/DEVIC.PNG" id="1_5ik54"] [ext_resource type="Texture2D" uid="uid://381ddynsa3gc" path="res://src/items/armor/textures/DEVIC.PNG" id="1_5ik54"]
[ext_resource type="Script" path="res://src/items/armor/ArmorInfo.cs" id="1_w3lql"] [ext_resource type="Script" path="res://src/items/armor/ArmorStats.cs" id="1_w3lql"]
[resource] [resource]
script = ExtResource("1_w3lql") script = ExtResource("1_w3lql")

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://dc0qjer88chme"] [gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://dc0qjer88chme"]
[ext_resource type="Script" path="res://src/items/armor/ArmorInfo.cs" id="1_3mc7x"] [ext_resource type="Script" path="res://src/items/armor/ArmorStats.cs" id="1_3mc7x"]
[ext_resource type="Texture2D" uid="uid://c57kuugsc2lti" path="res://src/items/armor/textures/GODDESS.PNG" id="1_5vleh"] [ext_resource type="Texture2D" uid="uid://c57kuugsc2lti" path="res://src/items/armor/textures/GODDESS.PNG" id="1_5vleh"]
[resource] [resource]

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://ceqnyutl7y7t4"] [gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://ceqnyutl7y7t4"]
[ext_resource type="Script" path="res://src/items/armor/ArmorInfo.cs" id="1_iqj2w"] [ext_resource type="Script" path="res://src/items/armor/ArmorStats.cs" id="1_iqj2w"]
[ext_resource type="Texture2D" uid="uid://cj5m8qkpqrcx4" path="res://src/items/armor/textures/IRON.PNG" id="1_jyoar"] [ext_resource type="Texture2D" uid="uid://cj5m8qkpqrcx4" path="res://src/items/armor/textures/IRON.PNG" id="1_jyoar"]
[resource] [resource]

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://chhxktntl4k8r"] [gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://chhxktntl4k8r"]
[ext_resource type="Script" path="res://src/items/armor/ArmorInfo.cs" id="1_frqfh"] [ext_resource type="Script" path="res://src/items/armor/ArmorStats.cs" id="1_frqfh"]
[ext_resource type="Texture2D" uid="uid://2qvbtq2obsac" path="res://src/items/armor/textures/LOGISTIAN.PNG" id="1_kh3n2"] [ext_resource type="Texture2D" uid="uid://2qvbtq2obsac" path="res://src/items/armor/textures/LOGISTIAN.PNG" id="1_kh3n2"]
[resource] [resource]

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://d3l8aa87tevgt"] [gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://d3l8aa87tevgt"]
[ext_resource type="Script" path="res://src/items/armor/ArmorInfo.cs" id="1_dh6tr"] [ext_resource type="Script" path="res://src/items/armor/ArmorStats.cs" id="1_dh6tr"]
[ext_resource type="Texture2D" uid="uid://ddtscpfj6nf6i" path="res://src/items/armor/textures/STOIC.PNG" id="1_xpphu"] [ext_resource type="Texture2D" uid="uid://ddtscpfj6nf6i" path="res://src/items/armor/textures/STOIC.PNG" id="1_xpphu"]
[resource] [resource]

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://dq4c6an78qa4q"] [gd_resource type="Resource" script_class="ArmorInfo" load_steps=3 format=3 uid="uid://dq4c6an78qa4q"]
[ext_resource type="Script" path="res://src/items/armor/ArmorInfo.cs" id="1_bkpin"] [ext_resource type="Script" path="res://src/items/armor/ArmorStats.cs" id="1_bkpin"]
[ext_resource type="Texture2D" uid="uid://dghvd33w32q63" path="res://src/items/armor/textures/WOODEN.PNG" id="1_vs6ua"] [ext_resource type="Texture2D" uid="uid://dghvd33w32q63" path="res://src/items/armor/textures/WOODEN.PNG" id="1_vs6ua"]
[resource] [resource]

View File

@@ -10,14 +10,12 @@ public partial class ConsumableItem : Node3D, IInventoryItem
{ {
public override void _Notification(int what) => this.Notify(what); public override void _Notification(int what) => this.Notify(what);
public Guid ID { get; } = new Guid();
[Dependency] public IGameRepo GameRepo => this.DependOn<IGameRepo>(); [Dependency] public IGameRepo GameRepo => this.DependOn<IGameRepo>();
public InventoryItemInfo Info => ConsumableItemInfo; public InventoryItemStats Info => ConsumableItemInfo;
[Export] [Export]
public ConsumableItemInfo ConsumableItemInfo { get; set; } public ConsumableItemStats ConsumableItemInfo { get; set; }
[Node] public Sprite3D Sprite { get; set; } = default!; [Node] public Sprite3D Sprite { get; set; } = default!;
@@ -40,54 +38,51 @@ public partial class ConsumableItem : Node3D, IInventoryItem
if (ConsumableItemInfo.HealVTAmount != 0) if (ConsumableItemInfo.HealVTAmount != 0)
HealVT(); HealVT();
GameRepo.InventoryItems.Value.Remove(this); GameRepo.PlayerData.Inventory.Remove(this);
} }
private void RaiseHP() private void RaiseHP()
{ {
if (GameRepo.PlayerStatInfo.Value.CurrentHP == GameRepo.PlayerStatInfo.Value.MaximumHP) if (GameRepo.PlayerData.CurrentHP == GameRepo.PlayerData.MaximumHP)
{ {
GameRepo.PlayerStatInfo.Value.MaximumHP += ConsumableItemInfo.RaiseHPAmount; GameRepo.PlayerData.MaximumHP.OnNext(GameRepo.PlayerData.MaximumHP.Value + ConsumableItemInfo.RaiseHPAmount);
GameRepo.PlayerStatInfo.Value.CurrentHP = GameRepo.PlayerStatInfo.Value.MaximumHP; GameRepo.PlayerData.CurrentHP.OnNext(GameRepo.PlayerData.MaximumHP.Value);
} }
} }
private void HealHP() private void HealHP()
{ {
GameRepo.PlayerStatInfo.Value.CurrentHP += ConsumableItemInfo.HealHPAmount; GameRepo.PlayerData.CurrentHP.OnNext(GameRepo.PlayerData.CurrentHP.Value + ConsumableItemInfo.HealHPAmount);
} }
private void RaiseVT() private void RaiseVT()
{ {
if (GameRepo.PlayerStatInfo.Value.CurrentVT == GameRepo.PlayerStatInfo.Value.MaximumVT) if (GameRepo.PlayerData.CurrentVT == GameRepo.PlayerData.MaximumVT)
{ {
GameRepo.PlayerStatInfo.Value.MaximumVT += ConsumableItemInfo.RaiseVTAmount; GameRepo.PlayerData.MaximumVT.OnNext(GameRepo.PlayerData.MaximumVT.Value + ConsumableItemInfo.RaiseVTAmount);
GameRepo.PlayerStatInfo.Value.CurrentVT = GameRepo.PlayerStatInfo.Value.MaximumVT; GameRepo.PlayerData.CurrentVT.OnNext(GameRepo.PlayerData.MaximumVT.Value);
} }
} }
private void HealVT() private void HealVT()
{ {
GameRepo.PlayerStatInfo.Value.CurrentVT += ConsumableItemInfo.HealVTAmount; GameRepo.PlayerData.CurrentVT.OnNext(GameRepo.PlayerData.CurrentVT.Value + ConsumableItemInfo.HealVTAmount);
} }
public void Throw() public void Throw()
{ {
GameRepo.InventoryItems.Value.Remove(this); GameRepo.PlayerData.Inventory.Remove(this);
} }
public void Drop() public void Drop()
{ {
GameRepo.InventoryItems.Value.Remove(this); GameRepo.PlayerData.Inventory.Remove(this);
} }
public void OnEntered(Node3D body) public void OnEntered(Node3D body)
{ {
if (GameRepo.InventoryItems.Value.Count() >= GameRepo.MaxItemSize) var isAdded = GameRepo.PlayerData.Inventory.TryAdd(this);
return; if (isAdded)
QueueFree();
var inventoryList = GameRepo.InventoryItems.Value.Append(this).ToList();
GameRepo.InventoryItems.OnNext(inventoryList);
QueueFree();
} }
} }

View File

@@ -1,12 +1,17 @@
[gd_scene load_steps=5 format=3 uid="uid://c6w7dpk0hurj0"] [gd_scene load_steps=5 format=3 uid="uid://c6w7dpk0hurj0"]
[ext_resource type="Script" path="res://src/items/consumable/ConsumableItem.cs" id="1_26bad"] [ext_resource type="Script" path="res://src/items/consumable/ConsumableItem.cs" id="1_26bad"]
[ext_resource type="Script" path="res://src/items/consumable/ConsumableItemInfo.cs" id="2_g3oo3"] [ext_resource type="Script" path="res://src/items/consumable/ConsumableItemStats.cs" id="2_g3oo3"]
[sub_resource type="Resource" id="Resource_33w5s"] [sub_resource type="Resource" id="Resource_33w5s"]
script = ExtResource("2_g3oo3") script = ExtResource("2_g3oo3")
HealHPAmount = 0
RaiseHPAmount = 0
HealVTAmount = 0
RaiseVTAmount = 0
Name = "" Name = ""
Description = "" Description = ""
SpawnRate = 0.5
[sub_resource type="BoxShape3D" id="BoxShape3D_7mh0f"] [sub_resource type="BoxShape3D" id="BoxShape3D_7mh0f"]
size = Vector3(0.778381, 0.929947, 0.731567) size = Vector3(0.778381, 0.929947, 0.731567)

View File

@@ -3,7 +3,7 @@
namespace GameJamDungeon; namespace GameJamDungeon;
[GlobalClass] [GlobalClass]
public partial class ConsumableItemInfo : InventoryItemInfo public partial class ConsumableItemStats : InventoryItemStats
{ {
[Export] [Export]
public int HealHPAmount { get; set; } = 0; public int HealHPAmount { get; set; } = 0;

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="ConsumableItemInfo" load_steps=3 format=3 uid="uid://75fpkwfp0t0k"] [gd_resource type="Resource" script_class="ConsumableItemInfo" load_steps=3 format=3 uid="uid://75fpkwfp0t0k"]
[ext_resource type="Script" path="res://src/items/consumable/ConsumableItemInfo.cs" id="1_f8ogj"] [ext_resource type="Script" path="res://src/items/consumable/ConsumableItemStats.cs" id="1_f8ogj"]
[ext_resource type="Texture2D" uid="uid://dbl5v5i1s3m2u" path="res://src/items/consumable/textures/stelo fragment.PNG" id="1_ic5xm"] [ext_resource type="Texture2D" uid="uid://dbl5v5i1s3m2u" path="res://src/items/consumable/textures/stelo fragment.PNG" id="1_ic5xm"]
[resource] [resource]

View File

@@ -11,18 +11,18 @@ public partial class ThrowableItem : Node3D, IInventoryItem
{ {
public override void _Notification(int what) => this.Notify(what); public override void _Notification(int what) => this.Notify(what);
public Guid ID { get; } = new Guid();
[Dependency] public IGameRepo GameRepo => this.DependOn<IGameRepo>(); [Dependency] public IGameRepo GameRepo => this.DependOn<IGameRepo>();
[Node] public IAnimationPlayer AnimationPlayer { get; set; } = default!; [Node] public IAnimationPlayer AnimationPlayer { get; set; } = default!;
[Node] public IHitbox Hitbox { get; set; } = default!; [Node] public IHitbox Hitbox { get; set; } = default!;
public InventoryItemInfo Info => ThrowableItemInfo; public InventoryItemStats Info => ThrowableItemInfo;
public int Count { get; }
[Export] [Export]
public ThrowableItemInfo ThrowableItemInfo { get; set; } public ThrowableItemStats ThrowableItemInfo { get; set; }
[Node] public Sprite3D Sprite { get; set; } = default!; [Node] public Sprite3D Sprite { get; set; } = default!;
@@ -37,22 +37,19 @@ public partial class ThrowableItem : Node3D, IInventoryItem
public void Throw() public void Throw()
{ {
GameRepo.InventoryItems.Value.Remove(this); GameRepo.PlayerData.Inventory.Remove(this);
} }
public void Drop() public void Drop()
{ {
GameRepo.InventoryItems.Value.Remove(this); GameRepo.PlayerData.Inventory.Remove(this);
} }
public void OnEntered(Node3D body) public void OnEntered(Node3D body)
{ {
if (GameRepo.InventoryItems.Value.Count() >= GameRepo.MaxItemSize) var isAdded = GameRepo.PlayerData.Inventory.TryAdd(this);
return; if (isAdded)
QueueFree();
var inventoryList = GameRepo.InventoryItems.Value.Append(this).ToList();
GameRepo.InventoryItems.OnNext(inventoryList);
QueueFree();
} }
private void OnAnimationFinished(StringName animName) private void OnAnimationFinished(StringName animName)

View File

@@ -3,7 +3,7 @@
namespace GameJamDungeon; namespace GameJamDungeon;
[GlobalClass] [GlobalClass]
public partial class ThrowableItemInfo : InventoryItemInfo public partial class ThrowableItemStats : InventoryItemStats
{ {
[Export] [Export]
public Godot.Collections.Array<ThrowableItemTag> ThrowableItemTags { get; set; } = new Godot.Collections.Array<ThrowableItemTag>(); public Godot.Collections.Array<ThrowableItemTag> ThrowableItemTags { get; set; } = new Godot.Collections.Array<ThrowableItemTag>();

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="ThrowableItemInfo" load_steps=3 format=3 uid="uid://bph8c6by4s047"] [gd_resource type="Resource" script_class="ThrowableItemStats" load_steps=3 format=3 uid="uid://bph8c6by4s047"]
[ext_resource type="Script" path="res://src/items/throwable/ThrowableItemInfo.cs" id="1_ewck5"] [ext_resource type="Script" path="res://src/items/throwable/ThrowableItemStats.cs" id="1_ewck5"]
[ext_resource type="Texture2D" uid="uid://mi70lolgtf3n" path="res://src/items/throwable/textures/GEOMANCER-DICE.png" id="1_jhits"] [ext_resource type="Texture2D" uid="uid://mi70lolgtf3n" path="res://src/items/throwable/textures/GEOMANCER-DICE.png" id="1_jhits"]
[resource] [resource]

View File

@@ -1,7 +1,7 @@
[gd_resource type="Resource" script_class="ThrowableItemInfo" load_steps=3 format=3 uid="uid://qqg0gdcb8fwg"] [gd_resource type="Resource" script_class="ThrowableItemInfo" load_steps=3 format=3 uid="uid://qqg0gdcb8fwg"]
[ext_resource type="Texture2D" uid="uid://dhfn51smm818x" path="res://src/items/throwable/textures/spell sign - luck.PNG" id="1_3605p"] [ext_resource type="Texture2D" uid="uid://dhfn51smm818x" path="res://src/items/throwable/textures/spell sign - luck.PNG" id="1_3605p"]
[ext_resource type="Script" path="res://src/items/throwable/ThrowableItemInfo.cs" id="1_s3pq7"] [ext_resource type="Script" path="res://src/items/throwable/ThrowableItemStats.cs" id="1_s3pq7"]
[resource] [resource]
script = ExtResource("1_s3pq7") script = ExtResource("1_s3pq7")

View File

@@ -3,21 +3,18 @@ using Chickensoft.Introspection;
using GameJamDungeon; using GameJamDungeon;
using Godot; using Godot;
using System; using System;
using System.Linq;
[Meta(typeof(IAutoNode))] [Meta(typeof(IAutoNode))]
public partial class Weapon : Node3D, IInventoryItem, IEquipable public partial class Weapon : Node3D, IInventoryItem, IEquipable
{ {
public override void _Notification(int what) => this.Notify(what); public override void _Notification(int what) => this.Notify(what);
public Guid ID { get; } = new Guid();
[Dependency] public IGameRepo GameRepo => this.DependOn<IGameRepo>(); [Dependency] public IGameRepo GameRepo => this.DependOn<IGameRepo>();
public InventoryItemInfo Info => WeaponInfo; public InventoryItemStats Info => WeaponStats;
[Export] [Export]
public WeaponInfo WeaponInfo { get; set; } = new WeaponInfo(); public WeaponStats WeaponStats { get; set; } = new WeaponStats();
[Node] public Sprite3D Sprite { get; set; } = default!; [Node] public Sprite3D Sprite { get; set; } = default!;
@@ -25,27 +22,24 @@ public partial class Weapon : Node3D, IInventoryItem, IEquipable
public void OnReady() public void OnReady()
{ {
Sprite.Texture = WeaponInfo.Texture; Sprite.Texture = WeaponStats.Texture;
Pickup.BodyEntered += OnEntered; Pickup.BodyEntered += OnEntered;
} }
public void Throw() public void Throw()
{ {
GameRepo.InventoryItems.Value.Remove(this); GameRepo.PlayerData.Inventory.Remove(this);
} }
public void Drop() public void Drop()
{ {
GameRepo.InventoryItems.Value.Remove(this); GameRepo.PlayerData.Inventory.Remove(this);
} }
public void OnEntered(Node3D body) public void OnEntered(Node3D body)
{ {
if (GameRepo.InventoryItems.Value.Count() >= GameRepo.MaxItemSize) var isAdded = GameRepo.PlayerData.Inventory.TryAdd(this);
return; if (isAdded)
QueueFree();
var inventoryList = GameRepo.InventoryItems.Value.Append(this).ToList();
GameRepo.InventoryItems.OnNext(inventoryList);
QueueFree();
} }
} }

View File

@@ -2,7 +2,7 @@ using GameJamDungeon;
using Godot; using Godot;
[GlobalClass] [GlobalClass]
public partial class WeaponInfo : InventoryItemInfo public partial class WeaponStats : InventoryItemStats
{ {
[Export] [Export]
public int Damage { get; set; } = 0; public int Damage { get; set; } = 0;

View File

@@ -1,7 +1,7 @@
[gd_resource type="Resource" script_class="WeaponInfo" load_steps=3 format=3 uid="uid://c1bg0o7nmu2xw"] [gd_resource type="Resource" script_class="WeaponInfo" load_steps=3 format=3 uid="uid://c1bg0o7nmu2xw"]
[ext_resource type="Texture2D" uid="uid://cil3xe3jq82r6" path="res://src/items/weapons/textures/JIBLETT.PNG" id="1_ifm43"] [ext_resource type="Texture2D" uid="uid://cil3xe3jq82r6" path="res://src/items/weapons/textures/JIBLETT.PNG" id="1_ifm43"]
[ext_resource type="Script" path="res://src/items/weapons/WeaponInfo.cs" id="1_re512"] [ext_resource type="Script" path="res://src/items/weapons/WeaponStats.cs" id="1_re512"]
[resource] [resource]
script = ExtResource("1_re512") script = ExtResource("1_re512")

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="WeaponInfo" load_steps=3 format=3 uid="uid://db075qhmlmrcu"] [gd_resource type="Resource" script_class="WeaponInfo" load_steps=3 format=3 uid="uid://db075qhmlmrcu"]
[ext_resource type="Script" path="res://src/items/weapons/WeaponInfo.cs" id="1_kbje7"] [ext_resource type="Script" path="res://src/items/weapons/WeaponStats.cs" id="1_kbje7"]
[ext_resource type="Texture2D" uid="uid://bkntmni5jxfpk" path="res://src/items/weapons/textures/KUBEL.PNG" id="1_kwtbu"] [ext_resource type="Texture2D" uid="uid://bkntmni5jxfpk" path="res://src/items/weapons/textures/KUBEL.PNG" id="1_kwtbu"]
[resource] [resource]

View File

@@ -1,7 +1,7 @@
[gd_resource type="Resource" script_class="WeaponInfo" load_steps=3 format=3 uid="uid://cfr100khjkloh"] [gd_resource type="Resource" script_class="WeaponInfo" load_steps=3 format=3 uid="uid://cfr100khjkloh"]
[ext_resource type="Texture2D" uid="uid://blq3nnyostunl" path="res://src/items/weapons/textures/LOVE JUDGEMENT.PNG" id="1_ivlxj"] [ext_resource type="Texture2D" uid="uid://blq3nnyostunl" path="res://src/items/weapons/textures/LOVE JUDGEMENT.PNG" id="1_ivlxj"]
[ext_resource type="Script" path="res://src/items/weapons/WeaponInfo.cs" id="1_vroib"] [ext_resource type="Script" path="res://src/items/weapons/WeaponStats.cs" id="1_vroib"]
[resource] [resource]
script = ExtResource("1_vroib") script = ExtResource("1_vroib")

View File

@@ -1,7 +1,7 @@
[gd_resource type="Resource" script_class="WeaponInfo" load_steps=3 format=3 uid="uid://ckj1m4iv4m02r"] [gd_resource type="Resource" script_class="WeaponInfo" load_steps=3 format=3 uid="uid://ckj1m4iv4m02r"]
[ext_resource type="Texture2D" uid="uid://740syoj0w14p" path="res://src/items/weapons/textures/PALM OF HEAVEN.PNG" id="1_hi6xm"] [ext_resource type="Texture2D" uid="uid://740syoj0w14p" path="res://src/items/weapons/textures/PALM OF HEAVEN.PNG" id="1_hi6xm"]
[ext_resource type="Script" path="res://src/items/weapons/WeaponInfo.cs" id="1_pwwg7"] [ext_resource type="Script" path="res://src/items/weapons/WeaponStats.cs" id="1_pwwg7"]
[resource] [resource]
script = ExtResource("1_pwwg7") script = ExtResource("1_pwwg7")

View File

@@ -1,7 +1,7 @@
[gd_resource type="Resource" script_class="WeaponInfo" load_steps=3 format=3 uid="uid://gebgo2x6nr3t"] [gd_resource type="Resource" script_class="WeaponInfo" load_steps=3 format=3 uid="uid://gebgo2x6nr3t"]
[ext_resource type="Texture2D" uid="uid://b8c7kd436tg4" path="res://src/items/weapons/textures/RONDO.PNG" id="1_cvwbh"] [ext_resource type="Texture2D" uid="uid://b8c7kd436tg4" path="res://src/items/weapons/textures/RONDO.PNG" id="1_cvwbh"]
[ext_resource type="Script" path="res://src/items/weapons/WeaponInfo.cs" id="1_xfb0x"] [ext_resource type="Script" path="res://src/items/weapons/WeaponStats.cs" id="1_xfb0x"]
[resource] [resource]
script = ExtResource("1_xfb0x") script = ExtResource("1_xfb0x")

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="WeaponInfo" load_steps=3 format=3 uid="uid://b7xr0l4a8g1gk"] [gd_resource type="Resource" script_class="WeaponInfo" load_steps=3 format=3 uid="uid://b7xr0l4a8g1gk"]
[ext_resource type="Script" path="res://src/items/weapons/WeaponInfo.cs" id="1_40b5j"] [ext_resource type="Script" path="res://src/items/weapons/WeaponStats.cs" id="1_40b5j"]
[ext_resource type="Texture2D" uid="uid://b1qbho30vnuxf" path="res://src/items/weapons/textures/sealing rod.PNG" id="1_wiylj"] [ext_resource type="Texture2D" uid="uid://b1qbho30vnuxf" path="res://src/items/weapons/textures/sealing rod.PNG" id="1_wiylj"]
[resource] [resource]

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="WeaponInfo" load_steps=3 format=3 uid="uid://bpdbuf0k0exb5"] [gd_resource type="Resource" script_class="WeaponInfo" load_steps=3 format=3 uid="uid://bpdbuf0k0exb5"]
[ext_resource type="Script" path="res://src/items/weapons/WeaponInfo.cs" id="1_cik6n"] [ext_resource type="Script" path="res://src/items/weapons/WeaponStats.cs" id="1_cik6n"]
[ext_resource type="Texture2D" uid="uid://cvtcsi2sagfwm" path="res://src/items/weapons/textures/SWAN SWORD.PNG" id="1_qc4eu"] [ext_resource type="Texture2D" uid="uid://cvtcsi2sagfwm" path="res://src/items/weapons/textures/SWAN SWORD.PNG" id="1_qc4eu"]
[resource] [resource]

View File

@@ -5,14 +5,21 @@ using DialogueManagerRuntime;
using Godot; using Godot;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
namespace GameJamDungeon; namespace GameJamDungeon;
public interface IMap : INode3D public interface IMap : INode3D
{ {
event Map.TeleportReachedEventHandler TeleportReached;
event Map.DialogueDecisionMadeEventHandler DialogueDecisionMade;
event Map.DungeonFinishedGeneratingEventHandler DungeonFinishedGenerating;
public List<IDungeonFloor> Floors { get; } public List<IDungeonFloor> Floors { get; }
public Vector3 GetPlayerSpawnPoint(); public Vector3 GetPlayerSpawnPoint();
public void SpawnNextFloor();
} }
@@ -23,6 +30,15 @@ public partial class Map : Node3D, IMap
[Node] public Area3D Teleport { get; set; } = default!; [Node] public Area3D Teleport { get; set; } = default!;
[Signal]
public delegate void TeleportReachedEventHandler();
[Signal]
public delegate void DialogueDecisionMadeEventHandler();
[Signal]
public delegate void DungeonFinishedGeneratingEventHandler();
public List<IDungeonFloor> Floors { get; set; } = default!; public List<IDungeonFloor> Floors { get; set; } = default!;
private IDungeonFloor _currentFloor; private IDungeonFloor _currentFloor;
@@ -32,6 +48,8 @@ public partial class Map : Node3D, IMap
Floors = GetChildren().OfType<IDungeonFloor>().ToList(); Floors = GetChildren().OfType<IDungeonFloor>().ToList();
_currentFloor = Floors.ElementAt(0); _currentFloor = Floors.ElementAt(0);
Teleport.BodyEntered += OnTeleportEntered; Teleport.BodyEntered += OnTeleportEntered;
Teleport.GlobalPosition = _currentFloor.GetTeleportSpawnPoint();
DialogueManager.DialogueEnded += DecisionMade;
} }
public Vector3 GetPlayerSpawnPoint() public Vector3 GetPlayerSpawnPoint()
@@ -39,10 +57,27 @@ public partial class Map : Node3D, IMap
return _currentFloor.GetPlayerSpawnPoint(); return _currentFloor.GetPlayerSpawnPoint();
} }
public void SpawnNextFloor()
{
var oldFloor = _currentFloor;
Floors.Remove(oldFloor);
oldFloor.CallDeferred(MethodName.QueueFree, []);
_currentFloor = Floors.ElementAt(0);
_currentFloor.InitializeDungeon();
Teleport.GlobalPosition = _currentFloor.GetTeleportSpawnPoint();
EmitSignal(SignalName.DungeonFinishedGenerating);
}
private void DecisionMade(Resource resource)
{
EmitSignal(SignalName.DialogueDecisionMade);
}
private void OnTeleportEntered(Node3D body) private void OnTeleportEntered(Node3D body)
{ {
DialogueManager.GetCurrentScene = (() => this); DialogueManager.GetCurrentScene = (() => this);
var dialogueResource = GD.Load<Resource>("res://src/ui/dialogue/FloorExit.dialogue"); var dialogueResource = GD.Load<Resource>("res://src/ui/dialogue/FloorExit.dialogue");
DialogueController.ShowDialogue(dialogueResource, "floor_exit"); DialogueController.ShowDialogue(dialogueResource, "floor_exit");
EmitSignal(SignalName.TeleportReached);
} }
} }

View File

@@ -2,12 +2,16 @@ using Chickensoft.AutoInject;
using Chickensoft.GodotNodeInterfaces; using Chickensoft.GodotNodeInterfaces;
using Chickensoft.Introspection; using Chickensoft.Introspection;
using Godot; using Godot;
using System.Collections.Generic;
using System.Linq;
public interface IDungeonFloor : INode3D public interface IDungeonFloor : INode3D
{ {
void InitializeDungeon(); void InitializeDungeon();
public Vector3 GetPlayerSpawnPoint(); public Vector3 GetPlayerSpawnPoint();
public Vector3 GetTeleportSpawnPoint();
} }
[Meta(typeof(IAutoNode))] [Meta(typeof(IAutoNode))]
@@ -17,13 +21,34 @@ public partial class DungeonFloor : Node3D, IDungeonFloor
[Node] public GodotObject DungeonGenerator { get; set; } = default!; [Node] public GodotObject DungeonGenerator { get; set; } = default!;
internal List<IDungeonRoom> Rooms { get; private set; }
public void InitializeDungeon() public void InitializeDungeon()
{ {
Rooms = new List<IDungeonRoom>();
DungeonGenerator.Call("generate"); DungeonGenerator.Call("generate");
Rooms = FindAllDungeonRooms(GetChildren().ToList(), Rooms);
} }
public Vector3 GetPlayerSpawnPoint() public Vector3 GetPlayerSpawnPoint()
{ {
return Vector3.Zero; return Rooms.First().PlayerSpawn.GlobalPosition;
}
public Vector3 GetTeleportSpawnPoint()
{
return Rooms.First().TeleportSpawn.GlobalPosition;
}
private List<IDungeonRoom> FindAllDungeonRooms(List<Node> nodesToSearch, List<IDungeonRoom> roomsFound)
{
if (nodesToSearch.Count == 0)
return roomsFound;
foreach (var node in nodesToSearch)
if (node is IDungeonRoom dungeonRoom)
roomsFound.Add(dungeonRoom);
return FindAllDungeonRooms(nodesToSearch.SelectMany(x => x.GetChildren()).ToList(), roomsFound);
} }
} }

View File

@@ -13,6 +13,8 @@ public partial class Overworld : Node3D, IDungeonFloor
[Node] public Marker3D PlayerSpawnPoint { get; set; } = default!; [Node] public Marker3D PlayerSpawnPoint { get; set; } = default!;
[Node] public Marker3D ExitSpawnPoint { get; set; } = default!;
public void InitializeDungeon() public void InitializeDungeon()
{ {
GameRepo.SetPlayerGlobalPosition(PlayerSpawnPoint.GlobalPosition); GameRepo.SetPlayerGlobalPosition(PlayerSpawnPoint.GlobalPosition);
@@ -22,4 +24,9 @@ public partial class Overworld : Node3D, IDungeonFloor
{ {
return PlayerSpawnPoint.GlobalPosition; return PlayerSpawnPoint.GlobalPosition;
} }
public Vector3 GetTeleportSpawnPoint()
{
return ExitSpawnPoint.GlobalPosition;
}
} }

View File

@@ -1097,15 +1097,18 @@ data = PackedVector3Array(0.5414, 0.1147, -0.9114, -0.5965, 0.1148, -1.0371, -0.
size = Vector2(35, 30) size = Vector2(35, 30)
[node name="Antechamber" type="Node3D"] [node name="Antechamber" type="Node3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.73082, 0, -1.86841) transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 1.73082, 0, -1.86841)
script = ExtResource("1_tdydv") script = ExtResource("1_tdydv")
size_in_voxels = Vector3i(5, 2, 5)
voxel_scale = Vector3(12, 12, 12)
[node name="Room" type="Node3D" parent="."] [node name="Room" type="Node3D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -6.03201, 0)
script = ExtResource("16_osbes") script = ExtResource("16_osbes")
[node name="NavigationRegion3D" type="NavigationRegion3D" parent="Room"] [node name="NavigationRegion3D" type="NavigationRegion3D" parent="Room"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.04836, 3.10489, 12.6166) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.04836, 9.49697, 12.6166)
navigation_mesh = SubResource("NavigationMesh_2x5qh") navigation_mesh = SubResource("NavigationMesh_2x5qh")
[node name="ANTECHAMBER" type="Node3D" parent="Room/NavigationRegion3D"] [node name="ANTECHAMBER" type="Node3D" parent="Room/NavigationRegion3D"]
@@ -1196,15 +1199,9 @@ skeleton = NodePath("")
transform = Transform3D(0, 0, -0.515006, 0, 0.54653, 0, 0.593558, 0, 0, 116.446, 7.82144, 86.6174) transform = Transform3D(0, 0, -0.515006, 0, 0.54653, 0, 0.593558, 0, 0, 116.446, 7.82144, 86.6174)
shape = SubResource("ConcavePolygonShape3D_cnvi5") shape = SubResource("ConcavePolygonShape3D_cnvi5")
[node name="DOOR" type="Marker3D" parent="Room"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.1142, -8.45784, 32.0232)
[node name="DOOR2" type="Marker3D" parent="Room"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.92078, -8.62051, -27.067)
[node name="PlayerSpawn" type="Marker3D" parent="Room"] [node name="PlayerSpawn" type="Marker3D" parent="Room"]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -11.8813, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -5.38078, 0)
[node name="Minimap Texture" type="MeshInstance3D" parent="Room"] [node name="Minimap Texture" type="MeshInstance3D" parent="Room"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.00325966, -7.7801, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.00325966, -7.7801, 0)
@@ -1217,170 +1214,170 @@ skeleton = NodePath("../..")
unique_name_in_owner = true unique_name_in_owner = true
[node name="ItemSpawn1" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn1" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.83448, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.83448, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn2" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn2" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.44186, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.44186, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn3" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn3" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.09183, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.09183, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn4" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn4" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.83448, -11.8091, -5.86665) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.83448, -5.49583, -5.86665)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn5" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn5" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.21845, -11.8091, -5.59059) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.21845, -5.49583, -5.59059)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn6" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn6" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn7" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn7" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn8" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn8" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn9" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn9" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn10" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn10" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn11" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn11" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn12" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn12" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn13" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn13" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn14" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn14" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn15" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn15" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn16" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn16" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn17" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn17" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn18" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn18" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn19" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn19" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn20" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn20" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn21" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn21" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn22" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn22" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn23" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn23" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn24" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn24" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn25" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn25" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn26" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn26" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn27" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn27" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn28" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn28" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn29" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn29" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn30" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn30" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn31" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn31" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn32" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn32" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn33" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn33" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn34" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn34" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn35" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn35" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn36" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn36" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn37" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn37" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn38" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn38" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn39" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn39" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="ItemSpawn40" type="Marker3D" parent="Room/ItemSpawnPoints"] [node name="ItemSpawn40" type="Marker3D" parent="Room/ItemSpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -11.8091, -2.92704) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10.8145, -5.49583, -2.92704)
gizmo_extents = 1.0 gizmo_extents = 1.0
[node name="EnemySpawnPoints" type="Node3D" parent="Room"] [node name="EnemySpawnPoints" type="Node3D" parent="Room"]
unique_name_in_owner = true unique_name_in_owner = true
[node name="EnemySpawn1" type="Marker3D" parent="Room/EnemySpawnPoints"] [node name="EnemySpawn1" type="Marker3D" parent="Room/EnemySpawnPoints"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.71409, -11.0741, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.71409, -3.95028, 0)
[node name="ItemDatabase" parent="Room" instance=ExtResource("17_50pl8")] [node name="ItemDatabase" parent="Room" instance=ExtResource("17_50pl8")]
unique_name_in_owner = true unique_name_in_owner = true
@@ -1389,5 +1386,12 @@ unique_name_in_owner = true
unique_name_in_owner = true unique_name_in_owner = true
SpawnRate = PackedFloat32Array(1) SpawnRate = PackedFloat32Array(1)
[node name="ExitSpawnLocation" type="Marker3D" parent="Room" groups=["Exit"]] [node name="TeleportSpawn" type="Marker3D" parent="Room" groups=["Exit"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.06499, -11.8837, -9.52855) unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.06499, -5.37073, -18.2257)
[node name="DOOR1" type="Marker3D" parent="Room"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.42407, 0, -28.6818)
[node name="DOOR2" type="Marker3D" parent="Room"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.1207, 0, 30.0499)

View File

@@ -9,6 +9,7 @@ public interface IDungeonRoom : INode3D
{ {
DungeonRoomLogic DungeonRoomLogic { get; } DungeonRoomLogic DungeonRoomLogic { get; }
public Marker3D PlayerSpawn { get; set; } public Marker3D PlayerSpawn { get; set; }
public Marker3D TeleportSpawn { get; set; }
} }
[Meta(typeof(IAutoNode))] [Meta(typeof(IAutoNode))]
@@ -24,6 +25,8 @@ public partial class DungeonRoom : Node3D, IDungeonRoom, IProvide<DungeonRoomLog
[Node] public Marker3D PlayerSpawn { get; set; } = default!; [Node] public Marker3D PlayerSpawn { get; set; } = default!;
[Node] public Marker3D TeleportSpawn { get; set; } = default!;
[Node] public Node3D ItemSpawnPoints { get; set; } = default!; [Node] public Node3D ItemSpawnPoints { get; set; } = default!;
[Node] public Node3D EnemySpawnPoints { get; set; } = default!; [Node] public Node3D EnemySpawnPoints { get; set; } = default!;

View File

@@ -119,3 +119,7 @@ transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, 0,
[node name="CollisionShape3D" type="CollisionShape3D" parent="NavigationRegion3D/StaticBody3D3"] [node name="CollisionShape3D" type="CollisionShape3D" parent="NavigationRegion3D/StaticBody3D3"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.320954, -4.84337, -0.0752945) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.320954, -4.84337, -0.0752945)
shape = SubResource("BoxShape3D_q0wqs") shape = SubResource("BoxShape3D_q0wqs")
[node name="ExitSpawnLocation" type="Marker3D" parent="." groups=["Exit"]]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.06499, -11.8837, -9.52855)

View File

@@ -1,9 +1,8 @@
[gd_scene load_steps=5 format=3 uid="uid://dvnc26rebk6o0"] [gd_scene load_steps=4 format=3 uid="uid://dvnc26rebk6o0"]
[ext_resource type="Script" path="res://src/map/dungeon/floors/Overworld.cs" id="1_5hmt3"] [ext_resource type="Script" path="res://src/map/dungeon/floors/Overworld.cs" id="1_5hmt3"]
[ext_resource type="PackedScene" uid="uid://dvj5lwymr02xn" path="res://src/map/overworld/OverworldMap.tscn" id="2_qwsky"] [ext_resource type="PackedScene" uid="uid://dvj5lwymr02xn" path="res://src/map/overworld/OverworldMap.tscn" id="2_qwsky"]
[ext_resource type="PackedScene" uid="uid://d4l4qutp8x40c" path="res://src/npc/rat/NPC.tscn" id="3_4sm8u"] [ext_resource type="PackedScene" uid="uid://d4l4qutp8x40c" path="res://src/npc/rat/NPC.tscn" id="3_4sm8u"]
[ext_resource type="PackedScene" uid="uid://bjqgl5u05ia04" path="res://src/map/dungeon/Teleport.tscn" id="4_4sp6u"]
[node name="Overworld" type="Node3D"] [node name="Overworld" type="Node3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.63488, -5.13176) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.63488, -5.13176)
@@ -21,6 +20,3 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.49531, 1.49242, 0)
[node name="NPC" parent="." instance=ExtResource("3_4sm8u")] [node name="NPC" parent="." instance=ExtResource("3_4sm8u")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.1364, 2.01954, -3.50556) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.1364, 2.01954, -3.50556)
[node name="Teleport" parent="." instance=ExtResource("4_4sp6u")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.25983, 1.61999, 5.45137)

View File

@@ -0,0 +1,7 @@
namespace GameJamDungeon;
public partial class MapLogic
{
public static class Input
{
}
}

View File

@@ -0,0 +1,16 @@
using Chickensoft.Introspection;
using Chickensoft.LogicBlocks;
namespace GameJamDungeon;
public partial class MapLogic
{
[Meta]
public partial record State : StateLogic<State>
{
public State()
{
}
}
}

13
src/map/state/MapLogic.cs Normal file
View File

@@ -0,0 +1,13 @@
using Chickensoft.Introspection;
using Chickensoft.LogicBlocks;
namespace GameJamDungeon;
public interface IMapLogic : ILogicBlock<MapLogic.State>;
[Meta]
[LogicBlock(typeof(State))]
public partial class MapLogic : LogicBlock<MapLogic.State>, IMapLogic
{
public override Transition GetInitialState() => To<State>();
}

View File

@@ -9,12 +9,8 @@ namespace GameJamDungeon
{ {
public interface IPlayer : ICharacterBody3D, IKillable public interface IPlayer : ICharacterBody3D, IKillable
{ {
PlayerStatInfo PlayerStatInfo { get; }
PlayerLogic PlayerLogic { get; } PlayerLogic PlayerLogic { get; }
PlayerData PlayerData { get; }
public Vector3 GetGlobalInputVector(); public Vector3 GetGlobalInputVector();
public float GetLeftStrafeInputVector(); public float GetLeftStrafeInputVector();
@@ -38,27 +34,13 @@ namespace GameJamDungeon
[Dependency] [Dependency]
public ISaveChunk<GameData> GameChunk => this.DependOn<ISaveChunk<GameData>>(); public ISaveChunk<GameData> GameChunk => this.DependOn<ISaveChunk<GameData>>();
/// <summary>Rotation speed (quaternions?/sec).</summary>
[Export(PropertyHint.Range, "0, 100, 0.1")]
public float RotationSpeed { get; set; } = 12.0f;
/// <summary>Player speed (meters/sec).</summary>
[Export(PropertyHint.Range, "0, 100, 0.1")]
public float MoveSpeed { get; set; } = 8f;
/// <summary>Player speed (meters^2/sec).</summary>
[Export(PropertyHint.Range, "0, 100, 0.1")]
public float Acceleration { get; set; } = 4f;
[Export] [Export]
public PlayerStatInfo PlayerStatInfo { get; set; } public PlayerStatResource PlayerStatResource { get; set; } = default!;
public PlayerLogic.Settings Settings { get; set; } = default!; public PlayerLogic.Settings Settings { get; set; } = default!;
public PlayerLogic PlayerLogic { get; set; } = default!; public PlayerLogic PlayerLogic { get; set; } = default!;
public PlayerData PlayerData { get; set; } = default!;
public PlayerLogic.IBinding PlayerBinding { get; set; } = default!; public PlayerLogic.IBinding PlayerBinding { get; set; } = default!;
[Node] public IAnimationPlayer AnimationPlayer { get; set; } = default!; [Node] public IAnimationPlayer AnimationPlayer { get; set; } = default!;
@@ -69,14 +51,10 @@ namespace GameJamDungeon
[Node] public Timer HealthTimer { get; set; } = default!; [Node] public Timer HealthTimer { get; set; } = default!;
[Node] public Label HPNumber { get; set; } = default!;
[Node] public Label VTNumber { get; set; } = default!;
[Node] public Label LevelNumber { get; set; } = default!;
[Node] public IArea3D CollisionDetector { get; set; } = default!; [Node] public IArea3D CollisionDetector { get; set; } = default!;
private PlayerData PlayerData { get; set; } = default!;
public void Initialize() public void Initialize()
{ {
AnimationPlayer.AnimationFinished += OnAnimationFinished; AnimationPlayer.AnimationFinished += OnAnimationFinished;
@@ -84,7 +62,29 @@ namespace GameJamDungeon
public void Setup() public void Setup()
{ {
Settings = new PlayerLogic.Settings() { RotationSpeed = RotationSpeed, MoveSpeed = MoveSpeed, Acceleration = Acceleration }; Settings = new PlayerLogic.Settings() { RotationSpeed = PlayerStatResource.RotationSpeed, MoveSpeed = PlayerStatResource.MoveSpeed, Acceleration = PlayerStatResource.Acceleration };
PlayerData = new PlayerData()
{
GlobalTransform = GlobalTransform,
StateMachine = PlayerLogic,
Velocity = Velocity,
Inventory = new Inventory(),
CurrentHP = new AutoProp<int>(PlayerStatResource.CurrentHP),
MaximumHP = new AutoProp<int>(PlayerStatResource.MaximumHP),
CurrentVT = new AutoProp<int>(PlayerStatResource.CurrentVT),
MaximumVT = new AutoProp<int>(PlayerStatResource.MaximumVT),
CurrentAttack = new AutoProp<int>(PlayerStatResource.CurrentAttack),
MaxAttack = new AutoProp<int>(PlayerStatResource.MaxAttack),
CurrentDefense = new AutoProp<int>(PlayerStatResource.CurrentDefense),
MaxDefense = new AutoProp<int>(PlayerStatResource.MaxDefense),
CurrentExp = new AutoProp<int>(PlayerStatResource.CurrentExp),
ExpToNextLevel = new AutoProp<int>(PlayerStatResource.ExpToNextLevel),
CurrentLevel = new AutoProp<int>(PlayerStatResource.CurrentLevel),
BonusAttack = new AutoProp<int>(PlayerStatResource.BonusAttack),
BonusDefense = new AutoProp<int>(PlayerStatResource.BonusDefense),
Luck = new AutoProp<double>(PlayerStatResource.Luck)
};
PlayerLogic = new PlayerLogic(); PlayerLogic = new PlayerLogic();
PlayerLogic.Set(this as IPlayer); PlayerLogic.Set(this as IPlayer);
@@ -92,6 +92,12 @@ namespace GameJamDungeon
PlayerLogic.Set(AppRepo); PlayerLogic.Set(AppRepo);
PlayerLogic.Set(GameRepo); PlayerLogic.Set(GameRepo);
PlayerLogic.Set(PlayerData); PlayerLogic.Set(PlayerData);
PlayerData.Inventory.EquippedWeapon.Sync += EquippedWeapon_Sync;
PlayerData.Inventory.EquippedArmor.Sync += EquippedArmor_Sync;
PlayerData.Inventory.EquippedAccessory.Sync += EquippedAccessory_Sync;
PlayerData.CurrentHP.Sync += CurrentHP_Sync;
} }
public void OnResolved() public void OnResolved()
@@ -106,9 +112,8 @@ namespace GameJamDungeon
}) })
.Handle((in PlayerLogic.Output.Animations.Attack output) => .Handle((in PlayerLogic.Output.Animations.Attack output) =>
{ {
var weaponInfo = GameRepo.EquippedWeapon.Value.WeaponInfo; var attackSpeed = PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.AttackSpeed;
var attackSpeed = (float)weaponInfo.AttackSpeed; AnimationPlayer.SetSpeedScale((float)attackSpeed);
AnimationPlayer.SetSpeedScale(attackSpeed);
AnimationPlayer.Play("attack"); AnimationPlayer.Play("attack");
}) })
.Handle((in PlayerLogic.Output.ThrowItem output) => .Handle((in PlayerLogic.Output.ThrowItem output) =>
@@ -117,11 +122,10 @@ namespace GameJamDungeon
this.Provide(); this.Provide();
PlayerLogic.Start(); PlayerLogic.Start();
GameRepo.SetPlayerData(PlayerData);
SwordSlashAnimation.Position = GetViewport().GetVisibleRect().Size / 2; SwordSlashAnimation.Position = GetViewport().GetVisibleRect().Size / 2;
GlobalPosition = GameRepo.PlayerGlobalPosition.Value; GlobalPosition = GameRepo.PlayerGlobalPosition.Value;
GameRepo.SetPlayerStatInfo(PlayerStatInfo); GameRepo.PlayerGlobalPosition.Sync += PlayerGlobalPosition_Sync;
HealthTimer.Timeout += OnHealthTimerTimeout; HealthTimer.Timeout += OnHealthTimerTimeout;
CollisionDetector.AreaEntered += OnEnemyHitBoxEntered; CollisionDetector.AreaEntered += OnEnemyHitBoxEntered;
} }
@@ -142,26 +146,6 @@ namespace GameJamDungeon
Settings.MoveSpeed /= 4; Settings.MoveSpeed /= 4;
} }
private void OnEnemyHitBoxEntered(Area3D area)
{
if (area is IHitbox hitBox)
{
if (GameRepo.PlayerStatInfo.Value.CurrentHP > 0)
{
var enemy = hitBox.GetParent<IEnemy>();
var isCriticalHit = false;
var rng = new RandomNumberGenerator();
rng.Randomize();
var roll = rng.Randf();
if (roll <= enemy.EnemyStatInfo.Luck)
isCriticalHit = true;
var damage = DamageCalculator.CalculateEnemyDamage(PlayerStatInfo, enemy.EnemyStatInfo, GameRepo.EquippedArmor.Value.ArmorInfo, isCriticalHit);
GameRepo.PlayerStatInfo.Value.CurrentHP = GameRepo.PlayerStatInfo.Value.CurrentHP - damage;
GD.Print($"Player hit for {damage} damage.");
}
}
}
public void OnPhysicsProcess(double delta) public void OnPhysicsProcess(double delta)
{ {
PlayerLogic.Input(new PlayerLogic.Input.PhysicsTick(delta)); PlayerLogic.Input(new PlayerLogic.Input.PhysicsTick(delta));
@@ -171,13 +155,6 @@ namespace GameJamDungeon
PlayerLogic.Input(new PlayerLogic.Input.Moved(GlobalPosition)); PlayerLogic.Input(new PlayerLogic.Input.Moved(GlobalPosition));
} }
public override void _Process(double delta)
{
OnHPChanged(GameRepo.PlayerStatInfo.Value.CurrentHP);
OnVTChanged(GameRepo.PlayerStatInfo.Value.CurrentVT);
OnLevelChanged(GameRepo.PlayerStatInfo.Value.CurrentLevel);
}
public Vector3 GetGlobalInputVector() public Vector3 GetGlobalInputVector()
{ {
var rawInput = Input.GetVector(GameInputs.MoveLeft, GameInputs.MoveRight, GameInputs.MoveUp, GameInputs.MoveDown); var rawInput = Input.GetVector(GameInputs.MoveLeft, GameInputs.MoveRight, GameInputs.MoveUp, GameInputs.MoveDown);
@@ -226,35 +203,72 @@ namespace GameJamDungeon
public void Kill() => PlayerLogic.Input(new PlayerLogic.Input.Killed()); public void Kill() => PlayerLogic.Input(new PlayerLogic.Input.Killed());
private void OnHPChanged(double newHP) private void PlayerGlobalPosition_Sync(Vector3 newPlayerPosition)
{ {
HPNumber.Text = $"{Mathf.RoundToInt(newHP)}/{PlayerStatInfo.MaximumHP}"; GlobalPosition = newPlayerPosition;
if (newHP <= 0.0)
{
PlayerLogic.Input(new PlayerLogic.Input.Killed());
HealthTimer.Stop();
}
}
private void OnVTChanged(int newVT)
{
VTNumber.Text = $"{newVT}/{PlayerStatInfo.MaximumVT}";
}
private void OnLevelChanged(int newLevel)
{
LevelNumber.Text = $"{newLevel}";
} }
private void OnPlayerPositionUpdated(Vector3 globalPosition) => GlobalPosition = globalPosition; private void OnPlayerPositionUpdated(Vector3 globalPosition) => GlobalPosition = globalPosition;
private void OnHealthTimerTimeout() private void OnHealthTimerTimeout()
{ {
if (GameRepo.PlayerStatInfo.Value.CurrentVT > 0) if (PlayerData.CurrentVT.Value > 0)
GameRepo.PlayerStatInfo.Value.CurrentVT = GameRepo.PlayerStatInfo.Value.CurrentVT - 1; PlayerData.CurrentVT.OnNext(PlayerData.CurrentVT.Value - 1);
else else
GameRepo.PlayerStatInfo.Value.CurrentHP = GameRepo.PlayerStatInfo.Value.CurrentHP - 1; PlayerData.CurrentHP.OnNext(PlayerData.CurrentHP.Value - 1);
}
private void EquippedAccessory_Sync(Accessory equippedItem)
{
PlayerData.BonusAttack.OnNext(PlayerData.BonusAttack.Value - PlayerData.Inventory.EquippedAccessory.Value.AccessoryInfo.ATKUp);
PlayerData.BonusDefense.OnNext(PlayerData.BonusDefense.Value - PlayerData.Inventory.EquippedAccessory.Value.AccessoryInfo.DEFUp);
PlayerData.MaximumHP.OnNext(PlayerData.MaximumHP.Value - PlayerData.Inventory.EquippedAccessory.Value.AccessoryInfo.MaxHPUp);
PlayerData.MaximumVT.OnNext(PlayerData.MaximumVT.Value - PlayerData.Inventory.EquippedAccessory.Value.AccessoryInfo.MaxVTUp);
PlayerData.Luck.OnNext(PlayerData.Luck.Value - PlayerData.Inventory.EquippedAccessory.Value.AccessoryInfo.LUCKUp);
PlayerData.BonusAttack.OnNext(PlayerData.BonusAttack.Value + equippedItem.AccessoryInfo.ATKUp);
PlayerData.BonusDefense.OnNext(PlayerData.BonusDefense.Value + equippedItem.AccessoryInfo.DEFUp);
PlayerData.MaximumHP.OnNext(PlayerData.MaximumHP.Value + equippedItem.AccessoryInfo.MaxHPUp);
PlayerData.MaximumVT.OnNext(PlayerData.MaximumVT.Value + equippedItem.AccessoryInfo.MaxVTUp);
PlayerData.Luck.OnNext(PlayerData.Luck.Value + equippedItem.AccessoryInfo.LUCKUp);
PlayerData.Inventory.Equip(equippedItem);
}
private void EquippedArmor_Sync(Armor equippedItem)
{
PlayerData.BonusDefense.OnNext(PlayerData.BonusDefense.Value - PlayerData.Inventory.EquippedArmor.Value.ArmorStats.Defense);
PlayerData.BonusDefense.OnNext(PlayerData.BonusDefense.Value + equippedItem.ArmorStats.Defense);
PlayerData.Inventory.Equip(equippedItem);
}
private void EquippedWeapon_Sync(Weapon equippedItem)
{
PlayerData.BonusAttack.OnNext(PlayerData.BonusAttack.Value - PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.Damage);
PlayerData.BonusAttack.OnNext(PlayerData.BonusAttack.Value + equippedItem.WeaponStats.Damage);
PlayerData.Inventory.Equip(equippedItem);
}
private void OnEnemyHitBoxEntered(Area3D area)
{
if (area is IHitbox hitBox)
{
var enemy = hitBox.GetParent<IEnemy>();
var isCriticalHit = false;
var rng = new RandomNumberGenerator();
rng.Randomize();
var roll = rng.Randf();
if (roll <= enemy.EnemyStatResource.Luck)
isCriticalHit = true;
var damage = DamageCalculator.CalculateEnemyDamage(PlayerData.CurrentDefense.Value + PlayerData.BonusDefense.Value, enemy.EnemyStatResource, GameRepo.PlayerData.Inventory.EquippedArmor.Value.ArmorStats, isCriticalHit);
PlayerData.CurrentHP.OnNext(PlayerData.CurrentHP.Value - Mathf.RoundToInt(damage));
GD.Print($"Player hit for {damage} damage.");
}
}
private void CurrentHP_Sync(int newHealth)
{
if (newHealth <= 0)
Kill();
} }
} }
} }

View File

@@ -1,34 +1,34 @@
[gd_scene load_steps=22 format=3 uid="uid://cfecvvav8kkp6"] [gd_scene load_steps=19 format=3 uid="uid://cfecvvav8kkp6"]
[ext_resource type="Script" path="res://src/player/Player.cs" id="1_xcol5"] [ext_resource type="Script" path="res://src/player/Player.cs" id="1_xcol5"]
[ext_resource type="Texture2D" uid="uid://bokx3h8kfdo5i" path="res://src/player/slash_0000_Classic_30.png" id="2_la11l"] [ext_resource type="Texture2D" uid="uid://bokx3h8kfdo5i" path="res://src/player/slash_0000_Classic_30.png" id="2_la11l"]
[ext_resource type="Script" path="res://src/hitbox/Hitbox.cs" id="2_lb3qc"] [ext_resource type="Script" path="res://src/hitbox/Hitbox.cs" id="2_lb3qc"]
[ext_resource type="Script" path="res://src/player/PlayerStatInfo.cs" id="2_n88di"] [ext_resource type="Script" path="res://src/player/PlayerStatResource.cs" id="2_xq68d"]
[ext_resource type="Texture2D" uid="uid://byosr5gk51237" path="res://src/player/slash_0001_Classic_29.png" id="3_ux3f1"] [ext_resource type="Texture2D" uid="uid://byosr5gk51237" path="res://src/player/slash_0001_Classic_29.png" id="3_ux3f1"]
[ext_resource type="Texture2D" uid="uid://nh071o6ii03j" path="res://src/player/slash_0002_Classic_28.png" id="4_gqnq0"] [ext_resource type="Texture2D" uid="uid://nh071o6ii03j" path="res://src/player/slash_0002_Classic_28.png" id="4_gqnq0"]
[ext_resource type="Texture2D" uid="uid://bodfblud4kea3" path="res://src/player/slash_0003_Classic_27.png" id="5_eebal"] [ext_resource type="Texture2D" uid="uid://bodfblud4kea3" path="res://src/player/slash_0003_Classic_27.png" id="5_eebal"]
[ext_resource type="Texture2D" uid="uid://de55prolicl0u" path="res://src/player/slash_0004_Classic_26.png" id="6_ngag5"] [ext_resource type="Texture2D" uid="uid://de55prolicl0u" path="res://src/player/slash_0004_Classic_26.png" id="6_ngag5"]
[ext_resource type="Texture2D" uid="uid://bp0msic3uk3kc" path="res://src/player/slash_0005_Layer-1.png" id="7_tp5uu"] [ext_resource type="Texture2D" uid="uid://bp0msic3uk3kc" path="res://src/player/slash_0005_Layer-1.png" id="7_tp5uu"]
[ext_resource type="Texture2D" uid="uid://hg2kraa5nrnl" path="res://src/ui/textures/blank level symbol.png" id="10_rsd7v"]
[ext_resource type="LabelSettings" uid="uid://ca1q6yu8blwxf" path="res://src/ui/label_settings/InventoryMainTextBold.tres" id="11_6gvkm"]
[ext_resource type="LabelSettings" uid="uid://dupifadnagodp" path="res://src/ui/label_settings/MainTextRegular.tres" id="12_f4uqk"]
[sub_resource type="Resource" id="Resource_up0v1"] [sub_resource type="Resource" id="Resource_btp2w"]
script = ExtResource("2_n88di") script = ExtResource("2_xq68d")
CurrentHP = 100.0 RotationSpeed = 3.0
MaximumHP = 100.0 MoveSpeed = 4.0
Acceleration = 1.0
CurrentHP = 100
MaximumHP = 100
CurrentVT = 90 CurrentVT = 90
MaximumVT = 90 MaximumVT = 90
CurrentExp = 0
ExpToNextLevel = 100
CurrentLevel = 1 CurrentLevel = 1
CurrentEXP = 0 CurrentAttack = 14
EXPToNextLevel = 100 CurrentDefense = 12
CurrentAttack = 12 MaxAttack = 14
MaxAttack = 12 MaxDefense = 12
CurrentDefense = 8
MaxDefense = 8
BonusAttack = 0 BonusAttack = 0
BonusDefense = 0 BonusDefense = 0
Luck = 0.0 Luck = 0.05
[sub_resource type="BoxShape3D" id="BoxShape3D_wedu3"] [sub_resource type="BoxShape3D" id="BoxShape3D_wedu3"]
@@ -98,8 +98,8 @@ tracks/1/keys = {
[sub_resource type="AnimationLibrary" id="AnimationLibrary_w8l8m"] [sub_resource type="AnimationLibrary" id="AnimationLibrary_w8l8m"]
_data = { _data = {
&"attack": SubResource("Animation_0jjwv"), "RESET": SubResource("Animation_hcjph"),
&"RESET": SubResource("Animation_hcjph") "attack": SubResource("Animation_0jjwv")
} }
[sub_resource type="SpriteFrames" id="SpriteFrames_ywvvo"] [sub_resource type="SpriteFrames" id="SpriteFrames_ywvvo"]
@@ -139,10 +139,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.381018, 0)
collision_layer = 38 collision_layer = 38
collision_mask = 7 collision_mask = 7
script = ExtResource("1_xcol5") script = ExtResource("1_xcol5")
RotationSpeed = 3.0 PlayerStatResource = SubResource("Resource_btp2w")
MoveSpeed = 4.0
Acceleration = 1.0
PlayerStatInfo = SubResource("Resource_up0v1")
[node name="Hitbox" type="Area3D" parent="."] [node name="Hitbox" type="Area3D" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
@@ -183,7 +180,7 @@ omni_range = 83.659
[node name="AnimationPlayer" type="AnimationPlayer" parent="."] [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
libraries = { libraries = {
&"": SubResource("AnimationLibrary_w8l8m") "": SubResource("AnimationLibrary_w8l8m")
} }
[node name="SwordSlashAnimation" type="AnimatedSprite2D" parent="."] [node name="SwordSlashAnimation" type="AnimatedSprite2D" parent="."]
@@ -197,82 +194,3 @@ unique_name_in_owner = true
process_mode = 1 process_mode = 1
wait_time = 3.0 wait_time = 3.0
autostart = true autostart = true
[node name="PlayerInfoUI" type="MarginContainer" parent="."]
offset_right = 629.0
offset_bottom = 256.0
theme_override_constants/margin_left = 32
[node name="HBoxContainer" type="HBoxContainer" parent="PlayerInfoUI"]
layout_mode = 2
[node name="CenterContainer" type="CenterContainer" parent="PlayerInfoUI/HBoxContainer"]
layout_mode = 2
[node name="TextureRect" type="TextureRect" parent="PlayerInfoUI/HBoxContainer/CenterContainer"]
custom_minimum_size = Vector2(128, 128)
layout_mode = 2
size_flags_vertical = 3
texture = ExtResource("10_rsd7v")
expand_mode = 1
stretch_mode = 4
[node name="LevelNumber" type="Label" parent="PlayerInfoUI/HBoxContainer/CenterContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(80, 80)
layout_mode = 2
text = "99"
label_settings = ExtResource("11_6gvkm")
horizontal_alignment = 1
vertical_alignment = 1
[node name="VBox" type="VBoxContainer" parent="PlayerInfoUI/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
theme_override_constants/separation = 15
[node name="HBox" type="HBoxContainer" parent="PlayerInfoUI/HBoxContainer/VBox"]
layout_mode = 2
size_flags_horizontal = 3
[node name="HP" type="Label" parent="PlayerInfoUI/HBoxContainer/VBox/HBox"]
layout_mode = 2
text = "HP: "
label_settings = ExtResource("11_6gvkm")
[node name="ReferenceRect" type="ReferenceRect" parent="PlayerInfoUI/HBoxContainer/VBox/HBox"]
custom_minimum_size = Vector2(30, 0)
layout_mode = 2
border_width = 0.0
[node name="HPNumber" type="Label" parent="PlayerInfoUI/HBoxContainer/VBox/HBox"]
unique_name_in_owner = true
layout_mode = 2
text = "222/222"
label_settings = ExtResource("12_f4uqk")
[node name="HBox2" type="HBoxContainer" parent="PlayerInfoUI/HBoxContainer/VBox"]
layout_mode = 2
[node name="VT" type="Label" parent="PlayerInfoUI/HBoxContainer/VBox/HBox2"]
layout_mode = 2
text = "VT:"
label_settings = ExtResource("11_6gvkm")
[node name="ReferenceRect" type="ReferenceRect" parent="PlayerInfoUI/HBoxContainer/VBox/HBox2"]
custom_minimum_size = Vector2(30, 0)
layout_mode = 2
border_width = 0.0
[node name="VTNumber" type="Label" parent="PlayerInfoUI/HBoxContainer/VBox/HBox2"]
unique_name_in_owner = true
layout_mode = 2
text = "444/444"
label_settings = ExtResource("12_f4uqk")
[node name="TextureButton" type="TextureButton" parent="PlayerInfoUI"]
layout_mode = 2
[node name="Marker3D" type="Marker3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -2.70201)

View File

@@ -1,4 +1,5 @@
using Chickensoft.Serialization; using Chickensoft.Collections;
using Chickensoft.Serialization;
using Godot; using Godot;
namespace GameJamDungeon namespace GameJamDungeon
@@ -12,5 +13,36 @@ namespace GameJamDungeon
public required PlayerLogic StateMachine { get; init; } public required PlayerLogic StateMachine { get; init; }
[Save("velocity")] [Save("velocity")]
public required Vector3 Velocity { get; init; } public required Vector3 Velocity { get; init; }
[Save("inventory")]
public required Inventory Inventory { get; init; }
[Save("currentHP")]
public required AutoProp<int> CurrentHP { get; init; }
[Save("maximumHP")]
public required AutoProp<int> MaximumHP { get; init; }
[Save("currentVT")]
public required AutoProp<int> CurrentVT { get; init; }
[Save("maximumVT")]
public required AutoProp<int> MaximumVT { get; init; }
[Save("currentExp")]
public required AutoProp<int> CurrentExp { get; init; }
[Save("expToNextLevel")]
public required AutoProp<int> ExpToNextLevel { get; init; }
[Save("currentLevel")]
public required AutoProp<int> CurrentLevel { get; init; }
[Save("currentAttack")]
public required AutoProp<int> CurrentAttack { get; init; }
[Save("currentDefense")]
public required AutoProp<int> CurrentDefense { get; init; }
[Save("maxAttack")]
public required AutoProp<int> MaxAttack { get; init; }
[Save("maxDefense")]
public required AutoProp<int> MaxDefense { get; init; }
[Save("bonusAttack")]
public required AutoProp<int> BonusAttack { get; init; }
[Save("bonusDefense")]
public required AutoProp<int> BonusDefense { get; init; }
[Save("luck")]
public required AutoProp<double> Luck { get; init; }
} }
} }

View File

@@ -1,73 +0,0 @@
using Chickensoft.Collections;
using Godot;
namespace GameJamDungeon
{
[GlobalClass]
public partial class PlayerStatInfo : Resource, ICharacterStats
{
[Export]
public double CurrentHP { get => _currentHP.Value; set => _currentHP.OnNext(Mathf.Min(MaximumHP, value)); }
[Export]
public double MaximumHP { get => _maximumHP.Value; set => _maximumHP.OnNext(value); }
[Export]
public int CurrentVT { get => _currentVT.Value; set => _currentVT.OnNext(Mathf.Min(MaximumVT, value)); }
[Export]
public int MaximumVT { get => _maximumVT.Value; set => _maximumVT.OnNext(value); }
[Export]
public int CurrentLevel { get => _currentLevel.Value; set => _currentLevel.OnNext(value); }
[Export]
public int CurrentEXP { get => _currentExp.Value; set => _currentExp.OnNext(value); }
[Export]
public int EXPToNextLevel { get => _expToNextLevel.Value; set => _expToNextLevel.OnNext(value); }
[Export]
public int CurrentAttack { get => _currentAttack.Value; set => _currentAttack.OnNext(Mathf.Min(MaxAttack, value)); }
[Export]
public int MaxAttack { get => _maxAttack.Value; set => _maxAttack.OnNext(value); }
[Export]
public int CurrentDefense { get => _currentDefense.Value; set => _currentDefense.OnNext(Mathf.Min(CurrentDefense, value)); }
[Export]
public int MaxDefense { get => _maxDefense.Value; set => _maxDefense.OnNext(value); }
[Export]
public int BonusAttack { get => _bonusAttack.Value; set => _bonusAttack.OnNext(value); }
[Export]
public int BonusDefense { get => _bonusDefense.Value; set => _bonusDefense.OnNext(value); }
[Export]
public double Luck { get => _luck.Value; set => _luck.OnNext(value); }
// AutoProp backing data
private readonly AutoProp<double> _currentHP = new AutoProp<double>(double.MaxValue);
private readonly AutoProp<double> _maximumHP = new AutoProp<double>(double.MaxValue);
private readonly AutoProp<int> _currentVT = new AutoProp<int>(int.MaxValue);
private readonly AutoProp<int> _maximumVT = new AutoProp<int>(int.MaxValue);
private readonly AutoProp<int> _currentExp = new AutoProp<int>(int.MaxValue);
private readonly AutoProp<int> _expToNextLevel = new AutoProp<int>(int.MaxValue);
private readonly AutoProp<int> _currentLevel = new AutoProp<int>(int.MaxValue);
private readonly AutoProp<int> _currentAttack = new AutoProp<int>(int.MaxValue);
private readonly AutoProp<int> _currentDefense = new AutoProp<int>(int.MaxValue);
private readonly AutoProp<int> _maxAttack = new AutoProp<int>(int.MaxValue);
private readonly AutoProp<int> _maxDefense = new AutoProp<int>(int.MaxValue);
private readonly AutoProp<int> _bonusAttack = new AutoProp<int>(int.MaxValue);
private readonly AutoProp<int> _bonusDefense = new AutoProp<int>(int.MaxValue);
private readonly AutoProp<double> _luck = new AutoProp<double>(double.MaxValue);
}
}

View File

@@ -0,0 +1,42 @@
using Godot;
namespace GameJamDungeon
{
[GlobalClass]
public partial class PlayerStatResource : Resource
{
/// <summary>Rotation speed (quaternions?/sec).</summary>
[Export(PropertyHint.Range, "0, 100, 0.1")]
public float RotationSpeed { get; set; } = 12.0f;
/// <summary>Player speed (meters/sec).</summary>
[Export(PropertyHint.Range, "0, 100, 0.1")]
public float MoveSpeed { get; set; } = 8f;
/// <summary>Player speed (meters^2/sec).</summary>
[Export(PropertyHint.Range, "0, 100, 0.1")]
public float Acceleration { get; set; } = 4f;
[Export] public int CurrentHP { get; set; }
[Export] public int MaximumHP { get; set; }
[Export] public int CurrentVT { get; set; }
[Export] public int MaximumVT { get; set; }
[Export] public int CurrentExp { get; set; }
[Export] public int ExpToNextLevel { get; set; }
[Export] public int CurrentLevel { get; set; }
[Export] public int CurrentAttack { get; set; }
[Export] public int CurrentDefense { get; set; }
[Export] public int MaxAttack { get; set; }
[Export] public int MaxDefense { get; set; }
[Export] public int BonusAttack { get; set; }
[Export] public int BonusDefense { get; set; }
[Export(PropertyHint.Range, "0, 1, 0.01")]
public double Luck { get; set; }
}
}

View File

@@ -1,16 +0,0 @@
[gd_resource type="Resource" script_class="PlayerStatInfo" load_steps=2 format=3 uid="uid://cofd1ylluj24"]
[ext_resource type="Script" path="res://src/player/PlayerStatInfo.cs" id="1_a84hi"]
[resource]
script = ExtResource("1_a84hi")
MaximumHP = 120.0
MaximumVT = 90
BaseAttack = 10
BaseDefense = 0
ElementAResistance = 0.0
ElementBResistance = 0.0
ElementCResistance = 15.0
BaseElementADamageBonus = 30.0
BaseElementBDamageBonus = 15.0
BaseElementCDamageBonus = 20.0

View File

@@ -4,9 +4,8 @@ namespace GameJamDungeon
{ {
public static class DamageCalculator public static class DamageCalculator
{ {
public static double CalculatePlayerDamage(PlayerStatInfo playerStatInfo, EnemyStatInfo enemyStatInfo, WeaponInfo weapon, bool isCriticalHit) public static double CalculatePlayerDamage(int totalAttack, EnemyStatResource enemyStatInfo, WeaponStats weapon, bool isCriticalHit)
{ {
var baseDamage = playerStatInfo.CurrentAttack + playerStatInfo.BonusAttack;
var hydricResistance = enemyStatInfo.HydricResistance; var hydricResistance = enemyStatInfo.HydricResistance;
var igneousResistance = enemyStatInfo.IgneousResistance; var igneousResistance = enemyStatInfo.IgneousResistance;
var telluricResistance = enemyStatInfo.TelluricResistance; var telluricResistance = enemyStatInfo.TelluricResistance;
@@ -27,7 +26,7 @@ namespace GameJamDungeon
var elementCDamage = (weapon.TelluricDamageBonus > 0 ? weapon.TelluricDamageBonus - telluricResistance : 0) / 100; var elementCDamage = (weapon.TelluricDamageBonus > 0 ? weapon.TelluricDamageBonus - telluricResistance : 0) / 100;
var elementDDamage = (weapon.AeolicDamageBonus > 0 ? weapon.AeolicDamageBonus - aeolicResistance : 0) / 100; var elementDDamage = (weapon.AeolicDamageBonus > 0 ? weapon.AeolicDamageBonus - aeolicResistance : 0) / 100;
var elementEDamage = (weapon.FerrumDamageBonus > 0 ? weapon.FerrumDamageBonus - ferrumResistance : 0) / 100; var elementEDamage = (weapon.FerrumDamageBonus > 0 ? weapon.FerrumDamageBonus - ferrumResistance : 0) / 100;
var elementalBonusDamage = baseDamage + (baseDamage * elementADamage) + (baseDamage * elementBDamage) + (baseDamage * elementCDamage) + (baseDamage * elementDDamage) + (baseDamage * elementEDamage); var elementalBonusDamage = totalAttack + (totalAttack * elementADamage) + (totalAttack * elementBDamage) + (totalAttack * elementCDamage) + (totalAttack * elementDDamage) + (totalAttack * elementEDamage);
var calculatedDamage = elementalBonusDamage - enemyStatInfo.CurrentDefense; var calculatedDamage = elementalBonusDamage - enemyStatInfo.CurrentDefense;
if (isCriticalHit) if (isCriticalHit)
@@ -36,16 +35,16 @@ namespace GameJamDungeon
return calculatedDamage; return calculatedDamage;
} }
public static double CalculateEnemyDamage(PlayerStatInfo playerStatInfo, EnemyStatInfo enemyStatInfo, ArmorInfo armor, bool isCriticalHit) public static double CalculateEnemyDamage(int playerTotalDefense, EnemyStatResource enemyStatInfo, ArmorStats armor, bool isCriticalHit)
{ {
var baseDamage = enemyStatInfo.CurrentAttack; var totalAttack = enemyStatInfo.CurrentAttack;
var elementADamage = (enemyStatInfo.BaseHydricDamageBonus > 0 ? enemyStatInfo.BaseHydricDamageBonus - armor.HydricResistance : 0) / 100; var elementADamage = (enemyStatInfo.BaseHydricDamageBonus > 0 ? enemyStatInfo.BaseHydricDamageBonus - armor.HydricResistance : 0) / 100;
var elementBDamage = (enemyStatInfo.IgneousDamageBonus > 0 ? enemyStatInfo.IgneousDamageBonus - armor.IgneousResistance : 0) / 100; var elementBDamage = (enemyStatInfo.IgneousDamageBonus > 0 ? enemyStatInfo.IgneousDamageBonus - armor.IgneousResistance : 0) / 100;
var elementCDamage = (enemyStatInfo.TelluricDamageBonus > 0 ? enemyStatInfo.TelluricDamageBonus - armor.TelluricResistance : 0) / 100; var elementCDamage = (enemyStatInfo.TelluricDamageBonus > 0 ? enemyStatInfo.TelluricDamageBonus - armor.TelluricResistance : 0) / 100;
var elementDDamage = (enemyStatInfo.AeolicDamageBonus > 0 ? enemyStatInfo.AeolicDamageBonus - armor.AeolicResistance : 0) / 100; var elementDDamage = (enemyStatInfo.AeolicDamageBonus > 0 ? enemyStatInfo.AeolicDamageBonus - armor.AeolicResistance : 0) / 100;
var elementEDamage = (enemyStatInfo.FerrumDamageBonus > 0 ? enemyStatInfo.FerrumDamageBonus - armor.FerrumResistance : 0) / 100; var elementEDamage = (enemyStatInfo.FerrumDamageBonus > 0 ? enemyStatInfo.FerrumDamageBonus - armor.FerrumResistance : 0) / 100;
var elementalBonusDamage = baseDamage + (baseDamage * elementADamage) + (baseDamage * elementBDamage) + (baseDamage * elementCDamage) + (baseDamage * elementDDamage) + (baseDamage * elementEDamage); var elementalBonusDamage = totalAttack + (totalAttack * elementADamage) + (totalAttack * elementBDamage) + (totalAttack * elementCDamage) + (totalAttack * elementDDamage) + (totalAttack * elementEDamage);
var calculatedDamage = elementalBonusDamage - playerStatInfo.CurrentDefense - (armor != null ? armor.Defense : 0); var calculatedDamage = elementalBonusDamage - playerTotalDefense - (armor != null ? armor.Defense : 0);
if (isCriticalHit) if (isCriticalHit)
calculatedDamage *= 2; calculatedDamage *= 2;

View File

@@ -1,19 +1,21 @@
namespace GameJamDungeon using Chickensoft.Collections;
namespace GameJamDungeon
{ {
public interface ICharacterStats public interface ICharacterStats
{ {
public double CurrentHP { get; } public IAutoProp<double> CurrentHP { get; }
public double MaximumHP { get; } public IAutoProp<double> MaximumHP { get; }
public int CurrentAttack { get; } public IAutoProp<int> CurrentAttack { get; }
public int CurrentDefense { get; } public IAutoProp<int> CurrentDefense { get; }
public int MaxAttack { get; } public IAutoProp<int> MaxAttack { get; }
public int MaxDefense { get; } public IAutoProp<int> MaxDefense { get; }
public double Luck { get; } public IAutoProp<double> Luck { get; }
} }
} }

View File

@@ -87,6 +87,7 @@ Panel/styles/panel = SubResource("StyleBoxFlat_uy0d5")
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_dboi3"] [sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_dboi3"]
[node name="DialogueBalloon" type="CanvasLayer"] [node name="DialogueBalloon" type="CanvasLayer"]
process_mode = 3
layer = 100 layer = 100
script = ExtResource("1_okfmu") script = ExtResource("1_okfmu")
NextAction = "ui_cancel" NextAction = "ui_cancel"

View File

@@ -1,6 +1,6 @@
~ floor_exit ~ floor_exit
Proceed to the next floor? Proceed to the next floor?
- Yes - Yes
do Exit() do SpawnNextFloor()
- No - No
=> END => END

View File

@@ -3,8 +3,6 @@ using Chickensoft.GodotNodeInterfaces;
using Chickensoft.Introspection; using Chickensoft.Introspection;
using GameJamDungeon; using GameJamDungeon;
using Godot; using Godot;
using System;
using System.Linq;
[Meta(typeof(IAutoNode))] [Meta(typeof(IAutoNode))]
public partial class FloorClearMenu : Control public partial class FloorClearMenu : Control
@@ -27,10 +25,4 @@ public partial class FloorClearMenu : Control
{ {
EmitSignal(SignalName.TransitionCompleted); EmitSignal(SignalName.TransitionCompleted);
} }
private void AnimationPlayer_AnimationFinished(StringName animName)
{
var spawnPoints = GetTree().GetNodesInGroup("Exit").OfType<Marker3D>();
GameRepo.CurrentFloor++;
}
} }

View File

@@ -2,19 +2,20 @@ using Chickensoft.AutoInject;
using Chickensoft.GodotNodeInterfaces; using Chickensoft.GodotNodeInterfaces;
using Chickensoft.Introspection; using Chickensoft.Introspection;
using Godot; using Godot;
using System.Threading.Tasks;
namespace GameJamDungeon; namespace GameJamDungeon;
public interface IInGameUI : IControl public interface IInGameUI : IControl
{ {
public Task ShowInventoryScreen(); public void ShowInventoryScreen();
public void HideInventoryScreen(); public void HideInventoryScreen();
public void ShowMiniMap(); public void ShowMiniMap();
public void HideMiniMap(); public void HideMiniMap();
public void ShowInventoryFullMessage(string rejectedItemName);
} }
[Meta(typeof(IAutoNode))] [Meta(typeof(IAutoNode))]
@@ -26,6 +27,13 @@ public partial class InGameUI : Control, IInGameUI
[Node] public IInventoryMenu InventoryMenu { get; set; } = default!; [Node] public IInventoryMenu InventoryMenu { get; set; } = default!;
[Node] public IPlayerInfoUI PlayerInfoUI { get; set; } = default!;
public void ShowInventoryFullMessage(string rejectedItemName)
{
PlayerInfoUI.DisplayInventoryFullMessage(rejectedItemName);
}
public void HideInventoryScreen() public void HideInventoryScreen()
{ {
InventoryMenu.Hide(); InventoryMenu.Hide();
@@ -36,9 +44,9 @@ public partial class InGameUI : Control, IInGameUI
MiniMap.Hide(); MiniMap.Hide();
} }
public async Task ShowInventoryScreen() public void ShowInventoryScreen()
{ {
await InventoryMenu.RedrawInventory(); InventoryMenu.RedrawInventory();
InventoryMenu.Show(); InventoryMenu.Show();
} }

View File

@@ -1,19 +1,27 @@
[gd_scene load_steps=4 format=3 uid="uid://b1muxus5qdbeu"] [gd_scene load_steps=5 format=3 uid="uid://b1muxus5qdbeu"]
[ext_resource type="Script" path="res://src/ui/in_game_ui/InGameUI.cs" id="1_sc13i"] [ext_resource type="Script" 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"]
[ext_resource type="PackedScene" uid="uid://dlj8qdg1c5048" path="res://src/inventory_menu/InventoryMenu.tscn" id="3_4vcdl"] [ext_resource type="PackedScene" uid="uid://dlj8qdg1c5048" path="res://src/inventory_menu/InventoryMenu.tscn" id="3_4vcdl"]
[ext_resource type="PackedScene" uid="uid://dxl8il8f13c2x" path="res://src/ui/player_ui/PlayerInfoUI.tscn" id="4_46s5l"]
[node name="InGameUI" type="Control"] [node name="InGameUI" type="Control"]
process_mode = 3 process_mode = 3
custom_minimum_size = Vector2(1920, 1080)
layout_mode = 3 layout_mode = 3
anchors_preset = 15 anchors_preset = 15
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
script = ExtResource("1_sc13i") script = ExtResource("1_sc13i")
[node name="PlayerInfoUI" parent="." instance=ExtResource("4_46s5l")]
unique_name_in_owner = true
layout_mode = 1
[node name="MiniMap" parent="." instance=ExtResource("2_6sfje")] [node name="MiniMap" parent="." instance=ExtResource("2_6sfje")]
unique_name_in_owner = true unique_name_in_owner = true
visible = false visible = false

View File

@@ -1,21 +1,5 @@
[gd_scene load_steps=5 format=3 uid="uid://blbqgw3wosc1w"] [gd_scene load_steps=5 format=3 uid="uid://blbqgw3wosc1w"]
[sub_resource type="Animation" id="Animation_bium7"]
resource_name = "fade_in"
length = 0.3
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.3),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 1)]
}
[sub_resource type="Animation" id="Animation_ccrq3"] [sub_resource type="Animation" id="Animation_ccrq3"]
resource_name = "fade_out" resource_name = "fade_out"
length = 0.5 length = 0.5
@@ -27,11 +11,27 @@ tracks/0/interp = 1
tracks/0/loop_wrap = true tracks/0/loop_wrap = true
tracks/0/keys = { tracks/0/keys = {
"times": PackedFloat32Array(0, 0.3), "times": PackedFloat32Array(0, 0.3),
"transitions": PackedFloat32Array(1, 1), "transitions": PackedFloat32Array(1, 7.7),
"update": 0, "update": 0,
"values": [Color(1, 1, 1, 1), Color(1, 1, 1, 0)] "values": [Color(1, 1, 1, 1), Color(1, 1, 1, 0)]
} }
[sub_resource type="Animation" id="Animation_bium7"]
resource_name = "fade_in"
length = 0.3
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.3),
"transitions": PackedFloat32Array(1, 7.7),
"update": 0,
"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 1)]
}
[sub_resource type="Animation" id="Animation_f1eqn"] [sub_resource type="Animation" id="Animation_f1eqn"]
length = 0.001 length = 0.001
tracks/0/type = "value" tracks/0/type = "value"

View File

@@ -0,0 +1,75 @@
using Chickensoft.AutoInject;
using Chickensoft.GodotNodeInterfaces;
using Chickensoft.Introspection;
using Godot;
namespace GameJamDungeon;
public interface IPlayerInfoUI : IControl
{
public void DisplayInventoryFullMessage(string rejectedItemName);
}
[Meta(typeof(IAutoNode))]
public partial class PlayerInfoUI : Control, IPlayerInfoUI
{
public override void _Notification(int what) => this.Notify(what);
private LabelSettings _labelSettings { get; set; }
#region Nodes
[Node] public VBoxContainer PlayerInfo { get; set; } = default!;
[Node] public Label LevelNumber { get; set; } = default!;
[Node] public Label HPNumber { get; set; } = default!;
[Node] public Label VTNumber { get; set; } = default!;
#endregion
[Dependency]
public IGameRepo GameRepo => this.DependOn<IGameRepo>();
public void OnResolved()
{
_labelSettings = GD.Load<LabelSettings>("res://src/ui/label_settings/MainTextRegular.tres");
GameRepo.PlayerData.CurrentHP.Sync += CurrentHP_Sync;
GameRepo.PlayerData.MaximumHP.Sync += MaximumHP_Sync;
GameRepo.PlayerData.CurrentVT.Sync += CurrentVT_Sync;
GameRepo.PlayerData.MaximumVT.Sync += MaximumVT_Sync;
GameRepo.PlayerData.CurrentLevel.Sync += CurrentLevel_Sync;
}
private void CurrentLevel_Sync(int obj)
{
LevelNumber.Text = $"{obj}";
}
private void MaximumVT_Sync(int obj)
{
VTNumber.Text = $"{GameRepo.PlayerData.CurrentVT.Value}/{obj}";
}
private void CurrentVT_Sync(int obj)
{
VTNumber.Text = $"{obj}/{GameRepo.PlayerData.MaximumVT.Value}";
}
private void MaximumHP_Sync(int obj)
{
HPNumber.Text = $"{GameRepo.PlayerData.CurrentHP.Value}/{obj}";
}
private void CurrentHP_Sync(int obj)
{
HPNumber.Text = $"{obj}/{GameRepo.PlayerData.MaximumHP.Value}";
}
public void DisplayInventoryFullMessage(string rejectedItemName)
{
var newLabel = new Label() { Text = $"Could not pick up {rejectedItemName}.", LabelSettings = _labelSettings };
PlayerInfo.AddChild(newLabel);
}
}

View File

@@ -0,0 +1,98 @@
[gd_scene load_steps=5 format=3 uid="uid://dxl8il8f13c2x"]
[ext_resource type="Texture2D" uid="uid://hg2kraa5nrnl" path="res://src/ui/textures/blank level symbol.png" id="1_78qrq"]
[ext_resource type="Script" path="res://src/ui/player_ui/PlayerInfoUI.cs" id="1_d8yyu"]
[ext_resource type="LabelSettings" uid="uid://ca1q6yu8blwxf" path="res://src/ui/label_settings/InventoryMainTextBold.tres" id="2_aa7fx"]
[ext_resource type="LabelSettings" uid="uid://dupifadnagodp" path="res://src/ui/label_settings/MainTextRegular.tres" id="3_xdjh1"]
[node name="PlayerInfoUI" 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_d8yyu")
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 1
anchors_preset = 9
anchor_bottom = 1.0
offset_right = 426.0
grow_vertical = 2
theme_override_constants/margin_left = 32
[node name="PlayerInfo" type="VBoxContainer" parent="MarginContainer"]
unique_name_in_owner = true
layout_mode = 2
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/PlayerInfo"]
layout_mode = 2
[node name="CenterContainer" type="CenterContainer" parent="MarginContainer/PlayerInfo/HBoxContainer"]
layout_mode = 2
[node name="TextureRect" type="TextureRect" parent="MarginContainer/PlayerInfo/HBoxContainer/CenterContainer"]
custom_minimum_size = Vector2(128, 128)
layout_mode = 2
size_flags_vertical = 3
texture = ExtResource("1_78qrq")
expand_mode = 1
stretch_mode = 4
[node name="LevelNumber" type="Label" parent="MarginContainer/PlayerInfo/HBoxContainer/CenterContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(80, 80)
layout_mode = 2
text = "99"
label_settings = ExtResource("2_aa7fx")
horizontal_alignment = 1
vertical_alignment = 1
[node name="VBox" type="VBoxContainer" parent="MarginContainer/PlayerInfo/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
theme_override_constants/separation = 15
[node name="HBox" type="HBoxContainer" parent="MarginContainer/PlayerInfo/HBoxContainer/VBox"]
layout_mode = 2
size_flags_horizontal = 3
[node name="HP" type="Label" parent="MarginContainer/PlayerInfo/HBoxContainer/VBox/HBox"]
layout_mode = 2
text = "HP: "
label_settings = ExtResource("2_aa7fx")
[node name="ReferenceRect" type="ReferenceRect" parent="MarginContainer/PlayerInfo/HBoxContainer/VBox/HBox"]
custom_minimum_size = Vector2(30, 0)
layout_mode = 2
border_width = 0.0
[node name="HPNumber" type="Label" parent="MarginContainer/PlayerInfo/HBoxContainer/VBox/HBox"]
unique_name_in_owner = true
layout_mode = 2
text = "222/222"
label_settings = ExtResource("3_xdjh1")
[node name="HBox2" type="HBoxContainer" parent="MarginContainer/PlayerInfo/HBoxContainer/VBox"]
layout_mode = 2
[node name="VT" type="Label" parent="MarginContainer/PlayerInfo/HBoxContainer/VBox/HBox2"]
layout_mode = 2
text = "VT:"
label_settings = ExtResource("2_aa7fx")
[node name="ReferenceRect" type="ReferenceRect" parent="MarginContainer/PlayerInfo/HBoxContainer/VBox/HBox2"]
custom_minimum_size = Vector2(30, 0)
layout_mode = 2
border_width = 0.0
[node name="VTNumber" type="Label" parent="MarginContainer/PlayerInfo/HBoxContainer/VBox/HBox2"]
unique_name_in_owner = true
layout_mode = 2
text = "444/444"
label_settings = ExtResource("3_xdjh1")
[node name="TextureButton" type="TextureButton" parent="MarginContainer"]
layout_mode = 2