Add multi-select batch fish selling
This commit is contained in:
parent
9277326164
commit
e560cc0b3e
9 changed files with 747 additions and 272 deletions
|
|
@ -8,12 +8,15 @@ enum Status {
|
|||
INVALID_VALUE,
|
||||
INVALID_BUYER,
|
||||
INVALID_OFFER,
|
||||
INVALID_SELECTION,
|
||||
TRANSACTION_FAILED,
|
||||
}
|
||||
|
||||
var success: bool = false
|
||||
var status: Status = Status.TRANSACTION_FAILED
|
||||
var catch_id: StringName
|
||||
var catch_ids: Array[StringName] = []
|
||||
var fish_count: int = 0
|
||||
var fish_name: String = ""
|
||||
var buyer_id: StringName
|
||||
var buyer_display_name: String = ""
|
||||
|
|
@ -32,14 +35,16 @@ func get_message() -> String:
|
|||
Status.SUCCESS:
|
||||
return sale_message
|
||||
Status.NOT_FOUND:
|
||||
return "Fish no longer exists."
|
||||
return "fish no longer exists."
|
||||
Status.FAVORITED:
|
||||
return "Favorited fish cannot be sold."
|
||||
return "favorited fish cannot be sold."
|
||||
Status.INVALID_VALUE:
|
||||
return "Invalid sale value."
|
||||
return "invalid sale value."
|
||||
Status.INVALID_BUYER:
|
||||
return "Buyer is unavailable."
|
||||
return "buyer is unavailable."
|
||||
Status.INVALID_OFFER:
|
||||
return "Invalid buyer offer."
|
||||
return "invalid buyer offer."
|
||||
Status.INVALID_SELECTION:
|
||||
return "the fish selection is invalid."
|
||||
_:
|
||||
return "Transaction failed."
|
||||
return "transaction failed."
|
||||
|
|
|
|||
|
|
@ -25,24 +25,53 @@ func can_sell(
|
|||
catch_id: StringName,
|
||||
buyer: FishBuyerProfileType,
|
||||
) -> bool:
|
||||
return _validate_sale(catch_id, buyer).is_success()
|
||||
return preview_batch([catch_id], buyer).is_success()
|
||||
|
||||
|
||||
func can_sell_batch(
|
||||
catch_ids: Array[StringName],
|
||||
buyer: FishBuyerProfileType,
|
||||
) -> bool:
|
||||
return preview_batch(catch_ids, buyer).is_success()
|
||||
|
||||
|
||||
func preview_batch(
|
||||
catch_ids: Array[StringName],
|
||||
buyer: FishBuyerProfileType,
|
||||
) -> FishSaleResultType:
|
||||
return _validate_batch(catch_ids, buyer)
|
||||
|
||||
|
||||
func sell(
|
||||
catch_id: StringName,
|
||||
buyer: FishBuyerProfileType,
|
||||
) -> FishSaleResultType:
|
||||
var result: FishSaleResultType = _validate_sale(catch_id, buyer)
|
||||
return sell_batch([catch_id], buyer)
|
||||
|
||||
|
||||
func sell_batch(
|
||||
catch_ids: Array[StringName],
|
||||
buyer: FishBuyerProfileType,
|
||||
) -> FishSaleResultType:
|
||||
var result: FishSaleResultType = _validate_batch(catch_ids, buyer)
|
||||
if not result.is_success():
|
||||
return result
|
||||
|
||||
var removed_catch: FishCatchType = _inventory.remove_catch_by_id(catch_id)
|
||||
if removed_catch == null:
|
||||
var inventory_snapshot: Array[FishCatchType] = _inventory.get_all_catches()
|
||||
var next_sequence_snapshot: int = _inventory.get_next_catch_sequence()
|
||||
var removed_catches: Array[FishCatchType] = (
|
||||
_inventory.remove_catches_by_ids(result.catch_ids)
|
||||
)
|
||||
if removed_catches.size() != result.catch_ids.size():
|
||||
result.success = false
|
||||
result.status = FishSaleResultType.Status.NOT_FOUND
|
||||
result.status = FishSaleResultType.Status.TRANSACTION_FAILED
|
||||
return result
|
||||
if not _wallet.credit(result.payout):
|
||||
_inventory.add_catch(removed_catch)
|
||||
if not _inventory.replace_all_catches(
|
||||
inventory_snapshot,
|
||||
next_sequence_snapshot
|
||||
):
|
||||
push_error("Unable to roll back a failed fish batch sale.")
|
||||
result.success = false
|
||||
result.status = FishSaleResultType.Status.TRANSACTION_FAILED
|
||||
return result
|
||||
|
|
@ -50,27 +79,22 @@ func sell(
|
|||
return result
|
||||
|
||||
|
||||
func _validate_sale(
|
||||
catch_id: StringName,
|
||||
func _validate_batch(
|
||||
catch_ids: Array[StringName],
|
||||
buyer: FishBuyerProfileType,
|
||||
) -> FishSaleResultType:
|
||||
var result := FishSaleResultType.new()
|
||||
result.catch_id = catch_id
|
||||
if (
|
||||
catch_id.is_empty()
|
||||
or _inventory == null
|
||||
or _wallet == null
|
||||
):
|
||||
result.status = FishSaleResultType.Status.NOT_FOUND
|
||||
result.catch_ids = catch_ids.duplicate()
|
||||
result.fish_count = catch_ids.size()
|
||||
if _inventory == null or _wallet == null:
|
||||
result.status = FishSaleResultType.Status.TRANSACTION_FAILED
|
||||
return result
|
||||
if catch_ids.is_empty():
|
||||
result.status = FishSaleResultType.Status.INVALID_SELECTION
|
||||
return result
|
||||
if buyer == null or not buyer.is_valid():
|
||||
result.status = FishSaleResultType.Status.INVALID_BUYER
|
||||
return result
|
||||
var fish_catch: FishCatchType = _inventory.get_catch_by_id(catch_id)
|
||||
if fish_catch == null:
|
||||
result.status = FishSaleResultType.Status.NOT_FOUND
|
||||
return result
|
||||
result.fish_name = fish_catch.fish.display_name
|
||||
result.buyer_id = buyer.id
|
||||
result.buyer_display_name = buyer.display_name
|
||||
result.buyer_animal_name = (
|
||||
|
|
@ -78,21 +102,55 @@ func _validate_sale(
|
|||
if not buyer.animal_name_plural.is_empty()
|
||||
else buyer.display_name
|
||||
)
|
||||
result.base_value = fish_catch.sale_value
|
||||
result.payout = buyer.get_offer(result.base_value)
|
||||
if fish_catch.is_favorited:
|
||||
var seen_ids: Dictionary[StringName, bool] = {}
|
||||
var contains_favorite: bool = false
|
||||
const MAX_SAFE_TOTAL: int = 9223372036854775807
|
||||
for catch_id: StringName in catch_ids:
|
||||
if catch_id.is_empty() or seen_ids.has(catch_id):
|
||||
result.status = FishSaleResultType.Status.INVALID_SELECTION
|
||||
return result
|
||||
seen_ids[catch_id] = true
|
||||
var fish_catch: FishCatchType = _inventory.get_catch_by_id(catch_id)
|
||||
if fish_catch == null:
|
||||
result.status = FishSaleResultType.Status.NOT_FOUND
|
||||
return result
|
||||
if fish_catch.is_favorited:
|
||||
contains_favorite = true
|
||||
if fish_catch.sale_value < 0:
|
||||
result.status = FishSaleResultType.Status.INVALID_VALUE
|
||||
return result
|
||||
var offer: int = buyer.get_offer(fish_catch.sale_value)
|
||||
if offer < 0:
|
||||
result.status = FishSaleResultType.Status.INVALID_OFFER
|
||||
return result
|
||||
if (
|
||||
result.base_value > MAX_SAFE_TOTAL - fish_catch.sale_value
|
||||
or result.payout > MAX_SAFE_TOTAL - offer
|
||||
):
|
||||
result.status = FishSaleResultType.Status.TRANSACTION_FAILED
|
||||
return result
|
||||
result.base_value += fish_catch.sale_value
|
||||
result.payout += offer
|
||||
if result.fish_count == 1:
|
||||
result.catch_id = fish_catch.catch_id
|
||||
result.fish_name = fish_catch.fish.display_name
|
||||
if contains_favorite:
|
||||
result.status = FishSaleResultType.Status.FAVORITED
|
||||
elif fish_catch.sale_value < 0:
|
||||
result.status = FishSaleResultType.Status.INVALID_VALUE
|
||||
elif result.payout < 0:
|
||||
result.status = FishSaleResultType.Status.INVALID_OFFER
|
||||
elif not _wallet.can_credit(result.payout):
|
||||
return result
|
||||
if not _wallet.can_credit(result.payout):
|
||||
result.status = FishSaleResultType.Status.TRANSACTION_FAILED
|
||||
else:
|
||||
result.status = FishSaleResultType.Status.SUCCESS
|
||||
result.success = true
|
||||
return result
|
||||
result.status = FishSaleResultType.Status.SUCCESS
|
||||
result.success = true
|
||||
if result.fish_count == 1:
|
||||
result.sale_message = buyer.get_sale_message(
|
||||
result.fish_name,
|
||||
result.payout
|
||||
)
|
||||
else:
|
||||
result.sale_message = "you sold %d fish to the %s for $%d." % [
|
||||
result.fish_count,
|
||||
result.buyer_animal_name,
|
||||
result.payout,
|
||||
]
|
||||
return result
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue