feat: Implement core game scene logic in main.gd and introduce goals_cycle_manager.gd for managing game goals and cycles.
This commit is contained in:
@@ -214,9 +214,60 @@ 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)
|
||||
if player.is_multiplayer_authority() and not multiplayer.is_server():
|
||||
_handle_local_goal_completion(player, time_remaining)
|
||||
return
|
||||
|
||||
if not multiplayer.is_server():
|
||||
return
|
||||
|
||||
# SERVER LOGIC continues...
|
||||
_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.")
|
||||
|
||||
# Clear playerboard locally
|
||||
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
|
||||
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
|
||||
SfxManager.play("complete_mission")
|
||||
|
||||
@rpc("any_peer")
|
||||
func request_server_goal_completion(time_remaining: float, client_generated_goals: Array):
|
||||
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)
|
||||
|
||||
func _process_goal_completion(player: Node, time_remaining: float, provided_goals: Array = []):
|
||||
"""Internal server-side logic for completion rewards and broadcasting."""
|
||||
# Use name.to_int() for ID because bots share authority 1
|
||||
var peer_id = player.name.to_int()
|
||||
|
||||
@@ -242,18 +293,23 @@ func on_goal_completed(player: Node, time_remaining: float):
|
||||
rpc("sync_player_score", peer_id, player_scores[peer_id])
|
||||
rpc("sync_goal_count", peer_id, player_goal_counts[peer_id])
|
||||
|
||||
# Clear playerboard tiles (they convert to powerup bar reward)
|
||||
# Clear playerboard tiles
|
||||
player.playerboard.fill(-1)
|
||||
# Use main scene's RPC which properly looks up player by ID on each client
|
||||
if main_scene:
|
||||
main_scene.rpc("sync_playerboard", peer_id, player.playerboard)
|
||||
|
||||
# Regenerate goals for this player
|
||||
regenerate_goals_for_player(player)
|
||||
# Regenerate goals for this player (or use provided ones)
|
||||
if provided_goals.size() > 0:
|
||||
player.goals = provided_goals
|
||||
if main_scene:
|
||||
main_scene.rpc("sync_player_goals", peer_id, provided_goals)
|
||||
else:
|
||||
regenerate_goals_for_player(player)
|
||||
|
||||
# Randomize 9 tiles around player
|
||||
# Randomize tiles around player
|
||||
_randomize_tiles_around_player(player)
|
||||
|
||||
# Only play RPC if not already handled locally by that player
|
||||
SfxManager.rpc("play_rpc", "complete_mission")
|
||||
print("[GoalsCycle] Player %d completed goal! +%d points (base: %d, time bonus: %d)" % [peer_id, score_earned, BASE_SCORE, time_bonus])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user