This commit is contained in:
Marek Le
2026-05-09 23:37:26 +02:00
parent 6d28b04c12
commit 2d4002bd3f
263 changed files with 5250 additions and 4597 deletions

View File

@@ -1,266 +1,133 @@
[gd_scene format=3]
[gd_scene load_steps=23 format=3 uid="uid://b0dungeon0001"]
[ext_resource type="PackedScene" path="res://scenes/player/player.tscn" id="player"]
[ext_resource type="PackedScene" path="res://scenes/hud/hud.tscn" id="hud"]
[ext_resource type="PackedScene" path="res://scenes/enemy/enemy.tscn" id="enemy"]
[ext_resource type="Resource" path="res://scenes/enemy/boss_stats.tres" id="boss_stats"]
[ext_resource type="Script" path="res://systems/dungeon_system.gd" id="dungeon_system"]
[ext_resource type="Script" path="res://scenes/dungeon/dungeon_manager.gd" id="dungeon_manager"]
[ext_resource type="Script" path="res://systems/audio_system.gd" id="audio_system"]
[ext_resource type="Script" path="res://systems/xp_system.gd" id="xp_system"]
[ext_resource type="PackedScene" path="res://scenes/portal/gate.tscn" id="gate"]
[ext_resource type="Script" path="res://systems/damage_system.gd" id="damage_system"]
[ext_resource type="Script" path="res://systems/health_system.gd" id="health_system"]
[ext_resource type="Script" path="res://systems/heal_system.gd" id="heal_system"]
[ext_resource type="Script" path="res://systems/shield_system.gd" id="shield_system"]
[ext_resource type="Script" path="res://systems/role_system.gd" id="role_system"]
[ext_resource type="Script" path="res://systems/ability_system.gd" id="ability_system"]
[ext_resource type="Script" path="res://systems/attack_system.gd" id="attack_system"]
[ext_resource type="Script" path="res://systems/cooldown_system.gd" id="cooldown_system"]
[ext_resource type="Script" path="res://systems/targeting_system.gd" id="targeting_system"]
[ext_resource type="Script" path="res://systems/aggro/aggro_system.gd" id="aggro_system"]
[ext_resource type="Script" path="res://systems/aggro/aggro_tracker.gd" id="aggro_tracker"]
[ext_resource type="Script" path="res://systems/aggro/aggro_decay.gd" id="aggro_decay"]
[ext_resource type="Script" path="res://systems/aggro/aggro_events.gd" id="aggro_events"]
[ext_resource type="Script" path="res://systems/ai_system.gd" id="ai_system"]
[ext_resource type="Script" path="res://systems/respawn_system.gd" id="respawn_system"]
[ext_resource type="Script" path="res://systems/spawn_system.gd" id="spawn_system"]
[ext_resource type="Script" path="res://systems/aura_system.gd" id="aura_system"]
[ext_resource type="Script" path="res://systems/buff_system.gd" id="buff_system"]
[ext_resource type="Script" path="res://systems/debuff_system.gd" id="debuff_system"]
[ext_resource type="Script" path="res://systems/element_system.gd" id="element_system"]
[ext_resource type="Script" path="res://systems/hud_system.gd" id="hud_system"]
[ext_resource type="Script" path="res://systems/nameplate_system.gd" id="nameplate_system"]
[ext_resource type="Resource" uid="uid://cgxtn7dfs40bh" path="res://scenes/player/role/tank/set.tres" id="tank_set"]
[ext_resource type="Resource" uid="uid://beodknb6i1pm4" path="res://scenes/player/role/damage/set.tres" id="damage_set"]
[ext_resource type="Resource" uid="uid://kcwuhnqy34mj" path="res://scenes/player/role/healer/set.tres" id="healer_set"]
[ext_resource type="Script" path="res://scenes/dungeon/dungeon_manager.gd" id="1"]
[ext_resource type="PackedScene" uid="uid://b0player00001" path="res://scenes/entities/player/player.tscn" id="2"]
[ext_resource type="Script" path="res://systems/health_system.gd" id="4"]
[ext_resource type="Script" path="res://systems/shield_system.gd" id="5"]
[ext_resource type="Script" path="res://systems/respawn_system.gd" id="6"]
[ext_resource type="Script" path="res://systems/cooldown_system.gd" id="7"]
[ext_resource type="Script" path="res://systems/role_system.gd" id="8"]
[ext_resource type="Script" path="res://systems/effect_system.gd" id="9"]
[ext_resource type="Script" path="res://systems/element_system.gd" id="10"]
[ext_resource type="Script" path="res://systems/aggro_system.gd" id="11"]
[ext_resource type="Script" path="res://systems/combat/ability_system.gd" id="12"]
[ext_resource type="Script" path="res://systems/combat/auto_attack_system.gd" id="13"]
[ext_resource type="Script" path="res://systems/spawn_system.gd" id="14"]
[ext_resource type="Script" path="res://systems/xp_system.gd" id="17"]
[ext_resource type="Script" path="res://systems/loot_system.gd" id="18"]
[ext_resource type="Script" path="res://systems/inventory_system.gd" id="19"]
[ext_resource type="Script" path="res://systems/chat_system.gd" id="24"]
[ext_resource type="Script" path="res://systems/map_system.gd" id="25"]
[ext_resource type="PackedScene" uid="uid://b0hud00001" path="res://scenes/hud/hud.tscn" id="26"]
[ext_resource type="Script" path="res://systems/audio_system.gd" id="27"]
[sub_resource type="NavigationMesh" id="NavigationMesh_1"]
vertices = PackedVector3Array(-7.0, 0.5, -7.0, -7.0, 0.5, 87.0, 7.0, 0.5, 87.0, 7.0, 0.5, -7.0)
polygons = [PackedInt32Array(3, 2, 0), PackedInt32Array(0, 2, 1)]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_1"]
sky_top_color = Color(0.1, 0.05, 0.1, 1)
sky_horizon_color = Color(0.15, 0.05, 0.05, 1)
ground_horizon_color = Color(0.1, 0.05, 0.05, 1)
ground_bottom_color = Color(0.0, 0.0, 0.0, 1)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_floor"]
albedo_color = Color(0.2, 0.18, 0.15, 1)
[sub_resource type="Sky" id="Sky_1"]
sky_material = SubResource("ProceduralSkyMaterial_1")
[sub_resource type="PlaneMesh" id="PlaneMesh_1"]
material = SubResource("StandardMaterial3D_floor")
size = Vector2(15, 90)
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_1"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_wall"]
albedo_color = Color(0.25, 0.22, 0.2, 1)
[sub_resource type="BoxMesh" id="BoxMesh_north_south"]
material = SubResource("StandardMaterial3D_wall")
size = Vector3(15, 3, 0.5)
[sub_resource type="BoxShape3D" id="BoxShape3D_north_south"]
size = Vector3(15, 3, 0.5)
[sub_resource type="BoxMesh" id="BoxMesh_east_west"]
material = SubResource("StandardMaterial3D_wall")
size = Vector3(0.5, 3, 90)
[sub_resource type="BoxShape3D" id="BoxShape3D_east_west"]
size = Vector3(0.5, 3, 90)
[sub_resource type="Environment" id="Environment_1"]
background_mode = 2
sky = SubResource("Sky_1")
ambient_light_source = 3
ambient_light_color = Color(0.2, 0.18, 0.2, 1)
ambient_light_energy = 0.4
[node name="Dungeon" type="Node3D"]
script = ExtResource("1")
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_1")
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(0.866, -0.354, 0.354, 0, 0.707, 0.707, -0.5, -0.612, 0.612, 0, 30, 0)
light_energy = 0.7
[node name="DungeonGeometry" type="Node3D" parent="."]
[node name="Systems" type="Node" parent="."]
[node name="HealthSystem" type="Node" parent="Systems"]
script = ExtResource("health_system")
[node name="DamageSystem" type="Node" parent="Systems"]
script = ExtResource("damage_system")
[node name="HealSystem" type="Node" parent="Systems"]
script = ExtResource("heal_system")
script = ExtResource("4")
[node name="ShieldSystem" type="Node" parent="Systems"]
script = ExtResource("shield_system")
[node name="RoleSystem" type="Node" parent="Systems"]
script = ExtResource("role_system")
tank_set = ExtResource("tank_set")
damage_set = ExtResource("damage_set")
healer_set = ExtResource("healer_set")
[node name="AbilitySystem" type="Node" parent="Systems"]
script = ExtResource("ability_system")
[node name="AttackSystem" type="Node" parent="Systems"]
script = ExtResource("attack_system")
[node name="CooldownSystem" type="Node" parent="Systems"]
script = ExtResource("cooldown_system")
[node name="TargetingSystem" type="Node" parent="Systems"]
script = ExtResource("targeting_system")
[node name="AggroSystem" type="Node" parent="Systems"]
script = ExtResource("aggro_system")
[node name="AggroTracker" type="Node" parent="Systems/AggroSystem"]
script = ExtResource("aggro_tracker")
[node name="AggroDecay" type="Node" parent="Systems/AggroSystem"]
script = ExtResource("aggro_decay")
[node name="AggroEvents" type="Node" parent="Systems/AggroSystem"]
script = ExtResource("aggro_events")
[node name="AISystem" type="Node" parent="Systems"]
script = ExtResource("ai_system")
script = ExtResource("5")
[node name="RespawnSystem" type="Node" parent="Systems"]
script = ExtResource("respawn_system")
script = ExtResource("6")
[node name="SpawnSystem" type="Node" parent="Systems"]
script = ExtResource("spawn_system")
[node name="CooldownSystem" type="Node" parent="Systems"]
script = ExtResource("7")
[node name="AuraSystem" type="Node" parent="Systems"]
script = ExtResource("aura_system")
[node name="RoleSystem" type="Node" parent="Systems"]
script = ExtResource("8")
[node name="BuffSystem" type="Node" parent="Systems"]
script = ExtResource("buff_system")
[node name="DebuffSystem" type="Node" parent="Systems"]
script = ExtResource("debuff_system")
[node name="EffectSystem" type="Node" parent="Systems"]
script = ExtResource("9")
[node name="ElementSystem" type="Node" parent="Systems"]
script = ExtResource("element_system")
script = ExtResource("10")
[node name="HudSystem" type="Node" parent="Systems"]
script = ExtResource("hud_system")
[node name="AggroSystem" type="Node" parent="Systems"]
script = ExtResource("11")
[node name="NameplateSystem" type="Node" parent="Systems"]
script = ExtResource("nameplate_system")
[node name="AbilitySystem" type="Node" parent="Systems"]
script = ExtResource("12")
[node name="NavigationRegion3D" type="NavigationRegion3D" parent="."]
navigation_mesh = SubResource("NavigationMesh_1")
[node name="AutoAttackSystem" type="Node" parent="Systems"]
script = ExtResource("13")
[node name="Boden" type="MeshInstance3D" parent="NavigationRegion3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 40)
mesh = SubResource("PlaneMesh_1")
[node name="SpawnSystem" type="Node" parent="Systems"]
script = ExtResource("14")
[node name="BodenCollision" type="StaticBody3D" parent="."]
[node name="CollisionShape3D" type="CollisionShape3D" parent="BodenCollision"]
shape = SubResource("WorldBoundaryShape3D_1")
[node name="WallSouth" type="StaticBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, -5.25)
[node name="Mesh" type="MeshInstance3D" parent="WallSouth"]
mesh = SubResource("BoxMesh_north_south")
[node name="CollisionShape3D" type="CollisionShape3D" parent="WallSouth"]
shape = SubResource("BoxShape3D_north_south")
[node name="WallNorth" type="StaticBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 85.25)
[node name="Mesh" type="MeshInstance3D" parent="WallNorth"]
mesh = SubResource("BoxMesh_north_south")
[node name="CollisionShape3D" type="CollisionShape3D" parent="WallNorth"]
shape = SubResource("BoxShape3D_north_south")
[node name="WallEast" type="StaticBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.75, 1.5, 40)
[node name="Mesh" type="MeshInstance3D" parent="WallEast"]
mesh = SubResource("BoxMesh_east_west")
[node name="CollisionShape3D" type="CollisionShape3D" parent="WallEast"]
shape = SubResource("BoxShape3D_east_west")
[node name="WallWest" type="StaticBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.75, 1.5, 40)
[node name="Mesh" type="MeshInstance3D" parent="WallWest"]
mesh = SubResource("BoxMesh_east_west")
[node name="CollisionShape3D" type="CollisionShape3D" parent="WallWest"]
shape = SubResource("BoxShape3D_east_west")
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.707, 0.707, 0, -0.707, 0.707, 0, 10, 40)
light_energy = 0.6
shadow_enabled = true
[node name="Player" parent="." instance=ExtResource("player")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -3)
[node name="HUD" parent="." instance=ExtResource("hud")]
[node name="Enemy1a" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0, 15)
[node name="Enemy1b" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 0, 15)
[node name="Enemy1c" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 15)
[node name="Enemy1d" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 0, 15)
[node name="Enemy2a" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0, 30)
[node name="Enemy2b" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 0, 30)
[node name="Enemy2c" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 30)
[node name="Enemy2d" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 0, 30)
[node name="Enemy3a" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0, 45)
[node name="Enemy3b" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 0, 45)
[node name="Enemy3c" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 45)
[node name="Enemy3d" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 0, 45)
[node name="Enemy4a" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0, 60)
[node name="Enemy4b" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 0, 60)
[node name="Enemy4c" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 60)
[node name="Enemy4d" parent="." instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 0, 60)
[node name="Boss" parent="." groups=["boss"] instance=ExtResource("enemy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 75)
stats = ExtResource("boss_stats")
[node name="ExitGate" parent="." instance=ExtResource("gate")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6, 0, -4)
target_scene = "res://scenes/world/world.tscn"
is_exit = true
[node name="DungeonSystem" type="Node" parent="Systems"]
script = ExtResource("dungeon_system")
[node name="AudioSystem" type="Node" parent="Systems"]
script = ExtResource("audio_system")
[node name="LootSystem" type="Node" parent="Systems"]
script = ExtResource("18")
[node name="XpSystem" type="Node" parent="Systems"]
script = ExtResource("xp_system")
script = ExtResource("17")
[node name="DungeonManager" type="Node" parent="."]
script = ExtResource("dungeon_manager")
[node name="InventorySystem" type="Node" parent="Systems"]
script = ExtResource("19")
[node name="ChatSystem" type="Node" parent="Systems"]
script = ExtResource("24")
[node name="MapSystem" type="Node" parent="Systems"]
script = ExtResource("25")
[node name="AudioSystem" type="Node" parent="Systems"]
script = ExtResource("27")
[node name="EntityRoot" type="Node3D" parent="."]
[node name="Players" type="Node3D" parent="EntityRoot"]
[node name="Enemies" type="Node3D" parent="EntityRoot"]
[node name="Loot" type="Node3D" parent="EntityRoot"]
[node name="Portals" type="Node3D" parent="EntityRoot"]
[node name="Buildings" type="Node3D" parent="EntityRoot"]
[node name="Gates" type="Node3D" parent="EntityRoot"]
[node name="Npcs" type="Node3D" parent="EntityRoot"]
[node name="PlayerSpawner" type="MultiplayerSpawner" parent="."]
_spawnable_scenes = PackedStringArray("res://scenes/entities/player/player.tscn")
spawn_path = NodePath("../EntityRoot/Players")
[node name="EnemySpawner" type="MultiplayerSpawner" parent="."]
_spawnable_scenes = PackedStringArray("res://scenes/entities/enemy/enemy.tscn")
spawn_path = NodePath("../EntityRoot/Enemies")
[node name="LootSpawner" type="MultiplayerSpawner" parent="."]
_spawnable_scenes = PackedStringArray("res://scenes/entities/loot/loot_drop.tscn")
spawn_path = NodePath("../EntityRoot/Loot")
[node name="HUD" parent="." instance=ExtResource("26")]

View File

@@ -0,0 +1,93 @@
extends Node
const ROOM_HEIGHT: float = 4.0
const WALL_THICKNESS: float = 0.4
const CORRIDOR_WIDTH: float = 4.0
var rng: RandomNumberGenerator
var rooms: Array = []
func generate(parent: Node3D, seed: int, scale_difficulty: float = 1.0) -> Dictionary:
rng = RandomNumberGenerator.new()
rng.seed = seed
rooms.clear()
var room_count: int = rng.randi_range(5, 8)
var pos := Vector3(0, 0, 0)
var dir := Vector3(0, 0, -1)
for i in range(room_count):
var w: float = rng.randf_range(8.0, 14.0)
var d: float = rng.randf_range(8.0, 14.0)
rooms.append({"pos": pos, "size": Vector3(w, ROOM_HEIGHT, d)})
if i == room_count - 1:
break
var corridor_len: float = rng.randf_range(4.0, 8.0)
var step: Vector3 = dir * (max(w, d) * 0.5 + corridor_len + 4.0)
pos += step
if rng.randf() < 0.5:
var rotate_left: bool = rng.randf() < 0.5
dir = dir.rotated(Vector3.UP, PI * 0.5 * (1 if rotate_left else -1))
_build_geometry(parent)
return {"rooms": rooms, "spawn": rooms[0].pos + Vector3(0, 1, 0), "boss": rooms[-1].pos}
func _build_geometry(parent: Node3D) -> void:
for r in rooms:
_build_room(parent, r.pos, r.size)
for i in range(rooms.size() - 1):
_build_corridor(parent, rooms[i].pos, rooms[i + 1].pos)
func _build_room(parent: Node3D, center: Vector3, size: Vector3) -> void:
_add_floor(parent, center, Vector2(size.x, size.z))
var hw: float = size.x * 0.5
var hd: float = size.z * 0.5
_add_wall(parent, center + Vector3(0, ROOM_HEIGHT * 0.5, -hd), Vector3(size.x, ROOM_HEIGHT, WALL_THICKNESS))
_add_wall(parent, center + Vector3(0, ROOM_HEIGHT * 0.5, hd), Vector3(size.x, ROOM_HEIGHT, WALL_THICKNESS))
_add_wall(parent, center + Vector3(-hw, ROOM_HEIGHT * 0.5, 0), Vector3(WALL_THICKNESS, ROOM_HEIGHT, size.z))
_add_wall(parent, center + Vector3(hw, ROOM_HEIGHT * 0.5, 0), Vector3(WALL_THICKNESS, ROOM_HEIGHT, size.z))
func _build_corridor(parent: Node3D, from: Vector3, to: Vector3) -> void:
var mid: Vector3 = (from + to) * 0.5
var d: float = from.distance_to(to)
var dir: Vector3 = (to - from).normalized()
_add_floor(parent, Vector3(mid.x, 0, mid.z), Vector2(d, CORRIDOR_WIDTH) if abs(dir.x) > abs(dir.z) else Vector2(CORRIDOR_WIDTH, d))
func _add_floor(parent: Node3D, center: Vector3, size: Vector2) -> void:
var body := StaticBody3D.new()
body.collision_layer = 1
body.collision_mask = 0
var mesh := MeshInstance3D.new()
var box := BoxMesh.new()
box.size = Vector3(size.x, 0.4, size.y)
mesh.mesh = box
var mat := StandardMaterial3D.new()
mat.albedo_color = Color(0.25, 0.22, 0.2)
mesh.material_override = mat
mesh.position = Vector3(0, -0.2, 0)
var col := CollisionShape3D.new()
var shape := BoxShape3D.new()
shape.size = Vector3(size.x, 0.4, size.y)
col.shape = shape
col.position = Vector3(0, -0.2, 0)
body.add_child(mesh)
body.add_child(col)
body.position = center
parent.add_child(body)
func _add_wall(parent: Node3D, center: Vector3, size: Vector3) -> void:
var body := StaticBody3D.new()
body.collision_layer = 1
body.collision_mask = 0
var mesh := MeshInstance3D.new()
var box := BoxMesh.new()
box.size = size
mesh.mesh = box
var mat := StandardMaterial3D.new()
mat.albedo_color = Color(0.35, 0.32, 0.28)
mesh.material_override = mat
var col := CollisionShape3D.new()
var shape := BoxShape3D.new()
shape.size = size
col.shape = shape
body.add_child(mesh)
body.add_child(col)
body.position = center
parent.add_child(body)

View File

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

View File

@@ -1,16 +1,82 @@
extends Node
extends Node3D
const PLAYER_SCENE: PackedScene = preload("res://scenes/entities/player/player.tscn")
const ENEMY_SCENE: PackedScene = preload("res://scenes/entities/enemy/enemy.tscn")
const GENERATOR: GDScript = preload("res://scenes/dungeon/dungeon_generator.gd")
@onready var players_root: Node3D = $EntityRoot/Players
@onready var dungeon_root: Node3D = $DungeonGeometry
@onready var spawn_system: Node = $Systems/SpawnSystem
var generator: Node
var data: Dictionary
func _ready() -> void:
call_deferred("_scale_dungeon")
add_to_group("dungeon")
generator = GENERATOR.new()
add_child(generator)
data = generator.generate(dungeon_root, GameState.dungeon_seed, GameState.current_wave * (5.0 if GameState.dungeon_red else 1.0))
EventBus.boss_defeated.connect(_on_boss_defeated)
Net.world_ready.connect(_on_world_ready)
Net.peer_world_loaded.connect(_on_peer_world_loaded)
if Net.is_host():
multiplayer.peer_connected.connect(_on_peer_connected)
multiplayer.peer_disconnected.connect(_on_peer_disconnected)
Net.reset_world_ready()
Net.mark_world_loaded()
func _scale_dungeon() -> void:
var variant_multiplier: float = 10.0 if GameState.last_dungeon_variant == 1 else 1.0
var total_scale: float = PlayerData.level_scale * variant_multiplier
var parent: Node = get_parent()
for child in parent.get_children():
if not child.is_in_group("enemies"):
continue
if child.is_in_group("boss"):
BossData.apply_scale(child, total_scale)
else:
EnemyData.apply_scale(child, total_scale)
func _exit_tree() -> void:
if Net.world_ready.is_connected(_on_world_ready):
Net.world_ready.disconnect(_on_world_ready)
if Net.peer_world_loaded.is_connected(_on_peer_world_loaded):
Net.peer_world_loaded.disconnect(_on_peer_world_loaded)
func _on_world_ready() -> void:
if not Net.is_host():
return
_spawn_player(1)
for id in multiplayer.get_peers():
_spawn_player(id)
_populate_dungeon()
func _populate_dungeon() -> void:
var difficulty: float = GameState.current_wave * (3.0 if GameState.dungeon_red else 1.0)
for i in range(data.rooms.size() - 1):
var room: Dictionary = data.rooms[i]
var n: int = 2 + (1 if GameState.dungeon_red else 0)
for j in range(n):
var off := Vector3(randf_range(-room.size.x * 0.3, room.size.x * 0.3), 0.5, randf_range(-room.size.z * 0.3, room.size.z * 0.3))
spawn_system.spawn_enemy_at(room.pos + off, GameState.dungeon_red, difficulty * 0.5)
spawn_system.spawn_boss_at(data.boss + Vector3(0, 0.5, 0), difficulty)
func _spawn_player(peer_id: int) -> void:
if players_root.get_node_or_null(str(peer_id)) != null:
return
var p: CharacterBody3D = PLAYER_SCENE.instantiate()
p.name = str(peer_id)
players_root.add_child(p, true)
p.global_position = data.spawn + Vector3(randf_range(-1, 1), 0, randf_range(-1, 1))
func _on_peer_connected(id: int) -> void:
Net.tell_peer_to_load_scene(id, GameState.SCENE_DUNGEON)
func _on_peer_world_loaded(peer_id: int) -> void:
if not Net.is_host():
return
_spawn_player(peer_id)
func _on_peer_disconnected(id: int) -> void:
var node := players_root.get_node_or_null(str(id))
if node:
node.queue_free()
func _on_boss_defeated(_b: Node) -> void:
if Net.is_host():
var t := get_tree().create_timer(2.0)
t.timeout.connect(func():
GameState.dungeon_seed = 0
_return.rpc())
@rpc("authority", "reliable", "call_local")
func _return() -> void:
GameState.change_scene(GameState.SCENE_WORLD)

View File

@@ -1 +1 @@
uid://bfkxrflfn5qx4
uid://civwsilci7nlx