fix alot of shit for webrtc to work

This commit is contained in:
2026-01-17 10:19:51 +01:00
parent f71b510cfc
commit eb718fa990
68 changed files with 6616 additions and 917 deletions

View File

@@ -96,7 +96,7 @@ func generate_dungeon(map_size: Vector2i, seed_value: int = 0, level: int = 1) -
# Calculate target room count based on level
# Level 1: 7-8 rooms, then increase by 2-3 rooms per level
var target_room_count = 7 + (level - 1) * 2 + rng.randi_range(0, 1) # Level 1: 7-8, Level 2: 9-10, etc.
print("DungeonGenerator: Level ", level, " - Target room count: ", target_room_count)
LogManager.log("DungeonGenerator: Level " + str(level) + " - Target room count: " + str(target_room_count), LogManager.CATEGORY_DUNGEON)
# Initialize grid (0 = wall, 1 = floor, 2 = door, 3 = corridor)
var grid = []
@@ -137,7 +137,7 @@ func generate_dungeon(map_size: Vector2i, seed_value: int = 0, level: int = 1) -
attempts -= 1
print("DungeonGenerator: Generated ", all_rooms.size(), " rooms (target was ", target_room_count, ")")
LogManager.log("DungeonGenerator: Generated " + str(all_rooms.size()) + " rooms (target was " + str(target_room_count) + ")", LogManager.CATEGORY_DUNGEON)
# 3. Connect rooms with corridors/doors
if all_rooms.size() > 1:
@@ -156,7 +156,7 @@ func generate_dungeon(map_size: Vector2i, seed_value: int = 0, level: int = 1) -
# 6. Mark exit room (farthest REACHABLE room from start)
# First find all reachable rooms from start
var reachable_rooms = _find_reachable_rooms(all_rooms[start_room_index], all_rooms, all_doors)
print("DungeonGenerator: Found ", reachable_rooms.size(), " reachable rooms from start (out of ", all_rooms.size(), " total)")
LogManager.log("DungeonGenerator: Found " + str(reachable_rooms.size()) + " reachable rooms from start (out of " + str(all_rooms.size()) + " total)", LogManager.CATEGORY_DUNGEON)
# CRITICAL: Remove inaccessible rooms (rooms not reachable from start)
# Store the start room before filtering (it should always be reachable)
@@ -179,13 +179,13 @@ func generate_dungeon(map_size: Vector2i, seed_value: int = 0, level: int = 1) -
filtered_rooms.append(room)
else:
inaccessible_count += 1
print("DungeonGenerator: Removing inaccessible room at (", room.x, ", ", room.y, ") - no corridor connection")
LogManager.log("DungeonGenerator: Removing inaccessible room at (" + str(room.x) + ", " + str(room.y) + ") - no corridor connection", LogManager.CATEGORY_DUNGEON)
# Update all_rooms to only include reachable rooms
all_rooms = filtered_rooms
if inaccessible_count > 0:
print("DungeonGenerator: Removed ", inaccessible_count, " inaccessible room(s). Remaining rooms: ", all_rooms.size())
LogManager.log("DungeonGenerator: Removed " + str(inaccessible_count) + " inaccessible room(s). Remaining rooms: " + str(all_rooms.size()), LogManager.CATEGORY_DUNGEON)
# Update start_room_index after filtering (find start room in new array using value-based comparison)
start_room_index = -1
@@ -197,7 +197,7 @@ func generate_dungeon(map_size: Vector2i, seed_value: int = 0, level: int = 1) -
break
if start_room_index == -1:
push_error("DungeonGenerator: ERROR - Start room was removed! This should never happen!")
LogManager.log_error("DungeonGenerator: ERROR - Start room was removed! This should never happen!", LogManager.CATEGORY_DUNGEON)
start_room_index = 0 # Fallback
# Also remove doors connected to inaccessible rooms (clean up all_doors)
@@ -229,23 +229,23 @@ func generate_dungeon(map_size: Vector2i, seed_value: int = 0, level: int = 1) -
filtered_doors.append(door)
else:
doors_removed += 1
print("DungeonGenerator: Removing door - room1 reachable: ", door_room1_reachable, ", room2 reachable: ", door_room2_reachable)
LogManager.log("DungeonGenerator: Removing door - room1 reachable: " + str(door_room1_reachable) + ", room2 reachable: " + str(door_room2_reachable), LogManager.CATEGORY_DUNGEON)
all_doors = filtered_doors
if doors_removed > 0:
print("DungeonGenerator: Removed ", doors_removed, " door(s) connected to inaccessible rooms. Remaining doors: ", all_doors.size())
LogManager.log("DungeonGenerator: Removed " + str(doors_removed) + " door(s) connected to inaccessible rooms. Remaining doors: " + str(all_doors.size()), LogManager.CATEGORY_DUNGEON)
# Find the farthest reachable room (now all rooms are reachable, but find farthest)
# Make sure we have at least 2 rooms (start and exit must be different)
# exit_room_index is already declared at function level
if all_rooms.size() < 2:
push_error("DungeonGenerator: ERROR - Not enough reachable rooms! Need at least 2 (start + exit), but only have ", all_rooms.size())
LogManager.log_error("DungeonGenerator: ERROR - Not enough reachable rooms! Need at least 2 (start + exit), but only have " + str(all_rooms.size()), LogManager.CATEGORY_DUNGEON)
# Use start room as exit if only one room exists (shouldn't happen, but handle gracefully)
if all_rooms.size() == 1:
exit_room_index = 0
else:
# No rooms at all - this is a critical error
push_error("DungeonGenerator: CRITICAL ERROR - No rooms left after filtering!")
LogManager.log_error("DungeonGenerator: CRITICAL ERROR - No rooms left after filtering!", LogManager.CATEGORY_DUNGEON)
return {} # Return empty dungeon
else:
exit_room_index = _find_farthest_room(all_rooms, start_room_index)
@@ -266,7 +266,7 @@ func generate_dungeon(map_size: Vector2i, seed_value: int = 0, level: int = 1) -
exit_room_index = second_farthest
all_rooms[exit_room_index].modifiers.append({"type": "EXIT"})
print("DungeonGenerator: Selected exit room at index ", exit_room_index, " position: ", all_rooms[exit_room_index].x, ",", all_rooms[exit_room_index].y)
LogManager.log("DungeonGenerator: Selected exit room at index " + str(exit_room_index) + " position: " + str(all_rooms[exit_room_index].x) + "," + str(all_rooms[exit_room_index].y), LogManager.CATEGORY_DUNGEON)
# 7. Render walls around rooms
_render_room_walls(all_rooms, grid, tile_grid, map_size, rng)
@@ -274,12 +274,12 @@ func generate_dungeon(map_size: Vector2i, seed_value: int = 0, level: int = 1) -
# 7.5. Place stairs in exit room BEFORE placing torches (so torches don't overlap stairs)
var stairs_data = _place_stairs_in_exit_room(all_rooms[exit_room_index], grid, tile_grid, map_size, all_doors, rng)
if stairs_data.is_empty():
print("DungeonGenerator: ERROR - Failed to place stairs in exit room! Room size: ", all_rooms[exit_room_index].w, "x", all_rooms[exit_room_index].h, " Doors: ", all_doors.size())
LogManager.log_error("DungeonGenerator: ERROR - Failed to place stairs in exit room! Room size: " + str(all_rooms[exit_room_index].w) + "x" + str(all_rooms[exit_room_index].h) + " Doors: " + str(all_doors.size()), LogManager.CATEGORY_DUNGEON)
# CRITICAL: Force place stairs - we MUST have an exit!
print("DungeonGenerator: FORCING stairs placement in exit room center")
LogManager.log("DungeonGenerator: FORCING stairs placement in exit room center", LogManager.CATEGORY_DUNGEON)
stairs_data = _force_place_stairs(all_rooms[exit_room_index], grid, tile_grid, map_size, all_doors, rng)
if stairs_data.is_empty():
push_error("DungeonGenerator: CRITICAL ERROR - Could not place stairs even with force placement!")
LogManager.log_error("DungeonGenerator: CRITICAL ERROR - Could not place stairs even with force placement!", LogManager.CATEGORY_DUNGEON)
# 8. Place torches in rooms (AFTER stairs, so torches don't overlap stairs)
var all_torches = []
@@ -309,7 +309,7 @@ func generate_dungeon(map_size: Vector2i, seed_value: int = 0, level: int = 1) -
break
if not already_in_list:
rooms_with_spawner_puzzles.append(puzzle_room)
print("DungeonGenerator: Room (", puzzle_room.x, ", ", puzzle_room.y, ") has monster spawner puzzle - will skip pre-spawning enemies")
LogManager.log("DungeonGenerator: Room (" + str(puzzle_room.x) + ", " + str(puzzle_room.y) + ") has monster spawner puzzle - will skip pre-spawning enemies", LogManager.CATEGORY_DUNGEON)
# 9. Place enemies in rooms (scaled by level, excluding start and exit rooms, and rooms with spawner puzzles)
var all_enemies = []
@@ -323,7 +323,7 @@ func generate_dungeon(map_size: Vector2i, seed_value: int = 0, level: int = 1) -
if spawner_room.x == room.x and spawner_room.y == room.y and \
spawner_room.w == room.w and spawner_room.h == room.h:
has_spawner_puzzle = true
print("DungeonGenerator: Skipping pre-spawned enemies for room (", room.x, ", ", room.y, ") - has monster spawner puzzle")
LogManager.log("DungeonGenerator: Skipping pre-spawned enemies for room (" + str(room.x) + ", " + str(room.y) + ") - has monster spawner puzzle", LogManager.CATEGORY_DUNGEON)
break
if not has_spawner_puzzle:
@@ -1317,7 +1317,7 @@ func _place_stairs_in_exit_room(exit_room: Dictionary, grid: Array, tile_grid: A
# Choose a random wall to place stairs on (excluding corners)
# Make sure stairs don't overlap any doors
# Returns stairs data with position and size for Area2D creation
print("DungeonGenerator: Placing stairs in exit room: ", exit_room.x, ",", exit_room.y, " size: ", exit_room.w, "x", exit_room.h, " doors: ", all_doors.size())
LogManager.log("DungeonGenerator: Placing stairs in exit room: " + str(exit_room.x) + "," + str(exit_room.y) + " size: " + str(exit_room.w) + "x" + str(exit_room.h) + " doors: " + str(all_doors.size()), LogManager.CATEGORY_DUNGEON)
var stairs_data: Dictionary = {}
var wall_choices = []
@@ -1334,7 +1334,7 @@ func _place_stairs_in_exit_room(exit_room: Dictionary, grid: Array, tile_grid: A
for stairs_tile_y in range(stairs_y, stairs_y + stairs_h):
if stairs_tile_x >= 0 and stairs_tile_x < map_size.x and stairs_tile_y >= 0 and stairs_tile_y < map_size.y:
if grid[stairs_tile_x][stairs_tile_y] == 2: # Grid value 2 = door
print("DungeonGenerator: Stairs tile (", stairs_tile_x, ",", stairs_tile_y, ") is marked as door in grid!")
LogManager.log("DungeonGenerator: Stairs tile (" + str(stairs_tile_x) + "," + str(stairs_tile_y) + ") is marked as door in grid!", LogManager.CATEGORY_DUNGEON)
return true
# SECOND: Check door dictionary - verify against all known doors
@@ -1377,7 +1377,8 @@ func _place_stairs_in_exit_room(exit_room: Dictionary, grid: Array, tile_grid: A
# Check if this stairs tile matches any door tile
for door_tile in door_tiles:
if stairs_tile_x == door_tile.x and stairs_tile_y == door_tile.y:
print("DungeonGenerator: Stairs tile (", stairs_tile_x, ",", stairs_tile_y, ") overlaps door tile (", door_tile.x, ",", door_tile.y, ") from door at (", door_x, ",", door_y, ") dir: ", door.dir if "dir" in door else "unknown")
var door_dir_str = str(door.dir) if "dir" in door else "unknown"
LogManager.log("DungeonGenerator: Stairs tile (" + str(stairs_tile_x) + "," + str(stairs_tile_y) + ") overlaps door tile (" + str(door_tile.x) + "," + str(door_tile.y) + ") from door at (" + str(door_x) + "," + str(door_y) + ") dir: " + door_dir_str, LogManager.CATEGORY_DUNGEON)
return true
return false
@@ -1453,7 +1454,7 @@ func _place_stairs_in_exit_room(exit_room: Dictionary, grid: Array, tile_grid: A
})
if wall_choices.size() == 0:
print("DungeonGenerator: ERROR - No valid walls for stairs! Exit room too small: ", exit_room.w, "x", exit_room.h)
LogManager.log_error("DungeonGenerator: ERROR - No valid walls for stairs! Exit room too small: " + str(exit_room.w) + "x" + str(exit_room.h), LogManager.CATEGORY_DUNGEON)
return {} # No valid walls for stairs
# Choose a random wall
@@ -1462,7 +1463,7 @@ func _place_stairs_in_exit_room(exit_room: Dictionary, grid: Array, tile_grid: A
if wall.dir == "UP" or wall.dir == "DOWN":
# Horizontal stairs (3x2)
if wall.x_range.size() == 0:
print("DungeonGenerator: ERROR - x_range is empty for ", wall.dir, " stairs")
LogManager.log_error("DungeonGenerator: ERROR - x_range is empty for " + str(wall.dir) + " stairs", LogManager.CATEGORY_DUNGEON)
return {}
# Try to find a position that doesn't overlap doors
@@ -1473,7 +1474,7 @@ func _place_stairs_in_exit_room(exit_room: Dictionary, grid: Array, tile_grid: A
valid_positions.append(test_x)
if valid_positions.size() == 0:
print("DungeonGenerator: ERROR - No valid position found for ", wall.dir, " stairs (all positions overlap doors)")
LogManager.log_error("DungeonGenerator: ERROR - No valid position found for " + str(wall.dir) + " stairs (all positions overlap doors)", LogManager.CATEGORY_DUNGEON)
# Don't allow stairs to overlap doors - this is a critical bug
# Instead, try the next wall or return empty to force placement elsewhere
return {} # No valid position found - will trigger _force_place_stairs
@@ -1493,7 +1494,7 @@ func _place_stairs_in_exit_room(exit_room: Dictionary, grid: Array, tile_grid: A
"world_size": Vector2(wall.w * tile_size, wall.h * tile_size)
}
print("DungeonGenerator: Placed ", wall.dir, " stairs at tile (", stairs_start_x, ",", wall.y, ") world pos: ", stairs_data.world_pos, " in room (", exit_room.x, ",", exit_room.y, ") size ", exit_room.w, "x", exit_room.h)
LogManager.log("DungeonGenerator: Placed " + str(wall.dir) + " stairs at tile (" + str(stairs_start_x) + "," + str(wall.y) + ") world pos: " + str(stairs_data.world_pos) + " in room (" + str(exit_room.x) + "," + str(exit_room.y) + ") size " + str(exit_room.w) + "x" + str(exit_room.h), LogManager.CATEGORY_DUNGEON)
# Mark grid cells as stairs (similar to doors)
for dx in range(wall.w):
@@ -1524,7 +1525,7 @@ func _place_stairs_in_exit_room(exit_room: Dictionary, grid: Array, tile_grid: A
elif wall.dir == "LEFT" or wall.dir == "RIGHT":
# Vertical stairs (2x3)
if wall.y_range.size() == 0:
print("DungeonGenerator: ERROR - y_range is empty for ", wall.dir, " stairs")
LogManager.log_error("DungeonGenerator: ERROR - y_range is empty for " + str(wall.dir) + " stairs", LogManager.CATEGORY_DUNGEON)
return {}
# Try to find a position that doesn't overlap doors
@@ -1535,7 +1536,7 @@ func _place_stairs_in_exit_room(exit_room: Dictionary, grid: Array, tile_grid: A
valid_positions.append(test_y)
if valid_positions.size() == 0:
print("DungeonGenerator: ERROR - No valid position found for ", wall.dir, " stairs (all positions overlap doors)")
LogManager.log_error("DungeonGenerator: ERROR - No valid position found for " + str(wall.dir) + " stairs (all positions overlap doors)", LogManager.CATEGORY_DUNGEON)
# Don't allow stairs to overlap doors - this is a critical bug
# Instead, try the next wall or return empty to force placement elsewhere
return {} # No valid position found - will trigger _force_place_stairs
@@ -1555,7 +1556,7 @@ func _place_stairs_in_exit_room(exit_room: Dictionary, grid: Array, tile_grid: A
"world_size": Vector2(wall.w * tile_size, wall.h * tile_size)
}
print("DungeonGenerator: Placed ", wall.dir, " stairs at tile (", wall.x, ",", stairs_start_y, ") world pos: ", stairs_data.world_pos, " in room (", exit_room.x, ",", exit_room.y, ") size ", exit_room.w, "x", exit_room.h)
LogManager.log("DungeonGenerator: Placed " + str(wall.dir) + " stairs at tile (" + str(wall.x) + "," + str(stairs_start_y) + ") world pos: " + str(stairs_data.world_pos) + " in room (" + str(exit_room.x) + "," + str(exit_room.y) + ") size " + str(exit_room.w) + "x" + str(exit_room.h), LogManager.CATEGORY_DUNGEON)
# Mark grid cells as stairs
for dx in range(wall.w):
@@ -1588,7 +1589,7 @@ func _force_place_stairs(exit_room: Dictionary, grid: Array, tile_grid: Array, m
# Force place stairs in exit room - used as fallback when normal placement fails
# Still tries to avoid door overlaps, but will place stairs even if room is small
# Uses same positioning logic as doors: at least 2 tiles from corners
print("DungeonGenerator: Force placing stairs in exit room: ", exit_room.x, ",", exit_room.y, " size: ", exit_room.w, "x", exit_room.h)
LogManager.log("DungeonGenerator: Force placing stairs in exit room: " + str(exit_room.x) + "," + str(exit_room.y) + " size: " + str(exit_room.w) + "x" + str(exit_room.h), LogManager.CATEGORY_DUNGEON)
var stairs_data: Dictionary = {}
var tile_size = 16
@@ -1747,7 +1748,7 @@ func _force_place_stairs(exit_room: Dictionary, grid: Array, tile_grid: Array, m
# If still no valid position found, return empty (don't place stairs that overlap doors!)
if not found_position:
print("DungeonGenerator: ERROR - Could not find any position for stairs that doesn't overlap doors!")
LogManager.log_error("DungeonGenerator: ERROR - Could not find any position for stairs that doesn't overlap doors!", LogManager.CATEGORY_DUNGEON)
return {}
stairs_data = {
@@ -1807,7 +1808,7 @@ func _force_place_stairs(exit_room: Dictionary, grid: Array, tile_grid: Array, m
# Fallback: use UP stairs tiles
tile_grid[x][y] = STAIRS_UP_START + Vector2i(dx, dy)
print("DungeonGenerator: Force placed ", stairs_dir, " stairs at tile (", stairs_data.x, ",", stairs_data.y, ") world pos: ", stairs_data.world_pos)
LogManager.log("DungeonGenerator: Force placed " + str(stairs_dir) + " stairs at tile (" + str(stairs_data.x) + "," + str(stairs_data.y) + ") world pos: " + str(stairs_data.world_pos), LogManager.CATEGORY_DUNGEON)
return stairs_data
func _place_interactable_objects_in_room(room: Dictionary, grid: Array, map_size: Vector2i, all_doors: Array, all_enemies: Array, rng: RandomNumberGenerator, room_puzzle_data: Dictionary = {}) -> Array:
@@ -1828,13 +1829,13 @@ func _place_interactable_objects_in_room(room: Dictionary, grid: Array, map_size
if puzzle_room.x == room.x and puzzle_room.y == room.y and \
puzzle_room.w == room.w and puzzle_room.h == room.h:
var puzzle_info = room_puzzle_data[puzzle_room]
print("DungeonGenerator: Checking room (", room.x, ",", room.y, ") - puzzle_room (", puzzle_room.x, ",", puzzle_room.y, ") puzzle_type: ", puzzle_info.type)
LogManager.log("DungeonGenerator: Checking room (" + str(room.x) + "," + str(room.y) + ") - puzzle_room (" + str(puzzle_room.x) + "," + str(puzzle_room.y) + ") puzzle_type: " + str(puzzle_info.type), LogManager.CATEGORY_DUNGEON)
if puzzle_info.type == "switch_pillar":
has_pillar_switch_puzzle = true
print("DungeonGenerator: Room (", room.x, ",", room.y, ") has pillar switch puzzle - will spawn at least 1 pillar")
LogManager.log("DungeonGenerator: Room (" + str(room.x) + "," + str(room.y) + ") has pillar switch puzzle - will spawn at least 1 pillar", LogManager.CATEGORY_DUNGEON)
break
else:
print("DungeonGenerator: room_puzzle_data is empty for room (", room.x, ",", room.y, ")")
LogManager.log("DungeonGenerator: room_puzzle_data is empty for room (" + str(room.x) + "," + str(room.y) + ")", LogManager.CATEGORY_DUNGEON)
# Calculate room floor area (excluding walls)
var floor_w = room.w - 4 # Excluding 2-tile walls on each side
@@ -2090,7 +2091,7 @@ func _place_blocking_doors(all_rooms: Array, all_doors: Array, grid: Array, map_
# STEP 1: For each room (except start/exit), randomly decide if it has a door-puzzle
var puzzle_room_chance = 0.4 # 40% chance per room
print("DungeonGenerator: Assigning puzzles to rooms (", all_rooms.size(), " total rooms, excluding start/exit)")
LogManager.log("DungeonGenerator: Assigning puzzles to rooms (" + str(all_rooms.size()) + " total rooms, excluding start/exit)", LogManager.CATEGORY_DUNGEON)
for i in range(all_rooms.size()):
if i == start_room_index or i == exit_room_index:
continue # Skip start and exit rooms
@@ -2098,7 +2099,7 @@ func _place_blocking_doors(all_rooms: Array, all_doors: Array, grid: Array, map_
var room = all_rooms[i]
if rng.randf() < puzzle_room_chance:
print("DungeonGenerator: Room (", room.x, ", ", room.y, ") selected for puzzle assignment")
LogManager.log("DungeonGenerator: Room (" + str(room.x) + ", " + str(room.y) + ") selected for puzzle assignment", LogManager.CATEGORY_DUNGEON)
# This room has a puzzle!
# CRITICAL SAFETY CHECK: Never assign puzzles to start or exit rooms
# Double-check even though we skip them in the loop
@@ -2128,10 +2129,10 @@ func _place_blocking_doors(all_rooms: Array, all_doors: Array, grid: Array, map_
doors_in_room.append(door)
if doors_in_room.size() == 0:
print("DungeonGenerator: Room (", room.x, ", ", room.y, ") has no doors connected - skipping puzzle assignment")
LogManager.log("DungeonGenerator: Room (" + str(room.x) + ", " + str(room.y) + ") has no doors connected - skipping puzzle assignment", LogManager.CATEGORY_DUNGEON)
continue # No doors connected to this room, skip
print("DungeonGenerator: Room (", room.x, ", ", room.y, ") has ", doors_in_room.size(), " doors - assigning puzzle")
LogManager.log("DungeonGenerator: Room (" + str(room.x) + ", " + str(room.y) + ") has " + str(doors_in_room.size()) + " doors - assigning puzzle", LogManager.CATEGORY_DUNGEON)
# Decide puzzle type: 33% walk switch, 33% pillar switch, 33% enemy spawner (if room is large enough)
var can_have_enemies = false
@@ -2153,13 +2154,13 @@ func _place_blocking_doors(all_rooms: Array, all_doors: Array, grid: Array, map_
"type": puzzle_type,
"doors": doors_in_room
}
print("DungeonGenerator: Stored puzzle data for room (", room.x, ", ", room.y, ") - type: ", puzzle_type, ", doors: ", doors_in_room.size())
LogManager.log("DungeonGenerator: Stored puzzle data for room (" + str(room.x) + ", " + str(room.y) + ") - type: " + str(puzzle_type) + ", doors: " + str(doors_in_room.size()), LogManager.CATEGORY_DUNGEON)
# Mark these doors as assigned
for door in doors_in_room:
assigned_doors.append(door)
print("DungeonGenerator: Assigned puzzles to ", room_puzzle_data.size(), " rooms")
LogManager.log("DungeonGenerator: Assigned puzzles to " + str(room_puzzle_data.size()) + " rooms", LogManager.CATEGORY_DUNGEON)
# STEP 2: Create blocking doors for rooms with puzzles
# CRITICAL: Blocking doors should ONLY be placed ON THE DOORS IN THE PUZZLE ROOM
@@ -2168,7 +2169,7 @@ func _place_blocking_doors(all_rooms: Array, all_doors: Array, grid: Array, map_
for room in room_puzzle_data.keys():
# CRITICAL SAFETY CHECK #1: Verify this room is actually in room_puzzle_data
if not room in room_puzzle_data:
push_error("DungeonGenerator: ERROR - Room (", room.x, ", ", room.y, ") is NOT in room_puzzle_data! This should never happen!")
LogManager.log_error("DungeonGenerator: ERROR - Room (" + str(room.x) + ", " + str(room.y) + ") is NOT in room_puzzle_data! This should never happen!", LogManager.CATEGORY_DUNGEON)
continue
# CRITICAL SAFETY CHECK #2: Never create blocking doors for start or exit rooms
@@ -2181,12 +2182,12 @@ func _place_blocking_doors(all_rooms: Array, all_doors: Array, grid: Array, map_
break
if room_index == start_room_index or room_index == exit_room_index:
push_error("DungeonGenerator: ERROR - Attempted to create blocking doors for start/exit room! Skipping.")
LogManager.log_error("DungeonGenerator: ERROR - Attempted to create blocking doors for start/exit room! Skipping.", LogManager.CATEGORY_DUNGEON)
continue
# CRITICAL SAFETY CHECK #3: Verify this room is actually in all_rooms (sanity check)
if room_index == -1:
push_error("DungeonGenerator: ERROR - Room (", room.x, ", ", room.y, ") not found in all_rooms! Skipping.")
LogManager.log_error("DungeonGenerator: ERROR - Room (" + str(room.x) + ", " + str(room.y) + ") not found in all_rooms! Skipping.", LogManager.CATEGORY_DUNGEON)
continue
var puzzle_info = room_puzzle_data[room]
@@ -2194,7 +2195,7 @@ func _place_blocking_doors(all_rooms: Array, all_doors: Array, grid: Array, map_
var puzzle_type = puzzle_info.type
if doors_in_room.size() == 0:
print("DungeonGenerator: WARNING - Room has puzzle but no doors! Skipping.")
LogManager.log("DungeonGenerator: WARNING - Room has puzzle but no doors! Skipping.", LogManager.CATEGORY_DUNGEON)
continue
# Randomly choose door type: 50% StoneDoor, 50% GateDoor
@@ -2219,9 +2220,9 @@ func _place_blocking_doors(all_rooms: Array, all_doors: Array, grid: Array, map_
"switch_data": switch_data,
"switch_room": room
}
print("DungeonGenerator: Created switch puzzle for room (", room.x, ", ", room.y, ") - type: ", switch_type)
LogManager.log("DungeonGenerator: Created switch puzzle for room (" + str(room.x) + ", " + str(room.y) + ") - type: " + str(switch_type), LogManager.CATEGORY_DUNGEON)
else:
print("DungeonGenerator: WARNING - Could not place floor switch in puzzle room (", room.x, ", ", room.y, ")! Skipping puzzle.")
LogManager.log("DungeonGenerator: WARNING - Could not place floor switch in puzzle room (" + str(room.x) + ", " + str(room.y) + ")! Skipping puzzle.", LogManager.CATEGORY_DUNGEON)
elif puzzle_type == "enemy":
# Add enemy spawner IN THE PUZZLE ROOM
var spawner_positions = []
@@ -2246,13 +2247,13 @@ func _place_blocking_doors(all_rooms: Array, all_doors: Array, grid: Array, map_
"spawner_data": spawner_data,
"spawner_room": room
}
print("DungeonGenerator: Created enemy spawner puzzle for room (", room.x, ", ", room.y, ") - spawner at ", spawner_data.position)
LogManager.log("DungeonGenerator: Created enemy spawner puzzle for room (" + str(room.x) + ", " + str(room.y) + ") - spawner at " + str(spawner_data.position), LogManager.CATEGORY_DUNGEON)
else:
print("DungeonGenerator: WARNING - Could not place enemy spawner in puzzle room (", room.x, ", ", room.y, ")! Skipping puzzle.")
LogManager.log("DungeonGenerator: WARNING - Could not place enemy spawner in puzzle room (" + str(room.x) + ", " + str(room.y) + ")! Skipping puzzle.", LogManager.CATEGORY_DUNGEON)
# CRITICAL SAFETY CHECK: Only create blocking doors if puzzle element was successfully created
if not puzzle_element_created:
push_error("DungeonGenerator: ERROR - Puzzle element was NOT created for room (", room.x, ", ", room.y, ") with puzzle_type: ", puzzle_type, "! Skipping ALL doors in this room.")
LogManager.log_error("DungeonGenerator: ERROR - Puzzle element was NOT created for room (" + str(room.x) + ", " + str(room.y) + ") with puzzle_type: " + str(puzzle_type) + "! Skipping ALL doors in this room.", LogManager.CATEGORY_DUNGEON)
# Remove doors from assigned list since we're not creating the puzzle
for door in doors_in_room:
if door in assigned_doors:
@@ -2261,12 +2262,12 @@ func _place_blocking_doors(all_rooms: Array, all_doors: Array, grid: Array, map_
# CRITICAL: Verify puzzle_element_data is valid before proceeding
if puzzle_element_data.is_empty() or not puzzle_element_data.has("type"):
push_error("DungeonGenerator: ERROR - puzzle_element_data is invalid for room (", room.x, ", ", room.y, ")! puzzle_element_created was true but data is empty!")
LogManager.log_error("DungeonGenerator: ERROR - puzzle_element_data is invalid for room (" + str(room.x) + ", " + str(room.y) + ")! puzzle_element_created was true but data is empty!", LogManager.CATEGORY_DUNGEON)
continue
# Create blocking doors for at least 1 door (minimum), or all doors in the room
# For now, create blocking doors for ALL doors in the puzzle room
print("DungeonGenerator: Creating blocking doors for room (", room.x, ", ", room.y, ") with ", doors_in_room.size(), " doors, puzzle type: ", puzzle_type, ", puzzle_element type: ", puzzle_element_data.type)
LogManager.log("DungeonGenerator: Creating blocking doors for room (" + str(room.x) + ", " + str(room.y) + ") with " + str(doors_in_room.size()) + " doors, puzzle type: " + str(puzzle_type) + ", puzzle_element type: " + str(puzzle_element_data.type), LogManager.CATEGORY_DUNGEON)
for door in doors_in_room:
# Determine direction based on which WALL of the PUZZLE ROOM the door is on
var direction = _determine_door_direction_for_puzzle_room(door, room, all_rooms)
@@ -2343,7 +2344,7 @@ func _place_blocking_doors(all_rooms: Array, all_doors: Array, grid: Array, map_
# Position is the OPEN state position (will move to CLOSED when entering room)
# CRITICAL: Verify room is still a valid puzzle room before creating door
if not room in room_puzzle_data:
push_error("DungeonGenerator: ERROR - Room (", room.x, ", ", room.y, ") is no longer in room_puzzle_data! Cannot create door.")
LogManager.log_error("DungeonGenerator: ERROR - Room (" + str(room.x) + ", " + str(room.y) + ") is no longer in room_puzzle_data! Cannot create door.", LogManager.CATEGORY_DUNGEON)
continue
# NOTE: door_room1 is already declared at line 1933 and verified to match puzzle room at line 1935-1940
@@ -2364,7 +2365,7 @@ func _place_blocking_doors(all_rooms: Array, all_doors: Array, grid: Array, map_
# Store puzzle room as room1 for blocking doors
door_data.original_room1 = room # Puzzle room is always room1 for blocking doors
print("DungeonGenerator: Creating blocking door for puzzle room (", room.x, ", ", room.y, ") - direction: ", direction, ", open_tile: (", open_tile_x, ",", open_tile_y, ")")
LogManager.log("DungeonGenerator: Creating blocking door for puzzle room (" + str(room.x) + ", " + str(room.y) + ") - direction: " + str(direction) + ", open_tile: (" + str(open_tile_x) + "," + str(open_tile_y) + ")", LogManager.CATEGORY_DUNGEON)
# CRITICAL: Add puzzle-specific data from the puzzle_element_data created above (shared across all doors in room)
# Only add door if puzzle element data is valid
@@ -2379,7 +2380,7 @@ func _place_blocking_doors(all_rooms: Array, all_doors: Array, grid: Array, map_
door_data.switch_type = puzzle_element_data.switch_type
door_data.switch_required_weight = puzzle_element_data.switch_weight
door_has_valid_puzzle = true
print("DungeonGenerator: Added switch data to door - switch at (", door_data.switch_tile_x, ", ", door_data.switch_tile_y, ")")
LogManager.log("DungeonGenerator: Added switch data to door - switch at (" + str(door_data.switch_tile_x) + ", " + str(door_data.switch_tile_y) + ")", LogManager.CATEGORY_DUNGEON)
elif puzzle_element_data.has("type") and puzzle_element_data.type == "enemy":
if puzzle_element_data.has("spawner_data") and puzzle_element_data.spawner_data.has("position"):
if not "enemy_spawners" in door_data:
@@ -2393,11 +2394,11 @@ func _place_blocking_doors(all_rooms: Array, all_doors: Array, grid: Array, map_
})
door_data.requires_enemies = true
door_has_valid_puzzle = true
print("DungeonGenerator: Added enemy spawner data to door - spawner at (", puzzle_element_data.spawner_data.tile_x, ", ", puzzle_element_data.spawner_data.tile_y, ")")
LogManager.log("DungeonGenerator: Added enemy spawner data to door - spawner at (" + str(puzzle_element_data.spawner_data.tile_x) + ", " + str(puzzle_element_data.spawner_data.tile_y) + ")", LogManager.CATEGORY_DUNGEON)
# CRITICAL SAFETY CHECK: Only add door to blocking doors if it has valid puzzle element
if not door_has_valid_puzzle:
push_error("DungeonGenerator: ERROR - Blocking door for room (", room.x, ", ", room.y, ") has no valid puzzle element! Skipping door. puzzle_type: ", puzzle_type, ", puzzle_element_data: ", puzzle_element_data)
LogManager.log_error("DungeonGenerator: ERROR - Blocking door for room (" + str(room.x) + ", " + str(room.y) + ") has no valid puzzle element! Skipping door. puzzle_type: " + str(puzzle_type) + ", puzzle_element_data: " + str(puzzle_element_data), LogManager.CATEGORY_DUNGEON)
continue # Skip this door - don't add it to blocking_doors
# FINAL SAFETY CHECK: Verify door has either requires_switch or requires_enemies set
@@ -2405,18 +2406,18 @@ func _place_blocking_doors(all_rooms: Array, all_doors: Array, grid: Array, map_
var has_switch = door_data.get("requires_switch", false) == true
var has_enemies = door_data.get("requires_enemies", false) == true
if not has_switch and not has_enemies:
push_error("DungeonGenerator: ERROR - Blocking door (StoneDoor/GateDoor) has neither requires_switch nor requires_enemies! Door data: ", door_data.keys(), " - SKIPPING DOOR")
LogManager.log_error("DungeonGenerator: ERROR - Blocking door (StoneDoor/GateDoor) has neither requires_switch nor requires_enemies! Door data: " + str(door_data.keys()) + " - SKIPPING DOOR", LogManager.CATEGORY_DUNGEON)
continue # Skip this door - it's invalid
# FINAL CRITICAL SAFETY CHECK: Verify door's blocking_room matches the puzzle room exactly
if door_data.blocking_room.x != room.x or door_data.blocking_room.y != room.y or \
door_data.blocking_room.w != room.w or door_data.blocking_room.h != room.h:
push_error("DungeonGenerator: ERROR - Door blocking_room (", door_data.blocking_room.x, ",", door_data.blocking_room.y, ") doesn't match puzzle room (", room.x, ",", room.y, ")! This door is for wrong room! SKIPPING DOOR")
LogManager.log_error("DungeonGenerator: ERROR - Door blocking_room (" + str(door_data.blocking_room.x) + "," + str(door_data.blocking_room.y) + ") doesn't match puzzle room (" + str(room.x) + "," + str(room.y) + ")! This door is for wrong room! SKIPPING DOOR", LogManager.CATEGORY_DUNGEON)
continue # Skip this door - it's for the wrong room
# Add door to blocking doors list ONLY if it has valid puzzle element
blocking_doors.append(door_data)
print("DungeonGenerator: Created blocking door for puzzle room (", room.x, ", ", room.y, ") - direction: ", direction, ", open tile: (", open_tile_x, ", ", open_tile_y, "), puzzle_type: ", puzzle_type, ", has_switch: ", door_data.get("requires_switch", false), ", has_enemies: ", door_data.get("requires_enemies", false))
LogManager.log("DungeonGenerator: Created blocking door for puzzle room (" + str(room.x) + ", " + str(room.y) + ") - direction: " + str(direction) + ", open tile: (" + str(open_tile_x) + ", " + str(open_tile_y) + "), puzzle_type: " + str(puzzle_type) + ", has_switch: " + str(door_data.get("requires_switch", false)) + ", has_enemies: " + str(door_data.get("requires_enemies", false)), LogManager.CATEGORY_DUNGEON)
# STEP 3: Randomly assign some doors as KeyDoors (except start/exit room doors and already assigned doors)
var key_door_chance = 0.2 # 20% chance per door