fix: enforce storage and tooling invariants
This commit is contained in:
@@ -288,6 +288,26 @@ static func from_dictionary(record_data: Dictionary) -> SimulationStateRecord:
|
||||
storage_ids[storage_id] = true
|
||||
storage_records_by_id[storage_id] = storage_record
|
||||
record.storages.append(storage_record)
|
||||
var pantry := (
|
||||
storage_records_by_id.get(SimulationIds.STORAGE_VILLAGE_PANTRY) as StorageStateRecord
|
||||
)
|
||||
if (
|
||||
pantry != null
|
||||
and not is_equal_approx(
|
||||
float(record.village.data["food"]), pantry.get_amount(SimulationIds.RESOURCE_FOOD)
|
||||
)
|
||||
):
|
||||
return null
|
||||
var woodpile := (
|
||||
storage_records_by_id.get(SimulationIds.STORAGE_VILLAGE_WOODPILE) as StorageStateRecord
|
||||
)
|
||||
if (
|
||||
woodpile != null
|
||||
and not is_equal_approx(
|
||||
float(record.village.data["wood"]), woodpile.get_amount(SimulationIds.RESOURCE_WOOD)
|
||||
)
|
||||
):
|
||||
return null
|
||||
|
||||
var event_ids := {}
|
||||
var event_records_by_id := {}
|
||||
@@ -689,7 +709,8 @@ static func _migrate_legacy(legacy_data: Dictionary, version: int) -> Dictionary
|
||||
StorageStateRecord
|
||||
. create(
|
||||
SimulationIds.STORAGE_VILLAGE_PANTRY,
|
||||
{String(SimulationIds.RESOURCE_FOOD): initial_food}
|
||||
{String(SimulationIds.RESOURCE_FOOD): initial_food},
|
||||
maxf(StorageStateRecord.DEFAULT_CAPACITY, initial_food)
|
||||
)
|
||||
. to_dictionary()
|
||||
),
|
||||
@@ -697,7 +718,8 @@ static func _migrate_legacy(legacy_data: Dictionary, version: int) -> Dictionary
|
||||
StorageStateRecord
|
||||
. create(
|
||||
SimulationIds.STORAGE_VILLAGE_WOODPILE,
|
||||
{String(SimulationIds.RESOURCE_WOOD): initial_wood}
|
||||
{String(SimulationIds.RESOURCE_WOOD): initial_wood},
|
||||
maxf(StorageStateRecord.DEFAULT_CAPACITY, initial_wood)
|
||||
)
|
||||
. to_dictionary()
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@ class_name StorageStateRecord
|
||||
extends RefCounted
|
||||
|
||||
const SCHEMA_VERSION := 1
|
||||
const DEFAULT_CAPACITY := 100.0
|
||||
|
||||
var data: Dictionary
|
||||
|
||||
@@ -11,7 +12,7 @@ func _init(record_data: Dictionary = {}) -> void:
|
||||
|
||||
|
||||
static func create(
|
||||
storage_id: StringName, initial_amounts: Dictionary, capacity: float = 100.0
|
||||
storage_id: StringName, initial_amounts: Dictionary, capacity: float = DEFAULT_CAPACITY
|
||||
) -> StorageStateRecord:
|
||||
return StorageStateRecord.new(
|
||||
{
|
||||
@@ -32,12 +33,28 @@ static func from_dictionary(record_data: Dictionary) -> StorageStateRecord:
|
||||
return null
|
||||
if not record_data["amounts"] is Dictionary:
|
||||
return null
|
||||
var capacity := float(record_data["capacity"])
|
||||
if not is_finite(capacity) or capacity < 0.0:
|
||||
return null
|
||||
var normalized := record_data.duplicate(true)
|
||||
normalized["schema_version"] = SCHEMA_VERSION
|
||||
normalized["capacity"] = float(record_data["capacity"])
|
||||
normalized["capacity"] = capacity
|
||||
var normalized_amounts := {}
|
||||
for item_id in record_data["amounts"]:
|
||||
normalized_amounts[String(item_id)] = float(record_data["amounts"][item_id])
|
||||
var total_amount := 0.0
|
||||
for raw_item_id in record_data["amounts"]:
|
||||
var item_id := String(raw_item_id)
|
||||
var amount := float(record_data["amounts"][raw_item_id])
|
||||
if (
|
||||
item_id.is_empty()
|
||||
or normalized_amounts.has(item_id)
|
||||
or not is_finite(amount)
|
||||
or amount < 0.0
|
||||
):
|
||||
return null
|
||||
total_amount += amount
|
||||
if not is_finite(total_amount) or total_amount > capacity:
|
||||
return null
|
||||
normalized_amounts[item_id] = amount
|
||||
normalized["amounts"] = normalized_amounts
|
||||
return StorageStateRecord.new(normalized)
|
||||
|
||||
@@ -62,6 +79,8 @@ func get_available_capacity() -> float:
|
||||
|
||||
|
||||
func deposit(item_id: StringName, requested_amount: float) -> float:
|
||||
if item_id.is_empty() or not is_finite(requested_amount) or requested_amount <= 0.0:
|
||||
return 0.0
|
||||
var accepted := minf(maxf(requested_amount, 0.0), get_available_capacity())
|
||||
if accepted <= 0.0:
|
||||
return 0.0
|
||||
@@ -70,6 +89,8 @@ func deposit(item_id: StringName, requested_amount: float) -> float:
|
||||
|
||||
|
||||
func withdraw(item_id: StringName, requested_amount: float) -> float:
|
||||
if item_id.is_empty() or not is_finite(requested_amount) or requested_amount <= 0.0:
|
||||
return 0.0
|
||||
var removed := minf(maxf(requested_amount, 0.0), get_amount(item_id))
|
||||
if removed <= 0.0:
|
||||
return 0.0
|
||||
|
||||
Reference in New Issue
Block a user