60 lines
1.6 KiB
GDScript
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),
|
|
}
|