Add unified inventory and animated menu backdrop
This commit is contained in:
parent
4985cc3374
commit
28ce6fedcb
16 changed files with 865 additions and 123 deletions
BIN
art/patterns/pattern_bluedot.png
Normal file
BIN
art/patterns/pattern_bluedot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
40
art/patterns/pattern_bluedot.png.import
Normal file
40
art/patterns/pattern_bluedot.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://d0o3ym81t1sxs"
|
||||
path="res://.godot/imported/pattern_bluedot.png-2880ee070284314ed1e7b46e1dbc0570.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/patterns/pattern_bluedot.png"
|
||||
dest_files=["res://.godot/imported/pattern_bluedot.png-2880ee070284314ed1e7b46e1dbc0570.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
|
|
@ -433,7 +433,6 @@ func _unhandled_input(event: InputEvent) -> void:
|
|||
get_viewport().set_input_as_handled()
|
||||
return
|
||||
if not has_active_fishing_rod():
|
||||
status_changed.emit("select a fishing rod to cast.")
|
||||
get_viewport().set_input_as_handled()
|
||||
return
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ enum Category {
|
|||
UTILITY,
|
||||
QUEST,
|
||||
COSMETIC,
|
||||
LURE,
|
||||
}
|
||||
|
||||
@export var item_id: StringName
|
||||
|
|
|
|||
48
main/main.gd
48
main/main.gd
|
|
@ -72,6 +72,8 @@ const NetworkProfileServiceType = preload(
|
|||
)
|
||||
|
||||
const TITLE_MUSIC_SILENCE_DB: float = -80.0
|
||||
const PLAYER_MENU_PATTERN_SCALE: float = 0.85
|
||||
const PLAYER_MENU_PATTERN_SCROLL_VELOCITY := Vector2(-7.0, -5.0)
|
||||
|
||||
@export var fish_catalog: FishPoolType
|
||||
@export var pelican_buyer_profile: FishBuyerProfileType
|
||||
|
|
@ -143,6 +145,7 @@ var _title_music_requested: bool = false
|
|||
var _quit_in_progress: bool = false
|
||||
var _join_requested_from_title: bool = false
|
||||
var _join_requested_from_pause: bool = false
|
||||
var _player_menu_backdrop_tween: Tween
|
||||
var _pending_join_endpoint: String = ""
|
||||
var _server_trust_dialog: ConfirmationDialog
|
||||
var _pending_trust_changed: bool = false
|
||||
|
|
@ -158,6 +161,18 @@ var _local_recovery_attempt_id: String = ""
|
|||
|
||||
func _ready() -> void:
|
||||
DisplayServer.window_set_title("NETfishing")
|
||||
var menu_pattern_material := (
|
||||
_player_menu_backdrop.material as ShaderMaterial
|
||||
)
|
||||
if menu_pattern_material != null:
|
||||
menu_pattern_material.set_shader_parameter(
|
||||
"display_scale",
|
||||
PLAYER_MENU_PATTERN_SCALE,
|
||||
)
|
||||
menu_pattern_material.set_shader_parameter(
|
||||
"scroll_velocity_pixels",
|
||||
PLAYER_MENU_PATTERN_SCROLL_VELOCITY,
|
||||
)
|
||||
get_window().size_changed.connect(_resize_native_overlays)
|
||||
_resize_native_overlays()
|
||||
if not _settings_manager.settings_changed.is_connected(
|
||||
|
|
@ -906,7 +921,38 @@ func _set_gameplay_active(active: bool) -> void:
|
|||
|
||||
|
||||
func _set_player_menu_backdrop_visible(is_visible: bool) -> void:
|
||||
_player_menu_backdrop.visible = is_visible and _gameplay_started
|
||||
if _player_menu_backdrop_tween != null:
|
||||
_player_menu_backdrop_tween.kill()
|
||||
_player_menu_backdrop_tween = null
|
||||
var should_show: bool = is_visible and _gameplay_started
|
||||
if should_show:
|
||||
var was_visible: bool = _player_menu_backdrop.visible
|
||||
_player_menu_backdrop.visible = true
|
||||
if not was_visible:
|
||||
_player_menu_backdrop.modulate.a = 0.0
|
||||
_player_menu_backdrop_tween = create_tween()
|
||||
_player_menu_backdrop_tween.tween_property(
|
||||
_player_menu_backdrop,
|
||||
"modulate:a",
|
||||
1.0,
|
||||
UIMotion.UTILITY_ENTER_DURATION,
|
||||
).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
|
||||
return
|
||||
if not _player_menu_backdrop.visible:
|
||||
return
|
||||
_player_menu_backdrop_tween = create_tween()
|
||||
_player_menu_backdrop_tween.tween_property(
|
||||
_player_menu_backdrop,
|
||||
"modulate:a",
|
||||
0.0,
|
||||
UIMotion.UTILITY_EXIT_DURATION,
|
||||
).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN)
|
||||
_player_menu_backdrop_tween.finished.connect(
|
||||
func() -> void:
|
||||
_player_menu_backdrop.visible = false
|
||||
_player_menu_backdrop.modulate.a = 1.0
|
||||
_player_menu_backdrop_tween = null
|
||||
)
|
||||
|
||||
|
||||
func _resize_native_overlays() -> void:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=42 format=3]
|
||||
[gd_scene load_steps=45 format=3]
|
||||
|
||||
[ext_resource type="PackedScene" path="res://world/test_world.tscn" id="1_world"]
|
||||
[ext_resource type="PackedScene" path="res://player/player.tscn" id="2_player"]
|
||||
|
|
@ -40,10 +40,19 @@
|
|||
[ext_resource type="Script" path="res://network/identity_backup_service.gd" id="38_identity_backup"]
|
||||
[ext_resource type="Script" path="res://ui/interface_font_controller.gd" id="39_fonts"]
|
||||
[ext_resource type="Shader" path="res://ui/title_water_background.gdshader" id="40_title_water"]
|
||||
[ext_resource type="Texture2D" path="res://art/patterns/pattern_bluedot.png" id="41_menu_pattern"]
|
||||
[ext_resource type="Shader" path="res://ui/player_menu_pattern.gdshader" id="42_menu_pattern"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_title_water_native"]
|
||||
shader = ExtResource("40_title_water")
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_player_menu_pattern"]
|
||||
shader = ExtResource("42_menu_pattern")
|
||||
shader_parameter/pattern_texture = ExtResource("41_menu_pattern")
|
||||
shader_parameter/source_tile_size = Vector2(128, 128)
|
||||
shader_parameter/display_scale = 0.85
|
||||
shader_parameter/scroll_velocity_pixels = Vector2(-7, -5)
|
||||
|
||||
[node name="Main" type="Node3D"]
|
||||
script = ExtResource("3_main")
|
||||
fish_catalog = ExtResource("6_pool")
|
||||
|
|
@ -70,7 +79,8 @@ unique_name_in_owner = true
|
|||
visible = false
|
||||
z_index = 10
|
||||
mouse_filter = 2
|
||||
color = Color(0.015, 0.02, 0.03, 0.72)
|
||||
material = SubResource("ShaderMaterial_player_menu_pattern")
|
||||
color = Color(1, 1, 1, 1)
|
||||
|
||||
[node name="InterfaceFontController" type="Node" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ signal interactive_pointer_ui_changed(is_open: bool)
|
|||
signal player_menu_backdrop_visibility_changed(is_visible: bool)
|
||||
|
||||
@onready var _status_label: Label = %StatusLabel
|
||||
@onready var _gameplay_transient_hud: Control = %GameplayTransientHUD
|
||||
@onready var _catch_track: Control = %CatchTrack
|
||||
@onready var _green_catch_progress: ProgressBar = %GreenCatchProgress
|
||||
@onready var _red_chase_progress: ProgressBar = %RedChaseProgress
|
||||
|
|
@ -72,6 +73,7 @@ var _gameplay_ui_enabled: bool = false
|
|||
var _fishing_spot: FishingSpotType
|
||||
var _system_menu_open: bool = false
|
||||
var _shop_open: bool = false
|
||||
var _player_menu_hotbar_visible: bool = false
|
||||
var _item_effects: PlayerItemEffectsType
|
||||
|
||||
|
||||
|
|
@ -137,6 +139,10 @@ func setup(
|
|||
_player_menu.menu_visibility_changed.connect(
|
||||
_on_player_menu_visibility_changed
|
||||
)
|
||||
_player_menu.menu_exit_started.connect(_on_player_menu_exit_started)
|
||||
_player_menu.inventory_hotbar_context_changed.connect(
|
||||
_on_inventory_hotbar_context_changed
|
||||
)
|
||||
_player_menu.setup(
|
||||
player,
|
||||
inventory,
|
||||
|
|
@ -251,16 +257,17 @@ func get_pause_menu() -> PauseMenuType:
|
|||
|
||||
func set_gameplay_ui_enabled(enabled: bool) -> void:
|
||||
_gameplay_ui_enabled = enabled
|
||||
_gameplay_transient_hud.visible = enabled and not _player_menu_open
|
||||
_refresh_chat_availability()
|
||||
if not enabled:
|
||||
close_player_menu_for_session_end()
|
||||
_fishing_shop.close_for_session_end()
|
||||
_fishing_panel.visible = false
|
||||
_shop_prompt.hide()
|
||||
_hotbar_ui.hide()
|
||||
_hotbar_ui.set_presentation_visible(false, false)
|
||||
_hotbar_ui.set_gameplay_input_enabled(false)
|
||||
else:
|
||||
_hotbar_ui.show()
|
||||
_refresh_hotbar_visibility()
|
||||
_hotbar_ui.set_gameplay_input_enabled(true)
|
||||
_refresh_fishing_panel_visibility()
|
||||
|
||||
|
|
@ -268,9 +275,7 @@ func set_gameplay_ui_enabled(enabled: bool) -> void:
|
|||
func set_system_menu_open(is_open: bool) -> void:
|
||||
_system_menu_open = is_open
|
||||
_refresh_chat_availability()
|
||||
_hotbar_ui.visible = (
|
||||
_gameplay_ui_enabled and not is_open and not _shop_open
|
||||
)
|
||||
_refresh_hotbar_visibility()
|
||||
_hotbar_ui.set_gameplay_input_enabled(
|
||||
_gameplay_ui_enabled
|
||||
and not is_open
|
||||
|
|
@ -495,24 +500,42 @@ func _on_showcase_changed(
|
|||
|
||||
func _on_player_menu_visibility_changed(is_open: bool) -> void:
|
||||
_player_menu_open = is_open
|
||||
_gameplay_transient_hud.visible = _gameplay_ui_enabled and not is_open
|
||||
if is_open:
|
||||
_hotbar_ui.set_presentation_visible(false, false)
|
||||
if _player_menu_hotbar_visible:
|
||||
_hotbar_ui.set_player_menu_context(true)
|
||||
_hotbar_ui.set_presentation_visible(true, true)
|
||||
else:
|
||||
_player_menu_hotbar_visible = false
|
||||
_hotbar_ui.set_presentation_visible(false, false)
|
||||
_hotbar_ui.set_player_menu_context(false)
|
||||
player_menu_backdrop_visibility_changed.emit(is_open)
|
||||
_refresh_chat_availability()
|
||||
_hotbar_ui.set_gameplay_input_enabled(
|
||||
_gameplay_ui_enabled and not is_open
|
||||
)
|
||||
_hotbar_ui.set_drag_enabled(is_open)
|
||||
_refresh_hotbar_visibility()
|
||||
_refresh_fishing_panel_visibility()
|
||||
_emit_interactive_pointer_ui_changed()
|
||||
if is_open:
|
||||
_shop_prompt.hide()
|
||||
else:
|
||||
_refresh_fishing_panel_visibility()
|
||||
|
||||
|
||||
func _on_player_menu_exit_started() -> void:
|
||||
if not _player_menu_open:
|
||||
return
|
||||
_hotbar_ui.set_drag_enabled(false)
|
||||
_hotbar_ui.set_presentation_visible(false, true)
|
||||
|
||||
|
||||
func _on_shop_visibility_changed(is_open: bool) -> void:
|
||||
_shop_open = is_open
|
||||
_refresh_chat_availability()
|
||||
_hotbar_ui.visible = (
|
||||
_gameplay_ui_enabled and not is_open and not _system_menu_open
|
||||
)
|
||||
_refresh_hotbar_visibility()
|
||||
_hotbar_ui.set_gameplay_input_enabled(
|
||||
_gameplay_ui_enabled
|
||||
and not is_open
|
||||
|
|
@ -524,6 +547,31 @@ func _on_shop_visibility_changed(is_open: bool) -> void:
|
|||
_emit_interactive_pointer_ui_changed()
|
||||
|
||||
|
||||
func _on_inventory_hotbar_context_changed(show_hotbar: bool) -> void:
|
||||
var context_changed: bool = _player_menu_hotbar_visible != show_hotbar
|
||||
_player_menu_hotbar_visible = show_hotbar
|
||||
if _player_menu_open and show_hotbar and context_changed:
|
||||
_hotbar_ui.set_presentation_visible(false, false)
|
||||
_hotbar_ui.set_player_menu_context(true)
|
||||
_hotbar_ui.set_drag_enabled(_player_menu_open and show_hotbar)
|
||||
if not context_changed:
|
||||
return
|
||||
_refresh_hotbar_visibility()
|
||||
|
||||
|
||||
func _refresh_hotbar_visibility() -> void:
|
||||
_hotbar_ui.set_presentation_visible(
|
||||
_gameplay_ui_enabled
|
||||
and not _system_menu_open
|
||||
and not _shop_open
|
||||
and (
|
||||
not _player_menu_open
|
||||
or _player_menu_hotbar_visible
|
||||
),
|
||||
_player_menu_open,
|
||||
)
|
||||
|
||||
|
||||
func _emit_interactive_pointer_ui_changed() -> void:
|
||||
interactive_pointer_ui_changed.emit(
|
||||
_system_menu_open or _player_menu_open or _shop_open
|
||||
|
|
|
|||
|
|
@ -41,7 +41,17 @@ script = ExtResource("1_ui")
|
|||
unique_name_in_owner = true
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="FishingPanel" type="PanelContainer" parent="UIRoot"]
|
||||
[node name="GameplayTransientHUD" type="Control" parent="UIRoot"]
|
||||
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
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="FishingPanel" type="PanelContainer" parent="UIRoot/GameplayTransientHUD"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
z_index = 60
|
||||
|
|
@ -59,33 +69,33 @@ grow_vertical = 0
|
|||
mouse_filter = 2
|
||||
theme = ExtResource("3_theme")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="UIRoot/FishingPanel"]
|
||||
[node name="MarginContainer" type="MarginContainer" parent="UIRoot/GameplayTransientHUD/FishingPanel"]
|
||||
theme_override_constants/margin_left = 14
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 14
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="UIRoot/FishingPanel/MarginContainer"]
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="UIRoot/GameplayTransientHUD/FishingPanel/MarginContainer"]
|
||||
theme_override_constants/separation = 4
|
||||
|
||||
[node name="StatusLabel" type="Label" parent="UIRoot/FishingPanel/MarginContainer/VBoxContainer"]
|
||||
[node name="StatusLabel" type="Label" parent="UIRoot/GameplayTransientHUD/FishingPanel/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
text = ""
|
||||
horizontal_alignment = 1
|
||||
theme_override_font_sizes/font_size = 16
|
||||
|
||||
[node name="ShowcaseDetails" type="Label" parent="UIRoot/FishingPanel/MarginContainer/VBoxContainer"]
|
||||
[node name="ShowcaseDetails" type="Label" parent="UIRoot/GameplayTransientHUD/FishingPanel/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="CatchTrack" type="Control" parent="UIRoot/FishingPanel/MarginContainer/VBoxContainer"]
|
||||
[node name="CatchTrack" type="Control" parent="UIRoot/GameplayTransientHUD/FishingPanel/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
custom_minimum_size = Vector2(0, 20)
|
||||
|
||||
[node name="GreenCatchProgress" type="ProgressBar" parent="UIRoot/FishingPanel/MarginContainer/VBoxContainer/CatchTrack"]
|
||||
[node name="GreenCatchProgress" type="ProgressBar" parent="UIRoot/GameplayTransientHUD/FishingPanel/MarginContainer/VBoxContainer/CatchTrack"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
|
|
@ -99,7 +109,7 @@ theme_override_styles/fill = SubResource("StyleBox_catch_fill")
|
|||
value = 0.0
|
||||
show_percentage = false
|
||||
|
||||
[node name="RedChaseProgress" type="ProgressBar" parent="UIRoot/FishingPanel/MarginContainer/VBoxContainer/CatchTrack"]
|
||||
[node name="RedChaseProgress" type="ProgressBar" parent="UIRoot/GameplayTransientHUD/FishingPanel/MarginContainer/VBoxContainer/CatchTrack"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
|
|
@ -113,7 +123,7 @@ theme_override_styles/fill = SubResource("StyleBox_chase_fill")
|
|||
value = 0.0
|
||||
show_percentage = false
|
||||
|
||||
[node name="BarrierMarkers" type="Control" parent="UIRoot/FishingPanel/MarginContainer/VBoxContainer/CatchTrack"]
|
||||
[node name="BarrierMarkers" type="Control" parent="UIRoot/GameplayTransientHUD/FishingPanel/MarginContainer/VBoxContainer/CatchTrack"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
|
|
@ -123,12 +133,12 @@ grow_horizontal = 2
|
|||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="BarrierSummary" type="Label" parent="UIRoot/FishingPanel/MarginContainer/VBoxContainer"]
|
||||
[node name="BarrierSummary" type="Label" parent="UIRoot/GameplayTransientHUD/FishingPanel/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="BarrierHealth" type="Label" parent="UIRoot/FishingPanel/MarginContainer/VBoxContainer"]
|
||||
[node name="BarrierHealth" type="Label" parent="UIRoot/GameplayTransientHUD/FishingPanel/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
horizontal_alignment = 1
|
||||
|
|
@ -139,7 +149,7 @@ unique_name_in_owner = true
|
|||
[node name="Hotbar" parent="UIRoot" instance=ExtResource("7_hotbar")]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[node name="ShopPrompt" type="PanelContainer" parent="UIRoot"]
|
||||
[node name="ShopPrompt" type="PanelContainer" parent="UIRoot/GameplayTransientHUD"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
z_index = 55
|
||||
|
|
@ -157,14 +167,14 @@ grow_vertical = 0
|
|||
mouse_filter = 2
|
||||
theme = ExtResource("3_theme")
|
||||
|
||||
[node name="Margin" type="MarginContainer" parent="UIRoot/ShopPrompt"]
|
||||
[node name="Margin" type="MarginContainer" parent="UIRoot/GameplayTransientHUD/ShopPrompt"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 12
|
||||
theme_override_constants/margin_top = 7
|
||||
theme_override_constants/margin_right = 12
|
||||
theme_override_constants/margin_bottom = 7
|
||||
|
||||
[node name="Label" type="Label" parent="UIRoot/ShopPrompt/Margin"]
|
||||
[node name="Label" type="Label" parent="UIRoot/GameplayTransientHUD/ShopPrompt/Margin"]
|
||||
layout_mode = 2
|
||||
text = "press e to open fishing shop"
|
||||
horizontal_alignment = 1
|
||||
|
|
@ -172,7 +182,7 @@ horizontal_alignment = 1
|
|||
[node name="FishingShop" parent="UIRoot" instance=ExtResource("8_shop")]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[node name="EffectStatus" type="Label" parent="UIRoot"]
|
||||
[node name="EffectStatus" type="Label" parent="UIRoot/GameplayTransientHUD"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
z_index = 54
|
||||
|
|
|
|||
61
ui/hotbar.gd
61
ui/hotbar.gd
|
|
@ -13,6 +13,7 @@ const DESKTOP_REFERENCE_SIZE := Vector2(1280.0, 720.0)
|
|||
const COMPACT_REFERENCE_SIZE := Vector2(640.0, 480.0)
|
||||
const HOTBAR_PRESENTATION_SCALE: float = 0.60
|
||||
const HOTBAR_CANONICAL_POSITION := Vector2(256.0, 288.0)
|
||||
const HOTBAR_MENU_POSITION := Vector2(80.0, 198.0)
|
||||
|
||||
@onready var _presentation_scale_root: Control = %HotbarPresentationScaleRoot
|
||||
@onready var _bubble_field: Control = %BubbleField
|
||||
|
|
@ -30,6 +31,9 @@ var _hovered_slot_index: int = -1
|
|||
var _item_name_suppressed: bool = false
|
||||
var _motion_elapsed: float = 0.0
|
||||
var _compact_layout: bool = false
|
||||
var _player_menu_context: bool = false
|
||||
var _visibility_tween: Tween
|
||||
var _visibility_generation: int = 0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
|
@ -82,6 +86,57 @@ func set_drag_enabled(enabled: bool) -> void:
|
|||
_hide_item_name()
|
||||
|
||||
|
||||
func set_player_menu_context(enabled: bool) -> void:
|
||||
if _player_menu_context == enabled:
|
||||
return
|
||||
_player_menu_context = enabled
|
||||
_presentation_scale_root.position = (
|
||||
HOTBAR_MENU_POSITION if enabled else HOTBAR_CANONICAL_POSITION
|
||||
)
|
||||
|
||||
|
||||
func set_presentation_visible(should_show: bool, animate: bool = true) -> void:
|
||||
_visibility_generation += 1
|
||||
var generation: int = _visibility_generation
|
||||
if _visibility_tween != null:
|
||||
_visibility_tween.kill()
|
||||
_visibility_tween = null
|
||||
if should_show:
|
||||
visible = true
|
||||
if not animate:
|
||||
modulate.a = 1.0
|
||||
return
|
||||
_visibility_tween = create_tween()
|
||||
_visibility_tween.tween_property(
|
||||
self,
|
||||
"modulate:a",
|
||||
1.0,
|
||||
UIMotion.UTILITY_ENTER_DURATION,
|
||||
)
|
||||
else:
|
||||
if not visible:
|
||||
return
|
||||
if not animate:
|
||||
visible = false
|
||||
modulate.a = 1.0
|
||||
return
|
||||
_visibility_tween = create_tween()
|
||||
_visibility_tween.tween_property(
|
||||
self,
|
||||
"modulate:a",
|
||||
0.0,
|
||||
UIMotion.UTILITY_EXIT_DURATION,
|
||||
)
|
||||
_visibility_tween.finished.connect(
|
||||
func() -> void:
|
||||
if generation != _visibility_generation:
|
||||
return
|
||||
visible = false
|
||||
modulate.a = 1.0
|
||||
_visibility_tween = null
|
||||
)
|
||||
|
||||
|
||||
func set_item_name_suppressed(suppressed: bool) -> void:
|
||||
_item_name_suppressed = suppressed
|
||||
if suppressed:
|
||||
|
|
@ -145,7 +200,11 @@ func _apply_layout() -> void:
|
|||
_presentation_scale_root.scale = (
|
||||
Vector2.ONE * HOTBAR_PRESENTATION_SCALE
|
||||
)
|
||||
_presentation_scale_root.position = HOTBAR_CANONICAL_POSITION
|
||||
_presentation_scale_root.position = (
|
||||
HOTBAR_MENU_POSITION
|
||||
if _player_menu_context
|
||||
else HOTBAR_CANONICAL_POSITION
|
||||
)
|
||||
var field_size := (
|
||||
Vector2(580.0, 82.0)
|
||||
if _compact_layout
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
[node name="Hotbar" type="Control"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
z_index = 20
|
||||
z_index = 35
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ func set_interactive(value: bool) -> void:
|
|||
func _build_ui() -> void:
|
||||
var paper := PanelContainer.new()
|
||||
paper.position = Vector2(116, 126)
|
||||
paper.size = Vector2(1048, 470)
|
||||
paper.size = Vector2(1048, 540)
|
||||
paper.add_theme_stylebox_override("panel", UtilityPageStyle.panel_style())
|
||||
add_child(paper)
|
||||
var margin := MarginContainer.new()
|
||||
|
|
@ -128,7 +128,7 @@ func _build_ui() -> void:
|
|||
page.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
root.add_child(page)
|
||||
_status = Label.new()
|
||||
_status.position = Vector2(18, 430)
|
||||
_status.position = Vector2(18, 448)
|
||||
_status.size = Vector2(900, 28)
|
||||
_status.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
_status.add_theme_color_override("font_color", Color("4a3f31"))
|
||||
|
|
@ -163,7 +163,7 @@ func _build_inbox() -> Control:
|
|||
page.add_child(archive_view)
|
||||
var scroll := ScrollContainer.new()
|
||||
scroll.position = Vector2(12, 62)
|
||||
scroll.size = Vector2(958, 342)
|
||||
scroll.size = Vector2(958, 374)
|
||||
page.add_child(scroll)
|
||||
_inbox_list = VBoxContainer.new()
|
||||
_inbox_list.custom_minimum_size = Vector2(930, 0)
|
||||
|
|
|
|||
|
|
@ -79,16 +79,29 @@ const COOLER_RARITY_EPIC := Color("a979cf")
|
|||
const COOLER_RARITY_LEGENDARY := Color("db78a7")
|
||||
|
||||
signal menu_visibility_changed(is_open: bool)
|
||||
signal inventory_hotbar_context_changed(show_hotbar: bool)
|
||||
signal menu_exit_started
|
||||
|
||||
enum Section {
|
||||
COOLER,
|
||||
BAG,
|
||||
TACKLE_BOX,
|
||||
LOGBOOK,
|
||||
MAIL,
|
||||
PROFILE,
|
||||
PLAYERS,
|
||||
}
|
||||
|
||||
enum BagView {
|
||||
EQUIPMENT,
|
||||
CONSUMABLES,
|
||||
}
|
||||
|
||||
enum TackleView {
|
||||
BAIT,
|
||||
LURES,
|
||||
}
|
||||
|
||||
enum SortMode {
|
||||
CATCH_ORDER,
|
||||
NAME,
|
||||
|
|
@ -142,6 +155,21 @@ enum CloseReason {
|
|||
@onready var _favorite_bubble: NotepadInkActionType = %FavoriteBubble
|
||||
@onready var _sell_bubble: NotepadInkActionType = %SellBubble
|
||||
@onready var _bag_page: Control = %BagPage
|
||||
@onready var _tackle_box_page: Control = %TackleBoxPage
|
||||
@onready var _inventory_sub_tabs: HBoxContainer = %InventorySubTabs
|
||||
@onready var _cooler_sub_tab: Button = %CoolerSubTab
|
||||
@onready var _bag_sub_tab: Button = %BagSubTab
|
||||
@onready var _tackle_sub_tab: Button = %TackleSubTab
|
||||
@onready var _bag_filter_tabs: HBoxContainer = %BagFilterTabs
|
||||
@onready var _equipment_filter: Button = %EquipmentFilter
|
||||
@onready var _consumables_filter: Button = %ConsumablesFilter
|
||||
@onready var _tackle_main_panel: PanelContainer = %TackleMainPanel
|
||||
@onready var _tackle_detail_panel: PanelContainer = %TackleDetailPanel
|
||||
@onready var _bait_filter: Button = %BaitFilter
|
||||
@onready var _lures_filter: Button = %LuresFilter
|
||||
@onready var _tackle_empty: Label = %TackleEmpty
|
||||
@onready var _tackle_detail_text: Label = %TackleDetailText
|
||||
@onready var _tackle_item_list: VBoxContainer = %TackleItemList
|
||||
@onready var _bag_outer_wall: PanelContainer = %BagOuterWall
|
||||
@onready var _bag_inner_liner: PanelContainer = %BagInnerLiner
|
||||
@onready var _bag_scroll: ScrollContainer = %BagScroll
|
||||
|
|
@ -171,7 +199,6 @@ enum CloseReason {
|
|||
@onready var _logbook_next: BubbleButtonType = %LogbookNext
|
||||
@onready var _logbook_page_status: BubbleStatusBubbleType = %LogbookPageStatus
|
||||
@onready var _inventory_tab: BubbleButtonType = %InventoryTab
|
||||
@onready var _bag_tab: BubbleButtonType = %BagTab
|
||||
@onready var _logbook_tab: BubbleButtonType = %LogbookTab
|
||||
@onready var _mail_tab: BubbleButtonType = %MailTab
|
||||
@onready var _profile_tab: BubbleButtonType = %ProfileTab
|
||||
|
|
@ -240,6 +267,10 @@ var _hotbar: PlayerHotbarType
|
|||
var _item_catalog: ItemCatalogType
|
||||
var _cooler_capacity: PlayerCoolerCapacityType
|
||||
var _current_section: Section = Section.COOLER
|
||||
var _last_inventory_section: Section = Section.COOLER
|
||||
var _bag_view: BagView = BagView.EQUIPMENT
|
||||
var _tackle_view: TackleView = TackleView.BAIT
|
||||
var _selected_tackle_item_id: StringName
|
||||
var _sort_mode: SortMode = SortMode.CATCH_ORDER
|
||||
var _sort_descending: bool = true
|
||||
var _fish_selection := FishBatchSelectionType.new()
|
||||
|
|
@ -265,6 +296,7 @@ var _presentation_rest_position: Vector2 = Vector2.ZERO
|
|||
var _content_rest_position: Vector2 = Vector2.ZERO
|
||||
var _cooler_rest_position: Vector2 = Vector2.ZERO
|
||||
var _bag_rest_position: Vector2 = Vector2.ZERO
|
||||
var _tackle_rest_position: Vector2 = Vector2.ZERO
|
||||
var _logbook_rest_position: Vector2 = Vector2.ZERO
|
||||
var _mail_rest_position: Vector2 = Vector2.ZERO
|
||||
var _profile_rest_position: Vector2 = Vector2.ZERO
|
||||
|
|
@ -286,10 +318,16 @@ var _logbook_page_tween: Tween
|
|||
|
||||
|
||||
func _ready() -> void:
|
||||
_inventory_tab.pressed.connect(
|
||||
_show_section.bind(Section.COOLER)
|
||||
_inventory_tab.pressed.connect(_show_last_inventory_section)
|
||||
_cooler_sub_tab.pressed.connect(_show_section.bind(Section.COOLER))
|
||||
_bag_sub_tab.pressed.connect(_show_section.bind(Section.BAG))
|
||||
_tackle_sub_tab.pressed.connect(_show_section.bind(Section.TACKLE_BOX))
|
||||
_equipment_filter.pressed.connect(_set_bag_view.bind(BagView.EQUIPMENT))
|
||||
_consumables_filter.pressed.connect(
|
||||
_set_bag_view.bind(BagView.CONSUMABLES)
|
||||
)
|
||||
_bag_tab.pressed.connect(_show_section.bind(Section.BAG))
|
||||
_bait_filter.pressed.connect(_set_tackle_view.bind(TackleView.BAIT))
|
||||
_lures_filter.pressed.connect(_set_tackle_view.bind(TackleView.LURES))
|
||||
_logbook_tab.pressed.connect(
|
||||
_show_section.bind(Section.LOGBOOK)
|
||||
)
|
||||
|
|
@ -319,7 +357,6 @@ func _ready() -> void:
|
|||
_update_sort_direction_text()
|
||||
_navigation_cluster.configure([
|
||||
_inventory_tab,
|
||||
_bag_tab,
|
||||
_logbook_tab,
|
||||
_mail_tab,
|
||||
_profile_tab,
|
||||
|
|
@ -328,6 +365,10 @@ func _ready() -> void:
|
|||
])
|
||||
_configure_navigation_focus()
|
||||
_apply_navigation_styles()
|
||||
_apply_inventory_styles()
|
||||
# Full-page Inventory controls are later siblings and otherwise win GUI
|
||||
# picking over the tab row even though the tabs draw above them.
|
||||
_inventory_sub_tabs.move_to_front()
|
||||
_apply_cooler_control_styles()
|
||||
_apply_cooler_wall_styles()
|
||||
_apply_cooler_notepad_style()
|
||||
|
|
@ -442,6 +483,8 @@ func setup(
|
|||
_fishing_spot.bite_activated.connect(_on_bite_activated)
|
||||
if not _bag.contents_changed.is_connected(_on_bag_changed):
|
||||
_bag.contents_changed.connect(_on_bag_changed)
|
||||
if not _hotbar.slots_changed.is_connected(_on_hotbar_changed):
|
||||
_hotbar.slots_changed.connect(_on_hotbar_changed)
|
||||
if not _cooler_capacity.capacity_changed.is_connected(
|
||||
_on_cooler_capacity_changed
|
||||
):
|
||||
|
|
@ -452,6 +495,9 @@ func setup(
|
|||
func _input(event: InputEvent) -> void:
|
||||
if event is InputEventKey and event.echo:
|
||||
return
|
||||
if _handle_inventory_shortcut(event):
|
||||
get_viewport().set_input_as_handled()
|
||||
return
|
||||
if visible:
|
||||
if event.is_action_pressed("open_backpack"):
|
||||
if not _transitioning and not _page_transitioning:
|
||||
|
|
@ -467,6 +513,54 @@ func _input(event: InputEvent) -> void:
|
|||
get_viewport().set_input_as_handled()
|
||||
|
||||
|
||||
func _handle_inventory_shortcut(event: InputEvent) -> bool:
|
||||
var key_event := event as InputEventKey
|
||||
if (
|
||||
key_event == null
|
||||
or not key_event.pressed
|
||||
or _is_text_input_active()
|
||||
):
|
||||
return false
|
||||
var physical_key: Key = key_event.physical_keycode
|
||||
var inventory_requested: bool = physical_key == KEY_I
|
||||
var tackle_requested: bool = (
|
||||
physical_key == KEY_V
|
||||
or event.is_action_pressed("open_tacklebox")
|
||||
)
|
||||
if not inventory_requested and not tackle_requested:
|
||||
return false
|
||||
var requested_section: Section = (
|
||||
Section.TACKLE_BOX if tackle_requested else _last_inventory_section
|
||||
)
|
||||
if visible:
|
||||
if (
|
||||
_current_section == requested_section
|
||||
and not _transitioning
|
||||
and not _page_transitioning
|
||||
):
|
||||
close_menu()
|
||||
elif not _transitioning and not _page_transitioning:
|
||||
_show_section(requested_section)
|
||||
else:
|
||||
if (
|
||||
_fishing_spot == null
|
||||
or not _fishing_spot.can_open_player_menu()
|
||||
):
|
||||
return false
|
||||
_current_section = requested_section
|
||||
open_menu()
|
||||
return true
|
||||
|
||||
|
||||
func _is_text_input_active() -> bool:
|
||||
var focus_owner: Control = get_viewport().gui_get_focus_owner()
|
||||
return (
|
||||
focus_owner != null
|
||||
and focus_owner.is_visible_in_tree()
|
||||
and (focus_owner is LineEdit or focus_owner is TextEdit)
|
||||
)
|
||||
|
||||
|
||||
func consume_escape() -> bool:
|
||||
if not visible:
|
||||
return false
|
||||
|
|
@ -537,6 +631,7 @@ func close_menu(
|
|||
CloseReason.TEARDOWN,
|
||||
]:
|
||||
_fish_selection.clear()
|
||||
menu_exit_started.emit()
|
||||
_begin_menu_exit(reason, restore_controls)
|
||||
|
||||
|
||||
|
|
@ -618,11 +713,15 @@ func _show_section(section: Section) -> void:
|
|||
|
||||
func _show_section_immediate(section: Section) -> void:
|
||||
_current_section = section
|
||||
if _is_inventory_section(section):
|
||||
_last_inventory_section = section
|
||||
if not is_node_ready():
|
||||
return
|
||||
_configure_navigation_focus()
|
||||
_cooler_page.visible = section == Section.COOLER
|
||||
_bag_page.visible = section == Section.BAG
|
||||
_tackle_box_page.visible = section == Section.TACKLE_BOX
|
||||
_inventory_sub_tabs.visible = _is_inventory_section(section)
|
||||
_logbook_page.visible = section == Section.LOGBOOK
|
||||
_mail_page.visible = section == Section.MAIL
|
||||
_profile_page.visible = section == Section.PROFILE
|
||||
|
|
@ -643,6 +742,7 @@ func _show_section_immediate(section: Section) -> void:
|
|||
_close_bag_detail()
|
||||
else:
|
||||
_update_bag_detail()
|
||||
_refresh_tackle_box()
|
||||
if section != Section.LOGBOOK:
|
||||
_cancel_logbook_page_transition(true)
|
||||
if section == Section.MAIL:
|
||||
|
|
@ -657,21 +757,36 @@ func _show_section_immediate(section: Section) -> void:
|
|||
_players_page.activate()
|
||||
else:
|
||||
_players_page.deactivate()
|
||||
_inventory_tab.button_pressed = section == Section.COOLER
|
||||
_bag_tab.button_pressed = section == Section.BAG
|
||||
_inventory_tab.button_pressed = _is_inventory_section(section)
|
||||
_cooler_sub_tab.button_pressed = section == Section.COOLER
|
||||
_bag_sub_tab.button_pressed = section == Section.BAG
|
||||
_tackle_sub_tab.button_pressed = section == Section.TACKLE_BOX
|
||||
_logbook_tab.button_pressed = section == Section.LOGBOOK
|
||||
_mail_tab.button_pressed = section == Section.MAIL
|
||||
_profile_tab.button_pressed = section == Section.PROFILE
|
||||
_players_tab.button_pressed = section == Section.PLAYERS
|
||||
_update_navigation_selection()
|
||||
_configure_active_page_focus()
|
||||
inventory_hotbar_context_changed.emit(
|
||||
section in [Section.COOLER, Section.BAG]
|
||||
)
|
||||
|
||||
|
||||
func _is_inventory_section(section: Section) -> bool:
|
||||
return section in [Section.COOLER, Section.BAG, Section.TACKLE_BOX]
|
||||
|
||||
|
||||
func _show_last_inventory_section() -> void:
|
||||
_show_section(_last_inventory_section)
|
||||
|
||||
|
||||
func _focus_current_section() -> void:
|
||||
if _current_section == Section.COOLER:
|
||||
_inventory_tab.grab_focus()
|
||||
_cooler_sub_tab.grab_focus()
|
||||
elif _current_section == Section.BAG:
|
||||
_bag_tab.grab_focus()
|
||||
_bag_sub_tab.grab_focus()
|
||||
elif _current_section == Section.TACKLE_BOX:
|
||||
_tackle_sub_tab.grab_focus()
|
||||
elif _current_section == Section.LOGBOOK:
|
||||
_logbook_tab.grab_focus()
|
||||
elif _current_section == Section.MAIL:
|
||||
|
|
@ -704,7 +819,6 @@ func _process(delta: float) -> void:
|
|||
func _configure_navigation_focus() -> void:
|
||||
var navigation: Array[BubbleButtonType] = [
|
||||
_inventory_tab,
|
||||
_bag_tab,
|
||||
_logbook_tab,
|
||||
_mail_tab,
|
||||
_profile_tab,
|
||||
|
|
@ -723,6 +837,26 @@ func _configure_navigation_focus() -> void:
|
|||
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
|
||||
var inventory_tabs: Array[Button] = [
|
||||
_cooler_sub_tab,
|
||||
_bag_sub_tab,
|
||||
_tackle_sub_tab,
|
||||
]
|
||||
for index: int in inventory_tabs.size():
|
||||
var tab: Button = inventory_tabs[index]
|
||||
tab.focus_neighbor_left = tab.get_path_to(
|
||||
inventory_tabs[maxi(index - 1, 0)]
|
||||
)
|
||||
tab.focus_neighbor_right = tab.get_path_to(
|
||||
inventory_tabs[mini(index + 1, inventory_tabs.size() - 1)]
|
||||
)
|
||||
tab.focus_neighbor_top = tab.get_path_to(_inventory_tab)
|
||||
_inventory_tab.focus_neighbor_bottom = _inventory_tab.get_path_to(
|
||||
inventory_tabs[int(_last_inventory_section)]
|
||||
)
|
||||
_tackle_sub_tab.focus_neighbor_bottom = _tackle_sub_tab.get_path_to(
|
||||
_bait_filter
|
||||
)
|
||||
|
||||
|
||||
func _configure_sale_confirmation_focus() -> void:
|
||||
|
|
@ -762,6 +896,8 @@ func _configure_active_page_focus() -> void:
|
|||
_configure_cooler_fish_focus()
|
||||
Section.BAG:
|
||||
_configure_bag_item_focus()
|
||||
Section.TACKLE_BOX:
|
||||
_bait_filter.grab_focus()
|
||||
Section.LOGBOOK:
|
||||
_configure_logbook_focus()
|
||||
Section.MAIL:
|
||||
|
|
@ -770,6 +906,132 @@ func _configure_active_page_focus() -> void:
|
|||
_profile_page.activate()
|
||||
|
||||
|
||||
func _apply_inventory_styles() -> void:
|
||||
for button: Button in [
|
||||
_cooler_sub_tab,
|
||||
_bag_sub_tab,
|
||||
_tackle_sub_tab,
|
||||
_equipment_filter,
|
||||
_consumables_filter,
|
||||
_bait_filter,
|
||||
_lures_filter,
|
||||
]:
|
||||
UtilityPageStyle.apply_button(button)
|
||||
for panel: PanelContainer in [_tackle_main_panel, _tackle_detail_panel]:
|
||||
panel.add_theme_stylebox_override(
|
||||
"panel",
|
||||
UtilityPageStyle.panel_style(),
|
||||
)
|
||||
for label: Label in [_tackle_empty, _tackle_detail_text]:
|
||||
label.add_theme_font_override("font", UtilityPageStyle.TuffyFont)
|
||||
label.add_theme_color_override(
|
||||
"font_color",
|
||||
UtilityPageStyle.INK,
|
||||
)
|
||||
|
||||
|
||||
func _set_bag_view(view: BagView) -> void:
|
||||
if _bag_view == view:
|
||||
return
|
||||
_bag_view = view
|
||||
_selected_bag_item_id = StringName()
|
||||
_refresh_bag()
|
||||
|
||||
|
||||
func _set_tackle_view(view: TackleView) -> void:
|
||||
_tackle_view = view
|
||||
_selected_tackle_item_id = StringName()
|
||||
_refresh_tackle_box()
|
||||
|
||||
|
||||
func _refresh_tackle_box() -> void:
|
||||
if not is_node_ready():
|
||||
return
|
||||
_bait_filter.button_pressed = _tackle_view == TackleView.BAIT
|
||||
_lures_filter.button_pressed = _tackle_view == TackleView.LURES
|
||||
for child: Node in _tackle_item_list.get_children():
|
||||
child.queue_free()
|
||||
var matching_items: Array[OwnedItemType] = []
|
||||
if _bag != null and _item_catalog != null:
|
||||
for owned: OwnedItemType in _bag.get_all_items():
|
||||
var item: ItemDataType = _item_catalog.get_item_by_id(
|
||||
owned.item_id
|
||||
)
|
||||
if item == null:
|
||||
continue
|
||||
if (
|
||||
_tackle_view == TackleView.BAIT
|
||||
and item.category == ItemDataType.Category.BAIT
|
||||
):
|
||||
matching_items.append(owned)
|
||||
elif (
|
||||
_tackle_view == TackleView.LURES
|
||||
and item.category == ItemDataType.Category.LURE
|
||||
):
|
||||
matching_items.append(owned)
|
||||
matching_items.sort_custom(_sort_bag_items)
|
||||
for owned: OwnedItemType in matching_items:
|
||||
var item: ItemDataType = _item_catalog.get_item_by_id(owned.item_id)
|
||||
var row := Button.new()
|
||||
row.text = "%s ×%d" % [item.display_name, owned.quantity]
|
||||
row.icon = item.icon
|
||||
row.alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||
row.toggle_mode = true
|
||||
row.button_pressed = owned.item_id == _selected_tackle_item_id
|
||||
UtilityPageStyle.apply_button(row)
|
||||
row.pressed.connect(_select_tackle_item.bind(owned.item_id))
|
||||
_tackle_item_list.add_child(row)
|
||||
_tackle_empty.text = (
|
||||
"No bait collected."
|
||||
if _tackle_view == TackleView.BAIT
|
||||
else "No lures collected."
|
||||
)
|
||||
_tackle_empty.visible = matching_items.is_empty()
|
||||
_update_tackle_detail()
|
||||
|
||||
|
||||
func _select_tackle_item(item_id: StringName) -> void:
|
||||
_selected_tackle_item_id = item_id
|
||||
_refresh_tackle_box()
|
||||
|
||||
|
||||
func _update_tackle_detail() -> void:
|
||||
var item: ItemDataType = (
|
||||
_item_catalog.get_item_by_id(_selected_tackle_item_id)
|
||||
if _item_catalog != null and not _selected_tackle_item_id.is_empty()
|
||||
else null
|
||||
)
|
||||
if item == null:
|
||||
_tackle_detail_text.text = (
|
||||
"Select bait for details."
|
||||
if _tackle_view == TackleView.BAIT
|
||||
else "Select a lure for details."
|
||||
)
|
||||
return
|
||||
var quantity: int = _bag.get_quantity(item.item_id) if _bag != null else 0
|
||||
var assigned_slot: int = -1
|
||||
if _hotbar != null:
|
||||
for slot_index: int in range(PlayerHotbarType.SLOT_COUNT):
|
||||
if _hotbar.get_item_id(slot_index) == item.item_id:
|
||||
assigned_slot = slot_index
|
||||
break
|
||||
var state_text: String = (
|
||||
"hotbar slot %d" % (assigned_slot + 1)
|
||||
if assigned_slot >= 0
|
||||
else "not assigned"
|
||||
)
|
||||
_tackle_detail_text.text = (
|
||||
"%s\n\nType: %s\nQuantity: %d\n%s\n\n%s"
|
||||
% [
|
||||
item.display_name,
|
||||
item.get_category_name(),
|
||||
quantity,
|
||||
state_text,
|
||||
item.description,
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
func _apply_cooler_control_styles() -> void:
|
||||
var profile: BubbleMenuProfile = _inventory_tab.profile
|
||||
if profile == null:
|
||||
|
|
@ -858,7 +1120,6 @@ func _apply_navigation_styles() -> void:
|
|||
var disabled := _make_navigation_style(profile.disabled_fill, 1, 0.14)
|
||||
for bubble: BubbleButtonType in [
|
||||
_inventory_tab,
|
||||
_bag_tab,
|
||||
_logbook_tab,
|
||||
_mail_tab,
|
||||
_profile_tab,
|
||||
|
|
@ -890,7 +1151,6 @@ func _make_navigation_style(
|
|||
func _apply_navigation_selection_presentation() -> void:
|
||||
for bubble: BubbleButtonType in [
|
||||
_inventory_tab,
|
||||
_bag_tab,
|
||||
_logbook_tab,
|
||||
_mail_tab,
|
||||
_profile_tab,
|
||||
|
|
@ -998,8 +1258,7 @@ func _on_mail_unread_count_changed(count: int) -> void:
|
|||
|
||||
|
||||
func _set_navigation_target(section: Section) -> void:
|
||||
_inventory_tab.button_pressed = section == Section.COOLER
|
||||
_bag_tab.button_pressed = section == Section.BAG
|
||||
_inventory_tab.button_pressed = _is_inventory_section(section)
|
||||
_logbook_tab.button_pressed = section == Section.LOGBOOK
|
||||
_mail_tab.button_pressed = section == Section.MAIL
|
||||
_profile_tab.button_pressed = section == Section.PROFILE
|
||||
|
|
@ -1033,16 +1292,16 @@ func _update_shell_layout() -> void:
|
|||
_cooler_rest_position = Vector2.ZERO
|
||||
_layout_cooler_fish(false)
|
||||
_cooler_outer_wall.position = (
|
||||
Vector2(14.0, 154.0) if compact else Vector2(54.0, 126.0)
|
||||
Vector2(14.0, 154.0) if compact else Vector2(54.0, 166.0)
|
||||
)
|
||||
_cooler_outer_wall.size = (
|
||||
Vector2(300.0, 206.0) if compact else Vector2(866.0, 476.0)
|
||||
Vector2(300.0, 218.0) if compact else Vector2(882.0, 484.0)
|
||||
)
|
||||
_detail_constellation.position = (
|
||||
Vector2(320.0, 154.0) if compact else Vector2(942.0, 126.0)
|
||||
Vector2(320.0, 154.0) if compact else Vector2(952.0, 166.0)
|
||||
)
|
||||
_detail_constellation.size = (
|
||||
Vector2(306.0, 196.0) if compact else Vector2(288.0, 476.0)
|
||||
Vector2(306.0, 196.0) if compact else Vector2(278.0, 436.0)
|
||||
)
|
||||
_notepad_binding.position = Vector2(44.0, 1.0) if compact else Vector2(28.0, 4.0)
|
||||
_notepad_binding.size = Vector2(218.0, 20.0) if compact else Vector2(232.0, 27.0)
|
||||
|
|
@ -1126,13 +1385,13 @@ func _update_shell_layout() -> void:
|
|||
Vector2(74.0, 42.0) if compact else Vector2(118.0, 50.0)
|
||||
)
|
||||
_favorite_bubble.position = (
|
||||
Vector2(144.0, 148.0) if compact else Vector2(26.0, 400.0)
|
||||
Vector2(144.0, 148.0) if compact else Vector2(26.0, 378.0)
|
||||
)
|
||||
_favorite_bubble.size = (
|
||||
Vector2(72.0, 42.0) if compact else Vector2(108.0, 50.0)
|
||||
)
|
||||
_sell_bubble.position = (
|
||||
Vector2(222.0, 148.0) if compact else Vector2(144.0, 400.0)
|
||||
Vector2(222.0, 148.0) if compact else Vector2(144.0, 378.0)
|
||||
)
|
||||
_sell_bubble.size = (
|
||||
Vector2(74.0, 42.0) if compact else Vector2(118.0, 50.0)
|
||||
|
|
@ -1147,27 +1406,30 @@ func _update_shell_layout() -> void:
|
|||
_bag_page.size = reference_size
|
||||
_bag_page.position = Vector2.ZERO
|
||||
_bag_rest_position = Vector2.ZERO
|
||||
_tackle_box_page.size = reference_size
|
||||
_tackle_box_page.position = Vector2.ZERO
|
||||
_tackle_rest_position = Vector2.ZERO
|
||||
_bag_outer_wall.position = (
|
||||
Vector2(14.0, 170.0) if compact else Vector2(122.0, 132.0)
|
||||
Vector2(14.0, 170.0) if compact else Vector2(54.0, 214.0)
|
||||
)
|
||||
_bag_outer_wall.size = (
|
||||
Vector2(612.0, 200.0) if compact else Vector2(896.0, 442.0)
|
||||
Vector2(612.0, 212.0) if compact else Vector2(882.0, 436.0)
|
||||
)
|
||||
_bag_host.custom_minimum_size = (
|
||||
Vector2(520.0, 140.0) if compact else Vector2(820.0, 350.0)
|
||||
Vector2(520.0, 152.0) if compact else Vector2(820.0, 380.0)
|
||||
)
|
||||
_bag_scroll.vertical_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
|
||||
_bag_detail_constellation.position = (
|
||||
Vector2.ZERO if compact else Vector2(984.0, 266.0)
|
||||
Vector2.ZERO if compact else Vector2(952.0, 166.0)
|
||||
)
|
||||
_bag_detail_constellation.size = (
|
||||
Vector2(640.0, 390.0) if compact else Vector2(272.0, 304.0)
|
||||
Vector2(640.0, 390.0) if compact else Vector2(278.0, 436.0)
|
||||
)
|
||||
_bag_sprite_detail_bubble.position = (
|
||||
Vector2(170.0, 164.0) if compact else Vector2.ZERO
|
||||
)
|
||||
_bag_sprite_detail_bubble.size = (
|
||||
Vector2(300.0, 188.0) if compact else Vector2(272.0, 304.0)
|
||||
Vector2(300.0, 188.0) if compact else Vector2(278.0, 436.0)
|
||||
)
|
||||
_bag_sprite_detail_texture.custom_minimum_size = (
|
||||
Vector2(72.0, 48.0) if compact else Vector2(100.0, 72.0)
|
||||
|
|
@ -1180,6 +1442,18 @@ func _update_shell_layout() -> void:
|
|||
"font_size",
|
||||
12 if compact else 15,
|
||||
)
|
||||
_tackle_main_panel.position = (
|
||||
Vector2(14.0, 154.0) if compact else Vector2(54.0, 166.0)
|
||||
)
|
||||
_tackle_main_panel.size = (
|
||||
Vector2(418.0, 218.0) if compact else Vector2(882.0, 484.0)
|
||||
)
|
||||
_tackle_detail_panel.position = (
|
||||
Vector2(438.0, 154.0) if compact else Vector2(952.0, 166.0)
|
||||
)
|
||||
_tackle_detail_panel.size = (
|
||||
Vector2(188.0, 218.0) if compact else Vector2(278.0, 484.0)
|
||||
)
|
||||
_logbook_page.size = reference_size
|
||||
_logbook_page.position = Vector2.ZERO
|
||||
_logbook_rest_position = Vector2.ZERO
|
||||
|
|
@ -1191,11 +1465,14 @@ func _update_shell_layout() -> void:
|
|||
_profile_page.position = Vector2(42.0, 104.0)
|
||||
_profile_page.size = Vector2(1196.0, 608.0)
|
||||
_profile_rest_position = _profile_page.position
|
||||
_players_page.set_anchors_preset(Control.PRESET_TOP_LEFT)
|
||||
_players_page.position = Vector2.ZERO
|
||||
_players_page.size = reference_size
|
||||
_book_backing.position = (
|
||||
Vector2(14.0, 164.0) if compact else Vector2(58.0, 128.0)
|
||||
)
|
||||
_book_backing.size = (
|
||||
Vector2(612.0, 210.0) if compact else Vector2(1164.0, 460.0)
|
||||
Vector2(612.0, 232.0) if compact else Vector2(1164.0, 522.0)
|
||||
)
|
||||
_right_page.visible = not compact
|
||||
_book_gutter.visible = not compact
|
||||
|
|
@ -1214,17 +1491,17 @@ func _update_shell_layout() -> void:
|
|||
Vector2(400.0, 52.0) if compact else Vector2(476.0, 52.0)
|
||||
)
|
||||
_logbook_previous.apply_layout(
|
||||
Vector2(58.0, 310.0) if compact else Vector2(116.0, 530.0),
|
||||
Vector2(58.0, 332.0) if compact else Vector2(116.0, 622.0),
|
||||
Vector2(66.0, 62.0) if compact else Vector2(76.0, 72.0),
|
||||
0.18,
|
||||
)
|
||||
_logbook_next.apply_layout(
|
||||
Vector2(582.0, 310.0) if compact else Vector2(1164.0, 530.0),
|
||||
Vector2(582.0, 332.0) if compact else Vector2(1164.0, 622.0),
|
||||
Vector2(66.0, 62.0) if compact else Vector2(76.0, 72.0),
|
||||
0.18,
|
||||
)
|
||||
_logbook_page_status.position = (
|
||||
Vector2(255.0, 286.0) if compact else Vector2(555.0, 524.0)
|
||||
Vector2(255.0, 308.0) if compact else Vector2(555.0, 608.0)
|
||||
)
|
||||
_logbook_page_status.size = (
|
||||
Vector2(130.0, 46.0) if compact else Vector2(170.0, 56.0)
|
||||
|
|
@ -1238,7 +1515,7 @@ func _update_shell_layout() -> void:
|
|||
)
|
||||
_cooler_host.custom_minimum_size = Vector2(
|
||||
520.0 if compact else 810.0,
|
||||
500.0 if compact else 412.0,
|
||||
512.0 if compact else 420.0,
|
||||
)
|
||||
_bag_grid.columns = 2 if compact else 3
|
||||
_logbook_grid.columns = 3 if compact else 4
|
||||
|
|
@ -1250,14 +1527,18 @@ func _update_shell_layout() -> void:
|
|||
_content_shell.position = _presentation_rest_position
|
||||
_cooler_page.position = _cooler_rest_position
|
||||
_bag_page.position = _bag_rest_position
|
||||
_tackle_box_page.position = _tackle_rest_position
|
||||
_logbook_page.position = _logbook_rest_position
|
||||
_mail_page.position = _mail_rest_position
|
||||
_profile_page.position = _profile_rest_position
|
||||
_players_page.position = Vector2.ZERO
|
||||
_cooler_page.modulate.a = 1.0
|
||||
_bag_page.modulate.a = 1.0
|
||||
_tackle_box_page.modulate.a = 1.0
|
||||
_logbook_page.modulate.a = 1.0
|
||||
_mail_page.modulate.a = 1.0
|
||||
_profile_page.modulate.a = 1.0
|
||||
_players_page.modulate.a = 1.0
|
||||
if not _page_transitioning:
|
||||
_content_stage.position = _content_rest_position
|
||||
_layout_cooler_fish(false)
|
||||
|
|
@ -1339,9 +1620,13 @@ func _begin_menu_entry() -> void:
|
|||
_content_shell.position = _presentation_rest_position + Vector2.DOWN * start_offset
|
||||
_cooler_page.position = _cooler_rest_position + Vector2.DOWN * start_offset
|
||||
_bag_page.position = _bag_rest_position + Vector2.DOWN * start_offset
|
||||
_tackle_box_page.position = (
|
||||
_tackle_rest_position + Vector2.DOWN * start_offset
|
||||
)
|
||||
_logbook_page.position = _logbook_rest_position + Vector2.DOWN * start_offset
|
||||
_mail_page.position = _mail_rest_position + Vector2.DOWN * start_offset
|
||||
_profile_page.position = _profile_rest_position + Vector2.DOWN * start_offset
|
||||
_players_page.position = Vector2.DOWN * start_offset
|
||||
var navigation_rest: Vector2 = _navigation_cluster.position
|
||||
_navigation_cluster.position = navigation_rest + Vector2.DOWN * start_offset
|
||||
var transition_duration := UIMotion.bubble_duration(start_offset)
|
||||
|
|
@ -1364,6 +1649,12 @@ func _begin_menu_entry() -> void:
|
|||
_bag_rest_position,
|
||||
transition_duration
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
_presentation_tween.tween_property(
|
||||
_tackle_box_page,
|
||||
"position",
|
||||
_tackle_rest_position,
|
||||
transition_duration
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
_presentation_tween.tween_property(
|
||||
_logbook_page,
|
||||
"position",
|
||||
|
|
@ -1382,6 +1673,12 @@ func _begin_menu_entry() -> void:
|
|||
_profile_rest_position,
|
||||
transition_duration
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
_presentation_tween.tween_property(
|
||||
_players_page,
|
||||
"position",
|
||||
Vector2.ZERO,
|
||||
transition_duration
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
_presentation_tween.tween_property(
|
||||
_navigation_cluster,
|
||||
"position",
|
||||
|
|
@ -1439,6 +1736,12 @@ func _begin_menu_exit(reason: CloseReason, restore_controls: bool) -> void:
|
|||
-_bag_page.size.y - TRANSITION_SAFE_MARGIN,
|
||||
transition_duration
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
_presentation_tween.tween_property(
|
||||
_tackle_box_page,
|
||||
"position:y",
|
||||
-_tackle_box_page.size.y - TRANSITION_SAFE_MARGIN,
|
||||
transition_duration
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
_presentation_tween.tween_property(
|
||||
_logbook_page,
|
||||
"position:y",
|
||||
|
|
@ -1457,6 +1760,12 @@ func _begin_menu_exit(reason: CloseReason, restore_controls: bool) -> void:
|
|||
-_profile_page.size.y - TRANSITION_SAFE_MARGIN,
|
||||
transition_duration
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
_presentation_tween.tween_property(
|
||||
_players_page,
|
||||
"position:y",
|
||||
-_players_page.size.y - TRANSITION_SAFE_MARGIN,
|
||||
transition_duration
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
_presentation_tween.tween_property(
|
||||
_navigation_cluster,
|
||||
"position:y",
|
||||
|
|
@ -1518,12 +1827,16 @@ func _get_section_root(section: Section) -> Control:
|
|||
return _cooler_page
|
||||
Section.BAG:
|
||||
return _bag_page
|
||||
Section.TACKLE_BOX:
|
||||
return _tackle_box_page
|
||||
Section.LOGBOOK:
|
||||
return _logbook_page
|
||||
Section.MAIL:
|
||||
return _mail_page
|
||||
_:
|
||||
Section.PROFILE:
|
||||
return _profile_page
|
||||
_:
|
||||
return _players_page
|
||||
|
||||
|
||||
func _get_section_rest_position(section: Section) -> Vector2:
|
||||
|
|
@ -1532,12 +1845,16 @@ func _get_section_rest_position(section: Section) -> Vector2:
|
|||
return _cooler_rest_position
|
||||
Section.BAG:
|
||||
return _bag_rest_position
|
||||
Section.TACKLE_BOX:
|
||||
return _tackle_rest_position
|
||||
Section.LOGBOOK:
|
||||
return _logbook_rest_position
|
||||
Section.MAIL:
|
||||
return _mail_rest_position
|
||||
_:
|
||||
Section.PROFILE:
|
||||
return _profile_rest_position
|
||||
_:
|
||||
return Vector2.ZERO
|
||||
|
||||
|
||||
func _begin_page_transition(section: Section) -> void:
|
||||
|
|
@ -1615,7 +1932,6 @@ func _set_shell_interactive(interactive: bool) -> void:
|
|||
_set_content_interactive(interactive)
|
||||
for bubble: BubbleButtonType in [
|
||||
_inventory_tab,
|
||||
_bag_tab,
|
||||
_logbook_tab,
|
||||
_mail_tab,
|
||||
_profile_tab,
|
||||
|
|
@ -1646,6 +1962,25 @@ func _set_content_interactive(interactive: bool) -> void:
|
|||
if interactive and _current_section == Section.BAG
|
||||
else Control.MOUSE_FILTER_IGNORE
|
||||
)
|
||||
_tackle_box_page.mouse_filter = (
|
||||
Control.MOUSE_FILTER_PASS
|
||||
if interactive and _current_section == Section.TACKLE_BOX
|
||||
else Control.MOUSE_FILTER_IGNORE
|
||||
)
|
||||
for tab: Button in [
|
||||
_cooler_sub_tab, _bag_sub_tab, _tackle_sub_tab,
|
||||
]:
|
||||
var tab_interactive: bool = (
|
||||
interactive and _is_inventory_section(_current_section)
|
||||
)
|
||||
tab.focus_mode = (
|
||||
Control.FOCUS_ALL if tab_interactive else Control.FOCUS_NONE
|
||||
)
|
||||
tab.mouse_filter = (
|
||||
Control.MOUSE_FILTER_STOP
|
||||
if tab_interactive
|
||||
else Control.MOUSE_FILTER_IGNORE
|
||||
)
|
||||
_logbook_page.mouse_filter = (
|
||||
Control.MOUSE_FILTER_PASS
|
||||
if interactive and _current_section == Section.LOGBOOK
|
||||
|
|
@ -1728,8 +2063,13 @@ func _cancel_page_tween() -> void:
|
|||
|
||||
func _reset_page_transition_visuals() -> void:
|
||||
for section: Section in [
|
||||
Section.COOLER, Section.BAG, Section.LOGBOOK, Section.MAIL,
|
||||
Section.COOLER,
|
||||
Section.BAG,
|
||||
Section.TACKLE_BOX,
|
||||
Section.LOGBOOK,
|
||||
Section.MAIL,
|
||||
Section.PROFILE,
|
||||
Section.PLAYERS,
|
||||
]:
|
||||
var page: Control = _get_section_root(section)
|
||||
page.position = _get_section_rest_position(section)
|
||||
|
|
@ -1793,6 +2133,12 @@ func _refresh_all() -> void:
|
|||
|
||||
func _on_bag_changed() -> void:
|
||||
_refresh_bag()
|
||||
_refresh_tackle_box()
|
||||
|
||||
|
||||
func _on_hotbar_changed() -> void:
|
||||
_update_bag_detail()
|
||||
_update_tackle_detail()
|
||||
|
||||
|
||||
func _refresh_bag() -> void:
|
||||
|
|
@ -1801,10 +2147,42 @@ func _refresh_bag() -> void:
|
|||
var owned_items: Array[OwnedItemType] = (
|
||||
_bag.get_all_items() if _bag != null else []
|
||||
)
|
||||
var filtered_items: Array[OwnedItemType] = []
|
||||
for owned: OwnedItemType in owned_items:
|
||||
var item: ItemDataType = (
|
||||
_item_catalog.get_item_by_id(owned.item_id)
|
||||
if _item_catalog != null
|
||||
else null
|
||||
)
|
||||
if item == null:
|
||||
continue
|
||||
var is_consumable: bool = (
|
||||
item.category == ItemDataType.Category.CONSUMABLE
|
||||
)
|
||||
if (
|
||||
(_bag_view == BagView.CONSUMABLES and is_consumable)
|
||||
or (
|
||||
_bag_view == BagView.EQUIPMENT
|
||||
and not is_consumable
|
||||
and item.category != ItemDataType.Category.BAIT
|
||||
and item.category != ItemDataType.Category.LURE
|
||||
)
|
||||
):
|
||||
filtered_items.append(owned)
|
||||
owned_items = filtered_items
|
||||
owned_items.sort_custom(_sort_bag_items)
|
||||
_sorted_bag_items = owned_items
|
||||
_equipment_filter.button_pressed = _bag_view == BagView.EQUIPMENT
|
||||
_consumables_filter.button_pressed = (
|
||||
_bag_view == BagView.CONSUMABLES
|
||||
)
|
||||
_bag_empty.visible = owned_items.is_empty()
|
||||
_bag_empty_state.visible = owned_items.is_empty()
|
||||
_bag_empty_state.text = (
|
||||
"No equipment in your Bag."
|
||||
if _bag_view == BagView.EQUIPMENT
|
||||
else "No consumables in your Bag."
|
||||
)
|
||||
if (
|
||||
not _selected_bag_item_id.is_empty()
|
||||
and (_bag == null or not _bag.owns_item(_selected_bag_item_id))
|
||||
|
|
@ -1858,7 +2236,7 @@ func _sync_bag_item_nodes(owned_items: Array[OwnedItemType]) -> void:
|
|||
continue
|
||||
var removed := _bag_item_nodes[item_id] as BagItemSpriteType
|
||||
_bag_item_nodes.erase(item_id)
|
||||
_release_focus_from(removed, _bag_tab)
|
||||
_release_focus_from(removed, _bag_sub_tab)
|
||||
removed.queue_free()
|
||||
_layout_bag_items()
|
||||
_configure_bag_item_focus()
|
||||
|
|
@ -1887,7 +2265,7 @@ func _layout_bag_items() -> void:
|
|||
_bag_item_field.custom_minimum_size = (
|
||||
Vector2(520.0, 140.0)
|
||||
if _compact_layout
|
||||
else Vector2(820.0, 350.0)
|
||||
else Vector2(820.0, 240.0)
|
||||
)
|
||||
for index: int in _sorted_bag_items.size():
|
||||
var owned: OwnedItemType = _sorted_bag_items[index]
|
||||
|
|
@ -1927,9 +2305,11 @@ func _configure_bag_item_focus() -> void:
|
|||
if item_node != null:
|
||||
controls.append(item_node)
|
||||
if controls.is_empty():
|
||||
_bag_tab.focus_neighbor_bottom = NodePath()
|
||||
_bag_sub_tab.focus_neighbor_bottom = NodePath()
|
||||
return
|
||||
_bag_tab.focus_neighbor_bottom = _bag_tab.get_path_to(controls.front())
|
||||
_bag_sub_tab.focus_neighbor_bottom = _bag_sub_tab.get_path_to(
|
||||
controls.front()
|
||||
)
|
||||
for index: int in controls.size():
|
||||
var control: BagItemSpriteType = controls[index]
|
||||
var column: int = index % 3
|
||||
|
|
@ -1943,7 +2323,7 @@ func _configure_bag_item_focus() -> void:
|
|||
controls[right_index]
|
||||
)
|
||||
control.focus_neighbor_top = (
|
||||
control.get_path_to(_bag_tab)
|
||||
control.get_path_to(_bag_sub_tab)
|
||||
if index < 3
|
||||
else control.get_path_to(controls[index - 3])
|
||||
)
|
||||
|
|
@ -1985,42 +2365,50 @@ func _update_bag_detail() -> void:
|
|||
if _bag != null and item != null
|
||||
else 0
|
||||
)
|
||||
var hotbar_assignment: String = "not assigned"
|
||||
if item != null and _hotbar != null:
|
||||
for slot_index: int in range(PlayerHotbarType.SLOT_COUNT):
|
||||
if _hotbar.get_item_id(slot_index) == item.item_id:
|
||||
hotbar_assignment = "hotbar slot %d" % (slot_index + 1)
|
||||
break
|
||||
var item_state: String = ""
|
||||
if item != null:
|
||||
if item.equippable:
|
||||
item_state = "equippable"
|
||||
elif item.usable:
|
||||
item_state = "usable"
|
||||
_bag_detail_texture.texture = item.icon if item != null else null
|
||||
_bag_detail_name.text = item.display_name if item != null else ""
|
||||
_bag_detail_data.text = (
|
||||
"%s\nquantity: %d\n%s\n%s"
|
||||
"%s\nquantity: %d\n%s\n%s\n%s"
|
||||
% [
|
||||
item.get_category_name(),
|
||||
quantity,
|
||||
item_state,
|
||||
hotbar_assignment,
|
||||
item.description,
|
||||
(
|
||||
"can be assigned to the hotbar."
|
||||
if item.hotbar_allowed
|
||||
else "cannot be assigned to the hotbar."
|
||||
),
|
||||
]
|
||||
if item != null
|
||||
else "select a bag item for details."
|
||||
)
|
||||
_bag_sprite_detail_texture.texture = item.icon if item != null else null
|
||||
_bag_sprite_detail_name.text = item.display_name if item != null else ""
|
||||
_bag_sprite_detail_name.text = (
|
||||
item.display_name if item != null else "bag notes"
|
||||
)
|
||||
_bag_sprite_detail_data.text = (
|
||||
"%s • quantity: %d\n%s\n%s"
|
||||
"%s • quantity: %d\n%s • %s\n%s"
|
||||
% [
|
||||
item.get_category_name(),
|
||||
quantity,
|
||||
item_state,
|
||||
hotbar_assignment,
|
||||
item.description,
|
||||
(
|
||||
"drag to any hotbar slot."
|
||||
if item.hotbar_allowed
|
||||
else "not compatible with the hotbar."
|
||||
),
|
||||
]
|
||||
if item != null
|
||||
else ""
|
||||
else "select an item for details."
|
||||
)
|
||||
_bag_detail_constellation.visible = (
|
||||
item != null and _current_section == Section.BAG
|
||||
_current_section == Section.BAG
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -2200,7 +2588,7 @@ func _layout_cooler_fish(animate: bool = true) -> void:
|
|||
var visible_field_size := (
|
||||
Vector2(218.0, 124.0)
|
||||
if _compact_layout
|
||||
else Vector2(784.0, 394.0)
|
||||
else Vector2(810.0, 280.0)
|
||||
)
|
||||
var side_margin: float = 2.0 if _compact_layout else 8.0
|
||||
var top_margin: float = 4.0 if _compact_layout else 6.0
|
||||
|
|
@ -2260,9 +2648,9 @@ func _configure_cooler_fish_focus() -> void:
|
|||
controls.append(fish_node)
|
||||
var columns: int = 3 if _compact_layout else 9
|
||||
if controls.is_empty():
|
||||
_inventory_tab.focus_neighbor_bottom = NodePath()
|
||||
_cooler_sub_tab.focus_neighbor_bottom = NodePath()
|
||||
return
|
||||
_inventory_tab.focus_neighbor_bottom = _inventory_tab.get_path_to(
|
||||
_cooler_sub_tab.focus_neighbor_bottom = _cooler_sub_tab.get_path_to(
|
||||
controls.front()
|
||||
)
|
||||
for index: int in controls.size():
|
||||
|
|
@ -2274,7 +2662,7 @@ func _configure_cooler_fish_focus() -> void:
|
|||
controls[mini(index + 1, controls.size() - 1)]
|
||||
)
|
||||
control.focus_neighbor_top = (
|
||||
control.get_path_to(_inventory_tab)
|
||||
control.get_path_to(_cooler_sub_tab)
|
||||
if index < columns
|
||||
else control.get_path_to(controls[index - columns])
|
||||
)
|
||||
|
|
@ -2460,7 +2848,7 @@ func _update_inventory_detail(fish_catch: FishCatchType) -> void:
|
|||
and _reservations.is_fish_reserved(fish_catch.catch_id)
|
||||
):
|
||||
_cooler_detail_name.text += " • reserved in mail"
|
||||
_cooler_weight_unit.text = "lb"
|
||||
_cooler_weight_unit.text = "lb • %s" % fish_catch.fish.get_rarity_name()
|
||||
if buyer_offer >= 0 and _default_buyer != null:
|
||||
_cooler_offer_label.text = "%s offer" % _default_buyer.display_name
|
||||
_cooler_offer_value.text = "$%d" % buyer_offer
|
||||
|
|
|
|||
|
|
@ -60,6 +60,42 @@ offset_right = 1280.0
|
|||
offset_bottom = 720.0
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="InventorySubTabs" type="HBoxContainer" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
z_index = 50
|
||||
layout_mode = 0
|
||||
offset_left = 54.0
|
||||
offset_top = 118.0
|
||||
offset_right = 504.0
|
||||
offset_bottom = 158.0
|
||||
mouse_filter = 1
|
||||
theme_override_constants/separation = 8
|
||||
|
||||
[node name="CoolerSubTab" type="Button" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/InventorySubTabs"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(132, 40)
|
||||
layout_mode = 2
|
||||
toggle_mode = true
|
||||
button_group = null
|
||||
text = "Cooler"
|
||||
|
||||
[node name="BagSubTab" type="Button" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/InventorySubTabs"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(132, 40)
|
||||
layout_mode = 2
|
||||
toggle_mode = true
|
||||
button_group = null
|
||||
text = "Bag"
|
||||
|
||||
[node name="TackleSubTab" type="Button" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/InventorySubTabs"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(154, 40)
|
||||
layout_mode = 2
|
||||
toggle_mode = true
|
||||
button_group = null
|
||||
text = "Tackle Box"
|
||||
|
||||
[node name="CoolerPage" type="Control" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
|
|
@ -434,6 +470,29 @@ offset_right = 1280.0
|
|||
offset_bottom = 720.0
|
||||
mouse_filter = 1
|
||||
|
||||
[node name="BagFilterTabs" type="HBoxContainer" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/BagPage"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_left = 122.0
|
||||
offset_top = 166.0
|
||||
offset_right = 442.0
|
||||
offset_bottom = 206.0
|
||||
theme_override_constants/separation = 8
|
||||
|
||||
[node name="EquipmentFilter" type="Button" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/BagPage/BagFilterTabs"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(150, 40)
|
||||
layout_mode = 2
|
||||
toggle_mode = true
|
||||
text = "Equipment"
|
||||
|
||||
[node name="ConsumablesFilter" type="Button" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/BagPage/BagFilterTabs"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(150, 40)
|
||||
layout_mode = 2
|
||||
toggle_mode = true
|
||||
text = "Consumables"
|
||||
|
||||
[node name="BagOuterWall" type="PanelContainer" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/BagPage"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
|
|
@ -539,6 +598,94 @@ theme_override_font_sizes/font_size = 15
|
|||
horizontal_alignment = 1
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="TackleBoxPage" type="Control" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 0
|
||||
offset_right = 1280.0
|
||||
offset_bottom = 720.0
|
||||
mouse_filter = 1
|
||||
|
||||
[node name="TackleMainPanel" type="PanelContainer" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/TackleBoxPage"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_left = 54.0
|
||||
offset_top = 166.0
|
||||
offset_right = 936.0
|
||||
offset_bottom = 602.0
|
||||
|
||||
[node name="Margin" type="MarginContainer" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/TackleBoxPage/TackleMainPanel"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 24
|
||||
theme_override_constants/margin_top = 20
|
||||
theme_override_constants/margin_right = 24
|
||||
theme_override_constants/margin_bottom = 20
|
||||
|
||||
[node name="Layout" type="VBoxContainer" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/TackleBoxPage/TackleMainPanel/Margin"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 14
|
||||
|
||||
[node name="TackleFilterTabs" type="HBoxContainer" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/TackleBoxPage/TackleMainPanel/Margin/Layout"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 8
|
||||
|
||||
[node name="BaitFilter" type="Button" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/TackleBoxPage/TackleMainPanel/Margin/Layout/TackleFilterTabs"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(150, 40)
|
||||
layout_mode = 2
|
||||
toggle_mode = true
|
||||
text = "Bait"
|
||||
|
||||
[node name="LuresFilter" type="Button" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/TackleBoxPage/TackleMainPanel/Margin/Layout/TackleFilterTabs"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(150, 40)
|
||||
layout_mode = 2
|
||||
toggle_mode = true
|
||||
text = "Lures"
|
||||
|
||||
[node name="TackleScroll" type="ScrollContainer" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/TackleBoxPage/TackleMainPanel/Margin/Layout"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="TackleItemList" type="VBoxContainer" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/TackleBoxPage/TackleMainPanel/Margin/Layout/TackleScroll"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 8
|
||||
|
||||
[node name="TackleEmpty" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/TackleBoxPage/TackleMainPanel/Margin/Layout"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
text = "No bait collected."
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="TackleDetailPanel" type="PanelContainer" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/TackleBoxPage"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_left = 952.0
|
||||
offset_top = 166.0
|
||||
offset_right = 1230.0
|
||||
offset_bottom = 602.0
|
||||
|
||||
[node name="Margin" type="MarginContainer" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/TackleBoxPage/TackleDetailPanel"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 20
|
||||
theme_override_constants/margin_top = 20
|
||||
theme_override_constants/margin_right = 20
|
||||
theme_override_constants/margin_bottom = 20
|
||||
|
||||
[node name="TackleDetailText" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/TackleBoxPage/TackleDetailPanel/Margin"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "Select bait or a lure for details."
|
||||
autowrap_mode = 2
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="LogbookPage" type="Control" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
|
|
@ -1209,15 +1356,15 @@ compact_reference_size = Vector2(840, 100)
|
|||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
toggle_mode = true
|
||||
text = "cooler"
|
||||
text = "inventory"
|
||||
script = ExtResource("6_bubble")
|
||||
profile = ExtResource("4_profile")
|
||||
neutral_size = Vector2(112, 108)
|
||||
desktop_anchor = Vector2(70, 60)
|
||||
compact_anchor = Vector2(70, 73.3333)
|
||||
compact_minimum_size = Vector2(84, 82)
|
||||
minimum_font_size = 25
|
||||
maximum_font_size = 25
|
||||
minimum_font_size = 20
|
||||
maximum_font_size = 22
|
||||
horizontal_amplitude = 1.2
|
||||
vertical_amplitude = 2.4
|
||||
motion_period = 5.6
|
||||
|
|
@ -1225,26 +1372,6 @@ motion_phase = 0.35
|
|||
deformation_amplitude = 0.012
|
||||
deformation_period = 6.4
|
||||
|
||||
[node name="BagTab" type="Button" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/NavigationCluster"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
toggle_mode = true
|
||||
text = "bag"
|
||||
script = ExtResource("6_bubble")
|
||||
profile = ExtResource("4_profile")
|
||||
neutral_size = Vector2(112, 108)
|
||||
desktop_anchor = Vector2(182, 60)
|
||||
compact_anchor = Vector2(182, 73.3333)
|
||||
compact_minimum_size = Vector2(84, 82)
|
||||
minimum_font_size = 25
|
||||
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="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/NavigationCluster"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
|
|
@ -1253,8 +1380,8 @@ text = "logbook"
|
|||
script = ExtResource("6_bubble")
|
||||
profile = ExtResource("4_profile")
|
||||
neutral_size = Vector2(112, 108)
|
||||
desktop_anchor = Vector2(294, 60)
|
||||
compact_anchor = Vector2(294, 73.3333)
|
||||
desktop_anchor = Vector2(210, 60)
|
||||
compact_anchor = Vector2(210, 73.3333)
|
||||
compact_minimum_size = Vector2(84, 82)
|
||||
minimum_font_size = 25
|
||||
maximum_font_size = 25
|
||||
|
|
@ -1273,8 +1400,8 @@ text = "mail"
|
|||
script = ExtResource("6_bubble")
|
||||
profile = ExtResource("4_profile")
|
||||
neutral_size = Vector2(112, 108)
|
||||
desktop_anchor = Vector2(406, 60)
|
||||
compact_anchor = Vector2(406, 73.3333)
|
||||
desktop_anchor = Vector2(350, 60)
|
||||
compact_anchor = Vector2(350, 73.3333)
|
||||
compact_minimum_size = Vector2(84, 82)
|
||||
minimum_font_size = 25
|
||||
maximum_font_size = 25
|
||||
|
|
@ -1309,8 +1436,8 @@ text = "profile"
|
|||
script = ExtResource("6_bubble")
|
||||
profile = ExtResource("4_profile")
|
||||
neutral_size = Vector2(112, 108)
|
||||
desktop_anchor = Vector2(518, 60)
|
||||
compact_anchor = Vector2(518, 73.3333)
|
||||
desktop_anchor = Vector2(490, 60)
|
||||
compact_anchor = Vector2(490, 73.3333)
|
||||
compact_minimum_size = Vector2(84, 82)
|
||||
minimum_font_size = 23
|
||||
maximum_font_size = 25
|
||||
|
|
|
|||
13
ui/player_menu_pattern.gdshader
Normal file
13
ui/player_menu_pattern.gdshader
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
shader_type canvas_item;
|
||||
|
||||
uniform sampler2D pattern_texture : source_color, repeat_enable, filter_nearest;
|
||||
uniform vec2 source_tile_size = vec2(128.0, 128.0);
|
||||
uniform float display_scale : hint_range(0.5, 2.0, 0.05) = 0.85;
|
||||
uniform vec2 scroll_velocity_pixels = vec2(-7.0, -5.0);
|
||||
|
||||
void fragment() {
|
||||
vec2 viewport_pixels = 1.0 / SCREEN_PIXEL_SIZE;
|
||||
vec2 display_tile_size = max(source_tile_size * display_scale, vec2(1.0));
|
||||
vec2 moving_pixels = UV * viewport_pixels + TIME * scroll_velocity_pixels;
|
||||
COLOR = texture(pattern_texture, moving_pixels / display_tile_size);
|
||||
}
|
||||
1
ui/player_menu_pattern.gdshader.uid
Normal file
1
ui/player_menu_pattern.gdshader.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://byw3iub66qvog
|
||||
|
|
@ -38,7 +38,7 @@ func deactivate() -> void:
|
|||
func _build() -> void:
|
||||
var paper := PanelContainer.new()
|
||||
paper.position = Vector2(58, 128)
|
||||
paper.size = Vector2(1164, 476)
|
||||
paper.size = Vector2(1164, 538)
|
||||
add_child(paper)
|
||||
paper.add_theme_stylebox_override("panel", UtilityPageStyle.panel_style())
|
||||
var root := VBoxContainer.new()
|
||||
|
|
@ -59,7 +59,7 @@ func _build() -> void:
|
|||
UtilityPageStyle.apply_button(button)
|
||||
_tabs.add_child(button)
|
||||
var scroll := ScrollContainer.new()
|
||||
scroll.custom_minimum_size = Vector2(0, 330)
|
||||
scroll.custom_minimum_size = Vector2(0, 392)
|
||||
scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
|
||||
root.add_child(scroll)
|
||||
_list = VBoxContainer.new()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue