Files
owniverse/world/owniverse/item_description.gd
T
Kirill c4e7302567 Add new tests and implement frame budget management
- Introduced `civilization_benchmark.gd` and `legacy_quantity_math.gd` for benchmarking and legacy quantity calculations.
- Created `test_dynamic_math.gd`, `test_frame_evolution.gd`, and `test_sparse_batches.gd` to validate mathematical operations and frame evolution logic.
- Implemented `frame_budget.gd` to manage cooperative work on the main thread, ensuring no partially calculated state is published.
- Added UID files for all new scripts to maintain unique identifiers.
2026-10-01 23:43:34 +03:00

91 lines
5.5 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
extends RefCounted
const E = preload("res://world/owniverse/math/exact.gd")
const GREEN = "#40cc40"
const RED = "#ff6060"
const GREY = "#888888"
const Parameters = preload("res://world/owniverse/world_parameters.gd")
static func number(value, digits: int = 0) -> String:
if not E.finite(value): return "—"
return E.grouped(value, digits, false)
static func colored(text: String, color: String) -> String:
return E.add(E.add(E.add(E.add("[color=", color), "]"), text), "[/color]")
static func matches(world, id: String) -> Array:
var result: Array = []
for key in world.catalog.entities:
var entity = world.catalog.entities[key]
if ((E.eq(key, id) or E.eq(entity.count_as, id)) or E.eq(entity.group_as, id)):
if (not world.catalog.is_group(key)):
result.append(key)
return result
static func quantities(world, id: String) -> Dictionary:
var free: Variant = 0
var total: Variant = 0
var physical: Dictionary = world.ledger.physical_amounts(world.state)
for key in matches(world, id):
free = E.add(free, world.state.amount.get(key, 0))
total = E.add(total, physical.get(key, 0))
if E.eq(id, "SMBH"):
free = world.state.amount.get(id, 0)
total = free
return {"free": free, "total": total}
static func costs(world, global: Node, id: String) -> String:
if (not world.catalog.entities.has(id)):
return ""
var lines: PackedStringArray = []
for requirements in [world.catalog.entities[id].cost, world.catalog.entities[id].bind]:
for resource in requirements:
var required: Variant = requirements[resource]
if E.lt(required, 0):
continue
var available: Variant = E.floor_value(world.ledger.available(world.state, resource))
var name: String = str(global.get_template(resource, "Entity", "Name").get("text", resource))
lines.append(colored(E.add(E.add(E.add(E.add(E.add(name, ": "), number(required)), " ("), number(available)), ")"), (GREEN if E.ge(available, required) else RED)))
return "\n".join(lines)
static func variables(world, global: Node, id: String, rate: Variant = 0.0) -> Dictionary:
var counts: Dictionary = quantities(world, id)
var show_total: bool = false
for key in matches(world, id):
show_total = (show_total or E.eq(world.catalog.entities[key].group_as, "Planet"))
var amount: String = (number((counts.total if show_total else counts.free)) if world.catalog.entities.has(id) else "—")
if ((not show_total) and E.gt(counts.total, counts.free)):
amount = E.add(amount, E.add(" ", colored(E.add(E.add("(", number(counts.total)), ")"), GREY)))
if E.ne(rate, 0):
amount = E.add(amount, E.add(" | ", colored(E.add((("−" if E.lt(rate, 0) else "+")), number(E.absolute(rate), 1)), (RED if E.lt(rate, 0) else GREEN))))
var physical: Dictionary = world.ledger.physical_amounts(world.state)
var voids: Variant = 0
for key in physical:
voids = E.add(voids, E.multiply(physical[key], world.catalog.entities[key].voids))
var he: Variant = world.state.amount.get("He", 0)
var h: Variant = world.state.amount.get("H", 0)
var mixture: String = "—"
if E.gt(E.add(he, h), 0):
mixture = E.add(E.add(E.add(E.add("He: ", number(E.mul_div(100, he, (E.add(he, h))), 2)), "% / H: "), number(E.mul_div(100, h, (E.add(he, h))), 2)), "%")
var environment: Dictionary = world.environment.stellar_environment(world.state)
return {"amount": amount, "colored costs": costs(world, global, id), "lifespan": (number(world.catalog.entities[id].lifespan) if world.catalog.entities.has(id) else "—"), "voids": number(voids), "he / h": E.add("\n", mixture), "metallicity": E.add(number(E.multiply(environment.metallicity, 100), 2), "%"), "энергия": number(world.state.energy), "плотность": number(environment.density, 6), "лет в секунду": number(world.state.speed_in_year), "amount1": "—", "amount2": "—", "amount3": "—", "amount4": "—"}
static func render(world, global: Node, id: String, category: String = "Entity", rate: Variant = 0.0) -> String:
var values: Dictionary = variables(world, global, id, rate)
if E.eq(category, "Indicator"):
if E.eq(id, "Density"):
id = Parameters.density_display(world.environment.stellar_environment(world.state).density).mode
var scales: Dictionary = {"Burnability": "Bur", "Explosiveness": "Exp", "Aggression": "Agg"}
if scales.has(id):
var level: Variant = Parameters.value(world.state, scales[id])
values.amount = number(level, (1 if E.ne(level, E.floor_value(level)) else 0))
values.scale = global.render_template(global.get_template(E.add("Scale", str(clampi(E.integer(E.round_value(level)), 1, 19))), "Indicator", "Scale"), {})
if E.eq(id, "Trends"):
for trend in Parameters.TRENDS:
values[trend.to_lower()] = E.add(number(E.multiply(world.state.get("trends", {}).get(trend, 0), 100), 2), "%")
if E.eq(id, "Energy"):
values["энергия"] = E.add(E.add(E.add(number(world.state.energy), " ("), number(E.multiply(E.clamp_value(E.divide(world.state.energy, Parameters.INITIAL_ENERGY), 0, 1), 100), 2)), "%)")
var title: String = global.render_template(global.get_template(id, category, "Name"), values)
var body: String = global.render_template(global.get_template(id, category, "Description"), values)
return E.add(E.add(E.add("[b]", ((title if E.ne(title, "") else id))), "[/b]\n"), body)