7380161743
Version bump to 2.3.6. New game mode features 20×20 arena with central cannon obstacle, three escalating phases (Open Arena, Route Pressure, Survival), and collectible tiles (Hearts, Diamonds, Stars, Coins) with pattern-matching missions. Players dodge candy volleys while completing collection goals. Updated export paths and version strings across all platforms (Windows, Android, Web, Linux).
145 lines
6.2 KiB
GDScript
145 lines
6.2 KiB
GDScript
extends GutTest
|
|
|
|
# =============================================================================
|
|
# Test: Gauntlet Tile Spawning & Mission System (Task #3)
|
|
# =============================================================================
|
|
|
|
var GauntletManagerScript = load("res://scripts/managers/gauntlet_manager.gd")
|
|
var manager: GauntletManager
|
|
|
|
func before_each():
|
|
manager = GauntletManagerScript.new()
|
|
add_child(manager)
|
|
|
|
func after_each():
|
|
manager.queue_free()
|
|
|
|
# =============================================================================
|
|
# Arena Constants
|
|
# =============================================================================
|
|
|
|
func test_arena_size_20x20():
|
|
assert_eq(manager.ARENA_COLUMNS, 20, "Arena should be 20 columns")
|
|
assert_eq(manager.ARENA_ROWS, 20, "Arena should be 20 rows")
|
|
|
|
func test_npc_center_position():
|
|
assert_eq(manager.NPC_CENTER, Vector2i(9, 9), "NPC center should be at (9,9)")
|
|
|
|
func test_npc_size_3x3():
|
|
assert_eq(manager.NPC_SIZE, 3, "NPC zone should be 3x3")
|
|
|
|
# =============================================================================
|
|
# NPC Zone Exclusion
|
|
# =============================================================================
|
|
|
|
func test_npc_zone_center_is_excluded():
|
|
assert_true(manager._is_npc_zone(Vector2i(9, 9)), "Center (9,9) should be NPC zone")
|
|
|
|
func test_npc_zone_corners_are_excluded():
|
|
assert_true(manager._is_npc_zone(Vector2i(8, 8)), "Top-left (8,8) should be NPC zone")
|
|
assert_true(manager._is_npc_zone(Vector2i(10, 8)), "Top-right (10,8) should be NPC zone")
|
|
assert_true(manager._is_npc_zone(Vector2i(8, 10)), "Bottom-left (8,10) should be NPC zone")
|
|
assert_true(manager._is_npc_zone(Vector2i(10, 10)), "Bottom-right (10,10) should be NPC zone")
|
|
|
|
func test_outside_npc_zone_not_excluded():
|
|
assert_false(manager._is_npc_zone(Vector2i(7, 9)), "Left of NPC zone should NOT be excluded")
|
|
assert_false(manager._is_npc_zone(Vector2i(11, 9)), "Right of NPC zone should NOT be excluded")
|
|
assert_false(manager._is_npc_zone(Vector2i(9, 7)), "Above NPC zone should NOT be excluded")
|
|
assert_false(manager._is_npc_zone(Vector2i(9, 11)), "Below NPC zone should NOT be excluded")
|
|
|
|
func test_arena_corners_not_excluded():
|
|
assert_false(manager._is_npc_zone(Vector2i(0, 0)), "Top-left corner should be walkable")
|
|
assert_false(manager._is_npc_zone(Vector2i(19, 0)), "Top-right corner should be walkable")
|
|
assert_false(manager._is_npc_zone(Vector2i(0, 19)), "Bottom-left corner should be walkable")
|
|
assert_false(manager._is_npc_zone(Vector2i(19, 19)), "Bottom-right corner should be walkable")
|
|
|
|
func test_npc_zone_total_cells():
|
|
var npc_count = 0
|
|
for x in range(manager.ARENA_COLUMNS):
|
|
for z in range(manager.ARENA_ROWS):
|
|
if manager._is_npc_zone(Vector2i(x, z)):
|
|
npc_count += 1
|
|
assert_eq(npc_count, 9, "NPC zone should occupy exactly 9 cells (3x3)")
|
|
|
|
func test_walkable_cells_count():
|
|
# 20x20 = 400 total, minus 9 NPC = 391 walkable
|
|
var walkable = 400 - 9
|
|
assert_eq(walkable, 391, "Should have 391 walkable cells")
|
|
|
|
# =============================================================================
|
|
# Tile Constants
|
|
# =============================================================================
|
|
|
|
func test_goal_tile_ids_valid():
|
|
# Heart(7), Diamond(8), Star(9), Coin(10) — match StopNGoManager
|
|
var goal_items = [7, 8, 9, 10]
|
|
for item in goal_items:
|
|
assert_gt(item, 0, "Goal tile ID %d should be positive" % item)
|
|
assert_lt(item, 17, "Goal tile ID %d should not conflict with sticky(17)" % item)
|
|
|
|
func test_tile_walkable_id():
|
|
assert_eq(manager.TILE_WALKABLE, 0, "Walkable tile should be ID 0")
|
|
|
|
func test_tile_obstacle_id():
|
|
assert_eq(manager.TILE_OBSTACLE, 4, "Obstacle tile should be ID 4")
|
|
|
|
func test_tile_sticky_id():
|
|
assert_eq(manager.TILE_STICKY, 17, "Sticky tile should be ID 17")
|
|
|
|
func test_tile_telegraph_id():
|
|
assert_eq(manager.TILE_TELEGRAPH, 18, "Telegraph tile should be ID 18")
|
|
|
|
# =============================================================================
|
|
# Method Existence
|
|
# =============================================================================
|
|
|
|
func test_setup_mission_tiles_exists():
|
|
assert_true(manager.has_method("setup_mission_tiles"), "Should have setup_mission_tiles()")
|
|
|
|
func test_spawn_mission_tiles_exists():
|
|
assert_true(manager.has_method("_spawn_mission_tiles"), "Should have _spawn_mission_tiles()")
|
|
|
|
# =============================================================================
|
|
# Sticky Cell System
|
|
# =============================================================================
|
|
|
|
func test_sticky_cells_initially_empty():
|
|
assert_eq(manager.sticky_cells.size(), 0, "Sticky cells should start empty")
|
|
|
|
func test_is_sticky_cell_false_for_clean():
|
|
assert_false(manager.is_sticky_cell(Vector2i(5, 5)), "Clean cell should not be sticky")
|
|
|
|
func test_is_sticky_cell_true_after_marking():
|
|
manager.sticky_cells[Vector2i(5, 5)] = true
|
|
assert_true(manager.is_sticky_cell(Vector2i(5, 5)), "Marked cell should be sticky")
|
|
|
|
func test_clear_sticky_cell():
|
|
manager.sticky_cells[Vector2i(3, 3)] = true
|
|
manager.clear_sticky_cell(Vector2i(3, 3))
|
|
assert_false(manager.is_sticky_cell(Vector2i(3, 3)), "Cleared cell should no longer be sticky")
|
|
|
|
# =============================================================================
|
|
# Phase Interaction with Tile Spawning
|
|
# =============================================================================
|
|
|
|
func test_initial_phase_is_open_arena():
|
|
assert_eq(manager.current_phase, GauntletManager.Phase.OPEN_ARENA, "Should start in Open Arena")
|
|
|
|
func test_phase_to_string_open_arena():
|
|
assert_eq(manager._phase_to_string(GauntletManager.Phase.OPEN_ARENA), "Open Arena")
|
|
|
|
func test_phase_to_string_route_pressure():
|
|
assert_eq(manager._phase_to_string(GauntletManager.Phase.ROUTE_PRESSURE), "Route Pressure")
|
|
|
|
func test_phase_to_string_survival():
|
|
assert_eq(manager._phase_to_string(GauntletManager.Phase.SURVIVAL_ENDGAME), "Survival!")
|
|
|
|
# =============================================================================
|
|
# Match Timer Integration
|
|
# =============================================================================
|
|
|
|
func test_match_duration_180s():
|
|
# Gauntlet uses 180s match (3 phases: 0-60, 60-120, 120-180)
|
|
var total = manager.PHASE_3_START + 60.0 # Phase 3 starts at 120, runs 60s
|
|
assert_eq(total, 180.0, "Total match should be 180 seconds")
|