Files
Blockline/tests/auto_reload.gd
T

72 lines
3.1 KiB
GDScript

extends SceneTree
var failed := 0
var total := 0
func _initialize() -> void: call_deferred("run")
func check(ok: bool, title: String) -> void:
total += 1
if not ok: failed += 1
print("PASS " if ok else "FAIL ", title)
func run() -> void:
var game: Node3D = load("res://scenes/main.tscn").instantiate()
root.add_child(game)
game.port = 27986
game.host({"server_name":"Foundation", "mode":"FFA", "max_players":2, "bots":0, "score_limit":100, "time_limit":600})
game.set_physics_process(false)
var p: Fighter = game.players[1]
p.set_physics_process(false)
p.set_process(false)
p.reset_at(Vector3(0, 0.1, 28))
check(p.shape.shape is CapsuleShape3D and p.find_children("*", "CollisionShape3D", true, false).size() == 1, "fighter exclusively uses one capsule")
var scans: Node = game.arena.get_node("QuarryRouteRocks")
var bodies: Array[Node] = scans.find_children("*", "StaticBody3D", true, false)
check(bodies.size() == 2, "two scan mesh colliders restored on headless host")
var boxes := true
for body in bodies: boxes = boxes and body.get_child(0).shape is ConcavePolygonShape3D
check(boxes, "route scans use original triangle collision")
var motion := InputEventMouseMotion.new()
motion.screen_relative = Vector2(20, -10)
motion.relative = Vector2(999,999)
FpsCamera.mouse(p, motion, 0.001)
check(is_equal_approx(p.yaw, -0.02) and is_equal_approx(p.pitch, 0.01), "raw screen-relative mouse input applied without smoothing")
p.view_controller.begin_physics(p)
var body_position := p.global_position
for rate in [60, 120, 144, 240]:
p.view_controller.render(p, 1.0 / rate)
check(p.global_position == body_position and is_equal_approx(p.camera.global_rotation.y, p.yaw), "camera render preserves physics and direct yaw at %s Hz" % rate)
game.headless = false
game.hud.hit_time = 0
game.shot_event(p.eye(), p.peer_id, p.weapon, false, false)
check(p.gun.muzzle.visible and p.gun.recoil_velocity.length() > 0 and game.hud.shot_time > 0, "single shot event immediately starts flash, recoil and crosshair pulse")
check(game.hud.hit_time == 0, "miss does not fake a hitmarker")
var recoil_before: Vector2 = p.gun.recoil_velocity
p.magazines[p.weapon] -= 1
p.shot_serial += 1
p.gun.animate(p, 0.0)
check(p.gun.recoil_velocity.is_equal_approx(recoil_before), "snapshot ammo change does not duplicate recoil")
game.shot_event(p.eye(), p.peer_id, p.weapon, true, true)
check(game.hud.hit_time > 0 and game.hud.head_hit, "confirmed headshot adds hit feedback in same event")
p.weapon = 0
p.reload_left = 0
p.melee_left = 0
p.mantle_left = 0
p.rope_active = false
p.infinite_left = 0
p.magazines[0] = 0
p.reserves[0] = 30
p.input_data = {}
game.combat.actions(p)
check(p.reload_left > 0, "empty magazine reloads without firing or pressing reload")
p.reload_left = 0
p.reserves[0] = 0
game.combat.actions(p)
check(p.reload_left == 0, "no reload without reserve ammunition")
p.reserves[0] = 30
p.infinite_left = 10
game.combat.actions(p)
check(p.reload_left == 0, "infinite ammunition prevents automatic reload")
game.leave()
game.queue_free()
await process_frame
print("AUTO RELOAD RESULT ", total - failed, "/", total)
quit(1 if failed else 0)