113 lines
3.5 KiB
GDScript
113 lines
3.5 KiB
GDScript
extends Node
|
|
|
|
signal resource_changed(resource_name: StringName, value: int)
|
|
signal state_reset
|
|
signal revision_changed(revision: int)
|
|
signal world_tree_rank_changed(rank: int)
|
|
|
|
const DEFAULT_RESOURCES := {
|
|
&"gold": 5000,
|
|
&"mana": 100,
|
|
&"materials": 50,
|
|
&"faith": 0,
|
|
}
|
|
|
|
var resources: Dictionary = DEFAULT_RESOURCES.duplicate(true)
|
|
var world_tree_rank := 1
|
|
var active_layer := 0
|
|
var revision := 0
|
|
|
|
func reset() -> void:
|
|
resources = DEFAULT_RESOURCES.duplicate(true)
|
|
world_tree_rank = 1
|
|
active_layer = 0
|
|
revision = 0
|
|
state_reset.emit()
|
|
for resource_name: StringName in resources:
|
|
resource_changed.emit(resource_name, resources[resource_name])
|
|
|
|
func get_resource(resource_name: StringName) -> int:
|
|
return int(resources.get(resource_name, 0))
|
|
|
|
func set_resource(resource_name: StringName, value: int) -> void:
|
|
var next_value := maxi(value, 0)
|
|
if get_resource(resource_name) == next_value:
|
|
return
|
|
resources[resource_name] = next_value
|
|
_touch_revision()
|
|
resource_changed.emit(resource_name, resources[resource_name])
|
|
|
|
func add_resource(resource_name: StringName, amount: int) -> int:
|
|
set_resource(resource_name, get_resource(resource_name) + amount)
|
|
return get_resource(resource_name)
|
|
|
|
func can_afford(cost: Dictionary) -> bool:
|
|
for resource_name: Variant in cost:
|
|
if get_resource(StringName(resource_name)) < int(cost[resource_name]):
|
|
return false
|
|
return true
|
|
|
|
func spend(cost: Dictionary) -> bool:
|
|
if not can_afford(cost):
|
|
return false
|
|
var deltas := {}
|
|
for resource_name: Variant in cost:
|
|
deltas[StringName(resource_name)] = -int(cost[resource_name])
|
|
return apply_resource_deltas(deltas)
|
|
|
|
func apply_resource_deltas(deltas: Dictionary) -> bool:
|
|
var next_values := {}
|
|
for resource_name: Variant in deltas:
|
|
var normalized_name := StringName(resource_name)
|
|
var next_value := get_resource(normalized_name) + int(deltas[resource_name])
|
|
if next_value < 0:
|
|
return false
|
|
next_values[normalized_name] = next_value
|
|
if next_values.is_empty():
|
|
return true
|
|
for resource_name: Variant in next_values:
|
|
resources[resource_name] = next_values[resource_name]
|
|
_touch_revision()
|
|
for resource_name: Variant in next_values:
|
|
resource_changed.emit(resource_name, int(next_values[resource_name]))
|
|
return true
|
|
|
|
func set_world_tree_rank(value: int) -> bool:
|
|
if value < world_tree_rank or value < 1 or value > 7:
|
|
return false
|
|
if value == world_tree_rank:
|
|
return true
|
|
world_tree_rank = value
|
|
_touch_revision()
|
|
world_tree_rank_changed.emit(world_tree_rank)
|
|
return true
|
|
|
|
func create_snapshot() -> Dictionary:
|
|
return {
|
|
&"resources": resources.duplicate(true),
|
|
&"world_tree_rank": world_tree_rank,
|
|
&"active_layer": active_layer,
|
|
&"revision": revision,
|
|
}
|
|
|
|
func restore_snapshot(snapshot: Dictionary) -> bool:
|
|
if not snapshot.has(&"resources") or not snapshot[&"resources"] is Dictionary:
|
|
return false
|
|
var restored_resources: Dictionary = snapshot[&"resources"]
|
|
for resource_name: Variant in restored_resources:
|
|
if int(restored_resources[resource_name]) < 0:
|
|
return false
|
|
resources = restored_resources.duplicate(true)
|
|
world_tree_rank = maxi(int(snapshot.get(&"world_tree_rank", 1)), 1)
|
|
active_layer = clampi(int(snapshot.get(&"active_layer", 0)), 0, 1)
|
|
revision = maxi(int(snapshot.get(&"revision", 0)), 0)
|
|
state_reset.emit()
|
|
for resource_name: Variant in resources:
|
|
resource_changed.emit(StringName(resource_name), int(resources[resource_name]))
|
|
revision_changed.emit(revision)
|
|
return true
|
|
|
|
func _touch_revision() -> void:
|
|
revision += 1
|
|
revision_changed.emit(revision)
|