feat: Add core player entity with movement, race, input, character selection, and multiplayer synchronization, integrating various game managers.
This commit is contained in:
@@ -105,21 +105,20 @@ func _update_hud_visuals():
|
||||
red_tint_overlay.visible = (current_phase == Phase.STOP)
|
||||
|
||||
var my_id = multiplayer.get_unique_id()
|
||||
if mission_label and player_missions.has(my_id):
|
||||
var mission = player_missions[my_id]
|
||||
# Get Icon name or ID for display
|
||||
var tile_name = "Items"
|
||||
match mission["target_tile"]:
|
||||
7: tile_name = "Hearts"
|
||||
8: tile_name = "Diamonds"
|
||||
9: tile_name = "Stars"
|
||||
10: tile_name = "Coins"
|
||||
|
||||
mission_label.text = "Collect %d %s: %d / %d" % [mission["required"], tile_name, mission["current"], mission["required"]]
|
||||
if mission_label:
|
||||
var main = get_node_or_null("/root/Main")
|
||||
var goals_cycle_manager = main.get_node_or_null("GoalsCycleManager") if main else null
|
||||
|
||||
if mission["current"] >= mission["required"]:
|
||||
mission_label.text = "MISSION COMPLETE! REACH FINISH!"
|
||||
# Get count from GoalsCycleManager (Source of truth for PlayerBoardLabel)
|
||||
var completed_count = goals_cycle_manager.player_goal_counts.get(my_id, 0) if goals_cycle_manager else 0
|
||||
|
||||
mission_label.text = "GOALS (%d/3)" % completed_count
|
||||
|
||||
if completed_count >= 3:
|
||||
mission_label.text = "ALL GOALS COMPLETE!\nREACH THE FINISH!"
|
||||
mission_label.add_theme_color_override("font_color", Color.GOLD)
|
||||
else:
|
||||
mission_label.add_theme_color_override("font_color", Color.WHITE)
|
||||
|
||||
func activate_client_side():
|
||||
is_active = true
|
||||
@@ -284,22 +283,9 @@ func _spawn_mission_tiles():
|
||||
count += 1
|
||||
|
||||
func _assign_missions():
|
||||
# Assign UNIQUE target tile types to players cyclicly
|
||||
var players = GameStateManager.players
|
||||
var tile_types = [ScarcityModel.TILE_HEART, ScarcityModel.TILE_DIAMOND, ScarcityModel.TILE_STAR, ScarcityModel.TILE_COIN]
|
||||
|
||||
var idx = 0
|
||||
for p_id in players:
|
||||
var target = tile_types[idx % tile_types.size()]
|
||||
player_missions[p_id] = {
|
||||
"target_tile": target,
|
||||
"required": 3,
|
||||
"current": 0
|
||||
}
|
||||
idx += 1
|
||||
|
||||
if can_rpc():
|
||||
rpc("sync_missions", player_missions)
|
||||
# NO-OP: Missions are now achievement-based (Complete 3 Goals)
|
||||
# which is tracked natively by GoalsCycleManager.
|
||||
pass
|
||||
|
||||
@rpc("authority", "call_local", "reliable")
|
||||
func sync_missions(missions: Dictionary):
|
||||
@@ -338,38 +324,38 @@ func _penalize_player(player_id: int):
|
||||
# Notification is also handled inside on_stop_phase_violation on the player node
|
||||
emit_signal("player_penalized", player_id)
|
||||
|
||||
func update_mission_progress(player_id: int, tile_id: int):
|
||||
if not player_missions.has(player_id): return
|
||||
|
||||
var mission = player_missions[player_id]
|
||||
if tile_id == mission["target_tile"]:
|
||||
mission["current"] = min(mission["current"] + 1, mission["required"])
|
||||
|
||||
if mission["current"] >= mission["required"]:
|
||||
emit_signal("mission_status_updated", player_id, true)
|
||||
|
||||
# FIX: NotificationManager.send_message_to_player() does NOT exist.
|
||||
# We need to find the player node and use send_message(target, msg, type)
|
||||
var main = get_node("/root/Main")
|
||||
if main:
|
||||
var player_node = main.get_node_or_null(str(player_id))
|
||||
if player_node:
|
||||
NotificationManager.send_message(player_node, "Mission Complete! Reach the Finish!", NotificationManager.MessageType.GOAL)
|
||||
|
||||
if multiplayer.is_server() and can_rpc():
|
||||
rpc("sync_mission_progress", player_id, mission["current"])
|
||||
func update_mission_progress(_player_id: int, _tile_id: int):
|
||||
# Redundant in Board-based mode, but kept for compatibility.
|
||||
# The board is synced separately via sync_playerboard in playerboard_manager.gd.
|
||||
pass
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func sync_mission_progress(player_id: int, current: int):
|
||||
if player_missions.has(player_id):
|
||||
player_missions[player_id]["current"] = current
|
||||
func sync_mission_progress(_player_id: int, _mission_index: int, _current: int):
|
||||
# Deprecated
|
||||
pass
|
||||
|
||||
func check_win_condition(player_id: int, position: Vector2i) -> bool:
|
||||
if not player_missions.has(player_id): return false
|
||||
# 1. Must reach the finish line (Column 21)
|
||||
if position.x < finish_line_x:
|
||||
return false
|
||||
|
||||
# 2. Must have 3 Goal Completions (tracked by GoalsCycleManager)
|
||||
var main = get_node_or_null("/root/Main")
|
||||
if not main: return false
|
||||
|
||||
var mission = player_missions[player_id]
|
||||
if mission["current"] >= mission["required"]:
|
||||
# Win when reaching X >= 21
|
||||
if position.x >= finish_line_x:
|
||||
return true
|
||||
return false
|
||||
var goals_cycle_manager = main.get_node_or_null("GoalsCycleManager")
|
||||
if not goals_cycle_manager: return false
|
||||
|
||||
var completed_count = goals_cycle_manager.player_goal_counts.get(player_id, 0)
|
||||
|
||||
if completed_count >= 3:
|
||||
print("[StopNGo] Player %d REACHED FINISH with %d goals complete!" % [player_id, completed_count])
|
||||
return true
|
||||
else:
|
||||
# Inform the player locally if they reach the end without goals
|
||||
var player_node = main.get_node_or_null(str(player_id))
|
||||
if player_node:
|
||||
NotificationManager.send_message(player_node, "Incomplete! Achieve 3 goals (x3) to win!", NotificationManager.MessageType.WARNING)
|
||||
|
||||
print("[StopNGo] Player %d reached finish but goal count too low: %d/3" % [player_id, completed_count])
|
||||
return false
|
||||
|
||||
Reference in New Issue
Block a user