Add item description and testing framework for Owniverse
- Introduced `item_description.gd` to handle item descriptions with localization support. - Implemented a testing script `test_descriptions.gd` to validate item description rendering and localization. - Added a new template file for Russian localization. - Included a large package file `owniverse.0.6.29-145.pck` for game assets. - Ensured proper memory management in tests with fixture and dispose functions.
This commit is contained in:
+24
-7
@@ -29,14 +29,30 @@ func get_localized_item_description(item_id: String, item: String) -> String:
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
# Russian templates include the class; legacy English keys omit it.
|
||||||
|
func get_template(id: String, category: String, field: String) -> Dictionary:
|
||||||
|
var rows: Dictionary = Templates.get(Locale, {})
|
||||||
|
for key in [id + "." + category + "." + field, id + "." + field]:
|
||||||
|
if rows.has(key):
|
||||||
|
return rows[key]
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
func render_template(row: Dictionary, variables: Dictionary) -> String:
|
||||||
|
var result: String = str(row.get("text", ""))
|
||||||
|
for i in range(5):
|
||||||
|
var variable: String = str(row.get("value" + str(i), "")).strip_edges()
|
||||||
|
var value: String = str(variables.get(variable, "—")) if variable != "" else ""
|
||||||
|
result = result.replace("%value" + str(i) + "%", value)
|
||||||
|
return result.replace("<br>", "\n").replace("[p]", "\n")
|
||||||
|
|
||||||
|
|
||||||
func get_description(item_id: String, items: Array = []) -> String:
|
func get_description(item_id: String, items: Array = []) -> String:
|
||||||
if !Templates[Locale].has(item_id):
|
var row: Dictionary = Templates.get(Locale, {}).get(item_id, {})
|
||||||
return ""
|
var variables: Dictionary = {}
|
||||||
var description: String = Templates[Locale][item_id]["text"]
|
for i in mini(items.size(), 5):
|
||||||
var value = 0
|
variables[str(row.get("value" + str(i), ""))] = items[i]
|
||||||
for item in items:
|
return render_template(row, variables)
|
||||||
description.replace("value" + str(value), str(item))
|
|
||||||
return description
|
|
||||||
|
|
||||||
|
|
||||||
func format_number(value: float, digits: int = 0) -> String:
|
func format_number(value: float, digits: int = 0) -> String:
|
||||||
@@ -58,6 +74,7 @@ func _ready() -> void:
|
|||||||
Locales["ru"] = _read_from_csv("res://data/locale.ru.txt")
|
Locales["ru"] = _read_from_csv("res://data/locale.ru.txt")
|
||||||
|
|
||||||
Templates["en"] = _read_from_csv("res://data/templates.en.txt")
|
Templates["en"] = _read_from_csv("res://data/templates.en.txt")
|
||||||
|
Templates["ru"] = _read_from_csv("res://data/templates.ru.txt")
|
||||||
|
|
||||||
|
|
||||||
func _read_from_csv(file_path: String) -> Dictionary:
|
func _read_from_csv(file_path: String) -> Dictionary:
|
||||||
|
|||||||
@@ -725,7 +725,7 @@ Aggression.Description|Evolution and competition.[p]%value0%: %value1%|scale|amo
|
|||||||
Trends.Description|Actions of advanced civilizations.[p]Antitheism: %value0%[p]Integration: %value1%[p]Xenocide: %value2%[p]Reconstruction: %value3%[p]Spirituality: %value4%[p]|antitheism|integration|xenocide|reconstruction|spirituality
|
Trends.Description|Actions of advanced civilizations.[p]Antitheism: %value0%[p]Integration: %value1%[p]Xenocide: %value2%[p]Reconstruction: %value3%[p]Spirituality: %value4%[p]|antitheism|integration|xenocide|reconstruction|spirituality
|
||||||
S.Description|%value0%[p]Voids: %value1%[p]Needed for placing objects.|amount|voids|||
|
S.Description|%value0%[p]Voids: %value1%[p]Needed for placing objects.|amount|voids|||
|
||||||
H.Description|%value0%[p]Used to create clouds and stars.|amount||||
|
H.Description|%value0%[p]Used to create clouds and stars.|amount||||
|
||||||
He.Description|%value0%[p]Saves hydrogen.%value1%|amount he / h||||
|
He.Description|%value0%[p]Saves hydrogen.%value1%|amount|he / h|||
|
||||||
Met.Description|%value0%[p]Needed to create planets.[p]Metallicity: %value1%|amount|metallicity|||
|
Met.Description|%value0%[p]Needed to create planets.[p]Metallicity: %value1%|amount|metallicity|||
|
||||||
N.Description|%value0%[p]Produces hydrogen.[p]%value2%[p]Baseline lifespan: %value3%|amount||colored costs|lifespan|
|
N.Description|%value0%[p]Produces hydrogen.[p]%value2%[p]Baseline lifespan: %value3%|amount||colored costs|lifespan|
|
||||||
G.Description|%value0%[p]Produces more hydrogen.[p]%value2%[p]Baseline lifespan: %value3%|amount||colored costs|lifespan|
|
G.Description|%value0%[p]Produces more hydrogen.[p]%value2%[p]Baseline lifespan: %value3%|amount||colored costs|lifespan|
|
||||||
@@ -1183,4 +1183,4 @@ Type1Civilizations.Path|GameHelp/en/Type1Civilizations|||||
|
|||||||
Type2Civilizations.Path|GameHelp/en/Type2Civilizations|||||
|
Type2Civilizations.Path|GameHelp/en/Type2Civilizations|||||
|
||||||
Type3Civilizations.Path|GameHelp/en/Type3Civilizations|||||
|
Type3Civilizations.Path|GameHelp/en/Type3Civilizations|||||
|
||||||
Type4Civilizations.Path|GameHelp/en/Type4Civilizations|||||
|
Type4Civilizations.Path|GameHelp/en/Type4Civilizations|||||
|
||||||
ButtonAbout.Image|Path/To/en/ButtonAbout.webp|||||
|
ButtonAbout.Image|Path/To/en/ButtonAbout.webp|||||
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="skip"
|
||||||
+2
-2
@@ -11,7 +11,7 @@ custom_features=""
|
|||||||
export_filter="all_resources"
|
export_filter="all_resources"
|
||||||
include_filter=""
|
include_filter=""
|
||||||
exclude_filter=""
|
exclude_filter=""
|
||||||
export_path="../../Documents/Owad/Owniverse.I/Builds/owniverse.0.6.28-144.exe"
|
export_path="../../../Documents/Owad/Owniverse.I/Builds/owniverse.0.6.29-145.console.exe"
|
||||||
patches=PackedStringArray()
|
patches=PackedStringArray()
|
||||||
patch_delta_encoding=false
|
patch_delta_encoding=false
|
||||||
patch_delta_compression_level_zstd=19
|
patch_delta_compression_level_zstd=19
|
||||||
@@ -112,7 +112,7 @@ architectures/armeabi-v7a=false
|
|||||||
architectures/arm64-v8a=true
|
architectures/arm64-v8a=true
|
||||||
architectures/x86=false
|
architectures/x86=false
|
||||||
architectures/x86_64=false
|
architectures/x86_64=false
|
||||||
version/code=144
|
version/code=145
|
||||||
version/name=""
|
version/name=""
|
||||||
package/unique_name="com.KIDGameProduction.Owniverse"
|
package/unique_name="com.KIDGameProduction.Owniverse"
|
||||||
package/name="Owniverse"
|
package/name="Owniverse"
|
||||||
|
|||||||
Binary file not shown.
+1
-1
@@ -15,7 +15,7 @@ general/updates_per_second=10
|
|||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="Owniverse"
|
config/name="Owniverse"
|
||||||
config/version="0.6.28"
|
config/version="0.6.29"
|
||||||
run/main_scene="uid://bv384dpmvjv8o"
|
run/main_scene="uid://bv384dpmvjv8o"
|
||||||
config/features=PackedStringArray("4.7", "Mobile")
|
config/features=PackedStringArray("4.7", "Mobile")
|
||||||
boot_splash/show_image=false
|
boot_splash/show_image=false
|
||||||
|
|||||||
+38
-11
@@ -4,6 +4,12 @@ const OWNIVERSE_ITEM = preload("uid://d3xjfxwe3w16v")
|
|||||||
|
|
||||||
const SPEED_TEXTURE_NAME_TEMPLATE = "res://ui/topmenu/time&speed/time%s.png"
|
const SPEED_TEXTURE_NAME_TEMPLATE = "res://ui/topmenu/time&speed/time%s.png"
|
||||||
|
|
||||||
|
const ItemDescription = preload("res://world/owniverse/item_description.gd")
|
||||||
|
var description_targets: Dictionary = {}
|
||||||
|
var description_samples: Dictionary = {}
|
||||||
|
var description_rates: Dictionary = {}
|
||||||
|
var description_elapsed: float = 0.0
|
||||||
|
|
||||||
const PAGE_COUNT = 5
|
const PAGE_COUNT = 5
|
||||||
const RESOURCE_PAGE = 1
|
const RESOURCE_PAGE = 1
|
||||||
const PAGE_WIDTH = 1080
|
const PAGE_WIDTH = 1080
|
||||||
@@ -123,20 +129,40 @@ func _on_indicator_pressed(indicator_name: String, page: int = 0):
|
|||||||
|
|
||||||
|
|
||||||
func _set_item_description(item: OwniverseItem) -> void:
|
func _set_item_description(item: OwniverseItem) -> void:
|
||||||
var description: String = "[b]" \
|
var category: String = "Entity" if owniverse.entities.has(item.item_id) else "Force"
|
||||||
+ Global.get_localized_item_description(item.item_name, "label") \
|
var id: String = item.item_id if category == "Entity" else item.item_name.capitalize()
|
||||||
+"[/b]" \
|
var page: int = clampi(item.item_page, 0, 4)
|
||||||
+"\n" \
|
if description_targets.get(page, {}).get("id", "") != id:
|
||||||
+ Global.get_localized_item_description(item.item_name, "description")
|
description_samples.erase(id)
|
||||||
var desc_page = clamp(item.item_page, 0, 4)
|
description_rates.erase(id)
|
||||||
g_item_descriptions[desc_page].text = description
|
description_targets[page] = {"id": id, "category": category}
|
||||||
|
_refresh_descriptions()
|
||||||
|
|
||||||
|
|
||||||
func _set_description(item_name: String, page: int) -> void:
|
func _set_description(item_name: String, page: int) -> void:
|
||||||
var description = Global.get_description(item_name + ".Name")
|
description_targets[page] = {"id": item_name, "category": "Indicator"}
|
||||||
description += "\n"
|
_refresh_descriptions()
|
||||||
description += Global.get_description(item_name + ".Description")
|
|
||||||
g_item_descriptions[page].text = description
|
|
||||||
|
func _refresh_descriptions() -> void:
|
||||||
|
for page in description_targets:
|
||||||
|
var target: Dictionary = description_targets[page]
|
||||||
|
var label: RichTextLabel = g_item_descriptions[page]
|
||||||
|
label.bbcode_enabled = true
|
||||||
|
label.text = ItemDescription.render(owniverse, Global, target.id, target.category, description_rates.get(target.id, 0.0))
|
||||||
|
|
||||||
|
|
||||||
|
func _update_descriptions(delta: float) -> void:
|
||||||
|
description_elapsed += delta
|
||||||
|
if description_elapsed < 0.25:
|
||||||
|
return
|
||||||
|
for page in description_targets:
|
||||||
|
var id: String = description_targets[page].id
|
||||||
|
var total: float = ItemDescription.quantities(owniverse, id).total
|
||||||
|
description_rates[id] = (total - description_samples[id]) / description_elapsed if description_samples.has(id) else 0.0
|
||||||
|
description_samples[id] = total
|
||||||
|
description_elapsed = 0.0
|
||||||
|
_refresh_descriptions()
|
||||||
|
|
||||||
|
|
||||||
func _control_page(item: OwniverseItem) -> void:
|
func _control_page(item: OwniverseItem) -> void:
|
||||||
@@ -299,6 +325,7 @@ func _ready() -> void:
|
|||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
|
|
||||||
owniverse.evolute(delta)
|
owniverse.evolute(delta)
|
||||||
|
_update_descriptions(delta)
|
||||||
set_owniverse_item_value()
|
set_owniverse_item_value()
|
||||||
set_datetime(owniverse.state.time.year)
|
set_datetime(owniverse.state.time.year)
|
||||||
|
|
||||||
|
|||||||
@@ -34,3 +34,15 @@ godot --headless --path Owniverse.GI --script res://tests/test_stellar_rules.gd
|
|||||||
Создание планет подключено к ручному и автоматическому производству звёзд. Бласты обрабатываются как события, а не ресурс. Выжившие планеты переходят преемнику звезды пропорционально числу реально полученных преемников; при отсутствии преемника освобождаются. Локальное разрушение выполняется перед передачей.
|
Создание планет подключено к ручному и автоматическому производству звёзд. Бласты обрабатываются как события, а не ресурс. Выжившие планеты переходят преемнику звезды пропорционально числу реально полученных преемников; при отсутствии преемника освобождаются. Локальное разрушение выполняется перед передачей.
|
||||||
|
|
||||||
Дополнительно проверяются частичная передача, альтернативные преемники, уровни разрушения 1/2, накопление слабых бластов, сохранения, ручное/автоматическое создание планет и несколько поколений за длинный шаг. Правила и формулы описаны в `../simulation_rules.md`.
|
Дополнительно проверяются частичная передача, альтернативные преемники, уровни разрушения 1/2, накопление слабых бластов, сохранения, ручное/автоматическое создание планет и несколько поколений за длинный шаг. Правила и формулы описаны в `../simulation_rules.md`.
|
||||||
|
|
||||||
|
## Описания выбранных объектов
|
||||||
|
|
||||||
|
```sh
|
||||||
|
godot --headless --path Owniverse.GI --script res://tests/test_descriptions.gd
|
||||||
|
```
|
||||||
|
|
||||||
|
Источник текста — `Global.Templates[Global.Locale]`. Заголовок берётся из `Name`, основной текст — из `Description`. Поддерживаются ключи с классом (`RD.Entity.Description`) и старые ключи без класса (`RD.Description`).
|
||||||
|
|
||||||
|
`%valueN%` заменяется значением переменной, имя которой записано в поле `valueN` этой строки. Поддерживаются `amount`, `colored costs`, `lifespan`, `voids`, `he / h`, `metallicity`, показатели энергии, плотности и скорости времени. `amount1`–`amount4` сил пока отображаются как `—`; неизвестные непустые обозначения тоже дают `—`, пустые поля — пустую строку. `[p]` превращается в разделение абзацев, цветовые BBCode-теги сохраняются.
|
||||||
|
|
||||||
|
Доступные требования зелёные, недоступные красные. Для объектов со связанными экземплярами выводится доступное количество и серым общее; для планет — общее количество. Скорость изменения вычисляется по реальному времени и обновляется раз в 0,25 секунды. Доли He/H вычисляются из текущих свободных запасов; при пустой смеси показывается `—`. Металличность и плотность используют расчёт среды GI. Счётчики исходной материи и этики Unity в текущей GI отсутствуют и здесь не добавляются.
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
extends SceneTree
|
||||||
|
const Clock = preload("res://world/owniverse/simulation_time.gd")
|
||||||
|
var checks: int = 0
|
||||||
|
var failures: int = 0
|
||||||
|
|
||||||
|
func _initialize() -> void:
|
||||||
|
call_deferred("run")
|
||||||
|
|
||||||
|
func check(condition: bool, message: String) -> void:
|
||||||
|
checks += 1
|
||||||
|
if not condition:
|
||||||
|
failures += 1
|
||||||
|
push_error(message)
|
||||||
|
|
||||||
|
func fixture():
|
||||||
|
var world = load("res://world/owniverse/owniverse.gd").new()
|
||||||
|
var global: Node = root.get_node("Global")
|
||||||
|
for id in global.OwniverseEntities:
|
||||||
|
var entity = load("res://world/owniverse/owniverse_entity.gd").new(global.OwniverseEntities[id])
|
||||||
|
world.entities[id] = entity
|
||||||
|
world.state.amount[id] = 0.0
|
||||||
|
world.state.stats.total_amount[id] = 0.0
|
||||||
|
if entity.group_as != "":
|
||||||
|
world.state.amount[entity.group_as] = 0.0
|
||||||
|
world.state.stats.total_amount[entity.group_as] = 0.0
|
||||||
|
world.entities["N"].life_product = {}
|
||||||
|
world.entities["N"].product_per_year_type = "H"
|
||||||
|
world.entities["N"].product_per_year_amount = 10.0
|
||||||
|
world.entities["N"].auto = 0.0
|
||||||
|
world.state.amount.N = 1.0
|
||||||
|
return world
|
||||||
|
|
||||||
|
func dispose(world) -> void:
|
||||||
|
for entity in world.entities.values():
|
||||||
|
entity.free()
|
||||||
|
world.free()
|
||||||
|
|
||||||
|
func run() -> void:
|
||||||
|
var global: Node = root.get_node("Global")
|
||||||
|
var description = load("res://world/owniverse/item_description.gd")
|
||||||
|
var world = fixture()
|
||||||
|
world.state.amount.H = 8.0
|
||||||
|
world.state.amount.He = 2.0
|
||||||
|
for locale in ["en", "ru"]:
|
||||||
|
global.Locale = locale
|
||||||
|
var text: String = description.render(world, global, "RD")
|
||||||
|
check(text.contains("[b]") and not text.contains("%value"), "Localized template resolved: " + locale)
|
||||||
|
check(text.contains("#40cc40"), "Affordable cost green: " + locale)
|
||||||
|
check(text.contains("4.0000E+10"), "Lifespan substituted: " + locale)
|
||||||
|
text = description.render(world, global, "He")
|
||||||
|
check(text.contains("He: 20.00% / H: 80.00%") and not text.contains("%value"), "Helium metadata and mixture: " + locale)
|
||||||
|
text = description.render(world, global, "Shovelin", "Force")
|
||||||
|
check(text.count("]—[/color]") == 4, "Missing force levels use dash: " + locale)
|
||||||
|
text = description.render(world, global, "YD")
|
||||||
|
check(text.contains("#ff6060"), "Insufficient cost red: " + locale)
|
||||||
|
var reordered: Dictionary = {"text": "%value0% / %value1%", "value0": "lifespan", "value1": "amount"}
|
||||||
|
check(global.render_template(reordered, {"amount": "12", "lifespan": "99"}) == "99 / 12", "Metadata chooses variables, not fixed argument positions")
|
||||||
|
world.state.amount.RD = 2.0
|
||||||
|
world.state.binds.G = {"RD": 3.0, "HP": 7.0}
|
||||||
|
var values: Dictionary = description.variables(world, global, "RD", -2.0)
|
||||||
|
check(values.amount.contains("2") and values.amount.contains("(5)") and values.amount.contains("#888888"), "Free and total counts with gray binding total")
|
||||||
|
check(values.amount.contains("#ff6060") and values.amount.contains("−2.0"), "Real-time decrease red")
|
||||||
|
values = description.variables(world, global, "HP")
|
||||||
|
check(values.amount == "7", "Planet description includes bound planets")
|
||||||
|
values = description.variables(world, global, "RD", 2.0)
|
||||||
|
check(values.amount.contains("#40cc40") and values.amount.contains("+2.0"), "Increase green")
|
||||||
|
var stage_script = load("res://stage/stage.gd")
|
||||||
|
check(stage_script.can_instantiate(), "Stage integration compiles")
|
||||||
|
var stage = stage_script.new()
|
||||||
|
stage.owniverse.free()
|
||||||
|
stage.owniverse = world
|
||||||
|
var label: RichTextLabel = RichTextLabel.new()
|
||||||
|
stage.g_item_descriptions = [label]
|
||||||
|
stage.description_targets[0] = {"id": "RD", "category": "Entity"}
|
||||||
|
stage._refresh_descriptions()
|
||||||
|
check(label.bbcode_enabled and label.text.contains("Красный карлик"), "Stage displays localized rich text")
|
||||||
|
stage._update_descriptions(0.25)
|
||||||
|
world.state.amount.RD += 1.0
|
||||||
|
stage._update_descriptions(0.25)
|
||||||
|
check(label.text.contains("+4.0"), "Selected description refreshes with rate per real second")
|
||||||
|
global.Locale = "en"
|
||||||
|
stage._update_descriptions(0.25)
|
||||||
|
check(label.text.contains("Red Dwarf"), "Selected description follows locale changes")
|
||||||
|
label.free()
|
||||||
|
stage.free()
|
||||||
|
dispose(world)
|
||||||
|
print("Descriptions: %d checks, %d failures" % [checks, failures])
|
||||||
|
quit(0 if failures == 0 else 1)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://b1efrwyimgle7
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
extends RefCounted
|
||||||
|
|
||||||
|
const GREEN = "#40cc40"
|
||||||
|
const RED = "#ff6060"
|
||||||
|
const GREY = "#888888"
|
||||||
|
|
||||||
|
static func number(value: float, digits: int = 0) -> String:
|
||||||
|
if not is_finite(value):
|
||||||
|
return "—"
|
||||||
|
if absf(value) >= 1e5:
|
||||||
|
var exponent: int = int(floor(log(absf(value)) / log(10.0)))
|
||||||
|
return "%.4fE%+d" % [value / pow(10.0, exponent), exponent]
|
||||||
|
return "%.*f" % [digits, value]
|
||||||
|
|
||||||
|
static func colored(text: String, color: String) -> String:
|
||||||
|
return "[color=" + color + "]" + text + "[/color]"
|
||||||
|
|
||||||
|
static func matches(world, id: String) -> Array:
|
||||||
|
var result: Array = []
|
||||||
|
for key in world.entities:
|
||||||
|
var entity = world.entities[key]
|
||||||
|
if key == id or entity.count_as == id or entity.group_as == id:
|
||||||
|
if not world._is_group(key):
|
||||||
|
result.append(key)
|
||||||
|
return result
|
||||||
|
|
||||||
|
static func quantities(world, id: String) -> Dictionary:
|
||||||
|
var free: float = 0.0
|
||||||
|
var total: float = 0.0
|
||||||
|
var physical: Dictionary = world._physical_amounts(world.state)
|
||||||
|
for key in matches(world, id):
|
||||||
|
free += world.state.amount.get(key, 0.0)
|
||||||
|
total += physical.get(key, 0.0)
|
||||||
|
if id == "SMBH":
|
||||||
|
free = world.state.amount.get(id, 0.0)
|
||||||
|
total = free
|
||||||
|
return {"free": free, "total": total}
|
||||||
|
|
||||||
|
static func costs(world, global: Node, id: String) -> String:
|
||||||
|
if not world.entities.has(id):
|
||||||
|
return ""
|
||||||
|
var lines: PackedStringArray = []
|
||||||
|
for requirements in [world.entities[id].cost, world.entities[id].bind]:
|
||||||
|
for resource in requirements:
|
||||||
|
var required: float = requirements[resource]
|
||||||
|
if required < 0.0:
|
||||||
|
continue
|
||||||
|
var available: float = floorf(world._available(world.state, resource))
|
||||||
|
var name: String = str(global.get_template(resource, "Entity", "Name").get("text", resource))
|
||||||
|
lines.append(colored(name + ": " + number(required) + " (" + number(available) + ")", GREEN if available >= required else RED))
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
static func variables(world, global: Node, id: String, rate: float = 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 world.entities[key].group_as == "Planet"
|
||||||
|
var amount: String = number(counts.total if show_total else counts.free) if world.entities.has(id) else "—"
|
||||||
|
if not show_total and counts.total > counts.free:
|
||||||
|
amount += " " + colored("(" + number(counts.total) + ")", GREY)
|
||||||
|
if rate != 0.0:
|
||||||
|
amount += " | " + colored(("−" if rate < 0.0 else "+") + number(absf(rate), 1), RED if rate < 0.0 else GREEN)
|
||||||
|
var physical: Dictionary = world._physical_amounts(world.state)
|
||||||
|
var voids: float = 0.0
|
||||||
|
for key in physical:
|
||||||
|
voids += physical[key] * world.entities[key].voids
|
||||||
|
var he: float = world.state.amount.get("He", 0.0)
|
||||||
|
var h: float = world.state.amount.get("H", 0.0)
|
||||||
|
var mixture: String = "—"
|
||||||
|
if he + h > 0.0:
|
||||||
|
mixture = "He: " + number(100.0 * he / (he + h), 2) + "% / H: " + number(100.0 * h / (he + h), 2) + "%"
|
||||||
|
var environment: Dictionary = world.stellar_environment(world.state)
|
||||||
|
return {
|
||||||
|
"amount": amount, "colored costs": costs(world, global, id),
|
||||||
|
"lifespan": number(world.entities[id].lifespan) if world.entities.has(id) else "—",
|
||||||
|
"voids": number(voids), "he / h": "\n" + mixture,
|
||||||
|
"metallicity": number(environment.metallicity * 100.0, 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: float = 0.0) -> String:
|
||||||
|
var values: Dictionary = variables(world, global, id, rate)
|
||||||
|
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 "[b]" + (title if title != "" else id) + "[/b]\n" + body
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dumnryq20c2ij
|
||||||
+25
-25
@@ -227,11 +227,11 @@ theme_override_fonts/normal_font = ExtResource("14_o7xkw")
|
|||||||
theme_override_fonts/bold_font = ExtResource("7_gwdna")
|
theme_override_fonts/bold_font = ExtResource("7_gwdna")
|
||||||
theme_override_fonts/bold_italics_font = ExtResource("15_bfrib")
|
theme_override_fonts/bold_italics_font = ExtResource("15_bfrib")
|
||||||
theme_override_fonts/italics_font = ExtResource("16_mip0j")
|
theme_override_fonts/italics_font = ExtResource("16_mip0j")
|
||||||
theme_override_font_sizes/normal_font_size = 42
|
theme_override_font_sizes/normal_font_size = 34
|
||||||
theme_override_font_sizes/bold_font_size = 54
|
theme_override_font_sizes/bold_font_size = 34
|
||||||
theme_override_font_sizes/bold_italics_font_size = 42
|
theme_override_font_sizes/bold_italics_font_size = 34
|
||||||
theme_override_font_sizes/italics_font_size = 42
|
theme_override_font_sizes/italics_font_size = 34
|
||||||
theme_override_font_sizes/mono_font_size = 42
|
theme_override_font_sizes/mono_font_size = 34
|
||||||
bbcode_enabled = true
|
bbcode_enabled = true
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
|
|
||||||
@@ -370,11 +370,11 @@ theme_override_fonts/normal_font = ExtResource("14_o7xkw")
|
|||||||
theme_override_fonts/bold_font = ExtResource("7_gwdna")
|
theme_override_fonts/bold_font = ExtResource("7_gwdna")
|
||||||
theme_override_fonts/bold_italics_font = ExtResource("15_bfrib")
|
theme_override_fonts/bold_italics_font = ExtResource("15_bfrib")
|
||||||
theme_override_fonts/italics_font = ExtResource("16_mip0j")
|
theme_override_fonts/italics_font = ExtResource("16_mip0j")
|
||||||
theme_override_font_sizes/normal_font_size = 42
|
theme_override_font_sizes/normal_font_size = 34
|
||||||
theme_override_font_sizes/bold_font_size = 54
|
theme_override_font_sizes/bold_font_size = 34
|
||||||
theme_override_font_sizes/bold_italics_font_size = 42
|
theme_override_font_sizes/bold_italics_font_size = 34
|
||||||
theme_override_font_sizes/italics_font_size = 42
|
theme_override_font_sizes/italics_font_size = 34
|
||||||
theme_override_font_sizes/mono_font_size = 42
|
theme_override_font_sizes/mono_font_size = 34
|
||||||
bbcode_enabled = true
|
bbcode_enabled = true
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
|
|
||||||
@@ -498,11 +498,11 @@ theme_override_fonts/normal_font = ExtResource("14_o7xkw")
|
|||||||
theme_override_fonts/bold_font = ExtResource("7_gwdna")
|
theme_override_fonts/bold_font = ExtResource("7_gwdna")
|
||||||
theme_override_fonts/bold_italics_font = ExtResource("15_bfrib")
|
theme_override_fonts/bold_italics_font = ExtResource("15_bfrib")
|
||||||
theme_override_fonts/italics_font = ExtResource("16_mip0j")
|
theme_override_fonts/italics_font = ExtResource("16_mip0j")
|
||||||
theme_override_font_sizes/normal_font_size = 42
|
theme_override_font_sizes/normal_font_size = 34
|
||||||
theme_override_font_sizes/bold_font_size = 54
|
theme_override_font_sizes/bold_font_size = 34
|
||||||
theme_override_font_sizes/bold_italics_font_size = 42
|
theme_override_font_sizes/bold_italics_font_size = 34
|
||||||
theme_override_font_sizes/italics_font_size = 42
|
theme_override_font_sizes/italics_font_size = 34
|
||||||
theme_override_font_sizes/mono_font_size = 42
|
theme_override_font_sizes/mono_font_size = 34
|
||||||
bbcode_enabled = true
|
bbcode_enabled = true
|
||||||
text = "Stars"
|
text = "Stars"
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
@@ -639,11 +639,11 @@ theme_override_fonts/normal_font = ExtResource("14_o7xkw")
|
|||||||
theme_override_fonts/bold_font = ExtResource("7_gwdna")
|
theme_override_fonts/bold_font = ExtResource("7_gwdna")
|
||||||
theme_override_fonts/bold_italics_font = ExtResource("15_bfrib")
|
theme_override_fonts/bold_italics_font = ExtResource("15_bfrib")
|
||||||
theme_override_fonts/italics_font = ExtResource("16_mip0j")
|
theme_override_fonts/italics_font = ExtResource("16_mip0j")
|
||||||
theme_override_font_sizes/normal_font_size = 42
|
theme_override_font_sizes/normal_font_size = 34
|
||||||
theme_override_font_sizes/bold_font_size = 54
|
theme_override_font_sizes/bold_font_size = 34
|
||||||
theme_override_font_sizes/bold_italics_font_size = 42
|
theme_override_font_sizes/bold_italics_font_size = 34
|
||||||
theme_override_font_sizes/italics_font_size = 42
|
theme_override_font_sizes/italics_font_size = 34
|
||||||
theme_override_font_sizes/mono_font_size = 42
|
theme_override_font_sizes/mono_font_size = 34
|
||||||
bbcode_enabled = true
|
bbcode_enabled = true
|
||||||
text = "Structures"
|
text = "Structures"
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
@@ -787,11 +787,11 @@ theme_override_fonts/normal_font = ExtResource("14_o7xkw")
|
|||||||
theme_override_fonts/bold_font = ExtResource("7_gwdna")
|
theme_override_fonts/bold_font = ExtResource("7_gwdna")
|
||||||
theme_override_fonts/bold_italics_font = ExtResource("15_bfrib")
|
theme_override_fonts/bold_italics_font = ExtResource("15_bfrib")
|
||||||
theme_override_fonts/italics_font = ExtResource("16_mip0j")
|
theme_override_fonts/italics_font = ExtResource("16_mip0j")
|
||||||
theme_override_font_sizes/normal_font_size = 42
|
theme_override_font_sizes/normal_font_size = 34
|
||||||
theme_override_font_sizes/bold_font_size = 54
|
theme_override_font_sizes/bold_font_size = 34
|
||||||
theme_override_font_sizes/bold_italics_font_size = 42
|
theme_override_font_sizes/bold_italics_font_size = 34
|
||||||
theme_override_font_sizes/italics_font_size = 42
|
theme_override_font_sizes/italics_font_size = 34
|
||||||
theme_override_font_sizes/mono_font_size = 42
|
theme_override_font_sizes/mono_font_size = 34
|
||||||
bbcode_enabled = true
|
bbcode_enabled = true
|
||||||
text = "Planets"
|
text = "Planets"
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
|
|||||||
Reference in New Issue
Block a user