extends SceneTree var failures: Array[String] = [] func _init() -> void: _run.call_deferred() func _run() -> void: await _check_blade_rain_lands_on_player_ground("res://resources/actions/jian_yu_left_lv3.tres", Vector2.LEFT, "A/left") await _check_blade_rain_lands_on_player_ground("res://resources/actions/jian_yu_right_lv3.tres", Vector2.RIGHT, "D/right") _finish() func _check_blade_rain_lands_on_player_ground(action_path: String, heading: Vector2, label: String) -> void: var parent := Node2D.new() root.add_child(parent) var player_scene := load("res://scenes/characters/player.tscn") as PackedScene var action := load(action_path) as Resource _expect(player_scene != null, "%s player scene should load" % label) _expect(action != null, "%s action should load" % label) if player_scene == null or action == null: parent.free() return var player := player_scene.instantiate() as Node2D parent.add_child(player) player.global_position = Vector2(1000.0, 560.0) player.set("heading", heading) await process_frame player.call("_spawn_world_fx", action) await process_frame var tile_count := 0 for child: Node in parent.get_children(): if child == player: continue var fx := child as Node2D if fx == null: continue var texture := child.get("texture") as Texture2D if texture == null or texture.resource_path.find("rain_lading_tile") == -1: continue tile_count += 1 var vframes := maxi(1, int(child.get("vframes"))) var sprite_scale := child.get("sprite_scale") as Vector2 var frame_height := float(texture.get_height()) / float(vframes) var visual_bottom_y := fx.global_position.y + frame_height * sprite_scale.y * 0.5 # The player art keeps its feet above the frame bottom, so the visible # ground line sits VISIBLE_GROUND_LINE_OFFSET above the actor origin. var ground_line_y: float = player.global_position.y + float(player.get_script().VISIBLE_GROUND_LINE_OFFSET) _expect_float(visual_bottom_y, ground_line_y, "%s blade-rain landing tile bottom should share the player's visible ground line" % label) _expect_int(tile_count, 8, "%s level-3 blade rain should spawn eight landing tiles" % label) parent.free() func _expect(condition: bool, label: String) -> void: if not condition: failures.append(label) func _expect_float(actual: float, expected: float, label: String) -> void: if absf(actual - expected) > 0.02: failures.append("%s: expected %.3f, got %.3f" % [label, expected, actual]) func _expect_int(actual: int, expected: int, label: String) -> void: if actual != expected: failures.append("%s: expected %d, got %d" % [label, expected, actual]) func _finish() -> void: if failures.is_empty(): print("PASS blade rain alignment") quit(0) else: for failure: String in failures: push_error(failure) quit(1)