From 0a878c520567c14f075c53c01c18a932b159886b Mon Sep 17 00:00:00 2001 From: adtpdn Date: Mon, 8 Jun 2026 12:19:34 +0800 Subject: [PATCH] update local arena of gauntlet --- docs/gauntlet-technical-implementation.md | 86 +++++++++---------- scenes/arena/gauntlet.tscn | 26 ++++++ scenes/main.gd | 1 + .../candy_cannon_controller.gd.uid | 1 + scripts/managers/gauntlet_manager.gd.uid | 1 + scripts/mode_config.gd.uid | 1 + tests/test_gauntlet_cannon_timer.gd.uid | 1 + tests/test_gauntlet_registration.gd.uid | 1 + tests/test_gauntlet_tile_spawning.gd.uid | 1 + 9 files changed, 76 insertions(+), 43 deletions(-) create mode 100644 scenes/arena/gauntlet.tscn create mode 100644 scripts/controllers/candy_cannon_controller.gd.uid create mode 100644 scripts/managers/gauntlet_manager.gd.uid create mode 100644 scripts/mode_config.gd.uid create mode 100644 tests/test_gauntlet_cannon_timer.gd.uid create mode 100644 tests/test_gauntlet_registration.gd.uid create mode 100644 tests/test_gauntlet_tile_spawning.gd.uid diff --git a/docs/gauntlet-technical-implementation.md b/docs/gauntlet-technical-implementation.md index 84e5c9b..84f429a 100644 --- a/docs/gauntlet-technical-implementation.md +++ b/docs/gauntlet-technical-implementation.md @@ -55,10 +55,10 @@ GauntletManager (NEW) #### `scripts/game_mode.gd` ```gdscript enum Mode { - FREEMODE = 0, - STOP_N_GO = 1, - TEKTON_DOORS = 2, - GAUNTLET = 3 # NEW + FREEMODE = 0, + STOP_N_GO = 1, + TEKTON_DOORS = 2, + GAUNTLET = 3 # NEW } # Add to from_string(), mode_to_string(), get_all_modes(), is_restricted() @@ -157,12 +157,12 @@ var gridmap: Node # Targeting weights per phase var phase_weights: Array = [ - # Phase 0 (Open Arena): 1×1=60%, 1×2=40%, 2×2=0% - {"1x1": 0.6, "1x2": 0.4, "2x2": 0.0}, - # Phase 1 (Route Pressure): 1×1=30%, 1×2=55%, 2×2=15% - {"1x1": 0.3, "1x2": 0.55, "2x2": 0.15}, - # Phase 2 (Survival): 1×1=15%, 1×2=55%, 2×2=30% - {"1x1": 0.15, "1x2": 0.55, "2x2": 0.30} + # Phase 0 (Open Arena): 1×1=60%, 1×2=40%, 2×2=0% + {"1x1": 0.6, "1x2": 0.4, "2x2": 0.0}, + # Phase 1 (Route Pressure): 1×1=30%, 1×2=55%, 2×2=15% + {"1x1": 0.3, "1x2": 0.55, "2x2": 0.15}, + # Phase 2 (Survival): 1×1=15%, 1×2=55%, 2×2=30% + {"1x1": 0.15, "1x2": 0.55, "2x2": 0.30} ] ``` @@ -273,22 +273,22 @@ Following the exact pattern of StopNGoManager / PortalModeManager: ```gdscript # _init_managers() — Add after portal_mode_manager block: if LobbyManager.game_mode == "Candy Cannon Survival": - gauntlet_manager = load("res://scripts/managers/gauntlet_manager.gd").new() - gauntlet_manager.name = "GauntletManager" - add_child(gauntlet_manager) - gauntlet_manager.initialize(self, $EnhancedGridMap) + gauntlet_manager = load("res://scripts/managers/gauntlet_manager.gd").new() + gauntlet_manager.name = "GauntletManager" + add_child(gauntlet_manager) + gauntlet_manager.initialize(self, $EnhancedGridMap) # _setup_host_game() — Add arena setup branch: elif LobbyManager.game_mode == "Candy Cannon Survival" and gauntlet_manager: - gauntlet_manager._setup_arena() + gauntlet_manager._setup_arena() # _start_game() — Add game mode start: elif LobbyManager.game_mode == "Candy Cannon Survival": - if gauntlet_manager: - gauntlet_manager.start_game_mode() - if goals_cycle_manager: - var match_duration = LobbyManager.get_match_duration() - goals_cycle_manager.start_match(float(match_duration)) + if gauntlet_manager: + gauntlet_manager.start_game_mode() + if goals_cycle_manager: + var match_duration = LobbyManager.get_match_duration() + goals_cycle_manager.start_match(float(match_duration)) ``` --- @@ -319,29 +319,29 @@ elif LobbyManager.game_mode == "Candy Cannon Survival": ```gdscript # In CandyCannonController._select_targets(): func _select_targets(count: int) -> Array[Vector2i]: - var targets: Array[Vector2i] = [] - var players = get_tree().get_nodes_in_group("Players") - - for i in range(count): - var roll = randf() - var target: Vector2i - - if roll < 0.60: - # Near a player (not same as last targeted) - target = _get_near_player_target(players) - elif roll < 0.85: - # Route-blocking (pathfinding bottleneck) - target = _get_route_blocking_target() - elif roll < 0.95: - # Random non-sticky - target = _get_random_non_sticky_target() - else: - # Chaos (anywhere) - target = _get_random_target() - - targets.append(target) - - return targets + var targets: Array[Vector2i] = [] + var players = get_tree().get_nodes_in_group("Players") + + for i in range(count): + var roll = randf() + var target: Vector2i + + if roll < 0.60: + # Near a player (not same as last targeted) + target = _get_near_player_target(players) + elif roll < 0.85: + # Route-blocking (pathfinding bottleneck) + target = _get_route_blocking_target() + elif roll < 0.95: + # Random non-sticky + target = _get_random_non_sticky_target() + else: + # Chaos (anywhere) + target = _get_random_target() + + targets.append(target) + + return targets # Anti-unfairness rules: # 1. last_targeted_player_id tracking prevents same-player targeting diff --git a/scenes/arena/gauntlet.tscn b/scenes/arena/gauntlet.tscn new file mode 100644 index 0000000..e88f29f --- /dev/null +++ b/scenes/arena/gauntlet.tscn @@ -0,0 +1,26 @@ +[gd_scene format=3 uid="uid://bx5a31fqhw8h8"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_floor"] +albedo_color = Color(0.2, 0.2, 0.2, 1) +uv1_scale = Vector3(20, 20, 20) + +[sub_resource type="PlaneMesh" id="PlaneMesh_floor"] +material = SubResource("StandardMaterial3D_floor") +size = Vector2(20, 20) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_zone"] +albedo_color = Color(0.8, 0.2, 0.5, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_cannon"] +material = SubResource("StandardMaterial3D_zone") +size = Vector3(3, 1, 3) + +[node name="Gauntlet" type="Node3D" unique_id=1063002869] + +[node name="PlaceholderFloor" type="MeshInstance3D" parent="." unique_id=932640085] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10, 0, 10) +mesh = SubResource("PlaneMesh_floor") + +[node name="PlaceholderCannonZone" type="MeshInstance3D" parent="." unique_id=1461272366] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.5, 0.5, 9.5) +mesh = SubResource("BoxMesh_cannon") diff --git a/scenes/main.gd b/scenes/main.gd index 8ed371f..bfb65c1 100644 --- a/scenes/main.gd +++ b/scenes/main.gd @@ -150,6 +150,7 @@ func _apply_arena_background(): texture_path = "res://assets/graphics/level_bg/placeholder_tekton_doors.jpg" "Gauntlet Arena": texture_path = "res://assets/graphics/level_bg/placeholder_classic.jpg" + _instantiate_3d_arena("res://scenes/arena/gauntlet.tscn") _hide_ground_tiles() "Classic", _: texture_path = "res://assets/graphics/level_bg/placeholder_classic.jpg" diff --git a/scripts/controllers/candy_cannon_controller.gd.uid b/scripts/controllers/candy_cannon_controller.gd.uid new file mode 100644 index 0000000..44cac8c --- /dev/null +++ b/scripts/controllers/candy_cannon_controller.gd.uid @@ -0,0 +1 @@ +uid://du7cne5070ia0 diff --git a/scripts/managers/gauntlet_manager.gd.uid b/scripts/managers/gauntlet_manager.gd.uid new file mode 100644 index 0000000..8ead6ba --- /dev/null +++ b/scripts/managers/gauntlet_manager.gd.uid @@ -0,0 +1 @@ +uid://ih7h4pb43awd diff --git a/scripts/mode_config.gd.uid b/scripts/mode_config.gd.uid new file mode 100644 index 0000000..49f6692 --- /dev/null +++ b/scripts/mode_config.gd.uid @@ -0,0 +1 @@ +uid://dsungfo2rdgdc diff --git a/tests/test_gauntlet_cannon_timer.gd.uid b/tests/test_gauntlet_cannon_timer.gd.uid new file mode 100644 index 0000000..e26a0b1 --- /dev/null +++ b/tests/test_gauntlet_cannon_timer.gd.uid @@ -0,0 +1 @@ +uid://ct0psnc84v1sy diff --git a/tests/test_gauntlet_registration.gd.uid b/tests/test_gauntlet_registration.gd.uid new file mode 100644 index 0000000..f745d06 --- /dev/null +++ b/tests/test_gauntlet_registration.gd.uid @@ -0,0 +1 @@ +uid://6pn8jkrn2kt diff --git a/tests/test_gauntlet_tile_spawning.gd.uid b/tests/test_gauntlet_tile_spawning.gd.uid new file mode 100644 index 0000000..892bb58 --- /dev/null +++ b/tests/test_gauntlet_tile_spawning.gd.uid @@ -0,0 +1 @@ +uid://cpwhlklp7jkkg