- assets/audio/music/zombie_industrial_loop.ogg: 57.60 s Ogg Vorbis loop generated locally with YuE2-3B on the Tesla V100 (score written for this track; vocals removed with HTDemucs). The loop is spliced at the track's structural repeat with a 0.6 s crossfade: measured seam dip <= 1.6 dB. - scripts/main.gd: "Music" AudioStreamPlayer at -11 dB, started at boot on desktop and on the start click on Web (browser autoplay policy). It forces stream.loop at runtime because the Web staging step re-imports the OGG with loop=false. - tools/test_music.gd: soundtrack test (loop, length, volume, playback, still playing after player death). - docs/MUSIC.md: source, loop construction, verification, licence. - docs/WEB-DEPLOY.md: release ab6054111f5919a8 notes. Initial commit of the project.
53 lines
2.0 KiB
GDScript
53 lines
2.0 KiB
GDScript
extends SceneTree
|
|
var world: Node3D
|
|
func _initialize() -> void:
|
|
call_deferred("run_test")
|
|
func run_test() -> void:
|
|
world = load("res://scenes/main.tscn").instantiate()
|
|
root.add_child(world)
|
|
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
|
await create_timer(2.4).timeout
|
|
var zombie: Node3D
|
|
for child in world.get_children():
|
|
if child.get_script() == world.ZombieScript:
|
|
zombie = child
|
|
break
|
|
assert(zombie != null)
|
|
world.player.hp = 10000
|
|
zombie.position = Vector3(0, 0, -3)
|
|
if zombie.entry_tween:
|
|
zombie.entry_tween.kill()
|
|
zombie.entering = false
|
|
var point := zombie.global_position + Vector3(0, 1.2, 0)
|
|
preload("res://scripts/blood_effects.gd").impact(world, point, Vector3(0, 0, -1))
|
|
zombie.take_damage(1000, point.y)
|
|
assert(zombie.dead and zombie.collision_layer == 0)
|
|
await create_timer(0.2).timeout
|
|
assert(get_nodes_in_group("blood_stains").size() == 1)
|
|
if DisplayServer.get_name() != "headless":
|
|
await RenderingServer.frame_post_draw
|
|
root.get_texture().get_image().save_png("/tmp/zombie-blood.png")
|
|
await create_timer(4.3).timeout
|
|
assert(is_instance_valid(zombie) and zombie.is_inside_tree())
|
|
assert(absf(zombie.position.y) < 0.01)
|
|
assert(get_nodes_in_group("zombie_corpses").has(zombie))
|
|
if DisplayServer.get_name() != "headless":
|
|
await RenderingServer.frame_post_draw
|
|
root.get_texture().get_image().save_png("/tmp/zombie-corpse.png")
|
|
world.player.take_damage(20000)
|
|
world.player.take_damage(12)
|
|
assert(world.player.death_started and world.player.hp == 0)
|
|
var ammo: int = world.player.ammo
|
|
world.player.shoot()
|
|
assert(world.player.ammo == ammo)
|
|
await create_timer(3).timeout
|
|
assert(world.player.camera.position.y < 0.25)
|
|
assert(world.player.death_overlay.color.a > 0.99)
|
|
if DisplayServer.get_name() != "headless":
|
|
await RenderingServer.frame_post_draw
|
|
root.get_texture().get_image().save_png("/tmp/zombie-death-fade.png")
|
|
print("PASS: persistent corpse, blood decal, single death, blocked shooting, camera fall, black fade")
|
|
world.queue_free()
|
|
await process_frame
|
|
quit()
|