diff --git a/data/owniverse_template_loader.gd b/data/owniverse_template_loader.gd index 85b1908..affd3ca 100644 --- a/data/owniverse_template_loader.gd +++ b/data/owniverse_template_loader.gd @@ -1008,7 +1008,7 @@ Trends.Report.Header|[b]Влияние развитых цивилизаций Int.Fed.Report.Max|[Интеграция] Федерация: [color=#cccc88]+%value0%[/color]. Увеличено число цивилизаций, подверженных воздействию дипломатии.|max|||| Int.Enl.Report.Max|[Интеграция] Просвещение: [color=#cccc88]+%value0%[/color]. Ускорен прогресс на примитивных стадиях жизни.|max|||| Int.Ord.Report.Max|[Интеграция] Новый порядок: [color=#cccc88]+%value0%[/color]. Оказывается помощь и поддержка цивилизациям, попавшим в кризисные обстоятельства.|max|||| -Emerged.Report.Header|[b]Максимальное число возникших сущностей[/b]||||| +Emerged.Report.Header|[b]Всего возникло сущностей[/b]||||| Ctm.Report.Max|Трансцендентная цивилизация мистиков: [color=#cccc88]%value0%[/color]|max|||| Ctb.Report.Max|Трансцендентная цивилизация строителей: [color=#cccc88]%value0%[/color]|max|||| Ctd.Report.Max|Трансцендентная цивилизация дипломатов: [color=#cccc88]%value0%[/color]|max|||| @@ -1075,7 +1075,7 @@ HP.Report.Max|Обитаемая планета: [color=#cccc88]%value0%[/color] RP.Report.Max|Каменистая планета: [color=#cccc88]%value0%[/color]|max|||| AB.Report.Max|Астероиды: [color=#cccc88]%value0%[/color]|max|||| GG.Report.Max|Газовый гигант: [color=#cccc88]%value0%[/color]|max|||| -Produced.Report.Header|[b]Максимальное число созданных объектов[/b]||||| +Produced.Report.Header|[b]Всего создано объектов[/b]||||| LUB.Report.Max|Вселенский пузырь: [color=#cccc88]%value0%[/color]|max|||| LGW.Report.Max|Великая стена: [color=#cccc88]%value0%[/color]|max|||| LGF.Report.Max|Галактическая нить: [color=#cccc88]%value0%[/color]|max|||| @@ -1116,7 +1116,7 @@ YD.Report.Max|Жёлтый карлик: [color=#cccc88]%value0%[/color]|max|||| OD.Report.Max|Оранжевый карлик: [color=#cccc88]%value0%[/color]|max|||| RD.Report.Max|Красный карлик: [color=#cccc88]%value0%[/color]|max|||| BD.Report.Max|Бурый карлик: [color=#cccc88]%value0%[/color]|max|||| -Obtained.Report.Header|[b]Максимум за время существования вселенной[/b]||||| +Obtained.Report.Header|[b]Всего получено ресурсов[/b]||||| S.Report.Max|Пространство: [color=#cccc88]%value0%[/color]|max|||| H.Report.Max|Водород: [color=#cccc88]%value0%[/color]|max|||| He.Report.Max|Гелий: [color=#cccc88]%value0%[/color]|max|||| @@ -2199,7 +2199,7 @@ Trends.Header|[b]Influence of advanced civilizations on the universe[/b]||||| Int.Fed.Max|[Integration] Federation: [color=#cccc88]+%value0%[/color]. The number of civilizations affected by diplomacy is increased.|max|||| Int.Enl.Max|[Integration] Enlightenment: [color=#cccc88]+%value0%[/color]. The progress during primitive stages of life development is accelerated.|max|||| Int.Ord.Max|[Integration] New Order: [color=#cccc88]+%value0%[/color]. Civilizations in crisis obtain aid and support.|max|||| -Emerged.Header|[b]Maximum amount of emerged entities[/b]||||| +Emerged.Header|[b]Total entities emerged[/b]||||| Ctm.Max|Transcendent mystics civilization: [color=#cccc88]%value0%[/color]|max|||| Ctb.Max|Transcendent builders civilization: [color=#cccc88]%value0%[/color]|max|||| Ctd.Max|Transcendent diplomats civilization: [color=#cccc88]%value0%[/color]|max|||| @@ -2266,7 +2266,7 @@ HP.Max|Habitable Planet: [color=#cccc88]%value0%[/color]|max|||| RP.Max|Rocky Planet: [color=#cccc88]%value0%[/color]|max|||| AB.Max|Asteroids: [color=#cccc88]%value0%[/color]|max|||| GG.Max|Gas Giant: [color=#cccc88]%value0%[/color]|max|||| -Produced.Header|[b]Maximum amount of created objects[/b]||||| +Produced.Header|[b]Total objects created[/b]||||| LUB.Max|Universe Bubble: [color=#cccc88]%value0%[/color]|max|||| LGW.Max|Great Wall: [color=#cccc88]%value0%[/color]|max|||| LGF.Max|Galactic Filament: [color=#cccc88]%value0%[/color]|max|||| @@ -2307,7 +2307,7 @@ YD.Max|Yellow Dwarf: [color=#cccc88]%value0%[/color]|max|||| OD.Max|Orange Dwarf: [color=#cccc88]%value0%[/color]|max|||| RD.Max|Red Dwarf: [color=#cccc88]%value0%[/color]|max|||| BD.Max|Brown Dwarf: [color=#cccc88]%value0%[/color]|max|||| -Obtained.Header|[b]Maximum for all the existence of the universe[/b]||||| +Obtained.Header|[b]Total resources obtained[/b]||||| S.Max|Space: [color=#cccc88]%value0%[/color]|max|||| H.Max|Hydrogen: [color=#cccc88]%value0%[/color]|max|||| He.Max|Helium: [color=#cccc88]%value0%[/color]|max|||| diff --git a/export_presets.cfg b/export_presets.cfg index 4aee7fe..e50b46c 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -12,7 +12,7 @@ custom_features="" export_filter="all_resources" include_filter="" exclude_filter="" -export_path="../../../Documents/Owad/Owniverse.I/Builds/owniverse.0.7.0-146.console.exe" +export_path="../../../Documents/Owad/Owniverse.I/Builds/owniverse.0.7.0-146.exe" patches=PackedStringArray() patch_delta_encoding=false patch_delta_compression_level_zstd=19 diff --git a/simulation_rules.md b/simulation_rules.md index 1031dcb..24c877b 100644 --- a/simulation_rules.md +++ b/simulation_rules.md @@ -278,3 +278,17 @@ H списывает только оставшуюся после замещен открытие и получение, отсутствие повторных уведомлений, паузу в меню, возврат индикаторов, сохранение прогресса и локализацию. Файл прогресса теста создаётся отдельно в `/tmp`. + + +## Отчёт о вселенной + +`ui/report/report.gd` форматирует готовое состояние при открытии +экрана отчёта и смене языка. Результат хранится в `Report/ReportBody`. +Периодического пересчёта отчёта и новых счётчиков симуляции нет. +Доли восьми типов звёзд учитывают звёзды в структурах. Строки количеств +используют накопленные `stats.total_amount` с существующими алиасами; +заголовки обозначают суммарное получение, а не исторические максимумы. +Эффекты интеграции показывают прирост готовых параметров Federation, +Enlightenment и Order относительно начального значения 1. +Нулевые строки и пустые разделы скрыты. Количества выводятся полностью, +с пробелами между группами по три цифры. Тексты и заголовок поддерживают RU/EN. diff --git a/tests/test_universe_report.gd b/tests/test_universe_report.gd new file mode 100644 index 0000000..ee5bace --- /dev/null +++ b/tests/test_universe_report.gd @@ -0,0 +1,36 @@ +extends SceneTree +const E = preload("res://world/owniverse/math/exact.gd") +const Report = preload("res://ui/report/report.gd") +class Ledger extends RefCounted: + func physical_amounts(_source: Dictionary) -> Dictionary: + return {"RD": 3, "HG": 1} +class Catalog extends RefCounted: + var entities: Dictionary = {} + func is_group(_id: String) -> bool: return false +class World extends RefCounted: + var catalog = Catalog.new() + var ledger = Ledger.new() + var state = {"amount": {}, "stats": {"total_amount": {"H": 1234}}, "world_parameters": {"Federation": 1, "Enlightenment": 1, "Order": 1}} +func _initialize() -> void: + call_deferred("run") +func run() -> void: + var global: Node = root.get_node("Global") + var world = World.new() + world.state.stats.total_amount.H = E.of("1234567890123456789012345") + var before: Dictionary = E.encode(world.state) + global.Locale = "en" + var text: String = Report.build(world, global) + assert(text.contains("75.00%") and text.contains("25.00%"), text) + assert(text.contains("1 234 567 890 123 456 789 012 345"), text) + assert(text.contains("Total resources obtained") and not text.contains("Total entities emerged"), text) + world.state.world_parameters.Federation = E.of("1.3") + text = Report.build(world, global) + assert(text.contains("Federation:") and text.contains("0.30"), text) + world.state.world_parameters.Federation = 1 + global.Locale = "ru" + text = Report.build(world, global) + assert(text.contains("Всего получено ресурсов") and text.contains("Красные карлики"), text) + assert(E.encode(world.state) == before, "Report mutated simulation") + assert(load("res://stage/stage.gd") != null) + print("Universe report checks: PASS") + quit() diff --git a/tests/test_universe_report.gd.uid b/tests/test_universe_report.gd.uid new file mode 100644 index 0000000..cc2457a --- /dev/null +++ b/tests/test_universe_report.gd.uid @@ -0,0 +1 @@ +uid://brb04x12elvqt diff --git a/ui/report/en/report.png b/ui/report/en/report.png index 6f30ec3..4c89835 100644 --- a/ui/report/en/report.png +++ b/ui/report/en/report.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1701b2a116c39ebf09e3f0f55cc8951fc21448900b2adf4e21ea0ea9cdd973b7 -size 17790 +oid sha256:701e6e508e597fd9561794d053f80c0eab2392d2782fa76a84b7423c87397579 +size 22473 diff --git a/ui/report/en/wipe_nutton.png b/ui/report/en/wipe_button.png similarity index 100% rename from ui/report/en/wipe_nutton.png rename to ui/report/en/wipe_button.png diff --git a/ui/report/report.gd b/ui/report/report.gd new file mode 100644 index 0000000..a86f4fd --- /dev/null +++ b/ui/report/report.gd @@ -0,0 +1,63 @@ +extends VBoxContainer +const E = preload("res://world/owniverse/math/exact.gd") +const Presentation = preload("res://world/owniverse/item_presentation.gd") +const STARS = ["RD", "OD", "YD", "WYD", "WS", "BG", "SG", "HG"] +const EFFECTS = {"Int.Fed": "Federation", "Int.Enl": "Enlightenment", "Int.Ord": "Order"} + +var report_locale: String = "" + +@onready var report_body: RichTextLabel = $ReportBody +@onready var report_header: TextureRect = $Header/Header + +func _ready() -> void: + visibility_changed.connect(_on_visibility_changed) + +func _process(_delta: float) -> void: + if is_visible_in_tree() and report_locale != get_node("/root/Global").Locale: + refresh() + +func _on_visibility_changed() -> void: + if is_node_ready() and is_visible_in_tree(): + refresh() + report_body.scroll_to_line(0) + +func refresh() -> void: + var global: Node = get_node("/root/Global") + report_locale = global.Locale + report_body.text = build(get_parent().owniverse, global) + report_header.texture = load("res://ui/report/" + report_locale + "/report.png") + +## Formats existing committed state only. No historical counters or simulation work. +static func build(world, global: Node) -> String: + var source: Dictionary = world.state + var totals: Dictionary = Presentation.amounts(source, world.catalog, true) + var physical: Dictionary = world.ledger.physical_amounts(source) + var star_total: Variant = 0 + for id in STARS: star_total = E.add(star_total, physical.get(id, 0)) + var blocks: PackedStringArray = [] + var lines: PackedStringArray = [] + var header: String = "" + # Russian keys provide the common order; get_template resolves both key formats. + for key in global.Templates.ru: + if not str(key).contains(".Report."): continue + var parts: PackedStringArray = str(key).rsplit(".Report.", true, 1) + var id: String = parts[0] + var kind: String = parts[1] + var row: Dictionary = global.get_template(id, "Report", kind) + if kind == "Header": + if not lines.is_empty(): blocks.append(header + "\n\n" + "\n".join(lines)) + lines.clear() + header = global.render_template(row, {}) + elif kind == "Fraction": + var amount: Variant = physical.get(id, 0) + if E.gt(amount, 0) and E.gt(star_total, 0): + var percent: String = E.grouped(E.mul_div(amount, 100, star_total), 2, false) + "%" + lines.append(global.render_template(row, {"proportion": percent})) + elif kind == "Max": + var amount: Variant = totals.get(id, 0) + if EFFECTS.has(id): + amount = E.subtract(source.world_parameters.get(EFFECTS[id], 1), 1) + if E.gt(amount, 0): + lines.append(global.render_template(row, {"max": E.grouped(amount, 2 if EFFECTS.has(id) else 0, false)})) + if not lines.is_empty(): blocks.append(header + "\n\n" + "\n".join(lines)) + return "\n\n".join(blocks) diff --git a/ui/report/report.gd.uid b/ui/report/report.gd.uid new file mode 100644 index 0000000..65ce923 --- /dev/null +++ b/ui/report/report.gd.uid @@ -0,0 +1 @@ +uid://v8h4ov33opyf diff --git a/ui/report/ru/report.png b/ui/report/ru/report.png index 6f35dbf..1cb4698 100644 --- a/ui/report/ru/report.png +++ b/ui/report/ru/report.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8d59ea0b6485f0e12c020ae7042b7b563353c436dcb88be1213ec4b64f5b0051 -size 23760 +oid sha256:d62b32bb87836f4f98d64e748724e259658ecce8a7b504fa59a653fb7f973e06 +size 30567 diff --git a/world/world.tscn b/world/world.tscn index ced124b..76ad8e2 100644 --- a/world/world.tscn +++ b/world/world.tscn @@ -71,6 +71,8 @@ [ext_resource type="Script" uid="uid://btsrt6rw3nr04" path="res://ui/audio/owniverse_music_player.gd" id="67_music"] [ext_resource type="Script" uid="uid://botb0k4qr0hqo" path="res://ui/audio/owniverse_effects_player.gd" id="68_effects"] +[ext_resource type="Script" path="res://ui/report/report.gd" id="69_report"] + [sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ifjjt"] [sub_resource type="ButtonGroup" id="ButtonGroup_58wjt"] @@ -1012,7 +1014,8 @@ layout_mode = 2 texture_normal = ExtResource("52_uvuuk") [node name="Report" type="VBoxContainer" parent="Stage" unique_id=1422399839] -visible = false +script = ExtResource("69_report") +custom_minimum_size = Vector2(1080, 1920) layout_mode = 0 offset_right = 40.0 offset_bottom = 40.0 @@ -1033,11 +1036,19 @@ custom_minimum_size = Vector2(1080, 0) layout_mode = 2 [node name="Header" type="TextureRect" parent="Stage/Report/Header" unique_id=1321780840] -custom_minimum_size = Vector2(824, 256) layout_mode = 2 texture = ExtResource("60_an6vj") +[node name="ReportBody" type="RichTextLabel" parent="Stage/Report" unique_id=1952288631] +layout_mode = 2 +size_flags_vertical = 3 +bbcode_enabled = true +scroll_active = true +theme_override_font_sizes/normal_font_size = 30 +theme_override_font_sizes/bold_font_size = 30 + [node name="Achievements" type="VBoxContainer" parent="Stage" unique_id=1847732432] +visible = false custom_minimum_size = Vector2(1080, 1920) layout_mode = 0 offset_right = 40.0