Add shop supplies and rebalance early economy
This commit is contained in:
parent
6386c5e3e3
commit
6a5923fdb8
41 changed files with 1159 additions and 52 deletions
|
|
@ -8,5 +8,5 @@ id = &"pelicans"
|
||||||
display_name = "Pelicans"
|
display_name = "Pelicans"
|
||||||
animal_name_singular = "pelican"
|
animal_name_singular = "pelican"
|
||||||
animal_name_plural = "pelicans"
|
animal_name_plural = "pelicans"
|
||||||
payout_multiplier = 0.7
|
payout_multiplier = 0.25
|
||||||
sale_message_template = "You sold your {fish} to the pelicans for ${payout}."
|
sale_message_template = "You sold your {fish} to the pelicans for ${payout}."
|
||||||
|
|
|
||||||
58
economy/fishing_shop_stock.gd
Normal file
58
economy/fishing_shop_stock.gd
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
class_name FishingShopStock
|
||||||
|
extends RefCounted
|
||||||
|
|
||||||
|
const ItemCatalogType = preload("res://items/item_catalog.gd")
|
||||||
|
const ItemDataType = preload("res://items/item_data.gd")
|
||||||
|
const PlayerBagType = preload("res://inventory/player_bag.gd")
|
||||||
|
const PlayerWalletType = preload("res://economy/player_wallet.gd")
|
||||||
|
|
||||||
|
const ITEM_PRICES: Dictionary[StringName, int] = {
|
||||||
|
&"coffee": 20,
|
||||||
|
&"energy_drink": 35,
|
||||||
|
&"snack": 30,
|
||||||
|
&"fish_finder": 60,
|
||||||
|
}
|
||||||
|
const ITEM_ORDER: Array[StringName] = [
|
||||||
|
&"coffee",
|
||||||
|
&"energy_drink",
|
||||||
|
&"snack",
|
||||||
|
&"fish_finder",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
static func get_price(item_id: StringName) -> int:
|
||||||
|
return ITEM_PRICES.get(item_id, -1)
|
||||||
|
|
||||||
|
|
||||||
|
static func get_stock_item_ids() -> Array[StringName]:
|
||||||
|
return ITEM_ORDER.duplicate()
|
||||||
|
|
||||||
|
|
||||||
|
static func purchase_one(
|
||||||
|
item_id: StringName,
|
||||||
|
wallet: PlayerWalletType,
|
||||||
|
bag: PlayerBagType,
|
||||||
|
catalog: ItemCatalogType,
|
||||||
|
) -> bool:
|
||||||
|
if wallet == null or bag == null or catalog == null:
|
||||||
|
return false
|
||||||
|
var price: int = get_price(item_id)
|
||||||
|
var item: ItemDataType = catalog.get_item_by_id(item_id)
|
||||||
|
if (
|
||||||
|
price < 0
|
||||||
|
or item == null
|
||||||
|
or not item.is_valid()
|
||||||
|
or item.category != ItemDataType.Category.CONSUMABLE
|
||||||
|
or not item.stackable
|
||||||
|
or not item.usable
|
||||||
|
or not bag.can_add_item(item_id, 1)
|
||||||
|
or not wallet.can_afford(price)
|
||||||
|
):
|
||||||
|
return false
|
||||||
|
if not wallet.debit(price):
|
||||||
|
return false
|
||||||
|
if bag.add_item(item_id, 1):
|
||||||
|
return true
|
||||||
|
if not wallet.credit(price):
|
||||||
|
push_error("Fishing Shop failed to roll back an item purchase.")
|
||||||
|
return false
|
||||||
1
economy/fishing_shop_stock.gd.uid
Normal file
1
economy/fishing_shop_stock.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://dvvvjfah26pp3
|
||||||
|
|
@ -8,6 +8,7 @@ const FishPoolType = preload("res://fish/fish_pool.gd")
|
||||||
const FishingContextType = preload("res://fishing/fishing_context.gd")
|
const FishingContextType = preload("res://fishing/fishing_context.gd")
|
||||||
|
|
||||||
var undiscovered_weight_multiplier: float = 1.5
|
var undiscovered_weight_multiplier: float = 1.5
|
||||||
|
var rarity_weight_multipliers: Array[float] = []
|
||||||
var use_deterministic_test_seed: bool = false
|
var use_deterministic_test_seed: bool = false
|
||||||
var deterministic_test_seed: int = 24680
|
var deterministic_test_seed: int = 24680
|
||||||
var selection_seed: int = 0
|
var selection_seed: int = 0
|
||||||
|
|
@ -45,6 +46,8 @@ func select_fish(
|
||||||
final_weight *= fish.availability.get_bait_weight_multiplier(context)
|
final_weight *= fish.availability.get_bait_weight_multiplier(context)
|
||||||
if not collection_log.has_discovered(fish.id):
|
if not collection_log.has_discovered(fish.id):
|
||||||
final_weight *= maxf(undiscovered_weight_multiplier, 0.0)
|
final_weight *= maxf(undiscovered_weight_multiplier, 0.0)
|
||||||
|
if fish.rarity >= 0 and fish.rarity < rarity_weight_multipliers.size():
|
||||||
|
final_weight *= maxf(rarity_weight_multipliers[fish.rarity], 0.0)
|
||||||
if final_weight <= 0.0:
|
if final_weight <= 0.0:
|
||||||
continue
|
continue
|
||||||
eligible_fish.append(fish)
|
eligible_fish.append(fish)
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ weight_max_lb = 8.0
|
||||||
display_scale_min = 0.9
|
display_scale_min = 0.9
|
||||||
display_scale_max = 1.5
|
display_scale_max = 1.5
|
||||||
display_scale_curve = 0.9
|
display_scale_curve = 0.9
|
||||||
sell_value_min = 12
|
sell_value_min = 7
|
||||||
sell_value_max = 45
|
sell_value_max = 7
|
||||||
sell_value_curve = 0.9
|
sell_value_curve = 0.9
|
||||||
display_texture = ExtResource("4_texture")
|
display_texture = ExtResource("4_texture")
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,6 @@ display_scale_min = 0.7
|
||||||
display_scale_max = 1.1
|
display_scale_max = 1.1
|
||||||
display_scale_curve = 1.0
|
display_scale_curve = 1.0
|
||||||
sell_value_min = 3
|
sell_value_min = 3
|
||||||
sell_value_max = 12
|
sell_value_max = 3
|
||||||
sell_value_curve = 1.0
|
sell_value_curve = 1.0
|
||||||
display_texture = ExtResource("4_texture")
|
display_texture = ExtResource("4_texture")
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ weight_max_lb = 18.0
|
||||||
display_scale_min = 1.0
|
display_scale_min = 1.0
|
||||||
display_scale_max = 1.8
|
display_scale_max = 1.8
|
||||||
display_scale_curve = 0.85
|
display_scale_curve = 0.85
|
||||||
sell_value_min = 25
|
sell_value_min = 10
|
||||||
sell_value_max = 90
|
sell_value_max = 10
|
||||||
sell_value_curve = 0.85
|
sell_value_curve = 0.85
|
||||||
display_texture = ExtResource("4_texture")
|
display_texture = ExtResource("4_texture")
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,13 @@ func set_reel_input(held: bool) -> void:
|
||||||
_auto_click_accumulator = 0.0
|
_auto_click_accumulator = 0.0
|
||||||
|
|
||||||
|
|
||||||
|
func set_effective_stats(reel_speed: float, click_power: int) -> void:
|
||||||
|
if state == CatchState.IDLE:
|
||||||
|
return
|
||||||
|
_reel_speed = maxf(reel_speed, 0.0)
|
||||||
|
_click_power = maxi(click_power, 1)
|
||||||
|
|
||||||
|
|
||||||
func handle_primary_pressed() -> void:
|
func handle_primary_pressed() -> void:
|
||||||
if state not in [CatchState.REELING, CatchState.BLOCKED_BY_BARRIER]:
|
if state not in [CatchState.REELING, CatchState.BLOCKED_BY_BARRIER]:
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,12 @@ const PlayerHotbarType = preload("res://inventory/player_hotbar.gd")
|
||||||
const PlayerFishingUpgradesType = preload(
|
const PlayerFishingUpgradesType = preload(
|
||||||
"res://progression/player_fishing_upgrades.gd"
|
"res://progression/player_fishing_upgrades.gd"
|
||||||
)
|
)
|
||||||
|
const PlayerItemEffectsType = preload(
|
||||||
|
"res://progression/player_item_effects.gd"
|
||||||
|
)
|
||||||
|
const PlayerCoolerCapacityType = preload(
|
||||||
|
"res://progression/player_cooler_capacity.gd"
|
||||||
|
)
|
||||||
const PlayerType = preload("res://player/player.gd")
|
const PlayerType = preload("res://player/player.gd")
|
||||||
const FishableWaterRegionType = preload(
|
const FishableWaterRegionType = preload(
|
||||||
"res://world/fishable_water_region.gd"
|
"res://world/fishable_water_region.gd"
|
||||||
|
|
@ -96,6 +102,8 @@ var _local_bag: PlayerBagType
|
||||||
var _local_hotbar: PlayerHotbarType
|
var _local_hotbar: PlayerHotbarType
|
||||||
var _item_catalog: ItemCatalogType
|
var _item_catalog: ItemCatalogType
|
||||||
var _fishing_upgrades: PlayerFishingUpgradesType
|
var _fishing_upgrades: PlayerFishingUpgradesType
|
||||||
|
var _item_effects: PlayerItemEffectsType
|
||||||
|
var _cooler_capacity: PlayerCoolerCapacityType
|
||||||
var _active_player: PlayerType
|
var _active_player: PlayerType
|
||||||
var _state_time_remaining: float = 0.0
|
var _state_time_remaining: float = 0.0
|
||||||
var _cast_charge: float = 0.0
|
var _cast_charge: float = 0.0
|
||||||
|
|
@ -137,6 +145,8 @@ func setup(
|
||||||
local_hotbar: PlayerHotbarType,
|
local_hotbar: PlayerHotbarType,
|
||||||
item_catalog: ItemCatalogType,
|
item_catalog: ItemCatalogType,
|
||||||
fishing_upgrades: PlayerFishingUpgradesType,
|
fishing_upgrades: PlayerFishingUpgradesType,
|
||||||
|
item_effects: PlayerItemEffectsType,
|
||||||
|
cooler_capacity: PlayerCoolerCapacityType,
|
||||||
) -> void:
|
) -> void:
|
||||||
_local_player = local_player
|
_local_player = local_player
|
||||||
_local_inventory = local_inventory
|
_local_inventory = local_inventory
|
||||||
|
|
@ -145,6 +155,18 @@ func setup(
|
||||||
_local_hotbar = local_hotbar
|
_local_hotbar = local_hotbar
|
||||||
_item_catalog = item_catalog
|
_item_catalog = item_catalog
|
||||||
_fishing_upgrades = fishing_upgrades
|
_fishing_upgrades = fishing_upgrades
|
||||||
|
_item_effects = item_effects
|
||||||
|
_cooler_capacity = cooler_capacity
|
||||||
|
if not _local_inventory.catches_changed.is_connected(
|
||||||
|
_on_cooler_availability_changed
|
||||||
|
):
|
||||||
|
_local_inventory.catches_changed.connect(
|
||||||
|
_on_cooler_availability_changed
|
||||||
|
)
|
||||||
|
if not _cooler_capacity.capacity_changed.is_connected(
|
||||||
|
_on_cooler_capacity_changed
|
||||||
|
):
|
||||||
|
_cooler_capacity.capacity_changed.connect(_on_cooler_capacity_changed)
|
||||||
|
|
||||||
|
|
||||||
func can_open_player_menu() -> bool:
|
func can_open_player_menu() -> bool:
|
||||||
|
|
@ -322,6 +344,10 @@ func _process(delta: float) -> void:
|
||||||
FishingState.WAITING_FOR_BITE:
|
FishingState.WAITING_FOR_BITE:
|
||||||
_update_waiting_for_bite(delta)
|
_update_waiting_for_bite(delta)
|
||||||
FishingState.FIGHTING:
|
FishingState.FIGHTING:
|
||||||
|
_catch_controller.set_effective_stats(
|
||||||
|
_get_effective_reel_speed(),
|
||||||
|
_get_effective_barrier_damage()
|
||||||
|
)
|
||||||
if not Input.is_action_pressed("fish_primary"):
|
if not Input.is_action_pressed("fish_primary"):
|
||||||
_catch_controller.set_reel_input(false)
|
_catch_controller.set_reel_input(false)
|
||||||
FishingState.COOLDOWN:
|
FishingState.COOLDOWN:
|
||||||
|
|
@ -347,10 +373,29 @@ func _unhandled_input(event: InputEvent) -> void:
|
||||||
FishingState.READY:
|
FishingState.READY:
|
||||||
if not _new_cast_press_armed:
|
if not _new_cast_press_armed:
|
||||||
return
|
return
|
||||||
|
var active_item: ItemDataType = _get_active_item()
|
||||||
|
if (
|
||||||
|
active_item != null
|
||||||
|
and active_item.category == ItemDataType.Category.CONSUMABLE
|
||||||
|
):
|
||||||
|
if _item_effects.use_consumable(active_item, _local_bag):
|
||||||
|
status_changed.emit(
|
||||||
|
_item_effects.get_feedback(active_item.item_id)
|
||||||
|
)
|
||||||
|
get_viewport().set_input_as_handled()
|
||||||
|
return
|
||||||
if not has_active_fishing_rod():
|
if not has_active_fishing_rod():
|
||||||
status_changed.emit("Select a fishing rod to cast.")
|
status_changed.emit("Select a fishing rod to cast.")
|
||||||
get_viewport().set_input_as_handled()
|
get_viewport().set_input_as_handled()
|
||||||
return
|
return
|
||||||
|
if (
|
||||||
|
_is_cooler_full()
|
||||||
|
):
|
||||||
|
status_changed.emit(
|
||||||
|
"Cooler full. Sell fish before casting again."
|
||||||
|
)
|
||||||
|
get_viewport().set_input_as_handled()
|
||||||
|
return
|
||||||
_begin_aiming(_local_player)
|
_begin_aiming(_local_player)
|
||||||
FishingState.WAITING_FOR_BITE:
|
FishingState.WAITING_FOR_BITE:
|
||||||
_withdrawal_input_held = true
|
_withdrawal_input_held = true
|
||||||
|
|
@ -411,10 +456,7 @@ func has_active_fishing_rod() -> bool:
|
||||||
or _item_catalog == null
|
or _item_catalog == null
|
||||||
):
|
):
|
||||||
return false
|
return false
|
||||||
var item_id: StringName = _local_hotbar.get_selected_item_id()
|
var item: ItemDataType = _get_active_item()
|
||||||
if item_id.is_empty() or not _local_bag.owns_item(item_id):
|
|
||||||
return false
|
|
||||||
var item: ItemDataType = _item_catalog.get_item_by_id(item_id)
|
|
||||||
return (
|
return (
|
||||||
item != null
|
item != null
|
||||||
and item.is_valid()
|
and item.is_valid()
|
||||||
|
|
@ -424,6 +466,38 @@ func has_active_fishing_rod() -> bool:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _get_active_item() -> ItemDataType:
|
||||||
|
if (
|
||||||
|
_local_bag == null
|
||||||
|
or _local_hotbar == null
|
||||||
|
or _item_catalog == null
|
||||||
|
):
|
||||||
|
return null
|
||||||
|
var item_id: StringName = _local_hotbar.get_selected_item_id()
|
||||||
|
if item_id.is_empty() or not _local_bag.owns_item(item_id):
|
||||||
|
return null
|
||||||
|
var item: ItemDataType = _item_catalog.get_item_by_id(item_id)
|
||||||
|
return item if item != null and item.is_valid() else null
|
||||||
|
|
||||||
|
|
||||||
|
func _is_cooler_full() -> bool:
|
||||||
|
return (
|
||||||
|
_cooler_capacity != null
|
||||||
|
and _local_inventory != null
|
||||||
|
and _local_inventory.get_all_catches().size()
|
||||||
|
>= _cooler_capacity.get_capacity()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_cooler_availability_changed() -> void:
|
||||||
|
if state == FishingState.READY and not _is_cooler_full():
|
||||||
|
refresh_active_item_status()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_cooler_capacity_changed(_level: int, _capacity: int) -> void:
|
||||||
|
_on_cooler_availability_changed()
|
||||||
|
|
||||||
|
|
||||||
func is_fighting() -> bool:
|
func is_fighting() -> bool:
|
||||||
return state == FishingState.FIGHTING
|
return state == FishingState.FIGHTING
|
||||||
|
|
||||||
|
|
@ -472,6 +546,13 @@ func _on_cast_completed() -> void:
|
||||||
return
|
return
|
||||||
_selection_context = _build_fishing_context(_selected_water_region)
|
_selection_context = _build_fishing_context(_selected_water_region)
|
||||||
_fish_selector.undiscovered_weight_multiplier = undiscovered_weight_multiplier
|
_fish_selector.undiscovered_weight_multiplier = undiscovered_weight_multiplier
|
||||||
|
_fish_selector.rarity_weight_multipliers = []
|
||||||
|
for rarity: int in range(FishDataType.Rarity.size()):
|
||||||
|
_fish_selector.rarity_weight_multipliers.append(
|
||||||
|
_item_effects.get_rarity_weight_multiplier(rarity)
|
||||||
|
if _item_effects != null
|
||||||
|
else 1.0
|
||||||
|
)
|
||||||
_fish_selector.use_deterministic_test_seed = use_deterministic_selection_seed
|
_fish_selector.use_deterministic_test_seed = use_deterministic_selection_seed
|
||||||
_fish_selector.deterministic_test_seed = deterministic_selection_seed
|
_fish_selector.deterministic_test_seed = deterministic_selection_seed
|
||||||
_fish_selector.begin_roll()
|
_fish_selector.begin_roll()
|
||||||
|
|
@ -485,7 +566,11 @@ func _on_cast_completed() -> void:
|
||||||
return
|
return
|
||||||
|
|
||||||
state = FishingState.WAITING_FOR_BITE
|
state = FishingState.WAITING_FOR_BITE
|
||||||
_state_time_remaining = wait_time
|
_state_time_remaining = wait_time * (
|
||||||
|
_item_effects.get_bite_time_multiplier()
|
||||||
|
if _item_effects != null
|
||||||
|
else 1.0
|
||||||
|
)
|
||||||
_withdrawal_progress = 0.0
|
_withdrawal_progress = 0.0
|
||||||
_withdrawal_input_held = false
|
_withdrawal_input_held = false
|
||||||
_bobber_water_position = _cast_target
|
_bobber_water_position = _cast_target
|
||||||
|
|
@ -618,16 +703,8 @@ func _activate_bite() -> void:
|
||||||
_presentation.begin_reeling()
|
_presentation.begin_reeling()
|
||||||
_catch_controller.start_encounter(
|
_catch_controller.start_encounter(
|
||||||
_selected_fish.catch_profile,
|
_selected_fish.catch_profile,
|
||||||
_active_player.reel_speed * (
|
_get_effective_reel_speed(),
|
||||||
_fishing_upgrades.get_reel_speed_multiplier()
|
_get_effective_barrier_damage()
|
||||||
if _fishing_upgrades != null
|
|
||||||
else 1.0
|
|
||||||
),
|
|
||||||
(
|
|
||||||
_fishing_upgrades.get_barrier_damage()
|
|
||||||
if _fishing_upgrades != null
|
|
||||||
else _active_player.click_power
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
_catch_controller.set_reel_input(
|
_catch_controller.set_reel_input(
|
||||||
Input.is_action_pressed("fish_primary")
|
Input.is_action_pressed("fish_primary")
|
||||||
|
|
@ -635,6 +712,34 @@ func _activate_bite() -> void:
|
||||||
_presentation.show_bite()
|
_presentation.show_bite()
|
||||||
|
|
||||||
|
|
||||||
|
func _get_effective_reel_speed() -> float:
|
||||||
|
if _active_player == null:
|
||||||
|
return 0.0
|
||||||
|
return _active_player.reel_speed * (
|
||||||
|
_fishing_upgrades.get_reel_speed_multiplier()
|
||||||
|
if _fishing_upgrades != null
|
||||||
|
else 1.0
|
||||||
|
) * (
|
||||||
|
_item_effects.get_reel_multiplier()
|
||||||
|
if _item_effects != null
|
||||||
|
else 1.0
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _get_effective_barrier_damage() -> int:
|
||||||
|
if _active_player == null:
|
||||||
|
return 1
|
||||||
|
return (
|
||||||
|
_fishing_upgrades.get_barrier_damage()
|
||||||
|
if _fishing_upgrades != null
|
||||||
|
else _active_player.click_power
|
||||||
|
) + (
|
||||||
|
_item_effects.get_barrier_bonus()
|
||||||
|
if _item_effects != null
|
||||||
|
else 0
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
func _on_catch_encounter_updated(
|
func _on_catch_encounter_updated(
|
||||||
progress: float,
|
progress: float,
|
||||||
chase_progress: float,
|
chase_progress: float,
|
||||||
|
|
|
||||||
|
|
@ -16,19 +16,13 @@ func setup(catalog: ItemCatalogType) -> void:
|
||||||
|
|
||||||
|
|
||||||
func add_item(item_id: StringName, quantity: int = 1) -> bool:
|
func add_item(item_id: StringName, quantity: int = 1) -> bool:
|
||||||
var item: ItemDataType = _resolve_valid_item(item_id)
|
if not can_add_item(item_id, quantity):
|
||||||
if item == null or quantity <= 0:
|
|
||||||
return false
|
return false
|
||||||
|
var item: ItemDataType = _resolve_valid_item(item_id)
|
||||||
var existing: OwnedItemType = get_owned_item(item_id)
|
var existing: OwnedItemType = get_owned_item(item_id)
|
||||||
if existing != null:
|
if existing != null:
|
||||||
if not item.stackable:
|
|
||||||
return false
|
|
||||||
if existing.quantity + quantity > item.max_stack:
|
|
||||||
return false
|
|
||||||
existing.quantity += quantity
|
existing.quantity += quantity
|
||||||
else:
|
else:
|
||||||
if quantity > (item.max_stack if item.stackable else 1):
|
|
||||||
return false
|
|
||||||
var owned := OwnedItemType.new()
|
var owned := OwnedItemType.new()
|
||||||
owned.item_id = item_id
|
owned.item_id = item_id
|
||||||
owned.quantity = quantity
|
owned.quantity = quantity
|
||||||
|
|
@ -37,6 +31,19 @@ func add_item(item_id: StringName, quantity: int = 1) -> bool:
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
func can_add_item(item_id: StringName, quantity: int = 1) -> bool:
|
||||||
|
var item: ItemDataType = _resolve_valid_item(item_id)
|
||||||
|
if item == null or quantity <= 0:
|
||||||
|
return false
|
||||||
|
var existing: OwnedItemType = get_owned_item(item_id)
|
||||||
|
if existing != null:
|
||||||
|
return (
|
||||||
|
item.stackable
|
||||||
|
and existing.quantity + quantity <= item.max_stack
|
||||||
|
)
|
||||||
|
return quantity <= (item.max_stack if item.stackable else 1)
|
||||||
|
|
||||||
|
|
||||||
func remove_item(item_id: StringName, quantity: int = 1) -> bool:
|
func remove_item(item_id: StringName, quantity: int = 1) -> bool:
|
||||||
if quantity <= 0:
|
if quantity <= 0:
|
||||||
return false
|
return false
|
||||||
|
|
|
||||||
16
items/catalog/coffee.tres
Normal file
16
items/catalog/coffee.tres
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
[gd_resource type="Resource" script_class="ItemData" load_steps=3 format=3]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://items/item_data.gd" id="1"]
|
||||||
|
[ext_resource type="Texture2D" path="res://items/icons/placeholder/coffee.svg" id="2"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1")
|
||||||
|
item_id = &"coffee"
|
||||||
|
display_name = "Coffee"
|
||||||
|
description = "Temporarily increases ground movement speed."
|
||||||
|
category = 3
|
||||||
|
icon = ExtResource("2")
|
||||||
|
stackable = true
|
||||||
|
max_stack = 99
|
||||||
|
usable = true
|
||||||
|
hotbar_allowed = true
|
||||||
17
items/catalog/cooler_expansion.tres
Normal file
17
items/catalog/cooler_expansion.tres
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
[gd_resource type="Resource" script_class="ItemData" load_steps=3 format=3]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://items/item_data.gd" id="1"]
|
||||||
|
[ext_resource type="Texture2D" path="res://items/icons/placeholder/cooler_expansion.svg" id="2"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1")
|
||||||
|
item_id = &"cooler_expansion"
|
||||||
|
display_name = "Cooler Expansion"
|
||||||
|
description = "Permanently increases the number of fish the Cooler can hold."
|
||||||
|
category = 4
|
||||||
|
icon = ExtResource("2")
|
||||||
|
stackable = false
|
||||||
|
max_stack = 1
|
||||||
|
usable = false
|
||||||
|
equippable = false
|
||||||
|
hotbar_allowed = false
|
||||||
16
items/catalog/energy_drink.tres
Normal file
16
items/catalog/energy_drink.tres
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
[gd_resource type="Resource" script_class="ItemData" load_steps=3 format=3]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://items/item_data.gd" id="1"]
|
||||||
|
[ext_resource type="Texture2D" path="res://items/icons/placeholder/energy_drink.svg" id="2"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1")
|
||||||
|
item_id = &"energy_drink"
|
||||||
|
display_name = "Energy Drink"
|
||||||
|
description = "Temporarily increases reeling progress."
|
||||||
|
category = 3
|
||||||
|
icon = ExtResource("2")
|
||||||
|
stackable = true
|
||||||
|
max_stack = 99
|
||||||
|
usable = true
|
||||||
|
hotbar_allowed = true
|
||||||
16
items/catalog/fish_finder.tres
Normal file
16
items/catalog/fish_finder.tres
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
[gd_resource type="Resource" script_class="ItemData" load_steps=3 format=3]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://items/item_data.gd" id="1"]
|
||||||
|
[ext_resource type="Texture2D" path="res://items/icons/placeholder/fish_finder.svg" id="2"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1")
|
||||||
|
item_id = &"fish_finder"
|
||||||
|
display_name = "Fish Finder"
|
||||||
|
description = "Temporarily shortens bite waits and improves rarity weights."
|
||||||
|
category = 3
|
||||||
|
icon = ExtResource("2")
|
||||||
|
stackable = true
|
||||||
|
max_stack = 99
|
||||||
|
usable = true
|
||||||
|
hotbar_allowed = true
|
||||||
|
|
@ -1,8 +1,13 @@
|
||||||
[gd_resource type="Resource" script_class="ItemCatalog" load_steps=3 format=3]
|
[gd_resource type="Resource" script_class="ItemCatalog" load_steps=8 format=3]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://items/item_catalog.gd" id="1_script"]
|
[ext_resource type="Script" path="res://items/item_catalog.gd" id="1_script"]
|
||||||
[ext_resource type="Resource" path="res://items/catalog/basic_fishing_rod.tres" id="2_rod"]
|
[ext_resource type="Resource" path="res://items/catalog/basic_fishing_rod.tres" id="2_rod"]
|
||||||
|
[ext_resource type="Resource" path="res://items/catalog/coffee.tres" id="3_coffee"]
|
||||||
|
[ext_resource type="Resource" path="res://items/catalog/energy_drink.tres" id="4_energy"]
|
||||||
|
[ext_resource type="Resource" path="res://items/catalog/snack.tres" id="5_snack"]
|
||||||
|
[ext_resource type="Resource" path="res://items/catalog/fish_finder.tres" id="6_finder"]
|
||||||
|
[ext_resource type="Resource" path="res://items/catalog/cooler_expansion.tres" id="7_cooler"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_script")
|
script = ExtResource("1_script")
|
||||||
items = [ExtResource("2_rod")]
|
items = [ExtResource("2_rod"), ExtResource("3_coffee"), ExtResource("4_energy"), ExtResource("5_snack"), ExtResource("6_finder"), ExtResource("7_cooler")]
|
||||||
|
|
|
||||||
16
items/catalog/snack.tres
Normal file
16
items/catalog/snack.tres
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
[gd_resource type="Resource" script_class="ItemData" load_steps=3 format=3]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://items/item_data.gd" id="1"]
|
||||||
|
[ext_resource type="Texture2D" path="res://items/icons/placeholder/snack.svg" id="2"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1")
|
||||||
|
item_id = &"snack"
|
||||||
|
display_name = "Snack"
|
||||||
|
description = "Temporarily adds one barrier damage."
|
||||||
|
category = 3
|
||||||
|
icon = ExtResource("2")
|
||||||
|
stackable = true
|
||||||
|
max_stack = 99
|
||||||
|
usable = true
|
||||||
|
hotbar_allowed = true
|
||||||
5
items/icons/placeholder/coffee.svg
Normal file
5
items/icons/placeholder/coffee.svg
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||||
|
<path d="M18 22h29v27H18z" fill="#f3d6a4" stroke="#17243a" stroke-width="5"/>
|
||||||
|
<path d="M47 28h6q7 0 7 7t-7 7h-6" fill="none" stroke="#17243a" stroke-width="5"/>
|
||||||
|
<path d="M25 17q-5-5 0-10M38 17q-5-5 0-10" fill="none" stroke="#54c7c0" stroke-width="4" stroke-linecap="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 349 B |
43
items/icons/placeholder/coffee.svg.import
Normal file
43
items/icons/placeholder/coffee.svg.import
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://ddx3pbgh2ele5"
|
||||||
|
path="res://.godot/imported/coffee.svg-aecf16cc8c38e5e0f432cd5395949bcf.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://items/icons/placeholder/coffee.svg"
|
||||||
|
dest_files=["res://.godot/imported/coffee.svg-aecf16cc8c38e5e0f432cd5395949bcf.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=1.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
||||||
5
items/icons/placeholder/cooler_expansion.svg
Normal file
5
items/icons/placeholder/cooler_expansion.svg
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||||
|
<path d="M9 22h46v32H9z" fill="#72c7e8" stroke="#17243a" stroke-width="5"/>
|
||||||
|
<path d="M7 13h50v12H7z" fill="#fff3d4" stroke="#17243a" stroke-width="5"/>
|
||||||
|
<path d="M32 31v16M24 39h16" stroke="#ef6b88" stroke-width="6" stroke-linecap="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 314 B |
43
items/icons/placeholder/cooler_expansion.svg.import
Normal file
43
items/icons/placeholder/cooler_expansion.svg.import
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://d115jiqughf40"
|
||||||
|
path="res://.godot/imported/cooler_expansion.svg-a3d63bc21ba230007f1039372b518c8f.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://items/icons/placeholder/cooler_expansion.svg"
|
||||||
|
dest_files=["res://.godot/imported/cooler_expansion.svg-a3d63bc21ba230007f1039372b518c8f.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=1.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
||||||
4
items/icons/placeholder/energy_drink.svg
Normal file
4
items/icons/placeholder/energy_drink.svg
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||||
|
<path d="M20 9h25l3 7-3 39H20l-3-39z" fill="#ef6b88" stroke="#17243a" stroke-width="5"/>
|
||||||
|
<path d="M36 18l-10 17h8l-5 14 13-20h-8z" fill="#ffe26b" stroke="#17243a" stroke-width="3" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 278 B |
43
items/icons/placeholder/energy_drink.svg.import
Normal file
43
items/icons/placeholder/energy_drink.svg.import
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://d3elrkttv1f1h"
|
||||||
|
path="res://.godot/imported/energy_drink.svg-8d7bc90bd15610c7852e4cf522a5b1ca.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://items/icons/placeholder/energy_drink.svg"
|
||||||
|
dest_files=["res://.godot/imported/energy_drink.svg-8d7bc90bd15610c7852e4cf522a5b1ca.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=1.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
||||||
6
items/icons/placeholder/fish_finder.svg
Normal file
6
items/icons/placeholder/fish_finder.svg
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||||
|
<rect x="8" y="10" width="48" height="44" rx="5" fill="#54c7c0" stroke="#17243a" stroke-width="5"/>
|
||||||
|
<circle cx="31" cy="32" r="15" fill="#dff7f3" stroke="#17243a" stroke-width="4"/>
|
||||||
|
<path d="M31 32q7-8 15 0M31 32q5 6 10 0" fill="none" stroke="#ef6b88" stroke-width="3"/>
|
||||||
|
<circle cx="31" cy="32" r="3" fill="#17243a"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 394 B |
43
items/icons/placeholder/fish_finder.svg.import
Normal file
43
items/icons/placeholder/fish_finder.svg.import
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cxsaix6vp7t6u"
|
||||||
|
path="res://.godot/imported/fish_finder.svg-33ab7d731566e03c2f84e185d3503b7d.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://items/icons/placeholder/fish_finder.svg"
|
||||||
|
dest_files=["res://.godot/imported/fish_finder.svg-33ab7d731566e03c2f84e185d3503b7d.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=1.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
||||||
5
items/icons/placeholder/snack.svg
Normal file
5
items/icons/placeholder/snack.svg
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||||
|
<path d="M12 17l8-7h30l5 9-5 35H17L9 46z" fill="#f7a84a" stroke="#17243a" stroke-width="5" stroke-linejoin="round"/>
|
||||||
|
<path d="M22 29h22M20 39h25" stroke="#fff3d4" stroke-width="5" stroke-linecap="round"/>
|
||||||
|
<path d="M50 10q-8 2-6 10 8 1 11-5z" fill="#fff3d4" stroke="#17243a" stroke-width="4"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 367 B |
43
items/icons/placeholder/snack.svg.import
Normal file
43
items/icons/placeholder/snack.svg.import
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://i611n7iwr8i6"
|
||||||
|
path="res://.godot/imported/snack.svg-dfbab25d47c1c79c46c1d7fcf9b21cfe.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://items/icons/placeholder/snack.svg"
|
||||||
|
dest_files=["res://.godot/imported/snack.svg-dfbab25d47c1c79c46c1d7fcf9b21cfe.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=1.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
||||||
13
main/main.gd
13
main/main.gd
|
|
@ -62,7 +62,8 @@ func _ready() -> void:
|
||||||
_player.bag,
|
_player.bag,
|
||||||
_player.hotbar,
|
_player.hotbar,
|
||||||
item_catalog,
|
item_catalog,
|
||||||
_player.fishing_upgrades
|
_player.fishing_upgrades,
|
||||||
|
_player.cooler_capacity
|
||||||
)
|
)
|
||||||
_save_manager.set_autosave_enabled(false)
|
_save_manager.set_autosave_enabled(false)
|
||||||
_fishing_spot.setup(
|
_fishing_spot.setup(
|
||||||
|
|
@ -72,7 +73,9 @@ func _ready() -> void:
|
||||||
_player.bag,
|
_player.bag,
|
||||||
_player.hotbar,
|
_player.hotbar,
|
||||||
item_catalog,
|
item_catalog,
|
||||||
_player.fishing_upgrades
|
_player.fishing_upgrades,
|
||||||
|
_player.item_effects,
|
||||||
|
_player.cooler_capacity
|
||||||
)
|
)
|
||||||
_game_ui.setup(
|
_game_ui.setup(
|
||||||
_player,
|
_player,
|
||||||
|
|
@ -88,7 +91,9 @@ func _ready() -> void:
|
||||||
item_catalog,
|
item_catalog,
|
||||||
main_shop_buyer_profile,
|
main_shop_buyer_profile,
|
||||||
_player.fishing_upgrades,
|
_player.fishing_upgrades,
|
||||||
_shop_interaction
|
_shop_interaction,
|
||||||
|
_player.item_effects,
|
||||||
|
_player.cooler_capacity
|
||||||
)
|
)
|
||||||
_water_recovery.setup(
|
_water_recovery.setup(
|
||||||
_player,
|
_player,
|
||||||
|
|
@ -210,6 +215,8 @@ func _apply_runtime_settings(settings: PlayerSettingsType) -> void:
|
||||||
|
|
||||||
func _set_gameplay_active(active: bool) -> void:
|
func _set_gameplay_active(active: bool) -> void:
|
||||||
_gameplay_started = active
|
_gameplay_started = active
|
||||||
|
if not active:
|
||||||
|
_player.item_effects.reset_all()
|
||||||
_player.set_movement_enabled(active)
|
_player.set_movement_enabled(active)
|
||||||
_player.set_camera_input_enabled(active)
|
_player.set_camera_input_enabled(active)
|
||||||
_fishing_spot.set_gameplay_input_enabled(active)
|
_fishing_spot.set_gameplay_input_enabled(active)
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,12 @@ const PlayerHotbarType = preload("res://inventory/player_hotbar.gd")
|
||||||
const PlayerFishingUpgradesType = preload(
|
const PlayerFishingUpgradesType = preload(
|
||||||
"res://progression/player_fishing_upgrades.gd"
|
"res://progression/player_fishing_upgrades.gd"
|
||||||
)
|
)
|
||||||
|
const PlayerItemEffectsType = preload(
|
||||||
|
"res://progression/player_item_effects.gd"
|
||||||
|
)
|
||||||
|
const PlayerCoolerCapacityType = preload(
|
||||||
|
"res://progression/player_cooler_capacity.gd"
|
||||||
|
)
|
||||||
|
|
||||||
class ShowcaseCameraSnapshot:
|
class ShowcaseCameraSnapshot:
|
||||||
extends RefCounted
|
extends RefCounted
|
||||||
|
|
@ -75,6 +81,8 @@ class ShowcaseCameraSnapshot:
|
||||||
@onready var bag: PlayerBagType = %Bag
|
@onready var bag: PlayerBagType = %Bag
|
||||||
@onready var hotbar: PlayerHotbarType = %Hotbar
|
@onready var hotbar: PlayerHotbarType = %Hotbar
|
||||||
@onready var fishing_upgrades: PlayerFishingUpgradesType = %FishingUpgrades
|
@onready var fishing_upgrades: PlayerFishingUpgradesType = %FishingUpgrades
|
||||||
|
@onready var item_effects: PlayerItemEffectsType = %ItemEffects
|
||||||
|
@onready var cooler_capacity: PlayerCoolerCapacityType = %CoolerCapacity
|
||||||
@onready var _cast_origin: Marker3D = %CastOrigin
|
@onready var _cast_origin: Marker3D = %CastOrigin
|
||||||
@onready var _fishing_rod: Node3D = %FishingRod
|
@onready var _fishing_rod: Node3D = %FishingRod
|
||||||
@onready var _fishing_rod_tip: Marker3D = %FishingRodTip
|
@onready var _fishing_rod_tip: Marker3D = %FishingRodTip
|
||||||
|
|
@ -141,7 +149,9 @@ func _physics_process(delta: float) -> void:
|
||||||
var input_strength: float = minf(input_vector.length(), 1.0)
|
var input_strength: float = minf(input_vector.length(), 1.0)
|
||||||
move_direction = move_direction.normalized()
|
move_direction = move_direction.normalized()
|
||||||
|
|
||||||
var speed: float = _get_current_speed()
|
var speed: float = (
|
||||||
|
_get_current_speed() * item_effects.get_movement_multiplier()
|
||||||
|
)
|
||||||
velocity.x = move_direction.x * speed * input_strength
|
velocity.x = move_direction.x * speed * input_strength
|
||||||
velocity.z = move_direction.z * speed * input_strength
|
velocity.z = move_direction.z * speed * input_strength
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_scene load_steps=16 format=3]
|
[gd_scene load_steps=18 format=3]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://player/player.gd" id="1_script"]
|
[ext_resource type="Script" path="res://player/player.gd" id="1_script"]
|
||||||
[ext_resource type="Script" path="res://inventory/fish_inventory.gd" id="2_inventory"]
|
[ext_resource type="Script" path="res://inventory/fish_inventory.gd" id="2_inventory"]
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
[ext_resource type="Script" path="res://inventory/player_bag.gd" id="6_bag"]
|
[ext_resource type="Script" path="res://inventory/player_bag.gd" id="6_bag"]
|
||||||
[ext_resource type="Script" path="res://inventory/player_hotbar.gd" id="7_hotbar"]
|
[ext_resource type="Script" path="res://inventory/player_hotbar.gd" id="7_hotbar"]
|
||||||
[ext_resource type="Script" path="res://progression/player_fishing_upgrades.gd" id="8_upgrades"]
|
[ext_resource type="Script" path="res://progression/player_fishing_upgrades.gd" id="8_upgrades"]
|
||||||
|
[ext_resource type="Script" path="res://progression/player_item_effects.gd" id="9_effects"]
|
||||||
|
[ext_resource type="Script" path="res://progression/player_cooler_capacity.gd" id="10_capacity"]
|
||||||
|
|
||||||
[sub_resource type="CapsuleShape3D" id="PlayerShape"]
|
[sub_resource type="CapsuleShape3D" id="PlayerShape"]
|
||||||
radius = 0.45
|
radius = 0.45
|
||||||
|
|
@ -103,6 +105,14 @@ script = ExtResource("7_hotbar")
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
script = ExtResource("8_upgrades")
|
script = ExtResource("8_upgrades")
|
||||||
|
|
||||||
|
[node name="ItemEffects" type="Node" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
script = ExtResource("9_effects")
|
||||||
|
|
||||||
|
[node name="CoolerCapacity" type="Node" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
script = ExtResource("10_capacity")
|
||||||
|
|
||||||
[node name="CatchDisplayAnchor" type="Marker3D" parent="Visuals"]
|
[node name="CatchDisplayAnchor" type="Marker3D" parent="Visuals"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
position = Vector3(0, 1.45, -1.15)
|
position = Vector3(0, 1.45, -1.15)
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,10 @@ FISHING
|
||||||
- Accessibility auto-click can be enabled in Settings.
|
- Accessibility auto-click can be enabled in Settings.
|
||||||
- Approach the bright Fishing Shop booth and press E to open it.
|
- Approach the bright Fishing Shop booth and press E to open it.
|
||||||
- The Fishing Shop buys one Cooler fish at a time for full base value.
|
- The Fishing Shop buys one Cooler fish at a time for full base value.
|
||||||
|
- Buy Coffee, Energy Drinks, Snacks, and Fish Finders as Bag supplies.
|
||||||
|
- Drag supplies from Bag to the hotbar and left-click in READY to use one.
|
||||||
|
- Coffee improves movement; other supplies temporarily improve fishing.
|
||||||
|
- The Cooler starts at 12 fish; buy permanent capacity expansions at the shop.
|
||||||
- Reel Speed upgrades increase authoritative green reeling progress.
|
- Reel Speed upgrades increase authoritative green reeling progress.
|
||||||
- Barrier Power upgrades increase damage per valid barrier action.
|
- Barrier Power upgrades increase damage per valid barrier action.
|
||||||
- Shop upgrades persist in the local progression save.
|
- Shop upgrades persist in the local progression save.
|
||||||
|
|
|
||||||
65
progression/player_cooler_capacity.gd
Normal file
65
progression/player_cooler_capacity.gd
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
class_name PlayerCoolerCapacity
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
const PlayerWalletType = preload("res://economy/player_wallet.gd")
|
||||||
|
|
||||||
|
signal capacity_changed(level: int, capacity: int)
|
||||||
|
|
||||||
|
const CAPACITIES: Array[int] = [12, 18, 24, 32, 40]
|
||||||
|
const EXPANSION_COSTS: Array[int] = [75, 175, 400, 850]
|
||||||
|
const MAX_LEVEL: int = 4
|
||||||
|
|
||||||
|
var _capacity_level: int = 0
|
||||||
|
|
||||||
|
|
||||||
|
func get_level() -> int:
|
||||||
|
return _capacity_level
|
||||||
|
|
||||||
|
|
||||||
|
func get_capacity() -> int:
|
||||||
|
return CAPACITIES[_capacity_level]
|
||||||
|
|
||||||
|
|
||||||
|
func get_next_capacity() -> int:
|
||||||
|
if _capacity_level >= MAX_LEVEL:
|
||||||
|
return -1
|
||||||
|
return CAPACITIES[_capacity_level + 1]
|
||||||
|
|
||||||
|
|
||||||
|
func get_next_cost() -> int:
|
||||||
|
if _capacity_level >= MAX_LEVEL:
|
||||||
|
return -1
|
||||||
|
return EXPANSION_COSTS[_capacity_level]
|
||||||
|
|
||||||
|
|
||||||
|
func can_purchase(wallet: PlayerWalletType) -> bool:
|
||||||
|
var cost: int = get_next_cost()
|
||||||
|
return wallet != null and cost >= 0 and wallet.can_afford(cost)
|
||||||
|
|
||||||
|
|
||||||
|
func purchase(wallet: PlayerWalletType) -> bool:
|
||||||
|
if not can_purchase(wallet):
|
||||||
|
return false
|
||||||
|
var cost: int = get_next_cost()
|
||||||
|
if not wallet.debit(cost):
|
||||||
|
return false
|
||||||
|
_capacity_level += 1
|
||||||
|
capacity_changed.emit(_capacity_level, get_capacity())
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
func restore_level(level: int) -> bool:
|
||||||
|
var validated: int = clampi(level, 0, MAX_LEVEL)
|
||||||
|
var changed: bool = _capacity_level != validated
|
||||||
|
_capacity_level = validated
|
||||||
|
if changed:
|
||||||
|
capacity_changed.emit(_capacity_level, get_capacity())
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
func reset_to_defaults() -> void:
|
||||||
|
restore_level(0)
|
||||||
|
|
||||||
|
|
||||||
|
func to_save_data() -> Dictionary:
|
||||||
|
return {"capacity_level": _capacity_level}
|
||||||
1
progression/player_cooler_capacity.gd.uid
Normal file
1
progression/player_cooler_capacity.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://c85ofvdqxyacg
|
||||||
142
progression/player_item_effects.gd
Normal file
142
progression/player_item_effects.gd
Normal file
|
|
@ -0,0 +1,142 @@
|
||||||
|
class_name PlayerItemEffects
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
const ItemDataType = preload("res://items/item_data.gd")
|
||||||
|
const PlayerBagType = preload("res://inventory/player_bag.gd")
|
||||||
|
|
||||||
|
signal effects_changed
|
||||||
|
|
||||||
|
const COFFEE_ID: StringName = &"coffee"
|
||||||
|
const ENERGY_DRINK_ID: StringName = &"energy_drink"
|
||||||
|
const SNACK_ID: StringName = &"snack"
|
||||||
|
const FISH_FINDER_ID: StringName = &"fish_finder"
|
||||||
|
const COFFEE_DURATION: float = 90.0
|
||||||
|
const ENERGY_DRINK_DURATION: float = 90.0
|
||||||
|
const SNACK_DURATION: float = 60.0
|
||||||
|
const FISH_FINDER_DURATION: float = 120.0
|
||||||
|
const COFFEE_MOVEMENT_MULTIPLIER: float = 1.10
|
||||||
|
const ENERGY_REEL_MULTIPLIER: float = 1.15
|
||||||
|
const SNACK_BARRIER_BONUS: int = 1
|
||||||
|
const FISH_FINDER_BITE_MULTIPLIER: float = 0.80
|
||||||
|
|
||||||
|
var _remaining: Dictionary[StringName, float] = {
|
||||||
|
COFFEE_ID: 0.0,
|
||||||
|
ENERGY_DRINK_ID: 0.0,
|
||||||
|
SNACK_ID: 0.0,
|
||||||
|
FISH_FINDER_ID: 0.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
var changed: bool = false
|
||||||
|
for item_id: StringName in _remaining:
|
||||||
|
var previous: float = _remaining[item_id]
|
||||||
|
if previous <= 0.0:
|
||||||
|
continue
|
||||||
|
var next: float = maxf(previous - delta, 0.0)
|
||||||
|
_remaining[item_id] = next
|
||||||
|
if next == 0.0:
|
||||||
|
changed = true
|
||||||
|
if changed:
|
||||||
|
effects_changed.emit()
|
||||||
|
|
||||||
|
|
||||||
|
func use_consumable(
|
||||||
|
item: ItemDataType,
|
||||||
|
bag: PlayerBagType,
|
||||||
|
) -> bool:
|
||||||
|
if (
|
||||||
|
item == null
|
||||||
|
or bag == null
|
||||||
|
or item.category != ItemDataType.Category.CONSUMABLE
|
||||||
|
or not item.usable
|
||||||
|
or not _remaining.has(item.item_id)
|
||||||
|
or not bag.owns_item(item.item_id)
|
||||||
|
):
|
||||||
|
return false
|
||||||
|
if not bag.remove_item(item.item_id, 1):
|
||||||
|
return false
|
||||||
|
_remaining[item.item_id] = _get_duration(item.item_id)
|
||||||
|
effects_changed.emit()
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
func reset_all() -> void:
|
||||||
|
var changed: bool = false
|
||||||
|
for item_id: StringName in _remaining:
|
||||||
|
changed = changed or _remaining[item_id] > 0.0
|
||||||
|
_remaining[item_id] = 0.0
|
||||||
|
if changed:
|
||||||
|
effects_changed.emit()
|
||||||
|
|
||||||
|
|
||||||
|
func get_remaining(item_id: StringName) -> float:
|
||||||
|
return maxf(_remaining.get(item_id, 0.0), 0.0)
|
||||||
|
|
||||||
|
|
||||||
|
func is_active(item_id: StringName) -> bool:
|
||||||
|
return get_remaining(item_id) > 0.0
|
||||||
|
|
||||||
|
|
||||||
|
func get_movement_multiplier() -> float:
|
||||||
|
return COFFEE_MOVEMENT_MULTIPLIER if is_active(COFFEE_ID) else 1.0
|
||||||
|
|
||||||
|
|
||||||
|
func get_reel_multiplier() -> float:
|
||||||
|
return ENERGY_REEL_MULTIPLIER if is_active(ENERGY_DRINK_ID) else 1.0
|
||||||
|
|
||||||
|
|
||||||
|
func get_barrier_bonus() -> int:
|
||||||
|
return SNACK_BARRIER_BONUS if is_active(SNACK_ID) else 0
|
||||||
|
|
||||||
|
|
||||||
|
func get_bite_time_multiplier() -> float:
|
||||||
|
return (
|
||||||
|
FISH_FINDER_BITE_MULTIPLIER
|
||||||
|
if is_active(FISH_FINDER_ID)
|
||||||
|
else 1.0
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func get_rarity_weight_multiplier(rarity: int) -> float:
|
||||||
|
if not is_active(FISH_FINDER_ID):
|
||||||
|
return 1.0
|
||||||
|
match rarity:
|
||||||
|
0:
|
||||||
|
return 1.0
|
||||||
|
1:
|
||||||
|
return 1.10
|
||||||
|
2:
|
||||||
|
return 1.15
|
||||||
|
3:
|
||||||
|
return 1.20
|
||||||
|
_:
|
||||||
|
return 1.25
|
||||||
|
|
||||||
|
|
||||||
|
func get_feedback(item_id: StringName) -> String:
|
||||||
|
match item_id:
|
||||||
|
COFFEE_ID:
|
||||||
|
return "Coffee active: movement speed increased."
|
||||||
|
ENERGY_DRINK_ID:
|
||||||
|
return "Energy Drink active: reeling speed increased."
|
||||||
|
SNACK_ID:
|
||||||
|
return "Snack active: barrier damage increased."
|
||||||
|
FISH_FINDER_ID:
|
||||||
|
return "Fish Finder active: bites and uncommon catches improved."
|
||||||
|
_:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
func _get_duration(item_id: StringName) -> float:
|
||||||
|
match item_id:
|
||||||
|
COFFEE_ID:
|
||||||
|
return COFFEE_DURATION
|
||||||
|
ENERGY_DRINK_ID:
|
||||||
|
return ENERGY_DRINK_DURATION
|
||||||
|
SNACK_ID:
|
||||||
|
return SNACK_DURATION
|
||||||
|
FISH_FINDER_ID:
|
||||||
|
return FISH_FINDER_DURATION
|
||||||
|
_:
|
||||||
|
return 0.0
|
||||||
1
progression/player_item_effects.gd.uid
Normal file
1
progression/player_item_effects.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://cvd5jj5wbab1k
|
||||||
|
|
@ -14,8 +14,11 @@ const PlayerHotbarType = preload("res://inventory/player_hotbar.gd")
|
||||||
const PlayerFishingUpgradesType = preload(
|
const PlayerFishingUpgradesType = preload(
|
||||||
"res://progression/player_fishing_upgrades.gd"
|
"res://progression/player_fishing_upgrades.gd"
|
||||||
)
|
)
|
||||||
|
const PlayerCoolerCapacityType = preload(
|
||||||
|
"res://progression/player_cooler_capacity.gd"
|
||||||
|
)
|
||||||
|
|
||||||
const SAVE_VERSION: int = 3
|
const SAVE_VERSION: int = 4
|
||||||
const BASIC_ROD_ID: StringName = &"basic_fishing_rod"
|
const BASIC_ROD_ID: StringName = &"basic_fishing_rod"
|
||||||
const SAVE_PATH: String = "user://player_save.json"
|
const SAVE_PATH: String = "user://player_save.json"
|
||||||
const TEMP_PATH: String = "user://player_save.json.tmp"
|
const TEMP_PATH: String = "user://player_save.json.tmp"
|
||||||
|
|
@ -34,6 +37,7 @@ class LoadSnapshot:
|
||||||
var selected_hotbar_slot: int = 0
|
var selected_hotbar_slot: int = 0
|
||||||
var reel_speed_level: int = 0
|
var reel_speed_level: int = 0
|
||||||
var barrier_power_level: int = 0
|
var barrier_power_level: int = 0
|
||||||
|
var cooler_capacity_level: int = 0
|
||||||
|
|
||||||
|
|
||||||
@export_range(0.05, 5.0, 0.05) var autosave_delay: float = 0.5
|
@export_range(0.05, 5.0, 0.05) var autosave_delay: float = 0.5
|
||||||
|
|
@ -46,6 +50,7 @@ var _bag: PlayerBagType
|
||||||
var _hotbar: PlayerHotbarType
|
var _hotbar: PlayerHotbarType
|
||||||
var _item_catalog: ItemCatalogType
|
var _item_catalog: ItemCatalogType
|
||||||
var _fishing_upgrades: PlayerFishingUpgradesType
|
var _fishing_upgrades: PlayerFishingUpgradesType
|
||||||
|
var _cooler_capacity: PlayerCoolerCapacityType
|
||||||
var _autosave_timer: Timer
|
var _autosave_timer: Timer
|
||||||
var _is_configured: bool = false
|
var _is_configured: bool = false
|
||||||
var _is_restoring: bool = false
|
var _is_restoring: bool = false
|
||||||
|
|
@ -70,6 +75,7 @@ func setup(
|
||||||
hotbar: PlayerHotbarType,
|
hotbar: PlayerHotbarType,
|
||||||
item_catalog: ItemCatalogType,
|
item_catalog: ItemCatalogType,
|
||||||
fishing_upgrades: PlayerFishingUpgradesType,
|
fishing_upgrades: PlayerFishingUpgradesType,
|
||||||
|
cooler_capacity: PlayerCoolerCapacityType,
|
||||||
) -> void:
|
) -> void:
|
||||||
_inventory = inventory
|
_inventory = inventory
|
||||||
_collection_log = collection_log
|
_collection_log = collection_log
|
||||||
|
|
@ -79,6 +85,7 @@ func setup(
|
||||||
_hotbar = hotbar
|
_hotbar = hotbar
|
||||||
_item_catalog = item_catalog
|
_item_catalog = item_catalog
|
||||||
_fishing_upgrades = fishing_upgrades
|
_fishing_upgrades = fishing_upgrades
|
||||||
|
_cooler_capacity = cooler_capacity
|
||||||
_is_configured = (
|
_is_configured = (
|
||||||
_inventory != null
|
_inventory != null
|
||||||
and _collection_log != null
|
and _collection_log != null
|
||||||
|
|
@ -88,6 +95,7 @@ func setup(
|
||||||
and _hotbar != null
|
and _hotbar != null
|
||||||
and _item_catalog != null
|
and _item_catalog != null
|
||||||
and _fishing_upgrades != null
|
and _fishing_upgrades != null
|
||||||
|
and _cooler_capacity != null
|
||||||
)
|
)
|
||||||
if not _is_configured:
|
if not _is_configured:
|
||||||
push_error("PlayerSaveManager setup is missing required references.")
|
push_error("PlayerSaveManager setup is missing required references.")
|
||||||
|
|
@ -114,6 +122,12 @@ func setup(
|
||||||
_on_upgrades_changed
|
_on_upgrades_changed
|
||||||
):
|
):
|
||||||
_fishing_upgrades.upgrades_changed.connect(_on_upgrades_changed)
|
_fishing_upgrades.upgrades_changed.connect(_on_upgrades_changed)
|
||||||
|
if not _cooler_capacity.capacity_changed.is_connected(
|
||||||
|
_on_cooler_capacity_changed
|
||||||
|
):
|
||||||
|
_cooler_capacity.capacity_changed.connect(
|
||||||
|
_on_cooler_capacity_changed
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
func load_player_data() -> bool:
|
func load_player_data() -> bool:
|
||||||
|
|
@ -183,6 +197,9 @@ func load_player_data() -> bool:
|
||||||
snapshot.reel_speed_level,
|
snapshot.reel_speed_level,
|
||||||
snapshot.barrier_power_level
|
snapshot.barrier_power_level
|
||||||
)
|
)
|
||||||
|
var cooler_restored: bool = _cooler_capacity.restore_level(
|
||||||
|
snapshot.cooler_capacity_level
|
||||||
|
)
|
||||||
_is_restoring = false
|
_is_restoring = false
|
||||||
if (
|
if (
|
||||||
not inventory_restored
|
not inventory_restored
|
||||||
|
|
@ -191,6 +208,7 @@ func load_player_data() -> bool:
|
||||||
or not bag_restored
|
or not bag_restored
|
||||||
or not hotbar_restored
|
or not hotbar_restored
|
||||||
or not upgrades_restored
|
or not upgrades_restored
|
||||||
|
or not cooler_restored
|
||||||
):
|
):
|
||||||
push_error("Validated player save could not be restored.")
|
push_error("Validated player save could not be restored.")
|
||||||
return false
|
return false
|
||||||
|
|
@ -400,6 +418,7 @@ func _build_save_dictionary() -> Dictionary:
|
||||||
"slots": serialized_slots,
|
"slots": serialized_slots,
|
||||||
},
|
},
|
||||||
"upgrades": _fishing_upgrades.to_save_data(),
|
"upgrades": _fishing_upgrades.to_save_data(),
|
||||||
|
"cooler": _cooler_capacity.to_save_data(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -418,12 +437,17 @@ func _build_load_snapshot(save_data: Dictionary) -> LoadSnapshot:
|
||||||
var bag_data: Dictionary = save_data["bag"]
|
var bag_data: Dictionary = save_data["bag"]
|
||||||
var hotbar_data: Dictionary = save_data["hotbar"]
|
var hotbar_data: Dictionary = save_data["hotbar"]
|
||||||
var upgrades_data: Dictionary = {}
|
var upgrades_data: Dictionary = {}
|
||||||
|
var cooler_data: Dictionary = {}
|
||||||
if typeof(save_data.get("upgrades")) == TYPE_DICTIONARY:
|
if typeof(save_data.get("upgrades")) == TYPE_DICTIONARY:
|
||||||
upgrades_data = save_data["upgrades"]
|
upgrades_data = save_data["upgrades"]
|
||||||
else:
|
else:
|
||||||
push_warning(
|
push_warning(
|
||||||
"Saved fishing upgrades were missing or invalid; using defaults."
|
"Saved fishing upgrades were missing or invalid; using defaults."
|
||||||
)
|
)
|
||||||
|
if typeof(save_data.get("cooler")) == TYPE_DICTIONARY:
|
||||||
|
cooler_data = save_data["cooler"]
|
||||||
|
else:
|
||||||
|
push_warning("Saved Cooler data was missing or invalid; using defaults.")
|
||||||
if (
|
if (
|
||||||
not wallet_data.has("balance")
|
not wallet_data.has("balance")
|
||||||
or typeof(collection_data.get("discovered_fish_ids")) != TYPE_ARRAY
|
or typeof(collection_data.get("discovered_fish_ids")) != TYPE_ARRAY
|
||||||
|
|
@ -600,6 +624,11 @@ func _build_load_snapshot(save_data: Dictionary) -> LoadSnapshot:
|
||||||
PlayerFishingUpgradesType.MAX_BARRIER_POWER_LEVEL,
|
PlayerFishingUpgradesType.MAX_BARRIER_POWER_LEVEL,
|
||||||
"barrier_power_level"
|
"barrier_power_level"
|
||||||
)
|
)
|
||||||
|
snapshot.cooler_capacity_level = _read_upgrade_level(
|
||||||
|
cooler_data.get("capacity_level"),
|
||||||
|
PlayerCoolerCapacityType.MAX_LEVEL,
|
||||||
|
"cooler.capacity_level"
|
||||||
|
)
|
||||||
return snapshot
|
return snapshot
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -619,6 +648,8 @@ func _migrate_save(
|
||||||
migrated = _migrate_version_1_to_2(migrated)
|
migrated = _migrate_version_1_to_2(migrated)
|
||||||
2:
|
2:
|
||||||
migrated = _migrate_version_2_to_3(migrated)
|
migrated = _migrate_version_2_to_3(migrated)
|
||||||
|
3:
|
||||||
|
migrated = _migrate_version_3_to_4(migrated)
|
||||||
_:
|
_:
|
||||||
return {}
|
return {}
|
||||||
if migrated.is_empty():
|
if migrated.is_empty():
|
||||||
|
|
@ -659,6 +690,13 @@ func _migrate_version_2_to_3(data: Dictionary) -> Dictionary:
|
||||||
return migrated
|
return migrated
|
||||||
|
|
||||||
|
|
||||||
|
func _migrate_version_3_to_4(data: Dictionary) -> Dictionary:
|
||||||
|
var migrated: Dictionary = data.duplicate(true)
|
||||||
|
migrated["save_version"] = 4
|
||||||
|
migrated["cooler"] = {"capacity_level": 0}
|
||||||
|
return migrated
|
||||||
|
|
||||||
|
|
||||||
func _mark_dirty() -> void:
|
func _mark_dirty() -> void:
|
||||||
if (
|
if (
|
||||||
_is_restoring
|
_is_restoring
|
||||||
|
|
@ -693,6 +731,13 @@ func _on_upgrades_changed(
|
||||||
_mark_dirty()
|
_mark_dirty()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_cooler_capacity_changed(
|
||||||
|
_level: int,
|
||||||
|
_capacity: int,
|
||||||
|
) -> void:
|
||||||
|
_mark_dirty()
|
||||||
|
|
||||||
|
|
||||||
func _on_autosave_timeout() -> void:
|
func _on_autosave_timeout() -> void:
|
||||||
if _is_dirty:
|
if _is_dirty:
|
||||||
save_now()
|
save_now()
|
||||||
|
|
@ -748,6 +793,7 @@ func _restore_defaults() -> void:
|
||||||
_bag.replace_all_items(default_items)
|
_bag.replace_all_items(default_items)
|
||||||
_hotbar.replace_state(default_slots, 0)
|
_hotbar.replace_state(default_slots, 0)
|
||||||
_fishing_upgrades.reset_to_defaults()
|
_fishing_upgrades.reset_to_defaults()
|
||||||
|
_cooler_capacity.reset_to_defaults()
|
||||||
_is_restoring = false
|
_is_restoring = false
|
||||||
_is_dirty = false
|
_is_dirty = false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,18 @@ const FishInventoryType = preload("res://inventory/fish_inventory.gd")
|
||||||
const FishSaleResultType = preload("res://economy/fish_sale_result.gd")
|
const FishSaleResultType = preload("res://economy/fish_sale_result.gd")
|
||||||
const FishSaleServiceType = preload("res://economy/fish_sale_service.gd")
|
const FishSaleServiceType = preload("res://economy/fish_sale_service.gd")
|
||||||
const PlayerWalletType = preload("res://economy/player_wallet.gd")
|
const PlayerWalletType = preload("res://economy/player_wallet.gd")
|
||||||
|
const FishingShopStockType = preload("res://economy/fishing_shop_stock.gd")
|
||||||
|
const ItemCatalogType = preload("res://items/item_catalog.gd")
|
||||||
|
const ItemDataType = preload("res://items/item_data.gd")
|
||||||
|
const PlayerBagType = preload("res://inventory/player_bag.gd")
|
||||||
const FishingSpotType = preload("res://fishing/fishing_spot.gd")
|
const FishingSpotType = preload("res://fishing/fishing_spot.gd")
|
||||||
const PlayerFishingUpgradesType = preload(
|
const PlayerFishingUpgradesType = preload(
|
||||||
"res://progression/player_fishing_upgrades.gd"
|
"res://progression/player_fishing_upgrades.gd"
|
||||||
)
|
)
|
||||||
const PlayerType = preload("res://player/player.gd")
|
const PlayerType = preload("res://player/player.gd")
|
||||||
|
const PlayerCoolerCapacityType = preload(
|
||||||
|
"res://progression/player_cooler_capacity.gd"
|
||||||
|
)
|
||||||
const ShopInteractionType = preload(
|
const ShopInteractionType = preload(
|
||||||
"res://world/fishing_shop_interaction.gd"
|
"res://world/fishing_shop_interaction.gd"
|
||||||
)
|
)
|
||||||
|
|
@ -30,6 +37,7 @@ enum CloseReason {
|
||||||
|
|
||||||
@onready var _wallet_label: Label = %WalletLabel
|
@onready var _wallet_label: Label = %WalletLabel
|
||||||
@onready var _fish_list: ItemList = %FishList
|
@onready var _fish_list: ItemList = %FishList
|
||||||
|
@onready var _sales_title: Label = %SalesTitle
|
||||||
@onready var _fish_empty: Label = %FishEmpty
|
@onready var _fish_empty: Label = %FishEmpty
|
||||||
@onready var _fish_texture: TextureRect = %FishTexture
|
@onready var _fish_texture: TextureRect = %FishTexture
|
||||||
@onready var _fish_name: Label = %FishName
|
@onready var _fish_name: Label = %FishName
|
||||||
|
|
@ -44,6 +52,11 @@ enum CloseReason {
|
||||||
@onready var _barrier_effect: Label = %BarrierEffect
|
@onready var _barrier_effect: Label = %BarrierEffect
|
||||||
@onready var _barrier_cost: Label = %BarrierCost
|
@onready var _barrier_cost: Label = %BarrierCost
|
||||||
@onready var _barrier_purchase: Button = %BarrierPurchase
|
@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_purchase: Button = %CoolerPurchase
|
||||||
@onready var _confirmation: PanelContainer = %SaleConfirmation
|
@onready var _confirmation: PanelContainer = %SaleConfirmation
|
||||||
@onready var _confirmation_text: Label = %ConfirmationText
|
@onready var _confirmation_text: Label = %ConfirmationText
|
||||||
@onready var _confirm_sale: Button = %ConfirmSale
|
@onready var _confirm_sale: Button = %ConfirmSale
|
||||||
|
|
@ -57,6 +70,9 @@ var _buyer: FishBuyerProfileType
|
||||||
var _upgrades: PlayerFishingUpgradesType
|
var _upgrades: PlayerFishingUpgradesType
|
||||||
var _fishing_spot: FishingSpotType
|
var _fishing_spot: FishingSpotType
|
||||||
var _interaction: ShopInteractionType
|
var _interaction: ShopInteractionType
|
||||||
|
var _bag: PlayerBagType
|
||||||
|
var _item_catalog: ItemCatalogType
|
||||||
|
var _cooler_capacity: PlayerCoolerCapacityType
|
||||||
var _selected_catch_id: StringName
|
var _selected_catch_id: StringName
|
||||||
var _confirmation_catch_id: StringName
|
var _confirmation_catch_id: StringName
|
||||||
var _prior_movement_enabled: bool = true
|
var _prior_movement_enabled: bool = true
|
||||||
|
|
@ -77,6 +93,7 @@ func _ready() -> void:
|
||||||
_cancel_sale.pressed.connect(_close_sale_confirmation)
|
_cancel_sale.pressed.connect(_close_sale_confirmation)
|
||||||
_reel_purchase.pressed.connect(_purchase_reel_speed)
|
_reel_purchase.pressed.connect(_purchase_reel_speed)
|
||||||
_barrier_purchase.pressed.connect(_purchase_barrier_power)
|
_barrier_purchase.pressed.connect(_purchase_barrier_power)
|
||||||
|
_cooler_purchase.pressed.connect(_purchase_cooler_capacity)
|
||||||
|
|
||||||
|
|
||||||
func setup(
|
func setup(
|
||||||
|
|
@ -88,6 +105,9 @@ func setup(
|
||||||
upgrades: PlayerFishingUpgradesType,
|
upgrades: PlayerFishingUpgradesType,
|
||||||
fishing_spot: FishingSpotType,
|
fishing_spot: FishingSpotType,
|
||||||
interaction: ShopInteractionType,
|
interaction: ShopInteractionType,
|
||||||
|
bag: PlayerBagType,
|
||||||
|
item_catalog: ItemCatalogType,
|
||||||
|
cooler_capacity: PlayerCoolerCapacityType,
|
||||||
) -> void:
|
) -> void:
|
||||||
_player = player
|
_player = player
|
||||||
_inventory = inventory
|
_inventory = inventory
|
||||||
|
|
@ -97,12 +117,21 @@ func setup(
|
||||||
_upgrades = upgrades
|
_upgrades = upgrades
|
||||||
_fishing_spot = fishing_spot
|
_fishing_spot = fishing_spot
|
||||||
_interaction = interaction
|
_interaction = interaction
|
||||||
|
_bag = bag
|
||||||
|
_item_catalog = item_catalog
|
||||||
|
_cooler_capacity = cooler_capacity
|
||||||
if not _inventory.catches_changed.is_connected(_on_inventory_changed):
|
if not _inventory.catches_changed.is_connected(_on_inventory_changed):
|
||||||
_inventory.catches_changed.connect(_on_inventory_changed)
|
_inventory.catches_changed.connect(_on_inventory_changed)
|
||||||
if not _wallet.balance_changed.is_connected(_on_wallet_changed):
|
if not _wallet.balance_changed.is_connected(_on_wallet_changed):
|
||||||
_wallet.balance_changed.connect(_on_wallet_changed)
|
_wallet.balance_changed.connect(_on_wallet_changed)
|
||||||
if not _upgrades.upgrades_changed.is_connected(_on_upgrades_changed):
|
if not _upgrades.upgrades_changed.is_connected(_on_upgrades_changed):
|
||||||
_upgrades.upgrades_changed.connect(_on_upgrades_changed)
|
_upgrades.upgrades_changed.connect(_on_upgrades_changed)
|
||||||
|
if not _bag.contents_changed.is_connected(_on_bag_changed):
|
||||||
|
_bag.contents_changed.connect(_on_bag_changed)
|
||||||
|
if not _cooler_capacity.capacity_changed.is_connected(
|
||||||
|
_on_cooler_capacity_changed
|
||||||
|
):
|
||||||
|
_cooler_capacity.capacity_changed.connect(_on_cooler_capacity_changed)
|
||||||
_refresh_all()
|
_refresh_all()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -207,6 +236,8 @@ func _refresh_all() -> void:
|
||||||
_refresh_fish_list()
|
_refresh_fish_list()
|
||||||
_refresh_selected_fish()
|
_refresh_selected_fish()
|
||||||
_refresh_upgrades()
|
_refresh_upgrades()
|
||||||
|
_refresh_supplies()
|
||||||
|
_refresh_cooler_capacity()
|
||||||
|
|
||||||
|
|
||||||
func _refresh_wallet() -> void:
|
func _refresh_wallet() -> void:
|
||||||
|
|
@ -222,6 +253,10 @@ func _refresh_fish_list() -> void:
|
||||||
var catches: Array[FishCatchType] = (
|
var catches: Array[FishCatchType] = (
|
||||||
_inventory.get_all_catches() if _inventory != null else []
|
_inventory.get_all_catches() if _inventory != null else []
|
||||||
)
|
)
|
||||||
|
_sales_title.text = "Cooler %d / %d • Full base value" % [
|
||||||
|
catches.size(),
|
||||||
|
_cooler_capacity.get_capacity() if _cooler_capacity != null else 0,
|
||||||
|
]
|
||||||
catches.sort_custom(
|
catches.sort_custom(
|
||||||
func(a: FishCatchType, b: FishCatchType) -> bool:
|
func(a: FishCatchType, b: FishCatchType) -> bool:
|
||||||
return a.catch_sequence > b.catch_sequence
|
return a.catch_sequence > b.catch_sequence
|
||||||
|
|
@ -335,6 +370,65 @@ func _refresh_upgrades() -> void:
|
||||||
_barrier_purchase.text = "MAX" if barrier_cost < 0 else "Purchase"
|
_barrier_purchase.text = "MAX" if barrier_cost < 0 else "Purchase"
|
||||||
|
|
||||||
|
|
||||||
|
func _refresh_supplies() -> void:
|
||||||
|
if _supplies_list == null:
|
||||||
|
return
|
||||||
|
for child: Node in _supplies_list.get_children():
|
||||||
|
_supplies_list.remove_child(child)
|
||||||
|
child.queue_free()
|
||||||
|
for item_id: StringName in FishingShopStockType.get_stock_item_ids():
|
||||||
|
var item: ItemDataType = _item_catalog.get_item_by_id(item_id)
|
||||||
|
if item == null:
|
||||||
|
continue
|
||||||
|
var button := Button.new()
|
||||||
|
button.custom_minimum_size = Vector2(195, 54)
|
||||||
|
button.icon = item.icon
|
||||||
|
button.expand_icon = true
|
||||||
|
button.alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||||
|
button.text = "%s\n$%d • Owned %d" % [
|
||||||
|
item.display_name,
|
||||||
|
FishingShopStockType.get_price(item_id),
|
||||||
|
_bag.get_quantity(item_id),
|
||||||
|
]
|
||||||
|
button.tooltip_text = item.description
|
||||||
|
button.disabled = (
|
||||||
|
_transaction_in_progress
|
||||||
|
or _closing
|
||||||
|
or not _bag.can_add_item(item_id, 1)
|
||||||
|
or not _wallet.can_afford(
|
||||||
|
FishingShopStockType.get_price(item_id)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
button.pressed.connect(_purchase_supply.bind(item_id))
|
||||||
|
_supplies_list.add_child(button)
|
||||||
|
|
||||||
|
|
||||||
|
func _refresh_cooler_capacity() -> void:
|
||||||
|
if _cooler_capacity == null:
|
||||||
|
return
|
||||||
|
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
|
||||||
|
or _closing
|
||||||
|
or not _cooler_capacity.can_purchase(_wallet)
|
||||||
|
)
|
||||||
|
if cost < 0:
|
||||||
|
_cooler_effect.text = "%d fish" % _cooler_capacity.get_capacity()
|
||||||
|
_cooler_cost.text = "MAX"
|
||||||
|
_cooler_purchase.text = "MAX"
|
||||||
|
else:
|
||||||
|
_cooler_effect.text = "%d → %d fish" % [
|
||||||
|
_cooler_capacity.get_capacity(),
|
||||||
|
next_capacity,
|
||||||
|
]
|
||||||
|
_cooler_cost.text = "$%d" % cost
|
||||||
|
_cooler_purchase.text = "Purchase"
|
||||||
|
|
||||||
|
|
||||||
func _on_fish_selected(index: int) -> void:
|
func _on_fish_selected(index: int) -> void:
|
||||||
if index < 0 or index >= _fish_list.item_count:
|
if index < 0 or index >= _fish_list.item_count:
|
||||||
return
|
return
|
||||||
|
|
@ -405,6 +499,59 @@ func _purchase_barrier_power() -> void:
|
||||||
_purchase_upgrade(false)
|
_purchase_upgrade(false)
|
||||||
|
|
||||||
|
|
||||||
|
func _purchase_supply(item_id: StringName) -> void:
|
||||||
|
if _transaction_in_progress or not _is_transaction_context_valid():
|
||||||
|
_feedback.text = "Unable to complete purchase."
|
||||||
|
return
|
||||||
|
var price: int = FishingShopStockType.get_price(item_id)
|
||||||
|
if not _bag.can_add_item(item_id, 1):
|
||||||
|
_feedback.text = "Bag cannot accept this item."
|
||||||
|
return
|
||||||
|
if not _wallet.can_afford(price):
|
||||||
|
_feedback.text = "Not enough money."
|
||||||
|
return
|
||||||
|
var transaction_generation: int = _generation
|
||||||
|
_transaction_in_progress = true
|
||||||
|
var purchased: bool = FishingShopStockType.purchase_one(
|
||||||
|
item_id,
|
||||||
|
_wallet,
|
||||||
|
_bag,
|
||||||
|
_item_catalog
|
||||||
|
)
|
||||||
|
_transaction_in_progress = false
|
||||||
|
if transaction_generation != _generation or not visible:
|
||||||
|
return
|
||||||
|
_feedback.text = (
|
||||||
|
"Item purchased." if purchased else "Unable to complete purchase."
|
||||||
|
)
|
||||||
|
_refresh_all()
|
||||||
|
|
||||||
|
|
||||||
|
func _purchase_cooler_capacity() -> void:
|
||||||
|
if _transaction_in_progress or not _is_transaction_context_valid():
|
||||||
|
_feedback.text = "Unable to complete purchase."
|
||||||
|
return
|
||||||
|
var cost: int = _cooler_capacity.get_next_cost()
|
||||||
|
if cost < 0:
|
||||||
|
_feedback.text = "Maximum level reached."
|
||||||
|
return
|
||||||
|
if not _wallet.can_afford(cost):
|
||||||
|
_feedback.text = "Not enough money."
|
||||||
|
return
|
||||||
|
var transaction_generation: int = _generation
|
||||||
|
_transaction_in_progress = true
|
||||||
|
var purchased: bool = _cooler_capacity.purchase(_wallet)
|
||||||
|
_transaction_in_progress = false
|
||||||
|
if transaction_generation != _generation or not visible:
|
||||||
|
return
|
||||||
|
_feedback.text = (
|
||||||
|
"Upgrade purchased."
|
||||||
|
if purchased
|
||||||
|
else "Unable to complete purchase."
|
||||||
|
)
|
||||||
|
_refresh_all()
|
||||||
|
|
||||||
|
|
||||||
func _purchase_upgrade(is_reel_speed: bool) -> void:
|
func _purchase_upgrade(is_reel_speed: bool) -> void:
|
||||||
if _transaction_in_progress or not _is_transaction_context_valid():
|
if _transaction_in_progress or not _is_transaction_context_valid():
|
||||||
_feedback.text = "Unable to complete purchase."
|
_feedback.text = "Unable to complete purchase."
|
||||||
|
|
@ -472,6 +619,8 @@ func _on_inventory_changed() -> void:
|
||||||
func _on_wallet_changed(_balance: int, _delta: int) -> void:
|
func _on_wallet_changed(_balance: int, _delta: int) -> void:
|
||||||
_refresh_wallet()
|
_refresh_wallet()
|
||||||
_refresh_upgrades()
|
_refresh_upgrades()
|
||||||
|
_refresh_supplies()
|
||||||
|
_refresh_cooler_capacity()
|
||||||
|
|
||||||
|
|
||||||
func _on_upgrades_changed(
|
func _on_upgrades_changed(
|
||||||
|
|
@ -481,6 +630,15 @@ func _on_upgrades_changed(
|
||||||
_refresh_upgrades()
|
_refresh_upgrades()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_bag_changed() -> void:
|
||||||
|
_refresh_supplies()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_cooler_capacity_changed(_level: int, _capacity: int) -> void:
|
||||||
|
_refresh_cooler_capacity()
|
||||||
|
_refresh_fish_list()
|
||||||
|
|
||||||
|
|
||||||
func _apply_mouse_close_policy(reason: CloseReason) -> void:
|
func _apply_mouse_close_policy(reason: CloseReason) -> void:
|
||||||
if not _mouse_snapshot_stored:
|
if not _mouse_snapshot_stored:
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
[gd_scene load_steps=6 format=3]
|
[gd_scene load_steps=7 format=3]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://ui/fishing_shop.gd" id="1_script"]
|
[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="Theme" path="res://ui/game_theme.tres" id="2_theme"]
|
||||||
[ext_resource type="Texture2D" path="res://items/icons/placeholder/reel_speed_upgrade.svg" id="3_reel"]
|
[ext_resource type="Texture2D" path="res://items/icons/placeholder/reel_speed_upgrade.svg" id="3_reel"]
|
||||||
[ext_resource type="Texture2D" path="res://items/icons/placeholder/barrier_power_upgrade.svg" id="4_barrier"]
|
[ext_resource type="Texture2D" path="res://items/icons/placeholder/barrier_power_upgrade.svg" 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/placeholder/fish_coin.svg" id="5_coin"]
|
||||||
|
[ext_resource type="Texture2D" path="res://items/icons/placeholder/cooler_expansion.svg" id="6_cooler"]
|
||||||
|
|
||||||
[node name="FishingShop" type="Control"]
|
[node name="FishingShop" type="Control"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
|
|
@ -37,10 +38,10 @@ anchor_left = 0.5
|
||||||
anchor_top = 0.5
|
anchor_top = 0.5
|
||||||
anchor_right = 0.5
|
anchor_right = 0.5
|
||||||
anchor_bottom = 0.5
|
anchor_bottom = 0.5
|
||||||
offset_left = -450.0
|
offset_left = -480.0
|
||||||
offset_top = -260.0
|
offset_top = -310.0
|
||||||
offset_right = 450.0
|
offset_right = 480.0
|
||||||
offset_bottom = 260.0
|
offset_bottom = 310.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
|
|
||||||
|
|
@ -98,12 +99,13 @@ size_flags_vertical = 3
|
||||||
theme_override_constants/separation = 12
|
theme_override_constants/separation = 12
|
||||||
|
|
||||||
[node name="FishSales" type="VBoxContainer" parent="ShopPanel/Margin/Layout/Body"]
|
[node name="FishSales" type="VBoxContainer" parent="ShopPanel/Margin/Layout/Body"]
|
||||||
custom_minimum_size = Vector2(500, 0)
|
custom_minimum_size = Vector2(420, 0)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
theme_override_constants/separation = 6
|
theme_override_constants/separation = 6
|
||||||
|
|
||||||
[node name="SalesTitle" type="Label" parent="ShopPanel/Margin/Layout/Body/FishSales"]
|
[node name="SalesTitle" type="Label" parent="ShopPanel/Margin/Layout/Body/FishSales"]
|
||||||
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Sell individual Cooler fish • Full base value"
|
text = "Sell individual Cooler fish • Full base value"
|
||||||
theme_override_font_sizes/font_size = 17
|
theme_override_font_sizes/font_size = 17
|
||||||
|
|
@ -111,11 +113,11 @@ theme_override_font_sizes/font_size = 17
|
||||||
[node name="SalesBody" type="HSplitContainer" parent="ShopPanel/Margin/Layout/Body/FishSales"]
|
[node name="SalesBody" type="HSplitContainer" parent="ShopPanel/Margin/Layout/Body/FishSales"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
split_offset = 265
|
split_offset = 220
|
||||||
theme_override_constants/separation = 8
|
theme_override_constants/separation = 8
|
||||||
|
|
||||||
[node name="ListPanel" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/FishSales/SalesBody"]
|
[node name="ListPanel" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/FishSales/SalesBody"]
|
||||||
custom_minimum_size = Vector2(250, 0)
|
custom_minimum_size = Vector2(205, 0)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="ListMargin" type="MarginContainer" parent="ShopPanel/Margin/Layout/Body/FishSales/SalesBody/ListPanel"]
|
[node name="ListMargin" type="MarginContainer" parent="ShopPanel/Margin/Layout/Body/FishSales/SalesBody/ListPanel"]
|
||||||
|
|
@ -143,7 +145,7 @@ icon_mode = 1
|
||||||
same_column_width = true
|
same_column_width = true
|
||||||
|
|
||||||
[node name="FishDetail" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/FishSales/SalesBody"]
|
[node name="FishDetail" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/FishSales/SalesBody"]
|
||||||
custom_minimum_size = Vector2(220, 0)
|
custom_minimum_size = Vector2(185, 0)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="DetailMargin" type="MarginContainer" parent="ShopPanel/Margin/Layout/Body/FishSales/SalesBody/FishDetail"]
|
[node name="DetailMargin" type="MarginContainer" parent="ShopPanel/Margin/Layout/Body/FishSales/SalesBody/FishDetail"]
|
||||||
|
|
@ -159,7 +161,7 @@ theme_override_constants/separation = 6
|
||||||
|
|
||||||
[node name="FishTexture" type="TextureRect" parent="ShopPanel/Margin/Layout/Body/FishSales/SalesBody/FishDetail/DetailMargin/DetailStack"]
|
[node name="FishTexture" type="TextureRect" parent="ShopPanel/Margin/Layout/Body/FishSales/SalesBody/FishDetail/DetailMargin/DetailStack"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
custom_minimum_size = Vector2(190, 100)
|
custom_minimum_size = Vector2(160, 90)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
expand_mode = 1
|
expand_mode = 1
|
||||||
stretch_mode = 5
|
stretch_mode = 5
|
||||||
|
|
@ -186,7 +188,7 @@ disabled = true
|
||||||
text = "Sell Selected"
|
text = "Sell Selected"
|
||||||
|
|
||||||
[node name="Upgrades" type="VBoxContainer" parent="ShopPanel/Margin/Layout/Body"]
|
[node name="Upgrades" type="VBoxContainer" parent="ShopPanel/Margin/Layout/Body"]
|
||||||
custom_minimum_size = Vector2(310, 0)
|
custom_minimum_size = Vector2(270, 0)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
theme_override_constants/separation = 8
|
theme_override_constants/separation = 8
|
||||||
|
|
||||||
|
|
@ -195,6 +197,27 @@ layout_mode = 2
|
||||||
text = "Fishing Upgrades"
|
text = "Fishing Upgrades"
|
||||||
theme_override_font_sizes/font_size = 17
|
theme_override_font_sizes/font_size = 17
|
||||||
|
|
||||||
|
[node name="Supplies" type="VBoxContainer" parent="ShopPanel/Margin/Layout/Body"]
|
||||||
|
custom_minimum_size = Vector2(210, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_constants/separation = 6
|
||||||
|
|
||||||
|
[node name="Title" type="Label" parent="ShopPanel/Margin/Layout/Body/Supplies"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Supplies"
|
||||||
|
theme_override_font_sizes/font_size = 17
|
||||||
|
|
||||||
|
[node name="Scroll" type="ScrollContainer" parent="ShopPanel/Margin/Layout/Body/Supplies"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 3
|
||||||
|
horizontal_scroll_mode = 0
|
||||||
|
|
||||||
|
[node name="SuppliesList" type="VBoxContainer" parent="ShopPanel/Margin/Layout/Body/Supplies/Scroll"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
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="ReelCard" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
|
|
@ -210,7 +233,7 @@ layout_mode = 2
|
||||||
theme_override_constants/separation = 9
|
theme_override_constants/separation = 9
|
||||||
|
|
||||||
[node name="Icon" type="TextureRect" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row"]
|
[node name="Icon" type="TextureRect" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row"]
|
||||||
custom_minimum_size = Vector2(60, 60)
|
custom_minimum_size = Vector2(48, 48)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
texture = ExtResource("3_reel")
|
texture = ExtResource("3_reel")
|
||||||
expand_mode = 1
|
expand_mode = 1
|
||||||
|
|
@ -261,7 +284,7 @@ layout_mode = 2
|
||||||
theme_override_constants/separation = 9
|
theme_override_constants/separation = 9
|
||||||
|
|
||||||
[node name="Icon" type="TextureRect" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row"]
|
[node name="Icon" type="TextureRect" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row"]
|
||||||
custom_minimum_size = Vector2(60, 60)
|
custom_minimum_size = Vector2(48, 48)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
texture = ExtResource("4_barrier")
|
texture = ExtResource("4_barrier")
|
||||||
expand_mode = 1
|
expand_mode = 1
|
||||||
|
|
@ -297,6 +320,57 @@ unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Purchase"
|
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 = 9
|
||||||
|
theme_override_constants/margin_right = 9
|
||||||
|
theme_override_constants/margin_bottom = 9
|
||||||
|
|
||||||
|
[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(48, 48)
|
||||||
|
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 = 17
|
||||||
|
|
||||||
|
[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"
|
||||||
|
|
||||||
|
[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"
|
||||||
|
|
||||||
|
[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"
|
||||||
|
|
||||||
|
[node name="CoolerPurchase" type="Button" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin/Row"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Purchase"
|
||||||
|
|
||||||
[node name="SaleConfirmation" type="PanelContainer" parent="."]
|
[node name="SaleConfirmation" type="PanelContainer" parent="."]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
visible = false
|
visible = false
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,12 @@ const PlayerFishingUpgradesType = preload(
|
||||||
const ShopInteractionType = preload(
|
const ShopInteractionType = preload(
|
||||||
"res://world/fishing_shop_interaction.gd"
|
"res://world/fishing_shop_interaction.gd"
|
||||||
)
|
)
|
||||||
|
const PlayerItemEffectsType = preload(
|
||||||
|
"res://progression/player_item_effects.gd"
|
||||||
|
)
|
||||||
|
const PlayerCoolerCapacityType = preload(
|
||||||
|
"res://progression/player_cooler_capacity.gd"
|
||||||
|
)
|
||||||
|
|
||||||
@onready var _status_label: Label = %StatusLabel
|
@onready var _status_label: Label = %StatusLabel
|
||||||
@onready var _catch_track: Control = %CatchTrack
|
@onready var _catch_track: Control = %CatchTrack
|
||||||
|
|
@ -40,6 +46,7 @@ const ShopInteractionType = preload(
|
||||||
@onready var _hotbar_ui: HotbarUIType = %Hotbar
|
@onready var _hotbar_ui: HotbarUIType = %Hotbar
|
||||||
@onready var _fishing_shop: FishingShopType = %FishingShop
|
@onready var _fishing_shop: FishingShopType = %FishingShop
|
||||||
@onready var _shop_prompt: PanelContainer = %ShopPrompt
|
@onready var _shop_prompt: PanelContainer = %ShopPrompt
|
||||||
|
@onready var _effect_status: Label = %EffectStatus
|
||||||
|
|
||||||
var _showcase_active: bool = false
|
var _showcase_active: bool = false
|
||||||
var _player_menu_open: bool = false
|
var _player_menu_open: bool = false
|
||||||
|
|
@ -47,6 +54,7 @@ var _gameplay_ui_enabled: bool = false
|
||||||
var _fishing_spot: FishingSpotType
|
var _fishing_spot: FishingSpotType
|
||||||
var _system_menu_open: bool = false
|
var _system_menu_open: bool = false
|
||||||
var _shop_open: bool = false
|
var _shop_open: bool = false
|
||||||
|
var _item_effects: PlayerItemEffectsType
|
||||||
|
|
||||||
|
|
||||||
func setup(
|
func setup(
|
||||||
|
|
@ -64,8 +72,11 @@ func setup(
|
||||||
main_shop_buyer: FishBuyerProfileType,
|
main_shop_buyer: FishBuyerProfileType,
|
||||||
fishing_upgrades: PlayerFishingUpgradesType,
|
fishing_upgrades: PlayerFishingUpgradesType,
|
||||||
shop_interaction: ShopInteractionType,
|
shop_interaction: ShopInteractionType,
|
||||||
|
item_effects: PlayerItemEffectsType,
|
||||||
|
cooler_capacity: PlayerCoolerCapacityType,
|
||||||
) -> void:
|
) -> void:
|
||||||
_fishing_spot = fishing_spot
|
_fishing_spot = fishing_spot
|
||||||
|
_item_effects = item_effects
|
||||||
fishing_spot.status_changed.connect(_on_fishing_status_changed)
|
fishing_spot.status_changed.connect(_on_fishing_status_changed)
|
||||||
fishing_spot.catch_display_changed.connect(_on_catch_display_changed)
|
fishing_spot.catch_display_changed.connect(_on_catch_display_changed)
|
||||||
fishing_spot.showcase_changed.connect(_on_showcase_changed)
|
fishing_spot.showcase_changed.connect(_on_showcase_changed)
|
||||||
|
|
@ -83,7 +94,8 @@ func setup(
|
||||||
fishing_spot,
|
fishing_spot,
|
||||||
bag,
|
bag,
|
||||||
hotbar,
|
hotbar,
|
||||||
item_catalog
|
item_catalog,
|
||||||
|
cooler_capacity
|
||||||
)
|
)
|
||||||
_hotbar_ui.setup(hotbar, bag, item_catalog, fishing_spot)
|
_hotbar_ui.setup(hotbar, bag, item_catalog, fishing_spot)
|
||||||
_fishing_shop.setup(
|
_fishing_shop.setup(
|
||||||
|
|
@ -94,11 +106,42 @@ func setup(
|
||||||
main_shop_buyer,
|
main_shop_buyer,
|
||||||
fishing_upgrades,
|
fishing_upgrades,
|
||||||
fishing_spot,
|
fishing_spot,
|
||||||
shop_interaction
|
shop_interaction,
|
||||||
|
bag,
|
||||||
|
item_catalog,
|
||||||
|
cooler_capacity
|
||||||
)
|
)
|
||||||
_fishing_shop.menu_visibility_changed.connect(_on_shop_visibility_changed)
|
_fishing_shop.menu_visibility_changed.connect(_on_shop_visibility_changed)
|
||||||
|
|
||||||
|
|
||||||
|
func _process(_delta: float) -> void:
|
||||||
|
if _item_effects == null or not _gameplay_ui_enabled:
|
||||||
|
_effect_status.hide()
|
||||||
|
return
|
||||||
|
var parts: Array[String] = []
|
||||||
|
for item_id: StringName in [
|
||||||
|
PlayerItemEffectsType.COFFEE_ID,
|
||||||
|
PlayerItemEffectsType.ENERGY_DRINK_ID,
|
||||||
|
PlayerItemEffectsType.SNACK_ID,
|
||||||
|
PlayerItemEffectsType.FISH_FINDER_ID,
|
||||||
|
]:
|
||||||
|
var remaining: float = _item_effects.get_remaining(item_id)
|
||||||
|
if remaining <= 0.0:
|
||||||
|
continue
|
||||||
|
var label: String = {
|
||||||
|
PlayerItemEffectsType.COFFEE_ID: "Coffee",
|
||||||
|
PlayerItemEffectsType.ENERGY_DRINK_ID: "Energy",
|
||||||
|
PlayerItemEffectsType.SNACK_ID: "Snack",
|
||||||
|
PlayerItemEffectsType.FISH_FINDER_ID: "Finder",
|
||||||
|
}.get(item_id, "")
|
||||||
|
parts.append(
|
||||||
|
"%s %d:%02d"
|
||||||
|
% [label, int(remaining) / 60, int(remaining) % 60]
|
||||||
|
)
|
||||||
|
_effect_status.text = " ".join(parts)
|
||||||
|
_effect_status.visible = not parts.is_empty()
|
||||||
|
|
||||||
|
|
||||||
func close_player_menu() -> void:
|
func close_player_menu() -> void:
|
||||||
_player_menu.close_menu()
|
_player_menu.close_menu()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,20 @@ horizontal_alignment = 1
|
||||||
[node name="FishingShop" parent="." instance=ExtResource("8_shop")]
|
[node name="FishingShop" parent="." instance=ExtResource("8_shop")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
|
|
||||||
|
[node name="EffectStatus" type="Label" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
visible = false
|
||||||
|
z_index = 54
|
||||||
|
offset_left = 18.0
|
||||||
|
offset_top = 18.0
|
||||||
|
offset_right = 500.0
|
||||||
|
offset_bottom = 44.0
|
||||||
|
mouse_filter = 2
|
||||||
|
theme = ExtResource("3_theme")
|
||||||
|
theme_override_colors/font_shadow_color = Color(0, 0, 0, 0.9)
|
||||||
|
theme_override_constants/shadow_offset_x = 2
|
||||||
|
theme_override_constants/shadow_offset_y = 2
|
||||||
|
|
||||||
[node name="ScreenFade" type="ColorRect" parent="."]
|
[node name="ScreenFade" type="ColorRect" parent="."]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
visible = false
|
visible = false
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@ const OwnedItemType = preload("res://items/owned_item.gd")
|
||||||
const PlayerBagType = preload("res://inventory/player_bag.gd")
|
const PlayerBagType = preload("res://inventory/player_bag.gd")
|
||||||
const PlayerHotbarType = preload("res://inventory/player_hotbar.gd")
|
const PlayerHotbarType = preload("res://inventory/player_hotbar.gd")
|
||||||
const ItemDragSourceType = preload("res://ui/item_drag_source.gd")
|
const ItemDragSourceType = preload("res://ui/item_drag_source.gd")
|
||||||
|
const PlayerCoolerCapacityType = preload(
|
||||||
|
"res://progression/player_cooler_capacity.gd"
|
||||||
|
)
|
||||||
|
|
||||||
signal menu_visibility_changed(is_open: bool)
|
signal menu_visibility_changed(is_open: bool)
|
||||||
|
|
||||||
|
|
@ -59,6 +62,7 @@ enum CloseReason {
|
||||||
@onready var _sort_option: OptionButton = %SortOption
|
@onready var _sort_option: OptionButton = %SortOption
|
||||||
@onready var _sort_direction: Button = %SortDirection
|
@onready var _sort_direction: Button = %SortDirection
|
||||||
@onready var _held_value: Label = %HeldValue
|
@onready var _held_value: Label = %HeldValue
|
||||||
|
@onready var _cooler_count: Label = %CoolerCount
|
||||||
@onready var _inventory_empty: Label = %InventoryEmpty
|
@onready var _inventory_empty: Label = %InventoryEmpty
|
||||||
@onready var _inventory_grid: GridContainer = %InventoryGrid
|
@onready var _inventory_grid: GridContainer = %InventoryGrid
|
||||||
@onready var _detail_texture: TextureRect = %DetailTexture
|
@onready var _detail_texture: TextureRect = %DetailTexture
|
||||||
|
|
@ -86,6 +90,7 @@ var _fishing_spot: FishingSpotType
|
||||||
var _bag: PlayerBagType
|
var _bag: PlayerBagType
|
||||||
var _hotbar: PlayerHotbarType
|
var _hotbar: PlayerHotbarType
|
||||||
var _item_catalog: ItemCatalogType
|
var _item_catalog: ItemCatalogType
|
||||||
|
var _cooler_capacity: PlayerCoolerCapacityType
|
||||||
var _current_section: Section = Section.COOLER
|
var _current_section: Section = Section.COOLER
|
||||||
var _sort_mode: SortMode = SortMode.CATCH_ORDER
|
var _sort_mode: SortMode = SortMode.CATCH_ORDER
|
||||||
var _sort_descending: bool = true
|
var _sort_descending: bool = true
|
||||||
|
|
@ -138,6 +143,7 @@ func setup(
|
||||||
bag: PlayerBagType,
|
bag: PlayerBagType,
|
||||||
hotbar: PlayerHotbarType,
|
hotbar: PlayerHotbarType,
|
||||||
item_catalog: ItemCatalogType,
|
item_catalog: ItemCatalogType,
|
||||||
|
cooler_capacity: PlayerCoolerCapacityType,
|
||||||
) -> void:
|
) -> void:
|
||||||
_player = player
|
_player = player
|
||||||
_inventory = inventory
|
_inventory = inventory
|
||||||
|
|
@ -150,6 +156,7 @@ func setup(
|
||||||
_bag = bag
|
_bag = bag
|
||||||
_hotbar = hotbar
|
_hotbar = hotbar
|
||||||
_item_catalog = item_catalog
|
_item_catalog = item_catalog
|
||||||
|
_cooler_capacity = cooler_capacity
|
||||||
if not _inventory.catches_changed.is_connected(_on_inventory_changed):
|
if not _inventory.catches_changed.is_connected(_on_inventory_changed):
|
||||||
_inventory.catches_changed.connect(_on_inventory_changed)
|
_inventory.catches_changed.connect(_on_inventory_changed)
|
||||||
if not _collection_log.fish_discovered.is_connected(_on_fish_discovered):
|
if not _collection_log.fish_discovered.is_connected(_on_fish_discovered):
|
||||||
|
|
@ -160,6 +167,10 @@ func setup(
|
||||||
_fishing_spot.bite_activated.connect(_on_bite_activated)
|
_fishing_spot.bite_activated.connect(_on_bite_activated)
|
||||||
if not _bag.contents_changed.is_connected(_on_bag_changed):
|
if not _bag.contents_changed.is_connected(_on_bag_changed):
|
||||||
_bag.contents_changed.connect(_on_bag_changed)
|
_bag.contents_changed.connect(_on_bag_changed)
|
||||||
|
if not _cooler_capacity.capacity_changed.is_connected(
|
||||||
|
_on_cooler_capacity_changed
|
||||||
|
):
|
||||||
|
_cooler_capacity.capacity_changed.connect(_on_cooler_capacity_changed)
|
||||||
_refresh_all()
|
_refresh_all()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -461,6 +472,14 @@ func _refresh_economy_summary() -> void:
|
||||||
)
|
)
|
||||||
_wallet_balance.text = "Wallet: $%d" % balance
|
_wallet_balance.text = "Wallet: $%d" % balance
|
||||||
_held_value.text = "Held fish base value: $%d" % held_total
|
_held_value.text = "Held fish base value: $%d" % 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,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
func _on_cooler_capacity_changed(_level: int, _capacity: int) -> void:
|
||||||
|
_refresh_economy_summary()
|
||||||
|
|
||||||
|
|
||||||
func _refresh_inventory() -> void:
|
func _refresh_inventory() -> void:
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,12 @@ text = "Newest first"
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
|
[node name="CoolerCount" type="Label" parent="MenuPanel/Margin/Layout/Content/InventorySection/SortBar"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
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="MenuPanel/Margin/Layout/Content/InventorySection/SortBar"]
|
[node name="HeldValue" type="Label" parent="MenuPanel/Margin/Layout/Content/InventorySection/SortBar"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue