Initial project sync
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
extends SceneTree
|
||||
|
||||
## zhan_bo (S charge + Space) must release along the player's current facing —
|
||||
## never auto-aim at the nearest enemy — and projectile collision circles must
|
||||
## stay inside the visible bullet/wave art.
|
||||
|
||||
var failures: Array[String] = []
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
_run.call_deferred()
|
||||
|
||||
|
||||
func _run() -> void:
|
||||
await _check_release_follows_facing()
|
||||
await _check_projectile_collision_fits_visual()
|
||||
_finish()
|
||||
|
||||
|
||||
func _check_release_follows_facing() -> void:
|
||||
var parent := Node2D.new()
|
||||
root.add_child(parent)
|
||||
var player_scene := load("res://scenes/characters/player.tscn") as PackedScene
|
||||
var action := load("res://resources/actions/zhan_bo_lv1.tres") as Resource
|
||||
_expect(player_scene != null, "player scene should load")
|
||||
_expect(action != null, "zhan_bo action should load")
|
||||
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)
|
||||
# An enemy on the RIGHT must not pull the release direction anymore.
|
||||
var decoy := Node2D.new()
|
||||
decoy.add_to_group("enemies")
|
||||
parent.add_child(decoy)
|
||||
decoy.global_position = Vector2(1400.0, 560.0)
|
||||
await process_frame
|
||||
|
||||
player.set("heading", Vector2.LEFT)
|
||||
var left_direction := player.call("projectile_direction", action) as Vector2
|
||||
_expect(left_direction.x < 0.0, "facing left should release the wave to the left even with an enemy on the right")
|
||||
var left_spawn := player.call("projectile_spawn_position", action) as Vector2
|
||||
_expect(left_spawn.x < player.global_position.x, "left release should spawn the wave on the player's left side")
|
||||
|
||||
player.set("heading", Vector2.RIGHT)
|
||||
var right_direction := player.call("projectile_direction", action) as Vector2
|
||||
_expect(right_direction.x > 0.0, "facing right should release the wave to the right")
|
||||
var right_spawn := player.call("projectile_spawn_position", action) as Vector2
|
||||
_expect(right_spawn.x > player.global_position.x, "right release should spawn the wave on the player's right side")
|
||||
parent.free()
|
||||
|
||||
|
||||
func _check_projectile_collision_fits_visual() -> void:
|
||||
var projectile_scene := load("res://scenes/combat/player_projectile.tscn") as PackedScene
|
||||
_expect(projectile_scene != null, "projectile scene should load")
|
||||
if projectile_scene == null:
|
||||
return
|
||||
|
||||
var bullet := projectile_scene.instantiate() as Area2D
|
||||
root.add_child(bullet)
|
||||
var wave := projectile_scene.instantiate() as Area2D
|
||||
wave.set("visual_profile", &"wave")
|
||||
root.add_child(wave)
|
||||
await process_frame
|
||||
|
||||
var bullet_shape := _circle_shape(bullet)
|
||||
var wave_shape := _circle_shape(wave)
|
||||
_expect(bullet_shape != null, "bullet projectile should keep a CircleShape2D")
|
||||
_expect(wave_shape != null, "wave projectile should keep a CircleShape2D")
|
||||
if bullet_shape != null:
|
||||
# effect_sheet flight frames are ~32x18px visible at scale 2.
|
||||
_expect(float(bullet_shape.radius) <= 9.0, "bullet collision radius (%s) must not exceed the visible bolt half-height 9" % str(bullet_shape.radius))
|
||||
if wave_shape != null:
|
||||
# Smallest wave frame is ~66x65px visible at scale 0.55.
|
||||
_expect(float(wave_shape.radius) <= 32.5, "wave collision radius (%s) must fit inside the smallest wave frame" % str(wave_shape.radius))
|
||||
if bullet_shape != null and wave_shape != null:
|
||||
_expect(bullet_shape != wave_shape, "profiles must not share one CircleShape2D subresource")
|
||||
_expect(float(wave_shape.radius) > float(bullet_shape.radius), "wave hit circle should stay larger than the small bullet's")
|
||||
bullet.queue_free()
|
||||
wave.queue_free()
|
||||
|
||||
|
||||
func _circle_shape(projectile: Area2D) -> CircleShape2D:
|
||||
if projectile == null:
|
||||
return null
|
||||
var shape_node := projectile.get_node_or_null("CollisionShape2D") as CollisionShape2D
|
||||
if shape_node == null:
|
||||
return null
|
||||
return shape_node.shape as CircleShape2D
|
||||
|
||||
|
||||
func _expect(condition: bool, label: String) -> void:
|
||||
if not condition:
|
||||
failures.append(label)
|
||||
|
||||
|
||||
func _finish() -> void:
|
||||
if failures.is_empty():
|
||||
print("PASS zhan_bo release facing and projectile collision fit")
|
||||
quit(0)
|
||||
else:
|
||||
for failure: String in failures:
|
||||
push_error(failure)
|
||||
quit(1)
|
||||
Reference in New Issue
Block a user