Polish world, shop, and artwork presentation
This commit is contained in:
parent
7d38bc962b
commit
117fdbfdaa
94 changed files with 1771 additions and 579 deletions
15
ui/art_kit_marker_icon.gdshader
Normal file
15
ui/art_kit_marker_icon.gdshader
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
shader_type canvas_item;
|
||||
|
||||
uniform vec4 marker_color : source_color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
|
||||
void fragment() {
|
||||
vec4 source = texture(TEXTURE, UV) * COLOR;
|
||||
float red_dominance = source.r - max(source.g, source.b);
|
||||
float marker_mask = smoothstep(0.04, 0.18, red_dominance);
|
||||
vec3 colored_marker = marker_color.rgb * source.r;
|
||||
COLOR = vec4(
|
||||
mix(source.rgb, colored_marker, marker_mask),
|
||||
source.a * marker_color.a
|
||||
);
|
||||
}
|
||||
1
ui/art_kit_marker_icon.gdshader.uid
Normal file
1
ui/art_kit_marker_icon.gdshader.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bsg3cwrnjq6ev
|
||||
|
|
@ -5,6 +5,7 @@ extends PanelContainer
|
|||
|
||||
@onready var _heading: Label = %Heading
|
||||
@onready var _value: Label = %Value
|
||||
@onready var _currency_icon: TextureRect = %CurrencyIcon
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
|
@ -16,3 +17,10 @@ func _ready() -> void:
|
|||
func set_content(heading: String, value: String) -> void:
|
||||
_heading.text = heading
|
||||
_value.text = value
|
||||
_currency_icon.visible = false
|
||||
|
||||
|
||||
func set_currency_amount(heading: String, amount: int) -> void:
|
||||
_heading.text = heading
|
||||
_value.text = str(amount)
|
||||
_currency_icon.visible = true
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
[gd_scene load_steps=3 format=3]
|
||||
[gd_scene load_steps=4 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"]
|
||||
[ext_resource type="Texture2D" path="res://items/icons/shop/32_currency.png" id="3_currency"]
|
||||
|
||||
[node name="BubbleStatusBubble" type="PanelContainer"]
|
||||
custom_minimum_size = Vector2(112, 62)
|
||||
|
|
@ -23,7 +24,25 @@ theme_override_font_sizes/font_size = 13
|
|||
text = "status"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="Value" type="Label" parent="Labels"]
|
||||
[node name="ValueRow" type="HBoxContainer" parent="Labels"]
|
||||
layout_mode = 2
|
||||
mouse_filter = 2
|
||||
theme_override_constants/separation = 3
|
||||
alignment = 1
|
||||
|
||||
[node name="CurrencyIcon" type="TextureRect" parent="Labels/ValueRow"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
custom_minimum_size = Vector2(18, 18)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("3_currency")
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
texture_filter = 1
|
||||
|
||||
[node name="Value" type="Label" parent="Labels/ValueRow"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
mouse_filter = 2
|
||||
|
|
|
|||
48
ui/components/currency_amount.gd
Normal file
48
ui/components/currency_amount.gd
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
class_name CurrencyAmount
|
||||
extends HBoxContainer
|
||||
|
||||
@export var amount: int = 0:
|
||||
set(value):
|
||||
amount = value
|
||||
_display_text = str(value)
|
||||
_refresh_amount()
|
||||
@export_range(8.0, 64.0, 1.0) var icon_size: float = 18.0:
|
||||
set(value):
|
||||
icon_size = value
|
||||
_refresh_icon_size()
|
||||
|
||||
@onready var _icon: TextureRect = %Icon
|
||||
@onready var _amount_label: Label = %Amount
|
||||
|
||||
var _display_text: String = "0"
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
_refresh_icon_size()
|
||||
_refresh_amount()
|
||||
|
||||
|
||||
func set_amount(value: int) -> void:
|
||||
amount = value
|
||||
|
||||
|
||||
func set_amount_text(value: String) -> void:
|
||||
_display_text = value
|
||||
_refresh_amount()
|
||||
|
||||
|
||||
func get_amount_label() -> Label:
|
||||
if _amount_label != null:
|
||||
return _amount_label
|
||||
return get_node_or_null("Amount") as Label
|
||||
|
||||
|
||||
func _refresh_amount() -> void:
|
||||
if _amount_label != null:
|
||||
_amount_label.text = _display_text
|
||||
|
||||
|
||||
func _refresh_icon_size() -> void:
|
||||
if _icon != null:
|
||||
_icon.custom_minimum_size = Vector2.ONE * icon_size
|
||||
1
ui/components/currency_amount.gd.uid
Normal file
1
ui/components/currency_amount.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://b7jx040ujcol
|
||||
29
ui/components/currency_amount.tscn
Normal file
29
ui/components/currency_amount.tscn
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
[gd_scene load_steps=3 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://ui/components/currency_amount.gd" id="1_script"]
|
||||
[ext_resource type="Texture2D" path="res://items/icons/shop/32_currency.png" id="2_coin"]
|
||||
|
||||
[node name="CurrencyAmount" type="HBoxContainer"]
|
||||
mouse_filter = 2
|
||||
theme_override_constants/separation = 3
|
||||
alignment = 1
|
||||
script = ExtResource("1_script")
|
||||
|
||||
[node name="Icon" type="TextureRect" parent="."]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(18, 18)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("2_coin")
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
texture_filter = 1
|
||||
|
||||
[node name="Amount" type="Label" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
mouse_filter = 2
|
||||
text = "0"
|
||||
vertical_alignment = 1
|
||||
28
ui/currency_presentation.gd
Normal file
28
ui/currency_presentation.gd
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
class_name CurrencyPresentation
|
||||
extends RefCounted
|
||||
|
||||
const ICON_PATH: String = (
|
||||
"res://items/icons/shop/32_currency.png"
|
||||
)
|
||||
const AMOUNT_SCENE: PackedScene = preload(
|
||||
"res://ui/components/currency_amount.tscn"
|
||||
)
|
||||
|
||||
|
||||
static func instantiate_amount(
|
||||
value: int,
|
||||
icon_size: float = 18.0,
|
||||
) -> CurrencyAmount:
|
||||
var display := AMOUNT_SCENE.instantiate() as CurrencyAmount
|
||||
display.icon_size = icon_size
|
||||
display.amount = value
|
||||
return display
|
||||
|
||||
|
||||
static func bbcode_amount(value: int, icon_size: int = 18) -> String:
|
||||
return "[img=%dx%d]%s[/img] %d" % [
|
||||
icon_size,
|
||||
icon_size,
|
||||
ICON_PATH,
|
||||
value,
|
||||
]
|
||||
1
ui/currency_presentation.gd.uid
Normal file
1
ui/currency_presentation.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bcvy1l2jqqbmt
|
||||
|
|
@ -30,6 +30,15 @@ const UIMotionType = preload("res://ui/ui_motion.gd")
|
|||
const FALLBACK_SUPPLY_ICON: Texture2D = preload(
|
||||
"res://ui/icons/pictograms/x_light.png"
|
||||
)
|
||||
const ART_KIT_MARKER_ICON: Texture2D = preload(
|
||||
"res://items/icons/art/art_kit_marker.png"
|
||||
)
|
||||
const ART_KIT_MARKER_SHADER: Shader = preload(
|
||||
"res://ui/art_kit_marker_icon.gdshader"
|
||||
)
|
||||
const CURRENCY_ICON: Texture2D = preload(
|
||||
"res://items/icons/shop/32_currency.png"
|
||||
)
|
||||
|
||||
signal menu_visibility_changed(is_open: bool)
|
||||
signal menu_exit_started
|
||||
|
|
@ -71,6 +80,8 @@ const SUPPLY_PRICE_FONT_SIZE: int = 15
|
|||
const SUPPLY_PRICE_Y: float = 60.0
|
||||
const SUPPLY_PRICE_HEIGHT: float = 24.0
|
||||
const SUPPLY_PRICE_HORIZONTAL_PADDING: float = 12.0
|
||||
const SUPPLY_PRICE_ICON_SIZE: float = 18.0
|
||||
const SUPPLY_PRICE_ICON_GAP: float = 3.0
|
||||
|
||||
@onready var _wallet_label: Label = %WalletLabel
|
||||
@onready var _shop_panel: PanelContainer = %ShopPanel
|
||||
|
|
@ -79,23 +90,20 @@ const SUPPLY_PRICE_HORIZONTAL_PADDING: float = 12.0
|
|||
@onready var _shop_cooler_page: Control = %ShopCoolerPage
|
||||
@onready var _shop_cooler_mount: Control = %ShopCoolerMount
|
||||
@onready var _shop_body: HBoxContainer = $ShopPanel/Margin/Layout/Body
|
||||
@onready var _feedback: Label = %Feedback
|
||||
@onready var _feedback: RichTextLabel = %Feedback
|
||||
@onready var _shop_tab_bar: HBoxContainer = %ShopTabBar
|
||||
@onready var _upgrades_content: VBoxContainer = %Upgrades
|
||||
@onready var _supplies_content: VBoxContainer = %Supplies
|
||||
@onready var _stock_title: Label = %StockTitle
|
||||
@onready var _reel_level: Label = %ReelLevel
|
||||
@onready var _reel_effect: Label = %ReelEffect
|
||||
@onready var _reel_cost: Label = %ReelCost
|
||||
@onready var _reel_cost: CurrencyAmount = %ReelCost
|
||||
@onready var _reel_price_bubble: PanelContainer = %ReelPriceBubble
|
||||
@onready var _reel_purchase: Button = %ReelPurchase
|
||||
@onready var _barrier_level: Label = %BarrierLevel
|
||||
@onready var _barrier_effect: Label = %BarrierEffect
|
||||
@onready var _barrier_cost: Label = %BarrierCost
|
||||
@onready var _barrier_cost: CurrencyAmount = %BarrierCost
|
||||
@onready var _barrier_price_bubble: PanelContainer = %BarrierPriceBubble
|
||||
@onready var _barrier_purchase: Button = %BarrierPurchase
|
||||
@onready var _supplies_list: VBoxContainer = %SuppliesList
|
||||
@onready var _cooler_level: Label = %CoolerLevel
|
||||
@onready var _cooler_effect: Label = %CoolerEffect
|
||||
@onready var _cooler_cost: Label = %CoolerCost
|
||||
@onready var _cooler_cost: CurrencyAmount = %CoolerCost
|
||||
@onready var _cooler_price_bubble: PanelContainer = %CoolerPriceBubble
|
||||
@onready var _cooler_purchase: Button = %CoolerPurchase
|
||||
|
||||
var _player: PlayerType
|
||||
|
|
@ -136,17 +144,17 @@ func _ready() -> void:
|
|||
|
||||
func _request_shop_cooler() -> bool:
|
||||
if _transaction_in_progress:
|
||||
_feedback.text = "Finish the current transaction first."
|
||||
_set_feedback("Finish the current transaction first.")
|
||||
return false
|
||||
if not _is_transaction_context_valid():
|
||||
_feedback.text = "The fishing shop is no longer available."
|
||||
_set_feedback("The fishing shop is no longer available.")
|
||||
return false
|
||||
sell_fish_requested.emit()
|
||||
return _cooler_page_active
|
||||
|
||||
|
||||
func _focus_shop_section() -> void:
|
||||
_feedback.text = ""
|
||||
_set_feedback("")
|
||||
if _shop_section == ShopSection.UPGRADES:
|
||||
_reel_purchase.grab_focus()
|
||||
return
|
||||
|
|
@ -193,6 +201,10 @@ func _select_shop_section(section_index: int, focus_content: bool) -> void:
|
|||
if _closing:
|
||||
return
|
||||
if section_index == int(_shop_section):
|
||||
if section_index != ShopSection.SELL_FISH:
|
||||
var showing_upgrades := section_index == ShopSection.UPGRADES
|
||||
_upgrades_content.visible = showing_upgrades
|
||||
_supplies_content.visible = not showing_upgrades
|
||||
_update_shop_tab_selection()
|
||||
if focus_content:
|
||||
_focus_shop_section()
|
||||
|
|
@ -236,13 +248,31 @@ func _apply_shop_styles() -> void:
|
|||
"panel", shop_panel_style
|
||||
)
|
||||
for panel: PanelContainer in [
|
||||
$ShopPanel/Margin/Layout/Body/Upgrades/ReelCard,
|
||||
$ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard,
|
||||
$ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard,
|
||||
_reel_price_bubble,
|
||||
_barrier_price_bubble,
|
||||
_cooler_price_bubble,
|
||||
]:
|
||||
panel.add_theme_stylebox_override(
|
||||
"panel", UtilityPageStyleType.row_style()
|
||||
var price_style := UtilityPageStyleType.rounded_style(
|
||||
UtilityPageStyleType.OCEAN_FIELD,
|
||||
18,
|
||||
)
|
||||
price_style.content_margin_left = 8.0
|
||||
price_style.content_margin_right = 8.0
|
||||
price_style.content_margin_top = 2.0
|
||||
price_style.content_margin_bottom = 2.0
|
||||
panel.add_theme_stylebox_override(
|
||||
"panel", price_style
|
||||
)
|
||||
for price: CurrencyAmount in [
|
||||
_reel_cost,
|
||||
_barrier_cost,
|
||||
_cooler_cost,
|
||||
]:
|
||||
var amount_label := price.get_amount_label()
|
||||
amount_label.add_theme_color_override(
|
||||
"font_color", SUPPLY_PRICE_COLOR
|
||||
)
|
||||
amount_label.add_theme_font_size_override("font_size", 18)
|
||||
for button: BaseButton in [
|
||||
%CloseButton,
|
||||
_reel_purchase,
|
||||
|
|
@ -336,7 +366,7 @@ func open_shop() -> bool:
|
|||
_player.set_camera_input_enabled(false)
|
||||
_fishing_spot.set_local_menu_input_suppressed(INPUT_OWNER, true)
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
_feedback.text = ""
|
||||
_set_feedback("")
|
||||
deactivate_shop_cooler_page()
|
||||
show()
|
||||
_shop_tab_bar.show()
|
||||
|
|
@ -520,7 +550,6 @@ func _refresh_upgrades() -> void:
|
|||
return
|
||||
var reel_level: int = _upgrades.get_reel_speed_level()
|
||||
var reel_cost: int = _upgrades.get_next_reel_speed_cost()
|
||||
_reel_level.text = "level %d" % reel_level
|
||||
_reel_purchase.disabled = (
|
||||
reel_cost < 0
|
||||
or _transaction_in_progress
|
||||
|
|
@ -529,27 +558,30 @@ func _refresh_upgrades() -> void:
|
|||
or not _network_shop.can_request_purchase()
|
||||
or not _upgrades.can_purchase_reel_speed(_wallet)
|
||||
)
|
||||
_reel_purchase.tooltip_text = (
|
||||
"Purchases are unavailable in this session."
|
||||
if _network_shop == null or not _network_shop.can_request_purchase()
|
||||
else ""
|
||||
)
|
||||
var reel_effect: String
|
||||
if reel_cost < 0:
|
||||
_reel_effect.text = "%.2f×" % _upgrades.get_reel_speed_multiplier()
|
||||
_reel_cost.text = "max"
|
||||
reel_effect = "%.2f× reel speed · maximum level" % (
|
||||
_upgrades.get_reel_speed_multiplier()
|
||||
)
|
||||
_reel_price_bubble.hide()
|
||||
else:
|
||||
_reel_effect.text = (
|
||||
_reel_price_bubble.show()
|
||||
reel_effect = (
|
||||
"%.2f× → %.2f×"
|
||||
% [
|
||||
_upgrades.get_reel_speed_multiplier(),
|
||||
1.0 + float(reel_level + 1) * 0.10,
|
||||
]
|
||||
)
|
||||
_reel_cost.text = "$%d" % reel_cost
|
||||
_reel_purchase.text = "max" if reel_cost < 0 else "purchase"
|
||||
_reel_cost.set_amount(reel_cost)
|
||||
_reel_purchase.tooltip_text = _upgrade_tooltip(
|
||||
"reel speed",
|
||||
reel_level,
|
||||
reel_effect,
|
||||
)
|
||||
_reel_purchase.accessibility_name = _reel_purchase.tooltip_text
|
||||
var barrier_level: int = _upgrades.get_barrier_power_level()
|
||||
var barrier_cost: int = _upgrades.get_next_barrier_power_cost()
|
||||
_barrier_level.text = "level %d" % barrier_level
|
||||
_barrier_purchase.disabled = (
|
||||
barrier_cost < 0
|
||||
or _transaction_in_progress
|
||||
|
|
@ -558,20 +590,39 @@ func _refresh_upgrades() -> void:
|
|||
or not _network_shop.can_request_purchase()
|
||||
or not _upgrades.can_purchase_barrier_power(_wallet)
|
||||
)
|
||||
_barrier_purchase.tooltip_text = _reel_purchase.tooltip_text
|
||||
var barrier_effect: String
|
||||
if barrier_cost < 0:
|
||||
_barrier_effect.text = "%d damage" % _upgrades.get_barrier_damage()
|
||||
_barrier_cost.text = "max"
|
||||
barrier_effect = "%d damage · maximum level" % (
|
||||
_upgrades.get_barrier_damage()
|
||||
)
|
||||
_barrier_price_bubble.hide()
|
||||
else:
|
||||
_barrier_effect.text = (
|
||||
_barrier_price_bubble.show()
|
||||
barrier_effect = (
|
||||
"%d damage → %d damage"
|
||||
% [
|
||||
_upgrades.get_barrier_damage(),
|
||||
barrier_level + 2,
|
||||
]
|
||||
)
|
||||
_barrier_cost.text = "$%d" % barrier_cost
|
||||
_barrier_purchase.text = "max" if barrier_cost < 0 else "purchase"
|
||||
_barrier_cost.set_amount(barrier_cost)
|
||||
_barrier_purchase.tooltip_text = _upgrade_tooltip(
|
||||
"rod power",
|
||||
barrier_level,
|
||||
barrier_effect,
|
||||
)
|
||||
_barrier_purchase.accessibility_name = _barrier_purchase.tooltip_text
|
||||
|
||||
|
||||
func _upgrade_tooltip(
|
||||
upgrade_name: String,
|
||||
level: int,
|
||||
effect: String,
|
||||
) -> String:
|
||||
var tooltip := "%s\nlevel %d\n%s" % [upgrade_name, level, effect]
|
||||
if _network_shop == null or not _network_shop.can_request_purchase():
|
||||
tooltip += "\nPurchases are unavailable in this session."
|
||||
return tooltip
|
||||
|
||||
|
||||
func _refresh_supplies() -> void:
|
||||
|
|
@ -632,9 +683,8 @@ func _refresh_supplies() -> void:
|
|||
var use_icon_tile: bool = (
|
||||
current_stock_grid != null
|
||||
)
|
||||
button.text = "%s\n$%d • owned %d" % [
|
||||
button.text = "%s\nowned %d" % [
|
||||
item.display_name,
|
||||
FishingShopStockType.get_price(item_id),
|
||||
owned,
|
||||
]
|
||||
var item_tooltip_text: String = item.description
|
||||
|
|
@ -646,27 +696,24 @@ func _refresh_supplies() -> void:
|
|||
button.text = ""
|
||||
else:
|
||||
button.text = (
|
||||
"%s\nunlock $%d" % [item.display_name, total_cost]
|
||||
"%s\nunlock and fill" % item.display_name
|
||||
if not bait_unlocked
|
||||
else "%s\n$%d each • %d/%d" % [
|
||||
else "%s\n%d/%d owned" % [
|
||||
item.display_name,
|
||||
FishingShopStockType.get_price(item_id),
|
||||
owned,
|
||||
item.max_stack,
|
||||
]
|
||||
)
|
||||
item_tooltip_text = (
|
||||
"%s\nunlock $%d • fills to %d/%d\n%s" % [
|
||||
"%s\nunlock and fill to %d/%d\n%s" % [
|
||||
item.display_name,
|
||||
total_cost,
|
||||
item.max_stack,
|
||||
item.max_stack,
|
||||
item.description,
|
||||
]
|
||||
if not bait_unlocked
|
||||
else "%s\n$%d each • %d/%d\n%s" % [
|
||||
else "%s\n%d/%d owned\n%s" % [
|
||||
item.display_name,
|
||||
FishingShopStockType.get_price(item_id),
|
||||
owned,
|
||||
item.max_stack,
|
||||
item.description,
|
||||
|
|
@ -677,9 +724,8 @@ func _refresh_supplies() -> void:
|
|||
button.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
||||
button.alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
button.text = ""
|
||||
item_tooltip_text = "%s\n$%d • owned %d\n%s" % [
|
||||
item_tooltip_text = "%s\nowned %d\n%s" % [
|
||||
item.display_name,
|
||||
FishingShopStockType.get_price(item_id),
|
||||
owned,
|
||||
item.description,
|
||||
]
|
||||
|
|
@ -704,7 +750,11 @@ func _refresh_supplies() -> void:
|
|||
_add_supply_icon_tile(
|
||||
current_stock_grid,
|
||||
button,
|
||||
FishingShopStockType.get_price(item_id),
|
||||
(
|
||||
total_cost
|
||||
if bait_topoff and not bait_unlocked
|
||||
else FishingShopStockType.get_price(item_id)
|
||||
),
|
||||
)
|
||||
else:
|
||||
_supplies_list.add_child(button)
|
||||
|
|
@ -769,14 +819,12 @@ func _add_art_kit_button(parent: GridContainer) -> void:
|
|||
return
|
||||
var owned: bool = _bag.get_quantity(ArtShopStockType.ART_KIT_ITEM_ID) > 0
|
||||
var button: Button = _make_stock_button(
|
||||
"%s\n$%d • %s" % [
|
||||
"%s\n%s" % [
|
||||
item.display_name,
|
||||
ArtShopStockType.ART_KIT_PRICE,
|
||||
"owned" if owned else "not owned",
|
||||
],
|
||||
"%s\n$%d • %s\n%s" % [
|
||||
"%s\n%s\n%s" % [
|
||||
item.display_name,
|
||||
ArtShopStockType.ART_KIT_PRICE,
|
||||
"owned" if owned else "not owned",
|
||||
item.description,
|
||||
],
|
||||
|
|
@ -808,19 +856,26 @@ func _add_art_upgrade_button(
|
|||
)
|
||||
var unlocked: bool = _art_unlocks.owns_product(product_id)
|
||||
var button: Button = _make_stock_button(
|
||||
"%s\n$%d • %s" % [
|
||||
"%s\n%s" % [
|
||||
ArtShopStockType.get_display_name(product_id),
|
||||
ArtShopStockType.UPGRADE_PRICE,
|
||||
"unlocked" if unlocked else "locked",
|
||||
],
|
||||
"%s\n$%d • %s\n%s" % [
|
||||
"%s\n%s\n%s" % [
|
||||
ArtShopStockType.get_display_name(product_id),
|
||||
ArtShopStockType.UPGRADE_PRICE,
|
||||
"unlocked" if unlocked else "locked",
|
||||
ArtShopStockType.get_description(product_id),
|
||||
],
|
||||
)
|
||||
_configure_supply_icon_tile(button, FALLBACK_SUPPLY_ICON)
|
||||
var marker_color_id: StringName = (
|
||||
PlayerArtUnlocksType.color_id_for_product(product_id)
|
||||
)
|
||||
if marker_color_id.is_empty():
|
||||
_configure_supply_icon_tile(button, FALLBACK_SUPPLY_ICON)
|
||||
else:
|
||||
_configure_marker_icon_tile(
|
||||
button,
|
||||
SurfaceDrawingPalette.get_color(marker_color_id),
|
||||
)
|
||||
_add_supply_icon_tile(
|
||||
parent,
|
||||
button,
|
||||
|
|
@ -863,6 +918,29 @@ func _configure_supply_icon_tile(
|
|||
button.text = ""
|
||||
|
||||
|
||||
func _configure_marker_icon_tile(
|
||||
button: Button,
|
||||
marker_color: Color,
|
||||
) -> void:
|
||||
button.custom_minimum_size = SUPPLY_ICON_TILE_SIZE
|
||||
button.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
||||
button.icon = null
|
||||
button.text = ""
|
||||
var icon := TextureRect.new()
|
||||
icon.name = "MarkerIcon"
|
||||
icon.position = Vector2(4.0, 4.0)
|
||||
icon.size = Vector2(64.0, 64.0)
|
||||
icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
var marker_material := ShaderMaterial.new()
|
||||
marker_material.shader = ART_KIT_MARKER_SHADER
|
||||
marker_material.set_shader_parameter("marker_color", marker_color)
|
||||
icon.material = marker_material
|
||||
icon.texture = ART_KIT_MARKER_ICON
|
||||
button.add_child(icon)
|
||||
|
||||
|
||||
func _add_supply_icon_tile(
|
||||
parent: GridContainer,
|
||||
button: Button,
|
||||
|
|
@ -875,7 +953,7 @@ func _add_supply_icon_tile(
|
|||
button.position = Vector2.ZERO
|
||||
button.size = SUPPLY_ICON_TILE_SIZE
|
||||
tile_host.add_child(button)
|
||||
var price_text := "$%d" % price
|
||||
var price_text := str(price)
|
||||
var price_text_width: float = UtilityPageStyleType.TuffyFont.get_string_size(
|
||||
price_text,
|
||||
HORIZONTAL_ALIGNMENT_LEFT,
|
||||
|
|
@ -884,7 +962,12 @@ func _add_supply_icon_tile(
|
|||
).x
|
||||
var price_width: float = minf(
|
||||
SUPPLY_ICON_TILE_SIZE.x,
|
||||
ceilf(price_text_width + SUPPLY_PRICE_HORIZONTAL_PADDING),
|
||||
ceilf(
|
||||
price_text_width
|
||||
+ SUPPLY_PRICE_ICON_SIZE
|
||||
+ SUPPLY_PRICE_ICON_GAP
|
||||
+ SUPPLY_PRICE_HORIZONTAL_PADDING
|
||||
),
|
||||
)
|
||||
var price_bubble := PanelContainer.new()
|
||||
price_bubble.name = "PriceBubble"
|
||||
|
|
@ -905,6 +988,23 @@ func _add_supply_icon_tile(
|
|||
price_style.content_margin_bottom = 0.0
|
||||
price_bubble.add_theme_stylebox_override("panel", price_style)
|
||||
tile_host.add_child(price_bubble)
|
||||
var price_row := HBoxContainer.new()
|
||||
price_row.name = "CurrencyAmount"
|
||||
price_row.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
price_row.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
price_row.add_theme_constant_override(
|
||||
"separation", int(SUPPLY_PRICE_ICON_GAP)
|
||||
)
|
||||
price_bubble.add_child(price_row)
|
||||
var price_icon := TextureRect.new()
|
||||
price_icon.name = "CurrencyIcon"
|
||||
price_icon.custom_minimum_size = Vector2.ONE * SUPPLY_PRICE_ICON_SIZE
|
||||
price_icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
price_icon.texture = CURRENCY_ICON
|
||||
price_icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||
price_icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
price_icon.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
price_row.add_child(price_icon)
|
||||
var price_label := Label.new()
|
||||
price_label.name = "Price"
|
||||
price_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
|
|
@ -921,7 +1021,7 @@ func _add_supply_icon_tile(
|
|||
"font_color", SUPPLY_PRICE_COLOR
|
||||
)
|
||||
price_label.add_theme_constant_override("outline_size", 0)
|
||||
price_bubble.add_child(price_label)
|
||||
price_row.add_child(price_label)
|
||||
|
||||
|
||||
func _refresh_cooler_capacity() -> void:
|
||||
|
|
@ -930,7 +1030,6 @@ func _refresh_cooler_capacity() -> void:
|
|||
var level: int = _cooler_capacity.get_level()
|
||||
var cost: int = _cooler_capacity.get_next_cost()
|
||||
var next_capacity: int = _cooler_capacity.get_next_capacity()
|
||||
_cooler_level.text = "level %d" % level
|
||||
_cooler_purchase.disabled = (
|
||||
cost < 0
|
||||
or _transaction_in_progress
|
||||
|
|
@ -939,18 +1038,25 @@ func _refresh_cooler_capacity() -> void:
|
|||
or not _network_shop.can_request_purchase()
|
||||
or not _cooler_capacity.can_purchase(_wallet)
|
||||
)
|
||||
_cooler_purchase.tooltip_text = _reel_purchase.tooltip_text
|
||||
var cooler_effect: String
|
||||
if cost < 0:
|
||||
_cooler_effect.text = "%d fish" % _cooler_capacity.get_capacity()
|
||||
_cooler_cost.text = "max"
|
||||
_cooler_purchase.text = "max"
|
||||
cooler_effect = "%d fish · maximum level" % (
|
||||
_cooler_capacity.get_capacity()
|
||||
)
|
||||
_cooler_price_bubble.hide()
|
||||
else:
|
||||
_cooler_effect.text = "%d → %d fish" % [
|
||||
_cooler_price_bubble.show()
|
||||
cooler_effect = "%d → %d fish" % [
|
||||
_cooler_capacity.get_capacity(),
|
||||
next_capacity,
|
||||
]
|
||||
_cooler_cost.text = "$%d" % cost
|
||||
_cooler_purchase.text = "purchase"
|
||||
_cooler_cost.set_amount(cost)
|
||||
_cooler_purchase.tooltip_text = _upgrade_tooltip(
|
||||
"cooler capacity",
|
||||
level,
|
||||
cooler_effect,
|
||||
)
|
||||
_cooler_purchase.accessibility_name = _cooler_purchase.tooltip_text
|
||||
|
||||
|
||||
func _purchase_reel_speed() -> void:
|
||||
|
|
@ -963,65 +1069,65 @@ func _purchase_barrier_power() -> void:
|
|||
|
||||
func _purchase_supply(item_id: StringName) -> void:
|
||||
if _transaction_in_progress or not _is_transaction_context_valid():
|
||||
_feedback.text = "unable to complete purchase."
|
||||
_set_feedback("unable to complete purchase.")
|
||||
return
|
||||
var owned: int = _bag.get_quantity(item_id)
|
||||
var item: ItemDataType = _item_catalog.get_item_by_id(item_id)
|
||||
if item == null:
|
||||
_feedback.text = "Purchase could not be completed."
|
||||
_set_feedback("Purchase could not be completed.")
|
||||
return
|
||||
var quantity: int = FishingShopStockType.get_purchase_quantity(
|
||||
item_id, owned, item.max_stack
|
||||
)
|
||||
if quantity <= 0 or not _bag.can_add_item(item_id, quantity):
|
||||
_feedback.text = "Your Bag is full."
|
||||
_set_feedback("Your Bag is full.")
|
||||
return
|
||||
var total_cost: int = FishingShopStockType.get_purchase_cost(
|
||||
item_id, quantity, _bag.is_bait_unlocked(item_id)
|
||||
)
|
||||
if total_cost < 0 or not _wallet.can_afford(total_cost):
|
||||
_feedback.text = "Not enough fish coin."
|
||||
_set_feedback("Insufficient funds.")
|
||||
return
|
||||
if _network_shop == null:
|
||||
_feedback.text = "Purchase could not be completed."
|
||||
_set_feedback("Purchase could not be completed.")
|
||||
return
|
||||
_network_shop.request_supply(item_id)
|
||||
|
||||
|
||||
func _purchase_art_kit() -> void:
|
||||
if _network_shop == null or not _is_transaction_context_valid():
|
||||
_feedback.text = "Purchase could not be completed."
|
||||
_set_feedback("Purchase could not be completed.")
|
||||
return
|
||||
_network_shop.request_art_kit()
|
||||
|
||||
|
||||
func _purchase_art_upgrade(product_id: StringName) -> void:
|
||||
if _network_shop == null or not _is_transaction_context_valid():
|
||||
_feedback.text = "Purchase could not be completed."
|
||||
_set_feedback("Purchase could not be completed.")
|
||||
return
|
||||
_network_shop.request_art_upgrade(product_id)
|
||||
|
||||
|
||||
func _purchase_cooler_capacity() -> void:
|
||||
if _transaction_in_progress or not _is_transaction_context_valid():
|
||||
_feedback.text = "unable to complete purchase."
|
||||
_set_feedback("unable to complete purchase.")
|
||||
return
|
||||
var cost: int = _cooler_capacity.get_next_cost()
|
||||
if cost < 0:
|
||||
_feedback.text = "Upgrade is already at maximum."
|
||||
_set_feedback("Upgrade is already at maximum.")
|
||||
return
|
||||
if not _wallet.can_afford(cost):
|
||||
_feedback.text = "Not enough fish coin."
|
||||
_set_feedback("Insufficient funds.")
|
||||
return
|
||||
if _network_shop == null:
|
||||
_feedback.text = "Purchase could not be completed."
|
||||
_set_feedback("Purchase could not be completed.")
|
||||
return
|
||||
_network_shop.request_cooler_capacity_upgrade()
|
||||
|
||||
|
||||
func _purchase_upgrade(is_reel_speed: bool) -> void:
|
||||
if _transaction_in_progress or not _is_transaction_context_valid():
|
||||
_feedback.text = "unable to complete purchase."
|
||||
_set_feedback("unable to complete purchase.")
|
||||
return
|
||||
var cost: int = (
|
||||
_upgrades.get_next_reel_speed_cost()
|
||||
|
|
@ -1029,13 +1135,13 @@ func _purchase_upgrade(is_reel_speed: bool) -> void:
|
|||
else _upgrades.get_next_barrier_power_cost()
|
||||
)
|
||||
if cost < 0:
|
||||
_feedback.text = "Upgrade is already at maximum."
|
||||
_set_feedback("Upgrade is already at maximum.")
|
||||
return
|
||||
if not _wallet.can_afford(cost):
|
||||
_feedback.text = "Not enough fish coin."
|
||||
_set_feedback("Insufficient funds.")
|
||||
return
|
||||
if _network_shop == null:
|
||||
_feedback.text = "Purchase could not be completed."
|
||||
_set_feedback("Purchase could not be completed.")
|
||||
return
|
||||
if is_reel_speed:
|
||||
_network_shop.request_reel_speed_upgrade()
|
||||
|
|
@ -1046,7 +1152,7 @@ func _purchase_upgrade(is_reel_speed: bool) -> void:
|
|||
func _on_network_purchase_pending(_request_id: String) -> void:
|
||||
_transaction_in_progress = true
|
||||
if visible:
|
||||
_feedback.text = "Purchasing…"
|
||||
_set_feedback("Purchasing…")
|
||||
_refresh_all()
|
||||
|
||||
|
||||
|
|
@ -1062,14 +1168,21 @@ func _on_network_purchase_finished(
|
|||
_transaction_in_progress = false
|
||||
if not visible:
|
||||
return
|
||||
_feedback.text = (
|
||||
"Purchase complete. $%d spent." % total_cost
|
||||
_set_feedback(
|
||||
(
|
||||
"Purchase complete • %s spent."
|
||||
% CurrencyPresentation.bbcode_amount(total_cost, 18)
|
||||
)
|
||||
if accepted
|
||||
else message
|
||||
)
|
||||
_refresh_all()
|
||||
|
||||
|
||||
func _set_feedback(message: String) -> void:
|
||||
_feedback.text = "[center]%s[/center]" % message
|
||||
|
||||
|
||||
func _is_transaction_context_valid() -> bool:
|
||||
return (
|
||||
visible
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
[gd_scene load_steps=8 format=3]
|
||||
[gd_scene load_steps=9 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://ui/fishing_shop.gd" id="1_script"]
|
||||
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
|
||||
[ext_resource type="Texture2D" path="res://items/icons/shop/64_speed_plus.png" id="3_reel"]
|
||||
[ext_resource type="Texture2D" path="res://items/icons/shop/64_power_plus.png" id="4_barrier"]
|
||||
[ext_resource type="Texture2D" path="res://items/icons/placeholder/fish_coin.svg" id="5_coin"]
|
||||
[ext_resource type="Texture2D" path="res://items/icons/shop/32_currency.png" id="5_coin"]
|
||||
[ext_resource type="Texture2D" path="res://items/icons/equipment/64_cooler_plus.png" id="6_cooler"]
|
||||
[ext_resource type="Texture2D" path="res://ui/icons/pictograms/x_light.png" id="7_close"]
|
||||
[ext_resource type="PackedScene" path="res://ui/components/currency_amount.tscn" id="8_currency"]
|
||||
|
||||
[node name="FishingShop" type="Control"]
|
||||
unique_name_in_owner = true
|
||||
|
|
@ -126,12 +127,16 @@ icon = ExtResource("7_close")
|
|||
expand_icon = true
|
||||
icon_max_width = 40
|
||||
|
||||
[node name="Feedback" type="Label" parent="ShopPanel/Margin/Layout"]
|
||||
[node name="Feedback" type="RichTextLabel" parent="ShopPanel/Margin/Layout"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 28)
|
||||
layout_mode = 2
|
||||
text = ""
|
||||
horizontal_alignment = 1
|
||||
theme_override_colors/font_color = Color(1, 0.82, 0.4, 1)
|
||||
bbcode_enabled = true
|
||||
fit_content = true
|
||||
scroll_active = false
|
||||
theme_override_colors/default_color = Color(1, 0.82, 0.4, 1)
|
||||
theme_override_font_sizes/normal_font_size = 20
|
||||
|
||||
[node name="ShopTabBar" type="HBoxContainer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
|
@ -184,164 +189,102 @@ layout_mode = 2
|
|||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 5
|
||||
|
||||
[node name="ReelCard" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades"]
|
||||
[node name="UpgradeScroll" type="ScrollContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="Margin" type="MarginContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 9
|
||||
theme_override_constants/margin_top = 7
|
||||
theme_override_constants/margin_right = 9
|
||||
theme_override_constants/margin_bottom = 7
|
||||
|
||||
[node name="Row" type="HBoxContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 9
|
||||
|
||||
[node name="Icon" type="TextureRect" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row"]
|
||||
custom_minimum_size = Vector2(88, 88)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("3_reel")
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
texture_filter = 1
|
||||
|
||||
[node name="Data" type="VBoxContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row"]
|
||||
[node name="UpgradeGrid" type="GridContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/h_separation = 20
|
||||
theme_override_constants/v_separation = 20
|
||||
columns = 3
|
||||
|
||||
[node name="Name" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row/Data"]
|
||||
[node name="ReelTile" type="Control" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid"]
|
||||
custom_minimum_size = Vector2(144, 168)
|
||||
layout_mode = 2
|
||||
text = "reel speed"
|
||||
theme_override_font_sizes/font_size = 22
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="ReelLevel" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row/Data"]
|
||||
[node name="ReelPurchase" type="Button" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/ReelTile"]
|
||||
unique_name_in_owner = true
|
||||
offset_right = 144.0
|
||||
offset_bottom = 144.0
|
||||
tooltip_text = "reel speed"
|
||||
icon = ExtResource("3_reel")
|
||||
expand_icon = true
|
||||
icon_max_width = 128
|
||||
|
||||
[node name="ReelPriceBubble" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/ReelTile"]
|
||||
unique_name_in_owner = true
|
||||
z_index = 2
|
||||
offset_left = 22.0
|
||||
offset_top = 128.0
|
||||
offset_right = 122.0
|
||||
offset_bottom = 160.0
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="ReelCost" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/ReelTile/ReelPriceBubble" instance=ExtResource("8_currency")]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "level 0"
|
||||
theme_override_font_sizes/font_size = 18
|
||||
amount = 50
|
||||
icon_size = 24.0
|
||||
|
||||
[node name="ReelEffect" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row/Data"]
|
||||
[node name="BarrierTile" type="Control" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid"]
|
||||
custom_minimum_size = Vector2(144, 168)
|
||||
layout_mode = 2
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="BarrierPurchase" type="Button" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/BarrierTile"]
|
||||
unique_name_in_owner = true
|
||||
offset_right = 144.0
|
||||
offset_bottom = 144.0
|
||||
tooltip_text = "rod power"
|
||||
icon = ExtResource("4_barrier")
|
||||
expand_icon = true
|
||||
icon_max_width = 128
|
||||
|
||||
[node name="BarrierPriceBubble" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/BarrierTile"]
|
||||
unique_name_in_owner = true
|
||||
z_index = 2
|
||||
offset_left = 22.0
|
||||
offset_top = 128.0
|
||||
offset_right = 122.0
|
||||
offset_bottom = 160.0
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="BarrierCost" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/BarrierTile/BarrierPriceBubble" instance=ExtResource("8_currency")]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "1.00× → 1.10×"
|
||||
theme_override_font_sizes/font_size = 18
|
||||
amount = 100
|
||||
icon_size = 24.0
|
||||
|
||||
[node name="ReelCost" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row/Data"]
|
||||
[node name="CoolerTile" type="Control" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid"]
|
||||
custom_minimum_size = Vector2(144, 168)
|
||||
layout_mode = 2
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="CoolerPurchase" type="Button" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/CoolerTile"]
|
||||
unique_name_in_owner = true
|
||||
offset_right = 144.0
|
||||
offset_bottom = 144.0
|
||||
tooltip_text = "cooler capacity"
|
||||
icon = ExtResource("6_cooler")
|
||||
expand_icon = true
|
||||
icon_max_width = 128
|
||||
|
||||
[node name="CoolerPriceBubble" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/CoolerTile"]
|
||||
unique_name_in_owner = true
|
||||
z_index = 2
|
||||
offset_left = 22.0
|
||||
offset_top = 128.0
|
||||
offset_right = 122.0
|
||||
offset_bottom = 160.0
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="CoolerCost" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/CoolerTile/CoolerPriceBubble" instance=ExtResource("8_currency")]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "$50"
|
||||
theme_override_font_sizes/font_size = 18
|
||||
|
||||
[node name="ReelPurchase" type="Button" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "purchase"
|
||||
|
||||
[node name="BarrierCard" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Margin" type="MarginContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 9
|
||||
theme_override_constants/margin_top = 7
|
||||
theme_override_constants/margin_right = 9
|
||||
theme_override_constants/margin_bottom = 7
|
||||
|
||||
[node name="Row" type="HBoxContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 9
|
||||
|
||||
[node name="Icon" type="TextureRect" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row"]
|
||||
custom_minimum_size = Vector2(88, 88)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("4_barrier")
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
texture_filter = 1
|
||||
|
||||
[node name="Data" type="VBoxContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Name" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row/Data"]
|
||||
layout_mode = 2
|
||||
text = "rod power"
|
||||
theme_override_font_sizes/font_size = 22
|
||||
|
||||
[node name="BarrierLevel" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row/Data"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "level 0"
|
||||
theme_override_font_sizes/font_size = 18
|
||||
|
||||
[node name="BarrierEffect" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row/Data"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "1 damage → 2 damage"
|
||||
theme_override_font_sizes/font_size = 18
|
||||
|
||||
[node name="BarrierCost" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row/Data"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "$100"
|
||||
theme_override_font_sizes/font_size = 18
|
||||
|
||||
[node name="BarrierPurchase" type="Button" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "purchase"
|
||||
|
||||
[node name="CoolerCard" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Margin" type="MarginContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 9
|
||||
theme_override_constants/margin_top = 7
|
||||
theme_override_constants/margin_right = 9
|
||||
theme_override_constants/margin_bottom = 7
|
||||
|
||||
[node name="Row" type="HBoxContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 9
|
||||
|
||||
[node name="Icon" type="TextureRect" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin/Row"]
|
||||
custom_minimum_size = Vector2(88, 88)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("6_cooler")
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
texture_filter = 1
|
||||
|
||||
[node name="Data" type="VBoxContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin/Row"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Name" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin/Row/Data"]
|
||||
layout_mode = 2
|
||||
text = "cooler capacity"
|
||||
theme_override_font_sizes/font_size = 22
|
||||
|
||||
[node name="CoolerLevel" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin/Row/Data"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "level 0"
|
||||
theme_override_font_sizes/font_size = 18
|
||||
|
||||
[node name="CoolerEffect" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin/Row/Data"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "12 → 18 fish"
|
||||
theme_override_font_sizes/font_size = 18
|
||||
|
||||
[node name="CoolerCost" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin/Row/Data"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "$75"
|
||||
theme_override_font_sizes/font_size = 18
|
||||
|
||||
[node name="CoolerPurchase" type="Button" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin/Row"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "purchase"
|
||||
amount = 75
|
||||
icon_size = 24.0
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ const InventoryNotepadType = preload(
|
|||
const LogbookPortraitType = preload(
|
||||
"res://ui/components/logbook_portrait.gd"
|
||||
)
|
||||
const CurrencyPresentationType = preload(
|
||||
"res://ui/currency_presentation.gd"
|
||||
)
|
||||
|
||||
const DETAIL_FADE_DURATION: float = 0.12
|
||||
const CATEGORY_FADE_DURATION: float = UIMotion.UTILITY_EXIT_DURATION
|
||||
|
|
@ -756,19 +759,17 @@ func _build_known_details(fish: FishDataType) -> void:
|
|||
_add_detail_row(left_stats, "number caught", "unknown")
|
||||
_add_detail_row(right_stats, "rarity", fish.get_rarity_name().to_lower())
|
||||
_add_detail_row(right_stats, "time of day", _availability_text(fish))
|
||||
_add_detail_row(
|
||||
_add_currency_detail_row(
|
||||
right_stats,
|
||||
"value range",
|
||||
"%d–%d fish coin" % [
|
||||
FishQualityType.apply_sale_value(
|
||||
fish.sell_value_min,
|
||||
FishQualityType.Tier.BORING,
|
||||
),
|
||||
FishQualityType.apply_sale_value(
|
||||
fish.sell_value_max,
|
||||
FishQualityType.Tier.SHINY,
|
||||
),
|
||||
],
|
||||
FishQualityType.apply_sale_value(
|
||||
fish.sell_value_min,
|
||||
FishQualityType.Tier.BORING,
|
||||
),
|
||||
FishQualityType.apply_sale_value(
|
||||
fish.sell_value_max,
|
||||
FishQualityType.Tier.SHINY,
|
||||
),
|
||||
)
|
||||
_add_detail_row(
|
||||
right_stats,
|
||||
|
|
@ -878,6 +879,31 @@ func _add_detail_row(
|
|||
parent.add_child(row)
|
||||
|
||||
|
||||
func _add_currency_detail_row(
|
||||
parent: VBoxContainer,
|
||||
row_name: String,
|
||||
minimum_value: int,
|
||||
maximum_value: int,
|
||||
) -> void:
|
||||
var row := VBoxContainer.new()
|
||||
row.add_theme_constant_override("separation", 2)
|
||||
var heading := _field_label(row_name, 14)
|
||||
heading.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
heading.add_theme_color_override("font_color", MUTED_INK)
|
||||
row.add_child(heading)
|
||||
var value: CurrencyAmount = (
|
||||
CurrencyPresentationType.instantiate_amount(minimum_value, 16.0)
|
||||
)
|
||||
value.set_amount_text("%d–%d" % [minimum_value, maximum_value])
|
||||
value.get_amount_label().add_theme_font_override(
|
||||
"font", InventoryNotepadType.HANDWRITTEN_FONT
|
||||
)
|
||||
value.get_amount_label().add_theme_font_size_override("font_size", 16)
|
||||
value.get_amount_label().add_theme_color_override("font_color", INK)
|
||||
row.add_child(value)
|
||||
parent.add_child(row)
|
||||
|
||||
|
||||
func _make_stats_column() -> VBoxContainer:
|
||||
var column := VBoxContainer.new()
|
||||
column.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ const SALUTATION_LABELS := {
|
|||
"good_luck_have_fun": "Good Luck Have Fun",
|
||||
}
|
||||
const FishQualityType = preload("res://fish/fish_quality.gd")
|
||||
const CurrencyPresentationType = preload(
|
||||
"res://ui/currency_presentation.gd"
|
||||
)
|
||||
|
||||
var _service: NetworkMailService
|
||||
var _reservations: PlayerAssetReservationService
|
||||
|
|
@ -36,14 +39,16 @@ var _signature: Label
|
|||
var _attachment_kind: OptionButton
|
||||
var _attachment_choice: OptionButton
|
||||
var _attachment_amount: LineEdit
|
||||
var _coin_available: Label
|
||||
var _coin_available_heading: Label
|
||||
var _coin_available: CurrencyAmount
|
||||
var _attachment_amount_currency_icon: TextureRect
|
||||
var _amount_minus: Button
|
||||
var _amount_plus: Button
|
||||
var _attachment_summary: Label
|
||||
var _attachment_summary: RichTextLabel
|
||||
var _send_button: Button
|
||||
var _status: Label
|
||||
var _letter_text: Label
|
||||
var _letter_gift: Label
|
||||
var _letter_gift: RichTextLabel
|
||||
var _accept: Button
|
||||
var _decline: Button
|
||||
var _archive: Button
|
||||
|
|
@ -212,7 +217,7 @@ func _build_compose() -> Control:
|
|||
_attachment_kind = OptionButton.new()
|
||||
_attachment_kind.position = Vector2(688, 48)
|
||||
_attachment_kind.size = Vector2(280, 46)
|
||||
for label: String in ["No gift", "Fish coin", "Fish", "Consumable"]:
|
||||
for label: String in ["No gift", "Currency", "Fish", "Consumable"]:
|
||||
_attachment_kind.add_item(label)
|
||||
_attachment_kind.item_selected.connect(_refresh_attachment_choices)
|
||||
page.add_child(_attachment_kind)
|
||||
|
|
@ -225,13 +230,34 @@ func _build_compose() -> Control:
|
|||
_update_attachment_summary()
|
||||
)
|
||||
page.add_child(_attachment_choice)
|
||||
_coin_available = Label.new()
|
||||
_coin_available.position = Vector2(688, 158)
|
||||
_coin_available.size = Vector2(280, 28)
|
||||
_coin_available_heading = Label.new()
|
||||
_coin_available_heading.text = "Available"
|
||||
_coin_available_heading.position = Vector2(688, 158)
|
||||
_coin_available_heading.size = Vector2(80, 28)
|
||||
page.add_child(_coin_available_heading)
|
||||
_coin_available = CurrencyPresentationType.instantiate_amount(0, 18.0)
|
||||
_coin_available.position = Vector2(770, 158)
|
||||
_coin_available.size = Vector2(198, 28)
|
||||
_coin_available.alignment = BoxContainer.ALIGNMENT_BEGIN
|
||||
page.add_child(_coin_available)
|
||||
_attachment_amount_currency_icon = TextureRect.new()
|
||||
_attachment_amount_currency_icon.position = Vector2(746, 204)
|
||||
_attachment_amount_currency_icon.size = Vector2(18, 18)
|
||||
_attachment_amount_currency_icon.texture = preload(
|
||||
"res://items/icons/shop/32_currency.png"
|
||||
)
|
||||
_attachment_amount_currency_icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||
_attachment_amount_currency_icon.stretch_mode = (
|
||||
TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
)
|
||||
_attachment_amount_currency_icon.texture_filter = (
|
||||
CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
)
|
||||
_attachment_amount_currency_icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
page.add_child(_attachment_amount_currency_icon)
|
||||
_attachment_amount = LineEdit.new()
|
||||
_attachment_amount.position = Vector2(746, 190)
|
||||
_attachment_amount.size = Vector2(164, 46)
|
||||
_attachment_amount.position = Vector2(770, 190)
|
||||
_attachment_amount.size = Vector2(140, 46)
|
||||
_attachment_amount.placeholder_text = "0"
|
||||
_attachment_amount.text = "0"
|
||||
_attachment_amount.text_changed.connect(_on_attachment_amount_changed)
|
||||
|
|
@ -248,9 +274,12 @@ func _build_compose() -> Control:
|
|||
_amount_plus.size = Vector2(48, 46)
|
||||
_amount_plus.pressed.connect(_step_attachment_amount.bind(1))
|
||||
page.add_child(_amount_plus)
|
||||
_attachment_summary = Label.new()
|
||||
_attachment_summary = RichTextLabel.new()
|
||||
_attachment_summary.position = Vector2(688, 246)
|
||||
_attachment_summary.size = Vector2(280, 78)
|
||||
_attachment_summary.bbcode_enabled = true
|
||||
_attachment_summary.fit_content = true
|
||||
_attachment_summary.scroll_active = false
|
||||
_attachment_summary.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
page.add_child(_attachment_summary)
|
||||
var cancel := Button.new()
|
||||
|
|
@ -281,9 +310,12 @@ func _build_letter() -> Control:
|
|||
_letter_text.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
_letter_text.vertical_alignment = VERTICAL_ALIGNMENT_TOP
|
||||
page.add_child(_letter_text)
|
||||
_letter_gift = Label.new()
|
||||
_letter_gift = RichTextLabel.new()
|
||||
_letter_gift.position = Vector2(730, 46)
|
||||
_letter_gift.size = Vector2(230, 180)
|
||||
_letter_gift.bbcode_enabled = true
|
||||
_letter_gift.fit_content = true
|
||||
_letter_gift.scroll_active = false
|
||||
_letter_gift.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
page.add_child(_letter_gift)
|
||||
_accept = Button.new()
|
||||
|
|
@ -479,13 +511,18 @@ func _refresh_attachment_choices(_index: int) -> void:
|
|||
_attachment_amount.visible = amount_visible
|
||||
_amount_minus.visible = amount_visible
|
||||
_amount_plus.visible = amount_visible
|
||||
_coin_available.visible = _attachment_kind.selected == 1
|
||||
var currency_selected: bool = _attachment_kind.selected == 1
|
||||
_coin_available_heading.visible = currency_selected
|
||||
_coin_available.visible = currency_selected
|
||||
_attachment_amount_currency_icon.visible = currency_selected
|
||||
_attachment_amount.position.x = 770.0 if currency_selected else 746.0
|
||||
_attachment_amount.size.x = 140.0 if currency_selected else 164.0
|
||||
match _attachment_kind.selected:
|
||||
0:
|
||||
_attachment_choice.add_item("No attachment")
|
||||
1:
|
||||
_attachment_choice.add_item("Fish coin")
|
||||
_coin_available.text = "Available: %d fish coin" % (
|
||||
_attachment_choice.add_item("Currency")
|
||||
_coin_available.set_amount(
|
||||
_reservations.get_available_fish_coin()
|
||||
)
|
||||
2:
|
||||
|
|
@ -705,7 +742,9 @@ func _attachment_text(attachment: Dictionary) -> String:
|
|||
PlayerAssetReservationService.AttachmentType.NONE:
|
||||
return "No gift attached."
|
||||
PlayerAssetReservationService.AttachmentType.FISH_COIN:
|
||||
return "%d fish coin" % int(attachment.get("amount", 0))
|
||||
return CurrencyPresentationType.bbcode_amount(
|
||||
int(attachment.get("amount", 0)), 18
|
||||
)
|
||||
PlayerAssetReservationService.AttachmentType.FISH:
|
||||
var fish_catch := _inventory.get_catch_by_id(
|
||||
StringName(str(attachment.get("catch_id", "")))
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ const FishInventoryType = preload("res://inventory/fish_inventory.gd")
|
|||
const InventoryNotepadType = preload(
|
||||
"res://ui/components/inventory_notepad.gd"
|
||||
)
|
||||
const CurrencyPresentationType = preload(
|
||||
"res://ui/currency_presentation.gd"
|
||||
)
|
||||
const OrganizerTabType = preload("res://ui/components/organizer_tab.gd")
|
||||
const FishPoolType = preload("res://fish/fish_pool.gd")
|
||||
const FishingSpotType = preload("res://fishing/fishing_spot.gd")
|
||||
|
|
@ -168,7 +171,7 @@ const SALE_CONFIRMATION_SIZE := Vector2(520.0, 190.0)
|
|||
@onready var _notepad_binding: Label = %BindingDecoration
|
||||
@onready var _notepad_title: Label = %NotepadTitle
|
||||
@onready var _notepad_rule: ColorRect = %NotepadRule
|
||||
@onready var _notepad_wallet_value: Label = %NotepadWalletValue
|
||||
@onready var _notepad_wallet_value: CurrencyAmount = %NotepadWalletValue
|
||||
@onready var _notepad_capacity_value: Label = %NotepadCapacityValue
|
||||
@onready var _cooler_detail_texture: TextureRect = %CoolerDetailTexture
|
||||
@onready var _cooler_detail_name: Label = %CoolerDetailName
|
||||
|
|
@ -178,7 +181,7 @@ const SALE_CONFIRMATION_SIZE := Vector2(520.0, 190.0)
|
|||
@onready var _cooler_weight_unit: Label = %CoolerWeightUnit
|
||||
@onready var _cooler_offer_row: HBoxContainer = %CoolerOfferRow
|
||||
@onready var _cooler_offer_label: Label = %CoolerOfferLabel
|
||||
@onready var _cooler_offer_value: Label = %CoolerOfferValue
|
||||
@onready var _cooler_offer_value: CurrencyAmount = %CoolerOfferValue
|
||||
@onready var _cooler_selection_summary: Control = %CoolerSelectionSummary
|
||||
@onready var _cooler_selection_empty: Label = %CoolerSelectionEmpty
|
||||
@onready var _cooler_selected_count_row: HBoxContainer = %CoolerSelectedCountRow
|
||||
|
|
@ -186,7 +189,7 @@ const SALE_CONFIRMATION_SIZE := Vector2(520.0, 190.0)
|
|||
@onready var _cooler_selected_count_label: Label = %CoolerSelectedCountLabel
|
||||
@onready var _cooler_combined_offer_row: HBoxContainer = %CoolerCombinedOfferRow
|
||||
@onready var _cooler_combined_offer_label: Label = %CoolerCombinedOfferLabel
|
||||
@onready var _cooler_combined_offer_value: Label = %CoolerCombinedOfferValue
|
||||
@onready var _cooler_combined_offer_value: CurrencyAmount = %CoolerCombinedOfferValue
|
||||
@onready var _favorite_bubble: NotepadInkActionType = %FavoriteBubble
|
||||
@onready var _sell_bubble: NotepadInkActionType = %SellBubble
|
||||
@onready var _sell_all_bubble: NotepadInkActionType = %SellAllBubble
|
||||
|
|
@ -247,7 +250,7 @@ const SALE_CONFIRMATION_SIZE := Vector2(520.0, 190.0)
|
|||
@onready var _content_stage: Control = %Content
|
||||
@onready var _cooler_scroll: ScrollContainer = %CoolerScroll
|
||||
@onready var _cooler_host: Control = %CoolerHost
|
||||
@onready var _wallet_balance: Label = %WalletBalance
|
||||
@onready var _wallet_balance: CurrencyAmount = %WalletBalance
|
||||
@onready var _header: Control = %Header
|
||||
@onready var _separator: Control = %Separator
|
||||
@onready var _wallet_status: BubbleStatusBubbleType = %WalletStatus
|
||||
|
|
@ -266,16 +269,16 @@ const SALE_CONFIRMATION_SIZE := Vector2(520.0, 190.0)
|
|||
@onready var _bag_detail_data: Label = %BagDetailData
|
||||
@onready var _sort_option: OptionButton = %SortOption
|
||||
@onready var _sort_direction: Button = %SortDirection
|
||||
@onready var _held_value: Label = %HeldValue
|
||||
@onready var _held_value: CurrencyAmount = %HeldValue
|
||||
@onready var _cooler_count: Label = %CoolerCount
|
||||
@onready var _inventory_empty: Label = %InventoryEmpty
|
||||
@onready var _selection_summary: Label = %SelectionSummary
|
||||
@onready var _favorite_button: Button = %FavoriteButton
|
||||
@onready var _sell_button: Button = %SellButton
|
||||
@onready var _sale_unavailable: Label = %SaleUnavailable
|
||||
@onready var _transaction_feedback: Label = %TransactionFeedback
|
||||
@onready var _transaction_feedback: RichTextLabel = %TransactionFeedback
|
||||
@onready var _sale_confirmation: PanelContainer = %SaleConfirmation
|
||||
@onready var _confirmation_message: Label = %ConfirmationMessage
|
||||
@onready var _confirmation_message: RichTextLabel = %ConfirmationMessage
|
||||
@onready var _confirm_sale_button: Button = %ConfirmSaleButton
|
||||
@onready var _cancel_sale_button: Button = %CancelSaleButton
|
||||
@onready var _logbook_empty: Label = %LogbookEmpty
|
||||
|
|
@ -1881,11 +1884,11 @@ func _apply_inventory_styles() -> void:
|
|||
UtilityPageStyle.panel_style(),
|
||||
)
|
||||
_confirmation_message.add_theme_font_override(
|
||||
"font",
|
||||
"normal_font",
|
||||
UtilityPageStyle.TuffyFont,
|
||||
)
|
||||
_confirmation_message.add_theme_color_override(
|
||||
"font_color",
|
||||
"default_color",
|
||||
UtilityPageStyle.OCEAN_TEXT_PRIMARY,
|
||||
)
|
||||
UtilityPageStyle.apply_ocean_button(_confirm_sale_button)
|
||||
|
|
@ -2405,14 +2408,13 @@ func _update_shell_layout() -> void:
|
|||
_notepad_capacity_value.size = (
|
||||
Vector2(142.0, 17.0) if compact else Vector2(124.0, 23.0)
|
||||
)
|
||||
for status_value: Label in [
|
||||
_notepad_wallet_value,
|
||||
_notepad_capacity_value,
|
||||
]:
|
||||
status_value.add_theme_font_size_override(
|
||||
"font_size",
|
||||
10 if compact else 14,
|
||||
)
|
||||
_notepad_wallet_value.icon_size = 10.0 if compact else 14.0
|
||||
_notepad_wallet_value.get_amount_label().add_theme_font_size_override(
|
||||
"font_size", 10 if compact else 14
|
||||
)
|
||||
_notepad_capacity_value.add_theme_font_size_override(
|
||||
"font_size", 10 if compact else 14
|
||||
)
|
||||
_cooler_detail_texture.position = (
|
||||
Vector2(5.0, 84.0) if compact else Vector2(80.0, 137.0)
|
||||
)
|
||||
|
|
@ -2594,22 +2596,21 @@ func _layout_cooler_detail_text(compact: bool) -> void:
|
|||
"font_size",
|
||||
13 if compact else 18,
|
||||
)
|
||||
_cooler_offer_value.add_theme_font_size_override(
|
||||
"font_size",
|
||||
10 if compact else 15,
|
||||
_cooler_offer_value.icon_size = 10.0 if compact else 15.0
|
||||
_cooler_offer_value.get_amount_label().add_theme_font_size_override(
|
||||
"font_size", 10 if compact else 15
|
||||
)
|
||||
|
||||
|
||||
func _layout_cooler_selection_text(compact: bool) -> void:
|
||||
var row_height: float = 17.5 if compact else 20.0
|
||||
for numeric_label: Label in [
|
||||
_cooler_selected_count_value,
|
||||
_cooler_combined_offer_value,
|
||||
]:
|
||||
numeric_label.add_theme_font_size_override(
|
||||
"font_size",
|
||||
10 if compact else 14,
|
||||
)
|
||||
_cooler_selected_count_value.add_theme_font_size_override(
|
||||
"font_size", 10 if compact else 14
|
||||
)
|
||||
_cooler_combined_offer_value.icon_size = 10.0 if compact else 14.0
|
||||
_cooler_combined_offer_value.get_amount_label().add_theme_font_size_override(
|
||||
"font_size", 10 if compact else 14
|
||||
)
|
||||
for word_label: Label in [
|
||||
_cooler_selection_empty,
|
||||
_cooler_selected_count_label,
|
||||
|
|
@ -3438,9 +3439,9 @@ func _refresh_economy_summary() -> void:
|
|||
if _inventory != null
|
||||
else 0
|
||||
)
|
||||
_wallet_balance.text = "wallet: $%d" % balance
|
||||
_wallet_status.set_content("wallet", "$%d" % balance)
|
||||
_notepad_wallet_value.text = "$%d" % balance
|
||||
_wallet_balance.set_amount(balance)
|
||||
_wallet_status.set_currency_amount("wallet", balance)
|
||||
_notepad_wallet_value.set_amount(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,
|
||||
|
|
@ -3449,8 +3450,8 @@ func _refresh_economy_summary() -> void:
|
|||
_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_status.set_currency_amount("held value", held_total)
|
||||
_held_value.set_amount(held_total)
|
||||
_cooler_count.text = "%d / %d" % [
|
||||
_inventory.get_all_catches().size() if _inventory != null else 0,
|
||||
_cooler_capacity.get_capacity() if _cooler_capacity != null else 0,
|
||||
|
|
@ -3707,7 +3708,7 @@ func _on_catch_card_pressed(catch_id: StringName) -> void:
|
|||
Input.is_key_pressed(KEY_CTRL),
|
||||
Input.is_key_pressed(KEY_SHIFT)
|
||||
)
|
||||
_transaction_feedback.text = ""
|
||||
_set_transaction_feedback("")
|
||||
_refresh_inventory()
|
||||
|
||||
|
||||
|
|
@ -3719,7 +3720,7 @@ func _on_fish_field_gui_input(event: InputEvent) -> void:
|
|||
and not get_viewport().gui_is_dragging()
|
||||
):
|
||||
_fish_selection.clear()
|
||||
_transaction_feedback.text = ""
|
||||
_set_transaction_feedback("")
|
||||
_refresh_inventory()
|
||||
|
||||
|
||||
|
|
@ -3751,9 +3752,9 @@ func _clear_cooler_detail_stats() -> void:
|
|||
_cooler_weight_value,
|
||||
_cooler_weight_unit,
|
||||
_cooler_offer_label,
|
||||
_cooler_offer_value,
|
||||
]:
|
||||
label.text = ""
|
||||
_cooler_offer_value.visible = false
|
||||
|
||||
|
||||
func _set_cooler_selection_summary_empty() -> void:
|
||||
|
|
@ -3764,10 +3765,10 @@ func _set_cooler_selection_summary_empty() -> void:
|
|||
_cooler_selected_count_value,
|
||||
_cooler_selected_count_label,
|
||||
_cooler_combined_offer_label,
|
||||
_cooler_combined_offer_value,
|
||||
]:
|
||||
label.visible = false
|
||||
label.text = ""
|
||||
_cooler_combined_offer_value.visible = false
|
||||
|
||||
|
||||
func _set_cooler_selection_summary(
|
||||
|
|
@ -3785,10 +3786,9 @@ func _set_cooler_selection_summary(
|
|||
_cooler_selected_count_label.text = "fish selected"
|
||||
if offer_value >= 0:
|
||||
_cooler_combined_offer_label.text = "combined offer"
|
||||
_cooler_combined_offer_value.text = "$%d" % offer_value
|
||||
_cooler_combined_offer_value.set_amount(offer_value)
|
||||
else:
|
||||
_cooler_combined_offer_label.text = "offer unavailable"
|
||||
_cooler_combined_offer_value.text = ""
|
||||
|
||||
|
||||
func _update_inventory_detail(fish_catch: FishCatchType) -> void:
|
||||
|
|
@ -3838,10 +3838,11 @@ func _update_inventory_detail(fish_catch: FishCatchType) -> void:
|
|||
]
|
||||
if buyer_offer >= 0 and active_buyer != null:
|
||||
_cooler_offer_label.text = _get_offer_label(active_buyer)
|
||||
_cooler_offer_value.text = "$%d" % buyer_offer
|
||||
_cooler_offer_value.visible = true
|
||||
_cooler_offer_value.set_amount(buyer_offer)
|
||||
else:
|
||||
_cooler_offer_label.text = "buyer unavailable"
|
||||
_cooler_offer_value.text = ""
|
||||
_cooler_offer_value.visible = false
|
||||
_favorite_button.disabled = false
|
||||
_favorite_button.text = (
|
||||
"unfavorite" if fish_catch.is_favorited else "favorite"
|
||||
|
|
@ -3970,12 +3971,8 @@ func _update_sale_summary() -> void:
|
|||
or preview.status == FishSaleResultType.Status.FAVORITED
|
||||
)
|
||||
):
|
||||
_selection_summary.text += "\n%s total offer: $%d" % [
|
||||
active_buyer.display_name,
|
||||
preview.payout,
|
||||
]
|
||||
_set_cooler_selection_summary(selected_count, preview.payout)
|
||||
_offer_status.set_content(offer_label, "$%d" % preview.payout)
|
||||
_offer_status.set_currency_amount(offer_label, preview.payout)
|
||||
else:
|
||||
_set_cooler_selection_summary(selected_count, -1)
|
||||
_offer_status.set_content(offer_label, "unavailable")
|
||||
|
|
@ -4058,7 +4055,7 @@ func _on_favorite_pressed() -> void:
|
|||
fish_catch.catch_id,
|
||||
not fish_catch.is_favorited
|
||||
):
|
||||
_transaction_feedback.text = (
|
||||
_set_transaction_feedback(
|
||||
"%s %s."
|
||||
% [
|
||||
fish_catch.fish.display_name,
|
||||
|
|
@ -4074,7 +4071,7 @@ func _on_sell_pressed() -> void:
|
|||
func _on_sell_all_pressed() -> void:
|
||||
var catch_ids: Array[StringName] = _get_sell_all_catch_ids()
|
||||
if catch_ids.is_empty():
|
||||
_transaction_feedback.text = "No sellable fish in the cooler."
|
||||
_set_transaction_feedback("No sellable fish in the cooler.")
|
||||
return
|
||||
_begin_sale_confirmation(catch_ids)
|
||||
|
||||
|
|
@ -4091,14 +4088,14 @@ func _begin_sale_confirmation(catch_ids: Array[StringName]) -> void:
|
|||
and _network_sale_service.is_local_sale_pending()
|
||||
)
|
||||
):
|
||||
_transaction_feedback.text = "Selling…"
|
||||
_set_transaction_feedback("Selling…")
|
||||
return
|
||||
if (
|
||||
_network_sale_service == null
|
||||
or buyer_id.is_empty()
|
||||
or not _network_sale_service.can_request_sale(buyer_id)
|
||||
):
|
||||
_transaction_feedback.text = (
|
||||
_set_transaction_feedback(
|
||||
"Selling is not supported by this server."
|
||||
)
|
||||
return
|
||||
|
|
@ -4114,7 +4111,7 @@ func _begin_sale_confirmation(catch_ids: Array[StringName]) -> void:
|
|||
active_buyer
|
||||
)
|
||||
if not preview.is_success():
|
||||
_transaction_feedback.text = (
|
||||
_set_transaction_feedback(
|
||||
"favorited fish cannot be sold. "
|
||||
+ "remove them from the selection first."
|
||||
if preview.status == FishSaleResultType.Status.FAVORITED
|
||||
|
|
@ -4128,15 +4125,15 @@ func _begin_sale_confirmation(catch_ids: Array[StringName]) -> void:
|
|||
_confirmation_generation = _menu_generation
|
||||
var fish_label: String = "fish"
|
||||
_confirmation_message.text = (
|
||||
"sell %d %s to the %s for $%d?\ncombined base value: $%d"
|
||||
% [
|
||||
preview.fish_count,
|
||||
fish_label,
|
||||
_get_buyer_display_group(active_buyer),
|
||||
preview.payout,
|
||||
preview.base_value,
|
||||
]
|
||||
)
|
||||
"[center]sell %d %s to the %s for %s?\n"
|
||||
+ "combined base value: %s[/center]"
|
||||
) % [
|
||||
preview.fish_count,
|
||||
fish_label,
|
||||
_get_buyer_display_group(active_buyer),
|
||||
CurrencyPresentationType.bbcode_amount(preview.payout, 22),
|
||||
CurrencyPresentationType.bbcode_amount(preview.base_value, 22),
|
||||
]
|
||||
_sale_confirmation.visible = true
|
||||
if _shop_cooler_context_active:
|
||||
shop_cooler_modal_changed.emit(true)
|
||||
|
|
@ -4182,7 +4179,7 @@ func _on_confirm_sale_pressed() -> void:
|
|||
and transaction_generation == _menu_generation
|
||||
and (visible or _shop_cooler_context_active)
|
||||
):
|
||||
_transaction_feedback.text = "Selling…"
|
||||
_set_transaction_feedback("Selling…")
|
||||
|
||||
|
||||
func _can_use_shared_world_actions() -> bool:
|
||||
|
|
@ -4195,7 +4192,7 @@ func _can_use_shared_world_actions() -> bool:
|
|||
func _on_network_sale_pending(_request_id: String) -> void:
|
||||
_sale_in_progress = true
|
||||
if visible or _shop_cooler_context_active:
|
||||
_transaction_feedback.text = "Selling…"
|
||||
_set_transaction_feedback("Selling…")
|
||||
_update_sale_summary()
|
||||
|
||||
|
||||
|
|
@ -4213,11 +4210,12 @@ func _on_network_sale_finished(
|
|||
return
|
||||
_refresh_all()
|
||||
var feedback_message: String = (
|
||||
"Sale complete. $%d received." % payout
|
||||
"Sale complete • %s received."
|
||||
% CurrencyPresentationType.bbcode_amount(payout, 20)
|
||||
if accepted
|
||||
else message
|
||||
)
|
||||
_transaction_feedback.text = feedback_message
|
||||
_set_transaction_feedback(feedback_message)
|
||||
if not accepted:
|
||||
_sale_unavailable.text = feedback_message
|
||||
_sale_unavailable.visible = true
|
||||
|
|
@ -4273,7 +4271,7 @@ func _revalidate_confirmation() -> void:
|
|||
or _confirmation_buyer.id != _confirmation_buyer_id
|
||||
):
|
||||
_close_sale_confirmation()
|
||||
_transaction_feedback.text = "sale selection is no longer available."
|
||||
_set_transaction_feedback("sale selection is no longer available.")
|
||||
return
|
||||
var preview: FishSaleResultType = _sale_service.preview_batch(
|
||||
_confirmation_catch_ids,
|
||||
|
|
@ -4288,7 +4286,7 @@ func _revalidate_confirmation() -> void:
|
|||
)
|
||||
):
|
||||
_close_sale_confirmation()
|
||||
_transaction_feedback.text = (
|
||||
_set_transaction_feedback(
|
||||
"favorited fish cannot be sold. "
|
||||
+ "remove them from the selection first."
|
||||
if preview.status == FishSaleResultType.Status.FAVORITED
|
||||
|
|
@ -4308,6 +4306,10 @@ func _get_buyer_display_group(
|
|||
return "buyer"
|
||||
|
||||
|
||||
func _set_transaction_feedback(message: String) -> void:
|
||||
_transaction_feedback.text = "[center]%s[/center]" % message
|
||||
|
||||
|
||||
func _get_active_sale_buyer() -> FishBuyerProfileType:
|
||||
if _sale_buyer_override != null and _sale_buyer_override.is_valid():
|
||||
return _sale_buyer_override
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=33 format=3]
|
||||
[gd_scene load_steps=34 format=3]
|
||||
|
||||
[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"]
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
[ext_resource type="Texture2D" path="res://ui/icons/tab_menu/profile_simple.png" id="29_profile_simple"]
|
||||
[ext_resource type="Texture2D" path="res://ui/icons/tab_menu/online_simple.png" id="30_online_simple"]
|
||||
[ext_resource type="Texture2D" path="res://ui/icons/tab_menu/close.png" id="31_close"]
|
||||
[ext_resource type="PackedScene" path="res://ui/components/currency_amount.tscn" id="32_currency"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_collection"]
|
||||
|
||||
|
|
@ -224,7 +225,7 @@ theme_override_font_sizes/font_size = 19
|
|||
text = "cooler notes"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="NotepadWalletValue" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation"]
|
||||
[node name="NotepadWalletValue" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation" instance=ExtResource("32_currency")]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_left = 18.0
|
||||
|
|
@ -232,9 +233,7 @@ offset_top = 61.0
|
|||
offset_right = 138.0
|
||||
offset_bottom = 84.0
|
||||
mouse_filter = 2
|
||||
theme_override_colors/font_color = Color(0.16, 0.16, 0.14, 1)
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "$0"
|
||||
icon_size = 14.0
|
||||
|
||||
[node name="NotepadCapacityValue" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation"]
|
||||
unique_name_in_owner = true
|
||||
|
|
@ -367,12 +366,11 @@ mouse_filter = 2
|
|||
theme_override_colors/font_color = Color(0.16, 0.16, 0.14, 1)
|
||||
theme_override_font_sizes/font_size = 18
|
||||
|
||||
[node name="CoolerOfferValue" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation/CoolerDetailStats/CoolerOfferRow"]
|
||||
[node name="CoolerOfferValue" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation/CoolerDetailStats/CoolerOfferRow" instance=ExtResource("32_currency")]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
mouse_filter = 2
|
||||
theme_override_colors/font_color = Color(0.16, 0.16, 0.14, 1)
|
||||
theme_override_font_sizes/font_size = 15
|
||||
icon_size = 15.0
|
||||
|
||||
[node name="CoolerSelectionSummary" type="Control" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation"]
|
||||
unique_name_in_owner = true
|
||||
|
|
@ -442,12 +440,11 @@ theme_override_colors/font_color = Color(0.2, 0.18, 0.15, 0.86)
|
|||
theme_override_font_sizes/font_size = 18
|
||||
text = "combined offer"
|
||||
|
||||
[node name="CoolerCombinedOfferValue" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation/CoolerSelectionSummary/CoolerCombinedOfferRow"]
|
||||
[node name="CoolerCombinedOfferValue" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation/CoolerSelectionSummary/CoolerCombinedOfferRow" instance=ExtResource("32_currency")]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
mouse_filter = 2
|
||||
theme_override_colors/font_color = Color(0.2, 0.18, 0.15, 0.86)
|
||||
theme_override_font_sizes/font_size = 14
|
||||
icon_size = 14.0
|
||||
|
||||
[node name="FavoriteBubble" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation" instance=ExtResource("12_ink_action")]
|
||||
unique_name_in_owner = true
|
||||
|
|
@ -965,24 +962,31 @@ unique_name_in_owner = true
|
|||
layout_mode = 2
|
||||
theme_override_constants/separation = 8
|
||||
|
||||
[node name="WalletBalance" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout/Header"]
|
||||
[node name="WalletHeading" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout/Header"]
|
||||
layout_mode = 2
|
||||
text = "wallet"
|
||||
theme_override_colors/font_color = Color(1, 0.82, 0.4, 1)
|
||||
|
||||
[node name="WalletBalance" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout/Header" instance=ExtResource("32_currency")]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "wallet: $0"
|
||||
theme_override_colors/font_color = Color(1, 0.82, 0.4, 1)
|
||||
alignment = 0
|
||||
|
||||
[node name="Separator" type="HSeparator" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="TransactionFeedback" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout"]
|
||||
[node name="TransactionFeedback" type="RichTextLabel" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 30)
|
||||
layout_mode = 2
|
||||
text = ""
|
||||
horizontal_alignment = 1
|
||||
theme_override_colors/font_color = Color(1, 0.82, 0.4, 1)
|
||||
theme_override_font_sizes/font_size = 21
|
||||
bbcode_enabled = true
|
||||
fit_content = true
|
||||
scroll_active = false
|
||||
theme_override_colors/default_color = Color(1, 0.82, 0.4, 1)
|
||||
theme_override_font_sizes/normal_font_size = 21
|
||||
|
||||
[node name="Content" type="Control" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout"]
|
||||
unique_name_in_owner = true
|
||||
|
|
@ -1057,12 +1061,16 @@ layout_mode = 2
|
|||
text = "0 / 12"
|
||||
theme_override_colors/font_color = Color(0.208, 0.725, 0.78, 1)
|
||||
|
||||
[node name="HeldValue" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout/Content/InventorySection/SortBar"]
|
||||
[node name="HeldValueHeading" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout/Content/InventorySection/SortBar"]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
text = "held fish base value"
|
||||
theme_override_colors/font_color = Color(0.682, 0.733, 0.761, 1)
|
||||
|
||||
[node name="HeldValue" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout/Content/InventorySection/SortBar" instance=ExtResource("32_currency")]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
text = "held fish base value: $0"
|
||||
theme_override_colors/font_color = Color(0.682, 0.733, 0.761, 1)
|
||||
|
||||
[node name="InventoryBody" type="BoxContainer" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout/Content/InventorySection"]
|
||||
unique_name_in_owner = true
|
||||
|
|
@ -1366,12 +1374,15 @@ layout_mode = 2
|
|||
theme_override_constants/separation = 12
|
||||
alignment = 1
|
||||
|
||||
[node name="ConfirmationMessage" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/SaleConfirmation/ConfirmationMargin/ConfirmationLayout"]
|
||||
[node name="ConfirmationMessage" type="RichTextLabel" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/SaleConfirmation/ConfirmationMargin/ConfirmationLayout"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 64)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 22
|
||||
bbcode_enabled = true
|
||||
fit_content = true
|
||||
scroll_active = false
|
||||
theme_override_font_sizes/normal_font_size = 22
|
||||
autowrap_mode = 2
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="ConfirmationButtons" type="HBoxContainer" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/SaleConfirmation/ConfirmationMargin/ConfirmationLayout"]
|
||||
layout_mode = 2
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ func _ready() -> void:
|
|||
UtilityPageStyleType.apply_ocean_button(button)
|
||||
button.custom_minimum_size = Vector2(48, 44)
|
||||
_make_button_round(button, 22)
|
||||
_enlarge_action_icon(_eraser_button)
|
||||
_enlarge_action_icon(_undo_button)
|
||||
_mode_button.custom_minimum_size = Vector2(48, 48)
|
||||
_make_button_round(_mode_button, 24)
|
||||
_mode_button.pressed.connect(_toggle_mode)
|
||||
|
|
@ -91,6 +93,25 @@ func _make_button_round(button: Button, radius: int) -> void:
|
|||
button.add_theme_stylebox_override(style_name, style)
|
||||
|
||||
|
||||
func _enlarge_action_icon(button: Button) -> void:
|
||||
# The shared ocean button uses generous text padding, leaving only a
|
||||
# 20-pixel icon area in these compact bubbles. Keep the 48x44 control and
|
||||
# hitbox intact while giving icon-only actions a full 40x40 presentation.
|
||||
button.add_theme_constant_override("icon_max_width", 40)
|
||||
for style_name: StringName in [
|
||||
&"normal", &"hover", &"pressed", &"focus", &"disabled",
|
||||
]:
|
||||
var existing: StyleBox = button.get_theme_stylebox(style_name)
|
||||
var style := existing.duplicate() as StyleBoxFlat
|
||||
if style == null:
|
||||
continue
|
||||
style.content_margin_left = 4.0
|
||||
style.content_margin_right = 4.0
|
||||
style.content_margin_top = 2.0
|
||||
style.content_margin_bottom = 2.0
|
||||
button.add_theme_stylebox_override(style_name, style)
|
||||
|
||||
|
||||
func setup(
|
||||
service: NetworkSurfaceDrawingService,
|
||||
unlocks: PlayerArtUnlocks,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
[gd_scene load_steps=6 format=3]
|
||||
[gd_scene load_steps=8 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://ui/surface_drawing_toolbar.gd" id="1_script"]
|
||||
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
|
||||
[ext_resource type="Texture2D" path="res://ui/icons/pictograms/undo_light.png" id="3_undo_light"]
|
||||
[ext_resource type="Texture2D" path="res://ui/icons/pictograms/check_mark_light.png" id="4_check_mark_light"]
|
||||
[ext_resource type="Texture2D" path="res://ui/icons/pictograms/x_light.png" id="5_x_light"]
|
||||
[ext_resource type="Texture2D" path="res://items/icons/art/art_kit_eraser.png" id="6_art_kit_eraser"]
|
||||
|
||||
[sub_resource type="ButtonGroup" id="GuideActionGroup"]
|
||||
allow_unpress = true
|
||||
|
||||
[node name="SurfaceDrawingToolbar" type="Control"]
|
||||
visible = false
|
||||
|
|
@ -51,9 +55,12 @@ tooltip_text = "grid size"
|
|||
[node name="EraserButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
texture_filter = 1
|
||||
tooltip_text = "toggle eraser"
|
||||
toggle_mode = true
|
||||
text = "⌫"
|
||||
accessibility_name = "toggle eraser"
|
||||
icon = ExtResource("6_art_kit_eraser")
|
||||
expand_icon = true
|
||||
|
||||
[node name="UndoButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
|
|
@ -67,24 +74,27 @@ expand_icon = true
|
|||
[node name="HideGuideButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
tooltip_text = "hide grid on next click"
|
||||
tooltip_text = "toggle hide grid mode"
|
||||
toggle_mode = true
|
||||
button_group = SubResource("GuideActionGroup")
|
||||
text = "◌"
|
||||
|
||||
[node name="RestoreGuideButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
tooltip_text = "restore hidden grid on next click"
|
||||
tooltip_text = "toggle show grid mode"
|
||||
toggle_mode = true
|
||||
button_group = SubResource("GuideActionGroup")
|
||||
text = "▤"
|
||||
|
||||
[node name="FinalizeGuideButton" type="Button" parent="TopPanel/Top"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
texture_filter = 1
|
||||
tooltip_text = "finish grid on next click"
|
||||
tooltip_text = "toggle finalize grid mode"
|
||||
toggle_mode = true
|
||||
accessibility_name = "finish grid on next click"
|
||||
button_group = SubResource("GuideActionGroup")
|
||||
accessibility_name = "toggle finalize grid mode"
|
||||
icon = ExtResource("4_check_mark_light")
|
||||
expand_icon = true
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
class_name TheNetPage
|
||||
extends Control
|
||||
|
||||
const CurrencyPresentationType = preload(
|
||||
"res://ui/currency_presentation.gd"
|
||||
)
|
||||
|
||||
enum View {
|
||||
DAILY,
|
||||
LIFETIME,
|
||||
|
|
@ -278,15 +282,11 @@ func _build_job_rows(jobs: Array[Dictionary], empty_text: String) -> void:
|
|||
)
|
||||
content.add_child(count)
|
||||
|
||||
var reward := Label.new()
|
||||
reward.custom_minimum_size.x = 98.0
|
||||
reward.text = "$%d • %d xp" % [
|
||||
int(job.get("fish_coin", 0)), int(job.get("experience", 0)),
|
||||
]
|
||||
reward.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
reward.add_theme_color_override(
|
||||
"font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
|
||||
var reward := _make_reward_display(
|
||||
int(job.get("fish_coin", 0)),
|
||||
int(job.get("experience", 0)),
|
||||
)
|
||||
reward.custom_minimum_size.x = 128.0
|
||||
content.add_child(reward)
|
||||
|
||||
var claim := Button.new()
|
||||
|
|
@ -326,17 +326,19 @@ func _build_payment_rows() -> void:
|
|||
var content := HBoxContainer.new()
|
||||
content.add_theme_constant_override("separation", 14)
|
||||
row.add_child(content)
|
||||
var reward_details := VBoxContainer.new()
|
||||
reward_details.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
var label := Label.new()
|
||||
label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
label.text = "%s\n$%d • %d xp" % [
|
||||
str(reward.get("title", "completed job")),
|
||||
int(reward.get("fish_coin", 0)),
|
||||
int(reward.get("experience", 0)),
|
||||
]
|
||||
label.text = str(reward.get("title", "completed job"))
|
||||
label.add_theme_color_override(
|
||||
"font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
|
||||
)
|
||||
content.add_child(label)
|
||||
reward_details.add_child(label)
|
||||
reward_details.add_child(_make_reward_display(
|
||||
int(reward.get("fish_coin", 0)),
|
||||
int(reward.get("experience", 0)),
|
||||
))
|
||||
content.add_child(reward_details)
|
||||
var claim := Button.new()
|
||||
claim.text = "claim"
|
||||
claim.custom_minimum_size = Vector2(110.0, 42.0)
|
||||
|
|
@ -363,6 +365,27 @@ func _claim(claim_id: String) -> void:
|
|||
_refresh()
|
||||
|
||||
|
||||
func _make_reward_display(fish_coin: int, experience: int) -> HBoxContainer:
|
||||
var reward := HBoxContainer.new()
|
||||
reward.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
reward.add_theme_constant_override("separation", 7)
|
||||
var currency: CurrencyAmount = (
|
||||
CurrencyPresentationType.instantiate_amount(fish_coin, 18.0)
|
||||
)
|
||||
currency.get_amount_label().add_theme_color_override(
|
||||
"font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
|
||||
)
|
||||
reward.add_child(currency)
|
||||
var experience_label := Label.new()
|
||||
experience_label.text = "• %d xp" % experience
|
||||
experience_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
experience_label.add_theme_color_override(
|
||||
"font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
|
||||
)
|
||||
reward.add_child(experience_label)
|
||||
return reward
|
||||
|
||||
|
||||
func _add_empty(message: String) -> void:
|
||||
var empty := Label.new()
|
||||
empty.text = message
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ const TitleCreditsPageType = preload("res://ui/title_credits_page.gd")
|
|||
const NetworkSessionType = preload("res://network/network_session.gd")
|
||||
const SavedServerStoreType = preload("res://network/saved_server_store.gd")
|
||||
const JoinGamePageType = preload("res://ui/network/join_game_page.gd")
|
||||
const CurrencyPresentationType = preload(
|
||||
"res://ui/currency_presentation.gd"
|
||||
)
|
||||
const DECORATIVE_FISH_TEXTURES: Array[Texture2D] = [
|
||||
preload("res://fish/species/bass/fish_bass_striped.png"),
|
||||
preload("res://fish/species/bluegill/fish_bluegill.png"),
|
||||
|
|
@ -106,7 +109,7 @@ enum ConfirmationAction {
|
|||
@onready var _join_game_button: BubbleButtonType = %JoinGameButton
|
||||
@onready var _new_game_label: Label = %NewGameLabel
|
||||
@onready var _delete_save_label: Label = %DeleteSaveLabel
|
||||
@onready var _feedback_label: Label = %FeedbackLabel
|
||||
@onready var _feedback_label: RichTextLabel = %FeedbackLabel
|
||||
@onready var _confirmation_page: TitleConfirmationBubblePageType = (
|
||||
%ConfirmationPage
|
||||
)
|
||||
|
|
@ -287,7 +290,7 @@ func open_join_game_page(endpoint: String = "") -> void:
|
|||
func report_network_error(message: String) -> void:
|
||||
_join_game_page.set_status(message)
|
||||
if not _join_game_page.visible:
|
||||
_feedback_label.text = message
|
||||
_feedback_label.text = _center_feedback_text(message)
|
||||
_feedback_label.show()
|
||||
_feedback_label.modulate.a = 1.0
|
||||
|
||||
|
|
@ -953,16 +956,23 @@ func _get_continue_stats_text() -> String:
|
|||
or _inspection.status != SaveInspectionType.Status.VALID_SUPPORTED
|
||||
):
|
||||
return ""
|
||||
return (
|
||||
"%d fish • $%d • %d discovered"
|
||||
% [
|
||||
return _center_feedback_text(
|
||||
"%d fish • %s • %d discovered" % [
|
||||
_inspection.catch_count,
|
||||
_inspection.wallet_balance,
|
||||
CurrencyPresentationType.bbcode_amount(
|
||||
_inspection.wallet_balance, 18
|
||||
),
|
||||
_inspection.discovered_species_count,
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
func _center_feedback_text(message: String) -> String:
|
||||
if message.begins_with("[center]"):
|
||||
return message
|
||||
return "[center]%s[/center]" % message
|
||||
|
||||
|
||||
func _on_continue_pressed() -> void:
|
||||
if (
|
||||
_action_in_progress
|
||||
|
|
@ -991,13 +1001,15 @@ func _on_new_game_pressed() -> void:
|
|||
new_game_requested.emit()
|
||||
return
|
||||
if _inspection.status == SaveInspectionType.Status.UNSUPPORTED_VERSION:
|
||||
_feedback_label.text = (
|
||||
_feedback_label.text = _center_feedback_text(
|
||||
"this save is from a newer game version. "
|
||||
+ "use delete save before starting over."
|
||||
)
|
||||
return
|
||||
if _inspection.status == SaveInspectionType.Status.IO_ERROR:
|
||||
_feedback_label.text = "the existing save cannot be accessed safely."
|
||||
_feedback_label.text = _center_feedback_text(
|
||||
"the existing save cannot be accessed safely."
|
||||
)
|
||||
return
|
||||
_open_confirmation(
|
||||
ConfirmationAction.NEW_GAME,
|
||||
|
|
@ -1043,14 +1055,16 @@ func _on_confirmation_accepted() -> void:
|
|||
_action_in_progress = false
|
||||
return
|
||||
if not _save_manager.delete_progression_save():
|
||||
_feedback_label.text = "failed to delete saved progression."
|
||||
_feedback_label.text = _center_feedback_text(
|
||||
"failed to delete saved progression."
|
||||
)
|
||||
_action_in_progress = false
|
||||
_refresh_save_inspection()
|
||||
_begin_confirmation_return()
|
||||
return
|
||||
_save_manager.initialize_new_game()
|
||||
_refresh_save_inspection()
|
||||
_feedback_label.text = "saved progression deleted."
|
||||
_feedback_label.text = _center_feedback_text("saved progression deleted.")
|
||||
_begin_confirmation_return()
|
||||
_action_in_progress = false
|
||||
|
||||
|
|
@ -1325,8 +1339,9 @@ func _begin_title_cluster_return(feedback_text: String) -> void:
|
|||
_title_settings_transition_generation += 1
|
||||
_cancel_title_settings_tween()
|
||||
_title_settings_transition_active = true
|
||||
if _feedback_label.text != feedback_text:
|
||||
_feedback_label.text = feedback_text
|
||||
var centered_feedback: String = _center_feedback_text(feedback_text)
|
||||
if _feedback_label.text != centered_feedback:
|
||||
_feedback_label.text = centered_feedback
|
||||
_feedback_label.visible = _feedback_visible_before_settings
|
||||
_hide_continue_stats_context()
|
||||
_set_title_bubbles_interactive(false)
|
||||
|
|
@ -1434,7 +1449,7 @@ func _refresh_save_inspection() -> void:
|
|||
_delete_save_label.modulate.a = (
|
||||
DISABLED_BUBBLE_LABEL_ALPHA if _delete_button.disabled else 1.0
|
||||
)
|
||||
_feedback_label.text = _inspection.message
|
||||
_feedback_label.text = _center_feedback_text(_inspection.message)
|
||||
if _inspection.status == SaveInspectionType.Status.VALID_SUPPORTED:
|
||||
_feedback_label.text = _get_continue_stats_text()
|
||||
if _continue_button.disabled:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=18 format=3]
|
||||
[gd_scene load_steps=19 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://ui/title_screen.gd" id="1_script"]
|
||||
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
|
||||
|
|
@ -22,6 +22,17 @@ shader = ExtResource("4_water_shader")
|
|||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_title_logo"]
|
||||
shader = ExtResource("6_logo_shader")
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_continue_stats"]
|
||||
content_margin_left = 14.0
|
||||
content_margin_top = 6.0
|
||||
content_margin_right = 14.0
|
||||
content_margin_bottom = 6.0
|
||||
bg_color = Color(0.031, 0.122, 0.169, 1)
|
||||
corner_radius_top_left = 14
|
||||
corner_radius_top_right = 14
|
||||
corner_radius_bottom_right = 14
|
||||
corner_radius_bottom_left = 14
|
||||
|
||||
[node name="TitleScreen" type="Control"]
|
||||
unique_name_in_owner = true
|
||||
z_index = 200
|
||||
|
|
@ -433,15 +444,18 @@ motion_phase = 4.8
|
|||
deformation_amplitude = 0.02
|
||||
deformation_period = 4.8
|
||||
|
||||
[node name="FeedbackLabel" type="Label" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent"]
|
||||
[node name="FeedbackLabel" type="RichTextLabel" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent"]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
custom_minimum_size = Vector2(0, 44)
|
||||
custom_minimum_size = Vector2(430, 44)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
text = ""
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
bbcode_enabled = true
|
||||
scroll_active = false
|
||||
autowrap_mode = 2
|
||||
vertical_alignment = 1
|
||||
theme_override_styles/normal = SubResource("StyleBoxFlat_continue_stats")
|
||||
|
||||
[node name="ConfirmationPage" parent="ResponsiveTitleStage/TitlePresentationScaleRoot" instance=ExtResource("10_confirmation_page")]
|
||||
unique_name_in_owner = true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue