Lift unlocking into first-class unlock groups defined in unlocks.toml, so one defence-station drop can grant a bundle of ships/modules/buildings/ recipes at once (e.g. the salvager module + salvage bay), and buildings can now be locked at game start and unlocked via a drop. Config: - New UnlocksConfig + ConfigLoader::loadUnlocks + validateUnlocks (unknown/ duplicate/non-assembler grants, unknown requires, empty group all fail load). - Drop unlock_at_station_level/unlock_requires from ship/module/recipe defs; add unlocked_at_start bool to recipes for graph-unreachable base recipes. Simulation: - Track awarded groups + per-building unlock state; an item starts unlocked iff no group grants it. Rework generateSchematicChoices/applySchematicChoice to operate on groups (grant all members at once). Extend state checksum. - isBuildingUnlocked query; tryPlaceBuilding rejects locked types. UI: - Build-menu buttons for locked buildings start hidden, revealed via a new UnlockedBuildingsChangedEvent (emitted from GameWorldView's poll loop). - Schematic choice dialog lists a group's granted items. - Blueprint placement excludes locked building types (REQ-LOCK-UI-BLUEPRINT). Data: unlocks.toml (app + test) reproduces the prior per-item gates as singleton groups and adds salvage_operations (salvager + salvage_bay, lvl 1) and reprocessing (reprocessing_plant, lvl 2). Tests: rewrote unlock/config/recipe-schematic/artifact/wave/shipyard tests for the group model; added UnlockGroupTest. All 443 cases pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7N59FsLA5e2kuVdqe4Uhc
120 lines
2.4 KiB
TOML
120 lines
2.4 KiB
TOML
[[module]]
|
|
id = "armor_plate"
|
|
tooltip = "Adds a large flat bonus to hit points."
|
|
surface_mask = ["OO"]
|
|
materials = [{item = "iron_ingot", amount = 2}]
|
|
production_time_seconds = 3
|
|
fill_color = "#808080"
|
|
glyph = "A"
|
|
|
|
[module.health]
|
|
multiplied_hp = 1.5
|
|
|
|
[[module]]
|
|
id = "sensor_booster"
|
|
surface_mask = ["O"]
|
|
materials = [{item = "circuit_board", amount = 1}]
|
|
production_time_seconds = 2
|
|
fill_color = "#40A0FF"
|
|
glyph = "S"
|
|
|
|
[module.sensor]
|
|
added_sensor_range_m = 100
|
|
|
|
[[module]]
|
|
id = "weapon_upgrade"
|
|
surface_mask = ["O"]
|
|
materials = [{item = "iron_ingot", amount = 1}, {item = "circuit_board", amount = 1}]
|
|
production_time_seconds = 4
|
|
fill_color = "#FF4040"
|
|
glyph = "W"
|
|
|
|
[module.weapon]
|
|
multiplied_damage = 1.2
|
|
|
|
[[module]]
|
|
id = "laser_cannon"
|
|
surface_mask = ["O"]
|
|
materials = [{item = "iron_ingot", amount = 1}]
|
|
production_time_seconds = 5
|
|
fill_color = "#FF8040"
|
|
glyph = "L"
|
|
|
|
[module.weapon]
|
|
damage = 2
|
|
attack_range_m = 50
|
|
attack_rate_hz = 2.0
|
|
|
|
[[module]]
|
|
id = "salvager"
|
|
surface_mask = ["OO"]
|
|
materials = [{item = "iron_ingot", amount = 2}]
|
|
production_time_seconds = 5
|
|
fill_color = "#AACC44"
|
|
glyph = "Sv"
|
|
|
|
[module.salvage]
|
|
collection_range_m = 500
|
|
cargo_capacity = 10
|
|
collection_rate_hz = 0.5
|
|
|
|
[[module]]
|
|
id = "repair_tool"
|
|
surface_mask = ["O"]
|
|
materials = [{item = "circuit_board", amount = 2}]
|
|
production_time_seconds = 5
|
|
fill_color = "#66CCFF"
|
|
glyph = "Rp"
|
|
|
|
[module.repair]
|
|
repair_rate_hz = 1
|
|
repair_amount_hp = 6
|
|
repair_range_m = 800
|
|
|
|
[[module]]
|
|
id = "weapon_primer"
|
|
surface_mask = ["O"]
|
|
materials = [{item = "iron_ingot", amount = 1}]
|
|
production_time_seconds = 4
|
|
fill_color = "#FF4040"
|
|
glyph = "Wp"
|
|
|
|
[module.weapon]
|
|
multiplied_attack_rate_hz = 1.2
|
|
|
|
[[module]]
|
|
id = "weapon_stabilizer"
|
|
surface_mask = ["O"]
|
|
materials = [{item = "iron_ingot", amount = 1}]
|
|
production_time_seconds = 4
|
|
fill_color = "#FF4040"
|
|
glyph = "Ws"
|
|
|
|
[module.weapon]
|
|
multiplied_attack_range_m = 1.5
|
|
multiplied_attack_rate_hz = 0.8
|
|
|
|
[[module]]
|
|
id = "afterburner"
|
|
surface_mask = ["O"]
|
|
materials = [{item = "iron_ingot", amount = 1}]
|
|
production_time_seconds = 2
|
|
fill_color = "#40A0FF"
|
|
glyph = "Ab"
|
|
|
|
[module.movement]
|
|
multiplied_speed_mps = 1.6
|
|
added_main_acceleration_mpss = 60
|
|
|
|
[[module]]
|
|
id = "maneuvering_thrusters"
|
|
surface_mask = ["O"]
|
|
materials = [{item = "iron_ingot", amount = 1}]
|
|
production_time_seconds = 2
|
|
fill_color = "#40A0FF"
|
|
glyph = "Mt"
|
|
|
|
[module.movement]
|
|
multiplied_speed_mps = 1.2
|
|
added_maneuvering_acceleration_mpss = 10
|