From 38a9696c0fbe082758482714860c1c75ae24009f Mon Sep 17 00:00:00 2001 From: CJN Date: Mon, 6 Jul 2026 22:01:48 +0800 Subject: [PATCH 1/4] feat: trap 3, 4, 6 state settings --- Scripts/traps/trap3-tracing_bullet.gd | 24 ++++++++++++++++++++++++ Scripts/traps/trap4-conveyor.gd | 21 +++++++++++++++++++++ Scripts/traps/trap6-scanline.gd | 26 ++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/Scripts/traps/trap3-tracing_bullet.gd b/Scripts/traps/trap3-tracing_bullet.gd index 5efc7425..0d6fd373 100644 --- a/Scripts/traps/trap3-tracing_bullet.gd +++ b/Scripts/traps/trap3-tracing_bullet.gd @@ -15,10 +15,12 @@ var speed := 0.0 var tracing := true var flying := false var wall_counter := 0 +var is_demo := false @onready var feather_effect = $FeatherEffect @onready var leave_wall_detector = $Area2D @onready var wait_timer = $WaitTimer @onready var animation = $AnimationPlayer +@onready var sprite = $AnimatedSprite2D static func initialize(pos: Vector2, dir: Vector2, speed: float) -> Trap3TracingBullet: @@ -32,6 +34,8 @@ static func initialize(pos: Vector2, dir: Vector2, speed: float) -> Trap3Tracing func _ready() -> void: + if is_demo: + return collision_layer = TRAP_COLLISION_LAYER collision_mask = 0 leave_wall_detector.collision_mask = WALL_COLLISION_LAYER @@ -104,3 +108,23 @@ func _on_wall_exited(_body: Node2D) -> void: wall_counter -= 1 if wall_counter <= 0: collision_mask = PLAYER_COLLISION_LAYER | WALL_COLLISION_LAYER + + +#------------------------- + + +func serialize_state() -> Dictionary: + return { + "type": "trap3-tracing_bullet", + "position": global_position, + "rotation": rotation, + "scale": sprite.scale, + "feather_effect": feather_effect.emitting + } + + +func apply_demo_state(data: Dictionary) -> void: + global_position = data.get("position", Vector2.ZERO) + rotation = data.get("rotation", 0.0) + sprite.scale = data.get("scale", Vector2.ZERO) + feather_effect.emitting = data.get("feather_effect", false) diff --git a/Scripts/traps/trap4-conveyor.gd b/Scripts/traps/trap4-conveyor.gd index 01716a6d..cf433143 100644 --- a/Scripts/traps/trap4-conveyor.gd +++ b/Scripts/traps/trap4-conveyor.gd @@ -11,6 +11,7 @@ var speed = trap_data["trap4-conveyor"]["speed"] var lifetime = trap_data["trap4-conveyor"]["lifetime"] var area_scale = trap_data["trap4-conveyor"]["scale"] var direction: Vector2 +var is_demo: bool = false var _is_disappearing: bool = false @onready var wave_animation: AnimatedSprite2D = $AnimatedSprite2D @@ -34,6 +35,8 @@ static func initialize(pos: Vector2, dir: Vector2) -> Trap4Conveyor: func _ready() -> void: # Trap should expire after the configured lifetime. + if is_demo: + return scale = Vector2(area_scale, area_scale) await get_tree().create_timer(lifetime).timeout _destroy_trap() @@ -64,3 +67,21 @@ func _on_body_entered(body: Node2D) -> void: func _on_body_exited(body: Node2D) -> void: if body == Global.game_manager.player and body is CharacterBody2D: body.external_velocity -= speed * direction + + +#----------------------------------------- +func serialize_state() -> Dictionary: + return { + "type": "trap4-conveyor", + "position": global_position, + "rotation": rotation, + "scale": scale, + "shader_reveal": wave_animation.material.get_shader_parameter("reveal") + } + + +func apply_demo_state(data: Dictionary) -> void: + global_position = data.get("position", Vector2.ZERO) + rotation = data.get("rotation", 0.0) + wave_animation.material.set_shader_parameter("reveal", data.get("shader_reveal", 1.0)) + scale = data.get("scale", Vector2.ZERO) diff --git a/Scripts/traps/trap6-scanline.gd b/Scripts/traps/trap6-scanline.gd index 5d762225..ed6be526 100644 --- a/Scripts/traps/trap6-scanline.gd +++ b/Scripts/traps/trap6-scanline.gd @@ -17,6 +17,7 @@ var velocity := Vector2(0, 0) var speed := 5.0 var line_pos := Vector2(0, 0) var time := 0.0 +var is_demo := false @onready var visual_line = $Hulas @@ -44,6 +45,8 @@ func _clamp_to_four_directions(dir: Vector2) -> Vector2: # Called when the node enters the scene tree for the first time. func _ready() -> void: + if is_demo: + return visible = true visual_line.visible = true body_entered.connect(_on_body_entered) @@ -70,3 +73,26 @@ func _physics_process(delta: float) -> void: func _on_body_entered(_body: Node2D) -> void: Global.player_hit.emit(damage) + + +#----------------------------------------- +func serialize_state() -> Dictionary: + return { + "type": "trap6-scanline", + "position": global_position, + "rotation": rotation, + "visual_line_modulate": visual_line.modulate, + "visual_line_position": visual_line.position, + "visual_line_scale": visual_line.scale, + "visual_line_rotation": visual_line.rotation + } + + +func apply_demo_state(data: Dictionary) -> void: + global_position = data.get("position", Vector2.ZERO) + rotation = data.get("rotation", 0.0) + visual_line.modulate = data.get("visual_line_modulate", Color.WHITE) + visual_line.position = data.get("visual_line_position", Vector2.ZERO) + visual_line.scale = data.get("visual_line_scale", Vector2.ONE) + visual_line.rotation = data.get("visual_line_rotation", 0.0) + #rotate hulas one by one? From 7b5ec637cc3e47cb047a69e142b67ddfdd507059 Mon Sep 17 00:00:00 2001 From: CJN Date: Tue, 7 Jul 2026 10:50:33 +0800 Subject: [PATCH 2/4] fix: trap6 rotation --- Scripts/network/network_manager.gd | 23 +++++++++++++++++++++++ Scripts/traps/trap6-scanline.gd | 11 +++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Scripts/network/network_manager.gd b/Scripts/network/network_manager.gd index 2ad820a0..1b430d52 100644 --- a/Scripts/network/network_manager.gd +++ b/Scripts/network/network_manager.gd @@ -200,6 +200,13 @@ func _start_from_command_line(args: Array) -> void: var port := get_server_port(args) print("[NetworkManager] startup mode=%s port=%d args=%s" % [mode, port, args]) + if _has_test_trap_flag(args): + var connect_addr := _extract_connect_address(args) + if connect_addr.is_empty(): + connect_addr = DEFAULT_SERVER_ADDRESS + _do_test_trap_start.call_deferred(connect_addr) + return + if _has_demo_flag(args): var connect_addr := _extract_connect_address(args) if connect_addr.is_empty(): @@ -213,6 +220,22 @@ func _start_from_command_line(args: Array) -> void: join_server(get_server_address(args), port) +## Returns true if [param args] contains the --test-trap flag. +func _has_test_trap_flag(args: Array) -> bool: + return args.has("--test-trap") + + +## Loads the trap_test scene and optionally joins the server. +## Called deferred to avoid change_scene_to_file during _ready() tree setup. +func _do_test_trap_start(connect_addr: String) -> void: + get_tree().change_scene_to_file("res://Scenes/trap_test.tscn") + # Only connect if --connect was explicitly provided. + # We re-read args here because _extract_connect_address returns + # DEFAULT_SERVER_ADDRESS when --connect is absent. + if _find_arg_value(OS.get_cmdline_user_args(), "--connect") != "": + join_server(connect_addr) + + ## Returns true if [param args] contains the --demo flag. func _has_demo_flag(args: Array) -> bool: return args.has("--demo") diff --git a/Scripts/traps/trap6-scanline.gd b/Scripts/traps/trap6-scanline.gd index ed6be526..b6850a6f 100644 --- a/Scripts/traps/trap6-scanline.gd +++ b/Scripts/traps/trap6-scanline.gd @@ -18,6 +18,7 @@ var speed := 5.0 var line_pos := Vector2(0, 0) var time := 0.0 var is_demo := false +var hula_rotate := false @onready var visual_line = $Hulas @@ -55,6 +56,7 @@ func _ready() -> void: if abs(line_dir.x) > 0.1: rotation = PI / 2 var hulas = visual_line.get_children() + hula_rotate = true for hula in hulas: hula.rotation = -PI / 2 @@ -84,7 +86,8 @@ func serialize_state() -> Dictionary: "visual_line_modulate": visual_line.modulate, "visual_line_position": visual_line.position, "visual_line_scale": visual_line.scale, - "visual_line_rotation": visual_line.rotation + "visual_line_rotation": visual_line.rotation, + "hula_rotate": hula_rotate } @@ -95,4 +98,8 @@ func apply_demo_state(data: Dictionary) -> void: visual_line.position = data.get("visual_line_position", Vector2.ZERO) visual_line.scale = data.get("visual_line_scale", Vector2.ONE) visual_line.rotation = data.get("visual_line_rotation", 0.0) - #rotate hulas one by one? + if !hula_rotate and data.get("hula_rotate", false): + hula_rotate = true + var hulas = visual_line.get_children() + for hula in hulas: + hula.rotation = -PI / 2 From 9e774be53dbe20549c7d9c9e9de3369c5ee6eec4 Mon Sep 17 00:00:00 2001 From: CJN Date: Tue, 7 Jul 2026 13:46:49 +0800 Subject: [PATCH 3/4] fix: trap3 effect not playing --- Scripts/traps/trap3-tracing_bullet.gd | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Scripts/traps/trap3-tracing_bullet.gd b/Scripts/traps/trap3-tracing_bullet.gd index 0d6fd373..76360a75 100644 --- a/Scripts/traps/trap3-tracing_bullet.gd +++ b/Scripts/traps/trap3-tracing_bullet.gd @@ -16,6 +16,7 @@ var tracing := true var flying := false var wall_counter := 0 var is_demo := false +var effect_reparented := false @onready var feather_effect = $FeatherEffect @onready var leave_wall_detector = $Area2D @onready var wait_timer = $WaitTimer @@ -49,6 +50,8 @@ func _ready() -> void: func _destroy() -> void: + $CollisionShape2D.set_deferred("disabled", true) + await get_tree().create_timer(0.1).timeout queue_free() @@ -128,3 +131,7 @@ func apply_demo_state(data: Dictionary) -> void: rotation = data.get("rotation", 0.0) sprite.scale = data.get("scale", Vector2.ZERO) feather_effect.emitting = data.get("feather_effect", false) + feather_effect.global_position = global_position + if !effect_reparented: + effect_reparented = true + feather_effect.reparent($"..") From b953b20a1b3980da10ff68c1e2f3123d90e9f035 Mon Sep 17 00:00:00 2001 From: cmj0415 Date: Wed, 8 Jul 2026 14:21:23 +0800 Subject: [PATCH 4/4] chore: remove lines for --trap-test flag --- Scripts/network/network_manager.gd | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/Scripts/network/network_manager.gd b/Scripts/network/network_manager.gd index 1b430d52..2ad820a0 100644 --- a/Scripts/network/network_manager.gd +++ b/Scripts/network/network_manager.gd @@ -200,13 +200,6 @@ func _start_from_command_line(args: Array) -> void: var port := get_server_port(args) print("[NetworkManager] startup mode=%s port=%d args=%s" % [mode, port, args]) - if _has_test_trap_flag(args): - var connect_addr := _extract_connect_address(args) - if connect_addr.is_empty(): - connect_addr = DEFAULT_SERVER_ADDRESS - _do_test_trap_start.call_deferred(connect_addr) - return - if _has_demo_flag(args): var connect_addr := _extract_connect_address(args) if connect_addr.is_empty(): @@ -220,22 +213,6 @@ func _start_from_command_line(args: Array) -> void: join_server(get_server_address(args), port) -## Returns true if [param args] contains the --test-trap flag. -func _has_test_trap_flag(args: Array) -> bool: - return args.has("--test-trap") - - -## Loads the trap_test scene and optionally joins the server. -## Called deferred to avoid change_scene_to_file during _ready() tree setup. -func _do_test_trap_start(connect_addr: String) -> void: - get_tree().change_scene_to_file("res://Scenes/trap_test.tscn") - # Only connect if --connect was explicitly provided. - # We re-read args here because _extract_connect_address returns - # DEFAULT_SERVER_ADDRESS when --connect is absent. - if _find_arg_value(OS.get_cmdline_user_args(), "--connect") != "": - join_server(connect_addr) - - ## Returns true if [param args] contains the --demo flag. func _has_demo_flag(args: Array) -> bool: return args.has("--demo")