79 lines
2.1 KiB
GDScript
79 lines
2.1 KiB
GDScript
class_name P93CoreLoopState
|
|
extends RefCounted
|
|
|
|
enum Phase { TITLE, HALL, ENCOUNTER, BATTLE, RESULT }
|
|
|
|
var revision := 0
|
|
var phase := Phase.TITLE
|
|
var coin := 24
|
|
var company: Array[String] = ["Hearthguard"]
|
|
var available_offers: Array[String] = ["Wayrunner", "Farstring", "Kindhand"]
|
|
var focused_offer := ""
|
|
var hired_member := ""
|
|
var selected_encounter := ""
|
|
var reward_committed := false
|
|
var last_reward := 0
|
|
var last_outcome := ""
|
|
var hire_receipts: Array[Dictionary] = []
|
|
var reward_receipts: Array[Dictionary] = []
|
|
|
|
|
|
func reset() -> void:
|
|
revision = 0
|
|
phase = Phase.TITLE
|
|
coin = 24
|
|
company.assign(["Hearthguard"])
|
|
available_offers.assign(["Wayrunner", "Farstring", "Kindhand"])
|
|
focused_offer = ""
|
|
hired_member = ""
|
|
selected_encounter = ""
|
|
reward_committed = false
|
|
last_reward = 0
|
|
last_outcome = ""
|
|
hire_receipts.clear()
|
|
reward_receipts.clear()
|
|
|
|
|
|
func snapshot() -> Dictionary:
|
|
return {
|
|
"revision": revision,
|
|
"phase": phase,
|
|
"coin": coin,
|
|
"company": company.duplicate(),
|
|
"capacity": 10,
|
|
"available_offers": available_offers.duplicate(),
|
|
"focused_offer": focused_offer,
|
|
"hired_member": hired_member,
|
|
"selected_encounter": selected_encounter,
|
|
"reward_committed": reward_committed,
|
|
"last_reward": last_reward,
|
|
"last_outcome": last_outcome,
|
|
"hire_receipts": hire_receipts.duplicate(true),
|
|
"reward_receipts": reward_receipts.duplicate(true),
|
|
}.duplicate(true)
|
|
|
|
|
|
func invariants_hold() -> bool:
|
|
if revision < 0 or coin < 0:
|
|
return false
|
|
if phase < Phase.TITLE or phase > Phase.RESULT:
|
|
return false
|
|
if company.is_empty() or company.size() > 10:
|
|
return false
|
|
var seen := {}
|
|
for member_id in company:
|
|
if member_id not in ["Hearthguard", "Wayrunner", "Farstring", "Kindhand"] or seen.has(member_id):
|
|
return false
|
|
seen[member_id] = true
|
|
for offer_id in available_offers:
|
|
if seen.has(offer_id):
|
|
return false
|
|
seen[offer_id] = true
|
|
if not focused_offer.is_empty() and focused_offer not in available_offers:
|
|
return false
|
|
if not selected_encounter.is_empty() and selected_encounter not in ["open_road", "crosswind", "bell_breach"]:
|
|
return false
|
|
if reward_committed and last_outcome != "victory":
|
|
return false
|
|
return true
|