Update
This commit is contained in:
@@ -5,3 +5,5 @@
|
|||||||
/android/
|
/android/
|
||||||
.tmp
|
.tmp
|
||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
|
daily_report_2024-12-04.md
|
||||||
|
daily_report_2025-12-06.md
|
||||||
|
|||||||
+7
-7
@@ -595,13 +595,13 @@ func create_specific_player(data: Dictionary):
|
|||||||
if playerboard_to_set.size() > 0 and player_character.race_manager:
|
if playerboard_to_set.size() > 0 and player_character.race_manager:
|
||||||
player_character.playerboard = playerboard_to_set
|
player_character.playerboard = playerboard_to_set
|
||||||
|
|
||||||
# Update position if not already set
|
# Always update position (including for existing nodes, so client sees host correctly)
|
||||||
if not node_already_exists:
|
player_character.current_position = data["position"]
|
||||||
player_character.global_position = Vector3(
|
player_character.global_position = Vector3(
|
||||||
data["position"].x * 2 + 1,
|
data["position"].x * 2 + 1,
|
||||||
1.0,
|
1.0,
|
||||||
data["position"].y * 2 + 1
|
data["position"].y * 2 + 1
|
||||||
)
|
)
|
||||||
|
|
||||||
# Update playerboard UI for local player
|
# Update playerboard UI for local player
|
||||||
if is_local_player:
|
if is_local_player:
|
||||||
|
|||||||
+21
-7
@@ -355,9 +355,10 @@ func _physics_process(delta):
|
|||||||
rpc("remote_set_position", global_position)
|
rpc("remote_set_position", global_position)
|
||||||
last_sent_position = global_position
|
last_sent_position = global_position
|
||||||
|
|
||||||
# Add continuous finish line check
|
# Add continuous finish line check (uses lap-aware finish locations)
|
||||||
if race_manager and current_position in race_manager.finish_locations and can_finish and not is_player_moving:
|
var current_finish = race_manager.get_current_finish_locations() if race_manager else []
|
||||||
start_new_lap()
|
if race_manager and current_position in current_finish and can_finish and not is_player_moving:
|
||||||
|
finish_race() # This handles lap increment and calls start_new_lap properly
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# Input
|
# Input
|
||||||
@@ -536,14 +537,15 @@ func start_movement_along_path(path: Array, clear_visual: bool = true):
|
|||||||
tween.set_ease(Tween.EASE_IN_OUT)
|
tween.set_ease(Tween.EASE_IN_OUT)
|
||||||
|
|
||||||
for point in path:
|
for point in path:
|
||||||
tween.tween_property(self, "position", grid_to_world(Vector2i(point.x, point.y)), 0.5)
|
tween.tween_property(self, "position", grid_to_world(Vector2i(point.x, point.y)), 0.25)
|
||||||
|
|
||||||
tween.tween_callback(func():
|
tween.tween_callback(func():
|
||||||
current_position = Vector2i(path[-1].x, path[-1].y)
|
current_position = Vector2i(path[-1].x, path[-1].y)
|
||||||
is_player_moving = false
|
is_player_moving = false
|
||||||
|
|
||||||
# Check if we've reached the finish line
|
# Check if we've reached the finish line (uses lap-aware finish locations)
|
||||||
if current_position in finish_locations and can_finish:
|
var current_finish_locs = race_manager.get_current_finish_locations() if race_manager else finish_locations
|
||||||
|
if current_position in current_finish_locs and can_finish:
|
||||||
finish_race()
|
finish_race()
|
||||||
|
|
||||||
var main = get_tree().get_root().get_node_or_null("Main")
|
var main = get_tree().get_root().get_node_or_null("Main")
|
||||||
@@ -1030,6 +1032,12 @@ func sync_grid_item(x: int, y: int, z: int, item: int):
|
|||||||
func sync_goals(new_goals: Array):
|
func sync_goals(new_goals: Array):
|
||||||
goals = new_goals.duplicate() # Make sure to duplicate the array
|
goals = new_goals.duplicate() # Make sure to duplicate the array
|
||||||
|
|
||||||
|
# Also update race_manager's goals directly
|
||||||
|
if race_manager:
|
||||||
|
race_manager.goals = new_goals.duplicate()
|
||||||
|
# Re-check finish availability with new goals
|
||||||
|
race_manager.update_finish_availability()
|
||||||
|
|
||||||
# Update the AllPlayerGoals UI
|
# Update the AllPlayerGoals UI
|
||||||
var main = get_tree().get_root().get_node_or_null("Main")
|
var main = get_tree().get_root().get_node_or_null("Main")
|
||||||
if main and main.has_method("_update_goals_ui_for_player"):
|
if main and main.has_method("_update_goals_ui_for_player"):
|
||||||
@@ -1053,7 +1061,8 @@ func _after_action_completed():
|
|||||||
action_manager.after_action_completed()
|
action_manager.after_action_completed()
|
||||||
|
|
||||||
func is_finish_position(pos: Vector2i) -> bool:
|
func is_finish_position(pos: Vector2i) -> bool:
|
||||||
return pos in finish_locations
|
var current_finish = race_manager.get_current_finish_locations() if race_manager else finish_locations
|
||||||
|
return pos in current_finish
|
||||||
|
|
||||||
func consume_action_points(points: int):
|
func consume_action_points(points: int):
|
||||||
action_manager.consume_action_points(points)
|
action_manager.consume_action_points(points)
|
||||||
@@ -1092,3 +1101,8 @@ func sync_position(pos: Vector2i):
|
|||||||
|
|
||||||
func highlight_valid_obstacle_cells():
|
func highlight_valid_obstacle_cells():
|
||||||
action_manager.highlight_valid_obstacle_cells()
|
action_manager.highlight_valid_obstacle_cells()
|
||||||
|
|
||||||
|
@rpc("any_peer", "call_local", "reliable")
|
||||||
|
func complete_race(final_position: int):
|
||||||
|
if race_manager:
|
||||||
|
race_manager.on_race_completed(final_position)
|
||||||
|
|||||||
@@ -8,15 +8,16 @@ var current_lap: int = 0
|
|||||||
var first_lap_goals: Array[int] = []
|
var first_lap_goals: Array[int] = []
|
||||||
var second_lap_goals: Array[int] = []
|
var second_lap_goals: Array[int] = []
|
||||||
var race_position: int = 0
|
var race_position: int = 0
|
||||||
|
var has_finished_race: bool = false
|
||||||
static var lap1_finishers: int = 0
|
static var lap1_finishers: int = 0
|
||||||
static var lap2_finishers: int = 0
|
static var lap2_finishers: int = 0
|
||||||
|
|
||||||
# Goals and Playerboard
|
# Goals and Playerboard
|
||||||
var goals: Array[int] = [0,0,0,0,0,0,0,0,0]
|
var goals: Array[int] = [0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
var playerboard: Array[int] = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
var playerboard: Array[int] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
var can_finish: bool = false
|
var can_finish: bool = false
|
||||||
|
|
||||||
# Finish locations (copied from player.gd)
|
# Finish locations (right side for 1st lap)
|
||||||
var finish_locations = [
|
var finish_locations = [
|
||||||
Vector2i(13, 0), Vector2i(13, 1), Vector2i(13, 2), Vector2i(13, 3),
|
Vector2i(13, 0), Vector2i(13, 1), Vector2i(13, 2), Vector2i(13, 3),
|
||||||
Vector2i(13, 4), Vector2i(13, 5), Vector2i(13, 6), Vector2i(13, 7),
|
Vector2i(13, 4), Vector2i(13, 5), Vector2i(13, 6), Vector2i(13, 7),
|
||||||
@@ -24,6 +25,21 @@ var finish_locations = [
|
|||||||
Vector2i(13, 12), Vector2i(13, 13)
|
Vector2i(13, 12), Vector2i(13, 13)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Spawn locations (left side for 2nd lap finish)
|
||||||
|
var spawn_locations = [
|
||||||
|
Vector2i(0, 0), Vector2i(0, 1), Vector2i(0, 2), Vector2i(0, 3),
|
||||||
|
Vector2i(0, 4), Vector2i(0, 5), Vector2i(0, 6), Vector2i(0, 7),
|
||||||
|
Vector2i(0, 8), Vector2i(0, 9), Vector2i(0, 10), Vector2i(0, 11),
|
||||||
|
Vector2i(0, 12), Vector2i(0, 13)
|
||||||
|
]
|
||||||
|
|
||||||
|
# Helper function to get current finish locations based on lap
|
||||||
|
func get_current_finish_locations() -> Array:
|
||||||
|
if current_lap == 0:
|
||||||
|
return finish_locations # 1st lap: finish at right side
|
||||||
|
else:
|
||||||
|
return spawn_locations # 2nd lap: finish at left side (spawn locations)
|
||||||
|
|
||||||
func initialize(p_player: Node3D, p_gridmap: Node):
|
func initialize(p_player: Node3D, p_gridmap: Node):
|
||||||
player = p_player
|
player = p_player
|
||||||
enhanced_gridmap = p_gridmap
|
enhanced_gridmap = p_gridmap
|
||||||
@@ -100,7 +116,8 @@ func update_finish_availability():
|
|||||||
func highlight_finish_line():
|
func highlight_finish_line():
|
||||||
if not player.is_multiplayer_authority() or player.is_bot:
|
if not player.is_multiplayer_authority() or player.is_bot:
|
||||||
return
|
return
|
||||||
for finish_pos in finish_locations:
|
var current_finish = get_current_finish_locations()
|
||||||
|
for finish_pos in current_finish:
|
||||||
if enhanced_gridmap:
|
if enhanced_gridmap:
|
||||||
enhanced_gridmap.set_cell_item(
|
enhanced_gridmap.set_cell_item(
|
||||||
Vector3i(finish_pos.x, 0, finish_pos.y),
|
Vector3i(finish_pos.x, 0, finish_pos.y),
|
||||||
@@ -110,7 +127,8 @@ func highlight_finish_line():
|
|||||||
func unhighlight_finish_line():
|
func unhighlight_finish_line():
|
||||||
if not player.is_multiplayer_authority() or player.is_bot:
|
if not player.is_multiplayer_authority() or player.is_bot:
|
||||||
return
|
return
|
||||||
for finish_pos in finish_locations:
|
var current_finish = get_current_finish_locations()
|
||||||
|
for finish_pos in current_finish:
|
||||||
if enhanced_gridmap:
|
if enhanced_gridmap:
|
||||||
enhanced_gridmap.set_cell_item(
|
enhanced_gridmap.set_cell_item(
|
||||||
Vector3i(finish_pos.x, 0, finish_pos.y),
|
Vector3i(finish_pos.x, 0, finish_pos.y),
|
||||||
@@ -118,7 +136,8 @@ func unhighlight_finish_line():
|
|||||||
)
|
)
|
||||||
|
|
||||||
func is_at_finish_line() -> bool:
|
func is_at_finish_line() -> bool:
|
||||||
return player.current_position in finish_locations
|
var current_finish = get_current_finish_locations()
|
||||||
|
return player.current_position in current_finish
|
||||||
|
|
||||||
func finish_race():
|
func finish_race():
|
||||||
if current_lap == 0:
|
if current_lap == 0:
|
||||||
@@ -129,32 +148,55 @@ func finish_race():
|
|||||||
player.rpc("display_message", message)
|
player.rpc("display_message", message)
|
||||||
|
|
||||||
current_lap += 1
|
current_lap += 1
|
||||||
player.rpc("start_new_lap")
|
start_new_lap()
|
||||||
|
|
||||||
elif current_lap == 1:
|
elif current_lap == 1:
|
||||||
lap2_finishers += 1
|
lap2_finishers += 1
|
||||||
race_position = lap2_finishers
|
race_position = lap2_finishers
|
||||||
var message = "Finish 2nd lap on " + get_ordinal_string(race_position)
|
var message = "RACE COMPLETE! Finished " + get_ordinal_string(race_position)
|
||||||
if player.is_multiplayer_authority():
|
if player.is_multiplayer_authority():
|
||||||
player.rpc("display_message", message)
|
player.rpc("display_message", message)
|
||||||
|
player.rpc("complete_race", race_position)
|
||||||
|
|
||||||
|
# Called when player finishes the entire race (2nd lap complete)
|
||||||
|
func on_race_completed(final_position: int):
|
||||||
|
has_finished_race = true
|
||||||
|
race_position = final_position
|
||||||
|
can_finish = false
|
||||||
|
|
||||||
|
# Disable all player input
|
||||||
|
player.set_process_input(false)
|
||||||
|
player.set_process_unhandled_input(false)
|
||||||
|
player.is_my_turn = false
|
||||||
|
player.action_points = 0
|
||||||
|
|
||||||
|
# Clear any highlights
|
||||||
|
if player.action_manager:
|
||||||
|
player.action_manager.clear_highlights()
|
||||||
|
player.action_manager.clear_playerboard_highlights()
|
||||||
|
|
||||||
|
# Unhighlight finish line
|
||||||
|
unhighlight_finish_line()
|
||||||
|
|
||||||
|
print("Player %s finished the race in position %d!" % [player.name, final_position])
|
||||||
|
|
||||||
func start_new_lap():
|
func start_new_lap():
|
||||||
if current_lap == 1:
|
if current_lap == 1:
|
||||||
var valid_finish_pos = find_valid_position_in_finish_line()
|
# Update goals to 2nd lap goals
|
||||||
if valid_finish_pos != Vector2i(-1, -1):
|
|
||||||
player.current_position = valid_finish_pos
|
|
||||||
player.update_player_position(player.current_position)
|
|
||||||
|
|
||||||
goals = second_lap_goals.duplicate()
|
goals = second_lap_goals.duplicate()
|
||||||
can_finish = false
|
can_finish = false
|
||||||
|
|
||||||
|
# Sync with all clients
|
||||||
if player.is_multiplayer_authority():
|
if player.is_multiplayer_authority():
|
||||||
player.rpc("sync_position", player.current_position)
|
player.rpc("sync_position", player.current_position)
|
||||||
player.rpc("sync_playerboard", playerboard)
|
player.rpc("sync_playerboard", playerboard)
|
||||||
player.rpc("sync_goals", goals)
|
player.rpc("sync_goals", goals)
|
||||||
|
|
||||||
|
print("Started 2nd lap with new goals: ", goals)
|
||||||
|
|
||||||
func find_valid_position_in_finish_line() -> Vector2i:
|
func find_valid_position_in_finish_line() -> Vector2i:
|
||||||
for pos in finish_locations:
|
var current_finish = get_current_finish_locations()
|
||||||
|
for pos in current_finish:
|
||||||
if not player.is_position_occupied(pos):
|
if not player.is_position_occupied(pos):
|
||||||
return pos
|
return pos
|
||||||
return Vector2i(-1, -1)
|
return Vector2i(-1, -1)
|
||||||
|
|||||||
@@ -48,15 +48,29 @@ func grab_item(grid_position: Vector2i) -> bool:
|
|||||||
if not player.is_multiplayer_authority():
|
if not player.is_multiplayer_authority():
|
||||||
return false
|
return false
|
||||||
|
|
||||||
# === Branching Logic: Host vs Client ===
|
# === Optimistic Local Update (immediate visual feedback) ===
|
||||||
|
# Apply changes locally first, server will validate/sync
|
||||||
|
enhanced_gridmap.set_cell_item(cell, -1) # Remove item visually immediately
|
||||||
|
player.playerboard[target_slot] = item # Add to playerboard immediately
|
||||||
|
|
||||||
|
# Update UI immediately for responsiveness
|
||||||
|
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||||
|
if main and main.ui_manager:
|
||||||
|
main.ui_manager.update_playerboard_ui()
|
||||||
|
|
||||||
|
# === Server Sync ===
|
||||||
if multiplayer.is_server():
|
if multiplayer.is_server():
|
||||||
# HOST/SERVER: Call the logic directly
|
# HOST/SERVER: Broadcast to all clients
|
||||||
_execute_grab(grid_position, cell, item)
|
main.rpc("sync_grid_item", cell.x, cell.y, cell.z, -1)
|
||||||
|
player.rpc("sync_playerboard", player.playerboard)
|
||||||
|
player.has_performed_action = true
|
||||||
|
player.consume_action_points(1)
|
||||||
|
player.rpc("force_action_state_none")
|
||||||
else:
|
else:
|
||||||
# CLIENT: Send RPC request to server (peer 1)
|
# CLIENT: Send RPC request to server for validation
|
||||||
player.rpc_id(1, "request_server_grab", grid_position, cell.x, cell.y, cell.z, item)
|
player.rpc_id(1, "request_server_grab", grid_position, cell.x, cell.y, cell.z, item)
|
||||||
|
|
||||||
return true # Request was sent or processed
|
return true # Action applied locally
|
||||||
|
|
||||||
func _execute_grab(grid_pos: Vector2i, cell: Vector3i, item_id: int):
|
func _execute_grab(grid_pos: Vector2i, cell: Vector3i, item_id: int):
|
||||||
var main = player.get_tree().get_root().get_node_or_null("Main")
|
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||||
@@ -178,10 +192,10 @@ func auto_put_item() -> bool:
|
|||||||
if valid_put_positions.is_empty():
|
if valid_put_positions.is_empty():
|
||||||
return false
|
return false
|
||||||
|
|
||||||
# Step 2: Find a tile that should NOT be on the board
|
# Step 2: Find a tile that should NOT be on the board (prioritize non-goal items)
|
||||||
var put_slot = -1
|
var put_slot = -1
|
||||||
|
|
||||||
# Count how many times each goal item appears in central 3x3
|
# Count how many times each goal item is needed in the goals
|
||||||
var goal_counts = {}
|
var goal_counts = {}
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
for j in range(3):
|
for j in range(3):
|
||||||
@@ -189,31 +203,18 @@ func auto_put_item() -> bool:
|
|||||||
if g != -1:
|
if g != -1:
|
||||||
goal_counts[g] = goal_counts.get(g, 0) + 1
|
goal_counts[g] = goal_counts.get(g, 0) + 1
|
||||||
|
|
||||||
# Now scan playerboard
|
# Priority 1: Find items that are NOT in goals at all (junk tiles)
|
||||||
for i in range(player.playerboard.size()):
|
for i in range(player.playerboard.size()):
|
||||||
var current_item = player.playerboard[i]
|
var current_item = player.playerboard[i]
|
||||||
if current_item == -1:
|
if current_item == -1:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Case 1: Item is not in goals at all → definitely junk
|
# Item is not in goals at all → definitely junk, put this first
|
||||||
if not current_item in player.goals:
|
if not current_item in player.goals:
|
||||||
put_slot = i
|
put_slot = i
|
||||||
break
|
break
|
||||||
|
|
||||||
# Case 2: Item is in goals, but we already have enough in correct spots
|
# Priority 2: Find items outside central 3x3 OR items in central 3x3 that don't match goal position
|
||||||
var current_count = 0
|
|
||||||
for r in range(1, 4): # central rows 1-3 (5x5 board)
|
|
||||||
for c in range(1, 4): # central cols 1-3
|
|
||||||
var idx = r * 5 + c
|
|
||||||
if player.playerboard[idx] == current_item:
|
|
||||||
current_count += 1
|
|
||||||
|
|
||||||
# If we already have all needed copies in central area, this is extra
|
|
||||||
if current_count >= goal_counts.get(current_item, 0):
|
|
||||||
put_slot = i
|
|
||||||
break
|
|
||||||
|
|
||||||
# If no junk found, fall back to any non-goal-matching tile outside center
|
|
||||||
if put_slot == -1:
|
if put_slot == -1:
|
||||||
for i in range(player.playerboard.size()):
|
for i in range(player.playerboard.size()):
|
||||||
var board_item = player.playerboard[i]
|
var board_item = player.playerboard[i]
|
||||||
@@ -221,31 +222,75 @@ func auto_put_item() -> bool:
|
|||||||
continue
|
continue
|
||||||
var row = i / 5
|
var row = i / 5
|
||||||
var col = i % 5
|
var col = i % 5
|
||||||
# If it's outside the central 3x3, it shouldn't be there
|
|
||||||
|
# If it's outside the central 3x3, it's potentially movable
|
||||||
if row < 1 or row > 3 or col < 1 or col > 3:
|
if row < 1 or row > 3 or col < 1 or col > 3:
|
||||||
if not board_item in player.goals or player.playerboard[i] != player.goals[(row - 1) * 3 + (col - 1)]:
|
put_slot = i
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# It's inside central 3x3 - check if it matches the corresponding goal position
|
||||||
|
var goal_row = row - 1
|
||||||
|
var goal_col = col - 1
|
||||||
|
var expected_goal = player.goals[goal_row * 3 + goal_col]
|
||||||
|
# If the item doesn't match what should be in this goal position, it's misplaced
|
||||||
|
if board_item != expected_goal and expected_goal != -1:
|
||||||
put_slot = i
|
put_slot = i
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# Priority 3: Find excess goal items (we have more than needed in central area)
|
||||||
|
if put_slot == -1:
|
||||||
|
for i in range(player.playerboard.size()):
|
||||||
|
var current_item = player.playerboard[i]
|
||||||
|
if current_item == -1:
|
||||||
|
continue
|
||||||
|
if not current_item in player.goals:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Count how many of this item we have in the correct central positions
|
||||||
|
var correctly_placed_count = 0
|
||||||
|
for goal_row in range(3):
|
||||||
|
for goal_col in range(3):
|
||||||
|
if player.goals[goal_row * 3 + goal_col] == current_item:
|
||||||
|
var board_idx = (goal_row + 1) * 5 + (goal_col + 1)
|
||||||
|
if player.playerboard[board_idx] == current_item:
|
||||||
|
correctly_placed_count += 1
|
||||||
|
|
||||||
|
# Count total of this item on the board
|
||||||
|
var total_count = 0
|
||||||
|
for board_item in player.playerboard:
|
||||||
|
if board_item == current_item:
|
||||||
|
total_count += 1
|
||||||
|
|
||||||
|
# If we have all needed copies already correctly placed, extras can go
|
||||||
|
if correctly_placed_count >= goal_counts.get(current_item, 0) and total_count > correctly_placed_count:
|
||||||
|
put_slot = i
|
||||||
|
break
|
||||||
|
|
||||||
if put_slot == -1:
|
if put_slot == -1:
|
||||||
return false # Nothing suitable to put
|
return false # Nothing suitable to put
|
||||||
|
|
||||||
# Step 3: Perform the put
|
# Step 3: Perform the put with optimistic local update
|
||||||
var target_pos = valid_put_positions[0]
|
var target_pos = valid_put_positions[0]
|
||||||
var item = player.playerboard[put_slot]
|
var item = player.playerboard[put_slot]
|
||||||
var cell = Vector3i(target_pos.x, 1, target_pos.y)
|
var cell = Vector3i(target_pos.x, 1, target_pos.y)
|
||||||
|
|
||||||
if player.is_multiplayer_authority():
|
if player.is_multiplayer_authority():
|
||||||
|
# === Optimistic Local Update (immediate visual feedback) ===
|
||||||
|
enhanced_gridmap.set_cell_item(cell, item) # Add item to grid visually immediately
|
||||||
|
player.playerboard[put_slot] = -1 # Remove from playerboard immediately
|
||||||
|
|
||||||
|
# Update UI immediately for responsiveness
|
||||||
|
var main = player.get_tree().get_root().get_node_or_null("Main")
|
||||||
|
if main and main.ui_manager:
|
||||||
|
main.ui_manager.update_playerboard_ui()
|
||||||
|
main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE
|
||||||
|
|
||||||
|
# === Server Sync ===
|
||||||
player.rpc("sync_grid_item", cell.x, cell.y, cell.z, item)
|
player.rpc("sync_grid_item", cell.x, cell.y, cell.z, item)
|
||||||
player.playerboard[put_slot] = -1
|
|
||||||
player.rpc("sync_playerboard", player.playerboard)
|
player.rpc("sync_playerboard", player.playerboard)
|
||||||
player.has_performed_action = true
|
player.has_performed_action = true
|
||||||
player.consume_action_points(1)
|
player.consume_action_points(1)
|
||||||
|
|
||||||
var main = player.get_tree().get_root().get_node_or_null("Main")
|
|
||||||
if main and main.ui_manager:
|
|
||||||
main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user