feat: Introduce static Tekton stands with a new manager for strategic, non-adjacent placement and synchronized randomized shapes.
This commit is contained in:
+50
-4
@@ -13,6 +13,8 @@ var camera_context_manager
|
||||
|
||||
# Minimal local state
|
||||
var _connection_check_timer: float = 0.0
|
||||
var reserved_static_positions: Array[Vector2i] = []
|
||||
|
||||
|
||||
func _ready():
|
||||
# Initialize scene managers
|
||||
@@ -356,6 +358,9 @@ func _setup_host_game():
|
||||
print("Spawning lobby player: ", peer_id)
|
||||
_spawn_lobby_client_sync(peer_id)
|
||||
|
||||
# 1. PVT: Pre-calculate Static Tekton positions so we know where NOT to spawn players
|
||||
_precalculate_static_positions()
|
||||
|
||||
# IMMEDIATELY assign random spawn positions before any player _ready() completes
|
||||
# Player _ready() has 0.1s await, so we assign before that completes
|
||||
# IMMEDIATELY assign spawn positions (Fixed or Random)
|
||||
@@ -540,6 +545,18 @@ func _assign_random_spawn_positions():
|
||||
var ground = enhanced_gridmap.get_cell_item(Vector3i(x, 0, z))
|
||||
if ground == 0: # Walkable
|
||||
var pos = Vector2i(x, z)
|
||||
|
||||
# SAFETY CHECK: Is this reserved for a Static Tekton Stand?
|
||||
# Stand covers [center-1, center+1]
|
||||
var is_safe = true
|
||||
for reserved in reserved_static_positions:
|
||||
if abs(x - reserved.x) <= 1 and abs(z - reserved.y) <= 1:
|
||||
is_safe = false
|
||||
break
|
||||
|
||||
if not is_safe:
|
||||
continue
|
||||
|
||||
all_spawns.append(pos)
|
||||
|
||||
if x < mid_x and z < mid_z:
|
||||
@@ -648,6 +665,14 @@ func spawn_tekton_npc():
|
||||
var item_id = enhanced_gridmap.get_cell_item(Vector3i(x, 1, y))
|
||||
if item_id == 4: continue # Wall/Stand
|
||||
|
||||
# Also check RESERVED positions (if they haven't spawned yet or for safety)
|
||||
var is_safe = true
|
||||
for reserved in reserved_static_positions:
|
||||
if abs(x - reserved.x) <= 1 and abs(y - reserved.y) <= 1:
|
||||
is_safe = false
|
||||
break
|
||||
if not is_safe: continue
|
||||
|
||||
valid_pos = Vector2i(x, y)
|
||||
|
||||
# Generate a consistent ID/Name for sync (add index to ensure uniqueness)
|
||||
@@ -691,6 +716,23 @@ func _create_tekton(pos: Vector2i, tekton_id: int, is_static: bool = false):
|
||||
else:
|
||||
print("[Main] Spawned Tekton at %s (ID: %d)" % [pos, tekton_id])
|
||||
|
||||
|
||||
|
||||
func _precalculate_static_positions():
|
||||
"""Calculate and reserve Static Tekton positions early."""
|
||||
if not multiplayer.is_server(): return
|
||||
var enhanced_gridmap = $EnhancedGridMap
|
||||
if not enhanced_gridmap: return
|
||||
|
||||
if not static_tekton_manager:
|
||||
static_tekton_manager = StaticTektonManager.new()
|
||||
|
||||
# Calculate 3 spots and STORE them
|
||||
var points: Array[Vector2i] = []
|
||||
points = static_tekton_manager.calculate_spawn_points(3, enhanced_gridmap)
|
||||
reserved_static_positions = points
|
||||
print("[Main] Pre-calculated Static Tekton Positions: %s" % str(reserved_static_positions))
|
||||
|
||||
func spawn_static_tektons():
|
||||
"""Spawn fixed static tektons using StaticTektonManager."""
|
||||
if not multiplayer.is_server(): return
|
||||
@@ -700,11 +742,15 @@ func spawn_static_tektons():
|
||||
print("[Main] Initializing StaticTektonManager...")
|
||||
if not static_tekton_manager:
|
||||
static_tekton_manager = StaticTektonManager.new()
|
||||
# Keeping manager instance in memory
|
||||
|
||||
# Calculate Spawn Points (Server Logic)
|
||||
var spawn_points = static_tekton_manager.calculate_spawn_points(3, enhanced_gridmap)
|
||||
print("[Main] Static Tekton Points: %s" % str(spawn_points))
|
||||
# Use pre-calculated points if available, otherwise calculate new ones
|
||||
var spawn_points = []
|
||||
if not reserved_static_positions.is_empty():
|
||||
spawn_points = reserved_static_positions
|
||||
else:
|
||||
spawn_points = static_tekton_manager.calculate_spawn_points(3, enhanced_gridmap)
|
||||
|
||||
print("[Main] Spawning Static Tektons at: %s" % str(spawn_points))
|
||||
|
||||
for i in range(spawn_points.size()):
|
||||
var pos = spawn_points[i]
|
||||
|
||||
@@ -13,7 +13,7 @@ const STATIC_CONTROLLER_SCRIPT = "res://scripts/static_tekton_controller.gd"
|
||||
# Mid-Left, Mid-Mid, Mid-Right
|
||||
# Bot-Left, Bot-Mid, Bot-Right
|
||||
|
||||
func calculate_spawn_points(count: int, gridmap: Node) -> Array:
|
||||
func calculate_spawn_points(count: int, gridmap: Node) -> Array[Vector2i]:
|
||||
"""
|
||||
Calculates random spawn positions for static tektons.
|
||||
Returns an Array of Vector2i positions.
|
||||
@@ -39,7 +39,7 @@ func calculate_spawn_points(count: int, gridmap: Node) -> Array:
|
||||
|
||||
# If count < 5, we prioritize corners then center
|
||||
# If count > 5, we only return 5 because that's the max safe non-adjacent set in 3x3
|
||||
var spawn_points = []
|
||||
var spawn_points: Array[Vector2i] = []
|
||||
|
||||
var iterations = min(count, target_indices.size())
|
||||
for i in range(iterations):
|
||||
|
||||
@@ -31,7 +31,6 @@ func _update_mesh_from_index():
|
||||
var shapes = [
|
||||
_create_cylinder(),
|
||||
_create_box(),
|
||||
_create_prism(),
|
||||
_create_sphere()
|
||||
]
|
||||
|
||||
@@ -61,11 +60,7 @@ func _create_box() -> BoxMesh:
|
||||
var mesh = BoxMesh.new()
|
||||
mesh.size = Vector3(3.2, 0.6, 3.2)
|
||||
return mesh
|
||||
|
||||
func _create_prism() -> PrismMesh:
|
||||
var mesh = PrismMesh.new()
|
||||
mesh.size = Vector3(3.2, 0.6, 3.2)
|
||||
return mesh
|
||||
|
||||
|
||||
func _create_sphere() -> SphereMesh:
|
||||
# A flattened sphere acting like a dome stand
|
||||
|
||||
Reference in New Issue
Block a user