Files
2026-08-12 20:50:44 +02:00

60 lines
1.6 KiB
GDScript

class_name AnalyticalRegionalUpdates
extends RefCounted
static func linear_value(
current_value: float,
rate_per_tick: float,
elapsed_ticks: int,
minimum: float = -INF,
maximum: float = INF
) -> float:
if elapsed_ticks <= 0 or not is_finite(current_value) or not is_finite(rate_per_tick):
return clampf(current_value, minimum, maximum)
return clampf(current_value + rate_per_tick * elapsed_ticks, minimum, maximum)
static func exponential_value(
current_value: float,
multiplier_per_tick: float,
elapsed_ticks: int,
minimum: float = -INF,
maximum: float = INF
) -> float:
if (
elapsed_ticks <= 0
or not is_finite(current_value)
or not is_finite(multiplier_per_tick)
or multiplier_per_tick < 0.0
):
return clampf(current_value, minimum, maximum)
return clampf(current_value * pow(multiplier_per_tick, elapsed_ticks), minimum, maximum)
static func periodic_occurrences(
first_due_tick: int, interval_ticks: int, through_tick: int
) -> int:
if first_due_tick < 0 or interval_ticks <= 0 or through_tick < first_due_tick:
return 0
return (through_tick - first_due_tick) / interval_ticks + 1
static func transfer_amount(
available: float,
demand: float,
rate_per_tick: float,
elapsed_ticks: int,
loss_fraction: float = 0.0
) -> Dictionary:
var sent := minf(
maxf(available, 0.0),
minf(maxf(demand, 0.0), maxf(rate_per_tick, 0.0) * maxi(elapsed_ticks, 0))
)
var received := sent * (1.0 - clampf(loss_fraction, 0.0, 1.0))
return {
"sent": sent,
"received": received,
"remaining_available": maxf(available - sent, 0.0),
"remaining_demand": maxf(demand - received, 0.0),
}