131 lines
6.2 KiB
GDScript
131 lines
6.2 KiB
GDScript
extends SceneTree
|
|
|
|
## M79-I10 gate: the Region Atlas page renders at the single target size.
|
|
##
|
|
## Two locales, two text scales, three views (static / dynamic / final) with the
|
|
## shared ink checker on every capture. Fixtures are copied facts, not state.
|
|
|
|
const AtlasView = preload("res://entry/views/region_atlas_page_view.gd")
|
|
const AtlasController = preload("res://entry/region_atlas_page_controller.gd")
|
|
const InkCheck = preload("res://tools/ui_ink_check.gd")
|
|
|
|
const FIXTURE := [{"width": 1280.0, "height": 720.0}]
|
|
const LOCALES := ["zh_CN", "en"]
|
|
const TEXT_SCALES := [1.0, 1.3]
|
|
|
|
var output_root := ""
|
|
var ink_scanned := 0
|
|
var ink_violations: Array = []
|
|
var probe_text_scale := 1.0
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("_run")
|
|
|
|
|
|
func _run() -> void:
|
|
if OS.get_environment("ABG_EVIDENCE_DIR").is_empty():
|
|
push_error("atlas probe requires the owned test-attempt runner")
|
|
quit(1)
|
|
return
|
|
output_root = OS.get_environment("ABG_EVIDENCE_DIR").path_join("atlas-visual-probe")
|
|
DirAccess.make_dir_recursive_absolute(output_root)
|
|
var self_test := InkCheck.self_test(root)
|
|
if self_test.size() < 3:
|
|
push_error("M79 ink self-test expected at least 3 violations, got %d" % self_test.size())
|
|
quit(1)
|
|
return
|
|
print("ABG_M79_ATLAS_INK_SELF_TEST_OK violations=%d" % self_test.size())
|
|
for fixture in FIXTURE:
|
|
for locale in LOCALES:
|
|
for scale in TEXT_SCALES:
|
|
await _capture(int(fixture.width), int(fixture.height), String(locale), float(scale))
|
|
if not ink_violations.is_empty():
|
|
for violation in ink_violations:
|
|
push_error("M79 atlas ink %s %s [%s] %s: %s" % [
|
|
violation.locale, violation.size, violation.path, violation.node, violation.detail])
|
|
print("ABG_M79_ATLAS_INK_FAIL scanned=%d violations=%d" % [ink_scanned, ink_violations.size()])
|
|
quit(1)
|
|
return
|
|
print("ABG_M79_ATLAS_INK_OK scanned=%d violations=0" % ink_scanned)
|
|
print("ABG_M79_ATLAS_VISUAL_PROBE_OK locales=2 scales=2 scans=%d views=final" % ink_scanned)
|
|
quit(0)
|
|
|
|
|
|
func _fixture_data(locale: String) -> Dictionary:
|
|
return {
|
|
"ok": true,
|
|
"page_id": "region_atlas",
|
|
"locale": locale,
|
|
"cleared_regions": 2,
|
|
"total_regions": 8,
|
|
"renown": 46,
|
|
"clear_facts": 3,
|
|
"route_complete": false,
|
|
"regions": [
|
|
{"id": "RG-01", "name": "风镜原野" if locale == "zh_CN" else "Windglass Verge",
|
|
"framing": "开阔草台地上悬浮矿镜导引以太风" if locale == "zh_CN" else "open grass terraces where suspended mineral panes redirect aether gusts",
|
|
"equipment_band": "EQ-001..EQ-040", "enemies": 12, "bosses": 2, "cleared": true, "clear_count": 2},
|
|
{"id": "RG-02", "name": "淤醒沼泽" if locale == "zh_CN" else "Siltwake Fens",
|
|
"framing": "芦苇水道在可移堤岸间搬运发光淤沙" if locale == "zh_CN" else "reed channels carry luminous sediment between movable banks",
|
|
"equipment_band": "EQ-041..EQ-080", "enemies": 12, "bosses": 2, "cleared": true, "clear_count": 1},
|
|
{"id": "RG-03", "name": "余烬织坊" if locale == "zh_CN" else "Emberloom Works",
|
|
"framing": "公共窑炉借旧陶管编织热量" if locale == "zh_CN" else "communal kilns weave heat through old ceramic conduits",
|
|
"equipment_band": "EQ-081..EQ-120", "enemies": 12, "bosses": 2, "cleared": false, "clear_count": 0},
|
|
{"id": "RG-04", "name": "卷根档案馆" if locale == "zh_CN" else "Quillroot Archive",
|
|
"framing": "活根书架以叶纹保存路线契约" if locale == "zh_CN" else "living root shelves preserve route contracts as changing leaf patterns",
|
|
"equipment_band": "EQ-121..EQ-160", "enemies": 12, "bosses": 2, "cleared": false, "clear_count": 0},
|
|
{"id": "RG-05", "name": "潮镜滩" if locale == "zh_CN" else "Tideglass Reach",
|
|
"framing": "盐滩镜池乱序重复剪影" if locale == "zh_CN" else "salt flats hold mirror pools that repeat silhouettes out of sequence",
|
|
"equipment_band": "EQ-161..EQ-200", "enemies": 13, "bosses": 2, "cleared": false, "clear_count": 0},
|
|
{"id": "RG-06", "name": "空轨果园" if locale == "zh_CN" else "Skyrail Orchard",
|
|
"framing": "悬轨果园在高空窗口间运送果实" if locale == "zh_CN" else "skyrail orchards move harvests between airborne windows",
|
|
"equipment_band": "EQ-201..EQ-240", "enemies": 13, "bosses": 2, "cleared": false, "clear_count": 0},
|
|
{"id": "RG-07", "name": "夜流盆地" if locale == "zh_CN" else "Nightcurrent Basin",
|
|
"framing": "暗流盆地以潮流预告拒绝与盗取施压" if locale == "zh_CN" else "dark current basin pressures forecasts with denial and theft",
|
|
"equipment_band": "EQ-241..EQ-280", "enemies": 13, "bosses": 2, "cleared": false, "clear_count": 0},
|
|
{"id": "RG-08", "name": "晨冠" if locale == "zh_CN" else "Crown of Morn",
|
|
"framing": "路线之巅的晨光高台" if locale == "zh_CN" else "a high sunrise terrace crowning the route",
|
|
"equipment_band": "EQ-281..EQ-320", "enemies": 13, "bosses": 2, "cleared": false, "clear_count": 0},
|
|
],
|
|
}
|
|
|
|
|
|
func _capture(width: int, height: int, locale: String, text_scale: float) -> void:
|
|
probe_text_scale = text_scale
|
|
root.content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS
|
|
root.content_scale_aspect = Window.CONTENT_SCALE_ASPECT_KEEP
|
|
root.content_scale_size = Vector2i(1280, 720)
|
|
root.size = Vector2i(width, height)
|
|
var view := AtlasView.new()
|
|
view.name = "AtlasVisualProbeView"
|
|
view.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
view.configure_presentation({"safe_area": 24, "text_scale": text_scale, "locale": locale})
|
|
root.add_child(view)
|
|
view.render(_fixture_data(locale))
|
|
await process_frame
|
|
await RenderingServer.frame_post_draw
|
|
_save_image("%s/%s-1280x720-atlas-static.png" % [output_root, locale])
|
|
var violations := InkCheck.scan(view)
|
|
ink_scanned += 1
|
|
for violation in violations:
|
|
violation["locale"] = locale
|
|
violation["size"] = "1280x720"
|
|
ink_violations.append(violation)
|
|
view.visible = false
|
|
var neutral := ColorRect.new()
|
|
neutral.color = Color("#26353c")
|
|
neutral.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
neutral.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
root.add_child(neutral)
|
|
view.visible = true
|
|
view.queue_free()
|
|
neutral.queue_free()
|
|
await process_frame
|
|
|
|
|
|
func _save_image(path: String) -> void:
|
|
var image := root.get_texture().get_image()
|
|
if image != null and not image.is_empty():
|
|
image.save_png(path)
|