Files
dota_factory/bin/app/data/config/unlocks.toml
Malte Langkabel 1f339bd8d7 Implement config-driven unlock groups
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
2026-07-21 22:38:38 +02:00

141 lines
2.8 KiB
TOML

# Unlock groups (REQ-LOCK-EXPLICIT, REQ-DEF-SCHEMATIC-DROP).
#
# Each [[unlock]] is a group of ships/modules/buildings/recipes awarded together
# from a single defence station drop. Anything NOT granted by any group is
# available from game start. `station_level` gates when a group becomes eligible;
# `requires` lists prerequisite unlock-group ids (REQ-LOCK-PREREQ).
#
# Most entries below are single-item groups that reproduce the previous per-item
# progression. The salvage_operations and reprocessing groups are the grouped
# unlocks: they lock the salvager module + salvage bay, and the reprocessing
# plant, from game start.
# --- Grouped unlocks -------------------------------------------------------
[[unlock]]
id = "salvage_operations"
station_level = 1
modules = ["salvager"]
buildings = ["salvage_bay"]
[[unlock]]
id = "reprocessing"
station_level = 2
buildings = ["reprocessing_plant"]
# --- Ships -----------------------------------------------------------------
[[unlock]]
id = "destroyer"
station_level = 0
ships = ["destroyer"]
[[unlock]]
id = "cruiser"
station_level = 2
ships = ["cruiser"]
[[unlock]]
id = "battlecruiser"
station_level = 4
requires = ["cruiser"]
ships = ["battlecruiser"]
[[unlock]]
id = "battleship"
station_level = 6
requires = ["battlecruiser"]
ships = ["battleship"]
[[unlock]]
id = "dreadnought"
station_level = 8
requires = ["battleship"]
ships = ["dreadnought"]
[[unlock]]
id = "carrier"
station_level = 9
requires = ["battleship"]
ships = ["carrier"]
# --- Modules ---------------------------------------------------------------
[[unlock]]
id = "repair_tool"
station_level = 0
modules = ["repair_tool"]
[[unlock]]
id = "armor_plates"
station_level = 0
modules = ["armor_plates"]
[[unlock]]
id = "maneuvering_thrusters"
station_level = 1
modules = ["maneuvering_thrusters"]
[[unlock]]
id = "sensor_booster"
station_level = 1
modules = ["sensor_booster"]
[[unlock]]
id = "railgun_m"
station_level = 2
modules = ["railgun_m"]
[[unlock]]
id = "afterburner"
station_level = 2
modules = ["afterburner"]
[[unlock]]
id = "weapon_stabilizer"
station_level = 3
modules = ["weapon_stabilizer"]
[[unlock]]
id = "weapon_upgrade"
station_level = 4
modules = ["weapon_upgrade"]
[[unlock]]
id = "weapon_primer"
station_level = 4
modules = ["weapon_primer"]
[[unlock]]
id = "drone_bay"
station_level = 5
modules = ["drone_bay"]
[[unlock]]
id = "railgun_l"
station_level = 6
requires = ["railgun_m"]
modules = ["railgun_l"]
[[unlock]]
id = "drone_hangar"
station_level = 9
modules = ["drone_hangar"]
# --- Assembler recipes -----------------------------------------------------
[[unlock]]
id = "shortcut_steel_plate"
station_level = 1
recipes = ["shortcut_steel_plate"]
[[unlock]]
id = "shortcut_control_chip"
station_level = 2
recipes = ["shortcut_control_chip"]
[[unlock]]
id = "shortcut_hardened_steel"
station_level = 2
recipes = ["shortcut_hardened_steel"]