feat: fix some bug
This commit is contained in:
@@ -215,7 +215,9 @@ func sync_cycle_end():
|
||||
func on_goal_completed(player: Node, time_remaining: float):
|
||||
"""Called when a player completes their goal pattern."""
|
||||
|
||||
# 1. LOCAL OPTIMISTIC UPDATE (for smoothness)
|
||||
# CLIENT PATH: clear board immediately for visual responsiveness,
|
||||
# then let server send back the single authoritative new goals.
|
||||
# Do NOT generate goals locally — that caused rollback/blinking.
|
||||
if player.is_multiplayer_authority() and not multiplayer.is_server():
|
||||
_handle_local_goal_completion(player, time_remaining)
|
||||
return
|
||||
@@ -223,48 +225,38 @@ func on_goal_completed(player: Node, time_remaining: float):
|
||||
if not multiplayer.is_server():
|
||||
return
|
||||
|
||||
# SERVER LOGIC continues...
|
||||
# SERVER LOGIC
|
||||
_process_goal_completion(player, time_remaining)
|
||||
|
||||
func _handle_local_goal_completion(player: Node, time_remaining: float):
|
||||
print("[GoalsCycle] Client: Handling goal completion locally for smoothness.")
|
||||
print("[GoalsCycle] Client: Goal completed — clearing board and requesting server sync.")
|
||||
|
||||
# Clear playerboard locally
|
||||
# Clear playerboard locally for immediate visual feedback (empty board)
|
||||
player.playerboard.fill(-1)
|
||||
|
||||
# Generate new goals locally (optimistic)
|
||||
var new_goals = GoalManager.initialize_random_goals(9, 7, 10, 1.0)
|
||||
var int_goals: Array[int] = []
|
||||
for g in new_goals:
|
||||
int_goals.append(g)
|
||||
player.goals = int_goals
|
||||
|
||||
# Update UI immediately
|
||||
# Update UI immediately so the board shows empty rather than stale
|
||||
if main_scene and main_scene.ui_manager:
|
||||
main_scene.ui_manager.update_playerboard_ui()
|
||||
|
||||
# Notify server to sync score and broadcast to others
|
||||
rpc_id(1, "request_server_goal_completion", time_remaining, int_goals)
|
||||
|
||||
# Visual/Sfx
|
||||
# Play sound locally — server will also trigger it, but client plays first for responsiveness
|
||||
SfxManager.play("complete_mission")
|
||||
|
||||
# Notify server — server will validate, award score, and broadcast authoritative new goals
|
||||
rpc_id(1, "request_server_goal_completion", time_remaining)
|
||||
|
||||
@rpc("any_peer")
|
||||
func request_server_goal_completion(time_remaining: float, client_generated_goals: Array):
|
||||
if not multiplayer.is_server(): return
|
||||
func request_server_goal_completion(time_remaining: float):
|
||||
"""Client notifies server of goal completion. Server validates, awards score,
|
||||
and broadcasts authoritative new goals back to all peers."""
|
||||
if not multiplayer.is_server():
|
||||
return
|
||||
|
||||
var sender_id = multiplayer.get_remote_sender_id()
|
||||
# Bots call it locally, so sender_id might be 1 or 0
|
||||
if sender_id == 0: sender_id = 1
|
||||
|
||||
var player_node = main_scene.get_node_or_null(str(sender_id))
|
||||
if player_node:
|
||||
# Use provided goals from client to ensure sync
|
||||
var int_goals: Array[int] = []
|
||||
for g in client_generated_goals: int_goals.append(g)
|
||||
|
||||
# Process completion with provided goals
|
||||
_process_goal_completion(player_node, time_remaining, int_goals)
|
||||
_process_goal_completion(player_node, time_remaining)
|
||||
|
||||
func _process_goal_completion(player: Node, time_remaining: float, provided_goals: Array = []):
|
||||
"""Internal server-side logic for completion rewards and broadcasting."""
|
||||
|
||||
Reference in New Issue
Block a user