Add map loading logic and spawn rate control

This commit is contained in:
2025-09-30 02:32:03 -07:00
parent 70d1871985
commit 6f582fcca1
43 changed files with 470 additions and 118 deletions

View File

@@ -1,16 +0,0 @@
namespace Zennysoft.Ma.Adapter;
public enum Floor
{
Overworld,
Altar,
BossFloorA,
BossFloorB,
GoddessOfGuidanceFloor,
VoidRoom,
FinalFloor,
Floor01,
Floor02,
Floor03,
Floor04,
Floor05,
}

View File

@@ -17,6 +17,4 @@ public partial record PlayerData
[Meta, Id("map_data")]
public partial record MapData
{
[Save("floor_list")]
public required Dictionary<Floor, string> FloorScenes { get; init; }
}

View File

@@ -28,4 +28,8 @@
<ProjectReference Include="..\Zennysoft.Game.Godot.Implementation\Zennysoft.Game.Implementation.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Map\" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,68 @@
using Godot;
using Godot.Collections;
using System.Linq;
using Zennysoft.Game.Ma;
[Tool]
public partial class DungeonFloorLayout : LayoutType
{
[Export]
public DungeonFloorSetType SetType
{
get => _setType;
set
{
_setType = value;
LayoutWithSpawnRate = [];
NotifyPropertyListChanged();
}
}
[ExportToolButton("Populate Map Data")]
public Callable PopulateMapList => Callable.From(() => PopulateDictionary(SetType));
[Export]
public Dictionary<string, float> LayoutWithSpawnRate { get; private set; }
[Export]
public Dictionary<EnemyType, float> EnemySpawnRates { get; set; } = default!;
private string _floorPath = "res://src/map/dungeon/floors/";
private DungeonFloorSetType _setType;
private void PopulateDictionary(DungeonFloorSetType setType)
{
var floorPath = _floorPath;
var floorType = string.Empty;
if (setType == DungeonFloorSetType.SetA)
floorType = "SetAFloors";
else if (setType == DungeonFloorSetType.SetB)
floorType = "SetBFloors";
var pathToScenes = $"{floorPath}/{floorType}";
var files = DirAccess.GetFilesAt(pathToScenes).Where(x => x.EndsWith(".tscn"));
var newMaps = new Dictionary<string, float>();
foreach (var file in files)
{
if (LayoutWithSpawnRate.ContainsKey($"{floorType}/{file}"))
{
var spawnRate = LayoutWithSpawnRate.TryGetValue($"{floorType}/{file}", out var currentSpawnRate);
newMaps.Add($"{floorType}/{file}", currentSpawnRate);
}
else
newMaps.Add($"{floorType}/{file}", 1.0f);
}
LayoutWithSpawnRate = newMaps;
NotifyPropertyListChanged();
}
public enum DungeonFloorSetType
{
SetA,
SetB
}
}

View File

@@ -0,0 +1 @@
uid://ci7o3nn4mdo8o

View File

@@ -0,0 +1,22 @@
#if TOOLS
using Godot;
using Zennysoft.Game.Ma;
[Tool]
public partial class DungeonFloorLayoutNode : EditorPlugin
{
public override void _EnterTree()
{
// Initialization of the plugin goes here.
var script = GD.Load<Script>("res://addons/dungeon_floor_layout/DungeonFloorLayout.cs");
var texture = GD.Load<Texture2D>("res://addons/dungeon_floor_layout/icon_door.png");
AddCustomType(nameof(DungeonFloorLayout), nameof(LayoutType), script, texture);
}
public override void _ExitTree()
{
// Clean-up of the plugin goes here.
RemoveCustomType(nameof(DungeonFloorLayout));
}
}
#endif

View File

@@ -0,0 +1 @@
uid://f87ejxatyy2n

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cgd2d4fusp4pg"
path="res://.godot/imported/icon_door.png-437da3e7d1cb55961e6afceef56e9ea2.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/dungeon_floor_layout/icon_door.png"
dest_files=["res://.godot/imported/icon_door.png-437da3e7d1cb55961e6afceef56e9ea2.ctex"]
[params]
compress/mode=0
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/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

View File

@@ -0,0 +1,7 @@
[plugin]
name="Dungeon Floor Layout"
description=""
author="Zenny"
version=""
script="DungeonFloorLayoutNode.cs"

View File

@@ -0,0 +1,25 @@
using Godot;
using Zennysoft.Game.Ma;
[Tool]
public partial class SpecialFloorLayout : LayoutType
{
[Export]
public SpecialFloorType FloorName { get; set; }
public override void _EnterTree()
{
base._EnterTree();
}
public enum SpecialFloorType
{
Overworld,
Altar,
BossFloorA,
BossFloorB,
GoddessOfGuidanceFloor,
TrueGoddessOfGuidanceFloor,
FinalFloor
}
}

View File

@@ -0,0 +1 @@
uid://cabvj6s31iucg

View File

@@ -0,0 +1,23 @@
#if TOOLS
using Godot;
using System;
using Zennysoft.Game.Ma;
[Tool]
public partial class SpecialFloorLayoutNode : EditorPlugin
{
public override void _EnterTree()
{
// Initialization of the plugin goes here.
var script = GD.Load<Script>("res://addons/special_floor_layout_node/SpecialFloorLayout.cs");
var texture = GD.Load<Texture2D>("res://addons/special_floor_layout_node/icon_door.png");
AddCustomType(nameof(SpecialFloorLayout), nameof(LayoutType), script, texture);
}
public override void _ExitTree()
{
// Clean-up of the plugin goes here.
RemoveCustomType(nameof(SpecialFloorLayout));
}
}
#endif

View File

@@ -0,0 +1 @@
uid://uy8mygg0jtd8

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://pxevsja7e3s0"
path="res://.godot/imported/icon_door.png-d7e4ac87b8cdfac1c9f03b9aff4c7e79.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/special_floor_layout_node/icon_door.png"
dest_files=["res://.godot/imported/icon_door.png-d7e4ac87b8cdfac1c9f03b9aff4c7e79.ctex"]
[params]
compress/mode=0
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/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

View File

@@ -0,0 +1,7 @@
[plugin]
name="Special Floor Layout Node"
description=""
author="Zenny"
version=""
script="SpecialFloorLayoutNode.cs"

View File

@@ -41,7 +41,7 @@ project/assembly_name="Ma"
[editor_plugins]
enabled=PackedStringArray("res://addons/dialogue_manager/plugin.cfg")
enabled=PackedStringArray("res://addons/dialogue_manager/plugin.cfg", "res://addons/dungeon_floor_layout/plugin.cfg", "res://addons/special_floor_layout_node/plugin.cfg")
[file_customization]

View File

@@ -1,12 +0,0 @@
using Godot;
namespace Zennysoft.Game.Ma;
public partial class EnemyDatabase : Node
{
[Export]
public PackedScene[] EnemyList;
[Export]
public float[] SpawnRate;
}

View File

@@ -0,0 +1,21 @@
namespace Zennysoft.Game.Ma;
public enum EnemyType
{
Sproingy,
Michael,
FilthEater,
Sara,
Ballos,
Chariot,
Chinthe,
AmbassadorGreen,
AmbassadorRed,
AmbassadorSteel,
AgniDemon,
AqueousDemon,
EdenPillar,
Palan,
ShieldOfHeaven,
GoldSproingy
}

View File

@@ -0,0 +1 @@
uid://bwqjmol68w6pr

View File

@@ -0,0 +1,56 @@
using Godot;
using System;
namespace Zennysoft.Game.Ma;
public static class EnemyTypeToEnemyConverter
{
private static readonly string _folderPath = "res://src/enemy/enemy_types";
public static Enemy Convert(EnemyType enemyType)
{
switch (enemyType)
{
case EnemyType.Sproingy:
return InstantiateFromPath(@$"{_folderPath}/01. sproingy/Sproingy.tscn");
case EnemyType.Michael:
return InstantiateFromPath(@$"{_folderPath}/02. michael/Michael.tscn");
case EnemyType.FilthEater:
return InstantiateFromPath(@$"{_folderPath}/03. filth_eater/FilthEater.tscn");
case EnemyType.Sara:
return InstantiateFromPath(@$"{_folderPath}/04. sara/Sara.tscn");
case EnemyType.Ballos:
return InstantiateFromPath(@$"{_folderPath}/05. ballos/Ballos.tscn");
case EnemyType.Chariot:
return InstantiateFromPath(@$"{_folderPath}/06. chariot/Chariot.tscn");
case EnemyType.Chinthe:
return InstantiateFromPath(@$"{_folderPath}/07. chinthe/Chinthe.tscn");
case EnemyType.AmbassadorGreen:
return InstantiateFromPath(@$"{_folderPath}/08a. Ambassador/Ambassador.tscn");
case EnemyType.AmbassadorRed:
return InstantiateFromPath(@$"{_folderPath}/08b. Ambassador (red)/AmbassadorRed.tscn");
case EnemyType.AmbassadorSteel:
return InstantiateFromPath(@$"{_folderPath}/08c. Ambassador (steel)/AmbassadorSteel.tscn");
case EnemyType.AgniDemon:
return InstantiateFromPath(@$"{_folderPath}/09. Agni/AgniDemon.tscn");
case EnemyType.AqueousDemon:
return InstantiateFromPath(@$"{_folderPath}/9b. Aqueos Demon/AqueosDemon.tscn");
case EnemyType.EdenPillar:
return InstantiateFromPath(@$"{_folderPath}/10. Eden Pillar/Eden Pillar.tscn");
case EnemyType.Palan:
return InstantiateFromPath(@$"{_folderPath}/11. Palan/Palan.tscn");
case EnemyType.ShieldOfHeaven:
return InstantiateFromPath(@$"{_folderPath}/12. Shield of Heaven/ShieldModelView.tscn");
case EnemyType.GoldSproingy:
return InstantiateFromPath(@$"{_folderPath}/13. gold sproingy/GoldSproingy.tscn");
default:
throw new NotImplementedException("Not supported");
}
}
private static Enemy InstantiateFromPath(string scenePath)
{
var enemyScene = GD.Load<PackedScene>(scenePath);
return enemyScene.Instantiate<Enemy>();
}
}

View File

@@ -0,0 +1 @@
uid://ctspbxmdle4vt

View File

@@ -17,6 +17,8 @@ public partial class Game : Node3D, IGame
{
public override void _Notification(int what) => this.Notify(what);
IGame IProvide<IGame>.Value() => this;
IGameRepo IProvide<IGameRepo>.Value() => GameRepo;
IPlayer IProvide<IPlayer>.Value() => _player;
@@ -97,7 +99,6 @@ public partial class Game : Node3D, IGame
},
MapData = new MapData()
{
FloorScenes = []
},
RescuedItems = new RescuedItemDatabase()
{

View File

@@ -8,7 +8,7 @@ using Godot;
using System.Threading.Tasks;
using Zennysoft.Ma.Adapter;
public interface IGame : IProvide<IGameRepo>, IProvide<IPlayer>, IProvide<IMap>, IProvide<ISaveChunk<GameData>>, INode3D
public interface IGame : IProvide<IGame>, IProvide<IGameRepo>, IProvide<IPlayer>, IProvide<IMap>, IProvide<ISaveChunk<GameData>>, INode3D
{
void LoadExistingGame();

View File

@@ -15,8 +15,6 @@ public interface IMap : INode3D, IProvide<ISaveChunk<MapInfo>>
Task LoadFloor(string sceneName);
ImmutableDictionary<Floor, string> FloorScenes { get; }
IDungeonFloor CurrentFloor { get; }
Transform3D GetPlayerSpawnPosition();

View File

@@ -0,0 +1,49 @@
using Godot;
using System;
using System.Linq;
using static SpecialFloorLayout;
namespace Zennysoft.Game.Ma;
public static class LayoutToScenePathConverter
{
private static readonly string _folderPath = "res://src/map/dungeon/floors";
public static string Convert(LayoutType layoutType)
{
if (layoutType is SpecialFloorLayout specialFloor)
{
var path = $"{_folderPath}/Special Floors/";
var files = DirAccess.GetFilesAt(path);
switch (specialFloor.FloorName)
{
case SpecialFloorType.Overworld:
return path + files.Single(x => x.Contains("Overworld.tscn"));
case SpecialFloorType.Altar:
return path + files.Single(x => x.Contains("Altar.tscn"));
case SpecialFloorType.BossFloorA:
return path + files.Single(x => x.Contains("Boss Floor A.tscn"));
case SpecialFloorType.BossFloorB:
return path + files.Single(x => x.Contains("Boss Floor B.tscn"));
case SpecialFloorType.GoddessOfGuidanceFloor:
return path + files.Single(x => x.Contains("Goddess of Guidance's Room.tscn"));
case SpecialFloorType.TrueGoddessOfGuidanceFloor:
return path + files.Single(x => x.Contains("Goddess of Guidance's Room - True Form.tscn"));
case SpecialFloorType.FinalFloor:
return path + files.Single(x => x.Contains("Final Floor.tscn"));
default:
throw new NotImplementedException();
}
}
else if (layoutType is DungeonFloorLayout dungeonFloor)
{
var rng = new RandomNumberGenerator();
rng.Randomize();
var index = (int)rng.RandWeighted([.. dungeonFloor.LayoutWithSpawnRate.Values]);
var result = dungeonFloor.LayoutWithSpawnRate.ElementAt(index);
return _folderPath + "/" + result.Key;
}
throw new NotImplementedException();
}
}

View File

@@ -0,0 +1 @@
uid://d0yn4yu7264c8

View File

@@ -0,0 +1,7 @@
using Godot;
namespace Zennysoft.Game.Ma;
public abstract partial class LayoutType : Node
{
}

View File

@@ -0,0 +1 @@
uid://csb6g5a657010

View File

@@ -36,9 +36,7 @@ public partial class Map : Node3D, IMap
#endregion
[Export]
private Array<Floor> Floors { get; set; } = default!;
public ImmutableDictionary<Floor, string> FloorScenes { get; private set; }
private Array<LayoutType> Floors { get; set; } = default!;
public IDungeonFloor CurrentFloor { get; private set; }
@@ -57,14 +55,6 @@ public partial class Map : Node3D, IMap
public void InitializeMapData()
{
FloorScenes = ImmutableDictionary<Floor, string>.Empty
.Add(Floor.Overworld, _floorFilePath + "Special Floors/Overworld.tscn")
.Add(Floor.Altar, _floorFilePath + "Special Floors/Altar.tscn")
.Add(Floor.BossFloorA, _floorFilePath + "Special Floors/15. Boss Floor A.tscn")
.Add(Floor.BossFloorB, _floorFilePath + "Special Floors/34. Boss Floor B.tscn")
.Add(Floor.GoddessOfGuidanceFloor, _floorFilePath + "Special Floors/35. Goddess of Guidance's Room.tscn")
.Add(Floor.VoidRoom, _floorFilePath + "Set B/30. Void Room.tscn")
.Add(Floor.FinalFloor, _floorFilePath + "Special Floors/36. Final Floor.tscn");
CurrentFloorNumber.OnNext(0);
}
@@ -79,9 +69,11 @@ public partial class Map : Node3D, IMap
public async Task LoadFloor()
{
GetMapFiles();
FloorScenes.TryGetValue(Floors.First(), out var sceneToLoad);
var floor = GetChildren().OfType<LayoutType>().ElementAt(CurrentFloorNumber.Value);
var sceneToLoad = LayoutToScenePathConverter.Convert(floor);
await LoadFloor(sceneToLoad);
if (CurrentFloor is DungeonFloor dungeonFloor && floor is DungeonFloorLayout dungeonFloorLayout)
dungeonFloor.SpawnEnemies(dungeonFloorLayout.EnemySpawnRates);
}
public async Task LoadFloor(string sceneName)
@@ -125,10 +117,4 @@ public partial class Map : Node3D, IMap
var transform = GetPlayerSpawnPosition();
Player.TeleportPlayer(transform);
}
private string[] GetMapFiles()
{
var folderLocation = _floorFilePath + "Floor" + CurrentFloorNumber.Value.ToString("D2");
return DirAccess.GetFilesAt(folderLocation);
}
}

View File

@@ -1,6 +1,8 @@
[gd_scene load_steps=6 format=3 uid="uid://by67pn7fdsg1m"]
[gd_scene load_steps=8 format=3 uid="uid://by67pn7fdsg1m"]
[ext_resource type="Script" uid="uid://14e8mu48ed4" path="res://src/map/Map.cs" id="1_bw70o"]
[ext_resource type="Script" uid="uid://cabvj6s31iucg" path="res://addons/special_floor_layout_node/SpecialFloorLayout.cs" id="2_00xd7"]
[ext_resource type="Script" uid="uid://ci7o3nn4mdo8o" path="res://addons/dungeon_floor_layout/DungeonFloorLayout.cs" id="3_v14r0"]
[sub_resource type="Animation" id="Animation_00xd7"]
length = 0.001
@@ -54,9 +56,9 @@ _data = {
&"fade_out": SubResource("Animation_v14r0")
}
[node name="Map" type="Node3D"]
[node name="Map" type="Node3D" node_paths=PackedStringArray("Floors")]
script = ExtResource("1_bw70o")
Floors = Array[int]([3, 2, 0, 4, 1, 5, 6])
Floors = [3, 2, 0, 4, 1, 5, 6]
[node name="ColorRect" type="ColorRect" parent="."]
anchors_preset = 15
@@ -71,3 +73,28 @@ unique_name_in_owner = true
libraries = {
&"": SubResource("AnimationLibrary_00xd7")
}
[node name="Overworld (Add SpecialFloorLayout node for special floors and pick the FloorName from the list)" type="Node" parent="."]
script = ExtResource("2_00xd7")
metadata/_custom_type_script = "uid://cabvj6s31iucg"
[node name="Altar (Arrange order of nodes to change default load order)" type="Node" parent="."]
script = ExtResource("2_00xd7")
FloorName = 1
metadata/_custom_type_script = "uid://cabvj6s31iucg"
[node name="Floor01 (Press Populate Map Data Button to load floor from SetAFloors folder)" type="Node" parent="."]
script = ExtResource("3_v14r0")
LayoutWithSpawnRate = Dictionary[String, float]({})
EnemySpawnRates = {
0: 1.0
}
metadata/_custom_type_script = "uid://ci7o3nn4mdo8o"
[node name="Floor02 (Add DungeonFloorLayout node for regular dungeon floors)" type="Node" parent="."]
script = ExtResource("3_v14r0")
LayoutWithSpawnRate = Dictionary[String, float]({})
EnemySpawnRates = {
0: 1.0
}
metadata/_custom_type_script = "uid://ci7o3nn4mdo8o"

View File

@@ -12,8 +12,6 @@ public partial class DungeonFloor : Node3D, IDungeonFloor
{
public override void _Notification(int what) => this.Notify(what);
[Node] public EnemyDatabase EnemyDatabase { get; set; } = default!;
private Transform3D _playerSpawnPoint;
public ImmutableList<IDungeonRoom> Rooms { get; private set; }
@@ -25,12 +23,16 @@ public partial class DungeonFloor : Node3D, IDungeonFloor
Rooms = [];
Rooms = FindAllDungeonRooms([.. GetChildren()], Rooms);
_playerSpawnPoint = RandomizePlayerSpawnPoint();
var monsterRooms = Rooms.OfType<MonsterRoom>();
foreach (var room in monsterRooms)
room.SpawnEnemies(EnemyDatabase);
}
public Transform3D GetPlayerSpawnPoint() => new Transform3D(_playerSpawnPoint.Basis, new Vector3(_playerSpawnPoint.Origin.X, -1.75f, _playerSpawnPoint.Origin.Z));
public void SpawnEnemies(Godot.Collections.Dictionary<EnemyType, float> enemyInfo)
{
var monsterRooms = Rooms.OfType<MonsterRoom>();
foreach (var room in monsterRooms)
room.SpawnEnemies(enemyInfo);
}
public Transform3D GetPlayerSpawnPoint() => new Transform3D(_playerSpawnPoint.Basis, new Vector3(_playerSpawnPoint.Origin.X, 0f, _playerSpawnPoint.Origin.Z));
private Transform3D RandomizePlayerSpawnPoint()
{

View File

@@ -11,8 +11,6 @@ public abstract partial class DungeonRoom : Node3D, IDungeonRoom
{
public override void _Notification(int what) => this.Notify(what);
[Node] public Marker3D PlayerSpawn { get; set; } = default!;
[Node] private MeshInstance3D _minimap { get; set; } = default!;
public bool IsPlayerInRoom => _isPlayerInRoom;
@@ -30,8 +28,8 @@ public abstract partial class DungeonRoom : Node3D, IDungeonRoom
public void Setup()
{
_enemiesInRoom = [];
_room.BodyEntered += Room_BodyEntered;
_room.BodyExited += Room_BodyExited;
//_room.BodyEntered += Room_BodyEntered;
//_room.BodyExited += Room_BodyExited;
}
private void Room_BodyExited(Node3D body)

View File

@@ -14,6 +14,8 @@ public partial class ExitRoom : DungeonRoom
[Node] private Area3D _exit { get; set; } = default!;
[Node] public Marker3D PlayerSpawn { get; set; } = default!;
public override void _Ready()
{
_exit.AreaEntered += Exit_AreaEntered;

View File

@@ -5,8 +5,6 @@ using System.Collections.Immutable;
namespace Zennysoft.Game.Ma;
public interface IDungeonRoom : INode3D
{
Marker3D PlayerSpawn { get; }
bool IsPlayerInRoom { get; }
bool PlayerDiscoveredRoom { get; }

View File

@@ -15,6 +15,8 @@ public partial class MonsterRoom : DungeonRoom
[Node] public Node3D EnemySpawnPoints { get; set; } = default!;
[Node] public Marker3D PlayerSpawn { get; set; } = default!;
[Node] public ItemDatabase ItemDatabase { get; set; } = default!;
public override void _Ready()
@@ -22,7 +24,7 @@ public partial class MonsterRoom : DungeonRoom
SpawnItems();
}
public void SpawnEnemies(EnemyDatabase enemyDatabase)
public void SpawnEnemies(Godot.Collections.Dictionary<EnemyType, float> enemyInfo)
{
var rng = new RandomNumberGenerator();
rng.Randomize();
@@ -35,15 +37,19 @@ public partial class MonsterRoom : DungeonRoom
break;
numberOfEnemiesToSpawn--;
var enemy = enemyDatabase.EnemyList[rng.RandWeighted(enemyDatabase.SpawnRate)];
var instantiatedEnemy = enemy.Instantiate<Enemy>();
instantiatedEnemy.Position = new Vector3(spawnPoint.Position.X, 0, spawnPoint.Position.Z);
var index = rng.RandWeighted([.. enemyInfo.Values]);
var selectedEnemy = enemyInfo.ElementAt((int)index);
var instantiatedEnemy = EnemyTypeToEnemyConverter.Convert(selectedEnemy.Key);
instantiatedEnemy.Position = new Vector3(spawnPoint.Position.X, 1.75f, spawnPoint.Position.Z);
AddChild(instantiatedEnemy);
}
}
private void SpawnItems()
{
if (ItemSpawnPoints == null)
return;
var itemSpawnPoints = ItemSpawnPoints.GetChildren();
var rng = new RandomNumberGenerator();
rng.Randomize();

View File

@@ -1,8 +0,0 @@
[gd_resource type="Resource" script_class="MapInfo" load_steps=2 format=3 uid="uid://c0764jocyuon4"]
[ext_resource type="Script" uid="uid://bb4a0ijn0q2ou" path="res://src/map/MapInfo.cs" id="1_hrh8w"]
[resource]
script = ExtResource("1_hrh8w")
MapNameAndOdds = Dictionary[String, float]({})
metadata/_custom_type_script = "uid://bb4a0ijn0q2ou"

View File

@@ -1,10 +1,9 @@
[gd_scene load_steps=16 format=3 uid="uid://dpec2lbt83dhe"]
[gd_scene load_steps=15 format=3 uid="uid://dpec2lbt83dhe"]
[ext_resource type="Script" uid="uid://dhollu4j3pynq" path="res://src/map/dungeon/code/MonsterRoom.cs" id="1_312b8"]
[ext_resource type="PackedScene" uid="uid://bvpwkx6ag1yf4" path="res://src/map/dungeon/models/Area 1/Antechamber/A1-Antechamber.glb" id="2_kycn2"]
[ext_resource type="Texture2D" uid="uid://ncu0fsnqyede" path="res://src/minimap/textures/Room Maps/mi_antechamber.png" id="6_0ndak"]
[ext_resource type="PackedScene" uid="uid://twrj4wixcbu7" path="res://src/items/ItemDatabase.tscn" id="17_25wvm"]
[ext_resource type="Texture2D" uid="uid://bkvegamuqdsdd" path="res://src/map/dungeon/corridors/Corridor A/CORRIDOR test_FLOOR1.jpg" id="17_jig7d"]
[ext_resource type="Texture2D" uid="uid://del2dfj3etokd" path="res://src/map/assets/Blocked Door A1 .png" id="20_le1vp"]
[sub_resource type="BoxShape3D" id="BoxShape3D_phhs1"]
@@ -21,10 +20,8 @@ albedo_texture = ExtResource("20_le1vp")
texture_filter = 0
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_b605t"]
albedo_texture = ExtResource("17_jig7d")
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cnaww"]
albedo_texture = ExtResource("17_jig7d")
[sub_resource type="BoxShape3D" id="BoxShape3D_e81mq"]
size = Vector3(20, 8, 16)
@@ -169,7 +166,8 @@ shape = SubResource("BoxShape3D_e81mq")
[node name="Minimap" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.61193, 0.859072, 0)
[node name="mi_antechamber" type="MeshInstance3D" parent="Minimap"]
[node name="Minimap" type="MeshInstance3D" parent="Minimap"]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.983959, 0)
layers = 2
mesh = SubResource("PlaneMesh_7ppra")

View File

@@ -111,3 +111,8 @@ popup/item_13/text = "Shield of Heaven"
popup/item_13/id = 13
popup/item_14/text = "Gold Sproingy"
popup/item_14/id = 14
[node name="LoadNextFloorButton" type="Button" parent="MarginContainer/VBoxContainer/HBoxContainer/VFlowContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "Load Next Floor"

View File

@@ -23,6 +23,8 @@ public partial class PauseDebugMenu : Control, IDebugMenu
[Node] public OptionButton SpawnEnemyDropDown { get; set; } = default!;
[Node] public Button LoadNextFloorButton { get; set; } = default!;
private readonly string _floorFilePath = @"res://src/map/dungeon/floors/";
private readonly string _enemyFilePath = @"res://src/enemy/enemy_types";
@@ -33,6 +35,8 @@ public partial class PauseDebugMenu : Control, IDebugMenu
public override void _Ready()
{
LoadNextFloorButton.Pressed += LoadNextFloorButton_Pressed;
_itemDatabase = new ItemDatabase();
_spawnableItems = _itemDatabase.Items;