add bulk staging to shop sales
This commit is contained in:
parent
046f5e0fdb
commit
0cc3ae9709
2 changed files with 119 additions and 8 deletions
|
|
@ -971,12 +971,21 @@ func _test_fishing_shop_sale_ui(
|
||||||
reserved_catch.catch_id,
|
reserved_catch.catch_id,
|
||||||
)
|
)
|
||||||
assert(staged.is_empty())
|
assert(staged.is_empty())
|
||||||
sell_inventory.call(
|
var sell_button := sell_inventory.get("_sell_button") as Button
|
||||||
"_stage",
|
var all_button := sell_inventory.get("_all_button") as Button
|
||||||
PlayerInventoryLayout.EntryKind.CATCH,
|
assert(sell_button != null and sell_button.text == "sell")
|
||||||
fish_catch.catch_id,
|
assert(all_button != null and all_button.text == "all")
|
||||||
|
assert(sell_button.get_parent() == all_button.get_parent())
|
||||||
|
assert(
|
||||||
|
sell_button.size_flags_horizontal == Control.SIZE_EXPAND_FILL
|
||||||
|
and all_button.size_flags_horizontal == Control.SIZE_EXPAND_FILL
|
||||||
)
|
)
|
||||||
|
sell_inventory.call("_stage_all_eligible")
|
||||||
assert(staged.has(PlayerInventoryLayout.catch_key(fish_catch.catch_id)))
|
assert(staged.has(PlayerInventoryLayout.catch_key(fish_catch.catch_id)))
|
||||||
|
assert(not staged.has(
|
||||||
|
PlayerInventoryLayout.catch_key(reserved_catch.catch_id)
|
||||||
|
))
|
||||||
|
assert(all_button.disabled)
|
||||||
assert((sell_inventory.get("_feedback") as Label).text.is_empty())
|
assert((sell_inventory.get("_feedback") as Label).text.is_empty())
|
||||||
var source_grid := sell_inventory.get("_inventory_grid") as GeneralInventoryGrid
|
var source_grid := sell_inventory.get("_inventory_grid") as GeneralInventoryGrid
|
||||||
var staged_source_found := false
|
var staged_source_found := false
|
||||||
|
|
@ -985,17 +994,19 @@ func _test_fishing_shop_sale_ui(
|
||||||
staged_source_found = bool(source_slot.get("_staged"))
|
staged_source_found = bool(source_slot.get("_staged"))
|
||||||
break
|
break
|
||||||
assert(staged_source_found)
|
assert(staged_source_found)
|
||||||
|
var expected_all_payout := int(sell_inventory.call("_calculate_total"))
|
||||||
|
assert(expected_all_payout >= fish_catch.sale_value)
|
||||||
var feedback := sell_inventory.get("_feedback") as Label
|
var feedback := sell_inventory.get("_feedback") as Label
|
||||||
var total_label := sell_inventory.get("_total_label") as Label
|
var total_label := sell_inventory.get("_total_label") as Label
|
||||||
var sell_button := sell_inventory.get("_sell_button") as Button
|
var sale_buttons := sell_button.get_parent() as HBoxContainer
|
||||||
assert(feedback.get_index() < total_label.get_parent().get_index())
|
assert(feedback.get_index() < total_label.get_parent().get_index())
|
||||||
assert(total_label.get_parent().get_index() < sell_button.get_index())
|
assert(total_label.get_parent().get_index() < sale_buttons.get_index())
|
||||||
_sale_result.clear()
|
_sale_result.clear()
|
||||||
sell_inventory.call("_submit_sale")
|
sell_inventory.call("_submit_sale")
|
||||||
await process_frame
|
await process_frame
|
||||||
assert(not _sale_result.is_empty() and bool(_sale_result[1]))
|
assert(not _sale_result.is_empty() and bool(_sale_result[1]))
|
||||||
assert(not player.inventory.contains_catch_id(fish_catch.catch_id))
|
assert(not player.inventory.contains_catch_id(fish_catch.catch_id))
|
||||||
assert(player.wallet.get_balance() == balance_before + fish_catch.sale_value)
|
assert(player.wallet.get_balance() == balance_before + expected_all_payout)
|
||||||
assert(not sale_service.is_local_sale_pending())
|
assert(not sale_service.is_local_sale_pending())
|
||||||
assert(reservations.release(reservation_id))
|
assert(reservations.release(reservation_id))
|
||||||
await _activate_pointer_control(shop_tabs[0] as Button, ui_viewport)
|
await _activate_pointer_control(shop_tabs[0] as Button, ui_viewport)
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ var _tray_grid: GridContainer
|
||||||
var _total_label: Label
|
var _total_label: Label
|
||||||
var _feedback: Label
|
var _feedback: Label
|
||||||
var _sell_button: Button
|
var _sell_button: Button
|
||||||
|
var _all_button: Button
|
||||||
var _staged: Dictionary[String, Dictionary] = {}
|
var _staged: Dictionary[String, Dictionary] = {}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -135,6 +136,67 @@ func _on_remove_requested(key: String) -> void:
|
||||||
_refresh_tray()
|
_refresh_tray()
|
||||||
|
|
||||||
|
|
||||||
|
func _stage_all_eligible() -> void:
|
||||||
|
if _layout == null:
|
||||||
|
return
|
||||||
|
var added_count := 0
|
||||||
|
for entry: Dictionary in _layout.get_entries(
|
||||||
|
PlayerInventoryLayout.InventoryContainer.INVENTORY
|
||||||
|
):
|
||||||
|
var kind := int(entry.get("kind", -1))
|
||||||
|
var identity := StringName(str(entry.get("identity", "")))
|
||||||
|
if identity.is_empty():
|
||||||
|
continue
|
||||||
|
var key := (
|
||||||
|
PlayerInventoryLayout.catch_key(identity)
|
||||||
|
if kind == PlayerInventoryLayout.EntryKind.CATCH
|
||||||
|
else PlayerInventoryLayout.item_key(identity)
|
||||||
|
)
|
||||||
|
if _staged.has(key):
|
||||||
|
continue
|
||||||
|
var record := _eligible_staged_record(kind, identity)
|
||||||
|
if record.is_empty():
|
||||||
|
continue
|
||||||
|
_staged[key] = record
|
||||||
|
added_count += 1
|
||||||
|
_feedback.text = (
|
||||||
|
""
|
||||||
|
if added_count > 0
|
||||||
|
else "no additional items are eligible for sale"
|
||||||
|
)
|
||||||
|
_refresh_tray()
|
||||||
|
|
||||||
|
|
||||||
|
func _eligible_staged_record(kind: int, identity: StringName) -> Dictionary:
|
||||||
|
if kind == PlayerInventoryLayout.EntryKind.CATCH:
|
||||||
|
var fish_catch := _fish_inventory.get_catch_by_id(identity)
|
||||||
|
if (
|
||||||
|
fish_catch == null
|
||||||
|
or fish_catch.is_favorited
|
||||||
|
or (
|
||||||
|
_reservations != null
|
||||||
|
and _reservations.is_fish_reserved(identity)
|
||||||
|
)
|
||||||
|
):
|
||||||
|
return {}
|
||||||
|
return {"kind": kind, "identity": identity, "quantity": 1}
|
||||||
|
if kind != PlayerInventoryLayout.EntryKind.ITEM:
|
||||||
|
return {}
|
||||||
|
var item := _item_catalog.get_item_by_id(identity)
|
||||||
|
if not ItemResalePolicy.is_sellable(item):
|
||||||
|
return {}
|
||||||
|
var available := _bag.get_quantity(identity)
|
||||||
|
if _reservations != null:
|
||||||
|
available = _reservations.get_available_item_quantity(identity)
|
||||||
|
if available < 1:
|
||||||
|
return {}
|
||||||
|
return {
|
||||||
|
"kind": kind,
|
||||||
|
"identity": identity,
|
||||||
|
"quantity": available,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func _submit_sale() -> void:
|
func _submit_sale() -> void:
|
||||||
if _staged.is_empty() or _network_sale == null:
|
if _staged.is_empty() or _network_sale == null:
|
||||||
return
|
return
|
||||||
|
|
@ -154,6 +216,7 @@ func _submit_sale() -> void:
|
||||||
|
|
||||||
func _on_sale_pending(_request_id: String) -> void:
|
func _on_sale_pending(_request_id: String) -> void:
|
||||||
_sell_button.disabled = true
|
_sell_button.disabled = true
|
||||||
|
_all_button.disabled = true
|
||||||
_feedback.text = "selling…"
|
_feedback.text = "selling…"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -243,6 +306,10 @@ func _refresh_tray() -> void:
|
||||||
or _network_sale == null
|
or _network_sale == null
|
||||||
or _network_sale.is_local_sale_pending()
|
or _network_sale.is_local_sale_pending()
|
||||||
)
|
)
|
||||||
|
_all_button.disabled = (
|
||||||
|
_network_sale != null
|
||||||
|
and _network_sale.is_local_sale_pending()
|
||||||
|
) or not _has_unstaged_eligible_entries()
|
||||||
call_deferred("_configure_focus")
|
call_deferred("_configure_focus")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -268,9 +335,32 @@ func _configure_focus() -> void:
|
||||||
if control != null and control.focus_mode != Control.FOCUS_NONE:
|
if control != null and control.focus_mode != Control.FOCUS_NONE:
|
||||||
controls.append(control)
|
controls.append(control)
|
||||||
controls.append(_sell_button)
|
controls.append(_sell_button)
|
||||||
|
controls.append(_all_button)
|
||||||
ControllerFocusNavigation.configure_spatial_neighbors(controls)
|
ControllerFocusNavigation.configure_spatial_neighbors(controls)
|
||||||
|
|
||||||
|
|
||||||
|
func _has_unstaged_eligible_entries() -> bool:
|
||||||
|
if _layout == null:
|
||||||
|
return false
|
||||||
|
for entry: Dictionary in _layout.get_entries(
|
||||||
|
PlayerInventoryLayout.InventoryContainer.INVENTORY
|
||||||
|
):
|
||||||
|
var kind := int(entry.get("kind", -1))
|
||||||
|
var identity := StringName(str(entry.get("identity", "")))
|
||||||
|
var key := (
|
||||||
|
PlayerInventoryLayout.catch_key(identity)
|
||||||
|
if kind == PlayerInventoryLayout.EntryKind.CATCH
|
||||||
|
else PlayerInventoryLayout.item_key(identity)
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
not identity.is_empty()
|
||||||
|
and not _staged.has(key)
|
||||||
|
and not _eligible_staged_record(kind, identity).is_empty()
|
||||||
|
):
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
|
||||||
func _calculate_total() -> int:
|
func _calculate_total() -> int:
|
||||||
var total: int = 0
|
var total: int = 0
|
||||||
for record: Dictionary in _staged.values():
|
for record: Dictionary in _staged.values():
|
||||||
|
|
@ -347,9 +437,19 @@ func _build_ui() -> void:
|
||||||
total_row.add_child(_total_label)
|
total_row.add_child(_total_label)
|
||||||
_sell_button = Button.new()
|
_sell_button = Button.new()
|
||||||
_sell_button.text = "sell"
|
_sell_button.text = "sell"
|
||||||
|
_sell_button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
UtilityPageStyle.apply_ocean_button(_sell_button)
|
UtilityPageStyle.apply_ocean_button(_sell_button)
|
||||||
_sell_button.pressed.connect(_submit_sale)
|
_sell_button.pressed.connect(_submit_sale)
|
||||||
(tray as VBoxContainer).add_child(_sell_button)
|
var sale_buttons := HBoxContainer.new()
|
||||||
|
sale_buttons.add_theme_constant_override("separation", 8)
|
||||||
|
(tray as VBoxContainer).add_child(sale_buttons)
|
||||||
|
sale_buttons.add_child(_sell_button)
|
||||||
|
_all_button = Button.new()
|
||||||
|
_all_button.text = "all"
|
||||||
|
_all_button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
UtilityPageStyle.apply_ocean_button(_all_button)
|
||||||
|
_all_button.pressed.connect(_stage_all_eligible)
|
||||||
|
sale_buttons.add_child(_all_button)
|
||||||
|
|
||||||
|
|
||||||
func _build_panel(parent: HBoxContainer, title_text: String) -> VBoxContainer:
|
func _build_panel(parent: HBoxContainer, title_text: String) -> VBoxContainer:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue