diff --git a/sc2/src/uqm/gendef.c b/sc2/src/uqm/gendef.c index cc939624f..aa223266a 100644 --- a/sc2/src/uqm/gendef.c +++ b/sc2/src/uqm/gendef.c @@ -22,22 +22,24 @@ #include -extern GenerateFunctions generateOrzFunctions; -extern GenerateFunctions generateSolFunctions; -extern GenerateFunctions generateThraddashFunctions; -extern GenerateFunctions generateUtwigFunctions; - - const GenerateFunctions * getGenerateFunctions (STAR_DESC *const star) { switch (star->Index) { - // Legacy ones are disabled... + // All of the generator enums are now disabled. + // I can just remove the enum, after a quick play-test. + case SOL_DEFINED: + + case BOMB_DEFINED: + case UTWIG_DEFINED: + case AQUA_HELIX_DEFINED: + case THRADD_DEFINED: + case TAALO_PROTECTOR_DEFINED: + case ORZ_DEFINED: case MAIDENS_DEFINED: case VUX_BEAST_DEFINED: case VUX_DEFINED: - case SUN_DEVICE_DEFINED: case MYCON_DEFINED: case EGG_CASE0_DEFINED: @@ -77,17 +79,6 @@ getGenerateFunctions (STAR_DESC *const star) default: abort(); - case SOL_DEFINED: - return &generateSolFunctions; - case BOMB_DEFINED: - case UTWIG_DEFINED: - return &generateUtwigFunctions; - case AQUA_HELIX_DEFINED: - case THRADD_DEFINED: - return &generateThraddashFunctions; - case TAALO_PROTECTOR_DEFINED: - case ORZ_DEFINED: - return &generateOrzFunctions; } } diff --git a/sc2/src/uqm/plandata.c b/sc2/src/uqm/plandata.c index ad5c860d9..3cbe92e62 100644 --- a/sc2/src/uqm/plandata.c +++ b/sc2/src/uqm/plandata.c @@ -550,7 +550,7 @@ STAR_DESC starmap_array[] = {{1777, 1405}, MAKE_STAR (DWARF_STAR, YELLOW_BODY, -1), 0, 0, 99}, // ADAM ADDED {{1703, 1432}, MAKE_STAR (GIANT_STAR, GREEN_BODY, -1), 0, 0, 171}, - {{1752, 1450}, MAKE_STAR (DWARF_STAR, YELLOW_BODY, -1), SOL_DEFINED, 0, 129}, + {{1752, 1450}, MAKE_STAR (DWARF_STAR, YELLOW_BODY, -1), 0, 0, 129, "Sol"}, {{1848, 1469}, MAKE_STAR (DWARF_STAR, BLUE_BODY, -1), 0, 4, 82, "Shofixti"}, {{1751, 1479}, MAKE_STAR (GIANT_STAR, GREEN_BODY, -1), 0, 1, 59, "Wreck"}, {{1707, 1501}, MAKE_STAR (DWARF_STAR, GREEN_BODY, -1), 0, 0, 52}, @@ -563,8 +563,10 @@ STAR_DESC starmap_array[] = {{6291, 2208}, MAKE_STAR (DWARF_STAR, GREEN_BODY, -1), 0, 5, 71, "Mycon Worlds", "Homeworld"}, {{ 742, 2268}, MAKE_STAR (DWARF_STAR, ORANGE_BODY, -1), 0, 0, 117, "Chmmr"}, {{6395, 2312}, MAKE_STAR (DWARF_STAR, GREEN_BODY, -1), 0, 2, 12, "Mycon Worlds", "Sun Device"}, + {{3713, 2537}, MAKE_STAR (DWARF_STAR, GREEN_BODY, -1), 0, 3, 86, "Orz", "Homeworld"}, {{3587, 2566}, MAKE_STAR (DWARF_STAR, GREEN_BODY, -1), 0, 7, 86, "Androsynth"}, {{3654, 2587}, MAKE_STAR (SUPER_GIANT_STAR, GREEN_BODY, -1), 0, 1, 86, "Melnorme", "3"}, + {{3721, 2619}, MAKE_STAR (DWARF_STAR, GREEN_BODY, -1), 0, 4, 86, "Orz", "Taalo Protector"}, {{6008, 2631}, MAKE_STAR (DWARF_STAR, YELLOW_BODY, -1), 0, 2, 14, "Mycon Worlds", "Egg Case 0"}, {{6354, 2729}, MAKE_STAR (DWARF_STAR, WHITE_BODY, -1), 0, 3, 12, "Mycon Worlds", "Egg Case 2"}, {{9469, 2806}, MAKE_STAR (DWARF_STAR, ORANGE_BODY, -1), 0, 6, 61, "Druuge"}, @@ -590,16 +592,21 @@ STAR_DESC starmap_array[] = {{2836, 7857}, MAKE_STAR (DWARF_STAR, WHITE_BODY, -1), 0, 5, 53, "Rainbow"}, {{5437, 8270}, MAKE_STAR (DWARF_STAR, RED_BODY, -1), 0, 5, 48, "Rainbow"}, + {{2535, 8358}, MAKE_STAR (DWARF_STAR, YELLOW_BODY, -1), 0, 4, 53, "Thraddash", "Homeworld"}, {{2582, 8507}, MAKE_STAR (SUPER_GIANT_STAR, YELLOW_BODY, -1), 0, 1, 2, "Melnorme", "7"}, {{7666, 8666}, MAKE_STAR (DWARF_STAR, ORANGE_BODY, -1), 0, 2, 46, "Rainbow"}, + {{2776, 8673}, MAKE_STAR (DWARF_STAR, ORANGE_BODY, -1), 0, 6, 53, "Thraddash", "Aqua Helix"}, + {{8630, 8693}, MAKE_STAR (DWARF_STAR, GREEN_BODY, -1), 0, 2, 3, "Utwig", "Homeworld"}, {{8534, 8797}, MAKE_STAR (DWARF_STAR, ORANGE_BODY, -1), 0, 3, 3, "Rainbow"}, {{9960, 9042}, MAKE_STAR (GIANT_STAR, WHITE_BODY, -1), 0, 0, 42, "Rainbow"}, {{7414, 9124}, MAKE_STAR (DWARF_STAR, GREEN_BODY, -1), 0, 2, 47, "Supox"}, + {{8500, 9372}, MAKE_STAR (DWARF_STAR, YELLOW_BODY, -1), 0, 6, 45, "Utwig", "Precursor Bomb"}, {{9159, 9745}, MAKE_STAR (SUPER_GIANT_STAR, BLUE_BODY, -1), 0, 1, 4, "Melnorme", "8"}, {{5704, 9795}, MAKE_STAR (DWARF_STAR, YELLOW_BODY, -1), 0, 4, 49, "VUX", "Beast"}, + {{MAX_X_UNIVERSE << 1, MAX_Y_UNIVERSE << 1}, 0, 0, 0, 0}, // QuasiSpace locations diff --git a/sc2/src/uqm/planets/generate/Makeinfo b/sc2/src/uqm/planets/generate/Makeinfo index 258cbf46b..1623106b4 100644 --- a/sc2/src/uqm/planets/generate/Makeinfo +++ b/sc2/src/uqm/planets/generate/Makeinfo @@ -1,7 +1,4 @@ -uqm_CFILES="gendefault.c - genorz.c - gensol.c - genthrad.c genutw.c" +uqm_CFILES="gendefault.c" uqm_HFILES="genall.h gendefault.h" uqm_CXXFILES="cxx-generator.cpp gensly-modern.cpp genshof-modern.cpp gencol-modern.cpp genwreck-modern.cpp genzfpscout-modern.cpp @@ -11,4 +8,5 @@ uqm_CXXFILES="cxx-generator.cpp gensly-modern.cpp genshof-modern.cpp genpet-modern.cpp genzoq-modern.cpp genyeh-modern.cpp genilw-modern.cpp genpku-modern.cpp gensam-modern.cpp genmyc-modern.cpp genrain-modern.cpp genmel-modern.cpp - genvux-modern.cpp" + genvux-modern.cpp genorz-modern.cpp gensol-modern.cpp + genthrad-modern.cpp genutw-modern.cpp" diff --git a/sc2/src/uqm/planets/generate/genorz.c b/sc2/src/uqm/planets/generate/genorz-modern.cpp similarity index 52% rename from sc2/src/uqm/planets/generate/genorz.c rename to sc2/src/uqm/planets/generate/genorz-modern.cpp index a50f318cc..dcb29eb3c 100644 --- a/sc2/src/uqm/planets/generate/genorz.c +++ b/sc2/src/uqm/planets/generate/genorz-modern.cpp @@ -30,41 +30,113 @@ #include "../../state.h" #include "libs/mathlib.h" +#include +#include +#include +#include +#include +#include +#include +#include -static bool GenerateOrz_generatePlanets (SOLARSYS_STATE *solarSys); -static bool GenerateOrz_generateOrbital (SOLARSYS_STATE *solarSys, - PLANET_DESC *world); -static COUNT GenerateOrz_generateEnergy (const SOLARSYS_STATE *, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); -static bool GenerateOrz_pickupEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +namespace +{ + using namespace std::literals::string_literals; + using namespace std::literals::string_view_literals; + using namespace Planets::exports; + + // Because we're more stringy and dynamic... It's possible that the + // supplemental arguments might be spelt wrong in various places. + // + // To help defend against this, the starmap checkers will make sure that + // only entries from this list are used. + // + // Further, I provide a `""_a` string suffix to facilitate C++23 compile + // time checks that each string being used is actually in this list. + // It does (at present) require the discipline to use `_a` suffix in all + // mentions. I can use more weaponized type system tricks to enforce + // that requirement. Some of those tricks require specialized typing + // in the STAR_DESC type... which I can't make C compatible. + // + // The right solution here is an Alepha::Enum. I'll probably be + // able to bring in Alepha soon -- but it's not worth it to + // make this code work like that. Instead, this somewhat peculiar + // merging of generation in this file should be decoupled. + // It mostly seems to exist to share the generation of the + // shattered world in the first planet slot -- after that, it just + // mostly does its own thing with each world. + + constexpr std::array required + { + "Homeworld"sv, + "Taalo Protector"sv, + }; + + constexpr bool + checkRequired( const std::string_view s ) + { + return end( required ) != std::find( begin( required ), end( required ), s ); + } + + + consteval std::string_view + operator ""_a( const char *const p, const std::size_t sz ) + { + const std::string_view rv{ p, p + sz }; + if( not checkRequired( rv ) ) + { + throw "The text specified was not one of the required argument strings"; + } + return rv; + }; + + class GenerateOrz + : public DefaultGenerator + { + bool generatePlanets( SolarSystem *solarSys ) override; + bool generateOrbital( SolarSystem *solarSys, + PLANET_DESC *world ); + COUNT generateEnergy (const SolarSystem *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); + bool pickupEnergy (SolarSystem *solarSys, + PLANET_DESC *world, COUNT whichNode); + + void + checkSupplementRequirements( const std::optional< std::string > ¶m ) override + { + if( not param.has_value() ) + { + throw std::runtime_error{ "Orz solar system did not have any supplementary " + "argument." }; + } + if( not checkRequired( param.value() ) ) + { + throw std::runtime_error{ "Orz solar system did not have any valid " + "supplementary argument (was instead: `"s + param.value() + "`)" }; + } + + std::cerr << "World had " << param.value() << " which was a permissible value" + << std::endl; + } + }; + + auto init= [] + { + Generator::add( "Orz", std::make_unique< GenerateOrz >() ); + + return 0xDEADBEEF; + }(); +} -const GenerateFunctions generateOrzFunctions = { - /* .initNpcs = */ GenerateDefault_initNpcs, - /* .reinitNpcs = */ GenerateDefault_reinitNpcs, - /* .uninitNpcs = */ GenerateDefault_uninitNpcs, - /* .generatePlanets = */ GenerateOrz_generatePlanets, - /* .generateMoons = */ GenerateDefault_generateMoons, - /* .generateName = */ GenerateDefault_generateName, - /* .generateOrbital = */ GenerateOrz_generateOrbital, - /* .generateMinerals = */ GenerateDefault_generateMinerals, - /* .generateEnergy = */ GenerateOrz_generateEnergy, - /* .generateLife = */ GenerateDefault_generateLife, - /* .pickupMinerals = */ GenerateDefault_pickupMinerals, - /* .pickupEnergy = */ GenerateOrz_pickupEnergy, - /* .pickupLife = */ GenerateDefault_pickupLife, -}; - - -static bool -GenerateOrz_generatePlanets (SOLARSYS_STATE *solarSys) +bool +GenerateOrz::generatePlanets( SolarSystem *const solarSys ) { COUNT angle; - GenerateDefault_generatePlanets (solarSys); + DefaultGenerator::generatePlanets (solarSys); - if (CurStarDescPtr->Index == ORZ_DEFINED) + if (CurStarDescPtr->supArg == "Homeworld"_a) { solarSys->PlanetDesc[0].data_index = WATER_WORLD; solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 156L / 100; @@ -80,18 +152,18 @@ GenerateOrz_generatePlanets (SOLARSYS_STATE *solarSys) return true; } -static bool -GenerateOrz_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) +bool +GenerateOrz::generateOrbital( SolarSystem *const solarSys, PLANET_DESC *const world ) { - if ((CurStarDescPtr->Index == ORZ_DEFINED + if ((CurStarDescPtr->supArg == "Homeworld"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) - || (CurStarDescPtr->Index == TAALO_PROTECTOR_DEFINED + || (CurStarDescPtr->supArg == "Taalo Protector"_a && matchWorld (solarSys, world, 1, 2) && !GET_GAME_STATE (TAALO_PROTECTOR))) { COUNT i; - if ((CurStarDescPtr->Index == ORZ_DEFINED + if ((CurStarDescPtr->supArg == "Homeworld"_a || !GET_GAME_STATE (TAALO_UNPROTECTED)) && StartSphereTracking (ORZ_SHIP)) { @@ -100,7 +172,7 @@ GenerateOrz_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) ReinitQueue (&GLOBAL (ip_group_q)); assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); - if (CurStarDescPtr->Index == ORZ_DEFINED) + if (CurStarDescPtr->supArg == "Homeworld"_a) { CloneShipFragment (ORZ_SHIP, &GLOBAL (npc_built_ship_q), INFINITE_FLEET); @@ -122,10 +194,10 @@ GenerateOrz_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) return true; { - BOOLEAN OrzSurvivors; + bool OrzSurvivors; OrzSurvivors = GetHeadLink (&GLOBAL (npc_built_ship_q)) - && (CurStarDescPtr->Index == ORZ_DEFINED + && (CurStarDescPtr->supArg == "Homeworld"_a || !GET_GAME_STATE (TAALO_UNPROTECTED)); GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY; @@ -140,7 +212,7 @@ GenerateOrz_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } SET_GAME_STATE (TAALO_UNPROTECTED, 1); - if (CurStarDescPtr->Index == TAALO_PROTECTOR_DEFINED) + if (CurStarDescPtr->supArg == "Taalo Protector"_a) { LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo); solarSys->PlanetSideFrame[1] = @@ -160,16 +232,16 @@ GenerateOrz_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } } - GenerateDefault_generateOrbital (solarSys, world); + DefaultGenerator::generateOrbital (solarSys, world); return true; } -static COUNT -GenerateOrz_generateEnergy (const SOLARSYS_STATE *solarSys, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) +COUNT +GenerateOrz::generateEnergy( const SolarSystem *const solarSys, + const PLANET_DESC *const world, const COUNT whichNode, NODE_INFO *const info ) { - if (CurStarDescPtr->Index == TAALO_PROTECTOR_DEFINED + if (CurStarDescPtr->supArg == "Taalo Protector"_a && matchWorld (solarSys, world, 1, 2)) { // This check is redundant since the retrieval bit will keep the @@ -182,7 +254,7 @@ GenerateOrz_generateEnergy (const SOLARSYS_STATE *solarSys, return GenerateDefault_generateArtifact (solarSys, whichNode, info); } - if (CurStarDescPtr->Index == ORZ_DEFINED + if (CurStarDescPtr->supArg == "Homeworld"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { return GenerateDefault_generateRuins (solarSys, whichNode, info); @@ -191,11 +263,11 @@ GenerateOrz_generateEnergy (const SOLARSYS_STATE *solarSys, return 0; } -static bool -GenerateOrz_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +bool +GenerateOrz::pickupEnergy (SolarSystem *const solarSys, PLANET_DESC *const world, + const COUNT whichNode ) { - if (CurStarDescPtr->Index == TAALO_PROTECTOR_DEFINED + if (CurStarDescPtr->supArg == "Taalo Protector"_a && matchWorld (solarSys, world, 1, 2)) { assert (!GET_GAME_STATE (TAALO_PROTECTOR) && whichNode == 0); @@ -209,7 +281,7 @@ GenerateOrz_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return true; // picked up } - if (CurStarDescPtr->Index == ORZ_DEFINED + if (CurStarDescPtr->supArg == "Homeworld"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { // Standard ruins report diff --git a/sc2/src/uqm/planets/generate/gensol.c b/sc2/src/uqm/planets/generate/gensol-modern.cpp similarity index 89% rename from sc2/src/uqm/planets/generate/gensol.c rename to sc2/src/uqm/planets/generate/gensol-modern.cpp index 2965ab21f..1d4c36e8d 100644 --- a/sc2/src/uqm/planets/generate/gensol.c +++ b/sc2/src/uqm/planets/generate/gensol-modern.cpp @@ -32,50 +32,47 @@ #include "../../starbase.h" -#define KELVIN( t ) ( t - 273 ); -#define DENSITY( d ) ( 100 * ( d / 5.513 ) ); -#define RADIUS( r ) ( 100 * ( r / 6.356 ) ) +namespace +{ + using namespace Planets::exports; + #define KELVIN( t ) ( t - 273 ); + #define DENSITY( d ) ( 100 * ( d / 5.513 ) ); + #define RADIUS( r ) ( 100 * ( r / 6.356 ) ) -static bool GenerateSol_initNpcs (SOLARSYS_STATE *solarSys); -static bool GenerateSol_reinitNpcs (SOLARSYS_STATE *solarSys); -static bool GenerateSol_generatePlanets (SOLARSYS_STATE *solarSys); -static bool GenerateSol_generateMoons (SOLARSYS_STATE *solarSys, - PLANET_DESC *planet); -static bool GenerateSol_generateName (const SOLARSYS_STATE *, - const PLANET_DESC *world); -static bool GenerateSol_generateOrbital (SOLARSYS_STATE *solarSys, - PLANET_DESC *world); -static COUNT GenerateSol_generateEnergy (const SOLARSYS_STATE *, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); -static COUNT GenerateSol_generateLife (const SOLARSYS_STATE *, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); -static bool GenerateSol_pickupEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); + class GenerateSol + : public DefaultGenerator + { + void initNpcs( SolarSystem *solarSys ) override; + void reinitNpcs( SolarSystem *solarSys ) override; + bool generatePlanets( SolarSystem *solarSys ) override; + bool generateMoons( SolarSystem *solarSys, + PLANET_DESC *planet ) override; + bool generateName( const SolarSystem *, + const PLANET_DESC *world ) override; + bool generateOrbital( SolarSystem *solarSys, + PLANET_DESC *world ) override; + COUNT generateEnergy( const SolarSystem *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO * ) override; + COUNT generateLife( const SolarSystem *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO * ) override; + bool pickupEnergy( SolarSystem *solarSys, + PLANET_DESC *world, COUNT whichNode ) override; -static int init_probe (void); -static void check_probe (void); + static int init_probe(); + static void check_probe(); + }; + auto init= [] + { + Generator::add( "Sol", std::make_unique< GenerateSol >() ); -const GenerateFunctions generateSolFunctions = { - /* .initNpcs = */ GenerateSol_initNpcs, - /* .reinitNpcs = */ GenerateSol_reinitNpcs, - /* .uninitNpcs = */ GenerateDefault_uninitNpcs, - /* .generatePlanets = */ GenerateSol_generatePlanets, - /* .generateMoons = */ GenerateSol_generateMoons, - /* .generateName = */ GenerateSol_generateName, - /* .generateOrbital = */ GenerateSol_generateOrbital, - /* .generateMinerals = */ GenerateDefault_generateMinerals, - /* .generateEnergy = */ GenerateSol_generateEnergy, - /* .generateLife = */ GenerateSol_generateLife, - /* .pickupMinerals = */ GenerateDefault_pickupMinerals, - /* .pickupEnergy = */ GenerateSol_pickupEnergy, - /* .pickupLife = */ GenerateDefault_pickupLife, -}; + return 0xDEADBEEF; + }(); +} - -static bool -GenerateSol_initNpcs (SOLARSYS_STATE *solarSys) +void +GenerateSol::initNpcs( SolarSystem *const solarSys ) { GLOBAL (BattleGroupRef) = GET_GAME_STATE_32 (URQUAN_PROBE_GRPOFFS0); if (GLOBAL (BattleGroupRef) == 0) @@ -87,17 +84,15 @@ GenerateSol_initNpcs (SOLARSYS_STATE *solarSys) } if (!init_probe ()) - GenerateDefault_initNpcs (solarSys); - - return true; + DefaultGenerator::initNpcs( solarSys ); } -static bool -GenerateSol_reinitNpcs (SOLARSYS_STATE *solarSys) +void +GenerateSol::reinitNpcs( SolarSystem *const solarSys ) { if (GET_GAME_STATE (CHMMR_BOMB_STATE) != 3) { - GenerateDefault_reinitNpcs (solarSys); + DefaultGenerator::reinitNpcs (solarSys); check_probe (); } else @@ -106,11 +101,10 @@ GenerateSol_reinitNpcs (SOLARSYS_STATE *solarSys) ReinitQueue (&GLOBAL (ip_group_q)); assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); } - return true; } -static bool -GenerateSol_generatePlanets (SOLARSYS_STATE *solarSys) +bool +GenerateSol::generatePlanets( SolarSystem *solarSys ) { COUNT planetI; @@ -203,13 +197,13 @@ GenerateSol_generatePlanets (SOLARSYS_STATE *solarSys) return true; } -static bool -GenerateSol_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet) +bool +GenerateSol::generateMoons( SolarSystem *const solarSys, PLANET_DESC *const planet ) { COUNT planetNr; DWORD rand_val; - GenerateDefault_generateMoons (solarSys, planet); + DefaultGenerator::generateMoons (solarSys, planet); planetNr = planetIndex (solarSys, planet); switch (planetNr) @@ -335,9 +329,9 @@ GenerateSol_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet) return true; } -static bool -GenerateSol_generateName (const SOLARSYS_STATE *solarSys, - const PLANET_DESC *world) +bool +GenerateSol::generateName (const SolarSystem *const solarSys, + const PLANET_DESC *const world ) { COUNT planetNr = planetIndex (solarSys, world); @@ -375,8 +369,8 @@ GenerateSol_generateName (const SOLARSYS_STATE *solarSys, return true; } -static bool -GenerateSol_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) +bool +GenerateSol::generateOrbital( SolarSystem *const solarSys, PLANET_DESC *const world ) { DWORD rand_val; COUNT planetNr; @@ -400,11 +394,11 @@ GenerateSol_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) ReinitQueue (&GLOBAL (ip_group_q)); assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); - CloneShipFragment (ANDROSYNTH_ID, + CloneShipFragment (SYREEN_SHIP, &GLOBAL (npc_built_ship_q), INFINITE_FLEET); GLOBAL (CurrentActivity) |= START_INTERPLANETARY; - InitCommunication( SUPOX_CONVERSATION ); + InitCommunication( ILWRATH_CONVERSATION ); if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))) { @@ -685,9 +679,9 @@ GenerateSol_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) return true; } -static COUNT -GenerateSol_generateEnergy (const SOLARSYS_STATE *solarSys, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) +COUNT +GenerateSol::generateEnergy( const SolarSystem *const solarSys, + const PLANET_DESC *const world, const COUNT whichNode, NODE_INFO *const info) { if (matchWorld (solarSys, world, 9, MATCH_PLANET)) { @@ -731,9 +725,9 @@ GenerateSol_generateEnergy (const SOLARSYS_STATE *solarSys, return 0; } -static bool -GenerateSol_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +bool +GenerateSol::pickupEnergy( SolarSystem *const solarSys, PLANET_DESC *const world, + const COUNT whichNode ) { if (matchWorld (solarSys, world, 9, MATCH_PLANET)) { // Pluto @@ -772,9 +766,9 @@ GenerateSol_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return false; } -static COUNT -GenerateSol_generateLife (const SOLARSYS_STATE *solarSys, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) +COUNT +GenerateSol::generateLife( const SolarSystem *const solarSys, + const PLANET_DESC *const world, const COUNT whichNode, NODE_INFO *const info) { if (matchWorld (solarSys, world, 2, 1)) { @@ -787,8 +781,8 @@ GenerateSol_generateLife (const SOLARSYS_STATE *solarSys, } -static int -init_probe (void) +int +GenerateSol::init_probe() { HIPGROUP hGroup; @@ -813,8 +807,8 @@ init_probe (void) return 0; } -static void -check_probe (void) +void +GenerateSol::check_probe() { HIPGROUP hGroup; IP_GROUP *GroupPtr; diff --git a/sc2/src/uqm/planets/generate/genthrad.c b/sc2/src/uqm/planets/generate/genthrad-modern.cpp similarity index 52% rename from sc2/src/uqm/planets/generate/genthrad.c rename to sc2/src/uqm/planets/generate/genthrad-modern.cpp index 875e5823a..a0ffb2a75 100644 --- a/sc2/src/uqm/planets/generate/genthrad.c +++ b/sc2/src/uqm/planets/generate/genthrad-modern.cpp @@ -30,41 +30,115 @@ #include "../../state.h" #include "libs/mathlib.h" +#include +#include +#include +#include +#include +#include +#include +#include -static bool GenerateThraddash_generatePlanets (SOLARSYS_STATE *solarSys); -static bool GenerateThraddash_generateOrbital (SOLARSYS_STATE *solarSys, - PLANET_DESC *world); -static COUNT GenerateThraddash_generateEnergy (const SOLARSYS_STATE *, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); -static bool GenerateThraddash_pickupEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +namespace +{ + using namespace std::literals::string_literals; + using namespace std::literals::string_view_literals; + using namespace Planets::exports; + + // Because we're more stringy and dynamic... It's possible that the + // supplemental arguments might be spelt wrong in various places. + // + // To help defend against this, the starmap checkers will make sure that + // only entries from this list are used. + // + // Further, I provide a `""_a` string suffix to facilitate C++23 compile + // time checks that each string being used is actually in this list. + // It does (at present) require the discipline to use `_a` suffix in all + // mentions. I can use more weaponized type system tricks to enforce + // that requirement. Some of those tricks require specialized typing + // in the STAR_DESC type... which I can't make C compatible. + // + // The right solution here is an Alepha::Enum. I'll probably be + // able to bring in Alepha soon -- but it's not worth it to + // make this code work like that. Instead, this somewhat peculiar + // merging of generation in this file should be decoupled. + // It mostly seems to exist to share the generation of the + // shattered world in the first planet slot -- after that, it just + // mostly does its own thing with each world. + + constexpr std::array required + { + "Homeworld"sv, + "Aqua Helix"sv, + }; + + constexpr std::string x= "Hello"; + + constexpr bool + checkRequired( const std::string_view s ) + { + return end( required ) != std::find( begin( required ), end( required ), s ); + } + + + consteval std::string_view + operator ""_a( const char *const p, const std::size_t sz ) + { + const std::string_view rv{ p, p + sz }; + if( not checkRequired( rv ) ) + { + throw "The text specified was not one of the required argument strings"; + } + return rv; + }; + + class GenerateThraddash + : public DefaultGenerator + { + bool generatePlanets( SolarSystem *solarSys ) override; + bool generateOrbital( SolarSystem *solarSys, + PLANET_DESC *world ) override; + COUNT generateEnergy( const SolarSystem *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO * ) override; + bool pickupEnergy( SolarSystem *solarSys, + PLANET_DESC *world, COUNT whichNode ) override; + + void + checkSupplementRequirements( const std::optional< std::string > ¶m ) override + { + if( not param.has_value() ) + { + throw std::runtime_error{ "Thraddash solar system did not have any " + "supplementary argument." }; + } + if( not checkRequired( param.value() ) ) + { + throw std::runtime_error{ "Thraddash solar system did not have any valid " + "supplementary argument (was instead: `"s + param.value() + "`)" }; + } + + std::cerr << "World had " << param.value() << " which was a permissible value" + << std::endl; + } + }; + + auto init= [] + { + Generator::add( "Thraddash", std::make_unique< GenerateThraddash >() ); + + return 0xDEADBEEF; + }(); +} -const GenerateFunctions generateThraddashFunctions = { - /* .initNpcs = */ GenerateDefault_initNpcs, - /* .reinitNpcs = */ GenerateDefault_reinitNpcs, - /* .uninitNpcs = */ GenerateDefault_uninitNpcs, - /* .generatePlanets = */ GenerateThraddash_generatePlanets, - /* .generateMoons = */ GenerateDefault_generateMoons, - /* .generateName = */ GenerateDefault_generateName, - /* .generateOrbital = */ GenerateThraddash_generateOrbital, - /* .generateMinerals = */ GenerateDefault_generateMinerals, - /* .generateEnergy = */ GenerateThraddash_generateEnergy, - /* .generateLife = */ GenerateDefault_generateLife, - /* .pickupMinerals = */ GenerateDefault_pickupMinerals, - /* .pickupEnergy = */ GenerateThraddash_pickupEnergy, - /* .pickupLife = */ GenerateDefault_pickupLife, -}; - - -static bool -GenerateThraddash_generatePlanets (SOLARSYS_STATE *solarSys) +bool +GenerateThraddash::generatePlanets( SolarSystem *const solarSys ) { COUNT angle; - GenerateDefault_generatePlanets (solarSys); + DefaultGenerator::generatePlanets (solarSys); - if (CurStarDescPtr->Index == AQUA_HELIX_DEFINED) + if (CurStarDescPtr->supArg == "Aqua Helix"_a) { solarSys->PlanetDesc[0].data_index = PRIMORDIAL_WORLD; solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 65L / 100; @@ -75,7 +149,7 @@ GenerateThraddash_generatePlanets (SOLARSYS_STATE *solarSys) solarSys->PlanetDesc[0].location.y = SINE (angle, solarSys->PlanetDesc[0].radius); } - else /* CurStarDescPtr->Index == THRADD_DEFINED */ + else if( CurStarDescPtr->supArg == "Homeworld"_a ) { solarSys->PlanetDesc[0].data_index = WATER_WORLD; solarSys->PlanetDesc[0].NumPlanets = 0; @@ -87,17 +161,22 @@ GenerateThraddash_generatePlanets (SOLARSYS_STATE *solarSys) solarSys->PlanetDesc[0].location.y = SINE (angle, solarSys->PlanetDesc[0].radius); } + else + { + throw std::runtime_error{ "Unexpected supplement argument `"s + + CurStarDescPtr->supArg + "`" }; + } return true; } -static bool -GenerateThraddash_generateOrbital (SOLARSYS_STATE *solarSys, - PLANET_DESC *world) +bool +GenerateThraddash::generateOrbital( SolarSystem *const solarSys, + PLANET_DESC *const world ) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { if (StartSphereTracking (THRADDASH_SHIP) - && (CurStarDescPtr->Index == THRADD_DEFINED + && (CurStarDescPtr->supArg == "Homeworld"_a || (!GET_GAME_STATE (HELIX_UNPROTECTED) && (BYTE)(GET_GAME_STATE (THRADD_MISSION) - 1) >= 3))) { @@ -110,7 +189,7 @@ GenerateThraddash_generateOrbital (SOLARSYS_STATE *solarSys, INFINITE_FLEET); GLOBAL (CurrentActivity) |= START_INTERPLANETARY; - if (CurStarDescPtr->Index == THRADD_DEFINED) + if (CurStarDescPtr->supArg == "Homeworld"_a) { SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7); } @@ -127,7 +206,7 @@ GenerateThraddash_generateOrbital (SOLARSYS_STATE *solarSys, ReinitQueue (&GLOBAL (npc_built_ship_q)); GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP); - if (CurStarDescPtr->Index == THRADD_DEFINED + if (CurStarDescPtr->supArg == "Homeworld"_a || (!GET_GAME_STATE (HELIX_UNPROTECTED) && (BYTE)(GET_GAME_STATE (THRADD_MISSION) - 1) >= 3)) return true; @@ -135,7 +214,7 @@ GenerateThraddash_generateOrbital (SOLARSYS_STATE *solarSys, RepairSISBorder (); } - if (CurStarDescPtr->Index == AQUA_HELIX_DEFINED + if (CurStarDescPtr->supArg == "Aqua Helix"_a && !GET_GAME_STATE (AQUA_HELIX)) { LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo); @@ -144,7 +223,7 @@ GenerateThraddash_generateOrbital (SOLARSYS_STATE *solarSys, solarSys->SysInfo.PlanetInfo.DiscoveryString = CaptureStringTable (LoadStringTable (AQUA_STRTAB)); } - else if (CurStarDescPtr->Index == THRADD_DEFINED) + else if (CurStarDescPtr->supArg == "Homeworld"_a) { LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo); solarSys->PlanetSideFrame[1] = @@ -154,21 +233,21 @@ GenerateThraddash_generateOrbital (SOLARSYS_STATE *solarSys, } } - GenerateDefault_generateOrbital (solarSys, world); + DefaultGenerator::generateOrbital (solarSys, world); return true; } -static COUNT -GenerateThraddash_generateEnergy (const SOLARSYS_STATE *solarSys, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) +COUNT +GenerateThraddash::generateEnergy( const SolarSystem *const solarSys, + const PLANET_DESC *const world, const COUNT whichNode, NODE_INFO *const info ) { - if (CurStarDescPtr->Index == THRADD_DEFINED + if (CurStarDescPtr->supArg == "Homeworld"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { return GenerateDefault_generateRuins (solarSys, whichNode, info); } - if (CurStarDescPtr->Index == AQUA_HELIX_DEFINED + if (CurStarDescPtr->supArg == "Aqua Helix"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { // This check is redundant since the retrieval bit will keep the @@ -184,11 +263,11 @@ GenerateThraddash_generateEnergy (const SOLARSYS_STATE *solarSys, return 0; } -static bool -GenerateThraddash_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +bool +GenerateThraddash::pickupEnergy( SolarSystem *const solarSys, PLANET_DESC *const world, + const COUNT whichNode ) { - if (CurStarDescPtr->Index == THRADD_DEFINED + if (CurStarDescPtr->supArg == "Homeworld"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { // Standard ruins report @@ -196,7 +275,7 @@ GenerateThraddash_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return false; } - if (CurStarDescPtr->Index == AQUA_HELIX_DEFINED + if (CurStarDescPtr->supArg == "Aqua Helix"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { assert (!GET_GAME_STATE (AQUA_HELIX) && whichNode == 0); diff --git a/sc2/src/uqm/planets/generate/genutw.c b/sc2/src/uqm/planets/generate/genutw-modern.cpp similarity index 55% rename from sc2/src/uqm/planets/generate/genutw.c rename to sc2/src/uqm/planets/generate/genutw-modern.cpp index 71ac2aa49..c96f8c831 100644 --- a/sc2/src/uqm/planets/generate/genutw.c +++ b/sc2/src/uqm/planets/generate/genutw-modern.cpp @@ -30,38 +30,112 @@ #include "../../state.h" #include "libs/mathlib.h" - -static bool GenerateUtwig_initNpcs (SOLARSYS_STATE *solarSys); -static bool GenerateUtwig_generatePlanets (SOLARSYS_STATE *solarSys); -static bool GenerateUtwig_generateOrbital (SOLARSYS_STATE *solarSys, - PLANET_DESC *world); -static COUNT GenerateUtwig_generateEnergy (const SOLARSYS_STATE *, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); -static bool GenerateUtwig_pickupEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); +#include +#include +#include +#include +#include +#include +#include +#include -const GenerateFunctions generateUtwigFunctions = { - /* .initNpcs = */ GenerateUtwig_initNpcs, - /* .reinitNpcs = */ GenerateDefault_reinitNpcs, - /* .uninitNpcs = */ GenerateDefault_uninitNpcs, - /* .generatePlanets = */ GenerateUtwig_generatePlanets, - /* .generateMoons = */ GenerateDefault_generateMoons, - /* .generateName = */ GenerateDefault_generateName, - /* .generateOrbital = */ GenerateUtwig_generateOrbital, - /* .generateMinerals = */ GenerateDefault_generateMinerals, - /* .generateEnergy = */ GenerateUtwig_generateEnergy, - /* .generateLife = */ GenerateDefault_generateLife, - /* .pickupMinerals = */ GenerateDefault_pickupMinerals, - /* .pickupEnergy = */ GenerateUtwig_pickupEnergy, - /* .pickupLife = */ GenerateDefault_pickupLife, -}; - - -static bool -GenerateUtwig_initNpcs (SOLARSYS_STATE *solarSys) +namespace { - if (CurStarDescPtr->Index == BOMB_DEFINED + using namespace std::literals::string_literals; + using namespace std::literals::string_view_literals; + using namespace Planets::exports; + + // Because we're more stringy and dynamic... It's possible that the + // supplemental arguments might be spelt wrong in various places. + // + // To help defend against this, the starmap checkers will make sure that + // only entries from this list are used. + // + // Further, I provide a `""_a` string suffix to facilitate C++23 compile + // time checks that each string being used is actually in this list. + // It does (at present) require the discipline to use `_a` suffix in all + // mentions. I can use more weaponized type system tricks to enforce + // that requirement. Some of those tricks require specialized typing + // in the STAR_DESC type... which I can't make C compatible. + // + // The right solution here is an Alepha::Enum. I'll probably be + // able to bring in Alepha soon -- but it's not worth it to + // make this code work like that. Instead, this somewhat peculiar + // merging of generation in this file should be decoupled. + // It mostly seems to exist to share the generation of the + // shattered world in the first planet slot -- after that, it just + // mostly does its own thing with each world. + + constexpr std::array required + { + "Homeworld"sv, + "Precursor Bomb"sv, + }; + + constexpr std::string x= "Hello"; + + constexpr bool + checkRequired( const std::string_view s ) + { + return end( required ) != std::find( begin( required ), end( required ), s ); + } + + + consteval std::string_view + operator ""_a( const char *const p, const std::size_t sz ) + { + const std::string_view rv{ p, p + sz }; + if( not checkRequired( rv ) ) + { + throw "The text specified was not one of the required argument strings"; + } + return rv; + }; + + class GenerateUtwig + : public DefaultGenerator + { + void initNpcs( SolarSystem *solarSys ) override; + bool generatePlanets( SolarSystem *solarSys ) override; + bool generateOrbital( SolarSystem *solarSys, + PLANET_DESC *world ) override; + COUNT generateEnergy( const SolarSystem *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO * ) override; + bool pickupEnergy( SolarSystem *solarSys, + PLANET_DESC *world, COUNT whichNode ) override; + + void + checkSupplementRequirements( const std::optional< std::string > ¶m ) override + { + if( not param.has_value() ) + { + throw std::runtime_error{ "Utwig solar system did not have any supplementary " + "argument." }; + } + if( not checkRequired( param.value() ) ) + { + throw std::runtime_error{ "Utwig solar system did not have any valid " + "supplementary argument (was instead: `"s + param.value() + "`)" }; + } + + std::cerr << "World had " << param.value() << " which was a permissible value" + << std::endl; + } + }; + + auto init= [] + { + Generator::add( "Utwig", std::make_unique< GenerateUtwig >() ); + return 0xDEADBEEF; + }(); +} + + +void +GenerateUtwig::initNpcs( SolarSystem *const solarSys ) +{ + if (CurStarDescPtr->supArg == "Precursor Bomb"_a && !GET_GAME_STATE (UTWIG_BOMB)) { ReinitQueue (&GLOBAL (ip_group_q)); @@ -69,20 +143,18 @@ GenerateUtwig_initNpcs (SOLARSYS_STATE *solarSys) } else { - GenerateDefault_initNpcs (solarSys); + DefaultGenerator::initNpcs (solarSys); } - - return true; } -static bool -GenerateUtwig_generatePlanets (SOLARSYS_STATE *solarSys) +bool +GenerateUtwig::generatePlanets( SolarSystem *const solarSys ) { COUNT angle; - GenerateDefault_generatePlanets (solarSys); + DefaultGenerator::generatePlanets (solarSys); - if (CurStarDescPtr->Index == UTWIG_DEFINED) + if (CurStarDescPtr->supArg == "Homeworld"_a) { solarSys->PlanetDesc[0].data_index = WATER_WORLD; solarSys->PlanetDesc[0].NumPlanets = 1; @@ -98,16 +170,16 @@ GenerateUtwig_generatePlanets (SOLARSYS_STATE *solarSys) return true; } -static bool -GenerateUtwig_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) +bool +GenerateUtwig::generateOrbital( SolarSystem *const solarSys, PLANET_DESC *const world ) { - if ((CurStarDescPtr->Index == UTWIG_DEFINED + if ((CurStarDescPtr->supArg == "Homeworld"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) - || (CurStarDescPtr->Index == BOMB_DEFINED + || (CurStarDescPtr->supArg == "Precursor Bomb"_a && matchWorld (solarSys, world, 5, 1) && !GET_GAME_STATE (UTWIG_BOMB))) { - if ((CurStarDescPtr->Index == UTWIG_DEFINED + if ((CurStarDescPtr->supArg == "Homeworld"_a || !GET_GAME_STATE (UTWIG_HAVE_ULTRON)) && StartSphereTracking (UTWIG_SHIP)) { @@ -120,7 +192,7 @@ GenerateUtwig_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) &GLOBAL (npc_built_ship_q), INFINITE_FLEET); GLOBAL (CurrentActivity) |= START_INTERPLANETARY; - if (CurStarDescPtr->Index == UTWIG_DEFINED) + if (CurStarDescPtr->supArg == "Homeworld"_a) { SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7); } @@ -139,7 +211,7 @@ GenerateUtwig_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) return true; } - if (CurStarDescPtr->Index == BOMB_DEFINED + if (CurStarDescPtr->supArg == "Precursor Bomb"_a && !GET_GAME_STATE (BOMB_UNPROTECTED) && StartSphereTracking (DRUUGE_SHIP)) { @@ -162,7 +234,7 @@ GenerateUtwig_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) return true; { - BOOLEAN DruugeSurvivors; + bool DruugeSurvivors; DruugeSurvivors = GetHeadLink (&GLOBAL (npc_built_ship_q)) != 0; @@ -179,7 +251,7 @@ GenerateUtwig_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } } - if (CurStarDescPtr->Index == BOMB_DEFINED) + if (CurStarDescPtr->supArg == "Precursor Bomb"_a) { LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo); solarSys->PlanetSideFrame[1] = @@ -197,9 +269,9 @@ GenerateUtwig_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } } - GenerateDefault_generateOrbital (solarSys, world); + DefaultGenerator::generateOrbital (solarSys, world); - if (CurStarDescPtr->Index == UTWIG_DEFINED + if (CurStarDescPtr->supArg == "Homeworld"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { solarSys->SysInfo.PlanetInfo.Weather = 1; @@ -209,17 +281,17 @@ GenerateUtwig_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) return true; } -static COUNT -GenerateUtwig_generateEnergy (const SOLARSYS_STATE *solarSys, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) +COUNT +GenerateUtwig::generateEnergy( const SolarSystem *const solarSys, + const PLANET_DESC *const world, const COUNT whichNode, NODE_INFO *const info ) { - if (CurStarDescPtr->Index == UTWIG_DEFINED + if (CurStarDescPtr->supArg == "Homeworld"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { return GenerateDefault_generateRuins (solarSys, whichNode, info); } - if (CurStarDescPtr->Index == BOMB_DEFINED + if (CurStarDescPtr->supArg == "Precursor Bomb"_a && matchWorld (solarSys, world, 5, 1)) { // This check is redundant since the retrieval bit will keep the @@ -235,11 +307,11 @@ GenerateUtwig_generateEnergy (const SOLARSYS_STATE *solarSys, return 0; } -static bool -GenerateUtwig_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +bool +GenerateUtwig::pickupEnergy( SolarSystem *const solarSys, PLANET_DESC *const world, + const COUNT whichNode ) { - if (CurStarDescPtr->Index == UTWIG_DEFINED + if (CurStarDescPtr->supArg == "Homeworld"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { // Standard ruins report @@ -247,7 +319,7 @@ GenerateUtwig_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return false; } - if (CurStarDescPtr->Index == BOMB_DEFINED + if (CurStarDescPtr->supArg == "Precursor Bomb"_a && matchWorld (solarSys, world, 5, 1)) { assert (!GET_GAME_STATE (UTWIG_BOMB) && whichNode == 0);