saumwacht-godot/tools/luneraria/people_lineup.gd
Martin Stickelbroeck faf0fbdef0 M3: Balance, Kartenprops, sieben Volksrepräsentanten und Abnahme
Bots planen Items/Champions vor der Armee und helfen deterministisch,
damit Spiegelmatches fair bleiben. Boss und Profile neu abgestimmt;
Balance-, Stress- und Volks-Werkzeuge sowie Kartenprops ergänzt.
2026-09-28 00:41:05 +02:00

86 lines
3.7 KiB
GDScript

extends Node3D
## Review lineup for the seven people representatives: the imported GLBs through
## AssetLibrary (same material path as in the match), posed at fixed clip times.
## Run (window): godot --path . res://tools/luneraria/people_lineup.tscn -- --out=res://docs/luneraria/screenshots
const Sanctuary = preload("res://scripts/presentation/sanctuary.gd")
const IDS: Array[String] = ["p_mensch", "p_elf", "p_zwerg", "p_troll", "p_fee", "p_ork", "p_biest"]
const POSES: Array = [["idle", 0.6, "ruhe"], ["attack_a", 0.9, "kontakt"], ["walk", 0.25, "laufen"], ["ability", 0.8, "faehigkeit"], ["death", 2.0, "tod"]]
var figures: Array = []
var camera: Camera3D
var out: String = "res://docs/luneraria/screenshots"
func _ready() -> void:
for arg: String in OS.get_cmdline_user_args():
if arg.begins_with("--out="):
out = arg.substr(6)
var environment := WorldEnvironment.new()
environment.environment = Environment.new()
environment.environment.background_mode = Environment.BG_COLOR
environment.environment.background_color = Color(.16, .18, .2)
environment.environment.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR
environment.environment.ambient_light_color = Color(.55, .58, .62)
environment.environment.ambient_light_energy = .6
environment.environment.tonemap_mode = Environment.TONE_MAPPER_ACES
add_child(environment)
var sun := DirectionalLight3D.new()
sun.rotation = Vector3(deg_to_rad(-48), deg_to_rad(-32), 0)
sun.light_energy = 1.35
sun.shadow_enabled = true
add_child(sun)
var ground := MeshInstance3D.new()
var plane := PlaneMesh.new()
plane.size = Vector2(24, 10)
ground.mesh = plane
var soil := StandardMaterial3D.new()
soil.resource_name = "ENV_soil_path"
soil.albedo_color = Color(.36, .31, .24)
ground.material_override = Sanctuary.terrain_material(soil)
add_child(ground)
for index: int in range(IDS.size()):
var figure: Node3D = AssetLibrary.instantiate_fighter(IDS[index])
if figure == null:
push_error("missing figure " + IDS[index])
continue
figure.position = Vector3((float(index) - 3.0) * 1.7, 0, 0)
figure.rotation.y = deg_to_rad(18)
add_child(figure)
figures.append(figure)
var label := Label3D.new()
var record: Dictionary = {}
for entry: Dictionary in JSON.parse_string(FileAccess.get_file_as_string("res://assets/luneraria/peoples_manifest.json")).assets:
if entry.id == IDS[index]:
record = entry
label.text = "%s\n%s" % [record.get("people", IDS[index]), record.get("name", "")]
label.font_size = 44
label.pixel_size = .004
label.outline_size = 10
label.position = figure.position + Vector3(0, -0.02, 1.1)
label.rotation.x = deg_to_rad(-60)
add_child(label)
camera = Camera3D.new()
camera.fov = 34
add_child(camera)
camera.look_at_from_position(Vector3(0, 2.4, 10.4), Vector3(0, .95, 0))
camera.current = true
call_deferred("run")
func run() -> void:
DirAccess.make_dir_recursive_absolute(ProjectSettings.globalize_path(out))
for pose: Array in POSES:
for figure: Node3D in figures:
figure.preview(pose[0], pose[1])
for frame: int in range(8):
await get_tree().process_frame
get_viewport().get_texture().get_image().save_png("%s/peoples-%s.png" % [out, pose[2]])
print("LINEUP ", pose[2])
# Close-up of the first three and the last four for detail.
for group: Array in [[0, 3, "a"], [3, 7, "b"]]:
var centre: float = ((float(group[0]) + float(group[1]) - 1.0) / 2.0 - 3.0) * 1.7
camera.fov = 26
camera.look_at_from_position(Vector3(centre, 1.9, 6.2), Vector3(centre, 1.0, 0))
for figure: Node3D in figures:
figure.preview("idle", 0.6)
for frame: int in range(8):
await get_tree().process_frame
get_viewport().get_texture().get_image().save_png("%s/peoples-detail-%s.png" % [out, group[2]])
get_tree().quit()