fix missing character model

This commit is contained in:
2025-02-20 11:29:03 +08:00
parent f9e0c81aee
commit 276aa439ab
2 changed files with 125 additions and 29 deletions
+92 -28
View File
@@ -325,41 +325,76 @@ func _on_peer_connected(new_peer_id):
# Increase delay to ensure scene is ready
await get_tree().create_timer(1.5).timeout
# Sync full state first
# First sync game state
rpc_id(new_peer_id, "sync_game_state", players, bots, game_started, turn_based_mode)
rpc_id(new_peer_id, "sync_preset_goals", preset_goals)
# Then add players in correct order
for peer_id in players:
if peer_id != new_peer_id: # Don't add the new player yet
rpc_id(new_peer_id, "add_player_character", peer_id)
# Sync existing player's goals immediately
# Wait a bit for the client to process state
await get_tree().create_timer(0.5).timeout
# Then sync all existing players in order
var sorted_players = players.duplicate()
sorted_players.sort()
for peer_id in sorted_players:
if peer_id != new_peer_id:
# First ensure player exists
var player = get_node_or_null(str(peer_id))
if player:
rpc_id(new_peer_id, "sync_player_goals", peer_id, player.goals)
# Sync player's full state
var player_data = {
"position": player.current_position,
"goals": player.goals,
"playerboard": player.playerboard
}
rpc_id(new_peer_id, "sync_existing_player", peer_id, player_data)
await get_tree().create_timer(0.1).timeout # Small delay between players
# Finally add the new player
await get_tree().create_timer(0.5).timeout
add_player_character(new_peer_id)
rpc("add_newly_connected_player_character", new_peer_id)
# Get next available bot ID and replace it
# Replace bot if needed
if bots.size() > 0:
replace_bot_with_player(new_peer_id)
# Force sync all players' goals to everyone
for player in get_tree().get_nodes_in_group("Players"):
var player_id = String(player.name).to_int()
rpc("sync_player_goals", player_id, player.goals)
# Update everyone's UI
# Final sync of all goals
await get_tree().create_timer(0.5).timeout
rpc("force_update_all_goals")
@rpc("call_local")
func force_update_all_goals():
# Force update the UI for all players
update_all_players_goals()
@rpc("reliable")
func sync_existing_player(peer_id: int, player_data: Dictionary):
# Create player if doesn't exist
if not has_node(str(peer_id)):
var player_character = player_scene.instantiate()
player_character.set_multiplayer_authority(peer_id)
player_character.name = str(peer_id)
player_character.current_position = player_data["position"]
add_child(player_character)
player_character.add_to_group("Players", true)
# Also update the boards
update_all_players_boards()
# Get player node and wait a frame to ensure it's ready
await get_tree().create_timer(0.1).timeout
var player = get_node_or_null(str(peer_id))
if player:
# Apply synced state
player.current_position = player_data["position"]
player.goals = player_data["goals"].duplicate()
player.playerboard = player_data["playerboard"].duplicate()
# Ensure proper grid-aligned positioning
player.global_position = Vector3(
player_data["position"].x * 2 + 1, # cell_size.x = 2
1.0,
player_data["position"].y * 2 + 1 # cell_size.z = 2
)
# Force position sync
player.rpc("sync_position", player_data["position"])
# Update UI
update_all_players_goals()
update_all_players_boards()
func _on_peer_disconnected(peer_id):
if multiplayer.is_server():
@@ -369,17 +404,35 @@ func _on_peer_disconnected(peer_id):
@rpc("any_peer", "call_local")
func add_player_character(peer_id):
# Check if player already exists
if has_node(str(peer_id)):
return
connected_peer_ids.append(peer_id)
var player_character = player_scene.instantiate()
player_character.set_multiplayer_authority(peer_id)
player_character.name = str(peer_id)
# Handle bot replacement position
if multiplayer.is_server() and bots.size() > 0:
var bot_to_replace = get_node_or_null(str(bots[0]))
if bot_to_replace:
player_character.current_position = bot_to_replace.current_position
# Set initial grid-aligned position
player_character.global_position = Vector3(
bot_to_replace.current_position.x * 2 + 1,
1.0,
bot_to_replace.current_position.y * 2 + 1
)
add_child(player_character)
player_character.add_to_group("Players", true)
# Force position sync after adding to tree
if multiplayer.is_server():
await get_tree().create_timer(0.1).timeout
player_character.rpc("sync_position", player_character.current_position)
# Set goals based on player ID if server
if multiplayer.is_server():
var goal_index = peer_id - 1
@@ -620,13 +673,12 @@ func update_all_players_boards():
# Board 1 should show host (server)
var host_player = null
# Find host player (ID 1)
for player in all_players:
if int(String(player.name)) == 1:
host_player = player
break
# Update host board
# Update host board (board 1)
var host_board = all_player_boards.get_node("1")
if host_player and host_board and host_board.has_node("PlayerboardUI"):
host_board.visible = true
@@ -634,22 +686,34 @@ func update_all_players_boards():
for slot_idx in range(25):
update_board_slot(board_ui, slot_idx, host_player.playerboard[slot_idx])
# Sort remaining players by ID for boards 2-4
var other_players = all_players.filter(func(p): return int(String(p.name)) != 1)
other_players.sort_custom(func(a, b): return int(String(a.name)) < int(String(b.name)))
# Sort remaining players by ID for boards 2,3,4
var other_players = all_players.filter(func(p):
var id = int(String(p.name))
return id != 1 and not p.is_in_group("Bots") # Exclude host and bots
)
other_players.sort_custom(func(a, b):
return int(String(a.name)) < int(String(b.name))
)
# Update boards 2-4 with remaining players
# Update client boards - board 2 for first client, board 3 for second client, etc.
for i in range(min(other_players.size(), 3)):
var board_num = i + 2 # boards 2,3,4
var board_idx = i + 2 # Start from board 2
var player = other_players[i]
var board = all_player_boards.get_node(str(board_num))
var board = all_player_boards.get_node(str(board_idx))
if board and board.has_node("PlayerboardUI"):
board.visible = true
board.name = str(board_idx) # Ensure board name matches index
var board_ui = board.get_node("PlayerboardUI")
for slot_idx in range(25):
update_board_slot(board_ui, slot_idx, player.playerboard[slot_idx])
# Hide unused boards
for i in range(other_players.size() + 2, 5):
var unused_board = all_player_boards.get_node_or_null(str(i))
if unused_board:
unused_board.visible = false
# Restore previous active tab
all_player_boards.current_tab = current_tab