79 lines
2 KiB
GDScript
79 lines
2 KiB
GDScript
class_name Inventory
|
|
extends RefCounted
|
|
|
|
var total_capacity: int = -1
|
|
var resource_capacities: Dictionary = {}
|
|
var _amounts: Dictionary = {}
|
|
|
|
|
|
func _init(initial: Dictionary = {}, capacity: int = -1) -> void:
|
|
total_capacity = capacity
|
|
for resource_id in initial:
|
|
set_amount(String(resource_id), int(initial[resource_id]))
|
|
|
|
|
|
func amount(resource_id: String) -> int:
|
|
return int(_amounts.get(resource_id, 0))
|
|
|
|
|
|
func total() -> int:
|
|
var result: int = 0
|
|
for value in _amounts.values():
|
|
result += int(value)
|
|
return result
|
|
|
|
|
|
func capacity_for(resource_id: String) -> int:
|
|
return int(resource_capacities.get(resource_id, -1))
|
|
|
|
|
|
func space_for(resource_id: String) -> int:
|
|
var space: int = 1 << 30
|
|
if total_capacity >= 0:
|
|
space = maxi(total_capacity - total(), 0)
|
|
var resource_capacity: int = capacity_for(resource_id)
|
|
if resource_capacity >= 0:
|
|
space = mini(space, maxi(resource_capacity - amount(resource_id), 0))
|
|
return space
|
|
|
|
|
|
func set_amount(resource_id: String, value: int) -> int:
|
|
_amounts.erase(resource_id)
|
|
var accepted: int = mini(maxi(value, 0), space_for(resource_id))
|
|
if accepted > 0:
|
|
_amounts[resource_id] = accepted
|
|
return amount(resource_id)
|
|
|
|
|
|
func deposit(resource_id: String, requested: int) -> int:
|
|
var moved: int = mini(maxi(requested, 0), space_for(resource_id))
|
|
if moved > 0:
|
|
_amounts[resource_id] = amount(resource_id) + moved
|
|
return moved
|
|
|
|
|
|
func withdraw(resource_id: String, requested: int) -> int:
|
|
var moved: int = mini(maxi(requested, 0), amount(resource_id))
|
|
if moved <= 0:
|
|
return 0
|
|
var remaining: int = amount(resource_id) - moved
|
|
if remaining > 0:
|
|
_amounts[resource_id] = remaining
|
|
else:
|
|
_amounts.erase(resource_id)
|
|
return moved
|
|
|
|
|
|
func transfer_to(destination: Inventory, resource_id: String, requested: int) -> int:
|
|
if destination == null:
|
|
return 0
|
|
var moved: int = mini(mini(maxi(requested, 0), amount(resource_id)), destination.space_for(resource_id))
|
|
if moved <= 0:
|
|
return 0
|
|
withdraw(resource_id, moved)
|
|
destination.deposit(resource_id, moved)
|
|
return moved
|
|
|
|
|
|
func snapshot() -> Dictionary:
|
|
return _amounts.duplicate()
|