Migrate settings to bubble menus
This commit is contained in:
parent
053cfe037d
commit
359a96f6e2
7 changed files with 1741 additions and 289 deletions
|
|
@ -149,7 +149,7 @@ func handle_escape() -> bool:
|
||||||
if _confirmation_panel.visible:
|
if _confirmation_panel.visible:
|
||||||
_close_confirmation()
|
_close_confirmation()
|
||||||
elif _settings_panel.visible:
|
elif _settings_panel.visible:
|
||||||
_settings_panel.close_panel()
|
_settings_panel.handle_back()
|
||||||
else:
|
else:
|
||||||
resume()
|
resume()
|
||||||
return true
|
return true
|
||||||
|
|
@ -176,7 +176,10 @@ func _open_settings() -> void:
|
||||||
if _action_in_progress or _confirmation_panel.visible:
|
if _action_in_progress or _confirmation_panel.visible:
|
||||||
return
|
return
|
||||||
_root_panel.hide()
|
_root_panel.hide()
|
||||||
_settings_panel.open_panel(_settings_manager)
|
_settings_panel.open_panel(
|
||||||
|
_settings_manager,
|
||||||
|
SettingsPanelType.PresentationMode.GAMEPLAY_MODAL
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
func _on_settings_applied() -> void:
|
func _on_settings_applied() -> void:
|
||||||
|
|
|
||||||
237
ui/settings/settings_bubble_page.gd
Normal file
237
ui/settings/settings_bubble_page.gd
Normal file
|
|
@ -0,0 +1,237 @@
|
||||||
|
class_name SettingsBubblePage
|
||||||
|
extends Control
|
||||||
|
|
||||||
|
@export var page_id: StringName
|
||||||
|
@export var cluster_path: NodePath = ^"BubbleCluster"
|
||||||
|
@export var bubble_paths: Array[NodePath] = []
|
||||||
|
@export var focus_paths: Array[NodePath] = []
|
||||||
|
@export var initial_focus_path: NodePath
|
||||||
|
@export var back_focus_path: NodePath
|
||||||
|
@export var maximum_layout_size: Vector2 = Vector2(720.0, 520.0)
|
||||||
|
@export var compact_maximum_layout_size: Vector2 = Vector2.ZERO
|
||||||
|
@export var compact_width_threshold: float = 680.0
|
||||||
|
@export var compact_height_threshold: float = 500.0
|
||||||
|
@export_range(0.1, 2.0, 0.01) var outgoing_rise_duration: float = 0.95
|
||||||
|
@export_range(0.1, 2.0, 0.01) var incoming_rise_duration: float = 1.05
|
||||||
|
@export_range(0.0, 128.0, 1.0) var transition_safe_margin: float = 24.0
|
||||||
|
|
||||||
|
var _cluster: BubbleCluster
|
||||||
|
var _bubbles: Array[BubbleButton] = []
|
||||||
|
var _focus_bubbles: Array[BubbleButton] = []
|
||||||
|
var _transition: Tween
|
||||||
|
var _transition_generation: int = 0
|
||||||
|
var _resting_cluster_position: Vector2 = Vector2.ZERO
|
||||||
|
var _is_transitioning: bool = false
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
_cluster = get_node(cluster_path) as BubbleCluster
|
||||||
|
for path: NodePath in bubble_paths:
|
||||||
|
var bubble := get_node(path) as BubbleButton
|
||||||
|
if bubble != null:
|
||||||
|
_bubbles.append(bubble)
|
||||||
|
for path: NodePath in focus_paths:
|
||||||
|
var bubble := get_node(path) as BubbleButton
|
||||||
|
if bubble != null:
|
||||||
|
_focus_bubbles.append(bubble)
|
||||||
|
_cluster.configure(_bubbles)
|
||||||
|
_configure_focus_order()
|
||||||
|
resized.connect(_update_layout)
|
||||||
|
call_deferred("_update_layout")
|
||||||
|
set_process(false)
|
||||||
|
|
||||||
|
|
||||||
|
func show_page(should_focus: bool = true) -> void:
|
||||||
|
_transition_generation += 1
|
||||||
|
_cancel_transition()
|
||||||
|
show()
|
||||||
|
_is_transitioning = false
|
||||||
|
_cluster.position = _resting_cluster_position
|
||||||
|
set_process(true)
|
||||||
|
_set_interactive(true)
|
||||||
|
if should_focus:
|
||||||
|
focus_initial()
|
||||||
|
|
||||||
|
|
||||||
|
func transition_out(
|
||||||
|
completed: Callable,
|
||||||
|
duration_override: float = -1.0,
|
||||||
|
) -> void:
|
||||||
|
_transition_generation += 1
|
||||||
|
_cancel_transition()
|
||||||
|
_is_transitioning = true
|
||||||
|
_set_interactive(false)
|
||||||
|
set_process(true)
|
||||||
|
var duration: float = (
|
||||||
|
duration_override
|
||||||
|
if duration_override > 0.0
|
||||||
|
else outgoing_rise_duration
|
||||||
|
)
|
||||||
|
var generation: int = _transition_generation
|
||||||
|
_transition = create_tween()
|
||||||
|
_transition.tween_property(
|
||||||
|
_cluster,
|
||||||
|
"position:y",
|
||||||
|
-_cluster.size.y - transition_safe_margin,
|
||||||
|
duration
|
||||||
|
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||||
|
_transition.finished.connect(
|
||||||
|
_finish_transition_out.bind(generation, completed),
|
||||||
|
CONNECT_ONE_SHOT
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func transition_in(
|
||||||
|
should_focus: bool,
|
||||||
|
completed: Callable,
|
||||||
|
duration_override: float = -1.0,
|
||||||
|
) -> void:
|
||||||
|
_transition_generation += 1
|
||||||
|
_cancel_transition()
|
||||||
|
show()
|
||||||
|
_is_transitioning = true
|
||||||
|
_set_interactive(false)
|
||||||
|
set_process(true)
|
||||||
|
var duration: float = (
|
||||||
|
duration_override
|
||||||
|
if duration_override > 0.0
|
||||||
|
else incoming_rise_duration
|
||||||
|
)
|
||||||
|
_cluster.position = Vector2(
|
||||||
|
_resting_cluster_position.x,
|
||||||
|
size.y + transition_safe_margin
|
||||||
|
)
|
||||||
|
var generation: int = _transition_generation
|
||||||
|
_transition = create_tween()
|
||||||
|
_transition.tween_property(
|
||||||
|
_cluster,
|
||||||
|
"position",
|
||||||
|
_resting_cluster_position,
|
||||||
|
duration
|
||||||
|
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||||
|
_transition.finished.connect(
|
||||||
|
_finish_transition_in.bind(generation, should_focus, completed),
|
||||||
|
CONNECT_ONE_SHOT
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func hide_page() -> void:
|
||||||
|
_transition_generation += 1
|
||||||
|
_cancel_transition()
|
||||||
|
_is_transitioning = false
|
||||||
|
_set_interactive(false)
|
||||||
|
set_process(false)
|
||||||
|
hide()
|
||||||
|
if _cluster != null:
|
||||||
|
_cluster.position = _resting_cluster_position
|
||||||
|
|
||||||
|
|
||||||
|
func focus_initial() -> void:
|
||||||
|
var initial := get_node_or_null(initial_focus_path) as Control
|
||||||
|
if initial != null and initial.visible and initial.focus_mode != Control.FOCUS_NONE:
|
||||||
|
initial.grab_focus()
|
||||||
|
|
||||||
|
|
||||||
|
func focus_back() -> void:
|
||||||
|
var back := get_node_or_null(back_focus_path) as Control
|
||||||
|
if back != null and back.visible and back.focus_mode != Control.FOCUS_NONE:
|
||||||
|
back.grab_focus()
|
||||||
|
|
||||||
|
|
||||||
|
func get_page_id() -> StringName:
|
||||||
|
return page_id
|
||||||
|
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
if visible:
|
||||||
|
_cluster.advance_motion(delta)
|
||||||
|
|
||||||
|
|
||||||
|
func _update_layout() -> void:
|
||||||
|
if not is_node_ready() or _cluster == null:
|
||||||
|
return
|
||||||
|
var compact: bool = (
|
||||||
|
size.x < compact_width_threshold
|
||||||
|
or size.y < compact_height_threshold
|
||||||
|
)
|
||||||
|
var layout_maximum: Vector2 = maximum_layout_size
|
||||||
|
if compact and compact_maximum_layout_size != Vector2.ZERO:
|
||||||
|
layout_maximum = compact_maximum_layout_size
|
||||||
|
var field_size := Vector2(
|
||||||
|
minf(size.x, layout_maximum.x),
|
||||||
|
minf(size.y, layout_maximum.y)
|
||||||
|
)
|
||||||
|
field_size.x = maxf(1.0, field_size.x)
|
||||||
|
field_size.y = maxf(1.0, field_size.y)
|
||||||
|
_resting_cluster_position = (size - field_size) * 0.5
|
||||||
|
if not _is_transitioning:
|
||||||
|
_cluster.position = _resting_cluster_position
|
||||||
|
_cluster.size = field_size
|
||||||
|
_cluster.apply_layout(field_size, compact)
|
||||||
|
|
||||||
|
|
||||||
|
func _configure_focus_order() -> void:
|
||||||
|
for bubble: BubbleButton in _bubbles:
|
||||||
|
bubble.focus_mode = Control.FOCUS_NONE
|
||||||
|
for index: int in _focus_bubbles.size():
|
||||||
|
var bubble: BubbleButton = _focus_bubbles[index]
|
||||||
|
if index > 0:
|
||||||
|
bubble.focus_neighbor_top = bubble.get_path_to(
|
||||||
|
_focus_bubbles[index - 1]
|
||||||
|
)
|
||||||
|
bubble.focus_neighbor_left = bubble.focus_neighbor_top
|
||||||
|
if index + 1 < _focus_bubbles.size():
|
||||||
|
bubble.focus_neighbor_bottom = bubble.get_path_to(
|
||||||
|
_focus_bubbles[index + 1]
|
||||||
|
)
|
||||||
|
bubble.focus_neighbor_right = bubble.focus_neighbor_bottom
|
||||||
|
|
||||||
|
|
||||||
|
func _set_interactive(interactive: bool) -> void:
|
||||||
|
mouse_filter = (
|
||||||
|
Control.MOUSE_FILTER_PASS
|
||||||
|
if interactive
|
||||||
|
else Control.MOUSE_FILTER_IGNORE
|
||||||
|
)
|
||||||
|
for bubble: BubbleButton in _focus_bubbles:
|
||||||
|
bubble.focus_mode = (
|
||||||
|
Control.FOCUS_ALL if interactive else Control.FOCUS_NONE
|
||||||
|
)
|
||||||
|
bubble.mouse_filter = (
|
||||||
|
Control.MOUSE_FILTER_STOP
|
||||||
|
if interactive
|
||||||
|
else Control.MOUSE_FILTER_IGNORE
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_transition_out(generation: int, completed: Callable) -> void:
|
||||||
|
if generation != _transition_generation or not visible:
|
||||||
|
return
|
||||||
|
_transition = null
|
||||||
|
_is_transitioning = false
|
||||||
|
hide()
|
||||||
|
_cluster.position = _resting_cluster_position
|
||||||
|
completed.call()
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_transition_in(
|
||||||
|
generation: int,
|
||||||
|
should_focus: bool,
|
||||||
|
completed: Callable,
|
||||||
|
) -> void:
|
||||||
|
if generation != _transition_generation or not visible:
|
||||||
|
return
|
||||||
|
_transition = null
|
||||||
|
_is_transitioning = false
|
||||||
|
_cluster.position = _resting_cluster_position
|
||||||
|
set_process(true)
|
||||||
|
_set_interactive(true)
|
||||||
|
if should_focus:
|
||||||
|
focus_initial()
|
||||||
|
completed.call()
|
||||||
|
|
||||||
|
|
||||||
|
func _cancel_transition() -> void:
|
||||||
|
if _transition != null:
|
||||||
|
_transition.kill()
|
||||||
|
_transition = null
|
||||||
1
ui/settings/settings_bubble_page.gd.uid
Normal file
1
ui/settings/settings_bubble_page.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://cwgitrlhjkepy
|
||||||
|
|
@ -1,86 +1,335 @@
|
||||||
class_name SettingsPanel
|
class_name SettingsPanel
|
||||||
extends PanelContainer
|
extends Control
|
||||||
|
|
||||||
const MAX_PANEL_SIZE: Vector2 = Vector2(720.0, 600.0)
|
const MAX_PANEL_SIZE: Vector2 = Vector2(960.0, 700.0)
|
||||||
const PANEL_EDGE_MARGIN: float = 16.0
|
const PANEL_EDGE_MARGIN: float = 16.0
|
||||||
|
const PAGE_ROOT: StringName = &"root"
|
||||||
|
const PAGE_DISPLAY: StringName = &"display"
|
||||||
|
const PAGE_CONTROLS: StringName = &"controls"
|
||||||
|
const PAGE_ACCESSIBILITY: StringName = &"accessibility"
|
||||||
|
const TITLE_HOST_OUTGOING_DURATION: float = 1.70
|
||||||
|
const TITLE_HOST_INCOMING_DURATION: float = 1.80
|
||||||
|
const PIXELATION_NAMES: PackedStringArray = [
|
||||||
|
"legible",
|
||||||
|
"cute",
|
||||||
|
"retro",
|
||||||
|
"hardcore",
|
||||||
|
"wtf",
|
||||||
|
]
|
||||||
const SettingsManagerType = preload(
|
const SettingsManagerType = preload(
|
||||||
"res://settings/player_settings_manager.gd"
|
"res://settings/player_settings_manager.gd"
|
||||||
)
|
)
|
||||||
|
|
||||||
signal applied
|
signal applied
|
||||||
signal closed
|
signal closed
|
||||||
|
signal opened
|
||||||
signal crisp_reset_focus_requested
|
signal crisp_reset_focus_requested
|
||||||
signal panel_visibility_changed(is_visible: bool)
|
signal panel_visibility_changed(is_visible: bool)
|
||||||
|
|
||||||
@onready var _auto_click_toggle: CheckButton = %AutoClickToggle
|
enum PresentationMode {
|
||||||
@onready var _auto_click_interval: HSlider = %AutoClickInterval
|
TITLE_EMBEDDED,
|
||||||
@onready var _auto_click_interval_value: Label = %AutoClickIntervalValue
|
GAMEPLAY_MODAL,
|
||||||
@onready var _mouse_sensitivity: HSlider = %MouseSensitivity
|
}
|
||||||
@onready var _mouse_sensitivity_value: Label = %MouseSensitivityValue
|
|
||||||
@onready var _controller_sensitivity: HSlider = %ControllerSensitivity
|
@onready var _backdrop: ColorRect = $Backdrop
|
||||||
@onready var _controller_sensitivity_value: Label = %ControllerSensitivityValue
|
@onready var _root_page: SettingsBubblePage = %RootPage
|
||||||
@onready var _invert_y_toggle: CheckButton = %InvertYToggle
|
@onready var _display_page: SettingsBubblePage = %DisplayPage
|
||||||
@onready var _world_pixel_size: HSlider = %WorldPixelSize
|
@onready var _controls_page: SettingsBubblePage = %ControlsPage
|
||||||
@onready var _world_pixel_size_value: Label = %WorldPixelSizeValue
|
@onready var _accessibility_page: SettingsBubblePage = %AccessibilityPage
|
||||||
@onready var _ui_pixel_size: HSlider = %UIPixelSize
|
|
||||||
@onready var _ui_pixel_size_value: Label = %UIPixelSizeValue
|
|
||||||
@onready var _feedback: Label = %SettingsFeedback
|
@onready var _feedback: Label = %SettingsFeedback
|
||||||
|
|
||||||
|
@onready var _world_value: BubbleButton = %WorldValue
|
||||||
|
@onready var _ui_value: BubbleButton = %UIValue
|
||||||
|
@onready var _mouse_value: BubbleButton = %MouseValue
|
||||||
|
@onready var _controller_value: BubbleButton = %ControllerValue
|
||||||
|
@onready var _invert_y_toggle: BubbleButton = %InvertYToggle
|
||||||
|
@onready var _auto_click_toggle: BubbleButton = %AutoClickToggle
|
||||||
|
@onready var _auto_click_interval: BubbleButton = %AutoClickIntervalValue
|
||||||
|
|
||||||
|
@onready var _world_options: Array[BubbleButton] = [
|
||||||
|
%WorldLegible,
|
||||||
|
%WorldCute,
|
||||||
|
%WorldRetro,
|
||||||
|
%WorldHardcore,
|
||||||
|
%WorldWtf,
|
||||||
|
]
|
||||||
|
@onready var _ui_options: Array[BubbleButton] = [
|
||||||
|
%UILegible,
|
||||||
|
%UICute,
|
||||||
|
%UIRetro,
|
||||||
|
%UIHardcore,
|
||||||
|
%UIWtf,
|
||||||
|
]
|
||||||
|
|
||||||
var _settings_manager: SettingsManagerType
|
var _settings_manager: SettingsManagerType
|
||||||
var _loading_controls: bool = false
|
|
||||||
var _effective_ui_pixel_size: int = PlayerSettings.DEFAULT_UI_PIXEL_SIZE
|
var _effective_ui_pixel_size: int = PlayerSettings.DEFAULT_UI_PIXEL_SIZE
|
||||||
|
var _page_stack: Array[StringName] = []
|
||||||
|
var _pages: Dictionary[StringName, SettingsBubblePage] = {}
|
||||||
|
var _page_transition_generation: int = 0
|
||||||
|
var _page_transition_active: bool = false
|
||||||
|
var _presentation_mode: PresentationMode = PresentationMode.GAMEPLAY_MODAL
|
||||||
|
var _auto_click_enabled: bool = false
|
||||||
|
var _auto_click_interval_value: float = 0.20
|
||||||
|
var _mouse_sensitivity: float = 0.005
|
||||||
|
var _controller_sensitivity: float = 2.5
|
||||||
|
var _invert_camera_y: bool = false
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
|
_pages = {
|
||||||
|
PAGE_ROOT: _root_page,
|
||||||
|
PAGE_DISPLAY: _display_page,
|
||||||
|
PAGE_CONTROLS: _controls_page,
|
||||||
|
PAGE_ACCESSIBILITY: _accessibility_page,
|
||||||
|
}
|
||||||
|
%DisplayCategory.pressed.connect(_push_page.bind(PAGE_DISPLAY))
|
||||||
|
%ControlsCategory.pressed.connect(_push_page.bind(PAGE_CONTROLS))
|
||||||
|
%AccessibilityCategory.pressed.connect(
|
||||||
|
_push_page.bind(PAGE_ACCESSIBILITY)
|
||||||
|
)
|
||||||
%ApplySettingsButton.pressed.connect(_apply_settings)
|
%ApplySettingsButton.pressed.connect(_apply_settings)
|
||||||
%CancelSettingsButton.pressed.connect(close_panel)
|
%RootBackButton.pressed.connect(close_panel)
|
||||||
_auto_click_interval.value_changed.connect(_refresh_value_labels)
|
%DisplayBackButton.pressed.connect(handle_back)
|
||||||
_mouse_sensitivity.value_changed.connect(_refresh_value_labels)
|
%ControlsBackButton.pressed.connect(handle_back)
|
||||||
_controller_sensitivity.value_changed.connect(_refresh_value_labels)
|
%AccessibilityBackButton.pressed.connect(handle_back)
|
||||||
_world_pixel_size.value_changed.connect(_on_pixel_size_changed)
|
%RootBackButton.gui_input.connect(_on_back_bubble_gui_input)
|
||||||
_ui_pixel_size.value_changed.connect(_on_pixel_size_changed)
|
%DisplayBackButton.gui_input.connect(_on_back_bubble_gui_input)
|
||||||
%CancelSettingsButton.gui_input.connect(_on_back_button_gui_input)
|
%ControlsBackButton.gui_input.connect(_on_back_bubble_gui_input)
|
||||||
get_viewport().size_changed.connect(_refresh_panel_size)
|
%AccessibilityBackButton.gui_input.connect(_on_back_bubble_gui_input)
|
||||||
|
for index: int in _world_options.size():
|
||||||
|
_world_options[index].pressed.connect(
|
||||||
|
_set_world_pixelation.bind(index + 1)
|
||||||
|
)
|
||||||
|
for index: int in _ui_options.size():
|
||||||
|
_ui_options[index].pressed.connect(
|
||||||
|
_set_ui_pixelation.bind(index + 1)
|
||||||
|
)
|
||||||
|
%MouseDecrease.pressed.connect(_adjust_mouse_sensitivity.bind(-1))
|
||||||
|
%MouseIncrease.pressed.connect(_adjust_mouse_sensitivity.bind(1))
|
||||||
|
_mouse_value.pressed.connect(_adjust_mouse_sensitivity.bind(1))
|
||||||
|
%ControllerDecrease.pressed.connect(
|
||||||
|
_adjust_controller_sensitivity.bind(-1)
|
||||||
|
)
|
||||||
|
%ControllerIncrease.pressed.connect(
|
||||||
|
_adjust_controller_sensitivity.bind(1)
|
||||||
|
)
|
||||||
|
_controller_value.pressed.connect(
|
||||||
|
_adjust_controller_sensitivity.bind(1)
|
||||||
|
)
|
||||||
|
_invert_y_toggle.pressed.connect(_toggle_invert_y)
|
||||||
|
_auto_click_toggle.pressed.connect(_toggle_auto_click)
|
||||||
|
%IntervalDecrease.pressed.connect(_adjust_auto_click_interval.bind(-1))
|
||||||
|
%IntervalIncrease.pressed.connect(_adjust_auto_click_interval.bind(1))
|
||||||
|
_auto_click_interval.pressed.connect(
|
||||||
|
_adjust_auto_click_interval.bind(1)
|
||||||
|
)
|
||||||
|
_mouse_value.gui_input.connect(
|
||||||
|
_on_continuous_value_input.bind(&"mouse")
|
||||||
|
)
|
||||||
|
_controller_value.gui_input.connect(
|
||||||
|
_on_continuous_value_input.bind(&"controller")
|
||||||
|
)
|
||||||
|
_auto_click_interval.gui_input.connect(
|
||||||
|
_on_continuous_value_input.bind(&"interval")
|
||||||
|
)
|
||||||
|
resized.connect(_refresh_panel_size)
|
||||||
var parent_control := get_parent() as Control
|
var parent_control := get_parent() as Control
|
||||||
if parent_control != null:
|
if parent_control != null:
|
||||||
parent_control.resized.connect(_refresh_panel_size)
|
parent_control.resized.connect(_refresh_panel_size)
|
||||||
|
for page: SettingsBubblePage in _pages.values():
|
||||||
|
page.hide_page()
|
||||||
call_deferred("_refresh_panel_size")
|
call_deferred("_refresh_panel_size")
|
||||||
|
|
||||||
|
|
||||||
func open_panel(settings_manager: SettingsManagerType) -> void:
|
func open_panel(
|
||||||
|
settings_manager: SettingsManagerType,
|
||||||
|
presentation_mode: PresentationMode = PresentationMode.GAMEPLAY_MODAL,
|
||||||
|
) -> void:
|
||||||
|
_cancel_page_transition()
|
||||||
|
_presentation_mode = presentation_mode
|
||||||
|
_backdrop.visible = presentation_mode == PresentationMode.GAMEPLAY_MODAL
|
||||||
_settings_manager = settings_manager
|
_settings_manager = settings_manager
|
||||||
_load_controls()
|
_load_controls()
|
||||||
_feedback.text = ""
|
_feedback.text = ""
|
||||||
show()
|
show()
|
||||||
|
_page_stack.clear()
|
||||||
|
_page_stack.append(PAGE_ROOT)
|
||||||
panel_visibility_changed.emit(true)
|
panel_visibility_changed.emit(true)
|
||||||
_auto_click_toggle.grab_focus()
|
if presentation_mode == PresentationMode.TITLE_EMBEDDED:
|
||||||
|
for page: SettingsBubblePage in _pages.values():
|
||||||
|
page.hide_page()
|
||||||
|
_page_transition_generation += 1
|
||||||
|
_page_transition_active = true
|
||||||
|
var generation: int = _page_transition_generation
|
||||||
|
_root_page.transition_in(
|
||||||
|
true,
|
||||||
|
_finish_embedded_open.bind(generation),
|
||||||
|
TITLE_HOST_INCOMING_DURATION
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
_show_active_page(true)
|
||||||
|
opened.emit()
|
||||||
|
|
||||||
|
|
||||||
func close_panel() -> void:
|
func close_panel() -> void:
|
||||||
if not visible:
|
if not visible:
|
||||||
return
|
return
|
||||||
|
if _presentation_mode == PresentationMode.TITLE_EMBEDDED:
|
||||||
|
if _page_transition_active:
|
||||||
|
return
|
||||||
|
_begin_embedded_close(false)
|
||||||
|
return
|
||||||
|
_finish_panel_close(false)
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_panel_close(applied_result: bool) -> void:
|
||||||
|
_cancel_page_transition()
|
||||||
|
for page: SettingsBubblePage in _pages.values():
|
||||||
|
page.hide_page()
|
||||||
|
_page_stack.clear()
|
||||||
hide()
|
hide()
|
||||||
panel_visibility_changed.emit(false)
|
panel_visibility_changed.emit(false)
|
||||||
_load_controls()
|
if applied_result:
|
||||||
closed.emit()
|
applied.emit()
|
||||||
|
else:
|
||||||
|
_load_controls()
|
||||||
|
closed.emit()
|
||||||
|
|
||||||
|
|
||||||
|
func handle_back() -> void:
|
||||||
|
if _page_transition_active:
|
||||||
|
return
|
||||||
|
if _page_stack.size() > 1:
|
||||||
|
_start_page_transition(_page_stack[-2], false)
|
||||||
|
return
|
||||||
|
close_panel()
|
||||||
|
|
||||||
|
|
||||||
|
func get_active_page_id() -> StringName:
|
||||||
|
return _page_stack.back() if not _page_stack.is_empty() else StringName()
|
||||||
|
|
||||||
|
|
||||||
|
func _push_page(page_id: StringName) -> void:
|
||||||
|
if (
|
||||||
|
_page_transition_active
|
||||||
|
or not _pages.has(page_id)
|
||||||
|
or get_active_page_id() == page_id
|
||||||
|
):
|
||||||
|
return
|
||||||
|
_start_page_transition(page_id, true)
|
||||||
|
|
||||||
|
|
||||||
|
func _start_page_transition(page_id: StringName, push_page: bool) -> void:
|
||||||
|
var outgoing_page: SettingsBubblePage = _get_active_page()
|
||||||
|
var incoming_page: SettingsBubblePage = _pages.get(page_id)
|
||||||
|
if outgoing_page == null or incoming_page == null:
|
||||||
|
return
|
||||||
|
_page_transition_generation += 1
|
||||||
|
_page_transition_active = true
|
||||||
|
var generation: int = _page_transition_generation
|
||||||
|
outgoing_page.transition_out(
|
||||||
|
_finish_outgoing_page.bind(
|
||||||
|
generation,
|
||||||
|
page_id,
|
||||||
|
push_page,
|
||||||
|
incoming_page
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_outgoing_page(
|
||||||
|
generation: int,
|
||||||
|
page_id: StringName,
|
||||||
|
push_page: bool,
|
||||||
|
incoming_page: SettingsBubblePage,
|
||||||
|
) -> void:
|
||||||
|
if generation != _page_transition_generation or not _page_transition_active:
|
||||||
|
return
|
||||||
|
if push_page:
|
||||||
|
_page_stack.append(page_id)
|
||||||
|
else:
|
||||||
|
_page_stack.pop_back()
|
||||||
|
for page: SettingsBubblePage in _pages.values():
|
||||||
|
if page != incoming_page:
|
||||||
|
page.hide_page()
|
||||||
|
incoming_page.transition_in(
|
||||||
|
true,
|
||||||
|
_finish_incoming_page.bind(generation)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_incoming_page(generation: int) -> void:
|
||||||
|
if generation != _page_transition_generation or not _page_transition_active:
|
||||||
|
return
|
||||||
|
_page_transition_active = false
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_embedded_open(generation: int) -> void:
|
||||||
|
if generation != _page_transition_generation or not _page_transition_active:
|
||||||
|
return
|
||||||
|
_page_transition_active = false
|
||||||
|
opened.emit()
|
||||||
|
|
||||||
|
|
||||||
|
func _begin_embedded_close(applied_result: bool) -> void:
|
||||||
|
var active_page: SettingsBubblePage = _get_active_page()
|
||||||
|
if active_page == null:
|
||||||
|
return
|
||||||
|
_page_transition_generation += 1
|
||||||
|
_page_transition_active = true
|
||||||
|
var generation: int = _page_transition_generation
|
||||||
|
active_page.transition_out(
|
||||||
|
_finish_embedded_close.bind(generation, applied_result),
|
||||||
|
TITLE_HOST_OUTGOING_DURATION
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_embedded_close(
|
||||||
|
generation: int,
|
||||||
|
applied_result: bool,
|
||||||
|
) -> void:
|
||||||
|
if generation != _page_transition_generation or not _page_transition_active:
|
||||||
|
return
|
||||||
|
_finish_panel_close(applied_result)
|
||||||
|
|
||||||
|
|
||||||
|
func _cancel_page_transition() -> void:
|
||||||
|
_page_transition_generation += 1
|
||||||
|
_page_transition_active = false
|
||||||
|
|
||||||
|
|
||||||
|
func _show_active_page(should_focus: bool) -> void:
|
||||||
|
for page_id: StringName in _pages:
|
||||||
|
var page: SettingsBubblePage = _pages[page_id]
|
||||||
|
if page_id == get_active_page_id():
|
||||||
|
page.show_page(should_focus)
|
||||||
|
else:
|
||||||
|
page.hide_page()
|
||||||
|
|
||||||
|
|
||||||
|
func _get_active_page() -> SettingsBubblePage:
|
||||||
|
return _pages.get(get_active_page_id()) as SettingsBubblePage
|
||||||
|
|
||||||
|
|
||||||
func _apply_settings() -> void:
|
func _apply_settings() -> void:
|
||||||
|
if _page_transition_active:
|
||||||
|
return
|
||||||
if _settings_manager == null:
|
if _settings_manager == null:
|
||||||
_feedback.text = "settings are unavailable."
|
_feedback.text = "settings are unavailable."
|
||||||
return
|
return
|
||||||
var edited := PlayerSettings.new()
|
var edited := PlayerSettings.new()
|
||||||
edited.auto_click_enabled = _auto_click_toggle.button_pressed
|
edited.auto_click_enabled = _auto_click_enabled
|
||||||
edited.auto_click_interval = float(_auto_click_interval.value)
|
edited.auto_click_interval = _auto_click_interval_value
|
||||||
edited.mouse_camera_sensitivity = float(_mouse_sensitivity.value)
|
edited.mouse_camera_sensitivity = _mouse_sensitivity
|
||||||
edited.controller_camera_sensitivity = float(_controller_sensitivity.value)
|
edited.controller_camera_sensitivity = _controller_sensitivity
|
||||||
edited.invert_camera_y = _invert_y_toggle.button_pressed
|
edited.invert_camera_y = _invert_camera_y
|
||||||
edited.world_pixel_size = roundi(_world_pixel_size.value)
|
edited.world_pixel_size = _settings_manager.current_settings.world_pixel_size
|
||||||
edited.ui_pixel_size = roundi(_ui_pixel_size.value)
|
edited.ui_pixel_size = _settings_manager.current_settings.ui_pixel_size
|
||||||
if _settings_manager.apply_settings(edited):
|
if _settings_manager.apply_settings(edited):
|
||||||
hide()
|
if _presentation_mode == PresentationMode.TITLE_EMBEDDED:
|
||||||
panel_visibility_changed.emit(false)
|
_begin_embedded_close(true)
|
||||||
applied.emit()
|
else:
|
||||||
|
_finish_panel_close(true)
|
||||||
else:
|
else:
|
||||||
_feedback.text = "failed to save settings."
|
_feedback.text = "failed to save settings."
|
||||||
|
|
||||||
|
|
@ -88,54 +337,139 @@ func _apply_settings() -> void:
|
||||||
func _load_controls() -> void:
|
func _load_controls() -> void:
|
||||||
if _settings_manager == null or not is_node_ready():
|
if _settings_manager == null or not is_node_ready():
|
||||||
return
|
return
|
||||||
_loading_controls = true
|
|
||||||
var settings: PlayerSettings = _settings_manager.current_settings
|
var settings: PlayerSettings = _settings_manager.current_settings
|
||||||
_auto_click_toggle.button_pressed = settings.auto_click_enabled
|
_auto_click_enabled = settings.auto_click_enabled
|
||||||
_auto_click_interval.value = settings.auto_click_interval
|
_auto_click_interval_value = settings.auto_click_interval
|
||||||
_mouse_sensitivity.value = settings.mouse_camera_sensitivity
|
_mouse_sensitivity = settings.mouse_camera_sensitivity
|
||||||
_controller_sensitivity.value = settings.controller_camera_sensitivity
|
_controller_sensitivity = settings.controller_camera_sensitivity
|
||||||
_invert_y_toggle.button_pressed = settings.invert_camera_y
|
_invert_camera_y = settings.invert_camera_y
|
||||||
_world_pixel_size.value = settings.world_pixel_size
|
_refresh_value_labels()
|
||||||
_ui_pixel_size.value = settings.ui_pixel_size
|
|
||||||
_loading_controls = false
|
|
||||||
_refresh_value_labels(0.0)
|
|
||||||
|
|
||||||
|
|
||||||
func _refresh_value_labels(_unused: float) -> void:
|
func _refresh_value_labels() -> void:
|
||||||
_auto_click_interval_value.text = "%.2f s" % _auto_click_interval.value
|
if _settings_manager == null:
|
||||||
_mouse_sensitivity_value.text = "%.4f" % _mouse_sensitivity.value
|
return
|
||||||
_controller_sensitivity_value.text = "%.1f" % _controller_sensitivity.value
|
var settings: PlayerSettings = _settings_manager.current_settings
|
||||||
_world_pixel_size_value.text = _pixel_size_label(
|
_world_value.text = (
|
||||||
roundi(_world_pixel_size.value),
|
"world\npixelation\n"
|
||||||
true
|
+ _pixel_size_label(settings.world_pixel_size)
|
||||||
)
|
)
|
||||||
_ui_pixel_size_value.text = _pixel_size_label(
|
_ui_value.text = (
|
||||||
roundi(_ui_pixel_size.value),
|
"ui\npixelation\n"
|
||||||
false
|
+ _pixel_size_label(settings.ui_pixel_size)
|
||||||
)
|
)
|
||||||
|
_mouse_value.text = "mouse\nsensitivity\n%.4f" % _mouse_sensitivity
|
||||||
|
_controller_value.text = (
|
||||||
|
"controller\nsensitivity\n%.1f" % _controller_sensitivity
|
||||||
|
)
|
||||||
|
_invert_y_toggle.text = (
|
||||||
|
"invert\nvertical\ncamera\n"
|
||||||
|
+ ("on" if _invert_camera_y else "off")
|
||||||
|
)
|
||||||
|
_auto_click_toggle.text = (
|
||||||
|
"accessibility\nauto-click\n"
|
||||||
|
+ ("on" if _auto_click_enabled else "off")
|
||||||
|
)
|
||||||
|
_auto_click_interval.text = (
|
||||||
|
"auto-click\ninterval\n%.2f s" % _auto_click_interval_value
|
||||||
|
)
|
||||||
|
for index: int in _world_options.size():
|
||||||
|
_world_options[index].button_pressed = (
|
||||||
|
index + 1 == settings.world_pixel_size
|
||||||
|
)
|
||||||
|
for index: int in _ui_options.size():
|
||||||
|
_ui_options[index].button_pressed = index + 1 == settings.ui_pixel_size
|
||||||
|
|
||||||
|
|
||||||
func _on_pixel_size_changed(_unused: float) -> void:
|
func _set_world_pixelation(pixel_size: int) -> void:
|
||||||
_refresh_value_labels(0.0)
|
if _settings_manager == null:
|
||||||
if _loading_controls or _settings_manager == null:
|
|
||||||
return
|
return
|
||||||
if not _settings_manager.apply_pixelation(
|
if not _settings_manager.apply_pixelation(
|
||||||
roundi(_world_pixel_size.value),
|
pixel_size,
|
||||||
roundi(_ui_pixel_size.value)
|
_settings_manager.current_settings.ui_pixel_size
|
||||||
):
|
):
|
||||||
_feedback.text = "failed to save pixelation settings."
|
_feedback.text = "failed to save pixelation settings."
|
||||||
|
return
|
||||||
|
_refresh_value_labels()
|
||||||
|
|
||||||
|
|
||||||
func _pixel_size_label(pixel_size: int, _is_world: bool) -> String:
|
func _set_ui_pixelation(pixel_size: int) -> void:
|
||||||
var names: PackedStringArray = [
|
if _settings_manager == null:
|
||||||
"legible",
|
return
|
||||||
"cute",
|
if not _settings_manager.apply_pixelation(
|
||||||
"retro",
|
_settings_manager.current_settings.world_pixel_size,
|
||||||
"hardcore",
|
pixel_size
|
||||||
"wtf",
|
):
|
||||||
]
|
_feedback.text = "failed to save pixelation settings."
|
||||||
var index: int = clampi(pixel_size - 1, 0, names.size() - 1)
|
return
|
||||||
return names[index]
|
_refresh_value_labels()
|
||||||
|
|
||||||
|
|
||||||
|
func _adjust_mouse_sensitivity(direction: int) -> void:
|
||||||
|
_mouse_sensitivity = clampf(
|
||||||
|
_mouse_sensitivity + float(direction) * 0.0005,
|
||||||
|
PlayerSettings.MIN_MOUSE_SENSITIVITY,
|
||||||
|
PlayerSettings.MAX_MOUSE_SENSITIVITY
|
||||||
|
)
|
||||||
|
_refresh_value_labels()
|
||||||
|
|
||||||
|
|
||||||
|
func _adjust_controller_sensitivity(direction: int) -> void:
|
||||||
|
_controller_sensitivity = clampf(
|
||||||
|
_controller_sensitivity + float(direction) * 0.1,
|
||||||
|
PlayerSettings.MIN_CONTROLLER_SENSITIVITY,
|
||||||
|
PlayerSettings.MAX_CONTROLLER_SENSITIVITY
|
||||||
|
)
|
||||||
|
_refresh_value_labels()
|
||||||
|
|
||||||
|
|
||||||
|
func _adjust_auto_click_interval(direction: int) -> void:
|
||||||
|
_auto_click_interval_value = clampf(
|
||||||
|
_auto_click_interval_value + float(direction) * 0.01,
|
||||||
|
PlayerSettings.MIN_AUTO_CLICK_INTERVAL,
|
||||||
|
PlayerSettings.MAX_AUTO_CLICK_INTERVAL
|
||||||
|
)
|
||||||
|
_refresh_value_labels()
|
||||||
|
|
||||||
|
|
||||||
|
func _toggle_invert_y() -> void:
|
||||||
|
_invert_camera_y = not _invert_camera_y
|
||||||
|
_refresh_value_labels()
|
||||||
|
|
||||||
|
|
||||||
|
func _toggle_auto_click() -> void:
|
||||||
|
_auto_click_enabled = not _auto_click_enabled
|
||||||
|
_refresh_value_labels()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_continuous_value_input(
|
||||||
|
event: InputEvent,
|
||||||
|
control_id: StringName,
|
||||||
|
) -> void:
|
||||||
|
var direction: int = 0
|
||||||
|
if event.is_action_pressed("ui_left"):
|
||||||
|
direction = -1
|
||||||
|
elif event.is_action_pressed("ui_right"):
|
||||||
|
direction = 1
|
||||||
|
if direction == 0:
|
||||||
|
return
|
||||||
|
match control_id:
|
||||||
|
&"mouse":
|
||||||
|
_adjust_mouse_sensitivity(direction)
|
||||||
|
&"controller":
|
||||||
|
_adjust_controller_sensitivity(direction)
|
||||||
|
&"interval":
|
||||||
|
_adjust_auto_click_interval(direction)
|
||||||
|
accept_event()
|
||||||
|
|
||||||
|
|
||||||
|
func _pixel_size_label(pixel_size: int) -> String:
|
||||||
|
var index: int = clampi(
|
||||||
|
pixel_size - 1,
|
||||||
|
0,
|
||||||
|
PIXELATION_NAMES.size() - 1
|
||||||
|
)
|
||||||
|
return PIXELATION_NAMES[index]
|
||||||
|
|
||||||
|
|
||||||
func set_effective_ui_pixel_size(pixel_size: int) -> void:
|
func set_effective_ui_pixel_size(pixel_size: int) -> void:
|
||||||
|
|
@ -145,11 +479,19 @@ func set_effective_ui_pixel_size(pixel_size: int) -> void:
|
||||||
PlayerSettings.MAX_UI_PIXEL_SIZE
|
PlayerSettings.MAX_UI_PIXEL_SIZE
|
||||||
)
|
)
|
||||||
if is_node_ready():
|
if is_node_ready():
|
||||||
_refresh_value_labels(0.0)
|
_refresh_value_labels()
|
||||||
|
|
||||||
|
|
||||||
func focus_back_button() -> void:
|
func focus_back_button() -> void:
|
||||||
%CancelSettingsButton.grab_focus()
|
var active_page: SettingsBubblePage = _get_active_page()
|
||||||
|
if active_page != null:
|
||||||
|
active_page.focus_back()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_back_bubble_gui_input(event: InputEvent) -> void:
|
||||||
|
if event.is_action_pressed("ui_down") or event.is_action_pressed("ui_focus_next"):
|
||||||
|
crisp_reset_focus_requested.emit()
|
||||||
|
accept_event()
|
||||||
|
|
||||||
|
|
||||||
func refresh_open_panel() -> void:
|
func refresh_open_panel() -> void:
|
||||||
|
|
@ -157,15 +499,6 @@ func refresh_open_panel() -> void:
|
||||||
_load_controls()
|
_load_controls()
|
||||||
|
|
||||||
|
|
||||||
func _on_back_button_gui_input(event: InputEvent) -> void:
|
|
||||||
if (
|
|
||||||
event.is_action_pressed("ui_down")
|
|
||||||
or event.is_action_pressed("ui_focus_next")
|
|
||||||
):
|
|
||||||
crisp_reset_focus_requested.emit()
|
|
||||||
accept_event()
|
|
||||||
|
|
||||||
|
|
||||||
func _refresh_panel_size() -> void:
|
func _refresh_panel_size() -> void:
|
||||||
if not is_node_ready():
|
if not is_node_ready():
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -1,195 +1,563 @@
|
||||||
[gd_scene load_steps=3 format=3]
|
[gd_scene load_steps=7 format=3]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://ui/settings_panel.gd" id="1_script"]
|
[ext_resource type="Script" path="res://ui/settings_panel.gd" id="1_panel"]
|
||||||
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
|
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
|
||||||
|
[ext_resource type="Script" path="res://ui/settings/settings_bubble_page.gd" id="3_page"]
|
||||||
|
[ext_resource type="PackedScene" path="res://ui/components/bubble_menu/bubble_button.tscn" id="4_bubble"]
|
||||||
|
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_cluster.gd" id="5_cluster"]
|
||||||
|
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="6_profile"]
|
||||||
|
|
||||||
[node name="SettingsPanel" type="PanelContainer"]
|
[node name="SettingsPanel" type="Control"]
|
||||||
visible = false
|
visible = false
|
||||||
custom_minimum_size = Vector2(720, 600)
|
custom_minimum_size = Vector2(960, 700)
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 0
|
||||||
theme = ExtResource("2_theme")
|
theme = ExtResource("2_theme")
|
||||||
script = ExtResource("1_script")
|
script = ExtResource("1_panel")
|
||||||
|
|
||||||
[node name="Margin" type="MarginContainer" parent="."]
|
[node name="Backdrop" type="ColorRect" parent="."]
|
||||||
layout_mode = 2
|
layout_mode = 1
|
||||||
theme_override_constants/margin_left = 28
|
anchors_preset = 15
|
||||||
theme_override_constants/margin_top = 24
|
anchor_right = 1.0
|
||||||
theme_override_constants/margin_right = 28
|
anchor_bottom = 1.0
|
||||||
theme_override_constants/margin_bottom = 24
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
color = Color(0.025, 0.085, 0.115, 0.72)
|
||||||
|
|
||||||
[node name="Scroll" type="ScrollContainer" parent="Margin"]
|
[node name="SettingsFeedback" type="Label" parent="."]
|
||||||
layout_mode = 2
|
unique_name_in_owner = true
|
||||||
horizontal_scroll_mode = 0
|
layout_mode = 1
|
||||||
|
anchors_preset = 12
|
||||||
[node name="Content" type="VBoxContainer" parent="Margin/Scroll"]
|
anchor_right = 1.0
|
||||||
layout_mode = 2
|
anchor_bottom = 1.0
|
||||||
size_flags_horizontal = 3
|
offset_top = -42.0
|
||||||
theme_override_constants/separation = 12
|
offset_bottom = -8.0
|
||||||
|
grow_horizontal = 2
|
||||||
[node name="Heading" type="Label" parent="Margin/Scroll/Content"]
|
grow_vertical = 0
|
||||||
layout_mode = 2
|
mouse_filter = 2
|
||||||
theme_override_font_sizes/font_size = 39
|
|
||||||
text = "settings"
|
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
|
||||||
[node name="AutoClickToggle" type="CheckButton" parent="Margin/Scroll/Content"]
|
[node name="RootPage" type="Control" parent="."]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 1
|
||||||
text = "accessibility auto-click"
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("3_page")
|
||||||
|
page_id = &"root"
|
||||||
|
bubble_paths = Array[NodePath]([NodePath("BubbleCluster/DisplayCategory"), NodePath("BubbleCluster/ControlsCategory"), NodePath("BubbleCluster/AccessibilityCategory"), NodePath("BubbleCluster/ApplySettingsButton"), NodePath("BubbleCluster/RootBackButton")])
|
||||||
|
focus_paths = Array[NodePath]([NodePath("BubbleCluster/DisplayCategory"), NodePath("BubbleCluster/ControlsCategory"), NodePath("BubbleCluster/AccessibilityCategory"), NodePath("BubbleCluster/ApplySettingsButton"), NodePath("BubbleCluster/RootBackButton")])
|
||||||
|
initial_focus_path = NodePath("BubbleCluster/DisplayCategory")
|
||||||
|
back_focus_path = NodePath("BubbleCluster/RootBackButton")
|
||||||
|
compact_maximum_layout_size = Vector2(544, 400)
|
||||||
|
|
||||||
[node name="AutoClickHelp" type="Label" parent="Margin/Scroll/Content"]
|
[node name="BubbleCluster" type="Control" parent="RootPage"]
|
||||||
layout_mode = 2
|
layout_mode = 0
|
||||||
text = "lower intervals click barriers faster while held."
|
offset_right = 720.0
|
||||||
autowrap_mode = 2
|
offset_bottom = 520.0
|
||||||
|
script = ExtResource("5_cluster")
|
||||||
|
profile = ExtResource("6_profile")
|
||||||
|
desktop_reference_size = Vector2(720, 520)
|
||||||
|
compact_reference_size = Vector2(608, 448)
|
||||||
|
|
||||||
[node name="AutoClickRow" type="HBoxContainer" parent="Margin/Scroll/Content"]
|
[node name="DisplayCategory" parent="RootPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
layout_mode = 2
|
|
||||||
theme_override_constants/separation = 12
|
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="Margin/Scroll/Content/AutoClickRow"]
|
|
||||||
custom_minimum_size = Vector2(260, 0)
|
|
||||||
layout_mode = 2
|
|
||||||
text = "auto-click interval"
|
|
||||||
autowrap_mode = 2
|
|
||||||
|
|
||||||
[node name="AutoClickInterval" type="HSlider" parent="Margin/Scroll/Content/AutoClickRow"]
|
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
custom_minimum_size = Vector2(0, 0)
|
||||||
size_flags_horizontal = 3
|
offset_left = 135.0
|
||||||
min_value = 0.1
|
offset_top = 90.0
|
||||||
max_value = 0.5
|
offset_right = 305.0
|
||||||
step = 0.01
|
offset_bottom = 250.0
|
||||||
value = 0.2
|
text = "display"
|
||||||
|
neutral_size = Vector2(170, 160)
|
||||||
|
desktop_anchor = Vector2(280, 180)
|
||||||
|
compact_anchor = Vector2(220, 150)
|
||||||
|
compact_minimum_size = Vector2(130, 124)
|
||||||
|
minimum_font_size = 18
|
||||||
|
maximum_font_size = 27
|
||||||
|
motion_phase = 0.35
|
||||||
|
|
||||||
[node name="AutoClickIntervalValue" type="Label" parent="Margin/Scroll/Content/AutoClickRow"]
|
[node name="ControlsCategory" parent="RootPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
custom_minimum_size = Vector2(100, 0)
|
custom_minimum_size = Vector2(0, 0)
|
||||||
layout_mode = 2
|
offset_left = 377.0
|
||||||
text = "0.20 s"
|
offset_top = 96.0
|
||||||
|
offset_right = 533.0
|
||||||
|
offset_bottom = 244.0
|
||||||
|
text = "controls"
|
||||||
|
neutral_size = Vector2(156, 148)
|
||||||
|
desktop_anchor = Vector2(440, 180)
|
||||||
|
compact_anchor = Vector2(385, 150)
|
||||||
|
compact_minimum_size = Vector2(124, 118)
|
||||||
|
minimum_font_size = 17
|
||||||
|
maximum_font_size = 25
|
||||||
|
motion_phase = 1.45
|
||||||
|
|
||||||
[node name="MouseRow" type="HBoxContainer" parent="Margin/Scroll/Content"]
|
[node name="AccessibilityCategory" parent="RootPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
layout_mode = 2
|
|
||||||
theme_override_constants/separation = 12
|
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="Margin/Scroll/Content/MouseRow"]
|
|
||||||
custom_minimum_size = Vector2(260, 0)
|
|
||||||
layout_mode = 2
|
|
||||||
text = "mouse camera sensitivity"
|
|
||||||
autowrap_mode = 2
|
|
||||||
|
|
||||||
[node name="MouseSensitivity" type="HSlider" parent="Margin/Scroll/Content/MouseRow"]
|
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
custom_minimum_size = Vector2(0, 0)
|
||||||
size_flags_horizontal = 3
|
offset_left = 240.0
|
||||||
min_value = 0.001
|
offset_top = 262.0
|
||||||
max_value = 0.012
|
offset_right = 420.0
|
||||||
step = 0.0005
|
offset_bottom = 428.0
|
||||||
value = 0.005
|
text = "accessibility"
|
||||||
|
neutral_size = Vector2(180, 168)
|
||||||
|
desktop_anchor = Vector2(367, 328)
|
||||||
|
compact_anchor = Vector2(307, 311)
|
||||||
|
compact_minimum_size = Vector2(150, 142)
|
||||||
|
minimum_font_size = 17
|
||||||
|
maximum_font_size = 27
|
||||||
|
motion_phase = 2.65
|
||||||
|
|
||||||
[node name="MouseSensitivityValue" type="Label" parent="Margin/Scroll/Content/MouseRow"]
|
[node name="ApplySettingsButton" parent="RootPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
custom_minimum_size = Vector2(100, 0)
|
custom_minimum_size = Vector2(0, 0)
|
||||||
layout_mode = 2
|
offset_left = 474.0
|
||||||
text = "0.0050"
|
offset_top = 308.0
|
||||||
|
offset_right = 586.0
|
||||||
[node name="ControllerRow" type="HBoxContainer" parent="Margin/Scroll/Content"]
|
offset_bottom = 412.0
|
||||||
layout_mode = 2
|
|
||||||
theme_override_constants/separation = 12
|
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="Margin/Scroll/Content/ControllerRow"]
|
|
||||||
custom_minimum_size = Vector2(260, 0)
|
|
||||||
layout_mode = 2
|
|
||||||
text = "controller camera sensitivity"
|
|
||||||
autowrap_mode = 2
|
|
||||||
|
|
||||||
[node name="ControllerSensitivity" type="HSlider" parent="Margin/Scroll/Content/ControllerRow"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
min_value = 0.5
|
|
||||||
max_value = 5.0
|
|
||||||
step = 0.1
|
|
||||||
value = 2.5
|
|
||||||
|
|
||||||
[node name="ControllerSensitivityValue" type="Label" parent="Margin/Scroll/Content/ControllerRow"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
custom_minimum_size = Vector2(100, 0)
|
|
||||||
layout_mode = 2
|
|
||||||
text = "2.5"
|
|
||||||
|
|
||||||
[node name="InvertYToggle" type="CheckButton" parent="Margin/Scroll/Content"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
layout_mode = 2
|
|
||||||
text = "invert vertical camera"
|
|
||||||
|
|
||||||
[node name="WorldPixelRow" type="HBoxContainer" parent="Margin/Scroll/Content"]
|
|
||||||
layout_mode = 2
|
|
||||||
theme_override_constants/separation = 12
|
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="Margin/Scroll/Content/WorldPixelRow"]
|
|
||||||
custom_minimum_size = Vector2(260, 0)
|
|
||||||
layout_mode = 2
|
|
||||||
text = "world pixelation"
|
|
||||||
autowrap_mode = 2
|
|
||||||
|
|
||||||
[node name="WorldPixelSize" type="HSlider" parent="Margin/Scroll/Content/WorldPixelRow"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
min_value = 1.0
|
|
||||||
max_value = 5.0
|
|
||||||
step = 1.0
|
|
||||||
value = 3.0
|
|
||||||
|
|
||||||
[node name="WorldPixelSizeValue" type="Label" parent="Margin/Scroll/Content/WorldPixelRow"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
custom_minimum_size = Vector2(170, 0)
|
|
||||||
layout_mode = 2
|
|
||||||
text = "retro"
|
|
||||||
|
|
||||||
[node name="UIPixelRow" type="HBoxContainer" parent="Margin/Scroll/Content"]
|
|
||||||
layout_mode = 2
|
|
||||||
theme_override_constants/separation = 12
|
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="Margin/Scroll/Content/UIPixelRow"]
|
|
||||||
custom_minimum_size = Vector2(260, 0)
|
|
||||||
layout_mode = 2
|
|
||||||
text = "ui pixelation"
|
|
||||||
autowrap_mode = 2
|
|
||||||
|
|
||||||
[node name="UIPixelSize" type="HSlider" parent="Margin/Scroll/Content/UIPixelRow"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_horizontal = 3
|
|
||||||
min_value = 1.0
|
|
||||||
max_value = 5.0
|
|
||||||
step = 1.0
|
|
||||||
value = 3.0
|
|
||||||
|
|
||||||
[node name="UIPixelSizeValue" type="Label" parent="Margin/Scroll/Content/UIPixelRow"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
custom_minimum_size = Vector2(170, 0)
|
|
||||||
layout_mode = 2
|
|
||||||
text = "retro"
|
|
||||||
|
|
||||||
[node name="SettingsFeedback" type="Label" parent="Margin/Scroll/Content"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
custom_minimum_size = Vector2(0, 44)
|
|
||||||
layout_mode = 2
|
|
||||||
horizontal_alignment = 1
|
|
||||||
|
|
||||||
[node name="Buttons" type="HBoxContainer" parent="Margin/Scroll/Content"]
|
|
||||||
layout_mode = 2
|
|
||||||
theme_override_constants/separation = 12
|
|
||||||
alignment = 2
|
|
||||||
|
|
||||||
[node name="ApplySettingsButton" type="Button" parent="Margin/Scroll/Content/Buttons"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
custom_minimum_size = Vector2(150, 64)
|
|
||||||
layout_mode = 2
|
|
||||||
text = "apply"
|
text = "apply"
|
||||||
|
neutral_size = Vector2(112, 104)
|
||||||
|
desktop_anchor = Vector2(511, 332)
|
||||||
|
compact_anchor = Vector2(470, 330)
|
||||||
|
compact_minimum_size = Vector2(94, 90)
|
||||||
|
minimum_font_size = 15
|
||||||
|
maximum_font_size = 19
|
||||||
|
motion_phase = 3.7
|
||||||
|
|
||||||
[node name="CancelSettingsButton" type="Button" parent="Margin/Scroll/Content/Buttons"]
|
[node name="RootBackButton" parent="RootPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
custom_minimum_size = Vector2(150, 64)
|
custom_minimum_size = Vector2(0, 0)
|
||||||
layout_mode = 2
|
offset_left = 70.0
|
||||||
|
offset_top = 343.0
|
||||||
|
offset_right = 170.0
|
||||||
|
offset_bottom = 437.0
|
||||||
text = "back"
|
text = "back"
|
||||||
|
neutral_size = Vector2(100, 94)
|
||||||
|
desktop_anchor = Vector2(220, 300)
|
||||||
|
compact_anchor = Vector2(155, 275)
|
||||||
|
compact_minimum_size = Vector2(84, 80)
|
||||||
|
minimum_font_size = 14
|
||||||
|
maximum_font_size = 17
|
||||||
|
motion_phase = 4.8
|
||||||
|
|
||||||
|
[node name="DisplayPage" type="Control" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("3_page")
|
||||||
|
page_id = &"display"
|
||||||
|
bubble_paths = Array[NodePath]([NodePath("BubbleCluster/WorldValue"), NodePath("BubbleCluster/WorldLegible"), NodePath("BubbleCluster/WorldCute"), NodePath("BubbleCluster/WorldRetro"), NodePath("BubbleCluster/WorldHardcore"), NodePath("BubbleCluster/WorldWtf"), NodePath("BubbleCluster/UIValue"), NodePath("BubbleCluster/UILegible"), NodePath("BubbleCluster/UICute"), NodePath("BubbleCluster/UIRetro"), NodePath("BubbleCluster/UIHardcore"), NodePath("BubbleCluster/UIWtf"), NodePath("BubbleCluster/DisplayBackButton")])
|
||||||
|
focus_paths = Array[NodePath]([NodePath("BubbleCluster/WorldLegible"), NodePath("BubbleCluster/WorldCute"), NodePath("BubbleCluster/WorldRetro"), NodePath("BubbleCluster/WorldHardcore"), NodePath("BubbleCluster/WorldWtf"), NodePath("BubbleCluster/UILegible"), NodePath("BubbleCluster/UICute"), NodePath("BubbleCluster/UIRetro"), NodePath("BubbleCluster/UIHardcore"), NodePath("BubbleCluster/UIWtf"), NodePath("BubbleCluster/DisplayBackButton")])
|
||||||
|
initial_focus_path = NodePath("BubbleCluster/WorldRetro")
|
||||||
|
back_focus_path = NodePath("BubbleCluster/DisplayBackButton")
|
||||||
|
compact_maximum_layout_size = Vector2(544, 400)
|
||||||
|
|
||||||
|
[node name="BubbleCluster" type="Control" parent="DisplayPage"]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_right = 720.0
|
||||||
|
offset_bottom = 520.0
|
||||||
|
script = ExtResource("5_cluster")
|
||||||
|
profile = ExtResource("6_profile")
|
||||||
|
desktop_reference_size = Vector2(720, 520)
|
||||||
|
compact_reference_size = Vector2(608, 448)
|
||||||
|
|
||||||
|
[node name="WorldValue" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
mouse_filter = 2
|
||||||
|
focus_mode = 0
|
||||||
|
text = "world\npixelation\nretro"
|
||||||
|
neutral_size = Vector2(160, 150)
|
||||||
|
desktop_anchor = Vector2(160, 240)
|
||||||
|
compact_anchor = Vector2(175, 210)
|
||||||
|
compact_minimum_size = Vector2(132, 126)
|
||||||
|
minimum_font_size = 15
|
||||||
|
maximum_font_size = 25
|
||||||
|
motion_phase = 0.2
|
||||||
|
|
||||||
|
[node name="WorldLegible" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
toggle_mode = true
|
||||||
|
text = "legible"
|
||||||
|
neutral_size = Vector2(90, 84)
|
||||||
|
desktop_anchor = Vector2(55, 175)
|
||||||
|
compact_anchor = Vector2(57, 135)
|
||||||
|
compact_minimum_size = Vector2(76, 72)
|
||||||
|
minimum_font_size = 12
|
||||||
|
maximum_font_size = 15
|
||||||
|
motion_phase = 0.8
|
||||||
|
|
||||||
|
[node name="WorldCute" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
toggle_mode = true
|
||||||
|
text = "cute"
|
||||||
|
neutral_size = Vector2(82, 78)
|
||||||
|
desktop_anchor = Vector2(130, 124)
|
||||||
|
compact_anchor = Vector2(145, 78)
|
||||||
|
compact_minimum_size = Vector2(70, 68)
|
||||||
|
minimum_font_size = 12
|
||||||
|
maximum_font_size = 14
|
||||||
|
motion_phase = 1.35
|
||||||
|
|
||||||
|
[node name="WorldRetro" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
toggle_mode = true
|
||||||
|
button_pressed = true
|
||||||
|
text = "retro"
|
||||||
|
neutral_size = Vector2(84, 80)
|
||||||
|
desktop_anchor = Vector2(237, 149)
|
||||||
|
compact_anchor = Vector2(272, 115)
|
||||||
|
compact_minimum_size = Vector2(72, 68)
|
||||||
|
minimum_font_size = 12
|
||||||
|
maximum_font_size = 14
|
||||||
|
motion_phase = 1.9
|
||||||
|
|
||||||
|
[node name="WorldHardcore" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
toggle_mode = true
|
||||||
|
text = "hardcore"
|
||||||
|
neutral_size = Vector2(100, 94)
|
||||||
|
desktop_anchor = Vector2(288, 240)
|
||||||
|
compact_anchor = Vector2(70, 310)
|
||||||
|
compact_minimum_size = Vector2(88, 84)
|
||||||
|
minimum_font_size = 12
|
||||||
|
maximum_font_size = 16
|
||||||
|
motion_phase = 2.45
|
||||||
|
|
||||||
|
[node name="WorldWtf" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
toggle_mode = true
|
||||||
|
text = "wtf"
|
||||||
|
neutral_size = Vector2(76, 72)
|
||||||
|
desktop_anchor = Vector2(225, 337)
|
||||||
|
compact_anchor = Vector2(284, 284)
|
||||||
|
compact_minimum_size = Vector2(66, 64)
|
||||||
|
minimum_font_size = 12
|
||||||
|
maximum_font_size = 13
|
||||||
|
motion_phase = 3.0
|
||||||
|
|
||||||
|
[node name="UIValue" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
mouse_filter = 2
|
||||||
|
focus_mode = 0
|
||||||
|
text = "ui\npixelation\nretro"
|
||||||
|
neutral_size = Vector2(160, 150)
|
||||||
|
desktop_anchor = Vector2(560, 240)
|
||||||
|
compact_anchor = Vector2(545, 210)
|
||||||
|
compact_minimum_size = Vector2(132, 126)
|
||||||
|
minimum_font_size = 15
|
||||||
|
maximum_font_size = 25
|
||||||
|
motion_phase = 3.55
|
||||||
|
|
||||||
|
[node name="UILegible" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
toggle_mode = true
|
||||||
|
text = "legible"
|
||||||
|
neutral_size = Vector2(90, 84)
|
||||||
|
desktop_anchor = Vector2(665, 175)
|
||||||
|
compact_anchor = Vector2(663, 135)
|
||||||
|
compact_minimum_size = Vector2(76, 72)
|
||||||
|
minimum_font_size = 12
|
||||||
|
maximum_font_size = 15
|
||||||
|
motion_phase = 4.1
|
||||||
|
|
||||||
|
[node name="UICute" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
toggle_mode = true
|
||||||
|
text = "cute"
|
||||||
|
neutral_size = Vector2(82, 78)
|
||||||
|
desktop_anchor = Vector2(590, 124)
|
||||||
|
compact_anchor = Vector2(575, 78)
|
||||||
|
compact_minimum_size = Vector2(70, 68)
|
||||||
|
minimum_font_size = 12
|
||||||
|
maximum_font_size = 14
|
||||||
|
motion_phase = 4.65
|
||||||
|
|
||||||
|
[node name="UIRetro" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
toggle_mode = true
|
||||||
|
button_pressed = true
|
||||||
|
text = "retro"
|
||||||
|
neutral_size = Vector2(84, 80)
|
||||||
|
desktop_anchor = Vector2(483, 149)
|
||||||
|
compact_anchor = Vector2(448, 115)
|
||||||
|
compact_minimum_size = Vector2(72, 68)
|
||||||
|
minimum_font_size = 12
|
||||||
|
maximum_font_size = 14
|
||||||
|
motion_phase = 5.2
|
||||||
|
|
||||||
|
[node name="UIHardcore" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
toggle_mode = true
|
||||||
|
text = "hardcore"
|
||||||
|
neutral_size = Vector2(100, 94)
|
||||||
|
desktop_anchor = Vector2(432, 240)
|
||||||
|
compact_anchor = Vector2(650, 310)
|
||||||
|
compact_minimum_size = Vector2(88, 84)
|
||||||
|
minimum_font_size = 12
|
||||||
|
maximum_font_size = 16
|
||||||
|
motion_phase = 5.75
|
||||||
|
|
||||||
|
[node name="UIWtf" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
toggle_mode = true
|
||||||
|
text = "wtf"
|
||||||
|
neutral_size = Vector2(76, 72)
|
||||||
|
desktop_anchor = Vector2(495, 337)
|
||||||
|
compact_anchor = Vector2(436, 284)
|
||||||
|
compact_minimum_size = Vector2(66, 64)
|
||||||
|
minimum_font_size = 12
|
||||||
|
maximum_font_size = 13
|
||||||
|
motion_phase = 0.55
|
||||||
|
|
||||||
|
[node name="DisplayBackButton" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
text = "back"
|
||||||
|
neutral_size = Vector2(96, 90)
|
||||||
|
desktop_anchor = Vector2(350, 445)
|
||||||
|
compact_anchor = Vector2(315, 390)
|
||||||
|
compact_minimum_size = Vector2(82, 78)
|
||||||
|
minimum_font_size = 13
|
||||||
|
maximum_font_size = 16
|
||||||
|
motion_phase = 1.1
|
||||||
|
|
||||||
|
[node name="ControlsPage" type="Control" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("3_page")
|
||||||
|
page_id = &"controls"
|
||||||
|
bubble_paths = Array[NodePath]([NodePath("BubbleCluster/MouseDecrease"), NodePath("BubbleCluster/MouseValue"), NodePath("BubbleCluster/MouseIncrease"), NodePath("BubbleCluster/ControllerDecrease"), NodePath("BubbleCluster/ControllerValue"), NodePath("BubbleCluster/ControllerIncrease"), NodePath("BubbleCluster/InvertYToggle"), NodePath("BubbleCluster/ControlsBackButton")])
|
||||||
|
focus_paths = Array[NodePath]([NodePath("BubbleCluster/MouseDecrease"), NodePath("BubbleCluster/MouseValue"), NodePath("BubbleCluster/MouseIncrease"), NodePath("BubbleCluster/ControllerDecrease"), NodePath("BubbleCluster/ControllerValue"), NodePath("BubbleCluster/ControllerIncrease"), NodePath("BubbleCluster/InvertYToggle"), NodePath("BubbleCluster/ControlsBackButton")])
|
||||||
|
initial_focus_path = NodePath("BubbleCluster/MouseValue")
|
||||||
|
back_focus_path = NodePath("BubbleCluster/ControlsBackButton")
|
||||||
|
|
||||||
|
[node name="BubbleCluster" type="Control" parent="ControlsPage"]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_right = 720.0
|
||||||
|
offset_bottom = 520.0
|
||||||
|
script = ExtResource("5_cluster")
|
||||||
|
profile = ExtResource("6_profile")
|
||||||
|
desktop_reference_size = Vector2(720, 520)
|
||||||
|
compact_reference_size = Vector2(608, 448)
|
||||||
|
|
||||||
|
[node name="MouseDecrease" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
text = "−"
|
||||||
|
neutral_size = Vector2(80, 76)
|
||||||
|
desktop_anchor = Vector2(75, 140)
|
||||||
|
compact_anchor = Vector2(49, 125)
|
||||||
|
compact_minimum_size = Vector2(68, 66)
|
||||||
|
minimum_font_size = 17
|
||||||
|
maximum_font_size = 24
|
||||||
|
motion_phase = 0.3
|
||||||
|
|
||||||
|
[node name="MouseValue" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
text = "mouse\nsensitivity\n0.0050"
|
||||||
|
neutral_size = Vector2(190, 180)
|
||||||
|
desktop_anchor = Vector2(210, 140)
|
||||||
|
compact_anchor = Vector2(200, 125)
|
||||||
|
compact_minimum_size = Vector2(160, 152)
|
||||||
|
minimum_font_size = 15
|
||||||
|
maximum_font_size = 25
|
||||||
|
motion_phase = 1.0
|
||||||
|
|
||||||
|
[node name="MouseIncrease" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
text = "+"
|
||||||
|
neutral_size = Vector2(80, 76)
|
||||||
|
desktop_anchor = Vector2(345, 140)
|
||||||
|
compact_anchor = Vector2(351, 125)
|
||||||
|
compact_minimum_size = Vector2(68, 66)
|
||||||
|
minimum_font_size = 17
|
||||||
|
maximum_font_size = 24
|
||||||
|
motion_phase = 1.7
|
||||||
|
|
||||||
|
[node name="ControllerDecrease" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
text = "−"
|
||||||
|
neutral_size = Vector2(80, 76)
|
||||||
|
desktop_anchor = Vector2(75, 365)
|
||||||
|
compact_anchor = Vector2(49, 340)
|
||||||
|
compact_minimum_size = Vector2(68, 66)
|
||||||
|
minimum_font_size = 17
|
||||||
|
maximum_font_size = 24
|
||||||
|
motion_phase = 2.4
|
||||||
|
|
||||||
|
[node name="ControllerValue" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
text = "controller\nsensitivity\n2.5"
|
||||||
|
neutral_size = Vector2(190, 180)
|
||||||
|
desktop_anchor = Vector2(210, 365)
|
||||||
|
compact_anchor = Vector2(200, 340)
|
||||||
|
compact_minimum_size = Vector2(160, 152)
|
||||||
|
minimum_font_size = 15
|
||||||
|
maximum_font_size = 25
|
||||||
|
motion_phase = 3.1
|
||||||
|
|
||||||
|
[node name="ControllerIncrease" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
text = "+"
|
||||||
|
neutral_size = Vector2(80, 76)
|
||||||
|
desktop_anchor = Vector2(345, 365)
|
||||||
|
compact_anchor = Vector2(351, 340)
|
||||||
|
compact_minimum_size = Vector2(68, 66)
|
||||||
|
minimum_font_size = 17
|
||||||
|
maximum_font_size = 24
|
||||||
|
motion_phase = 3.8
|
||||||
|
|
||||||
|
[node name="InvertYToggle" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
text = "invert\nvertical\ncamera\noff"
|
||||||
|
neutral_size = Vector2(176, 170)
|
||||||
|
desktop_anchor = Vector2(525, 230)
|
||||||
|
compact_anchor = Vector2(485, 225)
|
||||||
|
compact_minimum_size = Vector2(170, 164)
|
||||||
|
minimum_font_size = 14
|
||||||
|
maximum_font_size = 24
|
||||||
|
motion_phase = 4.5
|
||||||
|
|
||||||
|
[node name="ControlsBackButton" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
text = "back"
|
||||||
|
neutral_size = Vector2(100, 94)
|
||||||
|
desktop_anchor = Vector2(525, 425)
|
||||||
|
compact_anchor = Vector2(540, 395)
|
||||||
|
compact_minimum_size = Vector2(84, 80)
|
||||||
|
minimum_font_size = 14
|
||||||
|
maximum_font_size = 17
|
||||||
|
motion_phase = 5.2
|
||||||
|
|
||||||
|
[node name="AccessibilityPage" type="Control" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("3_page")
|
||||||
|
page_id = &"accessibility"
|
||||||
|
bubble_paths = Array[NodePath]([NodePath("BubbleCluster/AutoClickToggle"), NodePath("BubbleCluster/IntervalDecrease"), NodePath("BubbleCluster/AutoClickIntervalValue"), NodePath("BubbleCluster/IntervalIncrease"), NodePath("BubbleCluster/IntervalHelp"), NodePath("BubbleCluster/AccessibilityBackButton")])
|
||||||
|
focus_paths = Array[NodePath]([NodePath("BubbleCluster/AutoClickToggle"), NodePath("BubbleCluster/IntervalDecrease"), NodePath("BubbleCluster/AutoClickIntervalValue"), NodePath("BubbleCluster/IntervalIncrease"), NodePath("BubbleCluster/AccessibilityBackButton")])
|
||||||
|
initial_focus_path = NodePath("BubbleCluster/AutoClickToggle")
|
||||||
|
back_focus_path = NodePath("BubbleCluster/AccessibilityBackButton")
|
||||||
|
|
||||||
|
[node name="BubbleCluster" type="Control" parent="AccessibilityPage"]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_right = 720.0
|
||||||
|
offset_bottom = 520.0
|
||||||
|
script = ExtResource("5_cluster")
|
||||||
|
profile = ExtResource("6_profile")
|
||||||
|
desktop_reference_size = Vector2(720, 520)
|
||||||
|
compact_reference_size = Vector2(608, 448)
|
||||||
|
|
||||||
|
[node name="AutoClickToggle" parent="AccessibilityPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
text = "accessibility\nauto-click\noff"
|
||||||
|
neutral_size = Vector2(190, 180)
|
||||||
|
desktop_anchor = Vector2(200, 195)
|
||||||
|
compact_anchor = Vector2(129, 185)
|
||||||
|
compact_minimum_size = Vector2(160, 152)
|
||||||
|
minimum_font_size = 14
|
||||||
|
maximum_font_size = 27
|
||||||
|
motion_phase = 0.5
|
||||||
|
|
||||||
|
[node name="IntervalDecrease" parent="AccessibilityPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
text = "−"
|
||||||
|
neutral_size = Vector2(80, 76)
|
||||||
|
desktop_anchor = Vector2(340, 210)
|
||||||
|
compact_anchor = Vector2(280, 205)
|
||||||
|
compact_minimum_size = Vector2(68, 66)
|
||||||
|
minimum_font_size = 17
|
||||||
|
maximum_font_size = 24
|
||||||
|
motion_phase = 1.4
|
||||||
|
|
||||||
|
[node name="AutoClickIntervalValue" parent="AccessibilityPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
text = "auto-click\ninterval\n0.20 s"
|
||||||
|
neutral_size = Vector2(190, 180)
|
||||||
|
desktop_anchor = Vector2(475, 210)
|
||||||
|
compact_anchor = Vector2(431, 205)
|
||||||
|
compact_minimum_size = Vector2(160, 152)
|
||||||
|
minimum_font_size = 14
|
||||||
|
maximum_font_size = 26
|
||||||
|
motion_phase = 2.3
|
||||||
|
|
||||||
|
[node name="IntervalIncrease" parent="AccessibilityPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
text = "+"
|
||||||
|
neutral_size = Vector2(80, 76)
|
||||||
|
desktop_anchor = Vector2(610, 210)
|
||||||
|
compact_anchor = Vector2(582, 205)
|
||||||
|
compact_minimum_size = Vector2(68, 66)
|
||||||
|
minimum_font_size = 17
|
||||||
|
maximum_font_size = 24
|
||||||
|
motion_phase = 3.2
|
||||||
|
|
||||||
|
[node name="IntervalHelp" parent="AccessibilityPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
mouse_filter = 2
|
||||||
|
focus_mode = 0
|
||||||
|
text = "lower intervals\nclick barriers\nfaster\nwhile held"
|
||||||
|
neutral_size = Vector2(170, 160)
|
||||||
|
desktop_anchor = Vector2(315, 405)
|
||||||
|
compact_anchor = Vector2(280, 370)
|
||||||
|
compact_minimum_size = Vector2(160, 152)
|
||||||
|
minimum_font_size = 13
|
||||||
|
maximum_font_size = 22
|
||||||
|
motion_phase = 4.1
|
||||||
|
|
||||||
|
[node name="AccessibilityBackButton" parent="AccessibilityPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
text = "back"
|
||||||
|
neutral_size = Vector2(96, 90)
|
||||||
|
desktop_anchor = Vector2(560, 420)
|
||||||
|
compact_anchor = Vector2(520, 380)
|
||||||
|
compact_minimum_size = Vector2(82, 78)
|
||||||
|
minimum_font_size = 13
|
||||||
|
maximum_font_size = 16
|
||||||
|
motion_phase = 5.0
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,13 @@ const START_PROMPT_MIN_SCALE: float = 0.985
|
||||||
const START_PROMPT_MAX_SCALE: float = 1.015
|
const START_PROMPT_MAX_SCALE: float = 1.015
|
||||||
const START_PROMPT_CYCLE_SECONDS: float = 3.0
|
const START_PROMPT_CYCLE_SECONDS: float = 3.0
|
||||||
const DISABLED_BUBBLE_LABEL_ALPHA: float = 0.55
|
const DISABLED_BUBBLE_LABEL_ALPHA: float = 0.55
|
||||||
|
const INTRO_PROMPT_FADE_DURATION: float = 0.55
|
||||||
|
const INTRO_BUBBLE_TRAVEL_DURATION: float = 2.40
|
||||||
|
const INTRO_BRANDING_TRAVEL_DURATION: float = 2.0
|
||||||
|
const INTRO_BRANDING_START_DELAY: float = 0.35
|
||||||
|
const HOST_PRESENTATION_OUT_DURATION: float = 1.70
|
||||||
|
const HOST_PRESENTATION_IN_DURATION: float = 1.85
|
||||||
|
const HOST_CLUSTER_SAFE_MARGIN: float = 24.0
|
||||||
|
|
||||||
signal gameplay_requested
|
signal gameplay_requested
|
||||||
signal quit_requested
|
signal quit_requested
|
||||||
|
|
@ -93,7 +100,16 @@ enum ConfirmationAction {
|
||||||
@onready var _decorative_bubble_event_timer: Timer = %DecorativeBubbleEventTimer
|
@onready var _decorative_bubble_event_timer: Timer = %DecorativeBubbleEventTimer
|
||||||
@onready var _decorative_bubble_cluster_timer: Timer = %DecorativeBubbleClusterTimer
|
@onready var _decorative_bubble_cluster_timer: Timer = %DecorativeBubbleClusterTimer
|
||||||
@onready var _title_logo: TextureRect = %TitleLogo
|
@onready var _title_logo: TextureRect = %TitleLogo
|
||||||
|
@onready var _playtest_label: Label = %PlaytestLabel
|
||||||
|
@onready var _intro_branding_anchor: Control = %IntroBrandingAnchor
|
||||||
|
@onready var _presentation_center: CenterContainer = $Center
|
||||||
|
@onready var _main_content: VBoxContainer = $Center/MainContent
|
||||||
|
@onready var _branding_slot: Control = $Center/MainContent/BrandingSlot
|
||||||
|
@onready var _branding_motion_root: Control = %BrandingMotionRoot
|
||||||
|
@onready var _title_spacer: Control = $Center/MainContent/Spacer
|
||||||
@onready var _button_center: CenterContainer = %ButtonCenter
|
@onready var _button_center: CenterContainer = %ButtonCenter
|
||||||
|
@onready var _bubble_layout_slot: Control = $Center/MainContent/ButtonCenter/BubbleLayoutSlot
|
||||||
|
@onready var _bubble_motion_root: Control = %BubbleMotionRoot
|
||||||
@onready var _bubble_field: BubbleClusterType = %BubbleField
|
@onready var _bubble_field: BubbleClusterType = %BubbleField
|
||||||
@onready var _start_prompt_center: CenterContainer = %StartPromptCenter
|
@onready var _start_prompt_center: CenterContainer = %StartPromptCenter
|
||||||
@onready var _start_prompt_label: Label = %StartPromptLabel
|
@onready var _start_prompt_label: Label = %StartPromptLabel
|
||||||
|
|
@ -117,10 +133,39 @@ var _start_prompt_elapsed: float = 0.0
|
||||||
var _navigation_focus_active: bool = false
|
var _navigation_focus_active: bool = false
|
||||||
var _modal_restore_navigation_focus: bool = false
|
var _modal_restore_navigation_focus: bool = false
|
||||||
var _world_pixel_size: int = PlayerSettings.DEFAULT_WORLD_PIXEL_SIZE
|
var _world_pixel_size: int = PlayerSettings.DEFAULT_WORLD_PIXEL_SIZE
|
||||||
|
var _title_settings_transition: Tween
|
||||||
|
var _title_settings_transition_generation: int = 0
|
||||||
|
var _title_settings_transition_active: bool = false
|
||||||
|
var _title_bubble_rest_position: Vector2 = Vector2.ZERO
|
||||||
|
var _title_content_rest_position: Vector2 = Vector2.ZERO
|
||||||
|
var _title_entry_transition: Tween
|
||||||
|
var _title_entry_generation: int = 0
|
||||||
|
var _title_entry_transition_active: bool = false
|
||||||
|
var _intro_geometry_ready: bool = false
|
||||||
|
var _intro_layout_generation: int = 0
|
||||||
|
var _branding_intro_position: Vector2 = Vector2.ZERO
|
||||||
|
var _bubble_intro_position: Vector2 = Vector2.ZERO
|
||||||
|
var _feedback_visible_before_settings: bool = false
|
||||||
|
var _feedback_text_before_settings: String = ""
|
||||||
|
var _continue_stats_hovered: bool = false
|
||||||
|
var _continue_stats_focused: bool = false
|
||||||
|
var _continue_stats_fade: Tween
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
_continue_button.pressed.connect(_on_continue_pressed)
|
_continue_button.pressed.connect(_on_continue_pressed)
|
||||||
|
_continue_button.mouse_entered.connect(
|
||||||
|
_on_continue_stats_hover_changed.bind(true)
|
||||||
|
)
|
||||||
|
_continue_button.mouse_exited.connect(
|
||||||
|
_on_continue_stats_hover_changed.bind(false)
|
||||||
|
)
|
||||||
|
_continue_button.focus_entered.connect(
|
||||||
|
_on_continue_stats_focus_changed.bind(true)
|
||||||
|
)
|
||||||
|
_continue_button.focus_exited.connect(
|
||||||
|
_on_continue_stats_focus_changed.bind(false)
|
||||||
|
)
|
||||||
_new_game_button.pressed.connect(_on_new_game_pressed)
|
_new_game_button.pressed.connect(_on_new_game_pressed)
|
||||||
_settings_button.pressed.connect(_open_settings)
|
_settings_button.pressed.connect(_open_settings)
|
||||||
_delete_button.pressed.connect(_on_delete_pressed)
|
_delete_button.pressed.connect(_on_delete_pressed)
|
||||||
|
|
@ -129,6 +174,7 @@ func _ready() -> void:
|
||||||
%CancelConfirmButton.pressed.connect(_close_confirmation)
|
%CancelConfirmButton.pressed.connect(_close_confirmation)
|
||||||
_settings_panel.applied.connect(_on_settings_applied)
|
_settings_panel.applied.connect(_on_settings_applied)
|
||||||
_settings_panel.closed.connect(_on_settings_closed)
|
_settings_panel.closed.connect(_on_settings_closed)
|
||||||
|
_settings_panel.opened.connect(_on_settings_opened)
|
||||||
_bubble_field.configure(_get_title_buttons())
|
_bubble_field.configure(_get_title_buttons())
|
||||||
_decorative_fish_timer.timeout.connect(_on_decorative_fish_timer_timeout)
|
_decorative_fish_timer.timeout.connect(_on_decorative_fish_timer_timeout)
|
||||||
_decorative_bubble_event_timer.timeout.connect(
|
_decorative_bubble_event_timer.timeout.connect(
|
||||||
|
|
@ -144,6 +190,8 @@ func _ready() -> void:
|
||||||
set_process(false)
|
set_process(false)
|
||||||
call_deferred("_update_title_layout")
|
call_deferred("_update_title_layout")
|
||||||
call_deferred("_update_start_prompt_pivot")
|
call_deferred("_update_start_prompt_pivot")
|
||||||
|
call_deferred("_capture_title_bubble_rest_position")
|
||||||
|
call_deferred("_capture_title_content_rest_position")
|
||||||
|
|
||||||
|
|
||||||
func setup(
|
func setup(
|
||||||
|
|
@ -161,6 +209,8 @@ func setup(
|
||||||
|
|
||||||
|
|
||||||
func reopen() -> void:
|
func reopen() -> void:
|
||||||
|
_cancel_title_entry_transition()
|
||||||
|
_cancel_title_settings_transition()
|
||||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||||
_prepare_awaiting_start_input()
|
_prepare_awaiting_start_input()
|
||||||
_close_confirmation()
|
_close_confirmation()
|
||||||
|
|
@ -213,6 +263,17 @@ func _update_title_layout() -> void:
|
||||||
logo_width,
|
logo_width,
|
||||||
logo_width / LOGO_ASPECT_RATIO
|
logo_width / LOGO_ASPECT_RATIO
|
||||||
)
|
)
|
||||||
|
var branding_separation: float = float(
|
||||||
|
_main_content.get_theme_constant("separation")
|
||||||
|
)
|
||||||
|
var branding_size := Vector2(
|
||||||
|
logo_width,
|
||||||
|
logo_width / LOGO_ASPECT_RATIO
|
||||||
|
+ branding_separation
|
||||||
|
+ _playtest_label.get_combined_minimum_size().y
|
||||||
|
)
|
||||||
|
_branding_slot.custom_minimum_size = branding_size
|
||||||
|
_branding_motion_root.size = branding_size
|
||||||
var field_width: float = minf(BUBBLE_FIELD_MAX_WIDTH, available_width)
|
var field_width: float = minf(BUBBLE_FIELD_MAX_WIDTH, available_width)
|
||||||
var field_height: float = (
|
var field_height: float = (
|
||||||
BUBBLE_FIELD_COMPACT_HEIGHT
|
BUBBLE_FIELD_COMPACT_HEIGHT
|
||||||
|
|
@ -221,16 +282,22 @@ func _update_title_layout() -> void:
|
||||||
)
|
)
|
||||||
if size.y < BUBBLE_COMPACT_HEIGHT_THRESHOLD:
|
if size.y < BUBBLE_COMPACT_HEIGHT_THRESHOLD:
|
||||||
field_width = minf(BUBBLE_FIELD_COMPACT_WIDTH, available_width)
|
field_width = minf(BUBBLE_FIELD_COMPACT_WIDTH, available_width)
|
||||||
|
_bubble_layout_slot.custom_minimum_size = Vector2(field_width, field_height)
|
||||||
|
_bubble_motion_root.size = Vector2(field_width, field_height)
|
||||||
_bubble_field.custom_minimum_size = Vector2(field_width, field_height)
|
_bubble_field.custom_minimum_size = Vector2(field_width, field_height)
|
||||||
var compact_layout: bool = field_height == BUBBLE_FIELD_COMPACT_HEIGHT
|
var compact_layout: bool = field_height == BUBBLE_FIELD_COMPACT_HEIGHT
|
||||||
_bubble_field.apply_layout(
|
_bubble_field.apply_layout(
|
||||||
Vector2(field_width, field_height),
|
Vector2(field_width, field_height),
|
||||||
compact_layout
|
compact_layout
|
||||||
)
|
)
|
||||||
|
if not _title_settings_transition_active:
|
||||||
|
call_deferred("_capture_title_bubble_rest_position")
|
||||||
_new_game_label.text = "new\ngame" if compact_layout else "new game"
|
_new_game_label.text = "new\ngame" if compact_layout else "new game"
|
||||||
_delete_save_label.text = (
|
_delete_save_label.text = (
|
||||||
"delete\nsave" if compact_layout else "delete save"
|
"delete\nsave" if compact_layout else "delete save"
|
||||||
)
|
)
|
||||||
|
if _awaiting_start_input and not _title_entry_transition_active:
|
||||||
|
_schedule_intro_presentation()
|
||||||
_update_world_preview_resolution()
|
_update_world_preview_resolution()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -311,16 +378,22 @@ func _process(delta: float) -> void:
|
||||||
pulse_weight
|
pulse_weight
|
||||||
)
|
)
|
||||||
_start_prompt_label.scale = Vector2.ONE * prompt_scale
|
_start_prompt_label.scale = Vector2.ONE * prompt_scale
|
||||||
if _button_center.visible:
|
if _main_content.visible and _button_center.visible:
|
||||||
_bubble_field.advance_motion(delta)
|
_bubble_field.advance_motion(delta)
|
||||||
|
|
||||||
|
|
||||||
func _input(event: InputEvent) -> void:
|
func _input(event: InputEvent) -> void:
|
||||||
if not visible:
|
if not visible:
|
||||||
return
|
return
|
||||||
|
if _title_settings_transition_active or _title_entry_transition_active:
|
||||||
|
get_viewport().set_input_as_handled()
|
||||||
|
return
|
||||||
if _awaiting_start_input:
|
if _awaiting_start_input:
|
||||||
if not _is_start_prompt_reveal_event(event):
|
if not _is_start_prompt_reveal_event(event):
|
||||||
return
|
return
|
||||||
|
if not _intro_geometry_ready:
|
||||||
|
get_viewport().set_input_as_handled()
|
||||||
|
return
|
||||||
_reveal_primary_menu()
|
_reveal_primary_menu()
|
||||||
get_viewport().set_input_as_handled()
|
get_viewport().set_input_as_handled()
|
||||||
return
|
return
|
||||||
|
|
@ -332,7 +405,7 @@ func _input(event: InputEvent) -> void:
|
||||||
if _confirmation_panel.visible:
|
if _confirmation_panel.visible:
|
||||||
_close_confirmation()
|
_close_confirmation()
|
||||||
elif _settings_panel.visible:
|
elif _settings_panel.visible:
|
||||||
_close_settings()
|
_settings_panel.handle_back()
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
get_viewport().set_input_as_handled()
|
get_viewport().set_input_as_handled()
|
||||||
|
|
@ -359,6 +432,7 @@ func _handle_primary_menu_focus_input(event: InputEvent) -> bool:
|
||||||
if event is InputEventMouseMotion:
|
if event is InputEventMouseMotion:
|
||||||
_navigation_focus_active = false
|
_navigation_focus_active = false
|
||||||
_release_primary_menu_focus()
|
_release_primary_menu_focus()
|
||||||
|
_update_continue_stats_visibility()
|
||||||
return false
|
return false
|
||||||
if event is InputEventKey and (event as InputEventKey).echo:
|
if event is InputEventKey and (event as InputEventKey).echo:
|
||||||
return false
|
return false
|
||||||
|
|
@ -409,15 +483,25 @@ func _begin_title_entry() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _prepare_awaiting_start_input() -> void:
|
func _prepare_awaiting_start_input() -> void:
|
||||||
|
_cancel_title_entry_transition()
|
||||||
_awaiting_start_input = true
|
_awaiting_start_input = true
|
||||||
|
_intro_geometry_ready = false
|
||||||
_navigation_focus_active = false
|
_navigation_focus_active = false
|
||||||
_modal_restore_navigation_focus = false
|
_modal_restore_navigation_focus = false
|
||||||
_button_center.hide()
|
_button_center.show()
|
||||||
_feedback_label.hide()
|
_feedback_label.show()
|
||||||
|
_feedback_label.modulate.a = 0.0
|
||||||
|
_continue_stats_hovered = false
|
||||||
|
_continue_stats_focused = false
|
||||||
|
_cancel_continue_stats_fade()
|
||||||
|
_main_content.show()
|
||||||
_start_prompt_center.show()
|
_start_prompt_center.show()
|
||||||
|
_start_prompt_center.modulate.a = 1.0
|
||||||
|
_set_title_bubbles_interactive(false)
|
||||||
var focus_owner: Control = get_viewport().gui_get_focus_owner()
|
var focus_owner: Control = get_viewport().gui_get_focus_owner()
|
||||||
if focus_owner != null and is_ancestor_of(focus_owner):
|
if focus_owner != null and is_ancestor_of(focus_owner):
|
||||||
focus_owner.release_focus()
|
focus_owner.release_focus()
|
||||||
|
_schedule_intro_presentation()
|
||||||
|
|
||||||
|
|
||||||
func _start_entry_prompt_animation() -> void:
|
func _start_entry_prompt_animation() -> void:
|
||||||
|
|
@ -440,16 +524,240 @@ func _update_start_prompt_pivot() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _reveal_primary_menu() -> void:
|
func _reveal_primary_menu() -> void:
|
||||||
if not _awaiting_start_input:
|
if (
|
||||||
|
not _awaiting_start_input
|
||||||
|
or not _intro_geometry_ready
|
||||||
|
or _title_entry_transition_active
|
||||||
|
):
|
||||||
return
|
return
|
||||||
_awaiting_start_input = false
|
_awaiting_start_input = false
|
||||||
_stop_entry_prompt_animation()
|
_stop_entry_prompt_animation()
|
||||||
_start_prompt_center.hide()
|
_title_entry_generation += 1
|
||||||
_button_center.show()
|
_title_entry_transition_active = true
|
||||||
_feedback_label.show()
|
_set_title_bubbles_interactive(false)
|
||||||
|
var generation: int = _title_entry_generation
|
||||||
set_process(true)
|
set_process(true)
|
||||||
_navigation_focus_active = false
|
_navigation_focus_active = false
|
||||||
_release_title_focus()
|
_release_title_focus()
|
||||||
|
_title_entry_transition = create_tween()
|
||||||
|
_title_entry_transition.set_parallel(true)
|
||||||
|
_title_entry_transition.tween_property(
|
||||||
|
_start_prompt_center,
|
||||||
|
"modulate:a",
|
||||||
|
0.0,
|
||||||
|
INTRO_PROMPT_FADE_DURATION
|
||||||
|
).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_IN_OUT)
|
||||||
|
_title_entry_transition.tween_property(
|
||||||
|
_bubble_motion_root,
|
||||||
|
"position",
|
||||||
|
Vector2.ZERO,
|
||||||
|
INTRO_BUBBLE_TRAVEL_DURATION
|
||||||
|
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||||
|
_title_entry_transition.tween_property(
|
||||||
|
_branding_motion_root,
|
||||||
|
"position",
|
||||||
|
Vector2.ZERO,
|
||||||
|
INTRO_BRANDING_TRAVEL_DURATION
|
||||||
|
).set_delay(INTRO_BRANDING_START_DELAY).set_trans(
|
||||||
|
Tween.TRANS_QUAD
|
||||||
|
).set_ease(Tween.EASE_IN_OUT)
|
||||||
|
_title_entry_transition.finished.connect(
|
||||||
|
_finish_primary_menu_reveal.bind(generation),
|
||||||
|
CONNECT_ONE_SHOT
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_primary_menu_reveal(generation: int) -> void:
|
||||||
|
if (
|
||||||
|
generation != _title_entry_generation
|
||||||
|
or not _title_entry_transition_active
|
||||||
|
):
|
||||||
|
return
|
||||||
|
_title_entry_transition = null
|
||||||
|
_title_entry_transition_active = false
|
||||||
|
_start_prompt_center.hide()
|
||||||
|
_start_prompt_center.modulate.a = 1.0
|
||||||
|
_feedback_label.modulate.a = 0.0
|
||||||
|
_set_title_bubbles_interactive(true)
|
||||||
|
|
||||||
|
|
||||||
|
func _cancel_title_entry_transition() -> void:
|
||||||
|
_title_entry_generation += 1
|
||||||
|
if _title_entry_transition != null:
|
||||||
|
_title_entry_transition.kill()
|
||||||
|
_title_entry_transition = null
|
||||||
|
_title_entry_transition_active = false
|
||||||
|
if is_node_ready():
|
||||||
|
_start_prompt_center.modulate.a = 1.0
|
||||||
|
|
||||||
|
|
||||||
|
func _schedule_intro_presentation() -> void:
|
||||||
|
_intro_layout_generation += 1
|
||||||
|
_intro_geometry_ready = false
|
||||||
|
call_deferred(
|
||||||
|
"_prepare_intro_presentation",
|
||||||
|
_intro_layout_generation
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _prepare_intro_presentation(generation: int) -> void:
|
||||||
|
await get_tree().process_frame
|
||||||
|
await get_tree().process_frame
|
||||||
|
if (
|
||||||
|
generation != _intro_layout_generation
|
||||||
|
or not is_node_ready()
|
||||||
|
or not _awaiting_start_input
|
||||||
|
or _title_entry_transition_active
|
||||||
|
):
|
||||||
|
return
|
||||||
|
_branding_motion_root.size = _branding_slot.size
|
||||||
|
_bubble_motion_root.size = _bubble_layout_slot.size
|
||||||
|
var intro_tail_height: float = (
|
||||||
|
_title_spacer.get_combined_minimum_size().y
|
||||||
|
+ float(_main_content.get_theme_constant("separation"))
|
||||||
|
)
|
||||||
|
var branding_target_global := Vector2(
|
||||||
|
floorf(
|
||||||
|
_intro_branding_anchor.global_position.x
|
||||||
|
- _branding_motion_root.size.x * 0.5
|
||||||
|
),
|
||||||
|
floorf(
|
||||||
|
_intro_branding_anchor.global_position.y
|
||||||
|
- (_branding_motion_root.size.y + intro_tail_height) * 0.5
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_branding_intro_position = (
|
||||||
|
branding_target_global
|
||||||
|
- _branding_slot.global_position
|
||||||
|
)
|
||||||
|
var bubble_bounds: Rect2 = _get_title_bubble_global_bounds()
|
||||||
|
bubble_bounds.position -= _bubble_motion_root.position
|
||||||
|
var presentation_allowance: float = _get_bubble_offscreen_allowance()
|
||||||
|
_bubble_intro_position = Vector2(
|
||||||
|
0.0,
|
||||||
|
size.y
|
||||||
|
+ presentation_allowance
|
||||||
|
- bubble_bounds.position.y
|
||||||
|
)
|
||||||
|
_branding_motion_root.position = _branding_intro_position
|
||||||
|
_bubble_motion_root.position = _bubble_intro_position
|
||||||
|
_title_content_rest_position = _presentation_center.position
|
||||||
|
_title_bubble_rest_position = _bubble_field.position
|
||||||
|
_intro_geometry_ready = true
|
||||||
|
|
||||||
|
|
||||||
|
func _get_title_bubble_global_bounds() -> Rect2:
|
||||||
|
var bubbles: Array[BubbleButton] = _get_title_buttons()
|
||||||
|
var bounds: Rect2 = bubbles[0].get_global_rect()
|
||||||
|
for index: int in range(1, bubbles.size()):
|
||||||
|
bounds = bounds.merge(bubbles[index].get_global_rect())
|
||||||
|
return bounds
|
||||||
|
|
||||||
|
|
||||||
|
func _get_bubble_offscreen_allowance() -> float:
|
||||||
|
var maximum_vertical_amplitude: float = 0.0
|
||||||
|
var maximum_deformation_growth: float = 0.0
|
||||||
|
for bubble: BubbleButton in _get_title_buttons():
|
||||||
|
maximum_vertical_amplitude = maxf(
|
||||||
|
maximum_vertical_amplitude,
|
||||||
|
bubble.vertical_amplitude
|
||||||
|
)
|
||||||
|
var maximum_scale: float = (
|
||||||
|
1.0 + bubble.deformation_amplitude
|
||||||
|
) * _bubble_field.profile.hover_focus_scale
|
||||||
|
maximum_deformation_growth = maxf(
|
||||||
|
maximum_deformation_growth,
|
||||||
|
bubble.presented_size.y * (maximum_scale - 1.0) * 0.5
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
HOST_CLUSTER_SAFE_MARGIN
|
||||||
|
+ maximum_vertical_amplitude
|
||||||
|
+ maximum_deformation_growth
|
||||||
|
+ _bubble_field.profile.hover_focus_lift
|
||||||
|
+ _bubble_field.profile.maximum_separation
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_continue_stats_hover_changed(hovered: bool) -> void:
|
||||||
|
_continue_stats_hovered = hovered
|
||||||
|
_update_continue_stats_visibility()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_continue_stats_focus_changed(focused: bool) -> void:
|
||||||
|
_continue_stats_focused = focused
|
||||||
|
_update_continue_stats_visibility()
|
||||||
|
|
||||||
|
|
||||||
|
func _update_continue_stats_visibility() -> void:
|
||||||
|
if not is_node_ready():
|
||||||
|
return
|
||||||
|
var requested_visible: bool = (
|
||||||
|
_continue_stats_hovered
|
||||||
|
or (
|
||||||
|
_continue_stats_focused
|
||||||
|
and _navigation_focus_active
|
||||||
|
)
|
||||||
|
)
|
||||||
|
requested_visible = (
|
||||||
|
requested_visible
|
||||||
|
and not _continue_button.disabled
|
||||||
|
and _inspection != null
|
||||||
|
and _inspection.status == SaveInspectionType.Status.VALID_SUPPORTED
|
||||||
|
and not _awaiting_start_input
|
||||||
|
and not _title_entry_transition_active
|
||||||
|
and not _title_settings_transition_active
|
||||||
|
and not _settings_panel.visible
|
||||||
|
and not _confirmation_panel.visible
|
||||||
|
and not _action_in_progress
|
||||||
|
and _presentation_center.visible
|
||||||
|
)
|
||||||
|
if requested_visible:
|
||||||
|
_feedback_label.text = _get_continue_stats_text()
|
||||||
|
_fade_continue_stats_to(1.0 if requested_visible else 0.0)
|
||||||
|
|
||||||
|
|
||||||
|
func _hide_continue_stats_context() -> void:
|
||||||
|
_continue_stats_hovered = false
|
||||||
|
_continue_stats_focused = false
|
||||||
|
_fade_continue_stats_to(0.0)
|
||||||
|
|
||||||
|
|
||||||
|
func _fade_continue_stats_to(target_opacity: float) -> void:
|
||||||
|
if not is_node_ready():
|
||||||
|
return
|
||||||
|
_cancel_continue_stats_fade()
|
||||||
|
if is_equal_approx(_feedback_label.modulate.a, target_opacity):
|
||||||
|
_feedback_label.modulate.a = target_opacity
|
||||||
|
return
|
||||||
|
_continue_stats_fade = create_tween()
|
||||||
|
_continue_stats_fade.tween_property(
|
||||||
|
_feedback_label,
|
||||||
|
"modulate:a",
|
||||||
|
target_opacity,
|
||||||
|
INTRO_PROMPT_FADE_DURATION
|
||||||
|
).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_IN_OUT)
|
||||||
|
|
||||||
|
|
||||||
|
func _cancel_continue_stats_fade() -> void:
|
||||||
|
if _continue_stats_fade != null:
|
||||||
|
_continue_stats_fade.kill()
|
||||||
|
_continue_stats_fade = null
|
||||||
|
|
||||||
|
|
||||||
|
func _get_continue_stats_text() -> String:
|
||||||
|
if (
|
||||||
|
_inspection == null
|
||||||
|
or _inspection.status != SaveInspectionType.Status.VALID_SUPPORTED
|
||||||
|
):
|
||||||
|
return ""
|
||||||
|
return (
|
||||||
|
"%d fish • $%d • %d discovered"
|
||||||
|
% [
|
||||||
|
_inspection.catch_count,
|
||||||
|
_inspection.wallet_balance,
|
||||||
|
_inspection.discovered_species_count,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
func _on_continue_pressed() -> void:
|
func _on_continue_pressed() -> void:
|
||||||
|
|
@ -461,6 +769,7 @@ func _on_continue_pressed() -> void:
|
||||||
or not _inspection.can_continue()
|
or not _inspection.can_continue()
|
||||||
):
|
):
|
||||||
return
|
return
|
||||||
|
_hide_continue_stats_context()
|
||||||
_action_in_progress = true
|
_action_in_progress = true
|
||||||
if _save_manager.load_player_data():
|
if _save_manager.load_player_data():
|
||||||
_feedback_label.text = "save loaded."
|
_feedback_label.text = "save loaded."
|
||||||
|
|
@ -479,6 +788,7 @@ func _on_new_game_pressed() -> void:
|
||||||
or _inspection == null
|
or _inspection == null
|
||||||
):
|
):
|
||||||
return
|
return
|
||||||
|
_hide_continue_stats_context()
|
||||||
if _inspection.status == SaveInspectionType.Status.MISSING:
|
if _inspection.status == SaveInspectionType.Status.MISSING:
|
||||||
if _save_manager.initialize_new_game():
|
if _save_manager.initialize_new_game():
|
||||||
gameplay_requested.emit()
|
gameplay_requested.emit()
|
||||||
|
|
@ -508,6 +818,7 @@ func _on_delete_pressed() -> void:
|
||||||
or not _inspection.can_delete()
|
or not _inspection.can_delete()
|
||||||
):
|
):
|
||||||
return
|
return
|
||||||
|
_hide_continue_stats_context()
|
||||||
_open_confirmation(
|
_open_confirmation(
|
||||||
ConfirmationAction.DELETE_SAVE,
|
ConfirmationAction.DELETE_SAVE,
|
||||||
"delete your saved progression? this cannot be undone.",
|
"delete your saved progression? this cannot be undone.",
|
||||||
|
|
@ -540,6 +851,7 @@ func _open_confirmation(
|
||||||
message: String,
|
message: String,
|
||||||
confirm_text: String,
|
confirm_text: String,
|
||||||
) -> void:
|
) -> void:
|
||||||
|
_hide_continue_stats_context()
|
||||||
_modal_restore_navigation_focus = _navigation_focus_active
|
_modal_restore_navigation_focus = _navigation_focus_active
|
||||||
_confirmation_action = action
|
_confirmation_action = action
|
||||||
_confirmation_text.text = message
|
_confirmation_text.text = message
|
||||||
|
|
@ -563,11 +875,18 @@ func _close_confirmation() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _open_settings() -> void:
|
func _open_settings() -> void:
|
||||||
if _confirmation_panel.visible or _action_in_progress:
|
if (
|
||||||
|
_confirmation_panel.visible
|
||||||
|
or _action_in_progress
|
||||||
|
or _settings_panel.visible
|
||||||
|
or _title_settings_transition_active
|
||||||
|
):
|
||||||
return
|
return
|
||||||
|
_hide_continue_stats_context()
|
||||||
_modal_restore_navigation_focus = _navigation_focus_active
|
_modal_restore_navigation_focus = _navigation_focus_active
|
||||||
_feedback_label.text = ""
|
_feedback_visible_before_settings = _feedback_label.visible
|
||||||
_settings_panel.open_panel(_settings_manager)
|
_feedback_text_before_settings = _feedback_label.text
|
||||||
|
_begin_title_cluster_exit()
|
||||||
|
|
||||||
|
|
||||||
func _close_settings() -> void:
|
func _close_settings() -> void:
|
||||||
|
|
@ -575,12 +894,158 @@ func _close_settings() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _on_settings_applied() -> void:
|
func _on_settings_applied() -> void:
|
||||||
_feedback_label.text = "settings saved."
|
_begin_title_cluster_return("settings saved.")
|
||||||
_restore_settings_focus()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_settings_closed() -> void:
|
func _on_settings_closed() -> void:
|
||||||
|
_begin_title_cluster_return(_feedback_text_before_settings)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_settings_opened() -> void:
|
||||||
|
_title_settings_transition_active = false
|
||||||
|
|
||||||
|
|
||||||
|
func _begin_title_cluster_exit() -> void:
|
||||||
|
_title_settings_transition_generation += 1
|
||||||
|
_cancel_title_settings_tween()
|
||||||
|
_title_settings_transition_active = true
|
||||||
|
_title_content_rest_position = _presentation_center.position
|
||||||
|
_title_bubble_rest_position = _bubble_field.position
|
||||||
|
_set_title_bubbles_interactive(false)
|
||||||
|
_release_primary_menu_focus()
|
||||||
|
var generation: int = _title_settings_transition_generation
|
||||||
|
var exit_distance: float = (
|
||||||
|
_main_content.global_position.y
|
||||||
|
+ _main_content.size.y
|
||||||
|
+ HOST_CLUSTER_SAFE_MARGIN
|
||||||
|
)
|
||||||
|
_title_settings_transition = create_tween()
|
||||||
|
_title_settings_transition.tween_property(
|
||||||
|
_presentation_center,
|
||||||
|
"position:y",
|
||||||
|
_title_content_rest_position.y - exit_distance,
|
||||||
|
HOST_PRESENTATION_OUT_DURATION
|
||||||
|
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||||
|
_title_settings_transition.finished.connect(
|
||||||
|
_finish_title_cluster_exit.bind(generation),
|
||||||
|
CONNECT_ONE_SHOT
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_title_cluster_exit(generation: int) -> void:
|
||||||
|
if (
|
||||||
|
generation != _title_settings_transition_generation
|
||||||
|
or not _title_settings_transition_active
|
||||||
|
):
|
||||||
|
return
|
||||||
|
_title_settings_transition = null
|
||||||
|
_presentation_center.hide()
|
||||||
|
_presentation_center.position = _title_content_rest_position
|
||||||
|
_settings_panel.open_panel(
|
||||||
|
_settings_manager,
|
||||||
|
SettingsPanelType.PresentationMode.TITLE_EMBEDDED
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _begin_title_cluster_return(feedback_text: String) -> void:
|
||||||
|
_title_settings_transition_generation += 1
|
||||||
|
_cancel_title_settings_tween()
|
||||||
|
_title_settings_transition_active = true
|
||||||
|
if _feedback_label.text != feedback_text:
|
||||||
|
_feedback_label.text = feedback_text
|
||||||
|
_feedback_label.visible = _feedback_visible_before_settings
|
||||||
|
_hide_continue_stats_context()
|
||||||
|
_set_title_bubbles_interactive(false)
|
||||||
|
var generation: int = _title_settings_transition_generation
|
||||||
|
var rest_global_y: float = (
|
||||||
|
_presentation_center.global_position.y
|
||||||
|
- _presentation_center.position.y
|
||||||
|
+ _title_content_rest_position.y
|
||||||
|
)
|
||||||
|
_presentation_center.position = Vector2(
|
||||||
|
_title_content_rest_position.x,
|
||||||
|
_title_content_rest_position.y
|
||||||
|
+ size.y
|
||||||
|
+ HOST_CLUSTER_SAFE_MARGIN
|
||||||
|
- rest_global_y
|
||||||
|
)
|
||||||
|
_presentation_center.show()
|
||||||
|
_title_settings_transition = create_tween()
|
||||||
|
_title_settings_transition.tween_property(
|
||||||
|
_presentation_center,
|
||||||
|
"position",
|
||||||
|
_title_content_rest_position,
|
||||||
|
HOST_PRESENTATION_IN_DURATION
|
||||||
|
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||||
|
_title_settings_transition.finished.connect(
|
||||||
|
_finish_title_cluster_return.bind(generation),
|
||||||
|
CONNECT_ONE_SHOT
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_title_cluster_return(generation: int) -> void:
|
||||||
|
if (
|
||||||
|
generation != _title_settings_transition_generation
|
||||||
|
or not _title_settings_transition_active
|
||||||
|
):
|
||||||
|
return
|
||||||
|
_title_settings_transition = null
|
||||||
|
_title_settings_transition_active = false
|
||||||
|
_presentation_center.position = _title_content_rest_position
|
||||||
|
_bubble_field.position = _title_bubble_rest_position
|
||||||
|
_set_title_bubbles_interactive(true)
|
||||||
_restore_settings_focus()
|
_restore_settings_focus()
|
||||||
|
_update_continue_stats_visibility()
|
||||||
|
|
||||||
|
|
||||||
|
func _set_title_bubbles_interactive(interactive: bool) -> void:
|
||||||
|
for bubble: BubbleButton in _get_title_buttons():
|
||||||
|
bubble.focus_mode = (
|
||||||
|
Control.FOCUS_ALL if interactive else Control.FOCUS_NONE
|
||||||
|
)
|
||||||
|
bubble.mouse_filter = (
|
||||||
|
Control.MOUSE_FILTER_STOP
|
||||||
|
if interactive
|
||||||
|
else Control.MOUSE_FILTER_IGNORE
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _capture_title_bubble_rest_position() -> void:
|
||||||
|
if (
|
||||||
|
not is_node_ready()
|
||||||
|
or _title_settings_transition_active
|
||||||
|
or not _button_center.visible
|
||||||
|
):
|
||||||
|
return
|
||||||
|
_title_bubble_rest_position = _bubble_field.position
|
||||||
|
|
||||||
|
|
||||||
|
func _capture_title_content_rest_position() -> void:
|
||||||
|
if (
|
||||||
|
not is_node_ready()
|
||||||
|
or _title_settings_transition_active
|
||||||
|
or _title_entry_transition_active
|
||||||
|
or not _button_center.visible
|
||||||
|
):
|
||||||
|
return
|
||||||
|
_title_content_rest_position = _presentation_center.position
|
||||||
|
|
||||||
|
|
||||||
|
func _cancel_title_settings_transition() -> void:
|
||||||
|
_title_settings_transition_generation += 1
|
||||||
|
_cancel_title_settings_tween()
|
||||||
|
_title_settings_transition_active = false
|
||||||
|
if is_node_ready():
|
||||||
|
_presentation_center.position = _title_content_rest_position
|
||||||
|
_presentation_center.show()
|
||||||
|
_bubble_field.position = _title_bubble_rest_position
|
||||||
|
_set_title_bubbles_interactive(true)
|
||||||
|
|
||||||
|
|
||||||
|
func _cancel_title_settings_tween() -> void:
|
||||||
|
if _title_settings_transition != null:
|
||||||
|
_title_settings_transition.kill()
|
||||||
|
_title_settings_transition = null
|
||||||
|
|
||||||
|
|
||||||
func _restore_settings_focus() -> void:
|
func _restore_settings_focus() -> void:
|
||||||
|
|
@ -603,14 +1068,11 @@ func _refresh_save_inspection() -> void:
|
||||||
)
|
)
|
||||||
_feedback_label.text = _inspection.message
|
_feedback_label.text = _inspection.message
|
||||||
if _inspection.status == SaveInspectionType.Status.VALID_SUPPORTED:
|
if _inspection.status == SaveInspectionType.Status.VALID_SUPPORTED:
|
||||||
_feedback_label.text = (
|
_feedback_label.text = _get_continue_stats_text()
|
||||||
"%d fish • $%d • %d discovered"
|
if _continue_button.disabled:
|
||||||
% [
|
_hide_continue_stats_context()
|
||||||
_inspection.catch_count,
|
else:
|
||||||
_inspection.wallet_balance,
|
_update_continue_stats_visibility()
|
||||||
_inspection.discovered_species_count,
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func _focus_initial_button() -> void:
|
func _focus_initial_button() -> void:
|
||||||
|
|
@ -626,6 +1088,7 @@ func _focus_initial_button() -> void:
|
||||||
else:
|
else:
|
||||||
_new_game_button.grab_focus()
|
_new_game_button.grab_focus()
|
||||||
_navigation_focus_active = true
|
_navigation_focus_active = true
|
||||||
|
_update_continue_stats_visibility()
|
||||||
|
|
||||||
|
|
||||||
func _on_quit_pressed() -> void:
|
func _on_quit_pressed() -> void:
|
||||||
|
|
@ -634,6 +1097,7 @@ func _on_quit_pressed() -> void:
|
||||||
and not _confirmation_panel.visible
|
and not _confirmation_panel.visible
|
||||||
and not _settings_panel.visible
|
and not _settings_panel.visible
|
||||||
):
|
):
|
||||||
|
_hide_continue_stats_context()
|
||||||
quit_requested.emit()
|
quit_requested.emit()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -644,6 +1108,7 @@ func _on_title_visibility_changed() -> void:
|
||||||
set_process(true)
|
set_process(true)
|
||||||
_start_decorative_presentation()
|
_start_decorative_presentation()
|
||||||
else:
|
else:
|
||||||
|
_hide_continue_stats_context()
|
||||||
_stop_entry_prompt_animation()
|
_stop_entry_prompt_animation()
|
||||||
_navigation_focus_active = false
|
_navigation_focus_active = false
|
||||||
_modal_restore_navigation_focus = false
|
_modal_restore_navigation_focus = false
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,17 @@ text = "press any key to start"
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
vertical_alignment = 1
|
vertical_alignment = 1
|
||||||
|
|
||||||
|
[node name="IntroBrandingAnchor" type="Control" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 1
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
[node name="Center" type="CenterContainer" parent="."]
|
[node name="Center" type="CenterContainer" parent="."]
|
||||||
z_index = 10
|
z_index = 10
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
|
|
@ -115,7 +126,27 @@ layout_mode = 2
|
||||||
theme_override_constants/separation = 7
|
theme_override_constants/separation = 7
|
||||||
alignment = 1
|
alignment = 1
|
||||||
|
|
||||||
[node name="TitleLogo" type="TextureRect" parent="Center/MainContent"]
|
[node name="BrandingSlot" type="Control" parent="Center/MainContent"]
|
||||||
|
custom_minimum_size = Vector2(640, 215)
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="BrandingMotionRoot" type="Control" parent="Center/MainContent/BrandingSlot"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 0
|
||||||
|
offset_right = 640.0
|
||||||
|
offset_bottom = 215.0
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
|
[node name="BrandingContent" type="VBoxContainer" parent="Center/MainContent/BrandingSlot/BrandingMotionRoot"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
theme_override_constants/separation = 7
|
||||||
|
|
||||||
|
[node name="TitleLogo" type="TextureRect" parent="Center/MainContent/BrandingSlot/BrandingMotionRoot/BrandingContent"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
custom_minimum_size = Vector2(640, 190)
|
custom_minimum_size = Vector2(640, 190)
|
||||||
material = SubResource("ShaderMaterial_title_logo")
|
material = SubResource("ShaderMaterial_title_logo")
|
||||||
|
|
@ -126,7 +157,8 @@ texture = ExtResource("5_logo")
|
||||||
expand_mode = 1
|
expand_mode = 1
|
||||||
stretch_mode = 5
|
stretch_mode = 5
|
||||||
|
|
||||||
[node name="PlaytestLabel" type="Label" parent="Center/MainContent"]
|
[node name="PlaytestLabel" type="Label" parent="Center/MainContent/BrandingSlot/BrandingMotionRoot/BrandingContent"]
|
||||||
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
theme_override_colors/font_color = Color(0.682, 0.733, 0.761, 1)
|
theme_override_colors/font_color = Color(0.682, 0.733, 0.761, 1)
|
||||||
theme_override_font_sizes/font_size = 17
|
theme_override_font_sizes/font_size = 17
|
||||||
|
|
@ -142,14 +174,27 @@ unique_name_in_owner = true
|
||||||
visible = false
|
visible = false
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="BubbleField" type="Control" parent="Center/MainContent/ButtonCenter"]
|
[node name="BubbleLayoutSlot" type="Control" parent="Center/MainContent/ButtonCenter"]
|
||||||
unique_name_in_owner = true
|
|
||||||
custom_minimum_size = Vector2(396, 318)
|
custom_minimum_size = Vector2(396, 318)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="BubbleMotionRoot" type="Control" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 0
|
||||||
|
offset_right = 396.0
|
||||||
|
offset_bottom = 318.0
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
|
[node name="BubbleField" type="Control" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(396, 318)
|
||||||
|
layout_mode = 0
|
||||||
|
offset_right = 396.0
|
||||||
|
offset_bottom = 318.0
|
||||||
script = ExtResource("8_bubble_cluster")
|
script = ExtResource("8_bubble_cluster")
|
||||||
profile = ExtResource("9_bubble_profile")
|
profile = ExtResource("9_bubble_profile")
|
||||||
|
|
||||||
[node name="ContinueButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleField"]
|
[node name="ContinueButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
offset_left = 123.0
|
offset_left = 123.0
|
||||||
offset_top = 86.0
|
offset_top = 86.0
|
||||||
|
|
@ -169,7 +214,7 @@ motion_period = 5.8
|
||||||
deformation_amplitude = 0.01
|
deformation_amplitude = 0.01
|
||||||
deformation_period = 6.7
|
deformation_period = 6.7
|
||||||
|
|
||||||
[node name="NewGameButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleField"]
|
[node name="NewGameButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
offset_left = 42.0
|
offset_left = 42.0
|
||||||
offset_top = 4.0
|
offset_top = 4.0
|
||||||
|
|
@ -191,7 +236,7 @@ motion_phase = 1.2
|
||||||
deformation_amplitude = 0.018
|
deformation_amplitude = 0.018
|
||||||
deformation_period = 5.9
|
deformation_period = 5.9
|
||||||
|
|
||||||
[node name="NewGameLabel" type="Label" parent="Center/MainContent/ButtonCenter/BubbleField/NewGameButton"]
|
[node name="NewGameLabel" type="Label" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField/NewGameButton"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
|
|
@ -206,7 +251,7 @@ text = "new game"
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
vertical_alignment = 1
|
vertical_alignment = 1
|
||||||
|
|
||||||
[node name="SettingsButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleField"]
|
[node name="SettingsButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
offset_left = 264.0
|
offset_left = 264.0
|
||||||
offset_top = 17.0
|
offset_top = 17.0
|
||||||
|
|
@ -225,7 +270,7 @@ motion_period = 4.9
|
||||||
motion_phase = 2.5
|
motion_phase = 2.5
|
||||||
deformation_period = 6.3
|
deformation_period = 6.3
|
||||||
|
|
||||||
[node name="DeleteSaveButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleField"]
|
[node name="DeleteSaveButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
offset_left = -11.0
|
offset_left = -11.0
|
||||||
offset_top = 122.0
|
offset_top = 122.0
|
||||||
|
|
@ -246,7 +291,7 @@ motion_phase = 3.7
|
||||||
deformation_amplitude = 0.018
|
deformation_amplitude = 0.018
|
||||||
deformation_period = 5.4
|
deformation_period = 5.4
|
||||||
|
|
||||||
[node name="DeleteSaveLabel" type="Label" parent="Center/MainContent/ButtonCenter/BubbleField/DeleteSaveButton"]
|
[node name="DeleteSaveLabel" type="Label" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField/DeleteSaveButton"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
|
|
@ -261,7 +306,7 @@ text = "delete save"
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
vertical_alignment = 1
|
vertical_alignment = 1
|
||||||
|
|
||||||
[node name="QuitButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleField"]
|
[node name="QuitButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
offset_left = 275.0
|
offset_left = 275.0
|
||||||
offset_top = 217.0
|
offset_top = 217.0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue