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

@@ -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,17 +14,19 @@ 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;
_exit.AreaEntered += Exit_AreaEntered;
}
public void ExitReached()
=> Game.FloorExitReached();
=> Game.FloorExitReached();
private void Exit_AreaEntered(Area3D area)
{
if (area.GetOwner() is IPlayer)
ExitReached();
if (area.GetOwner() is IPlayer)
ExitReached();
}
}

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,51 +15,57 @@ 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()
{
SpawnItems();
SpawnItems();
}
public void SpawnEnemies(EnemyDatabase enemyDatabase)
public void SpawnEnemies(Godot.Collections.Dictionary<EnemyType, float> enemyInfo)
{
var rng = new RandomNumberGenerator();
rng.Randomize();
var enemySpawnPoints = EnemySpawnPoints.GetChildren();
var numberOfEnemiesToSpawn = rng.RandiRange(1, enemySpawnPoints.Count);
var rng = new RandomNumberGenerator();
rng.Randomize();
var enemySpawnPoints = EnemySpawnPoints.GetChildren();
var numberOfEnemiesToSpawn = rng.RandiRange(1, enemySpawnPoints.Count);
foreach (var spawnPoint in enemySpawnPoints.Cast<Marker3D>())
{
if (numberOfEnemiesToSpawn <= 0)
break;
numberOfEnemiesToSpawn--;
foreach (var spawnPoint in enemySpawnPoints.Cast<Marker3D>())
{
if (numberOfEnemiesToSpawn <= 0)
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);
AddChild(instantiatedEnemy);
}
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()
{
var itemSpawnPoints = ItemSpawnPoints.GetChildren();
var rng = new RandomNumberGenerator();
rng.Randomize();
var numberOfItemsToSpawn = rng.RandiRange(1, itemSpawnPoints.Count);
itemSpawnPoints.Shuffle();
var database = new ItemDatabase();
foreach (var spawnPoint in itemSpawnPoints.Cast<Marker3D>())
{
if (numberOfItemsToSpawn <= 0)
break;
numberOfItemsToSpawn--;
if (ItemSpawnPoints == null)
return;
var selectedItem = database.PickItem<InventoryItem>();
var duplicated = selectedItem.Duplicate((int)DuplicateFlags.UseInstantiation) as Node3D;
duplicated.Position = new Vector3(spawnPoint.Position.X, -1.5f, spawnPoint.Position.Z);
AddChild(duplicated);
}
var itemSpawnPoints = ItemSpawnPoints.GetChildren();
var rng = new RandomNumberGenerator();
rng.Randomize();
var numberOfItemsToSpawn = rng.RandiRange(1, itemSpawnPoints.Count);
itemSpawnPoints.Shuffle();
var database = new ItemDatabase();
foreach (var spawnPoint in itemSpawnPoints.Cast<Marker3D>())
{
if (numberOfItemsToSpawn <= 0)
break;
numberOfItemsToSpawn--;
var selectedItem = database.PickItem<InventoryItem>();
var duplicated = selectedItem.Duplicate((int)DuplicateFlags.UseInstantiation) as Node3D;
duplicated.Position = new Vector3(spawnPoint.Position.X, -1.5f, spawnPoint.Position.Z);
AddChild(duplicated);
}
}
}

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")