make the ruleset for first and second lap

This commit is contained in:
2025-04-21 16:23:48 +08:00
parent 49cc53e230
commit d397ef0931
3 changed files with 160 additions and 60 deletions
+159 -59
View File
@@ -15,12 +15,14 @@ var can_finish
@export var goals: Array[int] = [0,0,0,0,0,0,0,0,0]
@export 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]
# Modifier for Turn based
var has_performed_action: bool = false
var selected_gridmap_position = Vector2i(-1, -1)
var selected_playerboard_slot = -1
var targeted_playerboard_slot = -1
var action_points: int = 2
# Modifier for player models
var target_rotation: float = 0.0
var rotation_speed: float = 10.0
@@ -44,9 +46,10 @@ var finish_locations = [
]
var spawn_point_selected = false
var highlighted_spawn_points = []
# Action
# Action for hilighter
var highlighted_spawn_points = []
var highlighted_cells = []
var _is_processing_action = false
var _is_highlighting = false
@@ -65,7 +68,22 @@ var _is_highlighting = false
@export var has_moved_this_turn = false
var highlighted_cells = []
# Track, Lap, Position
var current_lap: int = 0
var first_lap_goals: Array[int] = [] # Current goals (partial 3x3)
var second_lap_goals: Array[int] = [] # Full 3x3 goals
var race_position: int = 0 # Track finish position
static var lap1_finishers: int = 0 # Static to track across all players
static var lap2_finishers: int = 0
# Function to get ordinal string (1st, 2nd, 3rd, 4th)
func get_ordinal_string(number: int) -> String:
match number:
1: return "1st"
2: return "2nd"
3: return "3rd"
4: return "4th"
_: return str(number) + "th"
func _ready():
# Ensure name is set first
@@ -81,6 +99,13 @@ func _ready():
push_error("Main scene not found")
return
# Modifier to handle the lap
if is_multiplayer_authority():
# Generate the first_lap_goals
first_lap_goals = goals.duplicate()
# Generate the second_lap_goals
generate_second_lap_goals()
# Ensure proper initialization order
enhanced_gridmap = get_node(enhanced_gridmap_path)
if main_scene:
@@ -182,12 +207,60 @@ func check_3x3_section(board: Array, goals: Array, start_row: int, start_col: in
return true
# Generate full 3x3 goals for second lap
func generate_second_lap_goals():
second_lap_goals.clear()
# Generate a complete 3x3 pattern (no empty spaces)
for i in range(9):
var val = (randi() % 4) + 7 # Values between 7 and 10
second_lap_goals.append(val)
if is_multiplayer_authority():
rpc("sync_second_lap_goals", second_lap_goals)
@rpc("any_peer", "reliable")
func sync_second_lap_goals(new_goals: Array):
second_lap_goals = new_goals
# Modify finish_race to handle lap completion
@rpc("any_peer", "reliable")
func finish_race():
if current_lap == 0: # Finishing first lap
lap1_finishers += 1
race_position = lap1_finishers
# Display first lap completion message
var message = "Finish 1st lap on " + get_ordinal_string(race_position)
if is_multiplayer_authority():
rpc("display_message", message)
# Start second lap
current_lap += 1
rpc("start_new_lap")
elif current_lap == 1: # Finishing second lap
lap2_finishers += 1
race_position = lap2_finishers
# Display second lap completion message
var message = "Finish 2nd lap on " + get_ordinal_string(race_position)
if is_multiplayer_authority():
rpc("display_message", message)
# Notify game completion
var main = get_tree().get_root().get_node_or_null("Main")
if main and is_multiplayer_authority():
main.player_finished_race(self)
# Add function to check 3x3 pattern matching anywhere in 5x5 playerboard
func check_pattern_match() -> bool:
# Early return if playerboard or goals are not properly sized
if playerboard.size() != 25 or goals.size() != 9:
return false
var current_goals = goals
# Convert 1D arrays to 2D for easier pattern matching
var board_2d = []
var goals_2d = []
@@ -214,23 +287,55 @@ func check_pattern_match() -> bool:
return false
# Add function to handle new lap
## Add function to handle new lap
#@rpc("any_peer", "reliable")
#func start_new_lap():
## Reset position to start
#current_position = find_valid_starting_position()
#update_player_position(current_position)
#
## Reset playerboard but keep the goals
#playerboard.fill(-1)
#
## Reset can_finish flag
#can_finish = false
#
## Sync with other clients
#if is_multiplayer_authority():
#rpc("sync_position", current_position)
#rpc("sync_playerboard", playerboard)
# Modify start_new_lap to handle different lap goals and starting positions
@rpc("any_peer", "reliable")
func start_new_lap():
# Reset position to start
current_position = find_valid_starting_position()
update_player_position(current_position)
# Reset playerboard but keep the goals
playerboard.fill(-1)
# Reset can_finish flag
can_finish = false
# Sync with other clients
if is_multiplayer_authority():
rpc("sync_position", current_position)
rpc("sync_playerboard", playerboard)
if current_lap == 1: # Moving to second lap
# Start from first lap finish line
var valid_finish_pos = find_valid_position_in_finish_line()
if valid_finish_pos != Vector2i(-1, -1):
current_position = valid_finish_pos
update_player_position(current_position)
# Set new goals (full 3x3)
goals = second_lap_goals.duplicate()
# Reset playerboard
playerboard.fill(-1)
# Reset can_finish flag
can_finish = false
# Sync with other clients
if is_multiplayer_authority():
rpc("sync_position", current_position)
rpc("sync_playerboard", playerboard)
rpc("sync_goals", goals)
# Function to find valid position in finish line
func find_valid_position_in_finish_line() -> Vector2i:
for pos in finish_locations:
if not is_position_occupied(pos):
return pos
return Vector2i(-1, -1)
# Add function to check if player can reach finish
func update_finish_availability():
@@ -243,8 +348,6 @@ func update_finish_availability():
else:
unhighlight_finish_line()
func unhighlight_finish_line():
if not is_multiplayer_authority() or is_bot:
return
@@ -288,7 +391,6 @@ func server_update_spawn_positions():
# Send the occupied positions back to the requesting client
rpc_id(sender_id, "receive_spawn_positions_update", occupied)
# Add client-side spawn position update receiver
# Add client-side spawn position update receiver
@rpc("authority", "reliable")
func receive_spawn_positions_update(occupied_positions: Array):
@@ -439,23 +541,6 @@ func is_position_occupied(pos: Vector2i) -> bool:
return true
return false
#func find_valid_starting_position() -> Vector2i:
#var rng = RandomNumberGenerator.new()
#rng.randomize()
#
#var max_attempts = 100
#var attempts = 0
#
#while attempts < max_attempts:
#var x = rng.randi_range(0, enhanced_gridmap.columns - 1)
#var y = rng.randi_range(0, enhanced_gridmap.rows - 1)
#var pos = Vector2i(x, y)
#if not is_position_occupied(pos):
#return pos
#attempts += 1
#
#return Vector2i.ZERO
func find_valid_starting_position() -> Vector2i:
if is_bot:
return _find_random_spawn_position()
@@ -494,27 +579,6 @@ func get_occupied_positions() -> Array:
occupied.append(player.current_position)
return occupied
#func select_spawn_point(spawn_pos: Vector2i) -> bool:
#if not is_multiplayer_authority() or is_bot or spawn_point_selected:
#return false
#
#if spawn_pos in highlighted_spawn_points:
#current_position = spawn_pos
#spawn_point_selected = true
#
## Update position in the world
#position = grid_to_world(spawn_pos)
#
## Clear ALL highlights comprehensively
#clear_spawn_highlights()
#
## Sync with other clients
#if is_multiplayer_authority():
#rpc("sync_position", current_position)
#
#return true
#return false
# Modify the select_spawn_point function to notify other clients
func select_spawn_point(spawn_pos: Vector2i) -> bool:
if not is_multiplayer_authority() or is_bot or spawn_point_selected:
@@ -618,9 +682,26 @@ func is_within_movement_range(target_position: Vector2i) -> bool:
return distance <= movement_range
func move_player_to_clicked_position(grid_position: Vector2i):
if not is_multiplayer_authority() or is_player_moving or action_points <= 0:
return
var is_valid_finish = false
# Make scenario for match checking laps, for handle lap count
if current_lap == 0: # first lap
is_valid_finish = grid_position in finish_locations
else: # second lap
is_valid_finish = grid_position in spawn_locations
if is_valid_finish:
if not can_finish:
can_finish = check_pattern_match()
if not can_finish:
return
if not is_within_movement_range(grid_position):
return
var main = get_tree().get_root().get_node_or_null("Main")
if not main or main.current_action_state != main.ActionState.MOVING or not grid_position in highlighted_cells:
return
@@ -651,6 +732,10 @@ func move_player_to_clicked_position(grid_position: Vector2i):
# Clear highlights after moving
if not (is_bot or is_in_group("Bots")):
clear_highlights()
# Handle finish line crossing
if is_valid_finish and can_finish:
rpc("finish_race")
@rpc("any_peer", "call_local")
func start_movement_along_path(path: Array, clear_visual: bool = true):
@@ -714,6 +799,21 @@ func end_turn():
if is_multiplayer_authority():
get_tree().get_root().get_node_or_null("Main").request_next_turn()
func reset_race():
current_lap = 0
race_position = 0
can_finish = false
goals = first_lap_goals.duplicate()
playerboard.fill(-1)
if is_multiplayer_authority():
rpc("sync_goals", goals)
rpc("sync_playerboard", playerboard)
# Add a static reset for new games
static func reset_race_stats():
lap1_finishers = 0
lap2_finishers = 0
@rpc("any_peer", "call_local", "unreliable")
func remote_set_position(authority_position):
global_position = authority_position