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

@@ -2,6 +2,7 @@ using Chickensoft.AutoInject;
using Chickensoft.Collections;
using Chickensoft.GodotNodeInterfaces;
using Chickensoft.Introspection;
using Chickensoft.LogicBlocks;
using Godot;
using System;
using System.Linq;
@@ -14,7 +15,7 @@ public interface IEnemy : ICharacterBody3D
public AutoProp<double> CurrentHP { get; set; }
public EnemyStatInfo EnemyStatInfo { get; set; }
public EnemyStatResource EnemyStatResource { 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>();
[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");
@@ -62,14 +63,14 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
public void Setup()
{
EnemyLogic = new EnemyLogic();
EnemyLogic.Set(EnemyStatInfo);
EnemyLogic.Set(EnemyStatResource);
EnemyLogic.Set(this as IEnemy);
EnemyLogic.Set(GameRepo);
}
public void Initialize()
{
CurrentHP = new AutoProp<double>(EnemyStatInfo.MaximumHP);
CurrentHP = new AutoProp<double>(EnemyStatResource.MaximumHP);
CurrentHP.Sync += OnHPChanged;
LineOfSight.BodyEntered += LineOfSight_BodyEntered;
PatrolTimer.Timeout += OnPatrolTimeout;
@@ -138,8 +139,8 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
})
.Handle((in EnemyLogic.Output.HitByPlayer output) =>
{
if (GameRepo.EquippedWeapon.Value.WeaponInfo.WeaponTags.Contains(WeaponTag.SelfDamage))
GameRepo.PlayerStatInfo.Value.CurrentHP -= 5;
if (GameRepo.PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.WeaponTags.Contains(WeaponTag.SelfDamage))
GameRepo.PlayerData.CurrentHP.OnNext(GameRepo.PlayerData.CurrentHP.Value - 5);
});
this.Provide();
@@ -182,9 +183,9 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
var rng = new RandomNumberGenerator();
rng.Randomize();
var roll = rng.Randf();
if (roll <= GameRepo.EquippedWeapon.Value.WeaponInfo.Luck)
if (roll <= GameRepo.PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.Luck)
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.");
EnemyLogic.Input(new EnemyLogic.Input.HitByPlayer(damage));
}

View File

@@ -3,7 +3,7 @@
namespace GameJamDungeon
{
[GlobalClass]
public partial class EnemyStatInfo : Resource, ICharacterStats
public partial class EnemyStatResource : Resource
{
[Export]
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"]
[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]
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="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"]
[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"]
resource_name = "Material.001"
cull_mode = 2
@@ -155,7 +175,7 @@ collision_layer = 10
collision_mask = 9
axis_lock_linear_y = true
script = ExtResource("1_jw471")
EnemyStatInfo = ExtResource("2_b8sx5")
EnemyStatResource = SubResource("Resource_rxw8v")
[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.GodotNodeInterfaces;
using Chickensoft.Introspection;
using DialogueManagerRuntime;
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
public interface IGame : IProvide<IGameRepo>, IProvide<IGame>, INode3D
{
public void ToggleInventory();
}
[Meta(typeof(IAutoNode))]
@@ -34,17 +29,17 @@ public partial class Game : Node3D, IGame
[Dependency] public IAppRepo AppRepo => this.DependOn<IAppRepo>();
#region Nodes
[Node] public IMap Map { get; set; } = default!;
[Node] public DialogueController DialogueController { get; set; } = default!;
[Node] public IPauseMenu PauseMenu { get; set; } = default!;
[Node] public InGameUI InGameUI { get; set; } = default!;
[Node] public FloorClearMenu FloorClearMenu { 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()
{
@@ -53,9 +48,30 @@ public partial class Game : Node3D, IGame
GameLogic.Set(GameRepo);
GameLogic.Set(AppRepo);
Instantiator = new Instantiator(GetTree());
}
FloorClearMenu.TransitionCompleted += OnFloorClearTransitionCompleted;
PauseMenu.TransitionCompleted += OnPauseMenuTransitioned;
private void PlayerInventory_InventoryAtCapacity(string rejectedItem)
{
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()
@@ -68,12 +84,6 @@ public partial class Game : Node3D, IGame
GameLogic.Input(new GameLogic.Input.PauseMenuTransitioned());
}
public void Exit()
{
GameLogic.Input(new GameLogic.Input.LoadNextFloor());
GameRepo.Resume();
}
public void OnResolved()
{
GameBinding = GameLogic.Bind();
@@ -92,6 +102,7 @@ public partial class Game : Node3D, IGame
.Handle((in GameLogic.Output.HidePauseMenu _) => { PauseMenu.Hide(); })
.Handle((in GameLogic.Output.ExitPauseMenu _) => { PauseMenu.FadeOut(); })
.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.HideInventory _) => { InGameUI.HideInventoryScreen(); })
.Handle((in GameLogic.Output.ShowMiniMap _) => { InGameUI.ShowMiniMap(); })
@@ -103,6 +114,14 @@ public partial class Game : Node3D, IGame
GameLogic.Input(new GameLogic.Input.Initialize());
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()
@@ -143,5 +162,5 @@ public partial class Game : Node3D, IGame
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")]
unique_name_in_owner = true
visible = false
[node name="InGameAudio" parent="." instance=ExtResource("6_qc71l")]
@@ -47,6 +46,7 @@ visible = false
[node name="FloorClearMenu" parent="." instance=ExtResource("11_rya1n")]
unique_name_in_owner = true
visible = false
modulate = Color(1, 1, 1, 1)
[node name="PauseMenu" parent="." instance=ExtResource("12_yev8k")]
unique_name_in_owner = true

View File

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

View File

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

View File

@@ -1,6 +1,7 @@
@startuml GameLogic
state "GameLogic State" as GameJamDungeon_GameLogic_State {
state "FloorCleared" as GameJamDungeon_GameLogic_State_FloorCleared
state "GameStarted" as GameJamDungeon_GameLogic_State_GameStarted
state "InventoryOpened" as GameJamDungeon_GameLogic_State_InventoryOpened
state "MenuBackdrop" as GameJamDungeon_GameLogic_State_MenuBackdrop
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
}
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_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_Paused --> GameJamDungeon_GameLogic_State_Resuming : PauseButtonPressed
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_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 : OnExit → HideInventory
GameJamDungeon_GameLogic_State_MinimapOpen : OnEnter → ShowMiniMap
GameJamDungeon_GameLogic_State_MinimapOpen : OnExit → HideMiniMap
GameJamDungeon_GameLogic_State_Paused : OnEnter → ShowPauseMenu
GameJamDungeon_GameLogic_State_Paused : OnExit → ExitPauseMenu
GameJamDungeon_GameLogic_State_Playing : OnEnter → StartGame
GameJamDungeon_GameLogic_State_Quit : OnEnter → ShowLostScreen
GameJamDungeon_GameLogic_State_Resuming : OnExit → HidePauseMenu

View File

@@ -1,107 +1,57 @@
using Chickensoft.Collections;
using Godot;
using System;
using System.Collections.Generic;
namespace GameJamDungeon;
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 Resume();
IAutoProp<bool> IsPaused { get; }
IAutoProp<Vector3> PlayerGlobalPosition { get; }
PlayerData PlayerData { get; }
public void SetPlayerData(PlayerData playerData);
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 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 void OnGameEnded();
event Action? Ended;
}
public class GameRepo : IGameRepo
{
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;
private readonly AutoProp<Vector3> _playerGlobalPosition;
public IAutoProp<bool> IsPaused => _isPaused;
private readonly AutoProp<bool> _isPaused;
private AutoProp<Weapon> _equippedWeapon;
public AutoProp<Weapon> EquippedWeapon => _equippedWeapon;
private AutoProp<Armor> _equippedArmor;
public AutoProp<Armor> EquippedArmor => _equippedArmor;
private AutoProp<Accessory> _equippedAccessory;
public AutoProp<Accessory> EquippedAccessory => _equippedAccessory;
public bool IsWithinDialogueSpace { get; set; }
public PlayerData PlayerData => _playerData;
private PlayerData _playerData;
public int MaxItemSize => 20;
private bool _disposedValue;
private AutoProp<PlayerStatInfo> _playerStatInfo;
public AutoProp<PlayerStatInfo> PlayerStatInfo => _playerStatInfo;
public int CurrentFloor { get; set; } = -1;
public int CurrentFloor { get; set; } = 0;
public GameRepo()
{
_inventoryItems = new AutoProp<List<IInventoryItem>>([]);
_isInventoryScreenOpened = new AutoProp<bool>(false);
_isPaused = new AutoProp<bool>(false);
_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()
@@ -118,37 +68,7 @@ public class GameRepo : IGameRepo
public void SetPlayerGlobalPosition(Vector3 playerGlobalPosition) => _playerGlobalPosition.OnNext(playerGlobalPosition);
public void SetPlayerStatInfo(PlayerStatInfo playerStatInfo) => _playerStatInfo.OnNext(playerStatInfo);
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 SetPlayerData(PlayerData playerData) => _playerData = playerData;
public void OnGameEnded()
{
@@ -156,42 +76,6 @@ public class GameRepo : IGameRepo
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)
{
if (!_disposedValue)
@@ -200,10 +84,6 @@ public class GameRepo : IGameRepo
{
_playerGlobalPosition.OnCompleted();
_playerGlobalPosition.Dispose();
_inventoryItems.OnCompleted();
_inventoryItems.Dispose();
_isInventoryScreenOpened.OnCompleted();
_isInventoryScreenOpened.Dispose();
_isPaused.OnCompleted();
_isPaused.Dispose();
}

View File

@@ -8,12 +8,17 @@ namespace GameJamDungeon
public partial record State
{
[Meta]
public partial record FloorCleared : State
public partial record FloorCleared : State, IGet<Input.GoToNextFloor>
{
public FloorCleared()
{
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()
{
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()); });
}
public Transition On(in Input.InventoryMenuToggle input) => To<Playing>();

View File

@@ -7,7 +7,7 @@ namespace GameJamDungeon
public partial record State
{
[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()
{
@@ -15,9 +15,9 @@ namespace GameJamDungeon
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)
{

View File

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

View File

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

View File

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

View File

@@ -42,9 +42,9 @@ public partial class ItemSlot : HBoxContainer, IItemSlot
ItemName.Text = Item.Info.Name;
EquipBonus.Text = "...";
ItemTexture.Texture = Item.Info.Texture;
GameRepo.EquippedWeapon.Sync += EquippedWeapon_Sync;
GameRepo.EquippedArmor.Sync += EquippedArmor_Sync;
GameRepo.EquippedAccessory.Sync += EquippedAccessory_Sync;
GameRepo.PlayerData.Inventory.EquippedWeapon.Sync += EquippedWeapon_Sync;
GameRepo.PlayerData.Inventory.EquippedArmor.Sync += EquippedArmor_Sync;
GameRepo.PlayerData.Inventory.EquippedAccessory.Sync += EquippedAccessory_Sync;
}
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;
namespace GameJamDungeon
{
public interface IInventoryItem : INode3D
{
public Guid ID { get; }
public IGameRepo GameRepo { get; }
public InventoryItemInfo Info { get; }
public InventoryItemStats Info { get; }
public void Throw();

View File

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

View File

@@ -31,23 +31,23 @@ namespace GameJamDungeon
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>();
armorScene.ArmorInfo = armorInfo;
armorScene.ArmorStats = armorInfo;
database.Add(armorScene);
}
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>();
weaponScene.WeaponInfo = weaponInfo;
weaponScene.WeaponStats = weaponInfo;
database.Add(weaponScene);
}
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>();
accessoryScene.AccessoryInfo = accessoryInfo;
database.Add(accessoryScene);
@@ -55,7 +55,7 @@ namespace GameJamDungeon
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>();
throwableItemScene.ThrowableItemInfo = throwableItemInfo;
database.Add(throwableItemScene);
@@ -63,7 +63,7 @@ namespace GameJamDungeon
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>();
consumableItemScene.ConsumableItemInfo = consumableItemInfo;
database.Add(consumableItemScene);

View File

@@ -1,16 +1,16 @@
[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="PackedScene" uid="uid://db206brufi83s" path="res://src/items/weapons/Weapon.tscn" id="2_14w53"]
[ext_resource type="PackedScene" uid="uid://dorr7v1tkeiy0" path="res://src/items/armor/Armor.tscn" id="3_p6rkn"]
[ext_resource type="PackedScene" uid="uid://b07srt3lckt4e" path="res://src/items/accessory/Accessory.tscn" id="4_oqm6k"]
[ext_resource type="PackedScene" uid="uid://1fl6s352e2ej" path="res://src/items/throwable/ThrowableItem.tscn" id="5_l0fpl"]
[ext_resource type="PackedScene" uid="uid://c6w7dpk0hurj0" path="res://src/items/consumable/ConsumableItem.tscn" id="6_51k8r"]
[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_8wlg5"]
[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_r5y4t"]
[ext_resource type="PackedScene" uid="uid://c6w7dpk0hurj0" path="res://src/items/consumable/ConsumableItem.tscn" id="6_yvger"]
[node name="ItemDatabase" type="Node"]
script = ExtResource("1_7b315")
WeaponScene = ExtResource("2_14w53")
ArmorScene = ExtResource("3_p6rkn")
AccessoryScene = ExtResource("4_oqm6k")
ThrowableItemScene = ExtResource("5_l0fpl")
ConsumableItemScene = ExtResource("6_51k8r")
WeaponScene = ExtResource("2_wq002")
ArmorScene = ExtResource("3_8wlg5")
AccessoryScene = ExtResource("4_pr7ub")
ThrowableItemScene = ExtResource("5_r5y4t")
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 Guid ID { get; } = new Guid();
[Dependency] public IGameRepo GameRepo => this.DependOn<IGameRepo>();
public InventoryItemInfo Info => AccessoryInfo;
public InventoryItemStats Info => AccessoryInfo;
[Export]
public AccessoryInfo AccessoryInfo { get; set; } = new AccessoryInfo();
public AccessoryStats AccessoryInfo { get; set; } = new AccessoryStats();
[Node] public Sprite3D Sprite { get; set; } = default!;
@@ -32,21 +30,18 @@ public partial class Accessory : Node3D, IInventoryItem, IEquipable
public void Throw()
{
GameRepo.InventoryItems.Value.Remove(this);
GameRepo.PlayerData.Inventory.Remove(this);
}
public void Drop()
{
GameRepo.InventoryItems.Value.Remove(this);
GameRepo.PlayerData.Inventory.Remove(this);
}
public void OnEntered(Node3D body)
{
if (GameRepo.InventoryItems.Value.Count() >= GameRepo.MaxItemSize)
return;
var inventoryList = GameRepo.InventoryItems.Value.Append(this).ToList();
GameRepo.InventoryItems.OnNext(inventoryList);
QueueFree();
var isAdded = GameRepo.PlayerData.Inventory.TryAdd(this);
if (isAdded)
QueueFree();
}
}

View File

@@ -4,7 +4,7 @@ using System;
namespace GameJamDungeon;
[GlobalClass]
public partial class AccessoryInfo : InventoryItemInfo
public partial class AccessoryStats : InventoryItemStats
{
[Export]
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="Script" path="res://src/items/accessory/AccessoryInfo.cs" id="1_sjkji"]
[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/AccessoryStats.cs" id="1_xqaot"]
[resource]
script = ExtResource("1_sjkji")
script = ExtResource("1_xqaot")
ATKUp = 0
DEFUp = 0
LUCKUp = 0.15
@@ -12,6 +12,6 @@ MaxHPUp = 0
MaxVTUp = 0
AccessoryTags = []
Name = "Mask of the Goddess of Avarice"
Description = "Raises LUCK."
Texture = ExtResource("1_578a0")
Description = "Raises Luck"
Texture = ExtResource("1_q42cv")
SpawnRate = 0.5

View File

@@ -1,7 +1,7 @@
[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="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]
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"]
[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]
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"]
[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]
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"]
[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"]
[resource]

View File

@@ -1,7 +1,7 @@
[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="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]
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"]
[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"]
[resource]

View File

@@ -1,6 +1,6 @@
[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"]
[resource]

View File

@@ -3,25 +3,26 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://hjyk3j24o48b"
path="res://.godot/imported/MASK 03.PNG-9ab390330efa1f35084ad56075377b4d.ctex"
path.s3tc="res://.godot/imported/MASK 03.PNG-9ab390330efa1f35084ad56075377b4d.s3tc.ctex"
metadata={
"vram_texture": false
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
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]
compress/mode=0
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@@ -31,4 +32,4 @@ process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
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 Godot;
using System;
using System.Collections.Generic;
using System.Linq;
[Meta(typeof(IAutoNode))]
public partial class Armor : Node3D, IInventoryItem, IEquipable
{
public override void _Notification(int what) => this.Notify(what);
public Guid ID { get; } = new Guid();
[Dependency] public IGameRepo GameRepo => this.DependOn<IGameRepo>();
public InventoryItemInfo Info => ArmorInfo;
public InventoryItemStats Info => ArmorStats;
[Export]
public ArmorInfo ArmorInfo { get; set; } = new ArmorInfo();
public ArmorStats ArmorStats { get; set; } = new ArmorStats();
[Node] public Sprite3D Sprite { get; set; } = default!;
@@ -26,27 +22,24 @@ public partial class Armor : Node3D, IInventoryItem, IEquipable
public void OnReady()
{
Sprite.Texture = ArmorInfo.Texture;
Sprite.Texture = ArmorStats.Texture;
Pickup.BodyEntered += OnEntered;
}
public void Throw()
{
GameRepo.InventoryItems.Value.Remove(this);
GameRepo.PlayerData.Inventory.Remove(this);
}
public void Drop()
{
GameRepo.InventoryItems.Value.Remove(this);
GameRepo.PlayerData.Inventory.Remove(this);
}
public void OnEntered(Node3D body)
{
if (GameRepo.InventoryItems.Value.Count() >= GameRepo.MaxItemSize)
return;
var inventoryList = GameRepo.InventoryItems.Value.Append(this).ToList();
GameRepo.InventoryItems.OnNext(inventoryList);
QueueFree();
var isAdded = GameRepo.PlayerData.Inventory.TryAdd(this);
if (isAdded)
QueueFree();
}
}

View File

@@ -3,7 +3,7 @@
namespace GameJamDungeon;
[GlobalClass]
public partial class ArmorInfo : InventoryItemInfo
public partial class ArmorStats : InventoryItemStats
{
[Export]
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"]
[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]
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"]
[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"]
[resource]

View File

@@ -1,6 +1,6 @@
[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"]
[resource]

View File

@@ -1,7 +1,7 @@
[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="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]
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"]
[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"]
[resource]

View File

@@ -1,6 +1,6 @@
[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"]
[resource]

View File

@@ -1,6 +1,6 @@
[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"]
[resource]

View File

@@ -1,6 +1,6 @@
[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"]
[resource]

View File

@@ -1,6 +1,6 @@
[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"]
[resource]

View File

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

View File

@@ -1,12 +1,17 @@
[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/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"]
script = ExtResource("2_g3oo3")
HealHPAmount = 0
RaiseHPAmount = 0
HealVTAmount = 0
RaiseVTAmount = 0
Name = ""
Description = ""
SpawnRate = 0.5
[sub_resource type="BoxShape3D" id="BoxShape3D_7mh0f"]
size = Vector3(0.778381, 0.929947, 0.731567)

View File

@@ -3,7 +3,7 @@
namespace GameJamDungeon;
[GlobalClass]
public partial class ConsumableItemInfo : InventoryItemInfo
public partial class ConsumableItemStats : InventoryItemStats
{
[Export]
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"]
[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"]
[resource]

View File

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

View File

@@ -3,7 +3,7 @@
namespace GameJamDungeon;
[GlobalClass]
public partial class ThrowableItemInfo : InventoryItemInfo
public partial class ThrowableItemStats : InventoryItemStats
{
[Export]
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"]
[resource]

View File

@@ -1,7 +1,7 @@
[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="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]
script = ExtResource("1_s3pq7")

View File

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

View File

@@ -2,7 +2,7 @@ using GameJamDungeon;
using Godot;
[GlobalClass]
public partial class WeaponInfo : InventoryItemInfo
public partial class WeaponStats : InventoryItemStats
{
[Export]
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"]
[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]
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"]
[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"]
[resource]

View File

@@ -1,7 +1,7 @@
[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="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]
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"]
[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]
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"]
[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]
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"]
[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"]
[resource]

View File

@@ -1,6 +1,6 @@
[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"]
[resource]

View File

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

View File

@@ -2,12 +2,16 @@ using Chickensoft.AutoInject;
using Chickensoft.GodotNodeInterfaces;
using Chickensoft.Introspection;
using Godot;
using System.Collections.Generic;
using System.Linq;
public interface IDungeonFloor : INode3D
{
void InitializeDungeon();
public Vector3 GetPlayerSpawnPoint();
public Vector3 GetTeleportSpawnPoint();
}
[Meta(typeof(IAutoNode))]
@@ -17,13 +21,34 @@ public partial class DungeonFloor : Node3D, IDungeonFloor
[Node] public GodotObject DungeonGenerator { get; set; } = default!;
internal List<IDungeonRoom> Rooms { get; private set; }
public void InitializeDungeon()
{
Rooms = new List<IDungeonRoom>();
DungeonGenerator.Call("generate");
Rooms = FindAllDungeonRooms(GetChildren().ToList(), Rooms);
}
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 ExitSpawnPoint { get; set; } = default!;
public void InitializeDungeon()
{
GameRepo.SetPlayerGlobalPosition(PlayerSpawnPoint.GlobalPosition);
@@ -22,4 +24,9 @@ public partial class Overworld : Node3D, IDungeonFloor
{
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)
[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")
size_in_voxels = Vector3i(5, 2, 5)
voxel_scale = Vector3(12, 12, 12)
[node name="Room" type="Node3D" parent="."]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -6.03201, 0)
script = ExtResource("16_osbes")
[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")
[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)
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"]
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"]
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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[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
[node name="EnemySpawnPoints" type="Node3D" parent="Room"]
unique_name_in_owner = true
[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")]
unique_name_in_owner = true
@@ -1389,5 +1386,12 @@ unique_name_in_owner = true
unique_name_in_owner = true
SpawnRate = PackedFloat32Array(1)
[node name="ExitSpawnLocation" type="Marker3D" parent="Room" groups=["Exit"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.06499, -11.8837, -9.52855)
[node name="TeleportSpawn" type="Marker3D" parent="Room" groups=["Exit"]]
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; }
public Marker3D PlayerSpawn { get; set; }
public Marker3D TeleportSpawn { get; set; }
}
[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 TeleportSpawn { get; set; } = default!;
[Node] public Node3D ItemSpawnPoints { 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"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.320954, -4.84337, -0.0752945)
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="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://bjqgl5u05ia04" path="res://src/map/dungeon/Teleport.tscn" id="4_4sp6u"]
[node name="Overworld" type="Node3D"]
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")]
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
{
PlayerStatInfo PlayerStatInfo { get; }
PlayerLogic PlayerLogic { get; }
PlayerData PlayerData { get; }
public Vector3 GetGlobalInputVector();
public float GetLeftStrafeInputVector();
@@ -38,27 +34,13 @@ namespace GameJamDungeon
[Dependency]
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]
public PlayerStatInfo PlayerStatInfo { get; set; }
public PlayerStatResource PlayerStatResource { get; set; } = default!;
public PlayerLogic.Settings Settings { get; set; } = default!;
public PlayerLogic PlayerLogic { get; set; } = default!;
public PlayerData PlayerData { get; set; } = default!;
public PlayerLogic.IBinding PlayerBinding { 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 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!;
private PlayerData PlayerData { get; set; } = default!;
public void Initialize()
{
AnimationPlayer.AnimationFinished += OnAnimationFinished;
@@ -84,7 +62,29 @@ namespace GameJamDungeon
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.Set(this as IPlayer);
@@ -92,6 +92,12 @@ namespace GameJamDungeon
PlayerLogic.Set(AppRepo);
PlayerLogic.Set(GameRepo);
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()
@@ -106,9 +112,8 @@ namespace GameJamDungeon
})
.Handle((in PlayerLogic.Output.Animations.Attack output) =>
{
var weaponInfo = GameRepo.EquippedWeapon.Value.WeaponInfo;
var attackSpeed = (float)weaponInfo.AttackSpeed;
AnimationPlayer.SetSpeedScale(attackSpeed);
var attackSpeed = PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.AttackSpeed;
AnimationPlayer.SetSpeedScale((float)attackSpeed);
AnimationPlayer.Play("attack");
})
.Handle((in PlayerLogic.Output.ThrowItem output) =>
@@ -117,11 +122,10 @@ namespace GameJamDungeon
this.Provide();
PlayerLogic.Start();
GameRepo.SetPlayerData(PlayerData);
SwordSlashAnimation.Position = GetViewport().GetVisibleRect().Size / 2;
GlobalPosition = GameRepo.PlayerGlobalPosition.Value;
GameRepo.SetPlayerStatInfo(PlayerStatInfo);
GameRepo.PlayerGlobalPosition.Sync += PlayerGlobalPosition_Sync;
HealthTimer.Timeout += OnHealthTimerTimeout;
CollisionDetector.AreaEntered += OnEnemyHitBoxEntered;
}
@@ -142,26 +146,6 @@ namespace GameJamDungeon
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)
{
PlayerLogic.Input(new PlayerLogic.Input.PhysicsTick(delta));
@@ -171,13 +155,6 @@ namespace GameJamDungeon
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()
{
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());
private void OnHPChanged(double newHP)
private void PlayerGlobalPosition_Sync(Vector3 newPlayerPosition)
{
HPNumber.Text = $"{Mathf.RoundToInt(newHP)}/{PlayerStatInfo.MaximumHP}";
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}";
GlobalPosition = newPlayerPosition;
}
private void OnPlayerPositionUpdated(Vector3 globalPosition) => GlobalPosition = globalPosition;
private void OnHealthTimerTimeout()
{
if (GameRepo.PlayerStatInfo.Value.CurrentVT > 0)
GameRepo.PlayerStatInfo.Value.CurrentVT = GameRepo.PlayerStatInfo.Value.CurrentVT - 1;
if (PlayerData.CurrentVT.Value > 0)
PlayerData.CurrentVT.OnNext(PlayerData.CurrentVT.Value - 1);
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="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/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://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://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://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"]
script = ExtResource("2_n88di")
CurrentHP = 100.0
MaximumHP = 100.0
[sub_resource type="Resource" id="Resource_btp2w"]
script = ExtResource("2_xq68d")
RotationSpeed = 3.0
MoveSpeed = 4.0
Acceleration = 1.0
CurrentHP = 100
MaximumHP = 100
CurrentVT = 90
MaximumVT = 90
CurrentExp = 0
ExpToNextLevel = 100
CurrentLevel = 1
CurrentEXP = 0
EXPToNextLevel = 100
CurrentAttack = 12
MaxAttack = 12
CurrentDefense = 8
MaxDefense = 8
CurrentAttack = 14
CurrentDefense = 12
MaxAttack = 14
MaxDefense = 12
BonusAttack = 0
BonusDefense = 0
Luck = 0.0
Luck = 0.05
[sub_resource type="BoxShape3D" id="BoxShape3D_wedu3"]
@@ -98,8 +98,8 @@ tracks/1/keys = {
[sub_resource type="AnimationLibrary" id="AnimationLibrary_w8l8m"]
_data = {
&"attack": SubResource("Animation_0jjwv"),
&"RESET": SubResource("Animation_hcjph")
"RESET": SubResource("Animation_hcjph"),
"attack": SubResource("Animation_0jjwv")
}
[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_mask = 7
script = ExtResource("1_xcol5")
RotationSpeed = 3.0
MoveSpeed = 4.0
Acceleration = 1.0
PlayerStatInfo = SubResource("Resource_up0v1")
PlayerStatResource = SubResource("Resource_btp2w")
[node name="Hitbox" type="Area3D" parent="."]
unique_name_in_owner = true
@@ -183,7 +180,7 @@ omni_range = 83.659
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
unique_name_in_owner = true
libraries = {
&"": SubResource("AnimationLibrary_w8l8m")
"": SubResource("AnimationLibrary_w8l8m")
}
[node name="SwordSlashAnimation" type="AnimatedSprite2D" parent="."]
@@ -197,82 +194,3 @@ unique_name_in_owner = true
process_mode = 1
wait_time = 3.0
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;
namespace GameJamDungeon
@@ -12,5 +13,36 @@ namespace GameJamDungeon
public required PlayerLogic StateMachine { get; init; }
[Save("velocity")]
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 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 igneousResistance = enemyStatInfo.IgneousResistance;
var telluricResistance = enemyStatInfo.TelluricResistance;
@@ -27,7 +26,7 @@ namespace GameJamDungeon
var elementCDamage = (weapon.TelluricDamageBonus > 0 ? weapon.TelluricDamageBonus - telluricResistance : 0) / 100;
var elementDDamage = (weapon.AeolicDamageBonus > 0 ? weapon.AeolicDamageBonus - aeolicResistance : 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;
if (isCriticalHit)
@@ -36,16 +35,16 @@ namespace GameJamDungeon
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 elementBDamage = (enemyStatInfo.IgneousDamageBonus > 0 ? enemyStatInfo.IgneousDamageBonus - armor.IgneousResistance : 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 elementEDamage = (enemyStatInfo.FerrumDamageBonus > 0 ? enemyStatInfo.FerrumDamageBonus - armor.FerrumResistance : 0) / 100;
var elementalBonusDamage = baseDamage + (baseDamage * elementADamage) + (baseDamage * elementBDamage) + (baseDamage * elementCDamage) + (baseDamage * elementDDamage) + (baseDamage * elementEDamage);
var calculatedDamage = elementalBonusDamage - playerStatInfo.CurrentDefense - (armor != null ? armor.Defense : 0);
var elementalBonusDamage = totalAttack + (totalAttack * elementADamage) + (totalAttack * elementBDamage) + (totalAttack * elementCDamage) + (totalAttack * elementDDamage) + (totalAttack * elementEDamage);
var calculatedDamage = elementalBonusDamage - playerTotalDefense - (armor != null ? armor.Defense : 0);
if (isCriticalHit)
calculatedDamage *= 2;

View File

@@ -1,19 +1,21 @@
namespace GameJamDungeon
using Chickensoft.Collections;
namespace GameJamDungeon
{
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"]
[node name="DialogueBalloon" type="CanvasLayer"]
process_mode = 3
layer = 100
script = ExtResource("1_okfmu")
NextAction = "ui_cancel"

View File

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

View File

@@ -3,8 +3,6 @@ using Chickensoft.GodotNodeInterfaces;
using Chickensoft.Introspection;
using GameJamDungeon;
using Godot;
using System;
using System.Linq;
[Meta(typeof(IAutoNode))]
public partial class FloorClearMenu : Control
@@ -27,10 +25,4 @@ public partial class FloorClearMenu : Control
{
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.Introspection;
using Godot;
using System.Threading.Tasks;
namespace GameJamDungeon;
public interface IInGameUI : IControl
{
public Task ShowInventoryScreen();
public void ShowInventoryScreen();
public void HideInventoryScreen();
public void ShowMiniMap();
public void HideMiniMap();
public void ShowInventoryFullMessage(string rejectedItemName);
}
[Meta(typeof(IAutoNode))]
@@ -26,6 +27,13 @@ public partial class InGameUI : Control, IInGameUI
[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()
{
InventoryMenu.Hide();
@@ -36,9 +44,9 @@ public partial class InGameUI : Control, IInGameUI
MiniMap.Hide();
}
public async Task ShowInventoryScreen()
public void ShowInventoryScreen()
{
await InventoryMenu.RedrawInventory();
InventoryMenu.RedrawInventory();
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="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://dxl8il8f13c2x" path="res://src/ui/player_ui/PlayerInfoUI.tscn" id="4_46s5l"]
[node name="InGameUI" type="Control"]
process_mode = 3
custom_minimum_size = Vector2(1920, 1080)
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
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")]
unique_name_in_owner = true
visible = false

View File

@@ -1,21 +1,5 @@
[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"]
resource_name = "fade_out"
length = 0.5
@@ -27,11 +11,27 @@ tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.3),
"transitions": PackedFloat32Array(1, 1),
"transitions": PackedFloat32Array(1, 7.7),
"update": 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"]
length = 0.001
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