Add session mail and player gifts
This commit is contained in:
parent
5dda74c9e4
commit
e53ad1ac38
19 changed files with 1929 additions and 22 deletions
200
progression/player_asset_reservation_service.gd
Normal file
200
progression/player_asset_reservation_service.gd
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
class_name PlayerAssetReservationService
|
||||
extends Node
|
||||
|
||||
enum AttachmentType { NONE, FISH_COIN, FISH, CONSUMABLE }
|
||||
|
||||
signal reservations_changed
|
||||
|
||||
var _wallet: PlayerWallet
|
||||
var _inventory: FishInventory
|
||||
var _bag: PlayerBag
|
||||
var _catalog: ItemCatalog
|
||||
var _reservations: Dictionary[String, Dictionary] = {}
|
||||
|
||||
|
||||
func setup(
|
||||
wallet: PlayerWallet,
|
||||
inventory: FishInventory,
|
||||
bag: PlayerBag,
|
||||
catalog: ItemCatalog,
|
||||
) -> void:
|
||||
_wallet = wallet
|
||||
_inventory = inventory
|
||||
_bag = bag
|
||||
_catalog = catalog
|
||||
|
||||
|
||||
func reserve(reservation_id: String, attachment: Dictionary) -> bool:
|
||||
if (
|
||||
reservation_id.is_empty()
|
||||
or reservation_id.length() > 96
|
||||
or _reservations.has(reservation_id)
|
||||
or not validate_attachment(attachment)
|
||||
):
|
||||
return false
|
||||
var kind: int = attachment["type"]
|
||||
match kind:
|
||||
AttachmentType.NONE:
|
||||
return true
|
||||
AttachmentType.FISH_COIN:
|
||||
if int(attachment["amount"]) > get_available_fish_coin():
|
||||
return false
|
||||
AttachmentType.FISH:
|
||||
var catch_id := StringName(str(attachment["catch_id"]))
|
||||
var fish_catch := _inventory.get_catch_by_id(catch_id)
|
||||
if (
|
||||
fish_catch == null
|
||||
or fish_catch.is_favorited
|
||||
or is_fish_reserved(catch_id)
|
||||
):
|
||||
return false
|
||||
AttachmentType.CONSUMABLE:
|
||||
var item_id := StringName(str(attachment["item_id"]))
|
||||
if (
|
||||
int(attachment["quantity"])
|
||||
> get_available_item_quantity(item_id)
|
||||
):
|
||||
return false
|
||||
_reservations[reservation_id] = attachment.duplicate(true)
|
||||
reservations_changed.emit()
|
||||
return true
|
||||
|
||||
|
||||
func release(reservation_id: String) -> bool:
|
||||
if not _reservations.erase(reservation_id):
|
||||
return false
|
||||
reservations_changed.emit()
|
||||
return true
|
||||
|
||||
|
||||
func release_all() -> void:
|
||||
if _reservations.is_empty():
|
||||
return
|
||||
_reservations.clear()
|
||||
reservations_changed.emit()
|
||||
|
||||
|
||||
func has_reservation(reservation_id: String) -> bool:
|
||||
return _reservations.has(reservation_id)
|
||||
|
||||
|
||||
func get_reservation(reservation_id: String) -> Dictionary:
|
||||
return _reservations.get(reservation_id, {}).duplicate(true)
|
||||
|
||||
|
||||
func get_available_fish_coin() -> int:
|
||||
return maxi(_wallet.get_balance() - get_reserved_fish_coin(), 0)
|
||||
|
||||
|
||||
func get_reserved_fish_coin() -> int:
|
||||
var total := 0
|
||||
for attachment: Dictionary in _reservations.values():
|
||||
if int(attachment.get("type", 0)) == AttachmentType.FISH_COIN:
|
||||
total += int(attachment.get("amount", 0))
|
||||
return total
|
||||
|
||||
|
||||
func get_available_item_quantity(item_id: StringName) -> int:
|
||||
return maxi(_bag.get_quantity(item_id) - get_reserved_item_quantity(item_id), 0)
|
||||
|
||||
|
||||
func get_reserved_item_quantity(item_id: StringName) -> int:
|
||||
var total := 0
|
||||
for attachment: Dictionary in _reservations.values():
|
||||
if (
|
||||
int(attachment.get("type", 0)) == AttachmentType.CONSUMABLE
|
||||
and StringName(str(attachment.get("item_id", ""))) == item_id
|
||||
):
|
||||
total += int(attachment.get("quantity", 0))
|
||||
return total
|
||||
|
||||
|
||||
func is_fish_reserved(catch_id: StringName) -> bool:
|
||||
for attachment: Dictionary in _reservations.values():
|
||||
if (
|
||||
int(attachment.get("type", 0)) == AttachmentType.FISH
|
||||
and StringName(str(attachment.get("catch_id", ""))) == catch_id
|
||||
):
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func can_commit(reservation_id: String) -> bool:
|
||||
var attachment := get_reservation(reservation_id)
|
||||
if attachment.is_empty():
|
||||
return false
|
||||
match int(attachment["type"]):
|
||||
AttachmentType.FISH_COIN:
|
||||
return _wallet.can_afford(int(attachment["amount"]))
|
||||
AttachmentType.FISH:
|
||||
return _inventory.get_catch_by_id(
|
||||
StringName(str(attachment["catch_id"]))
|
||||
) != null
|
||||
AttachmentType.CONSUMABLE:
|
||||
return (
|
||||
_bag.get_quantity(StringName(str(attachment["item_id"])))
|
||||
>= int(attachment["quantity"])
|
||||
)
|
||||
return false
|
||||
|
||||
|
||||
func commit_removal(reservation_id: String) -> bool:
|
||||
var attachment := get_reservation(reservation_id)
|
||||
if attachment.is_empty() or not can_commit(reservation_id):
|
||||
return false
|
||||
var applied := false
|
||||
match int(attachment["type"]):
|
||||
AttachmentType.FISH_COIN:
|
||||
applied = _wallet.debit(int(attachment["amount"]))
|
||||
AttachmentType.FISH:
|
||||
applied = _inventory.remove_catch_by_id(
|
||||
StringName(str(attachment["catch_id"]))
|
||||
) != null
|
||||
AttachmentType.CONSUMABLE:
|
||||
applied = _bag.remove_item(
|
||||
StringName(str(attachment["item_id"])),
|
||||
int(attachment["quantity"])
|
||||
)
|
||||
if applied:
|
||||
release(reservation_id)
|
||||
return applied
|
||||
|
||||
|
||||
func validate_attachment(attachment: Dictionary) -> bool:
|
||||
if typeof(attachment.get("type")) != TYPE_INT:
|
||||
return false
|
||||
match int(attachment["type"]):
|
||||
AttachmentType.NONE:
|
||||
return attachment.size() == 1
|
||||
AttachmentType.FISH_COIN:
|
||||
return (
|
||||
attachment.size() == 2
|
||||
and
|
||||
typeof(attachment.get("amount")) == TYPE_INT
|
||||
and int(attachment["amount"]) >= 1
|
||||
and int(attachment["amount"]) <= 1000000000
|
||||
)
|
||||
AttachmentType.FISH:
|
||||
return (
|
||||
attachment.size() == 3
|
||||
and
|
||||
typeof(attachment.get("catch_id")) == TYPE_STRING
|
||||
and not str(attachment["catch_id"]).is_empty()
|
||||
and str(attachment["catch_id"]).length() <= 160
|
||||
and typeof(attachment.get("catch")) == TYPE_DICTIONARY
|
||||
)
|
||||
AttachmentType.CONSUMABLE:
|
||||
if (
|
||||
attachment.size() != 3
|
||||
or
|
||||
typeof(attachment.get("item_id")) != TYPE_STRING
|
||||
or typeof(attachment.get("quantity")) != TYPE_INT
|
||||
or int(attachment["quantity"]) < 1
|
||||
or int(attachment["quantity"]) > 999
|
||||
):
|
||||
return false
|
||||
var item := _catalog.get_item_by_id(
|
||||
StringName(str(attachment["item_id"]))
|
||||
)
|
||||
return item != null and item.category == ItemData.Category.CONSUMABLE
|
||||
return false
|
||||
1
progression/player_asset_reservation_service.gd.uid
Normal file
1
progression/player_asset_reservation_service.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bheplri3k6ch7
|
||||
Loading…
Add table
Add a link
Reference in a new issue