Files
gamedev-the-steward/simulation/events/SimulationEventLog.gd
T
2026-07-16 12:36:50 +02:00

137 lines
3.3 KiB
GDScript

extends RefCounted
signal event_recorded(event: EconomicEventRecord)
const DEFAULT_RATE_WINDOW_TICKS := 200
const DEFAULT_TICKS_PER_DAY := 200.0
var events: Array[EconomicEventRecord] = []
var next_event_id := 0
func record_economic(
tick: int,
event_type: StringName,
actor_id: int,
source_id: StringName,
destination_id: StringName,
item_id: StringName,
amount: float,
world_position: Vector3 = Vector3.ZERO
) -> EconomicEventRecord:
if amount <= 0.0:
return null
var event := EconomicEventRecord.create(
next_event_id,
event_type,
tick,
actor_id,
source_id,
destination_id,
item_id,
amount,
world_position
)
_append(event)
return event
func record_narrative(
tick: int,
event_type: StringName,
actor_id: int,
source_id: StringName = &"",
action_display: String = "",
world_position: Vector3 = Vector3.ZERO,
action_id: StringName = &"",
item_id: StringName = &"",
required_amount: float = 0.0
) -> EconomicEventRecord:
var event := EconomicEventRecord.create_narrative(
next_event_id,
event_type,
tick,
actor_id,
source_id,
action_display,
world_position,
action_id,
item_id,
required_amount
)
_append(event)
return event
func get_for_actor(actor_id: int, max_count: int = 8) -> Array[EconomicEventRecord]:
var results: Array[EconomicEventRecord] = []
for index in range(events.size() - 1, -1, -1):
var event := events[index]
if int(event.data["actor_id"]) != actor_id:
continue
results.append(event)
if results.size() >= max_count:
break
results.reverse()
return results
func get_recent(max_count: int = 5) -> Array[EconomicEventRecord]:
var results: Array[EconomicEventRecord] = []
var start := maxi(events.size() - max_count, 0)
for index in range(start, events.size()):
results.append(events[index])
return results
func get_by_id(event_id: int) -> EconomicEventRecord:
for event in events:
if int(event.data["event_id"]) == event_id:
return event
return null
func get_by_ids(event_ids: Array[int]) -> Array[EconomicEventRecord]:
var results: Array[EconomicEventRecord] = []
for event_id in event_ids:
var event := get_by_id(event_id)
if event != null:
results.append(event)
return results
func get_consumption_rates(
current_tick: int,
window_ticks: int = DEFAULT_RATE_WINDOW_TICKS,
ticks_per_day: float = DEFAULT_TICKS_PER_DAY
) -> Dictionary:
var consumed := {
SimulationIds.RESOURCE_FOOD: 0.0,
SimulationIds.RESOURCE_WOOD: 0.0,
}
var first_tick := maxi(current_tick - window_ticks, 0)
for event in events:
if int(event.data["tick"]) < first_tick:
continue
if StringName(event.data["event_type"]) != SimulationIds.EVENT_ITEM_CONSUMED:
continue
var item_id := StringName(event.data["item_id"])
if consumed.has(item_id):
consumed[item_id] = float(consumed[item_id]) + float(event.data["amount"])
var elapsed := maxi(current_tick - first_tick, 1)
return {
"food_per_day": float(consumed[SimulationIds.RESOURCE_FOOD]) / elapsed * ticks_per_day,
"wood_per_day": float(consumed[SimulationIds.RESOURCE_WOOD]) / elapsed * ticks_per_day,
}
func restore(restored_events: Array[EconomicEventRecord], restored_next_id: int) -> void:
events = restored_events.duplicate()
next_event_id = restored_next_id
func _append(event: EconomicEventRecord) -> void:
next_event_id += 1
events.append(event)
event_recorded.emit(event)