Files
zombie-fps/tools/test_gameplay_improvements.gd
T

118 lines
3.9 KiB
GDScript

extends SceneTree
const Zombie = preload("res://scripts/zombie.gd")
var world: Node3D
var player: Node3D
func _initialize() -> void:
call_deferred("run_test")
func _freeze_others(actor: Node = null) -> void:
for zombie in get_nodes_in_group("live_zombies"):
if zombie != actor:
zombie.set_physics_process(false)
func run_test() -> void:
world = load("res://scenes/main.tscn").instantiate()
root.add_child(world)
player = world.player
player.set_physics_process(false)
player.touch_mode = true
_freeze_others()
player.hp = 20
player.ammo = 3
world.hud.update_status(player, 4, 1200)
assert(world.hud.health_value.text == "20")
assert(world.hud.ammo_value.text == "03 / 30")
assert(world.hud.health_value.get_theme_color("font_color") == world.hud.DANGER)
assert(not world.hud.help.visible)
print("PASS: HUD numeri, vita bassa, caricatore e modalita' touch")
player.hp = 100
player.ammo = 1
player.shoot()
assert(player.ammo == 0 and player.reloading)
var release_count := 0
for speaker in player.get_children():
if speaker is AudioStreamPlayer and speaker.stream.resource_path.ends_with("cliprelease1.wav"):
release_count += 1
player.start_reload() # must not add another reload
var repeated_count := 0
for speaker in player.get_children():
if speaker is AudioStreamPlayer and speaker.stream.resource_path.ends_with("cliprelease1.wav"):
repeated_count += 1
assert(repeated_count == release_count)
await create_timer(1.7).timeout
assert(player.ammo == 30 and not player.reloading)
print("PASS: ultimo colpo avvia auto-reload e completa a 30")
# Shared grid route: actual physics movement, not just returned waypoints.
Engine.time_scale = 4
var cases := [
[Vector3(-5, 0.1, -6.5), Vector3(-5, 0.1, 0)],
[Vector3(5, 0.1, 1.5), Vector3(5, 0.1, 7.5)],
[Vector3(-6, 0.1, 4), Vector3(-2, 0.1, 4)],
[Vector3(6.8, 0.1, -6), Vector3(6.8, 0.1, -2)],
]
player.hp = 10000
for positions in cases:
player.position = positions[1]
var actor := CharacterBody3D.new()
actor.set_script(Zombie)
actor.player = player
actor.navigation = world.navigation
actor.position = positions[0]
world.add_child(actor)
actor.entering = false
actor.speed = 3
var reached := false
for i in 420:
_freeze_others(actor)
await physics_frame
var delta: Vector3 = actor.position - player.position
delta.y = 0
if delta.length() < 1.8:
reached = true
break
assert(reached, "Zombie bloccato: %s -> %s, finale %s" % [positions[0], positions[1], actor.position])
actor.queue_free()
await process_frame
print("PASS: inseguimento fisico attorno a entrambe le scrivanie, sedie e bidone")
Engine.time_scale = 1
# A melee ray across the left desk must not hit through it.
player.position = Vector3(-5, 0.1, -3.2)
var actor := CharacterBody3D.new()
actor.set_script(Zombie)
actor.player = player
actor.position = Vector3(-5, 0.1, -4.8)
world.add_child(actor)
actor.entering = false
actor.set_physics_process(false)
await physics_frame
await physics_frame
assert(not actor._attack_clear())
var hp_before: float = player.hp
actor._attack()
assert(player.hp == hp_before)
print("PASS: nessun attacco attraverso la scrivania")
_freeze_others()
player.hp = 100
player.ammo = 1
player.shoot()
assert(player.reloading)
player.take_damage(1000)
var flatlines := 0
for speaker in player.get_children():
if speaker is AudioStreamPlayer and speaker.stream.resource_path.ends_with("flatline.wav"):
flatlines += 1
assert(flatlines == 1)
player.take_damage(10)
flatlines = 0
for speaker in player.get_children():
if speaker is AudioStreamPlayer and speaker.stream.resource_path.ends_with("flatline.wav"):
flatlines += 1
assert(flatlines == 1)
await create_timer(1.8).timeout
assert(player.hp == 0 and player.ammo == 0 and not player.reloading)
print("PASS: flatline una volta e auto-reload annullato dalla morte")
world.queue_free()
await process_frame
quit()