Compare commits

..

No commits in common. "bcffe2013d46ffc1f09cd2244a61b9ad0fc138d7" and "22f7119b720c09a53133002420da5a6e650e08a0" have entirely different histories.

24 changed files with 324 additions and 1559 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 554 B

Before After
Before After

View file

@ -1,63 +0,0 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://cb4bcakhoprm8"
path="res://.godot/imported/netfishing_base_character.blend-65bf3bc5b77cc1a37fa3f81ebd808d37.scn"
[deps]
source_file="res://art/source/characters/base/netfishing_base_character.blend"
dest_files=["res://.godot/imported/netfishing_base_character.blend-65bf3bc5b77cc1a37fa3f81ebd808d37.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
mesh_library/use_node_names_as_mesh_names=false
array_mesh/deduplicate_surfaces=true
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
blender/nodes/visible=0
blender/nodes/active_collection_only=false
blender/nodes/punctual_lights=true
blender/nodes/cameras=true
blender/nodes/custom_properties=true
blender/nodes/modifiers=1
blender/meshes/vertex_colors=1
blender/meshes/uvs=true
blender/meshes/normals=true
blender/meshes/export_geometry_nodes_instances=false
blender/meshes/gpu_instances=false
blender/meshes/tangents=true
blender/meshes/skins=2
blender/meshes/export_bones_deforming_mesh_only=false
blender/materials/unpack_enabled=true
blender/materials/export_materials=1
blender/animation/limit_playback=true
blender/animation/always_sample=true
blender/animation/group_tracks=true
gltf/naming_version=2
gltf/texture_map_mode=1

View file

@ -1,250 +0,0 @@
class_name BubbleConfirmationPage
extends Control
signal confirmed
signal cancelled
enum InitialFocus {
CONFIRM,
CANCEL,
}
@export var cluster_path: NodePath = ^"BubbleCluster"
@export var message_path: NodePath = ^"BubbleCluster/MessageBubble"
@export var message_label_path: NodePath = (
^"BubbleCluster/MessageBubble/MessageLabel"
)
@export var confirm_path: NodePath = ^"BubbleCluster/ConfirmButton"
@export var confirm_label_path: NodePath = (
^"BubbleCluster/ConfirmButton/ConfirmLabel"
)
@export var cancel_path: NodePath = ^"BubbleCluster/CancelButton"
@export var cancel_label_path: NodePath = (
^"BubbleCluster/CancelButton/CancelLabel"
)
@export var maximum_layout_size: Vector2 = Vector2(720.0, 520.0)
@export var compact_maximum_layout_size: Vector2 = Vector2(544.0, 400.0)
@export var compact_width_threshold: float = 680.0
@export var compact_height_threshold: float = 500.0
@export_range(0.0, 128.0, 1.0) var transition_safe_margin: float = 24.0
var _cluster: BubbleCluster
var _message: BubbleButton
var _message_label: Label
var _confirm_button: BubbleButton
var _confirm_label: Label
var _cancel_button: BubbleButton
var _cancel_label: Label
var _bubbles: Array[BubbleButton] = []
var _initial_focus: InitialFocus = InitialFocus.CONFIRM
var _resting_cluster_position: Vector2 = Vector2.ZERO
var _transition: Tween
var _transition_generation: int = 0
var _is_transitioning: bool = false
func _ready() -> void:
_cluster = get_node(cluster_path) as BubbleCluster
_message = get_node(message_path) as BubbleButton
_message_label = get_node(message_label_path) as Label
_confirm_button = get_node(confirm_path) as BubbleButton
_confirm_label = get_node(confirm_label_path) as Label
_cancel_button = get_node(cancel_path) as BubbleButton
_cancel_label = get_node(cancel_label_path) as Label
_bubbles = [_message, _confirm_button, _cancel_button]
_cluster.configure(_bubbles)
_message.focus_mode = Control.FOCUS_NONE
_message.mouse_filter = Control.MOUSE_FILTER_IGNORE
_confirm_button.pressed.connect(confirmed.emit)
_cancel_button.pressed.connect(cancelled.emit)
_configure_focus()
resized.connect(_update_layout)
call_deferred("_update_layout")
hide_page()
func configure(
message_text: String,
confirm_text: String,
cancel_text: String = "cancel",
initial_focus: InitialFocus = InitialFocus.CONFIRM,
) -> void:
_message_label.text = message_text
_confirm_label.text = confirm_text
_cancel_label.text = cancel_text
_initial_focus = initial_focus
func transition_in(duration: float, completed: Callable) -> void:
_transition_generation += 1
_cancel_transition()
show()
_is_transitioning = true
_set_interactive(false)
set_process(true)
_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, completed),
CONNECT_ONE_SHOT
)
func transition_out(duration: float, completed: Callable) -> void:
if not visible or _is_transitioning:
return
_transition_generation += 1
_cancel_transition()
_is_transitioning = true
_set_interactive(false)
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 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 lock_interaction() -> void:
_set_interactive(false)
func is_transitioning() -> bool:
return _is_transitioning
func focus_initial() -> void:
var target: BubbleButton = (
_cancel_button
if _initial_focus == InitialFocus.CANCEL
else _confirm_button
)
if target.visible and target.focus_mode != Control.FOCUS_NONE:
target.grab_focus()
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 = (
compact_maximum_layout_size
if compact
else 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() -> void:
var confirm_to_cancel: NodePath = _confirm_button.get_path_to(
_cancel_button
)
var cancel_to_confirm: NodePath = _cancel_button.get_path_to(
_confirm_button
)
_confirm_button.focus_neighbor_left = confirm_to_cancel
_confirm_button.focus_neighbor_right = confirm_to_cancel
_confirm_button.focus_neighbor_top = confirm_to_cancel
_confirm_button.focus_neighbor_bottom = confirm_to_cancel
_cancel_button.focus_neighbor_left = cancel_to_confirm
_cancel_button.focus_neighbor_right = cancel_to_confirm
_cancel_button.focus_neighbor_top = cancel_to_confirm
_cancel_button.focus_neighbor_bottom = cancel_to_confirm
func _set_interactive(interactive: bool) -> void:
mouse_filter = (
Control.MOUSE_FILTER_PASS
if interactive
else Control.MOUSE_FILTER_IGNORE
)
for bubble: BubbleButton in [_confirm_button, _cancel_button]:
if not interactive and bubble.has_focus():
bubble.release_focus()
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_in(
generation: int,
completed: Callable,
) -> void:
if generation != _transition_generation or not visible:
return
_transition = null
_is_transitioning = false
_cluster.position = _resting_cluster_position
_set_interactive(true)
focus_initial()
completed.call()
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
set_process(false)
completed.call()
func _cancel_transition() -> void:
if _transition != null:
_transition.kill()
_transition = null

View file

@ -1 +0,0 @@
uid://c5q6yypya7fr1

View file

@ -1,139 +0,0 @@
[gd_scene load_steps=7 format=3]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_confirmation_page.gd" id="1_page"]
[ext_resource type="PackedScene" path="res://ui/components/bubble_menu/bubble_button.tscn" id="2_bubble"]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_cluster.gd" id="3_cluster"]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_menu_profile.gd" id="4_profile_script"]
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="5_profile"]
[sub_resource type="Resource" id="BubbleMenuProfile_confirmation_action"]
script = ExtResource("4_profile_script")
normal_border_width = 3
emphasized_border_width = 4
[sub_resource type="Resource" id="BubbleMenuProfile_confirmation_message"]
script = ExtResource("4_profile_script")
corner_radius = 256
[node name="BubbleConfirmationPage" type="Control"]
visible = false
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
script = ExtResource("1_page")
[node name="BubbleCluster" type="Control" parent="."]
layout_mode = 0
offset_right = 720.0
offset_bottom = 520.0
script = ExtResource("3_cluster")
profile = ExtResource("5_profile")
desktop_reference_size = Vector2(720, 520)
compact_reference_size = Vector2(544, 400)
[node name="MessageBubble" parent="BubbleCluster" instance=ExtResource("2_bubble")]
custom_minimum_size = Vector2(0, 0)
profile = SubResource("BubbleMenuProfile_confirmation_message")
neutral_size = Vector2(356, 350)
desktop_anchor = Vector2(360, 214)
compact_anchor = Vector2(360, 196)
compact_minimum_size = Vector2(292, 288)
label_control_path = NodePath("MessageLabel")
minimum_font_size = 15
maximum_font_size = 22
horizontal_amplitude = 0.8
vertical_amplitude = 2.2
motion_period = 6.8
motion_phase = 0.45
deformation_amplitude = 0.008
deformation_period = 7.4
[node name="MessageLabel" type="Label" parent="BubbleCluster/MessageBubble"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 38.0
offset_top = 36.0
offset_right = -38.0
offset_bottom = -36.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
theme_override_colors/font_color = Color(0.035, 0.145, 0.22, 1)
theme_override_constants/line_spacing = -2
text = "confirm?"
horizontal_alignment = 1
vertical_alignment = 1
autowrap_mode = 2
[node name="ConfirmButton" parent="BubbleCluster" instance=ExtResource("2_bubble")]
custom_minimum_size = Vector2(0, 0)
profile = SubResource("BubbleMenuProfile_confirmation_action")
neutral_size = Vector2(142, 136)
desktop_anchor = Vector2(258, 432)
compact_anchor = Vector2(210, 432)
compact_minimum_size = Vector2(108, 104)
label_control_path = NodePath("ConfirmLabel")
minimum_font_size = 14
maximum_font_size = 22
horizontal_amplitude = 1.7
vertical_amplitude = 4.2
motion_period = 5.6
motion_phase = 2.15
deformation_amplitude = 0.014
deformation_period = 5.9
[node name="ConfirmLabel" type="Label" parent="BubbleCluster/ConfirmButton"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 14.0
offset_top = 14.0
offset_right = -14.0
offset_bottom = -14.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
text = "confirm"
horizontal_alignment = 1
vertical_alignment = 1
autowrap_mode = 2
[node name="CancelButton" parent="BubbleCluster" instance=ExtResource("2_bubble")]
custom_minimum_size = Vector2(0, 0)
neutral_size = Vector2(124, 120)
desktop_anchor = Vector2(462, 426)
compact_anchor = Vector2(510, 426)
compact_minimum_size = Vector2(98, 94)
label_control_path = NodePath("CancelLabel")
minimum_font_size = 14
maximum_font_size = 20
horizontal_amplitude = 1.5
vertical_amplitude = 3.8
motion_period = 5.1
motion_phase = 4.0
deformation_amplitude = 0.015
deformation_period = 5.4
[node name="CancelLabel" type="Label" parent="BubbleCluster/CancelButton"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 12.0
offset_top = 12.0
offset_right = -12.0
offset_bottom = -12.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
text = "cancel"
horizontal_alignment = 1
vertical_alignment = 1
autowrap_mode = 2

View file

@ -1,49 +0,0 @@
class_name BubbleContentShell
extends PanelContainer
@export var profile: BubbleMenuProfile
@export_range(0.0, 96.0, 1.0) var content_margin: float = 24.0
@export_range(0, 512, 1) var corner_radius: int = 72
@export_range(0, 12, 1) var border_width: int = 3
var _background_visible: bool = true
func _ready() -> void:
apply_profile()
func apply_profile() -> void:
if profile == null:
return
var style := StyleBoxFlat.new()
style.bg_color = profile.normal_fill
style.border_color = profile.normal_border
style.border_width_left = border_width
style.border_width_top = border_width
style.border_width_right = border_width
style.border_width_bottom = border_width
style.corner_radius_top_left = corner_radius
style.corner_radius_top_right = corner_radius
style.corner_radius_bottom_right = corner_radius
style.corner_radius_bottom_left = corner_radius
style.content_margin_left = content_margin
style.content_margin_top = content_margin
style.content_margin_right = content_margin
style.content_margin_bottom = content_margin
add_theme_stylebox_override("panel", style)
func set_background_visible(background_visible: bool) -> void:
_background_visible = background_visible
if not is_node_ready() or profile == null:
return
if _background_visible:
apply_profile()
return
var transparent_style := StyleBoxEmpty.new()
transparent_style.content_margin_left = content_margin
transparent_style.content_margin_top = content_margin
transparent_style.content_margin_right = content_margin
transparent_style.content_margin_bottom = content_margin
add_theme_stylebox_override("panel", transparent_style)

View file

@ -1 +0,0 @@
uid://bsplayercontentshell

View file

@ -1,8 +0,0 @@
[gd_scene load_steps=3 format=3]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_content_shell.gd" id="1_shell"]
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="2_profile"]
[node name="BubbleContentShell" type="PanelContainer"]
script = ExtResource("1_shell")
profile = ExtResource("2_profile")

View file

@ -1,21 +0,0 @@
class_name BubbleInformationPanel
extends PanelContainer
@export var profile: BubbleMenuProfile
@export_range(0.0, 96.0, 1.0) var content_margin: float = 20.0
@export_range(0, 512, 1) var corner_radius: int = 96
func _ready() -> void:
if profile == null:
return
var style: StyleBoxFlat = profile.make_normal_style()
style.corner_radius_top_left = corner_radius
style.corner_radius_top_right = corner_radius
style.corner_radius_bottom_left = corner_radius
style.corner_radius_bottom_right = corner_radius
style.content_margin_left = content_margin
style.content_margin_top = content_margin
style.content_margin_right = content_margin
style.content_margin_bottom = content_margin
add_theme_stylebox_override("panel", style)

View file

@ -1 +0,0 @@
uid://bubbleinformationpanel

View file

@ -1,9 +0,0 @@
[gd_scene load_steps=3 format=3]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_information_panel.gd" id="1_panel"]
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="2_profile"]
[node name="BubbleInformationPanel" type="PanelContainer"]
mouse_filter = 1
script = ExtResource("1_panel")
profile = ExtResource("2_profile")

View file

@ -1,125 +0,0 @@
class_name BubbleInventoryCell
extends Button
@export var profile: BubbleMenuProfile
@onready var _icon: TextureRect = %Icon
@onready var _primary_label: Label = %PrimaryLabel
@onready var _secondary_label: Label = %SecondaryLabel
@onready var _favorite_marker: Label = %FavoriteMarker
@onready var _selected_marker: Label = %SelectedMarker
var _selected: bool = false
var _focused_item: bool = false
var _compact: bool = false
var _icon_texture: Texture2D
var _primary_text: String = ""
var _secondary_text: String = ""
var _favorite: bool = false
func _ready() -> void:
focus_entered.connect(_refresh_style)
focus_exited.connect(_refresh_style)
_apply_compact_layout()
_apply_content()
_refresh_style()
func configure(
icon_texture: Texture2D,
primary_text: String,
secondary_text: String,
) -> void:
_icon_texture = icon_texture
_primary_text = primary_text
_secondary_text = secondary_text
if is_node_ready():
_apply_content()
func set_item_state(
selected: bool,
focused_item: bool,
favorite: bool,
) -> void:
_selected = selected
_focused_item = focused_item
_favorite = favorite
if is_node_ready():
_apply_content()
_refresh_style()
func set_compact(compact: bool) -> void:
_compact = compact
if not is_node_ready():
custom_minimum_size = (
Vector2(104.0, 98.0)
if compact
else Vector2(144.0, 136.0)
)
return
_apply_compact_layout()
func _apply_compact_layout() -> void:
custom_minimum_size = (
Vector2(104.0, 98.0)
if _compact
else Vector2(144.0, 136.0)
)
_icon.custom_minimum_size = (
Vector2(72.0, 44.0)
if _compact
else Vector2(104.0, 68.0)
)
_primary_label.add_theme_font_size_override(
"font_size",
15 if _compact else 18,
)
_secondary_label.add_theme_font_size_override(
"font_size",
13 if _compact else 15,
)
func _apply_content() -> void:
_icon.texture = _icon_texture
_primary_label.text = _primary_text
_secondary_label.text = _secondary_text
_selected_marker.visible = _selected
_favorite_marker.visible = _favorite
func _has_point(point: Vector2) -> bool:
var radius: Vector2 = size * 0.5
if radius.x <= 0.0 or radius.y <= 0.0:
return false
var normalized: Vector2 = (point - radius) / radius
return normalized.length_squared() <= 1.0
func _refresh_style() -> void:
if profile == null:
return
var normal_style: StyleBoxFlat = profile.make_normal_style()
var border_width: int = (
profile.emphasized_border_width
if _selected or _focused_item or has_focus()
else profile.normal_border_width
)
normal_style.border_width_left = border_width
normal_style.border_width_top = border_width
normal_style.border_width_right = border_width
normal_style.border_width_bottom = border_width
if _selected:
normal_style.bg_color = profile.pressed_fill
if _focused_item:
normal_style.border_color = profile.text_color
add_theme_stylebox_override("normal", normal_style)
add_theme_stylebox_override("hover", profile.make_hover_style())
add_theme_stylebox_override("focus", normal_style)
add_theme_stylebox_override("pressed", profile.make_pressed_style())
add_theme_stylebox_override("disabled", profile.make_disabled_style())
add_theme_color_override("font_color", profile.text_color)

View file

@ -1 +0,0 @@
uid://bubbleinventorycell

View file

@ -1,78 +0,0 @@
[gd_scene load_steps=3 format=3]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_inventory_cell.gd" id="1_cell"]
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="2_profile"]
[node name="BubbleInventoryCell" type="Button"]
custom_minimum_size = Vector2(144, 136)
toggle_mode = true
script = ExtResource("1_cell")
profile = ExtResource("2_profile")
[node name="Content" type="VBoxContainer" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 17.0
offset_top = 14.0
offset_right = -17.0
offset_bottom = -14.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
theme_override_constants/separation = 2
[node name="Icon" type="TextureRect" parent="Content"]
unique_name_in_owner = true
custom_minimum_size = Vector2(104, 68)
layout_mode = 2
size_flags_vertical = 3
mouse_filter = 2
texture_filter = 1
expand_mode = 1
stretch_mode = 5
[node name="PrimaryLabel" type="Label" parent="Content"]
unique_name_in_owner = true
layout_mode = 2
mouse_filter = 2
theme_override_font_sizes/font_size = 18
horizontal_alignment = 1
text_overrun_behavior = 3
[node name="SecondaryLabel" type="Label" parent="Content"]
unique_name_in_owner = true
layout_mode = 2
mouse_filter = 2
theme_override_colors/font_color = Color(0.16, 0.25, 0.29, 0.78)
theme_override_font_sizes/font_size = 15
horizontal_alignment = 1
[node name="FavoriteMarker" type="Label" parent="."]
unique_name_in_owner = true
visible = false
layout_mode = 0
offset_left = 102.0
offset_top = 12.0
offset_right = 132.0
offset_bottom = 42.0
mouse_filter = 2
theme_override_colors/font_color = Color(1, 0.82, 0.4, 1)
theme_override_font_sizes/font_size = 23
text = "★"
horizontal_alignment = 1
[node name="SelectedMarker" type="Label" parent="."]
unique_name_in_owner = true
visible = false
layout_mode = 0
offset_left = 14.0
offset_top = 10.0
offset_right = 42.0
offset_bottom = 38.0
mouse_filter = 2
theme_override_colors/font_color = Color(0.035, 0.145, 0.22, 1)
theme_override_font_sizes/font_size = 22
text = "✓"
horizontal_alignment = 1

View file

@ -1,18 +0,0 @@
class_name BubbleStatusBubble
extends PanelContainer
@export var profile: BubbleMenuProfile
@onready var _heading: Label = %Heading
@onready var _value: Label = %Value
func _ready() -> void:
mouse_filter = Control.MOUSE_FILTER_IGNORE
if profile != null:
add_theme_stylebox_override("panel", profile.make_normal_style())
func set_content(heading: String, value: String) -> void:
_heading.text = heading
_value.text = value

View file

@ -1 +0,0 @@
uid://bubblestatusbubble

View file

@ -1,32 +0,0 @@
[gd_scene load_steps=3 format=3]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_status_bubble.gd" id="1_status"]
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="2_profile"]
[node name="BubbleStatusBubble" type="PanelContainer"]
custom_minimum_size = Vector2(128, 88)
mouse_filter = 2
script = ExtResource("1_status")
profile = ExtResource("2_profile")
[node name="Labels" type="VBoxContainer" parent="."]
layout_mode = 2
mouse_filter = 2
theme_override_constants/separation = 0
alignment = 1
[node name="Heading" type="Label" parent="Labels"]
unique_name_in_owner = true
layout_mode = 2
mouse_filter = 2
theme_override_font_sizes/font_size = 15
text = "status"
horizontal_alignment = 1
[node name="Value" type="Label" parent="Labels"]
unique_name_in_owner = true
layout_mode = 2
mouse_filter = 2
theme_override_font_sizes/font_size = 21
text = "0"
horizontal_alignment = 1

View file

@ -15,9 +15,6 @@ const SettingsManagerType = preload(
"res://settings/player_settings_manager.gd" "res://settings/player_settings_manager.gd"
) )
const SettingsPanelType = preload("res://ui/settings_panel.gd") const SettingsPanelType = preload("res://ui/settings_panel.gd")
const BubbleConfirmationPageType = preload(
"res://ui/components/bubble_menu/bubble_confirmation_page.gd"
)
const FishingSpotType = preload("res://fishing/fishing_spot.gd") const FishingSpotType = preload("res://fishing/fishing_spot.gd")
signal return_to_title_requested signal return_to_title_requested
@ -49,9 +46,11 @@ enum CloseReason {
@onready var _transition_flurry: BubbleTransitionFlurry = ( @onready var _transition_flurry: BubbleTransitionFlurry = (
%TransitionBubbleLayer %TransitionBubbleLayer
) )
@onready var _confirmation_page: BubbleConfirmationPageType = ( @onready var _confirmation_panel: PanelContainer = %ConfirmationPanel
%ConfirmationPage @onready var _confirmation_title: Label = %ConfirmationTitle
) @onready var _confirmation_text: Label = %ConfirmationText
@onready var _confirm_button: Button = %ConfirmButton
@onready var _cancel_button: Button = %CancelConfirmButton
@onready var _feedback: Label = %FeedbackLabel @onready var _feedback: Label = %FeedbackLabel
@onready var _save_button: BubbleButton = %SaveButton @onready var _save_button: BubbleButton = %SaveButton
@ -71,6 +70,9 @@ var _root_transition_generation: int = 0
var _closing_menu: bool = false var _closing_menu: bool = false
var _backdrop_fade: Tween var _backdrop_fade: Tween
var _backdrop_fade_generation: int = 0 var _backdrop_fade_generation: int = 0
var _confirmation_fade: Tween
var _confirmation_fade_generation: int = 0
var _confirmation_fade_active: bool = false
func _ready() -> void: func _ready() -> void:
@ -80,15 +82,16 @@ func _ready() -> void:
%ReturnToTitleButton.pressed.connect(_confirm_return_to_title) %ReturnToTitleButton.pressed.connect(_confirm_return_to_title)
%ResetProgressButton.pressed.connect(_confirm_reset_progress) %ResetProgressButton.pressed.connect(_confirm_reset_progress)
%QuitButton.pressed.connect(_request_quit) %QuitButton.pressed.connect(_request_quit)
_confirmation_page.confirmed.connect(_accept_confirmation) _confirm_button.pressed.connect(_accept_confirmation)
_confirmation_page.cancelled.connect(_close_confirmation) _cancel_button.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.navigation_transition_started.connect( _settings_panel.navigation_transition_started.connect(
_emit_transition_flurry _emit_transition_flurry
) )
_dim_background.color.a = 0.0 _dim_background.color.a = 0.0
_confirmation_page.hide_page() _confirmation_panel.modulate.a = 0.0
_set_confirmation_interactive(false)
resized.connect(_update_responsive_pause_stage) resized.connect(_update_responsive_pause_stage)
call_deferred("_update_responsive_pause_stage") call_deferred("_update_responsive_pause_stage")
@ -121,7 +124,7 @@ func open_menu() -> void:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
_feedback.text = "" _feedback.text = ""
_settings_panel.hide() _settings_panel.hide()
_confirmation_page.hide_page() _confirmation_panel.hide()
_confirmation_action = ConfirmationAction.NONE _confirmation_action = ConfirmationAction.NONE
_action_in_progress = false _action_in_progress = false
_root_page.hide_page() _root_page.hide_page()
@ -165,9 +168,9 @@ func close_menu(
func handle_escape() -> bool: func handle_escape() -> bool:
if not visible: if not visible:
return false return false
if _root_transition_active or _confirmation_page.is_transitioning(): if _root_transition_active or _confirmation_fade_active:
return true return true
if _confirmation_page.visible: if _confirmation_panel.visible:
_close_confirmation() _close_confirmation()
elif _settings_panel.visible: elif _settings_panel.visible:
_settings_panel.handle_back() _settings_panel.handle_back()
@ -278,57 +281,53 @@ func _open_confirmation(
if _action_in_progress or _root_transition_active: if _action_in_progress or _root_transition_active:
return return
_confirmation_action = action _confirmation_action = action
_confirmation_page.configure( _confirmation_title.text = title
"%s\n\n%s" % [title, message], _confirmation_text.text = message
confirm_text, _confirm_button.text = confirm_text
"cancel", _confirm_button.theme_type_variation = (
( &"DangerButton" if dangerous else StringName()
BubbleConfirmationPageType.InitialFocus.CANCEL
if dangerous
else BubbleConfirmationPageType.InitialFocus.CONFIRM
) )
) _begin_root_exit(_show_confirmation.bind(dangerous))
_begin_root_exit(_show_confirmation)
func _show_confirmation() -> void: func _show_confirmation(dangerous: bool) -> void:
_confirmation_page.transition_in( _fade_confirmation(
PAGE_INCOMING_DURATION, true,
_finish_confirmation_open _finish_confirmation_open.bind(dangerous)
) )
func _finish_confirmation_open() -> void: func _finish_confirmation_open(dangerous: bool) -> void:
pass _set_confirmation_interactive(true)
if dangerous:
_cancel_button.grab_focus()
else:
_confirm_button.grab_focus()
func _close_confirmation() -> void: func _close_confirmation() -> void:
if _root_transition_active or _confirmation_page.is_transitioning(): if _root_transition_active or _confirmation_fade_active:
return return
_confirmation_action = ConfirmationAction.NONE _confirmation_action = ConfirmationAction.NONE
_emit_transition_flurry() _fade_confirmation(false, _finish_confirmation_cancel)
_confirmation_page.transition_out(
PAGE_OUTGOING_DURATION,
_finish_confirmation_cancel
)
func _finish_confirmation_cancel() -> void: func _finish_confirmation_cancel() -> void:
_begin_root_entry(true) _begin_root_entry(false)
func _accept_confirmation() -> void: func _accept_confirmation() -> void:
if ( if (
_action_in_progress _action_in_progress
or _root_transition_active or _root_transition_active
or _confirmation_page.is_transitioning() or _confirmation_fade_active
): ):
return return
var action: ConfirmationAction = _confirmation_action var action: ConfirmationAction = _confirmation_action
_confirmation_action = ConfirmationAction.NONE _confirmation_action = ConfirmationAction.NONE
_action_in_progress = true _action_in_progress = true
_confirmation_page.transition_out( _fade_confirmation(
VISIBILITY_FADE_DURATION, false,
_finish_confirmation_accept.bind(action) _finish_confirmation_accept.bind(action)
) )
@ -418,11 +417,14 @@ func _finish_close(reason: CloseReason, restore_controls: bool) -> void:
_root_transition_generation += 1 _root_transition_generation += 1
_root_transition_active = false _root_transition_active = false
_cancel_backdrop_fade() _cancel_backdrop_fade()
_cancel_confirmation_fade()
_dim_background.color.a = 0.0 _dim_background.color.a = 0.0
_dim_background.hide() _dim_background.hide()
_confirmation_panel.modulate.a = 0.0
_set_confirmation_interactive(false)
_settings_panel.hide() _settings_panel.hide()
_root_page.hide_page() _root_page.hide_page()
_confirmation_page.hide_page() _confirmation_panel.hide()
_confirmation_action = ConfirmationAction.NONE _confirmation_action = ConfirmationAction.NONE
_action_in_progress = false _action_in_progress = false
_transition_flurry.clear_flurries() _transition_flurry.clear_flurries()
@ -481,6 +483,83 @@ func _cancel_backdrop_fade() -> void:
_backdrop_fade = null _backdrop_fade = null
func _fade_confirmation(
fade_in: bool,
completed: Callable,
) -> void:
_confirmation_fade_generation += 1
_cancel_confirmation_fade()
_confirmation_fade_active = true
_set_confirmation_interactive(false)
_confirmation_panel.show()
var target_alpha: float = 1.0 if fade_in else 0.0
if is_equal_approx(_confirmation_panel.modulate.a, target_alpha):
_finish_confirmation_fade(
_confirmation_fade_generation,
fade_in,
completed
)
return
var generation: int = _confirmation_fade_generation
_confirmation_fade = create_tween()
_confirmation_fade.tween_property(
_confirmation_panel,
"modulate:a",
target_alpha,
VISIBILITY_FADE_DURATION
).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_IN_OUT)
_confirmation_fade.finished.connect(
_finish_confirmation_fade.bind(
generation,
fade_in,
completed
),
CONNECT_ONE_SHOT
)
func _finish_confirmation_fade(
generation: int,
faded_in: bool,
completed: Callable,
) -> void:
if generation != _confirmation_fade_generation or not visible:
return
_confirmation_fade = null
_confirmation_fade_active = false
_confirmation_panel.modulate.a = 1.0 if faded_in else 0.0
if not faded_in:
_confirmation_panel.hide()
completed.call()
func _cancel_confirmation_fade() -> void:
_confirmation_fade_generation += 1
_confirmation_fade_active = false
if _confirmation_fade != null:
_confirmation_fade.kill()
_confirmation_fade = null
func _set_confirmation_interactive(interactive: bool) -> void:
_confirmation_panel.mouse_filter = (
Control.MOUSE_FILTER_STOP
if interactive
else Control.MOUSE_FILTER_IGNORE
)
for button: Button in [_confirm_button, _cancel_button]:
if not interactive and button.has_focus():
button.release_focus()
button.focus_mode = (
Control.FOCUS_ALL if interactive else Control.FOCUS_NONE
)
button.mouse_filter = (
Control.MOUSE_FILTER_STOP
if interactive
else Control.MOUSE_FILTER_IGNORE
)
func _update_responsive_pause_stage() -> void: func _update_responsive_pause_stage() -> void:
if not is_node_ready(): if not is_node_ready():
return return

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=10 format=3] [gd_scene load_steps=9 format=3]
[ext_resource type="Script" path="res://ui/pause_menu.gd" id="1_script"] [ext_resource type="Script" path="res://ui/pause_menu.gd" id="1_script"]
[ext_resource type="PackedScene" path="res://ui/settings_panel.tscn" id="2_settings"] [ext_resource type="PackedScene" path="res://ui/settings_panel.tscn" id="2_settings"]
@ -8,7 +8,6 @@
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_cluster.gd" id="6_cluster"] [ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_cluster.gd" id="6_cluster"]
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="7_profile"] [ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="7_profile"]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_transition_flurry.gd" id="8_flurry"] [ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_transition_flurry.gd" id="8_flurry"]
[ext_resource type="PackedScene" path="res://ui/components/bubble_menu/bubble_confirmation_page.tscn" id="9_confirmation"]
[node name="PauseMenu" type="Control"] [node name="PauseMenu" type="Control"]
unique_name_in_owner = true unique_name_in_owner = true
@ -201,11 +200,61 @@ mouse_filter = 2
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
[node name="ConfirmationPage" parent="ResponsivePauseStage/PausePresentationScaleRoot" instance=ExtResource("9_confirmation")] [node name="ConfirmationCenter" type="CenterContainer" parent="."]
unique_name_in_owner = true z_index = 3
layout_mode = 1 layout_mode = 1
anchors_preset = 15 anchors_preset = 15
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
mouse_filter = 2
[node name="ConfirmationPanel" type="PanelContainer" parent="ConfirmationCenter"]
unique_name_in_owner = true
visible = false
custom_minimum_size = Vector2(700, 0)
layout_mode = 2
[node name="Margin" type="MarginContainer" parent="ConfirmationCenter/ConfirmationPanel"]
layout_mode = 2
theme_override_constants/margin_left = 28
theme_override_constants/margin_top = 24
theme_override_constants/margin_right = 28
theme_override_constants/margin_bottom = 24
[node name="Content" type="VBoxContainer" parent="ConfirmationCenter/ConfirmationPanel/Margin"]
layout_mode = 2
theme_override_constants/separation = 15
[node name="ConfirmationTitle" type="Label" parent="ConfirmationCenter/ConfirmationPanel/Margin/Content"]
unique_name_in_owner = true
layout_mode = 2
theme_override_colors/font_color = Color(0.937, 0.357, 0.384, 1)
theme_override_font_sizes/font_size = 36
text = "confirm"
horizontal_alignment = 1
[node name="ConfirmationText" type="Label" parent="ConfirmationCenter/ConfirmationPanel/Margin/Content"]
unique_name_in_owner = true
layout_mode = 2
text = "are you sure?"
horizontal_alignment = 1
autowrap_mode = 2
[node name="Buttons" type="HBoxContainer" parent="ConfirmationCenter/ConfirmationPanel/Margin/Content"]
layout_mode = 2
theme_override_constants/separation = 12
alignment = 1
[node name="ConfirmButton" type="Button" parent="ConfirmationCenter/ConfirmationPanel/Margin/Content/Buttons"]
unique_name_in_owner = true
custom_minimum_size = Vector2(240, 64)
layout_mode = 2
text = "confirm"
[node name="CancelConfirmButton" type="Button" parent="ConfirmationCenter/ConfirmationPanel/Margin/Content/Buttons"]
unique_name_in_owner = true
custom_minimum_size = Vector2(180, 64)
layout_mode = 2
text = "cancel"

View file

@ -25,30 +25,6 @@ const PlayerCoolerCapacityType = preload(
const FishBatchSelectionType = preload( const FishBatchSelectionType = preload(
"res://ui/fish_batch_selection.gd" "res://ui/fish_batch_selection.gd"
) )
const BubbleButtonType = preload(
"res://ui/components/bubble_menu/bubble_button.gd"
)
const BubbleClusterType = preload(
"res://ui/components/bubble_menu/bubble_cluster.gd"
)
const BubbleContentShellType = preload(
"res://ui/components/bubble_menu/bubble_content_shell.gd"
)
const BubbleInventoryCellType = preload(
"res://ui/components/bubble_menu/bubble_inventory_cell.gd"
)
const BubbleInventoryCellScene = preload(
"res://ui/components/bubble_menu/bubble_inventory_cell.tscn"
)
const BubbleStatusBubbleType = preload(
"res://ui/components/bubble_menu/bubble_status_bubble.gd"
)
const MENU_ENTER_DURATION: float = 0.58
const MENU_EXIT_DURATION: float = 0.52
const PAGE_OUT_DURATION: float = 0.34
const PAGE_IN_DURATION: float = 0.42
const TRANSITION_SAFE_MARGIN: float = 28.0
signal menu_visibility_changed(is_open: bool) signal menu_visibility_changed(is_open: bool)
@ -73,32 +49,16 @@ enum CloseReason {
TEARDOWN, TEARDOWN,
} }
@onready var _navigation_cluster: BubbleClusterType = %NavigationCluster @onready var _inventory_tab: Button = %InventoryTab
@onready var _inventory_tab: BubbleButtonType = %InventoryTab @onready var _bag_tab: Button = %BagTab
@onready var _bag_tab: BubbleButtonType = %BagTab @onready var _logbook_tab: Button = %LogbookTab
@onready var _logbook_tab: BubbleButtonType = %LogbookTab @onready var _close_button: Button = %CloseButton
@onready var _close_button: BubbleButtonType = %CloseButton
@onready var _content_shell: BubbleContentShellType = %MenuPanel
@onready var _content_stage: Control = %Content
@onready var _cooler_scroll: ScrollContainer = %CoolerScroll
@onready var _cooler_host: VBoxContainer = %CoolerHost
@onready var _wallet_balance: Label = %WalletBalance @onready var _wallet_balance: Label = %WalletBalance
@onready var _header: Control = %Header
@onready var _separator: Control = %Separator
@onready var _wallet_status: BubbleStatusBubbleType = %WalletStatus
@onready var _capacity_status: BubbleStatusBubbleType = %CapacityStatus
@onready var _held_value_status: BubbleStatusBubbleType = %HeldValueStatus
@onready var _selection_status: BubbleStatusBubbleType = %SelectionStatus
@onready var _offer_status: BubbleStatusBubbleType = %OfferStatus
@onready var _inventory_section: Control = %InventorySection @onready var _inventory_section: Control = %InventorySection
@onready var _inventory_body: BoxContainer = %InventoryBody
@onready var _inventory_scroll: ScrollContainer = %InventoryScroll
@onready var _bag_section: Control = %BagSection @onready var _bag_section: Control = %BagSection
@onready var _logbook_section: Control = %LogbookSection @onready var _logbook_section: Control = %LogbookSection
@onready var _bag_empty: Label = %BagEmpty @onready var _bag_empty: Label = %BagEmpty
@onready var _bag_grid: GridContainer = %BagGrid @onready var _bag_grid: GridContainer = %BagGrid
@onready var _bag_list: Control = %BagList
@onready var _bag_detail: Control = %BagDetail
@onready var _bag_detail_texture: TextureRect = %BagDetailTexture @onready var _bag_detail_texture: TextureRect = %BagDetailTexture
@onready var _bag_detail_name: Label = %BagDetailName @onready var _bag_detail_name: Label = %BagDetailName
@onready var _bag_detail_data: Label = %BagDetailData @onready var _bag_detail_data: Label = %BagDetailData
@ -108,8 +68,6 @@ enum CloseReason {
@onready var _cooler_count: Label = %CoolerCount @onready var _cooler_count: Label = %CoolerCount
@onready var _inventory_empty: Label = %InventoryEmpty @onready var _inventory_empty: Label = %InventoryEmpty
@onready var _inventory_grid: GridContainer = %InventoryGrid @onready var _inventory_grid: GridContainer = %InventoryGrid
@onready var _inventory_list: Control = %InventoryList
@onready var _detail_panel: Control = %DetailPanel
@onready var _detail_texture: TextureRect = %DetailTexture @onready var _detail_texture: TextureRect = %DetailTexture
@onready var _detail_name: Label = %DetailName @onready var _detail_name: Label = %DetailName
@onready var _detail_data: Label = %DetailData @onready var _detail_data: Label = %DetailData
@ -124,10 +82,7 @@ enum CloseReason {
@onready var _cancel_sale_button: Button = %CancelSaleButton @onready var _cancel_sale_button: Button = %CancelSaleButton
@onready var _logbook_empty: Label = %LogbookEmpty @onready var _logbook_empty: Label = %LogbookEmpty
@onready var _logbook_grid: GridContainer = %LogbookGrid @onready var _logbook_grid: GridContainer = %LogbookGrid
@onready var _status_shoal: HBoxContainer = %StatusShoal
@onready var _sort_bar: HBoxContainer = %SortBar
var _compact_layout: bool = false
var _player: PlayerType var _player: PlayerType
var _inventory: FishInventoryType var _inventory: FishInventoryType
var _collection_log: CollectionLogType var _collection_log: CollectionLogType
@ -156,24 +111,9 @@ var _confirmation_buyer: FishBuyerProfileType
var _confirmation_buyer_id: StringName var _confirmation_buyer_id: StringName
var _confirmation_generation: int = -1 var _confirmation_generation: int = -1
var _sale_in_progress: bool = false var _sale_in_progress: bool = false
var _presentation_tween: Tween
var _page_tween: Tween
var _transition_generation: int = 0
var _page_transition_generation: int = 0
var _transitioning: bool = false
var _page_transitioning: bool = false
var _presentation_rest_position: Vector2 = Vector2.ZERO
var _content_rest_position: Vector2 = Vector2.ZERO
func _ready() -> void: func _ready() -> void:
_inventory_section.reparent(_cooler_host)
_inventory_section.size_flags_horizontal = Control.SIZE_EXPAND_FILL
_inventory_section.size_flags_vertical = Control.SIZE_EXPAND_FILL
_inventory_section.move_child(
_sort_bar,
_inventory_section.get_child_count() - 1,
)
_inventory_tab.pressed.connect( _inventory_tab.pressed.connect(
_show_section.bind(Section.COOLER) _show_section.bind(Section.COOLER)
) )
@ -193,18 +133,7 @@ func _ready() -> void:
_sort_option.add_item("rarity", SortMode.RARITY) _sort_option.add_item("rarity", SortMode.RARITY)
_sort_option.select(SortMode.CATCH_ORDER) _sort_option.select(SortMode.CATCH_ORDER)
_update_sort_direction_text() _update_sort_direction_text()
_navigation_cluster.configure([ _show_section(_current_section)
_inventory_tab,
_bag_tab,
_logbook_tab,
_close_button,
])
_configure_navigation_focus()
_apply_cooler_control_styles()
resized.connect(_update_shell_layout)
_show_section_immediate(_current_section)
call_deferred("_update_shell_layout")
set_process(false)
func setup( func setup(
@ -256,7 +185,6 @@ func _input(event: InputEvent) -> void:
return return
if visible: if visible:
if event.is_action_pressed("open_backpack"): if event.is_action_pressed("open_backpack"):
if not _transitioning and not _page_transitioning:
close_menu() close_menu()
get_viewport().set_input_as_handled() get_viewport().set_input_as_handled()
return return
@ -272,8 +200,6 @@ func _input(event: InputEvent) -> void:
func consume_escape() -> bool: func consume_escape() -> bool:
if not visible: if not visible:
return false return false
if _transitioning or _page_transitioning:
return true
if _sale_confirmation.visible: if _sale_confirmation.visible:
_close_sale_confirmation() _close_sale_confirmation()
else: else:
@ -290,9 +216,6 @@ func open_menu() -> void:
): ):
return return
_menu_generation += 1 _menu_generation += 1
_transition_generation += 1
_cancel_presentation_tween()
_cancel_page_tween()
_prior_movement_enabled = _player.is_movement_enabled() _prior_movement_enabled = _player.is_movement_enabled()
_prior_camera_input_enabled = _player.is_camera_input_enabled() _prior_camera_input_enabled = _player.is_camera_input_enabled()
_prior_mouse_mode = Input.mouse_mode _prior_mouse_mode = Input.mouse_mode
@ -304,9 +227,8 @@ func open_menu() -> void:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
visible = true visible = true
_refresh_all() _refresh_all()
_show_section_immediate(_current_section) _show_section(_current_section)
_update_shell_layout() _focus_current_section()
_begin_menu_entry()
menu_visibility_changed.emit(true) menu_visibility_changed.emit(true)
@ -316,10 +238,6 @@ func close_menu(
) -> void: ) -> void:
if not visible: if not visible:
return return
if _transitioning:
if reason != CloseReason.USER:
_finish_close(reason, restore_controls, _menu_generation)
return
get_viewport().gui_cancel_drag() get_viewport().gui_cancel_drag()
_close_sale_confirmation() _close_sale_confirmation()
if reason in [ if reason in [
@ -329,7 +247,18 @@ func close_menu(
CloseReason.TEARDOWN, CloseReason.TEARDOWN,
]: ]:
_fish_selection.clear() _fish_selection.clear()
_begin_menu_exit(reason, restore_controls) var closing_generation: int = _menu_generation
visible = false
get_viewport().gui_release_focus()
if _fishing_spot != null and is_instance_valid(_fishing_spot):
_fishing_spot.set_local_menu_input_suppressed(INPUT_OWNER, false)
if restore_controls:
_restore_player_controls(closing_generation)
else:
_control_snapshot_stored = false
_apply_mouse_close_policy(reason)
_menu_generation += 1
menu_visibility_changed.emit(false)
func close_for_water_recovery() -> void: func close_for_water_recovery() -> void:
@ -347,10 +276,8 @@ func close_for_session_end() -> void:
func _exit_tree() -> void: func _exit_tree() -> void:
_cancel_presentation_tween()
_cancel_page_tween()
if visible: if visible:
_finish_close(CloseReason.TEARDOWN, false, _menu_generation) close_menu(CloseReason.TEARDOWN, false)
_fish_selection.clear() _fish_selection.clear()
_menu_generation += 1 _menu_generation += 1
@ -392,32 +319,17 @@ func _on_bite_activated() -> void:
func _show_section(section: Section) -> void: func _show_section(section: Section) -> void:
if (
section == _current_section
or _transitioning
or _page_transitioning
or _sale_confirmation.visible
or get_viewport().gui_is_dragging()
):
return
_begin_page_transition(section)
func _show_section_immediate(section: Section) -> void:
_current_section = section _current_section = section
if not is_node_ready(): if not is_node_ready():
return return
_inventory_section.visible = section == Section.COOLER _inventory_section.visible = section == Section.COOLER
_cooler_scroll.visible = section == Section.COOLER
_bag_section.visible = section == Section.BAG _bag_section.visible = section == Section.BAG
_logbook_section.visible = section == Section.LOGBOOK _logbook_section.visible = section == Section.LOGBOOK
_content_shell.set_background_visible(section != Section.COOLER)
_header.visible = section != Section.COOLER
_separator.visible = section != Section.COOLER
_inventory_tab.button_pressed = section == Section.COOLER _inventory_tab.button_pressed = section == Section.COOLER
_bag_tab.button_pressed = section == Section.BAG _bag_tab.button_pressed = section == Section.BAG
_logbook_tab.button_pressed = section == Section.LOGBOOK _logbook_tab.button_pressed = section == Section.LOGBOOK
_update_navigation_selection() if visible:
_focus_current_section()
func _focus_current_section() -> void: func _focus_current_section() -> void:
@ -429,346 +341,6 @@ func _focus_current_section() -> void:
_logbook_tab.grab_focus() _logbook_tab.grab_focus()
func _process(delta: float) -> void:
if visible:
_navigation_cluster.advance_motion(delta)
func _configure_navigation_focus() -> void:
var navigation: Array[BubbleButtonType] = [
_inventory_tab,
_bag_tab,
_logbook_tab,
_close_button,
]
for index: int in navigation.size():
var bubble: BubbleButtonType = navigation[index]
var previous: BubbleButtonType = navigation[
(index - 1 + navigation.size()) % navigation.size()
]
var next: BubbleButtonType = navigation[
(index + 1) % navigation.size()
]
bubble.focus_neighbor_left = bubble.get_path_to(previous)
bubble.focus_neighbor_right = bubble.get_path_to(next)
bubble.focus_neighbor_top = bubble.focus_neighbor_left
bubble.focus_neighbor_bottom = bubble.focus_neighbor_right
func _apply_cooler_control_styles() -> void:
var profile: BubbleMenuProfile = _inventory_tab.profile
if profile == null:
return
_sort_option.add_theme_stylebox_override(
"normal",
profile.make_normal_style(),
)
_sort_option.add_theme_stylebox_override(
"hover",
profile.make_hover_style(),
)
_sort_option.add_theme_stylebox_override(
"focus",
profile.make_hover_style(),
)
_sort_option.add_theme_stylebox_override(
"pressed",
profile.make_pressed_style(),
)
_sort_option.add_theme_color_override("font_color", profile.text_color)
_sort_option.add_theme_color_override(
"font_hover_color",
profile.text_hover_color,
)
_sort_option.add_theme_color_override(
"font_focus_color",
profile.text_hover_color,
)
func _update_navigation_selection() -> void:
_set_navigation_target(_current_section)
func _set_navigation_target(section: Section) -> void:
_inventory_tab.button_pressed = section == Section.COOLER
_bag_tab.button_pressed = section == Section.BAG
_logbook_tab.button_pressed = section == Section.LOGBOOK
func _update_shell_layout() -> void:
if not is_node_ready():
return
var compact: bool = size.y < 560.0 or size.x < 760.0
_compact_layout = compact
var side_margin: float = 10.0 if compact else 42.0
var top_margin: float = 96.0 if compact else 104.0
var bottom_margin: float = 96.0 if compact else 138.0
_content_shell.position = Vector2(side_margin, top_margin)
_content_shell.size = Vector2(
maxf(1.0, size.x - side_margin * 2.0),
maxf(1.0, size.y - top_margin - bottom_margin)
)
_presentation_rest_position = _content_shell.position
var navigation_size := Vector2(
minf(size.x - 20.0, 610.0 if compact else 760.0),
52.0 if compact else 96.0
)
_navigation_cluster.position = Vector2(
(size.x - navigation_size.x) * 0.5,
4.0 if compact else 14.0
)
_navigation_cluster.size = navigation_size
_navigation_cluster.apply_layout(navigation_size, compact)
_inventory_grid.columns = 2 if compact else 3
_bag_grid.columns = 2 if compact else 3
_logbook_grid.columns = 3 if compact else 4
_inventory_list.custom_minimum_size.x = 292.0 if compact else 350.0
_inventory_list.size_flags_horizontal = Control.SIZE_EXPAND_FILL
_detail_panel.custom_minimum_size.x = 176.0 if compact else 210.0
_bag_list.custom_minimum_size.x = 300.0 if compact else 360.0
_bag_detail.custom_minimum_size.x = 176.0 if compact else 220.0
_content_stage.custom_minimum_size.y = 220.0 if compact else 260.0
call_deferred("_sync_cooler_width")
_inventory_body.vertical = compact
_inventory_scroll.vertical_scroll_mode = (
ScrollContainer.SCROLL_MODE_DISABLED
if compact
else ScrollContainer.SCROLL_MODE_AUTO
)
_inventory_list.custom_minimum_size.y = 240.0 if compact else 0.0
_detail_panel.custom_minimum_size = (
Vector2(0.0, 310.0)
if compact
else Vector2(430.0, 0.0)
)
_status_shoal.add_theme_constant_override(
"separation",
4 if compact else 8,
)
_inventory_body.queue_sort()
_content_rest_position = _content_stage.position
if not _transitioning:
_content_shell.position = _presentation_rest_position
if not _page_transitioning:
_content_stage.position = _content_rest_position
func _sync_cooler_width() -> void:
if not is_node_ready():
return
_cooler_host.custom_minimum_size.x = minf(
_content_stage.size.x,
1380.0,
)
_cooler_host.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
func _begin_menu_entry() -> void:
_transitioning = true
_set_shell_interactive(false)
set_process(true)
var generation: int = _transition_generation
var start_offset: float = size.y + TRANSITION_SAFE_MARGIN
_content_shell.position = _presentation_rest_position + Vector2.DOWN * start_offset
var navigation_rest: Vector2 = _navigation_cluster.position
_navigation_cluster.position = navigation_rest + Vector2.DOWN * start_offset
_presentation_tween = create_tween().set_parallel(true)
_presentation_tween.tween_property(
_content_shell,
"position",
_presentation_rest_position,
MENU_ENTER_DURATION
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
_presentation_tween.tween_property(
_navigation_cluster,
"position",
navigation_rest,
MENU_ENTER_DURATION
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
_presentation_tween.chain().tween_callback(
_finish_menu_entry.bind(generation)
)
func _finish_menu_entry(generation: int) -> void:
if generation != _transition_generation or not visible:
return
_presentation_tween = null
_transitioning = false
_set_shell_interactive(true)
_focus_current_section()
func _begin_menu_exit(reason: CloseReason, restore_controls: bool) -> void:
if reason != CloseReason.USER:
_finish_close(reason, restore_controls, _menu_generation)
return
_transition_generation += 1
_cancel_presentation_tween()
_transitioning = true
_set_shell_interactive(false)
get_viewport().gui_release_focus()
var generation: int = _transition_generation
var closing_generation: int = _menu_generation
var end_y: float = -maxf(
_content_shell.size.y,
_navigation_cluster.size.y
) - TRANSITION_SAFE_MARGIN
_presentation_tween = create_tween().set_parallel(true)
_presentation_tween.tween_property(
_content_shell,
"position:y",
end_y,
MENU_EXIT_DURATION
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
_presentation_tween.tween_property(
_navigation_cluster,
"position:y",
-_navigation_cluster.size.y - TRANSITION_SAFE_MARGIN,
MENU_EXIT_DURATION
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
_presentation_tween.chain().tween_callback(
_finish_menu_exit.bind(
generation,
reason,
restore_controls,
closing_generation,
)
)
func _finish_menu_exit(
generation: int,
reason: CloseReason,
restore_controls: bool,
closing_generation: int,
) -> void:
if generation != _transition_generation or not visible:
return
_presentation_tween = null
_finish_close(reason, restore_controls, closing_generation)
func _finish_close(
reason: CloseReason,
restore_controls: bool,
closing_generation: int,
) -> void:
_cancel_presentation_tween()
_cancel_page_tween()
_transitioning = false
_page_transitioning = false
visible = false
set_process(false)
get_viewport().gui_release_focus()
if _fishing_spot != null and is_instance_valid(_fishing_spot):
_fishing_spot.set_local_menu_input_suppressed(INPUT_OWNER, false)
if restore_controls:
_restore_player_controls(closing_generation)
else:
_control_snapshot_stored = false
_apply_mouse_close_policy(reason)
_menu_generation += 1
_transition_generation += 1
menu_visibility_changed.emit(false)
func _begin_page_transition(section: Section) -> void:
_page_transition_generation += 1
_cancel_page_tween()
_page_transitioning = true
_set_content_interactive(false)
_set_navigation_target(section)
var generation: int = _page_transition_generation
_page_tween = create_tween()
_page_tween.tween_property(
_content_stage,
"modulate:a",
0.0,
PAGE_OUT_DURATION
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
_page_tween.parallel().tween_property(
_content_stage,
"position:y",
_content_rest_position.y - 18.0,
PAGE_OUT_DURATION
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
_page_tween.tween_callback(
_swap_page.bind(section, generation)
)
_page_tween.tween_property(
_content_stage,
"modulate:a",
1.0,
PAGE_IN_DURATION
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
_page_tween.parallel().tween_property(
_content_stage,
"position",
_content_rest_position,
PAGE_IN_DURATION
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
_page_tween.finished.connect(
_finish_page_transition.bind(generation),
CONNECT_ONE_SHOT
)
func _swap_page(section: Section, generation: int) -> void:
if generation != _page_transition_generation or not visible:
return
_show_section_immediate(section)
_content_stage.position = _content_rest_position + Vector2.DOWN * 18.0
func _finish_page_transition(generation: int) -> void:
if generation != _page_transition_generation or not visible:
return
_page_tween = null
_page_transitioning = false
_content_stage.position = _content_rest_position
_content_stage.modulate.a = 1.0
_set_content_interactive(true)
_focus_current_section()
func _set_shell_interactive(interactive: bool) -> void:
_set_content_interactive(interactive)
for bubble: BubbleButtonType in [
_inventory_tab,
_bag_tab,
_logbook_tab,
_close_button,
]:
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 _set_content_interactive(interactive: bool) -> void:
_content_stage.mouse_filter = (
Control.MOUSE_FILTER_PASS
if interactive
else Control.MOUSE_FILTER_IGNORE
)
func _cancel_presentation_tween() -> void:
if _presentation_tween != null:
_presentation_tween.kill()
_presentation_tween = null
func _cancel_page_tween() -> void:
if _page_tween != null:
_page_tween.kill()
_page_tween = null
func _on_sort_selected(index: int) -> void: func _on_sort_selected(index: int) -> void:
_sort_mode = _sort_option.get_item_id(index) _sort_mode = _sort_option.get_item_id(index)
_refresh_inventory() _refresh_inventory()
@ -914,12 +486,6 @@ func _refresh_economy_summary() -> void:
else 0 else 0
) )
_wallet_balance.text = "wallet: $%d" % balance _wallet_balance.text = "wallet: $%d" % balance
_wallet_status.set_content("wallet", "$%d" % balance)
_capacity_status.set_content("cooler", "%d / %d" % [
_inventory.get_all_catches().size() if _inventory != null else 0,
_cooler_capacity.get_capacity() if _cooler_capacity != null else 0,
])
_held_value_status.set_content("held value", "$%d" % held_total)
_held_value.text = "held fish base value: $%d" % held_total _held_value.text = "held fish base value: $%d" % held_total
_cooler_count.text = "%d / %d" % [ _cooler_count.text = "%d / %d" % [
_inventory.get_all_catches().size() if _inventory != null else 0, _inventory.get_all_catches().size() if _inventory != null else 0,
@ -952,32 +518,11 @@ func _refresh_inventory() -> void:
selected = _inventory.get_catch(_fish_selection.get_focused_id()) selected = _inventory.get_catch(_fish_selection.get_focused_id())
for fish_catch: FishCatchType in catches: for fish_catch: FishCatchType in catches:
_inventory_grid.add_child(_create_inventory_card(fish_catch)) _inventory_grid.add_child(_create_inventory_card(fish_catch))
_configure_inventory_card_focus()
_update_inventory_detail(selected) _update_inventory_detail(selected)
_update_sale_summary() _update_sale_summary()
_update_sort_direction_text() _update_sort_direction_text()
func _configure_inventory_card_focus() -> void:
var cards: Array[Control] = []
for child: Node in _inventory_grid.get_children():
if child is Control:
cards.append(child as Control)
var columns: int = maxi(_inventory_grid.columns, 1)
for index: int in cards.size():
var card: Control = cards[index]
var row: int = floori(float(index) / float(columns))
var column: int = index % columns
var left_index: int = row * columns + maxi(column - 1, 0)
var right_index: int = mini(index + 1, cards.size() - 1)
var top_index: int = maxi(index - columns, 0)
var bottom_index: int = mini(index + columns, cards.size() - 1)
card.focus_neighbor_left = card.get_path_to(cards[left_index])
card.focus_neighbor_right = card.get_path_to(cards[right_index])
card.focus_neighbor_top = card.get_path_to(cards[top_index])
card.focus_neighbor_bottom = card.get_path_to(cards[bottom_index])
func _compare_catches(left: FishCatchType, right: FishCatchType) -> bool: func _compare_catches(left: FishCatchType, right: FishCatchType) -> bool:
var comparison: int = 0 var comparison: int = 0
match _sort_mode: match _sort_mode:
@ -995,23 +540,92 @@ func _compare_catches(left: FishCatchType, right: FishCatchType) -> bool:
func _create_inventory_card(fish_catch: FishCatchType) -> Button: func _create_inventory_card(fish_catch: FishCatchType) -> Button:
var card := BubbleInventoryCellScene.instantiate() as BubbleInventoryCellType var card := Button.new()
card.set_compact(_compact_layout) card.theme_type_variation = &"CardButton"
card.custom_minimum_size = Vector2(132.0, 118.0)
card.toggle_mode = true
var is_selected: bool = _fish_selection.is_selected(fish_catch.catch_id) var is_selected: bool = _fish_selection.is_selected(fish_catch.catch_id)
var is_focused: bool = ( var is_focused: bool = (
fish_catch.catch_id == _fish_selection.get_focused_id() fish_catch.catch_id == _fish_selection.get_focused_id()
) )
card.configure( card.button_pressed = is_selected
fish_catch.fish.display_texture,
fish_catch.fish.display_name,
"%.2f lb" % fish_catch.weight_lb,
)
card.set_item_state(
is_selected,
is_focused,
fish_catch.is_favorited,
)
card.pressed.connect(_on_catch_card_pressed.bind(fish_catch.catch_id)) card.pressed.connect(_on_catch_card_pressed.bind(fish_catch.catch_id))
_apply_inventory_card_styles(
card,
UIPalette.get_rarity_color(fish_catch.fish.rarity),
is_selected,
is_focused
)
var content := VBoxContainer.new()
content.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT, Control.PRESET_MODE_MINSIZE, 8)
content.add_theme_constant_override("separation", 3)
content.mouse_filter = Control.MOUSE_FILTER_IGNORE
card.add_child(content)
content.add_child(_create_texture_frame(
fish_catch.fish.display_texture,
Vector2(108.0, 62.0)
))
var name_label := Label.new()
name_label.text = fish_catch.fish.display_name
name_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
name_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
content.add_child(name_label)
var weight_label := Label.new()
weight_label.text = "%.2f lb" % fish_catch.weight_lb
weight_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
weight_label.add_theme_color_override(
"font_color",
UIPalette.MUTED_TEXT
)
weight_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
content.add_child(weight_label)
if fish_catch.is_favorited:
var favorite_marker := Label.new()
favorite_marker.text = ""
favorite_marker.add_theme_color_override(
"font_color",
UIPalette.SECONDARY
)
favorite_marker.add_theme_font_size_override("font_size", 27)
favorite_marker.set_anchors_preset(Control.PRESET_TOP_RIGHT)
favorite_marker.offset_left = -28.0
favorite_marker.offset_top = 5.0
favorite_marker.offset_right = -8.0
favorite_marker.offset_bottom = 29.0
favorite_marker.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
favorite_marker.mouse_filter = Control.MOUSE_FILTER_IGNORE
card.add_child(favorite_marker)
if is_selected:
var selected_marker := Label.new()
selected_marker.text = ""
selected_marker.add_theme_color_override(
"font_color",
UIPalette.SUCCESS
)
selected_marker.add_theme_font_size_override("font_size", 27)
selected_marker.set_anchors_preset(Control.PRESET_TOP_LEFT)
selected_marker.offset_left = 8.0
selected_marker.offset_top = 5.0
selected_marker.offset_right = 30.0
selected_marker.offset_bottom = 29.0
selected_marker.mouse_filter = Control.MOUSE_FILTER_IGNORE
card.add_child(selected_marker)
if is_focused:
var focus_marker := Label.new()
focus_marker.text = ""
focus_marker.add_theme_color_override(
"font_color",
UIPalette.PRIMARY
)
focus_marker.set_anchors_preset(Control.PRESET_BOTTOM_RIGHT)
focus_marker.offset_left = -26.0
focus_marker.offset_top = -25.0
focus_marker.offset_right = -8.0
focus_marker.offset_bottom = -7.0
focus_marker.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
focus_marker.mouse_filter = Control.MOUSE_FILTER_IGNORE
card.add_child(focus_marker)
return card return card
@ -1148,8 +762,6 @@ func _update_sale_summary() -> void:
) )
if selected_count == 0: if selected_count == 0:
_selection_summary.text = "no fish selected" _selection_summary.text = "no fish selected"
_selection_status.set_content("selected", "none")
_offer_status.set_content("pelican offer", "")
_sell_button.text = "sell fish" _sell_button.text = "sell fish"
_sell_button.disabled = true _sell_button.disabled = true
_sale_unavailable.text = "" _sale_unavailable.text = ""
@ -1166,7 +778,6 @@ func _update_sale_summary() -> void:
else "%d fish selected" % selected_count else "%d fish selected" % selected_count
) )
_selection_summary.text = count_text _selection_summary.text = count_text
_selection_status.set_content("selected", str(selected_count))
if ( if (
preview != null preview != null
and preview.payout >= 0 and preview.payout >= 0
@ -1180,9 +791,6 @@ func _update_sale_summary() -> void:
_default_buyer.display_name, _default_buyer.display_name,
preview.payout, preview.payout,
] ]
_offer_status.set_content("pelican offer", "$%d" % preview.payout)
else:
_offer_status.set_content("pelican offer", "unavailable")
_sell_button.disabled = preview == null or not preview.is_success() _sell_button.disabled = preview == null or not preview.is_success()
if preview != null and preview.status == FishSaleResultType.Status.FAVORITED: if preview != null and preview.status == FishSaleResultType.Status.FAVORITED:
_sale_unavailable.text = ( _sale_unavailable.text = (

View file

@ -1,15 +1,7 @@
[gd_scene load_steps=9 format=3] [gd_scene load_steps=3 format=3]
[ext_resource type="Script" path="res://ui/player_menu.gd" id="1_menu"] [ext_resource type="Script" path="res://ui/player_menu.gd" id="1_menu"]
[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/components/bubble_menu/bubble_content_shell.gd" id="3_shell"]
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="4_profile"]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_cluster.gd" id="5_cluster"]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_button.gd" id="6_bubble"]
[ext_resource type="PackedScene" path="res://ui/components/bubble_menu/bubble_status_bubble.tscn" id="7_status"]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_information_panel.gd" id="8_info"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_collection"]
[node name="PlayerMenu" type="Control"] [node name="PlayerMenu" type="Control"]
visible = false visible = false
@ -36,16 +28,13 @@ mouse_filter = 2
color = Color(0.015, 0.02, 0.03, 0.72) color = Color(0.015, 0.02, 0.03, 0.72)
[node name="MenuPanel" type="PanelContainer" parent="."] [node name="MenuPanel" type="PanelContainer" parent="."]
unique_name_in_owner = true layout_mode = 1
layout_mode = 0 anchor_left = 0.02
offset_left = 42.0 anchor_top = 0.025
offset_top = 104.0 anchor_right = 0.98
offset_right = 1238.0 anchor_bottom = 0.96
offset_bottom = 582.0 grow_horizontal = 2
script = ExtResource("3_shell") grow_vertical = 2
profile = ExtResource("4_profile")
content_margin = 22.0
corner_radius = 74
[node name="Margin" type="MarginContainer" parent="MenuPanel"] [node name="Margin" type="MarginContainer" parent="MenuPanel"]
layout_mode = 2 layout_mode = 2
@ -59,20 +48,51 @@ layout_mode = 2
theme_override_constants/separation = 8 theme_override_constants/separation = 8
[node name="Header" type="HBoxContainer" parent="MenuPanel/Margin/Layout"] [node name="Header" type="HBoxContainer" parent="MenuPanel/Margin/Layout"]
unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
theme_override_constants/separation = 8 theme_override_constants/separation = 8
[node name="Title" type="Label" parent="MenuPanel/Margin/Layout/Header"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_colors/font_color = Color(0.208, 0.725, 0.78, 1)
theme_override_font_sizes/font_size = 33
text = "player menu"
[node name="WalletBalance" type="Label" parent="MenuPanel/Margin/Layout/Header"] [node name="WalletBalance" type="Label" parent="MenuPanel/Margin/Layout/Header"]
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
size_flags_horizontal = 3
text = "wallet: $0" text = "wallet: $0"
theme_override_colors/font_color = Color(1, 0.82, 0.4, 1) theme_override_colors/font_color = Color(1, 0.82, 0.4, 1)
[node name="Separator" type="HSeparator" parent="MenuPanel/Margin/Layout"] [node name="InventoryTab" type="Button" parent="MenuPanel/Margin/Layout/Header"]
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
toggle_mode = true
text = "cooler"
custom_minimum_size = Vector2(130, 58)
[node name="BagTab" type="Button" parent="MenuPanel/Margin/Layout/Header"]
unique_name_in_owner = true
layout_mode = 2
toggle_mode = true
text = "bag"
custom_minimum_size = Vector2(110, 58)
[node name="LogbookTab" type="Button" parent="MenuPanel/Margin/Layout/Header"]
unique_name_in_owner = true
layout_mode = 2
toggle_mode = true
text = "logbook"
custom_minimum_size = Vector2(140, 58)
[node name="CloseButton" type="Button" parent="MenuPanel/Margin/Layout/Header"]
unique_name_in_owner = true
layout_mode = 2
text = "close"
custom_minimum_size = Vector2(110, 58)
[node name="Separator" type="HSeparator" parent="MenuPanel/Margin/Layout"]
layout_mode = 2
[node name="TransactionFeedback" type="Label" parent="MenuPanel/Margin/Layout"] [node name="TransactionFeedback" type="Label" parent="MenuPanel/Margin/Layout"]
unique_name_in_owner = true unique_name_in_owner = true
@ -83,26 +103,10 @@ theme_override_colors/font_color = Color(1, 0.82, 0.4, 1)
theme_override_font_sizes/font_size = 21 theme_override_font_sizes/font_size = 21
[node name="Content" type="Control" parent="MenuPanel/Margin/Layout"] [node name="Content" type="Control" parent="MenuPanel/Margin/Layout"]
unique_name_in_owner = true
custom_minimum_size = Vector2(0, 260) custom_minimum_size = Vector2(0, 260)
layout_mode = 2 layout_mode = 2
size_flags_vertical = 3 size_flags_vertical = 3
[node name="CoolerScroll" type="ScrollContainer" parent="MenuPanel/Margin/Layout/Content"]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
horizontal_scroll_mode = 0
[node name="CoolerHost" type="VBoxContainer" parent="MenuPanel/Margin/Layout/Content/CoolerScroll"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
[node name="InventorySection" type="VBoxContainer" parent="MenuPanel/Margin/Layout/Content"] [node name="InventorySection" type="VBoxContainer" parent="MenuPanel/Margin/Layout/Content"]
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 1 layout_mode = 1
@ -113,26 +117,7 @@ grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
theme_override_constants/separation = 7 theme_override_constants/separation = 7
[node name="StatusShoal" type="HBoxContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection"]
unique_name_in_owner = true
layout_mode = 2
theme_override_constants/separation = 8
alignment = 1
[node name="WalletStatus" parent="MenuPanel/Margin/Layout/Content/InventorySection/StatusShoal" instance=ExtResource("7_status")]
unique_name_in_owner = true
layout_mode = 2
[node name="CapacityStatus" parent="MenuPanel/Margin/Layout/Content/InventorySection/StatusShoal" instance=ExtResource("7_status")]
unique_name_in_owner = true
layout_mode = 2
[node name="HeldValueStatus" parent="MenuPanel/Margin/Layout/Content/InventorySection/StatusShoal" instance=ExtResource("7_status")]
unique_name_in_owner = true
layout_mode = 2
[node name="SortBar" type="HBoxContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection"] [node name="SortBar" type="HBoxContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection"]
unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
theme_override_constants/separation = 6 theme_override_constants/separation = 6
@ -143,21 +128,13 @@ text = "sort:"
[node name="SortOption" type="OptionButton" parent="MenuPanel/Margin/Layout/Content/InventorySection/SortBar"] [node name="SortOption" type="OptionButton" parent="MenuPanel/Margin/Layout/Content/InventorySection/SortBar"]
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
custom_minimum_size = Vector2(136, 104) custom_minimum_size = Vector2(190, 58)
[node name="SortDirection" type="Button" parent="MenuPanel/Margin/Layout/Content/InventorySection/SortBar"] [node name="SortDirection" type="Button" parent="MenuPanel/Margin/Layout/Content/InventorySection/SortBar"]
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
custom_minimum_size = Vector2(136, 104) custom_minimum_size = Vector2(190, 58)
text = "newest first" text = "newest first"
script = ExtResource("6_bubble")
profile = ExtResource("4_profile")
neutral_size = Vector2(136, 104)
minimum_font_size = 15
maximum_font_size = 20
horizontal_amplitude = 0.0
vertical_amplitude = 0.0
deformation_amplitude = 0.0
[node name="SortSpacer" type="Control" parent="MenuPanel/Margin/Layout/Content/InventorySection/SortBar"] [node name="SortSpacer" type="Control" parent="MenuPanel/Margin/Layout/Content/InventorySection/SortBar"]
layout_mode = 2 layout_mode = 2
@ -165,29 +142,25 @@ size_flags_horizontal = 3
[node name="CoolerCount" type="Label" parent="MenuPanel/Margin/Layout/Content/InventorySection/SortBar"] [node name="CoolerCount" type="Label" parent="MenuPanel/Margin/Layout/Content/InventorySection/SortBar"]
unique_name_in_owner = true unique_name_in_owner = true
visible = false
layout_mode = 2 layout_mode = 2
text = "0 / 12" text = "0 / 12"
theme_override_colors/font_color = Color(0.208, 0.725, 0.78, 1) theme_override_colors/font_color = Color(0.208, 0.725, 0.78, 1)
[node name="HeldValue" type="Label" parent="MenuPanel/Margin/Layout/Content/InventorySection/SortBar"] [node name="HeldValue" type="Label" parent="MenuPanel/Margin/Layout/Content/InventorySection/SortBar"]
unique_name_in_owner = true unique_name_in_owner = true
visible = false
layout_mode = 2 layout_mode = 2
text = "held fish base value: $0" text = "held fish base value: $0"
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)
[node name="InventoryBody" type="BoxContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection"] [node name="InventoryBody" type="HSplitContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection"]
unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
size_flags_vertical = 3 size_flags_vertical = 3
split_offset = 510
theme_override_constants/separation = 8 theme_override_constants/separation = 8
[node name="InventoryList" type="PanelContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody"] [node name="InventoryList" type="PanelContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody"]
unique_name_in_owner = true
custom_minimum_size = Vector2(350, 0) custom_minimum_size = Vector2(350, 0)
layout_mode = 2 layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxEmpty_collection")
[node name="InventoryListMargin" type="MarginContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/InventoryList"] [node name="InventoryListMargin" type="MarginContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/InventoryList"]
layout_mode = 2 layout_mode = 2
@ -207,7 +180,6 @@ text = "your cooler is empty."
horizontal_alignment = 1 horizontal_alignment = 1
[node name="InventoryScroll" type="ScrollContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/InventoryList/InventoryListMargin/InventoryStack"] [node name="InventoryScroll" type="ScrollContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/InventoryList/InventoryListMargin/InventoryStack"]
unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
size_flags_vertical = 3 size_flags_vertical = 3
horizontal_scroll_mode = 0 horizontal_scroll_mode = 0
@ -221,13 +193,8 @@ theme_override_constants/v_separation = 7
columns = 3 columns = 3
[node name="DetailPanel" type="PanelContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody"] [node name="DetailPanel" type="PanelContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody"]
unique_name_in_owner = true
custom_minimum_size = Vector2(210, 0) custom_minimum_size = Vector2(210, 0)
layout_mode = 2 layout_mode = 2
script = ExtResource("8_info")
profile = ExtResource("4_profile")
content_margin = 12.0
corner_radius = 96
[node name="DetailMargin" type="MarginContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel"] [node name="DetailMargin" type="MarginContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel"]
layout_mode = 2 layout_mode = 2
@ -254,75 +221,33 @@ layout_mode = 2
theme_override_colors/font_color = Color(0.208, 0.725, 0.78, 1) theme_override_colors/font_color = Color(0.208, 0.725, 0.78, 1)
theme_override_font_sizes/font_size = 29 theme_override_font_sizes/font_size = 29
horizontal_alignment = 1 horizontal_alignment = 1
theme_override_colors/font_color = Color(0.035, 0.145, 0.22, 1)
[node name="DetailData" type="Label" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel/DetailMargin/DetailStack"] [node name="DetailData" type="Label" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel/DetailMargin/DetailStack"]
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
autowrap_mode = 2 autowrap_mode = 2
horizontal_alignment = 1 horizontal_alignment = 1
theme_override_colors/font_color = Color(0.035, 0.145, 0.22, 1)
[node name="SelectionSummary" type="Label" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel/DetailMargin/DetailStack"] [node name="SelectionSummary" type="Label" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel/DetailMargin/DetailStack"]
unique_name_in_owner = true unique_name_in_owner = true
visible = false
layout_mode = 2 layout_mode = 2
text = "no fish selected" text = "no fish selected"
autowrap_mode = 2 autowrap_mode = 2
horizontal_alignment = 1 horizontal_alignment = 1
theme_override_colors/font_color = Color(0.208, 0.725, 0.78, 1) theme_override_colors/font_color = Color(0.208, 0.725, 0.78, 1)
[node name="ActionRow" type="HBoxContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel/DetailMargin/DetailStack"] [node name="FavoriteButton" type="Button" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel/DetailMargin/DetailStack"]
layout_mode = 2
theme_override_constants/separation = 8
alignment = 1
[node name="FavoriteButton" type="Button" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel/DetailMargin/DetailStack/ActionRow"]
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
disabled = true disabled = true
text = "favorite" text = "favorite"
custom_minimum_size = Vector2(112, 104)
size_flags_horizontal = 4
script = ExtResource("6_bubble")
profile = ExtResource("4_profile")
neutral_size = Vector2(112, 104)
minimum_font_size = 15
maximum_font_size = 20
horizontal_amplitude = 0.0
vertical_amplitude = 0.0
deformation_amplitude = 0.0
[node name="SellButton" type="Button" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel/DetailMargin/DetailStack/ActionRow"] [node name="SellButton" type="Button" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel/DetailMargin/DetailStack"]
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
disabled = true disabled = true
text = "sell" text = "sell"
custom_minimum_size = Vector2(112, 104) theme_type_variation = &"DangerButton"
size_flags_horizontal = 4
script = ExtResource("6_bubble")
profile = ExtResource("4_profile")
neutral_size = Vector2(112, 104)
minimum_font_size = 15
maximum_font_size = 20
horizontal_amplitude = 0.0
vertical_amplitude = 0.0
deformation_amplitude = 0.0
[node name="ContextStatus" type="HBoxContainer" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel/DetailMargin/DetailStack"]
layout_mode = 2
theme_override_constants/separation = 6
alignment = 1
[node name="SelectionStatus" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel/DetailMargin/DetailStack/ContextStatus" instance=ExtResource("7_status")]
unique_name_in_owner = true
custom_minimum_size = Vector2(108, 78)
layout_mode = 2
[node name="OfferStatus" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel/DetailMargin/DetailStack/ContextStatus" instance=ExtResource("7_status")]
unique_name_in_owner = true
custom_minimum_size = Vector2(128, 78)
layout_mode = 2
[node name="SaleUnavailable" type="Label" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel/DetailMargin/DetailStack"] [node name="SaleUnavailable" type="Label" parent="MenuPanel/Margin/Layout/Content/InventorySection/InventoryBody/DetailPanel/DetailMargin/DetailStack"]
unique_name_in_owner = true unique_name_in_owner = true
@ -347,7 +272,6 @@ theme_override_constants/separation = 7
layout_mode = 2 layout_mode = 2
text = "drag hotbar-compatible items onto a slot below. right-click a slot to clear it." text = "drag hotbar-compatible items onto a slot below. right-click a slot to clear it."
horizontal_alignment = 1 horizontal_alignment = 1
autowrap_mode = 2
[node name="BagBody" type="HSplitContainer" parent="MenuPanel/Margin/Layout/Content/BagSection"] [node name="BagBody" type="HSplitContainer" parent="MenuPanel/Margin/Layout/Content/BagSection"]
layout_mode = 2 layout_mode = 2
@ -356,7 +280,6 @@ split_offset = 540
theme_override_constants/separation = 8 theme_override_constants/separation = 8
[node name="BagList" type="PanelContainer" parent="MenuPanel/Margin/Layout/Content/BagSection/BagBody"] [node name="BagList" type="PanelContainer" parent="MenuPanel/Margin/Layout/Content/BagSection/BagBody"]
unique_name_in_owner = true
custom_minimum_size = Vector2(360, 0) custom_minimum_size = Vector2(360, 0)
layout_mode = 2 layout_mode = 2
@ -391,7 +314,6 @@ theme_override_constants/v_separation = 7
columns = 3 columns = 3
[node name="BagDetail" type="PanelContainer" parent="MenuPanel/Margin/Layout/Content/BagSection/BagBody"] [node name="BagDetail" type="PanelContainer" parent="MenuPanel/Margin/Layout/Content/BagSection/BagBody"]
unique_name_in_owner = true
custom_minimum_size = Vector2(220, 0) custom_minimum_size = Vector2(220, 0)
layout_mode = 2 layout_mode = 2
@ -507,99 +429,3 @@ unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
text = "cancel" text = "cancel"
custom_minimum_size = Vector2(170, 64) custom_minimum_size = Vector2(170, 64)
[node name="NavigationCluster" type="Control" parent="."]
unique_name_in_owner = true
layout_mode = 0
offset_left = 260.0
offset_top = 14.0
offset_right = 1020.0
offset_bottom = 110.0
mouse_filter = 1
script = ExtResource("5_cluster")
profile = ExtResource("4_profile")
desktop_reference_size = Vector2(760, 96)
compact_reference_size = Vector2(610, 74)
[node name="InventoryTab" type="Button" parent="NavigationCluster"]
unique_name_in_owner = true
custom_minimum_size = Vector2(148, 138)
layout_mode = 0
toggle_mode = true
text = "cooler"
script = ExtResource("6_bubble")
profile = ExtResource("4_profile")
neutral_size = Vector2(148, 138)
desktop_anchor = Vector2(118, 68)
compact_anchor = Vector2(118, 68)
compact_minimum_size = Vector2(84, 78)
minimum_font_size = 16
maximum_font_size = 27
horizontal_amplitude = 1.2
vertical_amplitude = 2.4
motion_period = 5.6
motion_phase = 0.35
deformation_amplitude = 0.012
deformation_period = 6.4
[node name="BagTab" type="Button" parent="NavigationCluster"]
unique_name_in_owner = true
custom_minimum_size = Vector2(122, 116)
layout_mode = 0
toggle_mode = true
text = "bag"
script = ExtResource("6_bubble")
profile = ExtResource("4_profile")
neutral_size = Vector2(122, 116)
desktop_anchor = Vector2(300, 62)
compact_anchor = Vector2(300, 62)
compact_minimum_size = Vector2(70, 68)
minimum_font_size = 16
maximum_font_size = 25
horizontal_amplitude = 1.0
vertical_amplitude = 2.0
motion_period = 5.1
motion_phase = 1.65
deformation_amplitude = 0.011
deformation_period = 6.0
[node name="LogbookTab" type="Button" parent="NavigationCluster"]
unique_name_in_owner = true
custom_minimum_size = Vector2(158, 146)
layout_mode = 0
toggle_mode = true
text = "logbook"
script = ExtResource("6_bubble")
profile = ExtResource("4_profile")
neutral_size = Vector2(158, 146)
desktop_anchor = Vector2(478, 70)
compact_anchor = Vector2(478, 70)
compact_minimum_size = Vector2(88, 80)
minimum_font_size = 16
maximum_font_size = 27
horizontal_amplitude = 1.3
vertical_amplitude = 2.5
motion_period = 5.9
motion_phase = 2.85
deformation_amplitude = 0.012
deformation_period = 6.7
[node name="CloseButton" type="Button" parent="NavigationCluster"]
unique_name_in_owner = true
custom_minimum_size = Vector2(112, 106)
layout_mode = 0
text = "close"
script = ExtResource("6_bubble")
profile = ExtResource("4_profile")
neutral_size = Vector2(112, 106)
desktop_anchor = Vector2(652, 61)
compact_anchor = Vector2(652, 61)
compact_minimum_size = Vector2(66, 64)
minimum_font_size = 15
maximum_font_size = 23
horizontal_amplitude = 1.0
vertical_amplitude = 1.9
motion_period = 5.3
motion_phase = 4.2
deformation_amplitude = 0.01
deformation_period = 6.2