133 lines
4.3 KiB
GDScript
133 lines
4.3 KiB
GDScript
extends Node
|
|
|
|
func _ready() -> void:
|
|
EventBus.assert_ready() # Verify autoload order
|
|
|
|
var current_floor: int = 0
|
|
var current_room_id: String = ""
|
|
var run_active: bool = false
|
|
|
|
# --- Collected this run (lost on death) ---
|
|
var run_items: Array[Resource] = []
|
|
var card_packs_found: Array[Resource] = []
|
|
|
|
# --- Credits (brought in + earned in run — lost on death, returned on success) ---
|
|
var run_credits: int = 0 # total spendable during this run
|
|
var credits_brought_in: int = 0
|
|
|
|
# --- Brought into the run (lost on death) ---
|
|
var buff_items_brought: Array[Resource] = []
|
|
var npc_ids_on_run: Array[String] = []
|
|
|
|
# --- Floor-to-floor carry (not saved, only lives for one scene reload) ---
|
|
var player_health_carry: float = -1.0 # -1 = no carry, use default full health
|
|
|
|
# --- Spawned items on current floor (prevents duplicates across rooms) ---
|
|
var spawned_item_paths: Array[String] = []
|
|
|
|
# --- Hub spawn flag (cleared after hub reads it) ---
|
|
var returning_from_run: bool = false
|
|
|
|
func start_run(brought_credits: int, brought_buffs: Array[Resource], brought_npc_ids: Array[String]) -> void:
|
|
current_floor = 1
|
|
current_room_id = ""
|
|
run_active = true
|
|
player_health_carry = -1.0
|
|
run_items.clear()
|
|
card_packs_found.clear()
|
|
spawned_item_paths.clear()
|
|
credits_brought_in = brought_credits
|
|
run_credits = brought_credits
|
|
buff_items_brought = brought_buffs.duplicate()
|
|
npc_ids_on_run = brought_npc_ids.duplicate()
|
|
EventBus.credits_changed.emit(run_credits)
|
|
EventBus.run_started.emit()
|
|
|
|
func end_run(player_survived: bool) -> void:
|
|
run_active = false
|
|
returning_from_run = true
|
|
if player_survived:
|
|
_apply_run_rewards()
|
|
else:
|
|
_apply_run_death()
|
|
EventBus.run_ended.emit(player_survived)
|
|
|
|
func advance_floor() -> void:
|
|
EventBus.floor_cleared.emit(current_floor)
|
|
current_floor += 1
|
|
spawned_item_paths.clear() # Reset for new floor
|
|
|
|
func collect_item(item: Resource) -> void:
|
|
run_items.append(item)
|
|
EventBus.item_collected.emit(item)
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Item spawn tracking — prevents same item appearing in multiple rooms
|
|
# ---------------------------------------------------------------------------
|
|
const PATCH_KIT_PATH := "res://data/run_items/patch_kit.tres"
|
|
|
|
func is_item_available(path: String) -> bool:
|
|
# Patch Kit always restocks - can be purchased multiple times
|
|
if path == PATCH_KIT_PATH:
|
|
return true
|
|
# Check if already collected
|
|
for collected in run_items:
|
|
if collected.resource_path == path:
|
|
return false
|
|
# Check if already spawned on this floor
|
|
if path in spawned_item_paths:
|
|
return false
|
|
return true
|
|
|
|
func reserve_item(path: String) -> void:
|
|
# Don't reserve Patch Kit - it can appear in multiple places
|
|
if path == PATCH_KIT_PATH:
|
|
return
|
|
if path not in spawned_item_paths:
|
|
spawned_item_paths.append(path)
|
|
|
|
func collect_card_pack(pack: Resource) -> void:
|
|
card_packs_found.append(pack)
|
|
EventBus.card_pack_found.emit(pack)
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Credit management — called by currency_orb and shop_item_pedestal
|
|
# ---------------------------------------------------------------------------
|
|
func earn_credits(amount: int) -> void:
|
|
run_credits += amount
|
|
EventBus.credits_changed.emit(run_credits)
|
|
|
|
func spend_credits(amount: int) -> void:
|
|
run_credits = maxi(run_credits - amount, 0)
|
|
EventBus.credits_changed.emit(run_credits)
|
|
|
|
func _apply_run_rewards() -> void:
|
|
# Permanent: card packs go to collection
|
|
for pack in card_packs_found:
|
|
CardCollection.open_pack(pack)
|
|
# Return all remaining run credits to the player's wallet (on hand)
|
|
UpgradeManager.wallet_credits += run_credits
|
|
run_credits = 0
|
|
# Run items are non-permanent — clear them (body parts stay via UpgradeManager)
|
|
run_items.clear()
|
|
card_packs_found.clear()
|
|
spawned_item_paths.clear()
|
|
# Health resets on hub return — do not carry it over
|
|
player_health_carry = -1.0
|
|
# NPCs survive
|
|
for npc_id in npc_ids_on_run:
|
|
NPCManager.return_npc_to_hub(npc_id)
|
|
|
|
func _apply_run_death() -> void:
|
|
# Everything brought in / found is lost
|
|
run_items.clear()
|
|
card_packs_found.clear()
|
|
spawned_item_paths.clear()
|
|
run_credits = 0
|
|
credits_brought_in = 0
|
|
buff_items_brought.clear()
|
|
# NPCs on run are lost
|
|
for npc_id in npc_ids_on_run:
|
|
NPCManager.lose_npc(npc_id)
|
|
npc_ids_on_run.clear()
|
|
EventBus.player_died.emit() |