Restore catch quality inventory styling

This commit is contained in:
Alexander Sellite 2026-08-24 13:50:57 -04:00
parent 8b13ba1d7d
commit 4dc87235ec
4 changed files with 141 additions and 11 deletions

View file

@ -62,6 +62,7 @@ func _run() -> void:
fish_catch.sale_value = Bluegill.get_sale_value_for_weight(
fish_catch.weight_lb
)
fish_catch.quality = FishQuality.Tier.IMPRESSIVE
assert(catches.add_catch(fish_catch))
assert(layout.get_inventory_count() == 2)
assert(layout.move_entry_to_first_free(
@ -106,8 +107,53 @@ func _run() -> void:
== Color(UtilityPageStyle.OCEAN_SELECTED, 0.92)
)
staged_slot.set_staged(false)
var quality_slot := GeneralInventorySlot.new()
root.add_child(quality_slot)
quality_slot.set_presentation_size(Vector2(78.0, 78.0))
quality_slot.configure(
0,
PlayerInventoryLayout.InventoryContainer.STORAGE,
false,
layout,
bag,
catches,
hotbar,
ItemCatalogResource,
)
assert(quality_slot.entry_identity == fish_catch.catch_id)
assert(
(quality_slot.get_theme_stylebox("normal") as StyleBoxFlat).bg_color
== GeneralInventorySlot.quality_background_color(
FishQuality.Tier.IMPRESSIVE,
GeneralInventorySlot.QualityEmphasis.NORMAL,
)
)
quality_slot.set_staged(true)
assert(
(quality_slot.get_theme_stylebox("normal") as StyleBoxFlat).bg_color
== GeneralInventorySlot.quality_background_color(
FishQuality.Tier.IMPRESSIVE,
GeneralInventorySlot.QualityEmphasis.SELECTED,
)
)
var distinct_quality_colors: Dictionary[Color, bool] = {}
for quality: int in FishQuality.TIER_COUNT:
var quality_color := GeneralInventorySlot.quality_background_color(
quality,
GeneralInventorySlot.QualityEmphasis.NORMAL,
)
assert(not distinct_quality_colors.has(quality_color))
distinct_quality_colors[quality_color] = true
assert(distinct_quality_colors.size() == FishQuality.TIER_COUNT)
var sale_tray_slot := ShopSaleTraySlot.new()
root.add_child(sale_tray_slot)
sale_tray_slot.configure(
"catch:%s" % fish_catch.catch_id,
fish_catch.fish.display_texture,
fish_catch.fish.display_name,
1,
fish_catch.quality,
)
assert(
sale_tray_slot.custom_minimum_size
== GeneralInventoryGrid.DEFAULT_SLOT_SIZE
@ -117,6 +163,14 @@ func _run() -> void:
) as StyleBoxFlat
assert(sale_tray_style != null)
assert(sale_tray_style.corner_radius_top_left == 26)
var expected_tray_quality_color := (
GeneralInventorySlot.quality_background_color(
FishQuality.Tier.IMPRESSIVE,
GeneralInventorySlot.QualityEmphasis.NORMAL,
)
)
expected_tray_quality_color.a = 0.96
assert(sale_tray_style.bg_color == expected_tray_quality_color)
var wallet := PlayerWallet.new()
root.add_child(wallet)
assert(wallet.restore_balance(15000))

View file

@ -11,6 +11,12 @@ const LockedContentPresentationType = preload(
"res://ui/components/locked_content_presentation.gd"
)
enum QualityEmphasis {
NORMAL,
HOVER,
SELECTED,
}
var slot_index: int = -1
var container: int = -1
var entry_kind: int = -1
@ -29,6 +35,7 @@ var _context_text: String = ""
var _context_hovered: bool = false
var _context_focused: bool = false
var _staged: bool = false
var _quality_tier: int = -1
func _ready() -> void:
@ -101,10 +108,12 @@ func refresh() -> void:
entry_kind = -1
entry_identity = StringName()
_context_text = ""
_quality_tier = -1
_icon.texture = null
_quantity.text = ""
disabled = _locked
_apply_icon_geometry()
_apply_style()
if _locked:
_icon.texture = LockedContentPresentationType.ICON
_icon.modulate = LockedContentPresentationType.icon_modulate()
@ -152,12 +161,14 @@ func refresh() -> void:
)
if fish_catch == null:
return
_quality_tier = fish_catch.quality
_icon.texture = fish_catch.fish.display_texture
_context_text = _catch_context_text(fish_catch)
var catch_name: String = FishQuality.qualified_name(
fish_catch.fish.display_name, fish_catch.quality
)
accessibility_name = "%s, slot %d" % [catch_name, slot_index + 1]
_apply_style()
func _on_pressed() -> void:
@ -306,27 +317,62 @@ func _drop_data(_at_position: Vector2, data: Variant) -> void:
func _apply_style() -> void:
var radius: int = roundi(minf(_presentation_size.x, _presentation_size.y) * 0.5)
var normal_color: Color = quality_background_color(
_quality_tier,
QualityEmphasis.SELECTED if _staged else QualityEmphasis.NORMAL,
)
var normal := UtilityPageStyle.rounded_style(
Color(
UtilityPageStyle.OCEAN_SELECTED
if _staged else UtilityPageStyle.OCEAN_FIELD,
0.92 if _staged else 0.88,
),
normal_color,
radius,
)
var hover := UtilityPageStyle.rounded_style(
Color(UtilityPageStyle.OCEAN_SELECTED, 0.92), radius
quality_background_color(_quality_tier, QualityEmphasis.HOVER),
radius,
)
var selected := UtilityPageStyle.rounded_style(
quality_background_color(_quality_tier, QualityEmphasis.SELECTED),
radius,
)
var locked := UtilityPageStyle.rounded_style(
LockedContentPresentationType.disabled_background_color(), radius
)
for state: StringName in [&"normal", &"pressed"]:
add_theme_stylebox_override(state, normal)
add_theme_stylebox_override("normal", normal)
add_theme_stylebox_override(
"pressed", selected if FishQuality.is_valid(_quality_tier) else normal
)
add_theme_stylebox_override("disabled", locked)
for state: StringName in [&"hover", &"focus"]:
add_theme_stylebox_override(state, hover)
static func quality_background_color(
quality: int,
emphasis: QualityEmphasis,
) -> Color:
var base_color: Color
var alpha: float
var quality_mix: float
match emphasis:
QualityEmphasis.HOVER:
base_color = UtilityPageStyle.OCEAN_SELECTED
alpha = 0.92
quality_mix = 0.64
QualityEmphasis.SELECTED:
base_color = UtilityPageStyle.OCEAN_SELECTED
alpha = 0.92
quality_mix = 0.82
_:
base_color = UtilityPageStyle.OCEAN_FIELD
alpha = 0.88
quality_mix = 0.46
if not FishQuality.is_valid(quality):
return Color(base_color, alpha)
return Color(
base_color.lerp(UIPalette.get_quality_color(quality), quality_mix),
alpha,
)
func _apply_presentation() -> void:
_apply_icon_geometry()
var is_large: bool = _presentation_size.x >= 70.0

View file

@ -7,6 +7,7 @@ signal drop_requested(payload: Dictionary)
var entry_key: String = ""
var _icon: TextureRect
var _quantity: Label
var _quality_tier: int = -1
func _ready() -> void:
@ -32,11 +33,29 @@ func _ready() -> void:
_quantity.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
_quantity.mouse_filter = Control.MOUSE_FILTER_IGNORE
add_child(_quantity)
_apply_style()
func _apply_style() -> void:
var normal_color := GeneralInventorySlot.quality_background_color(
_quality_tier,
GeneralInventorySlot.QualityEmphasis.NORMAL,
)
var hover_color := GeneralInventorySlot.quality_background_color(
_quality_tier,
GeneralInventorySlot.QualityEmphasis.SELECTED,
)
# Preserve the tray's established opacity while sharing the inventory's
# quality colors. Ordinary items and the empty drop target stay unchanged.
normal_color.a = 0.96
hover_color.a = 0.96
var normal := UtilityPageStyle.rounded_style(
Color(UtilityPageStyle.OCEAN_FIELD, 0.96), 26
normal_color,
26,
)
var hover := UtilityPageStyle.rounded_style(
Color(UtilityPageStyle.OCEAN_SELECTED, 0.96), 26
hover_color,
26,
)
for state: StringName in [&"normal", &"pressed", &"disabled"]:
add_theme_stylebox_override(state, normal)
@ -49,12 +68,15 @@ func configure(
icon: Texture2D,
label: String,
quantity: int = 1,
quality: int = -1,
) -> void:
entry_key = key
_quality_tier = quality
_icon.texture = icon
_quantity.text = "×%d" % quantity if quantity > 1 else ""
tooltip_text = "%s · select to remove" % label
accessibility_name = tooltip_text
_apply_style()
func _can_drop_data(_at_position: Vector2, data: Variant) -> bool:

View file

@ -205,12 +205,14 @@ func _refresh_tray() -> void:
var identity := StringName(str(record["identity"]))
var icon: Texture2D
var label: String
var quality: int = -1
if int(record["kind"]) == PlayerInventoryLayout.EntryKind.CATCH:
var fish_catch := _fish_inventory.get_catch_by_id(identity)
if fish_catch == null:
continue
icon = fish_catch.fish.display_texture
label = fish_catch.fish.display_name
quality = fish_catch.quality
else:
var item := _item_catalog.get_item_by_id(identity)
if item == null:
@ -219,7 +221,13 @@ func _refresh_tray() -> void:
label = item.display_name
var slot := ShopSaleTraySlot.new()
_tray_grid.add_child(slot)
slot.configure(key, icon, label, int(record.get("quantity", 1)))
slot.configure(
key,
icon,
label,
int(record.get("quantity", 1)),
quality,
)
slot.remove_requested.connect(_on_remove_requested)
slot.drop_requested.connect(_on_drop_payload)
var drop_slot := ShopSaleTraySlot.new()