Capture current source, content data, tests, asset licenses, and original-specification traceability. Original implementation remains incomplete. The accepted matching UI generation passed 154 suites and 12,253 checks, with eight rendered staff-contract screens reviewed. Latest native Windows and full-original acceptance remain outstanding.
124 lines
6.3 KiB
GDScript
124 lines
6.3 KiB
GDScript
class_name WorldTreeRankDialog
|
||
extends ConfirmationDialog
|
||
|
||
const LayerSkin := preload("res://scripts/ui/layer_interface_skin.gd")
|
||
|
||
signal status_requested(message: String, success: bool)
|
||
const LABELS := {
|
||
&"reputation":"評判", &"asset_gold":"所持金", &"faith_lifetime":"累計信仰", &"guest_lifetime":"累計来客数",
|
||
&"underground_influence":"裏社会への影響", &"reputation_or_underground_influence":"評判または裏社会への影響",
|
||
&"active_above_ground_facilities":"地上の稼働施設", &"active_underground_facilities":"地下の稼働施設",
|
||
&"important_rank_5":"重要クエスト", &"main_chapter_complete":"本編の章目標",
|
||
}
|
||
var _runtime: Variant
|
||
var _target := -1
|
||
var _pending_id := 0
|
||
var _queue_id := 0
|
||
var _skin_styles: Array[StyleBoxFlat] = []
|
||
func configure(runtime: Variant) -> void: _runtime=runtime
|
||
func _ready() -> void:
|
||
name="WorldTreeRankDialog"
|
||
title="世界樹ランク"
|
||
get_ok_button().text="昇格する"
|
||
get_cancel_button().text="閉じる"
|
||
confirmed.connect(_promote)
|
||
_runtime.command_completed.connect(_on_command_completed)
|
||
_build_skin()
|
||
apply_layer_skin(LayerSkin.active_layer(self))
|
||
func show_rank() -> void:
|
||
refresh()
|
||
popup_centered(Vector2i(480,260))
|
||
func refresh() -> void:
|
||
var queue_id: int=_runtime.command_queue.get_instance_id()
|
||
if queue_id!=_queue_id:
|
||
_pending_id=0
|
||
_queue_id=queue_id
|
||
for command: Dictionary in _runtime.command_queue.create_snapshot().get("pending",[]):
|
||
if command.get("command_type","")=="set_world_tree_rank":
|
||
_pending_id=int(command["command_id"])
|
||
break
|
||
var report: Dictionary=_runtime.get_live_progression_report()
|
||
var rank: int=report[&"snapshot"][&"current_rank"]
|
||
var evaluation: Dictionary=report[&"evaluation"]
|
||
_target=rank+1
|
||
var lines: Array[String]=["現在のランク:%d" % rank]
|
||
if rank>=ProgressionService.MAX_RANK:
|
||
lines.append("最高ランクに到達しています。")
|
||
else:
|
||
lines.append("ランク%dへの条件" % _target)
|
||
for requirement: Dictionary in evaluation[&"requirements"]:
|
||
var label: String=LABELS.get(StringName(requirement[&"id"]),"進行条件")
|
||
var value: String="%d / %d" % [requirement[&"current"],requirement[&"required"]]
|
||
if requirement[&"comparison"]==&"QUEST_COMPLETED": value="達成済み" if requirement[&"met"] else "未達成"
|
||
lines.append("%s %s:%s" % ["✓" if requirement[&"met"] else "・",label,value])
|
||
if evaluation.get(&"eligible",false):lines.append("条件を満たしています。昇格すると建設範囲が広がります。")
|
||
elif evaluation.get(&"reason",&"")==&"QUARANTINED":lines.append("進行データの確認が必要なため、現在は昇格できません。")
|
||
if evaluation.get(&"reason",&"")==&"OPERATIONS_BLOCKED":
|
||
var reason: StringName=evaluation.get(&"block_reason",&"")
|
||
lines.append("未払い経費を精算するまで昇格できません。" if reason in [&"ARREARS_REMAIN",&"UNPAID_EXPENSES"] else "ゲーム終了後は昇格できません。" if reason==&"BANKRUPT" else "営業状態の復旧が必要なため、現在は昇格できません。")
|
||
if evaluation.get(&"reason",&"")==&"UNAVAILABLE":lines.append("条件を確認できません。もう一度開き直してください。")
|
||
if _pending_id!=0:lines.append("昇格申請を受理しました。時間更新を待っています。")
|
||
dialog_text="\n\n".join(lines)
|
||
get_ok_button().disabled=rank>=ProgressionService.MAX_RANK or not evaluation.get(&"eligible",false) or _pending_id!=0
|
||
func _promote() -> void:
|
||
if _pending_id!=0 or _target<2:return
|
||
var result: CommandResult=_runtime.submit_command(&"set_world_tree_rank",{&"rank":_target,&"request_id":StringName("ui_rank_%d" % _target)})
|
||
for command: Dictionary in _runtime.command_queue.create_snapshot().get("pending",[]):
|
||
if result.is_success() and int(command["command_id"])==result.command_id:
|
||
_pending_id=result.command_id
|
||
status_requested.emit("昇格申請を受理しました。次の時間更新で反映します。",true)
|
||
return
|
||
_finish(result)
|
||
func _on_command_completed(result: CommandResult) -> void:
|
||
if _pending_id!=0 and result.command_id==_pending_id:
|
||
_pending_id=0
|
||
_finish(result)
|
||
func _finish(result: CommandResult) -> void:
|
||
status_requested.emit("世界樹ランクが上がりました。" if result.is_success() else "昇格できませんでした。現在の条件を確認してください。",result.is_success())
|
||
refresh()
|
||
|
||
|
||
func _build_skin() -> void:
|
||
# Window uses a local Theme rather than Control theme overrides.
|
||
# Keep native dialog input, focus and confirmation behaviour intact.
|
||
theme = Theme.new()
|
||
var panel := _skin_box(Color("f4e3bd"), &"panel_parchment")
|
||
theme.set_stylebox("panel", "AcceptDialog", panel)
|
||
var border := _skin_box(Color("49311f"), &"panel_outer")
|
||
border.expand_margin_top = 32
|
||
theme.set_stylebox("embedded_border", "Window", border)
|
||
theme.set_color("title_color", "Window", Color("fff0cf"))
|
||
get_label().add_theme_color_override("font_color", Color("55371e"))
|
||
LayerSkin.register_text(get_label(), 0)
|
||
for button: Button in [get_ok_button(), get_cancel_button()]:
|
||
for key: StringName in [&"normal", &"hover", &"pressed", &"disabled", &"focus"]:
|
||
var role: StringName = &"button_normal"
|
||
var color := Color("65452d")
|
||
if key in [&"hover", &"focus"]: role = &"button_hover"; color = Color("896139")
|
||
elif key == &"pressed": role = &"button_pressed"; color = Color("49311f")
|
||
elif key == &"disabled": role = &"button_disabled"; color = Color("786852")
|
||
button.add_theme_stylebox_override(key, _skin_box(color, role))
|
||
for key: StringName in [&"font_color", &"font_hover_color", &"font_pressed_color", &"font_hover_pressed_color", &"font_focus_color"]:
|
||
button.add_theme_color_override(key, Color("fff0cf"))
|
||
button.add_theme_color_override("font_disabled_color", Color("c7bda9"))
|
||
LayerSkin.register_toggle_text(button, 0)
|
||
|
||
|
||
func _skin_box(background: Color, role: StringName) -> StyleBoxFlat:
|
||
var style := StyleBoxFlat.new()
|
||
style.bg_color = background
|
||
style.border_color = Color("a96f2f")
|
||
style.set_border_width_all(2)
|
||
style.set_content_margin_all(10)
|
||
LayerSkin.register_style(style, role, 0)
|
||
_skin_styles.append(style)
|
||
return style
|
||
|
||
|
||
func apply_layer_skin(layer: int) -> void:
|
||
for style: StyleBoxFlat in _skin_styles:
|
||
LayerSkin.apply_style(style, layer)
|
||
LayerSkin.register_text(get_label(), layer)
|
||
for button: Button in [get_ok_button(), get_cancel_button()]:
|
||
LayerSkin.register_toggle_text(button, layer)
|