Files
tekton/scripts/ui/boot_screen.gd
T

182 lines
6.0 KiB
GDScript

extends Control
## Boot screen that handles update checking before launching the game
## On mobile: Shows update UI and handles in-game patching
## On desktop: Quick check, then proceeds (assumes launcher handles updates)
@onready var status_label := %StatusLabel as Label
@onready var progress_container := %ProgressContainer as VBoxContainer
@onready var progress_bar := %ProgressBar as ProgressBar
@onready var progress_label := %ProgressLabel as Label
@onready var button_container := %ButtonContainer as HBoxContainer
@onready var update_button := %UpdateButton as Button
@onready var skip_button := %SkipButton as Button
@onready var store_button := %StoreButton as Button
@onready var version_label := $VersionLabel as Label
var update_manager: Node
var update_info: Dictionary = {}
var main_scene_path := "res://scenes/main.tscn" # Your main game scene
func _ready() -> void:
# Get or create the update manager
update_manager = _get_update_manager()
# Connect signals
update_manager.update_check_completed.connect(_on_update_check_completed)
update_manager.update_check_failed.connect(_on_update_check_failed)
update_manager.download_started.connect(_on_download_started)
update_manager.download_progress.connect(_on_download_progress)
update_manager.download_completed.connect(_on_download_completed)
update_manager.download_failed.connect(_on_download_failed)
update_manager.store_update_required.connect(_on_store_update_required)
# Connect buttons
update_button.pressed.connect(_on_update_pressed)
skip_button.pressed.connect(_on_skip_pressed)
store_button.pressed.connect(_on_store_pressed)
# Show current version
version_label.text = "v" + update_manager.current_version
# Start update check after a brief delay
await get_tree().create_timer(0.5).timeout
_check_for_updates()
func _get_update_manager() -> Node:
# Try to get from autoload first
if has_node("/root/GameUpdateManager"):
return get_node("/root/GameUpdateManager")
# Otherwise, create instance
var manager_script := load("res://scripts/managers/game_update_manager.gd")
var manager: Node = manager_script.new()
manager.name = "GameUpdateManager"
get_tree().root.add_child(manager)
return manager
func _check_for_updates() -> void:
status_label.text = "Checking for updates..."
progress_container.visible = false
button_container.visible = false
# On desktop without launcher, skip update check and go straight to game
if update_manager.is_desktop() and not update_manager._launcher_available():
# Quick check but don't block
update_manager.check_for_updates()
# Auto-proceed after short delay if on desktop
await get_tree().create_timer(2.0).timeout
if not update_info.get("has_update", false):
_proceed_to_game()
else:
update_manager.check_for_updates()
func _on_update_check_completed(has_update: bool, info: Dictionary) -> void:
update_info = info
version_label.text = "v" + info.current_version
if has_update:
if info.needs_store_update:
status_label.text = "A required update is available.\nPlease update from the store."
button_container.visible = true
update_button.visible = false
skip_button.visible = false
store_button.visible = true
elif info.can_patch:
status_label.text = "Update available: v" + info.latest_version
button_container.visible = true
update_button.visible = true
skip_button.visible = true
store_button.visible = false
else:
# Desktop with launcher - just proceed
status_label.text = "Update available via launcher"
await get_tree().create_timer(1.5).timeout
_proceed_to_game()
else:
status_label.text = "Game is up to date!"
await get_tree().create_timer(1.0).timeout
_proceed_to_game()
func _on_update_check_failed(error: String) -> void:
status_label.text = "Could not check for updates"
print("[BootScreen] Update check failed: ", error)
# Allow playing anyway
await get_tree().create_timer(1.5).timeout
_proceed_to_game()
func _on_update_pressed() -> void:
button_container.visible = false
status_label.text = "Downloading update..."
update_manager.download_update()
func _on_skip_pressed() -> void:
_proceed_to_game()
func _on_store_pressed() -> void:
update_manager.open_store_page()
func _on_download_started(_total_size: int) -> void:
progress_container.visible = true
progress_bar.value = 0
progress_label.text = "0%"
func _on_download_progress(_downloaded: int, _total: int, percentage: float) -> void:
progress_bar.value = percentage
progress_label.text = "%.0f%%" % percentage
func _on_download_completed() -> void:
status_label.text = "Update installed!"
progress_container.visible = false
# Reload the game to apply changes
await get_tree().create_timer(1.0).timeout
get_tree().reload_current_scene()
func _on_download_failed(error: String) -> void:
status_label.text = "Update failed: " + error
progress_container.visible = false
button_container.visible = true
update_button.text = "Retry"
func _on_store_update_required(store_url: String) -> void:
status_label.text = "Please update from the store"
button_container.visible = true
update_button.visible = false
skip_button.visible = false
store_button.visible = true
func _proceed_to_game() -> void:
# Load any previously downloaded patches
_load_existing_patches()
# Change to main game scene
get_tree().change_scene_to_file(main_scene_path)
func _load_existing_patches() -> void:
# Load any PCK files from the patches directory
var patches_dir := "user://patches/"
var dir := DirAccess.open(patches_dir)
if not dir:
return
var patches: Array[String] = []
dir.list_dir_begin()
var patch_file := dir.get_next()
while patch_file != "":
if patch_file.ends_with(".pck"):
patches.append(patch_file)
patch_file = dir.get_next()
dir.list_dir_end()
# Sort patches by version (filename includes version)
patches.sort()
# Load each patch in order
for patch in patches:
var patch_path := patches_dir + patch
if ProjectSettings.load_resource_pack(patch_path, true):
print("[BootScreen] Loaded patch: ", patch)
else:
push_warning("[BootScreen] Failed to load patch: ", patch)