175 lines
6.1 KiB
GDScript
175 lines
6.1 KiB
GDScript
class_name ABGEntryShell
|
|
extends Control
|
|
|
|
const BootService = preload("res://entry/boot_service.gd")
|
|
const GUILD_BACKGROUND = preload("res://assets/backgrounds/p9_3_guild_hall.png")
|
|
const UI_FONT = preload("res://assets/fonts/NotoSansSC.ttf")
|
|
|
|
signal boot_completed
|
|
|
|
@export var auto_start := true
|
|
var boot_service := BootService.new()
|
|
var boot_snapshot: Dictionary = {}
|
|
var boot_generation := 0
|
|
var status_label: Label
|
|
var detail_label: Label
|
|
var progress_bar: ProgressBar
|
|
var retry_button: Button
|
|
var diagnostics_label: Label
|
|
|
|
|
|
func _ready() -> void:
|
|
set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
_build_boot_screen()
|
|
if auto_start:
|
|
call_deferred("start_boot")
|
|
|
|
|
|
func start_boot() -> void:
|
|
boot_generation += 1
|
|
var generation := boot_generation
|
|
boot_snapshot = boot_service.begin()
|
|
_render_boot_state()
|
|
while generation == boot_generation and String(boot_snapshot.state) == "running":
|
|
await get_tree().process_frame
|
|
boot_snapshot = boot_service.verify_next()
|
|
_render_boot_state()
|
|
if generation == boot_generation and String(boot_snapshot.state) == "complete":
|
|
await get_tree().create_timer(0.18).timeout
|
|
if generation == boot_generation:
|
|
boot_completed.emit()
|
|
_show_next_step_hold()
|
|
|
|
|
|
func retry_boot() -> void:
|
|
if String(boot_snapshot.get("state", "")) != "error":
|
|
return
|
|
start_boot()
|
|
|
|
|
|
func _build_boot_screen() -> void:
|
|
for child in get_children():
|
|
child.queue_free()
|
|
|
|
var background := TextureRect.new()
|
|
background.name = "EntryBackground"
|
|
background.texture = GUILD_BACKGROUND
|
|
background.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
|
background.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_COVERED
|
|
background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
background.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
add_child(background)
|
|
|
|
var shade := ColorRect.new()
|
|
shade.name = "EntryShade"
|
|
shade.color = Color(0.035, 0.07, 0.10, 0.40)
|
|
shade.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
shade.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
add_child(shade)
|
|
|
|
var safe := MarginContainer.new()
|
|
safe.name = "EntrySafeArea"
|
|
safe.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
safe.add_theme_constant_override("margin_left", 56)
|
|
safe.add_theme_constant_override("margin_right", 56)
|
|
safe.add_theme_constant_override("margin_top", 40)
|
|
safe.add_theme_constant_override("margin_bottom", 40)
|
|
add_child(safe)
|
|
|
|
var layout := VBoxContainer.new()
|
|
layout.name = "BootLayout"
|
|
layout.alignment = BoxContainer.ALIGNMENT_END
|
|
layout.add_theme_constant_override("separation", 10)
|
|
safe.add_child(layout)
|
|
|
|
var identity := Label.new()
|
|
identity.name = "BootIdentity"
|
|
identity.text = "AETHERBOUND GUILD"
|
|
identity.add_theme_font_override("font", UI_FONT)
|
|
identity.add_theme_font_size_override("font_size", 34)
|
|
identity.add_theme_color_override("font_color", Color("#f3f6f2"))
|
|
identity.add_theme_color_override("font_shadow_color", Color(0.05, 0.08, 0.10, 0.8))
|
|
identity.add_theme_constant_override("shadow_offset_x", 2)
|
|
identity.add_theme_constant_override("shadow_offset_y", 2)
|
|
layout.add_child(identity)
|
|
|
|
status_label = Label.new()
|
|
status_label.name = "BootStatus"
|
|
status_label.add_theme_font_override("font", UI_FONT)
|
|
status_label.add_theme_font_size_override("font_size", 20)
|
|
status_label.add_theme_color_override("font_color", Color("#f3f6f2"))
|
|
layout.add_child(status_label)
|
|
|
|
detail_label = Label.new()
|
|
detail_label.name = "BootDetail"
|
|
detail_label.add_theme_font_override("font", UI_FONT)
|
|
detail_label.add_theme_font_size_override("font_size", 16)
|
|
detail_label.add_theme_color_override("font_color", Color("#d7e0dd"))
|
|
detail_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
|
layout.add_child(detail_label)
|
|
|
|
progress_bar = ProgressBar.new()
|
|
progress_bar.name = "BootProgress"
|
|
progress_bar.custom_minimum_size = Vector2(420, 12)
|
|
progress_bar.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
|
progress_bar.show_percentage = false
|
|
layout.add_child(progress_bar)
|
|
|
|
retry_button = Button.new()
|
|
retry_button.name = "BootRetry"
|
|
retry_button.text = "Retry verification"
|
|
retry_button.custom_minimum_size = Vector2(240, 52)
|
|
retry_button.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
|
retry_button.add_theme_font_override("font", UI_FONT)
|
|
retry_button.add_theme_font_size_override("font_size", 18)
|
|
retry_button.pressed.connect(retry_boot)
|
|
layout.add_child(retry_button)
|
|
|
|
diagnostics_label = Label.new()
|
|
diagnostics_label.name = "BootDiagnostics"
|
|
diagnostics_label.add_theme_font_override("font", UI_FONT)
|
|
diagnostics_label.add_theme_font_size_override("font_size", 14)
|
|
diagnostics_label.add_theme_color_override("font_color", Color("#ffd4d4"))
|
|
layout.add_child(diagnostics_label)
|
|
|
|
|
|
func _render_boot_state() -> void:
|
|
if status_label == null:
|
|
return
|
|
var state := String(boot_snapshot.get("state", "running"))
|
|
var step := String(boot_snapshot.get("step", "resources"))
|
|
progress_bar.max_value = max(1, int(boot_snapshot.get("total", 1)))
|
|
progress_bar.value = int(boot_snapshot.get("completed", 0))
|
|
retry_button.visible = state == "error"
|
|
diagnostics_label.visible = state == "error"
|
|
match state:
|
|
"error":
|
|
status_label.text = "Verification needs attention"
|
|
detail_label.text = "Local data was left unchanged. Resolve the issue, then retry this check."
|
|
diagnostics_label.text = "Diagnostic: %s" % String(boot_snapshot.get("code", "UNKNOWN"))
|
|
"complete":
|
|
status_label.text = "Local verification complete"
|
|
detail_label.text = "Resources, settings storage and save access are ready."
|
|
diagnostics_label.text = ""
|
|
_:
|
|
status_label.text = "Preparing the guild threshold"
|
|
detail_label.text = _step_text(step)
|
|
diagnostics_label.text = ""
|
|
|
|
|
|
func _step_text(step: String) -> String:
|
|
match step:
|
|
"resources": return "Checking required local resources..."
|
|
"storage": return "Checking local storage access..."
|
|
"preferences": return "Checking display and accessibility settings..."
|
|
"save": return "Checking the latest local run record..."
|
|
return "Completing local verification..."
|
|
|
|
|
|
func _show_next_step_hold() -> void:
|
|
status_label.text = "First-launch setup"
|
|
detail_label.text = "Language, safe area and accessibility setup will open next."
|
|
progress_bar.visible = false
|
|
retry_button.visible = false
|
|
diagnostics_label.visible = false
|