Files
ElHombreAlex--FTL-Faster-Th…/tools/capture_damage_visuals.gd
T

137 lines
5.7 KiB
GDScript

extends SceneTree
const ShipModel = preload("res://scripts/ship_model.gd")
const Effects = preload("res://scripts/combat_effects.gd")
const UiAssets = preload("res://scripts/ftl_ui_assets.gd")
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
# Presentation fixtures only. No bridge, game process, input or save writes.
root.size = Vector2i(1400, 900)
var world := WorldEnvironment.new()
var environment := Environment.new()
environment.background_mode = Environment.BG_COLOR
environment.background_color = Color("101923")
environment.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR
environment.ambient_light_color = Color("d4e7f2")
environment.ambient_light_energy = 0.65
world.environment = environment
root.add_child(world)
var light := DirectionalLight3D.new()
light.rotation_degrees = Vector3(-50, -25, 0)
light.light_energy = 1.2
root.add_child(light)
var camera := Camera3D.new()
camera.projection = Camera3D.PROJECTION_ORTHOGONAL
camera.size = 1.15
camera.position = Vector3(0.1, 1.8, 1.1)
root.add_child(camera)
camera.look_at(Vector3.ZERO)
var ship := ShipModel.new()
root.add_child(ship)
ship.build("__damage_fixture__", true)
ship.inspect_rooms = true
ship.set_process(false)
var rooms: Array = []
for id in range(6):
rooms.append({"id": id, "visible": id != 3, "oxygen": 0 if id == 5 else 100,
"breach_tiles": [{"x": 175, "y": 35 if id == 4 else 105}] if id >= 4 else []})
ship.apply_live({"rooms": rooms, "room_systems": {"0": "shields", "1": "weapons", "2": "engines", "3": "oxygen"},
"system_status": [{"room_id": 0, "health": 4, "max_health": 4, "health_visible": true, "health_detail_visible": true},
{"room_id": 1, "health": 2, "max_health": 4, "repair_progress": 0.55, "health_visible": true, "health_detail_visible": true},
{"room_id": 2, "health": 0, "max_health": 2, "health_visible": true, "health_detail_visible": true},
{"room_id": 3, "health": 1, "max_health": 3, "health_visible": true, "health_detail_visible": false}]})
ship.room_hazards.animate(0.38)
var labels := Node3D.new()
root.add_child(labels)
for item in [["FULL", 0], ["REPAIRING", 1], ["DISABLED", 2], ["SENSOR FOG", 3], ["AIR ESCAPING", 4], ["VACUUM", 5]]:
var area: Area3D = ship.room_nodes[item[1]]
_world_label(labels, item[0], area.position + Vector3(0, 0.11, 0.0), 0.0012)
var title := _caption("SYSTEM CONDITION / NATIVE REPAIR / BREACHES", Vector2(46, 35), 34)
var footer := _caption("Native damage changes room and utility colours. Repaired systems clear them; fog hides breach locations.", Vector2(46, 840), 23)
await _capture("damage_rooms_fixture.png")
labels.hide()
title.text = "VANILLA CROSS BREACH / OXYGEN-DRIVEN AIR"
footer.text = "The opening stays at the native tile center. Escaping air stops when the room has no oxygen."
camera.size = 0.52
camera.position = ship.room_nodes[4].position + Vector3(0.20, 0.6, 0.6)
camera.look_at(ship.room_nodes[4].position)
await _capture("breach_cross_fixture.png")
ship.queue_free()
labels.queue_free()
await process_frame
var sender := ShipModel.new()
root.add_child(sender)
sender.build("__damage_fixture__", false)
sender.set_process(false)
sender.hide()
sender.position = Vector3(-1.5, 0, 0)
sender.scale = Vector3.ONE * 0.30
var effects := Effects.new()
root.add_child(effects)
effects.set_process(false)
var targets: Array[Node3D] = []
for i in range(3):
var receiver := ShipModel.new()
root.add_child(receiver)
receiver.build("__damage_fixture__", true)
receiver.set_process(false)
receiver.scale = Vector3.ONE * 0.30
receiver.position = Vector3((i - 1) * 0.76, 0, 0)
receiver.inspect_rooms = true
receiver.apply_live({"rooms": [{"id": 0, "visible": true}], "shield": 2 if i == 1 else 0})
targets.append(receiver)
_world_label(root, ["HULL HIT", "SHIELD HIT", "EVADED"][i], receiver.position + Vector3(0, 0.40, 0), 0.0018)
var point: Dictionary = {"x": 70, "y": 70}
effects.resolve_live({"projectile_id": "fixture-hull", "outcome": "hull", "target": point}, targets[0])
effects.resolve_live({"projectile_id": "fixture-shield", "outcome": "shield", "target": point}, targets[1])
effects.spawn_shot({"kind": "missile", "outcome": "pending", "projectile_id": "fixture-miss", "target": point}, sender, targets[2])
effects.update_live_projectiles([{"id": "fixture-miss", "progress": 0.93, "missed": true}])
effects._process(0.06)
camera.size = 1.45
camera.position = Vector3(0.30, 2.3, 2.2)
camera.look_at(Vector3(0, 0.1, 0))
title.text = "ACTUAL OUTCOMES / DISTINCT FEEDBACK"
footer.text = "Orange hull impact / blue shield absorption / passing missile and MISS. Evasion never creates an impact."
await _capture("miss_outcomes_fixture.png")
print("DAMAGE_VISUAL_CAPTURE PASS")
quit()
func _capture(filename: String) -> void:
for i in range(12):
await process_frame
await RenderingServer.frame_post_draw
var path := ProjectSettings.globalize_path("res://local_game_data/" + filename)
root.get_texture().get_image().save_png(path)
print("DAMAGE_VISUAL_CAPTURE ", path)
func _world_label(parent: Node, text: String, point: Vector3, pixel_size: float) -> void:
var label := Label3D.new()
label.text = text
label.font = UiAssets.font("body")
label.font_size = 32
label.pixel_size = pixel_size
label.modulate = Color("fff2c4")
label.outline_size = 4
label.billboard = BaseMaterial3D.BILLBOARD_ENABLED
label.no_depth_test = true
label.position = point
parent.add_child(label)
func _caption(text: String, point: Vector2, font_size: int) -> Label:
var label := Label.new()
label.text = text
label.position = point
label.add_theme_font_override("font", UiAssets.font("body"))
label.add_theme_font_size_override("font_size", font_size)
label.modulate = Color("fff2c4")
root.add_child(label)
return label