diff --git a/src/game/data/catalog.cpp b/src/game/data/catalog.cpp index def5ee1..fa11c35 100644 --- a/src/game/data/catalog.cpp +++ b/src/game/data/catalog.cpp @@ -297,10 +297,10 @@ CrossCheck Catalog::cross_check() const { return t; }; - // weapon requires -> tech + // weapon requires_tech -> tech for (const WeaponDef& w : weapons) { - if (w.requires.empty()) x.weapons_without_requires.push_back(w.file); - for (const std::string& r : w.requires) { + if (w.requires_tech.empty()) x.weapons_without_requires.push_back(w.file); + for (const std::string& r : w.requires_tech) { const TechNode* exact = nullptr; const TechNode* t = tech_ref(r, &exact); if (!t) @@ -314,9 +314,9 @@ CrossCheck Catalog::cross_check() const { x.unresolved_weapon_names.push_back({w.file, w.name, 0}); } - // sections: requires, options, bank weapons, turret pairs + // sections: requires_tech, options, bank weapons, turret pairs for (const ShipSectionDef& s : sections) { - for (const std::string& r : s.requires) { + for (const std::string& r : s.requires_tech) { if (is_group_ref(r)) { if (!tech.requirement_exists(r)) x.section_requires_dangling.push_back({s.file, r, 0}); continue; @@ -342,7 +342,7 @@ CrossCheck Catalog::cross_check() const { } } - // tech: ship sections, weapon files, requires, allows + // tech: ship sections, weapon files, requires_tech, allows std::set weapon_files; for (const WeaponDef& w : weapons) weapon_files.insert(fold(w.file)); for (const TechNode& t : tech.nodes) { @@ -353,7 +353,7 @@ CrossCheck Catalog::cross_check() const { std::replace(k.begin(), k.end(), '\\', '/'); if (!weapon_files.count(k)) x.tech_weapon_file_dangling.push_back({t.name, wf, t.line}); } - for (const std::string& r : t.requires) + for (const std::string& r : t.requires_tech) if (!tech.requirement_exists(r)) x.tech_requires_dangling.push_back({t.name, r, t.line}); for (std::size_t ei : t.allows) { const AllowsEdge& e = tech.edges[ei]; diff --git a/src/game/data/common.h b/src/game/data/common.h index 4a168d2..c1d34ee 100644 --- a/src/game/data/common.h +++ b/src/game/data/common.h @@ -26,7 +26,7 @@ Species parse_species(std::string_view name); // case-insensitive; "NPC struct Problem { enum class Kind { MissingBlock, // file has no top-level block of the expected name - MissingKey, // a key the schema requires is absent + MissingKey, // a key the schema requires_tech is absent BadValue, // a value does not have the expected shape (kept in raw) Unparsed, // a structured value (allows string, turret row) could not be parsed Duplicate, // an id / name occurs twice diff --git a/src/game/data/shipsection.cpp b/src/game/data/shipsection.cpp index bb6b660..fe7db8c 100644 --- a/src/game/data/shipsection.cpp +++ b/src/game/data/shipsection.cpp @@ -134,7 +134,7 @@ Loaded load_shipsection(const mars::parse::Document& doc, std::s s.model = f.required_str("model"); s.dam_model = f.str("dam_model"); - s.requires = f.strs("requires"); + s.requires_tech = f.strs("requires"); s.section_type_text = f.str("section_type"); s.section_type = parse_section_type(s.section_type_text); s.section_class_text = f.str("section_class"); diff --git a/src/game/data/shipsection.h b/src/game/data/shipsection.h index 7b1ab64..8c706f0 100644 --- a/src/game/data/shipsection.h +++ b/src/game/data/shipsection.h @@ -1,7 +1,7 @@ // game::data -- ShipSectionDef: one `Species//sections/*.shipsection`. // // shipsection { -// model PATH requires TECH... section_type command|mission|engine +// model PATH requires_tech TECH... section_type command|mission|engine // section_class destroyer|cruiser|dreadnought // health mass cost cpoints crew socket_fore/socket_aft NODE // option TECH -- one-member option group @@ -83,7 +83,7 @@ struct ShipSectionDef { // body std::string model, dam_model; - std::vector requires; // AND; may name GRP_ + std::vector requires_tech; // AND; may name GRP_ std::string section_type_text; SectionType section_type = SectionType::None; std::string section_class_text; diff --git a/src/game/data/techtree.cpp b/src/game/data/techtree.cpp index 13a4058..7c23908 100644 --- a/src/game/data/techtree.cpp +++ b/src/game/data/techtree.cpp @@ -150,7 +150,7 @@ Loaded load_tech_tree(const mars::parse::Document& doc, std::string fi t.group = f.str("group"); t.option_cost = f.opt_double("option_cost"); t.unlock_explicitly = f.opt_bool("unlock_explicitly"); - t.requires = f.strs("requires"); + t.requires_tech = f.strs("requires"); for (const Block* s : t.raw.blocks_named("strategy")) { for (const std::string& v : s->strs("inc")) t.benefits_inc.push_back(v); for (const std::string& v : s->strs("dec")) t.benefits_dec.push_back(v); diff --git a/src/game/data/techtree.h b/src/game/data/techtree.h index 8e7c82f..6cd77d8 100644 --- a/src/game/data/techtree.h +++ b/src/game/data/techtree.h @@ -2,7 +2,7 @@ // // tech { // name "IND_Waldo" family "IND" type P threat N group TORPS option_cost 1.2 -// requires "TECH" | "GRP_" -- prerequisite beyond the allows edge +// requires_tech "TECH" | "GRP_" -- prerequisite beyond the allows edge // allows "CHILD RP:cost Human:% Zuul:% Hiver:% Tarkas:% Liir:% Morrigi:%" // strategy { inc TECHBEN_X dec TECHBEN_Y } // ship { section STEM ... } -- "new section" notice (not a build gate) @@ -59,7 +59,7 @@ struct TechNode { std::string group; // as written; group membership is matched upper-cased std::optional option_cost; std::optional unlock_explicitly; - std::vector requires; + std::vector requires_tech; std::vector benefits_inc, benefits_dec; // TECHBEN_* tokens, kept as data std::vector sections; // ship{section} stems std::vector weapon_files; // weapon{filename} @@ -87,7 +87,7 @@ public: std::vector edges_from(std::string_view name) const; std::vector roots() const; // nodes no edge points at - // A `requires` token is satisfiable if it names a tech or a non-empty group. + // A `requires_tech` token is satisfiable if it names a tech or a non-empty group. bool requirement_exists(std::string_view token) const; void rebuild_index(); diff --git a/src/game/data/weapon.cpp b/src/game/data/weapon.cpp index 6cfb1a9..22734f8 100644 --- a/src/game/data/weapon.cpp +++ b/src/game/data/weapon.cpp @@ -56,7 +56,7 @@ Loaded load_weapon(const mars::parse::Document& doc, std::string file w.weapon_class = f.required_str("weaponclass"); w.weapon_family = f.str("weaponfamily"); w.weapon_damage_type = f.str("weapondamagetype"); - w.requires = f.strs("requires"); + w.requires_tech = f.strs("requires"); w.compatible_section = f.strs("compatible_section"); w.exclusive_species = f.str("exclusive_species"); w.cost = f.opt_int("cost"); diff --git a/src/game/data/weapon.h b/src/game/data/weapon.h index 3f15bbb..0b6771a 100644 --- a/src/game/data/weapon.h +++ b/src/game/data/weapon.h @@ -2,7 +2,7 @@ // // weapon { // name @WEAPON_X weaponclass bullet weaponfamily gauss -// requires TECH [requires TECH2] cost N +// requires_tech TECH [requires_tech TECH2] cost N // turretsize small turretclass standard // burst_volleys N recharge_time T range R range_planet RP // fc_* true/false rating_* N @@ -72,7 +72,7 @@ struct WeaponDef { std::string weapon_class; // drives engine behaviour (bullet, beam, missile, ...) std::string weapon_family; // AI grouping (gauss, laser, torpedo, ...) std::string weapon_damage_type; - std::vector requires; // AND of techs; may be empty + std::vector requires_tech; // AND of techs; may be empty std::vector compatible_section; // rider weapons: section stems they carry std::string exclusive_species; std::optional cost; diff --git a/src/game/design/rules.cpp b/src/game/design/rules.cpp index ee15b59..da3e59e 100644 --- a/src/game/design/rules.cpp +++ b/src/game/design/rules.cpp @@ -48,7 +48,7 @@ std::vector option_groups(const ShipSectionDef& s) { std::vector applied_techs(const ShipSectionDef& s, const std::vector& chosen) { std::vector out; if (auto hct = hull_class_tech(s)) out.push_back(*hct); - out.insert(out.end(), s.requires.begin(), s.requires.end()); + out.insert(out.end(), s.requires_tech.begin(), s.requires_tech.end()); for (const data::OptionGroup* g : option_groups(s)) for (const std::string& member : g->members) for (const std::string& c : chosen) @@ -64,7 +64,7 @@ std::vector options_from_applied(const ShipSectionDef& s, const std auto hct = hull_class_tech(s); for (const std::string& t : applied) { if (hct && iequals(t, *hct)) continue; - if (contains_fold(s.requires, t)) continue; + if (contains_fold(s.requires_tech, t)) continue; out.push_back(t); } return out; @@ -248,7 +248,7 @@ std::vector Ruleset::validate(const Design& d) const { if (want->empty()) continue; if (!part->def || !iequals(part->def->stem, *want)) add(v, "A8", Level::Error, - m.stem + " requires " + slot_str(part->slot) + " section " + *want + ", got " + + m.stem + " requires_tech " + slot_str(part->slot) + " section " + *want + ", got " + (part->def ? part->def->stem : std::string("none")), part->slot); } @@ -365,8 +365,8 @@ std::vector Ruleset::validate(const Design& d) const { } } if (known && bank.weapon.empty()) - for (const std::string& t : w->requires) - if (!known->satisfies(cat.tech, t)) add(v, "C2", Level::Error, w->stem + " requires " + t, p->slot, bi); + for (const std::string& t : w->requires_tech) + if (!known->satisfies(cat.tech, t)) add(v, "C2", Level::Error, w->stem + " requires_tech " + t, p->slot, bi); } } @@ -394,18 +394,18 @@ std::vector Ruleset::validate(const Design& d) const { // -- tech gating ---------------------------------------------------------- // Engine-generated hidden designs (the per-race "Default Assault Shuttle") // exist in every save regardless of research: the Tarkas _AssaultShuttle - // requires DRN_AdvFrm and the design is there on turn 1. Gating on hidden + // requires_tech DRN_AdvFrm and the design is there on turn 1. Gating on hidden // designs is therefore reported at warn level. const Level gate = hidden ? Level::Warn : Level::Error; for (const Filled* p : present) { const ShipSectionDef& s = *p->def; - for (const std::string& t : s.requires) { + for (const std::string& t : s.requires_tech) { if (!cat.tech.find(t) && !data::is_group_ref(t)) - add(v, "C1", Level::Warn, s.stem + " requires unknown tech " + t, p->slot); + add(v, "C1", Level::Warn, s.stem + " requires_tech unknown tech " + t, p->slot); else if (known && !known->satisfies(cat.tech, t)) - add(v, "C1", gate, s.stem + " requires " + t, p->slot); + add(v, "C1", gate, s.stem + " requires_tech " + t, p->slot); if (unobtainable(t, race)) - add(v, "C5", Level::Error, s.stem + " requires " + t + ", which " + std::string(rk) + " can never research", p->slot); + add(v, "C5", Level::Error, s.stem + " requires_tech " + t + ", which " + std::string(rk) + " can never research", p->slot); } if (auto hct = hull_class_tech(s); hct && known && !known->satisfies(cat.tech, *hct)) add(v, "C4", gate, s.stem + " is a " + fold(s.section_class_text) + " section; " + *hct + " not researched", p->slot); diff --git a/src/game/design/rules.h b/src/game/design/rules.h index e8cdd9a..12bb6ed 100644 --- a/src/game/design/rules.h +++ b/src/game/design/rules.h @@ -11,12 +11,12 @@ // B* banks: one weapon per bank{}, none empty, fixed NPC banks bound to // their file, fit = class-accept table + a _turrets.txt row, weapon // scope / exclusive_species / rider carriers / hidden weapons. -// C* tech gating: section and weapon `requires` (GRP_ = any of the group), +// C* tech gating: section and weapon `requires_tech` (GRP_ = any of the group), // chosen options, the implicit hull-class tech (IND_CruisCon / // IND_DreadCon, stations exempt), race availability. Hidden default // designs are gated at warn level (code rule the data does not show). // D* options: at most one per group, members only; applied_techs = -// [hull-class tech] + requires + chosen options in group order (D2). +// [hull-class tech] + requires_tech + chosen options in group order (D2). // // Nothing here throws; every finding is a Violation. #pragma once @@ -44,12 +44,12 @@ inline bool is_station(const data::ShipSectionDef& s) { return data::iequals(s.d std::vector option_groups(const data::ShipSectionDef& s); // D2: the techs a section instance is built with -- exactly the save's DOpts -// list: hull-class tech, `requires` in file order, then the chosen option of +// list: hull-class tech, `requires_tech` in file order, then the chosen option of // each group in group order (spelled as chosen). std::vector applied_techs(const data::ShipSectionDef& s, const std::vector& chosen_options); // Inverse of applied_techs for a save record: drops the hull-class tech and -// the `requires` from a DOpts list, leaving the chosen options. +// the `requires_tech` from a DOpts list, leaving the chosen options. std::vector options_from_applied(const data::ShipSectionDef& s, const std::vector& applied); // B4: which weapon turret classes a bank turret class takes besides an exact diff --git a/tests/game_data/dump_catalog.cpp b/tests/game_data/dump_catalog.cpp index d7694fd..27ac681 100644 --- a/tests/game_data/dump_catalog.cpp +++ b/tests/game_data/dump_catalog.cpp @@ -191,7 +191,7 @@ J weapon_json(const WeaponDef& w) { .set("weaponclass", jstr(w.weapon_class)) .set("weaponfamily", jstr(w.weapon_family)) .set("weapondamagetype", jstr(w.weapon_damage_type)) - .set("requires", jstrs(w.requires)) + .set("requires", jstrs(w.requires_tech)) .set("compatible_section", jstrs(w.compatible_section)) .set("exclusive_species", jstr(w.exclusive_species)) .set("cost", jopt(w.cost)) @@ -270,7 +270,7 @@ J section_json(const ShipSectionDef& s) { JObj t; t.set("model", jstr(s.model)) .set("dam_model", jstr(s.dam_model)) - .set("requires", jstrs(s.requires)) + .set("requires", jstrs(s.requires_tech)) .set("section_type", jstr(s.section_type_text)) .set("section_type_enum", jstr(section_type_name(s.section_type))) .set("section_class", jstr(s.section_class_text)) @@ -385,7 +385,7 @@ J tech_json(const TechTree& t) { .set("group", n.group.empty() ? jnull() : jstr(n.group)) .set("option_cost", jopt(n.option_cost)) .set("unlock_explicitly", jopt(n.unlock_explicitly)) - .set("requires", jstrs(n.requires)) + .set("requires", jstrs(n.requires_tech)) .set("benefits_inc", jstrs(n.benefits_inc)) .set("benefits_dec", jstrs(n.benefits_dec)) .set("sections", jstrs(n.sections)) diff --git a/tests/game_data/realdata_test.cpp b/tests/game_data/realdata_test.cpp index d999b73..ea51d79 100644 --- a/tests/game_data/realdata_test.cpp +++ b/tests/game_data/realdata_test.cpp @@ -57,17 +57,17 @@ int main() { const WeaponDef* g = cat.weapon("bal_gauss"); EXPECT(g && g->id && *g->id == 8); EXPECT(g && g->cost && *g->cost == 50 && g->turret_size == "small" && g->turret_class == "standard"); - EXPECT(g && g->requires.size() == 1 && g->requires[0] == "WEP_GsDrvr"); + EXPECT(g && g->requires_tech.size() == 1 && g->requires_tech[0] == "WEP_GsDrvr"); EXPECT(g && g->bolt && g->bolt->rangetable.maximum.range && *g->bolt->rangetable.maximum.range == 455); EXPECT(g && g->bolt && g->bolt->planet.pop && *g->bolt->planet.pop == 3500); EXPECT(g && g->fc.requires_los && *g->fc.requires_los && g->fc.manual_target && !*g->fc.manual_target); EXPECT(g && g->display_name && *g->display_name == "Gauss Cannon"); EXPECT(cat.weapon_by_id(8) == g); - EXPECT(cat.weapon("mis") && cat.weapon("mis")->requires.empty()); + EXPECT(cat.weapon("mis") && cat.weapon("mis")->requires_tech.empty()); const ShipSectionDef* fis = cat.section("Human", "DEFission"); EXPECT(fis && fis->id && *fis->id == 47); - EXPECT(fis && fis->requires.size() == 2 && fis->requires[1] == "DRV_Node"); + EXPECT(fis && fis->requires_tech.size() == 2 && fis->requires_tech[1] == "DRV_Node"); EXPECT(fis && fis->section_type == SectionType::Engine && fis->section_class == SectionClass::Destroyer); EXPECT(fis && fis->options.size() == 3 && fis->options[0].members.size() == 5 && fis->options[2].scalar && fis->options[2].members[0] == "DRV_RecFiss"); @@ -131,7 +131,7 @@ int main() { // ---- cross-check -------------------------------------------------- CrossCheck x = cat.cross_check(); std::printf("cross-check: dangling %zu (manifest gaps %zu, unresolved names %zu); case mismatches %zu/%zu; " - "no-requires %zu; missing sectiondesc %zu; roots %zu\n", + "no-requires_tech %zu; missing sectiondesc %zu; roots %zu\n", x.dangling_count(), x.manifest_ids_without_file.size(), x.unresolved_weapon_names.size(), x.weapon_requires_case_mismatch.size(), x.section_requires_case_mismatch.size(), x.weapons_without_requires.size(), x.missing_sectiondesc.size(), x.tech_roots.size()); diff --git a/tests/game_data/test_catalog.cpp b/tests/game_data/test_catalog.cpp index d353202..808f0ab 100644 --- a/tests/game_data/test_catalog.cpp +++ b/tests/game_data/test_catalog.cpp @@ -22,10 +22,10 @@ fs::path make_root() { fs::path root = fs::temp_directory_path() / ("game_data_test_" + std::to_string(static_cast(stamp))); fs::remove_all(root); put(root / "Weapons/bal_gauss.weapon", - "weapon { name @WEAPON_BAL_GAUSS weaponclass bullet requires WEP_GsDrvr cost 50 turretsize small turretclass standard\n" + "weapon { name @WEAPON_BAL_GAUSS weaponclass bullet requires_tech WEP_GsDrvr cost 50 turretsize small turretclass standard\n" " bolt { rangetable { max_range 455 } dam_pop 3500 } }\n"); put(root / "Weapons/las_odd.weapon", - "weapon { name @WEAPON_LAS_ODD weaponclass beam requires WEP_NOPE requires wep_gsdrvr turretsize Large turretclass Beam }\n"); + "weapon { name @WEAPON_LAS_ODD weaponclass beam requires_tech WEP_NOPE requires_tech wep_gsdrvr turretsize Large turretclass Beam }\n"); put(root / "Weapons/mis.weapon", "weapon { name @WEAPON_MIS weaponclass missile turretsize medium turretclass missile }\n"); put(root / "Weapons/_weapons.txt", "// ids\n8 bal_gauss.weapon\n21 mis.weapon\n// DELETED - 36\n40 ghost.weapon\n"); @@ -38,7 +38,7 @@ fs::path make_root() { " bank { turretclass standard turretsize small mount { node N1 } } }\n"); put(root / "Species/Human/sections/DEFission.shipsection", "shipsection { model b.X section_type engine section_class destroyer health 1 mass 2 socket_fore EngineNode\n" - " requires DRV_Fissn requires grp_torps requires GRP_Empty\n" + " requires_tech DRV_Fissn requires_tech grp_torps requires_tech GRP_Empty\n" " bank { turretclass strafe turretsize small mount { node N1 } } }\n"); put(root / "Species/Human/sections/_shipsections.txt", "1 DECommand.shipsection\n47 defission.SHIPSECTION\n98 DEWar.shipsection\n"); put(root / "Species/_NPC/sections/_Herald.shipsection", @@ -52,7 +52,7 @@ fs::path make_root() { "tech { name \"IND_ROOT\" family \"IND\" allows \"IND_PlyAlloy RP:5000\" allows \"WEP_Missing RP:1\" allows \"BAD\" }\n" "tech { name \"IND_PlyAlloy\" ship { section DECommand section DENowhere } weapon { filename \"Weapons/bal_gauss.weapon\" }\n" " weapon { filename \"Weapons/nope.weapon\" } }\n" - "tech { name \"WEP_GsDrvr\" group TORPS requires \"GRP_TORPS\" requires \"GRP_Nothing\" requires \"IND_Gone\" }\n" + "tech { name \"WEP_GsDrvr\" group TORPS requires_tech \"GRP_TORPS\" requires_tech \"GRP_Nothing\" requires_tech \"IND_Gone\" }\n" "tech { name \"DRV_Fissn\" }\n"); put(root / "Locale/EN/Strings.csv", "#Key+A955,String,Size,Notes\n" diff --git a/tests/game_data/test_shipsection.cpp b/tests/game_data/test_shipsection.cpp index 9aaaeb3..8a2e7fb 100644 --- a/tests/game_data/test_shipsection.cpp +++ b/tests/game_data/test_shipsection.cpp @@ -53,8 +53,8 @@ TEST(section_typed_fields) { CHECK(s.section_type == SectionType::Engine); CHECK_EQ(s.section_class_text, "Destroyer"); CHECK(s.section_class == SectionClass::Destroyer); - CHECK_EQ(s.requires.size(), std::size_t{2}); - CHECK_EQ(s.requires[1], "DRV_Node"); + CHECK_EQ(s.requires_tech.size(), std::size_t{2}); + CHECK_EQ(s.requires_tech[1], "DRV_Node"); CHECK_EQ(s.engine_techera, "fission"); CHECK(s.health && *s.health == 450); CHECK(s.mass && *s.mass == 2500); diff --git a/tests/game_data/test_techtree.cpp b/tests/game_data/test_techtree.cpp index 271579b..099f020 100644 --- a/tests/game_data/test_techtree.cpp +++ b/tests/game_data/test_techtree.cpp @@ -125,7 +125,7 @@ TEST(tech_tree_nodes_edges_groups) { const TechNode* alloy = t.find("IND_PlyAlloy"); CHECK(alloy->option_cost && *alloy->option_cost == 1.2); // OPTION_COST key case - CHECK_EQ(alloy->requires.size(), std::size_t{1}); + CHECK_EQ(alloy->requires_tech.size(), std::size_t{1}); CHECK(t.find("IND_StlthArm")->unlock_explicitly.value_or(false)); const TechNode* dsr = t.find("WEP_Dsrptr"); diff --git a/tests/game_data/test_weapon.cpp b/tests/game_data/test_weapon.cpp index dcdf537..947877a 100644 --- a/tests/game_data/test_weapon.cpp +++ b/tests/game_data/test_weapon.cpp @@ -56,9 +56,9 @@ TEST(weapon_typed_fields) { CHECK_EQ(w.name, "@WEAPON_TEST_GUN"); CHECK_EQ(w.weapon_class, "bullet"); CHECK_EQ(w.weapon_family, "gauss"); - CHECK_EQ(w.requires.size(), std::size_t{2}); - CHECK_EQ(w.requires[0], "WEP_A"); - CHECK_EQ(w.requires[1], "WEP_B"); + CHECK_EQ(w.requires_tech.size(), std::size_t{2}); + CHECK_EQ(w.requires_tech[0], "WEP_A"); + CHECK_EQ(w.requires_tech[1], "WEP_B"); CHECK(w.cost && *w.cost == 50); CHECK_EQ(w.turret_size, "small"); CHECK_EQ(w.turret_class, "Standard"); // kept as written diff --git a/tests/game_design/mini_catalog.cpp b/tests/game_design/mini_catalog.cpp index 9e74680..4b5f767 100644 --- a/tests/game_design/mini_catalog.cpp +++ b/tests/game_design/mini_catalog.cpp @@ -43,7 +43,7 @@ std::string de_armor(const char* extra = "") { std::string de_fission(const char* drive) { return "shipsection { model c.X Section_Type Engine section_class Destroyer socket_fore EngineNode\n" - " requires DRV_Fissn requires " + std::string(drive) + + " requires_tech DRV_Fissn requires_tech " + std::string(drive) + "\n health 450 mass 2500 cost 5000 cpoints 1380 engine_techera fission ftlspeed .2 nodespeed 4 range 9\n" + std::string(kArmorOptions) + " option DRV_RecFiss\n" " netforcelimits { force_forward 23000 force_right 23000 force_up 23000 torque_yaw 5 torque_pitch 5 torque_roll 5 speed 40 rotspeed 10 }\n" + @@ -59,7 +59,7 @@ std::string de_platform() { const char* kRider = "shipsection { model r.X section_class destroyer design_class rider entity_class rider health 50 mass 100 cost 100 }\n"; const char* kRiderGated = - "shipsection { model r.X section_class destroyer design_class rider entity_class rider requires DRN_AdvFrm health 50 mass 100 cost 100 }\n"; + "shipsection { model r.X section_class destroyer design_class rider entity_class rider requires_tech DRN_AdvFrm health 50 mass 100 cost 100 }\n"; void write_human(const fs::path& r) { fs::path s = r / "Species/Human/sections"; @@ -75,10 +75,10 @@ void write_human(const fs::path& r) { bank("strafe", "small", 4) + bank("standard", "large", 1) + "}\n"); put(s / "DETorpedo.shipsection", "shipsection { model e.X section_type mission section_class destroyer socket_fore F socket_aft A health 1 mass 1 cost 1\n" - " requires GRP_Torps\n" + bank("torpedo", "large", 1) + bank("missile", "medium", 1) + "}\n"); + " requires_tech GRP_Torps\n" + bank("torpedo", "large", 1) + bank("missile", "medium", 1) + "}\n"); put(s / "DEAssaultShuttle.shipsection", "shipsection { model e.X section_type mission section_class destroyer socket_fore F socket_aft A health 1 mass 1 cost 1\n" - " requires DRN_AdvFrm\n" + bank("assaultshuttlerider", "large", 1) + bank("tarkahunter", "large", 1) + "}\n"); + " requires_tech DRN_AdvFrm\n" + bank("assaultshuttlerider", "large", 1) + bank("tarkahunter", "large", 1) + "}\n"); put(s / "DEPlanetMissile.shipsection", "shipsection { model e.X section_type mission section_class destroyer socket_fore F socket_aft A health 1 mass 1 cost 1\n" + bank("planetmissile", "large", 1) + "}\n"); @@ -90,12 +90,12 @@ void write_human(const fs::path& r) { bank("standard", "large", 2) + "}\n"); put(s / "CRFission.shipsection", "shipsection { model f.X section_type engine section_class cruiser socket_fore EngineNode health 1 mass 30 cost 300 crew 15\n" - " requires DRV_Fissn requires DRV_Node engine_techera fission ftlspeed .2 nodespeed 4\n" + + " requires_tech DRV_Fissn requires_tech DRV_Node engine_techera fission ftlspeed .2 nodespeed 4\n" + bank("standard", "medium", 1) + "}\n"); // the station triple (design_class station: no hull-class tech; partners pinned) put(s / "DNStation.shipsection", "shipsection { model g.X section_type mission section_class dreadnought socket_fore Fore socket_aft Aft\n" - " requires IND_OrbCom health 9000 mass 100000 cost 700000 crew 100 entity_class \"Station\" design_class station command_quota 46\n" + " requires_tech IND_OrbCom health 9000 mass 100000 cost 700000 crew 100 entity_class \"Station\" design_class station command_quota 46\n" " explicit_command_section \"DNStation_Fore\" explicit_engine_section \"DNStation_Aft\"\n" + bank("standard", "large", 2) + "}\n"); put(s / "DNStation_Fore.shipsection", diff --git a/tests/game_design/test_tech.cpp b/tests/game_design/test_tech.cpp index 2466432..acaae98 100644 --- a/tests/game_design/test_tech.cpp +++ b/tests/game_design/test_tech.cpp @@ -42,7 +42,7 @@ TEST(C1_group_requirements) { TEST(C1_unknown_tech_is_a_warning) { Design d = armor(); d.engine() = use("DEOddTech", {"bal_gauss"}); - // DEOddTech requires DRV_Fissn (known) and XXX_Nowhere (not in the tree): + // DEOddTech requires_tech DRV_Fissn (known) and XXX_Nowhere (not in the tree): // a token the tree cannot satisfy is reported, never an error. std::vector v = mini_rules().validate(d); CHECK_EQ(join(rules_at(v, Level::Error)), "");