2026-09-16 19:54:47 +03:00
|
|
|
extends RefCounted
|
2026-10-07 22:51:55 +03:00
|
|
|
## Shared civilization coefficients and worship derived from float profiles.
|
2026-09-30 08:08:27 +03:00
|
|
|
const E = preload("res://world/owniverse/math/exact.gd")
|
2026-09-16 19:54:47 +03:00
|
|
|
const State = preload("res://world/owniverse/civilization_state.gd")
|
|
|
|
|
const ETHICS = State.ETHICS
|
|
|
|
|
const OPPOSITE = {"m": "l", "l": "m", "w": "d", "d": "w", "c": "b", "b": "c"}
|
|
|
|
|
|
2026-10-07 22:51:55 +03:00
|
|
|
# Cache the weighted float worship rate multiplied by the exact population.
|
2026-10-08 21:10:36 +03:00
|
|
|
static func worship(world, target: Dictionary, rules: Dictionary, physical: Dictionary = {}) -> Variant:
|
2026-10-05 22:16:59 +03:00
|
|
|
var result: Variant = 0
|
2026-10-08 21:10:36 +03:00
|
|
|
if physical.is_empty(): physical = world.ledger.physical_amounts(target)
|
2026-10-05 22:16:59 +03:00
|
|
|
for id in rules:
|
|
|
|
|
if not rules[id].worships: continue
|
2026-10-06 23:02:42 +03:00
|
|
|
var pop: Dictionary = State.normalize_profile(target.ethics.get(id, {}))
|
2026-10-05 22:16:59 +03:00
|
|
|
var coefficients: Dictionary = {}
|
|
|
|
|
for ethic in pop: coefficients[ethic] = rules[id].ethics[ethic].worship
|
|
|
|
|
var cached: Dictionary = world.ledger.worship_products.get(id, {})
|
2026-10-06 23:02:42 +03:00
|
|
|
var count: Variant = physical.get(id, 0)
|
|
|
|
|
if cached.is_empty() or not E.eq(cached.population, pop) or not E.eq(cached.coefficients, coefficients) or not E.eq(cached.count, count):
|
|
|
|
|
var worship_rate: float = 0.0
|
|
|
|
|
for ethic in pop: worship_rate += (0.0 + pop[ethic]) * E.approx(E.of(coefficients[ethic]))
|
|
|
|
|
cached = {"population": pop.duplicate(), "coefficients": coefficients, "count": count, "product": E.multiply(count, worship_rate)}
|
2026-10-05 22:16:59 +03:00
|
|
|
world.ledger.worship_products[id] = cached
|
2026-10-06 23:02:42 +03:00
|
|
|
result = E.add(result, cached.product)
|
2026-10-05 22:16:59 +03:00
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
static func coefficients(world, rules: Dictionary, id: String, modifiers: Dictionary) -> Dictionary:
|
|
|
|
|
if not E.eq(world.ledger.civilization_modifiers, modifiers):
|
|
|
|
|
world.ledger.civilization_modifiers = modifiers.duplicate()
|
|
|
|
|
world.ledger.civilization_coefficients.clear()
|
|
|
|
|
var cached: Dictionary = world.ledger.civilization_coefficients.get(id, {})
|
|
|
|
|
var signature: String = ""
|
|
|
|
|
for ethic in ETHICS:
|
|
|
|
|
var row: Dictionary = rules[id].ethics[ethic]
|
|
|
|
|
signature += ethic + ":" + str(row.progress) + "," + str(row.degradation) + "," + str(row.war) + "," + str(row.colonization) + ";"
|
|
|
|
|
if not cached.is_empty() and cached.signature == signature: return cached.rates
|
|
|
|
|
var rates: Dictionary = {}
|
|
|
|
|
for ethic in rules[id].ethics:
|
|
|
|
|
var row: Dictionary = rules[id].ethics[ethic]
|
2026-10-07 22:51:55 +03:00
|
|
|
var p: float = maxf(0.0, E.approx(E.of(row.progress)) * E.approx(modifiers.progress))
|
|
|
|
|
var d: float = maxf(0.0, E.approx(E.of(row.degradation)) * E.approx(modifiers.degradation))
|
|
|
|
|
var scale: float = maxf(1.0, p + d)
|
|
|
|
|
rates[ethic] = {"pro": p / scale, "deg": d / scale,
|
|
|
|
|
"war": clampf(E.approx(E.of(row.war)) * E.approx(modifiers.war), 0.0, 1.0),
|
|
|
|
|
"col": clampf(E.approx(E.of(row.colonization)) * E.approx(modifiers.colonization), 0.0, 1.0)}
|
2026-10-05 22:16:59 +03:00
|
|
|
world.ledger.civilization_coefficients[id] = {"signature": signature, "rates": rates}
|
|
|
|
|
return rates
|