feat: Implement Stop n Go game mode with phase management, missions, dynamic safe zones, and associated UI and managers.
This commit is contained in:
@@ -22,6 +22,16 @@ var safe_zone_spawned: bool = false
|
||||
# Power-Up Tile Spawning
|
||||
const POWERUP_TILES = [11, 14] # Speed (11) and Ghost (14)
|
||||
const POWERUP_SPAWN_COUNT: int = 5 # Number of power-up tiles to spawn
|
||||
var powerups_spawned: bool = false
|
||||
var stop_phase_occurred: bool = false
|
||||
|
||||
const PERMANENT_POWERUP_LOCATIONS: Array[Vector2i] = [
|
||||
Vector2i(4, 3), # Area 1
|
||||
Vector2i(8, 7), # Area 2
|
||||
Vector2i(11, 4), # Area 3
|
||||
Vector2i(15, 8), # Area 4
|
||||
Vector2i(18, 5) # Area 5
|
||||
]
|
||||
|
||||
var current_phase: Phase = Phase.GO
|
||||
var phase_timer: float = GO_DURATION
|
||||
@@ -231,6 +241,7 @@ func _start_phase(phase: Phase):
|
||||
rpc("sync_phase", phase_name, phase_timer)
|
||||
|
||||
if phase == Phase.STOP:
|
||||
stop_phase_occurred = true
|
||||
# --- DYNAMIC SAFE ZONE: Penalize players outside the zone ---
|
||||
if safe_zone_spawned:
|
||||
var all_players = get_tree().get_nodes_in_group("Players")
|
||||
@@ -238,7 +249,7 @@ func _start_phase(phase: Phase):
|
||||
if not _is_in_safe_zone(p.current_position):
|
||||
_scatter_player_tiles(p)
|
||||
|
||||
# --- POWER-UP TILES: Spawn 5 Speed & Ghost tiles ---
|
||||
# Refresh power-ups every STOP phase
|
||||
_spawn_powerup_tiles()
|
||||
|
||||
# If GO phase starts, clear all STOP phase freezes and safe zone
|
||||
@@ -323,6 +334,11 @@ func setup_mission_tiles():
|
||||
if multiplayer.is_server():
|
||||
_spawn_mission_tiles()
|
||||
|
||||
func spawn_initial_powerups():
|
||||
"""Public wrapper to spawn powerups before game start."""
|
||||
if multiplayer.is_server():
|
||||
_spawn_powerup_tiles()
|
||||
|
||||
func _spawn_mission_tiles():
|
||||
var gridmap = get_parent().get_node_or_null("EnhancedGridMap")
|
||||
if not gridmap:
|
||||
@@ -679,7 +695,7 @@ func sync_clear_safe_zone(centers_to_clear: Array):
|
||||
# =============================================================================
|
||||
|
||||
func _spawn_powerup_tiles():
|
||||
"""Server: Spawn 5 Speed & Ghost power-up tiles at random walkable positions."""
|
||||
"""Server: Spawn 5 permanent power-up tiles at fixed positions."""
|
||||
if not multiplayer.is_server(): return
|
||||
|
||||
var main = get_node_or_null("/root/Main")
|
||||
@@ -688,40 +704,24 @@ func _spawn_powerup_tiles():
|
||||
var gridmap = main.get_node_or_null("EnhancedGridMap")
|
||||
if not gridmap: return
|
||||
|
||||
# Collect valid positions (walkable floor, no existing item on Floor 1)
|
||||
var valid_positions: Array[Vector2i] = []
|
||||
for x in range(gridmap.columns):
|
||||
for z in range(gridmap.rows):
|
||||
var floor_tile = gridmap.get_cell_item(Vector3i(x, 0, z))
|
||||
# Skip void, obstacles, start, finish
|
||||
if floor_tile == -1 or floor_tile == TILE_OBSTACLE:
|
||||
continue
|
||||
# Skip cells that already have items on Floor 1
|
||||
var existing_item = gridmap.get_cell_item(Vector3i(x, 1, z))
|
||||
if existing_item != -1:
|
||||
continue
|
||||
valid_positions.append(Vector2i(x, z))
|
||||
print("[StopNGo] Spawning/Refreshing 5 static power-up tiles...")
|
||||
|
||||
if valid_positions.is_empty():
|
||||
print("[StopNGo] WARNING: No valid positions for power-up tiles!")
|
||||
return
|
||||
|
||||
# Shuffle and pick up to POWERUP_SPAWN_COUNT positions
|
||||
var rng = RandomNumberGenerator.new()
|
||||
rng.randomize()
|
||||
valid_positions.shuffle()
|
||||
|
||||
var spawn_count = min(POWERUP_SPAWN_COUNT, valid_positions.size())
|
||||
|
||||
for i in range(spawn_count):
|
||||
var pos = valid_positions[i]
|
||||
var tile_id = POWERUP_TILES[rng.randi() % POWERUP_TILES.size()]
|
||||
for i in range(PERMANENT_POWERUP_LOCATIONS.size()):
|
||||
var pos = PERMANENT_POWERUP_LOCATIONS[i]
|
||||
|
||||
# Set Floor 0 beneath power-up to ID 1 (Hover pattern) - Static PADS
|
||||
gridmap.set_cell_item(Vector3i(pos.x, 0, pos.y), 1)
|
||||
|
||||
# Cycle through the available power-up types
|
||||
var tile_id = POWERUP_TILES[i % POWERUP_TILES.size()]
|
||||
|
||||
# Place on Floor 1
|
||||
gridmap.set_cell_item(Vector3i(pos.x, 1, pos.y), tile_id)
|
||||
|
||||
# Sync to all clients
|
||||
# Sync both floor and tile to all clients and host
|
||||
if can_rpc():
|
||||
main.rpc("sync_grid_item", pos.x, 1, pos.y, tile_id)
|
||||
main.rpc("sync_grid_item", pos.x, 0, pos.y, 1) # Sync floor change (Pad on)
|
||||
main.rpc("sync_grid_item", pos.x, 1, pos.y, tile_id) # Sync power-up
|
||||
|
||||
print("[StopNGo] Spawned %d power-up tiles (Speed & Ghost)" % spawn_count)
|
||||
powerups_spawned = true
|
||||
print("[StopNGo] Static power-up refresh completed.")
|
||||
|
||||
Reference in New Issue
Block a user