feat: Introduce Tekton roaming NPC with grid movement, player interaction, tile spawning, and visual effects.

This commit is contained in:
Yogi Wiguna
2026-03-13 10:07:17 +08:00
parent 74a81425c5
commit 200e198428
4 changed files with 48 additions and 31 deletions
+10 -5
View File
@@ -392,7 +392,7 @@ func _execute_block_floor(target_pos: Vector2i = Vector2i.ZERO):
if "immutable_items" in enhanced_gridmap:
if original_item in enhanced_gridmap.immutable_items:
is_immutable = true
if original_item in [1, 2, 3, 4, 16] or is_immutable: continue
if original_item in [1, 2, 3, 4, 15, 16] or is_immutable: continue
batch_data.append({"x": block_pos.x, "y": 0, "z": block_pos.z, "item": 4})
@@ -442,6 +442,11 @@ func spawn_powerups_around(center: Vector2i, force_powerups: bool = true, only_c
# PROTECTED FLOOR CHECK: Don't spawn on existing walls or void
var f0 = enhanced_gridmap.get_cell_item(Vector3i(pos.x, 0, pos.y))
var f1 = enhanced_gridmap.get_cell_item(Vector3i(pos.x, 1, pos.y))
# Stop n Go: Don't overwrite static powerup spawns (ID 15 floor)
if LobbyManager.is_game_mode(GameMode.Mode.STOP_N_GO) and f0 == 15:
continue
if f0 in [4, -1] or f1 in [4, 16]:
continue
@@ -449,16 +454,16 @@ func spawn_powerups_around(center: Vector2i, force_powerups: bool = true, only_c
var mode = LobbyManager.get_game_mode()
if only_common or LobbyManager.is_game_mode(GameMode.Mode.STOP_N_GO):
# Spawn ONLY common tiles (7-10) for Stop n Go or if forced
# Spawn ONLY common tiles (7-10) in Stop n Go mode (User Request)
item_id = rng.randi_range(7, 10)
else:
# Free mode: 80% Chance for Common Tile (7-10), 20% for PowerUp
# Other modes: 80% Chance for Common Tile (7-10), 20% for PowerUp
if rng.randf() < 0.8:
item_id = rng.randi_range(7, 10)
else:
# 20% Chance for PowerUp
var is_restricted = GameMode.is_restricted(mode)
if is_restricted:
if LobbyManager.is_game_mode(GameMode.Mode.TEKTON_DOORS):
# Restrict to Speed (11) and Ghost (14) for Tekton Doors
item_id = [11, 14].pick_random()
else:
item_id = rng.randi_range(11, 14)
+7 -7
View File
@@ -16,7 +16,7 @@ var safe_zone_centers: Array[Vector2i] = []
var safe_zone_spawned: bool = false
# Power-Up Tile Spawning
const POWERUP_TILES = [11, 12, 13, 14] # Speed, Freeze, Wall, Ghost
const POWERUP_TILES = [11, 14] # Speed, Ghost (Freeze and Wall excluded in this mode)
const POWERUP_SPAWN_COUNT: int = 5 # Number of power-up tiles to spawn
var powerups_spawned: bool = false
var stop_phase_occurred: bool = false
@@ -360,8 +360,8 @@ func _spawn_mission_tiles():
var base_tile = gridmap.get_cell_item(Vector3i(x, 0, z))
var current_item = gridmap.get_cell_item(Vector3i(x, 1, z))
# PROTECTED FLOOR CHECK: Don't spawn on walls or void
if base_tile in [TILE_OBSTACLE, -1] or current_item == TILE_OBSTACLE:
# PROTECTED FLOOR CHECK: Don't spawn on walls, void, or static powerup pods
if base_tile in [TILE_OBSTACLE, -1, TILE_LIGHTNING_STONE] or current_item == TILE_OBSTACLE:
continue
# Spawn tiles with 60% density
@@ -593,9 +593,9 @@ func _scatter_player_tiles(player_node: Node):
# Bounds check
if pos.x < 0 or pos.x >= gridmap.columns or pos.y < 0 or pos.y >= gridmap.rows:
continue
# Check floor is walkable (not void, not obstacle)
# Check floor is walkable (not void, not obstacle, not static powerup spawn)
var floor_tile = gridmap.get_cell_item(Vector3i(pos.x, 0, pos.y))
if floor_tile == -1 or floor_tile == TILE_OBSTACLE:
if floor_tile == -1 or floor_tile == TILE_OBSTACLE or floor_tile == TILE_LIGHTNING_STONE:
continue
# Check floor 1 is empty (no existing item)
var existing_item = gridmap.get_cell_item(Vector3i(pos.x, 1, pos.y))
@@ -750,8 +750,8 @@ func _spawn_powerup_tiles():
# Set Floor 0 beneath power-up to ID 15 (Ancient Lightning Stone)
gridmap.set_cell_item(Vector3i(pos.x, 0, pos.y), TILE_LIGHTNING_STONE)
# Cycle through the available power-up types
var tile_id = POWERUP_TILES[i % POWERUP_TILES.size()]
# Select a random power-up type (User Request: ensure all types can spawn)
var tile_id = POWERUP_TILES.pick_random()
# Place on Floor 1
gridmap.set_cell_item(Vector3i(pos.x, 1, pos.y), tile_id)