Capture current source, content data, tests, asset licenses, and original-specification traceability. Original implementation remains incomplete. The accepted matching UI generation passed 154 suites and 12,253 checks, with eight rendered staff-contract screens reviewed. Latest native Windows and full-original acceptance remain outstanding.
100 lines
4.2 KiB
GDScript
100 lines
4.2 KiB
GDScript
extends RefCounted
|
|
|
|
## Finite mana reserve; timing and production rates belong to the caller.
|
|
## Every advance supplies totals for ONE interval, not a per-minute rate.
|
|
## Generation first covers demand, then unused mana enters storage up to capacity.
|
|
## No Runtime wiring or default balance values are implied by this component.
|
|
const VERSION := 1
|
|
const LIMIT := 1000000000
|
|
var _capacity := -1
|
|
var _amount := -1
|
|
var _minute := -1
|
|
var _last_flow: Dictionary = {}
|
|
|
|
func initialize(amount: Variant, capacity: Variant, minute: Variant) -> Dictionary:
|
|
if _minute >= 0:
|
|
return _failure(&"ALREADY_INITIALIZED")
|
|
if not _integer(amount) or not _integer(capacity) or not _integer(minute) or amount > capacity:
|
|
return _failure(&"INVALID_INITIAL_STATE")
|
|
_capacity = capacity
|
|
_amount = amount
|
|
_minute = minute
|
|
return {&"ok": true}
|
|
|
|
func get_amount() -> int:
|
|
return _amount
|
|
|
|
func is_depleted() -> bool:
|
|
return _minute >= 0 and _amount == 0
|
|
|
|
func advance_to(minute: Variant, generation: Variant, demand: Variant) -> Dictionary:
|
|
if _minute < 0:
|
|
return _failure(&"NOT_INITIALIZED")
|
|
if not _integer(minute) or not _integer(generation) or not _integer(demand) or minute < _minute:
|
|
return _failure(&"INVALID_FLOW")
|
|
if minute == _minute:
|
|
if not _last_flow.is_empty() and generation == _last_flow[&"generation"] and demand == _last_flow[&"demand"]:
|
|
return {&"ok": true, &"replayed": true, &"flow": _last_flow.duplicate(true)}
|
|
return _failure(&"REPLAY_MISMATCH")
|
|
var flow := _plan(_amount, _capacity, generation, demand, _minute, minute)
|
|
_amount = flow[&"after"]
|
|
_minute = minute
|
|
_last_flow = flow
|
|
return {&"ok": true, &"replayed": false, &"flow": flow.duplicate(true)}
|
|
|
|
func create_snapshot() -> Dictionary:
|
|
return {&"version": VERSION, &"capacity": _capacity, &"amount": _amount,
|
|
&"minute": _minute, &"last_flow": _last_flow.duplicate(true)}
|
|
|
|
func restore_snapshot(source: Dictionary) -> bool:
|
|
if not _keys(source, ["version", "capacity", "amount", "minute", "last_flow"]) \
|
|
or typeof(source["version"]) != TYPE_INT or source["version"] != VERSION \
|
|
or not _integer(source["capacity"]) or not _integer(source["amount"]) \
|
|
or not _integer(source["minute"]) or source["amount"] > source["capacity"] \
|
|
or not source["last_flow"] is Dictionary:
|
|
return false
|
|
var flow: Dictionary = source["last_flow"]
|
|
if not flow.is_empty():
|
|
if not _keys(flow, ["from_minute", "to_minute", "before", "generation", "demand", "consumed", "shortage", "overflow", "after"]):
|
|
return false
|
|
for key: Variant in flow:
|
|
# Overflow may include an entire reserve plus this interval's supply.
|
|
if typeof(flow[key]) != TYPE_INT or flow[key] < 0 or flow[key] > LIMIT * 2:
|
|
return false
|
|
if not _integer(flow["generation"]) or not _integer(flow["demand"]) \
|
|
or not _integer(flow["from_minute"]) or flow["from_minute"] >= flow["to_minute"] \
|
|
or flow["to_minute"] != source["minute"] or flow["before"] > source["capacity"]:
|
|
return false
|
|
var expected := _plan(flow["before"], source["capacity"], flow["generation"], flow["demand"], flow["from_minute"], flow["to_minute"])
|
|
if expected != flow or flow["after"] != source["amount"]:
|
|
return false
|
|
# Commit only after validation; invalid loads leave the existing reserve intact.
|
|
_capacity = source["capacity"]
|
|
_amount = source["amount"]
|
|
_minute = source["minute"]
|
|
_last_flow = flow.duplicate(true)
|
|
return true
|
|
|
|
static func _plan(before: int, capacity: int, generation: int, demand: int, start: int, end: int) -> Dictionary:
|
|
var available := before + generation
|
|
var consumed := mini(available, demand)
|
|
var remaining := available - consumed
|
|
return {&"from_minute": start, &"to_minute": end, &"before": before,
|
|
&"generation": generation, &"demand": demand, &"consumed": consumed,
|
|
&"shortage": demand - consumed, &"overflow": maxi(remaining - capacity, 0),
|
|
&"after": mini(remaining, capacity)}
|
|
|
|
static func _integer(value: Variant) -> bool:
|
|
return typeof(value) == TYPE_INT and value >= 0 and value <= LIMIT
|
|
|
|
static func _keys(source: Dictionary, expected: Array) -> bool:
|
|
if source.size() != expected.size():
|
|
return false
|
|
for key: Variant in source:
|
|
if typeof(key) not in [TYPE_STRING, TYPE_STRING_NAME] or String(key) not in expected:
|
|
return false
|
|
return true
|
|
|
|
static func _failure(code: StringName) -> Dictionary:
|
|
return {&"ok": false, &"code": code}
|