extends SceneTree func _initialize() -> void: call_deferred("run_test") func run_test() -> void: var world = load("res://scenes/main.tscn").instantiate() root.add_child(world) var office = world.get_node("OfficeAtmosphere") assert(get_nodes_in_group("office_props").size() == 6) var desks := 0 var chairs := 0 for prop in get_nodes_in_group("office_props"): if prop.name.begins_with("OfficeDesk"): desks += 1 if prop.name.begins_with("OfficeChair"): chairs += 1 assert(prop.collision_layer == 1) assert(desks == 2 and chairs == 3) print("PASS: due scrivanie, tre sedie, bidone con collisioni") var flames = office.get_node("FireBarrel/BarrelFlames") assert(flames is CPUParticles3D and flames.amount == 28 and flames.emitting) assert(office.fire_light.shadow_enabled) assert(office.fire_rig is Node3D and office.fire_rig.flame == flames) for i in 100: office.fire_rig._process(0.016) var energy: float = office.fire_light.light_energy assert(energy >= office.fire_rig.MIN_ENERGY and energy <= office.fire_rig.MAX_ENERGY) print("PASS: fiamme CPU leggere e flicker continuo entro limiti") var lights: Array[Node] = world.find_children("*", "OmniLight3D", true, false) assert(lights.size() == 6) # due lampade, principale + rimbalzo + nucleo, muzzle flash assert(world.find_children("DeskLampLight", "OmniLight3D", true, false).size() == 2) var shadow_casters := lights.filter(func(light): return light.shadow_enabled) assert(shadow_casters.size() == 1 and shadow_casters[0] == office.fire_light) for node in world.get_children(): assert(not node is OmniLight3D) # nessuna plafoniera if node is WorldEnvironment: assert(node.environment.ambient_light_energy <= 0.15) assert(node.environment.glow_enabled and node.environment.glow_hdr_threshold >= 1.2) print("PASS: plafoniera rimossa, ambient basso, una sola luce con ombre su sei totali") await physics_frame await physics_frame var space = world.get_world_3d().direct_space_state # Ogni finestra deve essere un'APERTURA e deve essere COLLEGATA al centro: gli zombie # entrano e devono poter arrivare. Il raggio prova l'apertura; il percorso A* prova # la raggiungibilita', anche quando un arredo cade su una diagonale. var inside_points: Array[Vector3] = [] for window in world.room.windows: var edge: Vector3 = window.center + Vector3(window.normal) * 0.8 + Vector3(0, 0.8, 0) var q := PhysicsRayQueryParameters3D.create(edge, Vector3(0, 0.8, 0), 1) q.exclude = [world.player.get_rid()] inside_points.append(edge) if not space.intersect_ray(q).is_empty(): print(" (nota: un arredo ostruisce la diagonale da ", edge, " al centro)") assert(inside_points.size() >= 8) for point in inside_points: var path: PackedVector3Array = world.navigation.route(point, Vector3(0, 0, 0)) assert(path.size() >= 2) # raggiungibile dal centro assert(path[path.size() - 1].distance_to(Vector3.ZERO) < 1.5) var q := PhysicsRayQueryParameters3D.create(Vector3(-5, 0.5, -2), Vector3(-5, 0.5, -4), 1) assert(not space.intersect_ray(q).is_empty()) print("PASS: otto aperture libere e tutte collegate al centro dalla navigazione, scrivanie solide") if "--screenshot" in OS.get_cmdline_user_args(): world.player.set_physics_process(false) world.player.position = Vector3(0, 0.1, 0) world.player.camera.rotation.x = -0.08 for i in 3: if i == 2: world.player.look_at(Vector3(-4, 0.1, 4)) else: world.player.rotation.y = -PI * 0.25 if i == 0 else PI * 0.25 + PI await create_timer(0.4).timeout await RenderingServer.frame_post_draw root.get_texture().get_image().save_png("/tmp/zombie-office-%d.png" % i) world.queue_free() await process_frame quit()