fix webrtc FINALLY!
This commit is contained in:
@@ -2483,7 +2483,13 @@ func _send_dungeon_blob_sync(client_peer_id: int):
|
||||
# Send metadata first
|
||||
var metadata = dungeon_blob_metadata
|
||||
print("GameWorld: HOST - [CHUNK 0] Sending metadata...")
|
||||
_sync_dungeon_blob_metadata.rpc_id(client_peer_id, metadata.seed, metadata.level, metadata.map_size, metadata.host_room, total_chunks)
|
||||
# Include all state data in metadata so client knows what's already changed
|
||||
var defeated_list = metadata.get("defeated_enemies", [])
|
||||
var broken_list = metadata.get("broken_objects", [])
|
||||
var door_states_list = metadata.get("door_states", [])
|
||||
var opened_chests_list = metadata.get("opened_chests", [])
|
||||
var loot_list = metadata.get("existing_loot", [])
|
||||
_sync_dungeon_blob_metadata.rpc_id(client_peer_id, metadata.seed, metadata.level, metadata.map_size, metadata.host_room, total_chunks, defeated_list, broken_list, door_states_list, opened_chests_list, loot_list)
|
||||
|
||||
# Initialize acknowledgment tracking
|
||||
var chunk_acks = {}
|
||||
@@ -2729,11 +2735,73 @@ func _pack_dungeon_blob():
|
||||
LogManager.log("GameWorld: Packing dungeon blob - enemies: " + str(enemy_count) + ", torches: " + str(torch_count) + ", objects: " + str(object_count), LogManager.CATEGORY_DUNGEON)
|
||||
|
||||
# Store metadata separately (small, sent first)
|
||||
# Include defeated enemies so clients know which enemies not to spawn
|
||||
var defeated_indices = []
|
||||
for enemy_index in defeated_enemies.keys():
|
||||
defeated_indices.append(enemy_index)
|
||||
|
||||
# Collect broken object indices
|
||||
var broken_indices = []
|
||||
for obj_index in broken_objects.keys():
|
||||
broken_indices.append(obj_index)
|
||||
|
||||
# Collect door states
|
||||
var door_states_list = []
|
||||
var entities_node = get_node_or_null("Entities")
|
||||
if entities_node:
|
||||
for child in entities_node.get_children():
|
||||
if child.is_in_group("blocking_door") or child.has_method("_sync_door_open"):
|
||||
var door_state = {
|
||||
"door_name": child.name,
|
||||
"is_closed": child.is_closed if "is_closed" in child else true,
|
||||
"puzzle_solved": child.puzzle_solved if "puzzle_solved" in child else false,
|
||||
"key_used": child.key_used if "key_used" in child else false,
|
||||
"position": child.position if "position" in child else Vector2.ZERO,
|
||||
"closed_position": child.closed_position if "closed_position" in child else Vector2.ZERO,
|
||||
"open_offset": child.open_offset if "open_offset" in child else Vector2.ZERO
|
||||
}
|
||||
door_states_list.append(door_state)
|
||||
|
||||
# Collect opened chest names
|
||||
var opened_chest_names = []
|
||||
if entities_node:
|
||||
for child in entities_node.get_children():
|
||||
if child.is_in_group("interactable_object"):
|
||||
if "object_type" in child and child.object_type == "Chest":
|
||||
if "is_chest_opened" in child and child.is_chest_opened:
|
||||
opened_chest_names.append(child.name)
|
||||
|
||||
# Collect existing loot
|
||||
var loot_list = []
|
||||
if entities_node:
|
||||
for child in entities_node.get_children():
|
||||
if child.is_in_group("loot"):
|
||||
var current_velocity = child.velocity if "velocity" in child else Vector2.ZERO
|
||||
var current_velocity_z = child.velocity_z if "velocity_z" in child else 0.0
|
||||
var loot_data = {
|
||||
"position": child.global_position,
|
||||
"loot_type": child.loot_type if "loot_type" in child else 0,
|
||||
"loot_id": child.get_meta("loot_id") if child.has_meta("loot_id") else -1,
|
||||
"velocity": current_velocity,
|
||||
"velocity_z": current_velocity_z
|
||||
}
|
||||
# For item loot, include item data
|
||||
if child.loot_type == child.LootType.ITEM and "item" in child and child.item:
|
||||
var item = child.item
|
||||
if item.has_method("save"):
|
||||
loot_data["item_data"] = item.save()
|
||||
loot_list.append(loot_data)
|
||||
|
||||
dungeon_blob_metadata = {
|
||||
"seed": dungeon_seed,
|
||||
"level": current_level,
|
||||
"map_size": full_dungeon_data.map_size,
|
||||
"host_room": _get_host_room()
|
||||
"host_room": _get_host_room(),
|
||||
"defeated_enemies": defeated_indices,
|
||||
"broken_objects": broken_indices,
|
||||
"door_states": door_states_list,
|
||||
"opened_chests": opened_chest_names,
|
||||
"existing_loot": loot_list
|
||||
}
|
||||
|
||||
# Serialize to bytes
|
||||
@@ -2906,11 +2974,56 @@ func _sync_dungeon(dungeon_data_sync: Dictionary, seed_value: int, level: int, h
|
||||
call_deferred("_fix_player_appearance_after_dungeon_sync")
|
||||
|
||||
@rpc("authority", "reliable", "call_local")
|
||||
func _sync_dungeon_blob_metadata(seed_value: int, level: int, map_size_sync: Vector2i, host_room: Dictionary, total_chunks: int):
|
||||
func _sync_dungeon_blob_metadata(seed_value: int, level: int, map_size_sync: Vector2i, host_room: Dictionary, total_chunks: int, defeated_enemies_list: Array = [], broken_objects_list: Array = [], door_states_list: Array = [], opened_chests_list: Array = [], existing_loot_list: Array = []):
|
||||
# Client receives metadata for blob sync
|
||||
print("=== _sync_dungeon_blob_metadata RPC RECEIVED on client ===")
|
||||
print("=== [CHUNK 0] Client received blob metadata - Level: ", level, ", Map size: ", map_size_sync, ", Total chunks: ", total_chunks, " ===")
|
||||
print("=== [CHUNK 0] Client received blob metadata - Level: ", level, ", Map size: ", map_size_sync, ", Total chunks: ", total_chunks)
|
||||
print("=== Defeated enemies: ", defeated_enemies_list.size(), ", Broken objects: ", broken_objects_list.size(), ", Door states: ", door_states_list.size(), ", Opened chests: ", opened_chests_list.size(), ", Existing loot: ", existing_loot_list.size(), " ===")
|
||||
if not multiplayer.is_server():
|
||||
# Store defeated enemies BEFORE dungeon is unpacked and enemies are spawned
|
||||
defeated_enemies.clear()
|
||||
for enemy_index in defeated_enemies_list:
|
||||
defeated_enemies[enemy_index] = true
|
||||
if defeated_enemies_list.size() > 0:
|
||||
print("GameWorld: Client - Received ", defeated_enemies_list.size(), " defeated enemy indices before dungeon spawn")
|
||||
LogManager.log("GameWorld: Client received " + str(defeated_enemies_list.size()) + " defeated enemy indices", LogManager.CATEGORY_NETWORK)
|
||||
|
||||
# Store broken objects BEFORE objects are spawned
|
||||
broken_objects.clear()
|
||||
for obj_index in broken_objects_list:
|
||||
broken_objects[obj_index] = true
|
||||
if broken_objects_list.size() > 0:
|
||||
print("GameWorld: Client - Received ", broken_objects_list.size(), " broken object indices before dungeon spawn")
|
||||
LogManager.log("GameWorld: Client received " + str(broken_objects_list.size()) + " broken object indices", LogManager.CATEGORY_NETWORK)
|
||||
|
||||
# Store door states (will be applied after doors spawn)
|
||||
pending_door_states.clear()
|
||||
for door_state in door_states_list:
|
||||
var door_name = door_state.get("door_name", "")
|
||||
if door_name != "":
|
||||
pending_door_states[door_name] = door_state
|
||||
if door_states_list.size() > 0:
|
||||
print("GameWorld: Client - Received ", door_states_list.size(), " door states before dungeon spawn")
|
||||
LogManager.log("GameWorld: Client received " + str(door_states_list.size()) + " door states", LogManager.CATEGORY_NETWORK)
|
||||
|
||||
# Store opened chest states (will be applied after chests spawn)
|
||||
pending_chest_opens.clear()
|
||||
for chest_name in opened_chests_list:
|
||||
pending_chest_opens[chest_name] = {
|
||||
"loot_type": "coin", # Default, actual loot type should be stored if available
|
||||
"player_peer_id": 0,
|
||||
"item_data": {}
|
||||
}
|
||||
if opened_chests_list.size() > 0:
|
||||
print("GameWorld: Client - Received ", opened_chests_list.size(), " opened chest names before dungeon spawn")
|
||||
LogManager.log("GameWorld: Client received " + str(opened_chests_list.size()) + " opened chest names", LogManager.CATEGORY_NETWORK)
|
||||
|
||||
# Store existing loot (will be spawned after dungeon is loaded)
|
||||
# We'll need to store this temporarily and spawn it after dungeon is ready
|
||||
# For now, we'll spawn it immediately after dungeon blob is reassembled
|
||||
if existing_loot_list.size() > 0:
|
||||
print("GameWorld: Client - Received ", existing_loot_list.size(), " existing loot items before dungeon spawn")
|
||||
LogManager.log("GameWorld: Client received " + str(existing_loot_list.size()) + " existing loot items", LogManager.CATEGORY_NETWORK)
|
||||
# Check if this is a new level (different from current)
|
||||
var is_new_level = (current_level != level)
|
||||
if is_new_level:
|
||||
@@ -2921,11 +3034,13 @@ func _sync_dungeon_blob_metadata(seed_value: int, level: int, map_size_sync: Vec
|
||||
dungeon_sync_in_progress.clear()
|
||||
|
||||
# Reset blob sync state
|
||||
# Store metadata including state data for later use
|
||||
dungeon_sync_metadata = {
|
||||
"map_size": map_size_sync,
|
||||
"seed": seed_value,
|
||||
"level": level,
|
||||
"host_room": host_room
|
||||
"host_room": host_room,
|
||||
"existing_loot": existing_loot_list # Store for spawning after dungeon is ready
|
||||
}
|
||||
dungeon_sync_chunks.clear()
|
||||
dungeon_sync_received_chunks = 0
|
||||
@@ -3168,6 +3283,31 @@ func _reassemble_dungeon_blob():
|
||||
_spawn_room_triggers()
|
||||
print("GameWorld: Client - Room triggers spawned")
|
||||
|
||||
# Apply door states (from metadata) - after doors are spawned
|
||||
if pending_door_states.size() > 0:
|
||||
print("GameWorld: Client - Applying ", pending_door_states.size(), " pending door states...")
|
||||
var entities_node = get_node_or_null("Entities")
|
||||
if entities_node:
|
||||
for child in entities_node.get_children():
|
||||
if child.is_in_group("blocking_door") or child.has_method("_sync_door_open"):
|
||||
if pending_door_states.has(child.name):
|
||||
_apply_pending_door_state(child)
|
||||
print("GameWorld: Client - Door states applied")
|
||||
|
||||
# Spawn existing loot (from metadata) - call the RPC handler directly since we're the client
|
||||
if dungeon_sync_metadata.has("existing_loot"):
|
||||
var loot_list = dungeon_sync_metadata.existing_loot
|
||||
if loot_list.size() > 0:
|
||||
print("GameWorld: Client - Spawning ", loot_list.size(), " existing loot items from metadata...")
|
||||
for loot_data in loot_list:
|
||||
if loot_data.has("item_data"):
|
||||
# Call the RPC handler directly (it's marked as call_local)
|
||||
_sync_item_loot_spawn(loot_data.position, loot_data.item_data, loot_data.get("velocity", Vector2.ZERO), loot_data.get("velocity_z", 0.0), loot_data.get("loot_id", -1))
|
||||
else:
|
||||
# Call the RPC handler directly (it's marked as call_local)
|
||||
_sync_loot_spawn(loot_data.position, loot_data.get("loot_type", 0), loot_data.get("velocity", Vector2.ZERO), loot_data.get("velocity_z", 0.0), loot_data.get("loot_id", -1))
|
||||
print("GameWorld: Client - Existing loot spawned")
|
||||
|
||||
# Update spawn points
|
||||
print("GameWorld: Client - Updating spawn points...")
|
||||
var host_room = dungeon_sync_metadata.host_room
|
||||
|
||||
Reference in New Issue
Block a user