From e07f567d764709a976c4be4d170697b3dab0aa24 Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Sun, 28 Apr 2024 03:12:28 -0400 Subject: [PATCH] Added VUX dynamics. --- sc2/src/uqm/gendef.c | 10 +- sc2/src/uqm/plandata.c | 4 +- sc2/src/uqm/planets/generate/Makeinfo | 5 +- .../generate/{genvux.c => genvux-modern.cpp} | 208 ++++++++++++------ 4 files changed, 153 insertions(+), 74 deletions(-) rename sc2/src/uqm/planets/generate/{genvux.c => genvux-modern.cpp} (57%) diff --git a/sc2/src/uqm/gendef.c b/sc2/src/uqm/gendef.c index 3f9b316b8..cc939624f 100644 --- a/sc2/src/uqm/gendef.c +++ b/sc2/src/uqm/gendef.c @@ -26,7 +26,6 @@ extern GenerateFunctions generateOrzFunctions; extern GenerateFunctions generateSolFunctions; extern GenerateFunctions generateThraddashFunctions; extern GenerateFunctions generateUtwigFunctions; -extern GenerateFunctions generateVuxFunctions; const GenerateFunctions * @@ -35,12 +34,15 @@ getGenerateFunctions (STAR_DESC *const star) switch (star->Index) { // Legacy ones are disabled... + case MAIDENS_DEFINED: + case VUX_BEAST_DEFINED: + case VUX_DEFINED: + case SUN_DEVICE_DEFINED: case MYCON_DEFINED: case EGG_CASE0_DEFINED: case EGG_CASE1_DEFINED: case EGG_CASE2_DEFINED: - case MELNORME0_DEFINED: case MELNORME1_DEFINED: case MELNORME2_DEFINED: @@ -86,10 +88,6 @@ getGenerateFunctions (STAR_DESC *const star) case TAALO_PROTECTOR_DEFINED: case ORZ_DEFINED: return &generateOrzFunctions; - case MAIDENS_DEFINED: - case VUX_BEAST_DEFINED: - case VUX_DEFINED: - return &generateVuxFunctions; } } diff --git a/sc2/src/uqm/plandata.c b/sc2/src/uqm/plandata.c index 825436283..d45e99ceb 100644 --- a/sc2/src/uqm/plandata.c +++ b/sc2/src/uqm/plandata.c @@ -554,7 +554,9 @@ STAR_DESC starmap_array[] = {{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}, + {{4333, 1687}, MAKE_STAR (DWARF_STAR, ORANGE_BODY, -1), 0, 2, 88, "VUX", "Homeworld"}, {{3352, 1940}, MAKE_STAR (SUPER_GIANT_STAR, WHITE_BODY, -1), 0, 0, 97, "Melnorme", "2"}, + {{4221, 1986}, MAKE_STAR (DWARF_STAR, BLUE_BODY, -1), 0, 1, 100, "VUX", "ZEX"}, {{6479, 2062}, MAKE_STAR (DWARF_STAR, GREEN_BODY, -1), 0, 3, 71, "Mycon Worlds", "Egg Case 1"}, {{2104, 2083}, MAKE_STAR (DWARF_STAR, ORANGE_BODY, -1), 0, 0, 118, "Zoq-Fot-Pik Scout"}, @@ -595,7 +597,7 @@ STAR_DESC starmap_array[] = {{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"}, {{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}, diff --git a/sc2/src/uqm/planets/generate/Makeinfo b/sc2/src/uqm/planets/generate/Makeinfo index 30f986d88..258cbf46b 100644 --- a/sc2/src/uqm/planets/generate/Makeinfo +++ b/sc2/src/uqm/planets/generate/Makeinfo @@ -1,7 +1,7 @@ uqm_CFILES="gendefault.c genorz.c gensol.c - genthrad.c genutw.c genvux.c" + genthrad.c genutw.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 @@ -10,4 +10,5 @@ uqm_CXXFILES="cxx-generator.cpp gensly-modern.cpp genshof-modern.cpp gentrap-modern.cpp gensup-modern.cpp genspa-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" + genmyc-modern.cpp genrain-modern.cpp genmel-modern.cpp + genvux-modern.cpp" diff --git a/sc2/src/uqm/planets/generate/genvux.c b/sc2/src/uqm/planets/generate/genvux-modern.cpp similarity index 57% rename from sc2/src/uqm/planets/generate/genvux.c rename to sc2/src/uqm/planets/generate/genvux-modern.cpp index d4a0642cb..adfe4774c 100644 --- a/sc2/src/uqm/planets/generate/genvux.c +++ b/sc2/src/uqm/planets/generate/genvux-modern.cpp @@ -32,45 +32,117 @@ #include "../../state.h" #include "libs/mathlib.h" +#include +#include +#include +#include +#include +#include -static bool GenerateVux_generatePlanets (SOLARSYS_STATE *solarSys); -static bool GenerateVux_generateOrbital (SOLARSYS_STATE *solarSys, - PLANET_DESC *world); -static COUNT GenerateVux_generateEnergy (const SOLARSYS_STATE *, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); -static COUNT GenerateVux_generateLife (const SOLARSYS_STATE *, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); -static bool GenerateVux_pickupEnergy (SOLARSYS_STATE *, PLANET_DESC *world, - COUNT whichNode); -static bool GenerateVux_pickupLife (SOLARSYS_STATE *, PLANET_DESC *world, - COUNT whichNode); +namespace +{ + using namespace std::literals::string_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< std::string_view, 3 > required + { + "Homeworld", + "ZEX", + "Beast", + }; + + 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 GenerateVux + : public DefaultGenerator + { + bool generatePlanets (SOLARSYS_STATE *solarSys); + bool generateOrbital (SOLARSYS_STATE *solarSys, + PLANET_DESC *world); + COUNT generateEnergy (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); + COUNT generateLife (const SOLARSYS_STATE *, + const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); + bool pickupEnergy (SOLARSYS_STATE *, PLANET_DESC *world, + COUNT whichNode); + bool pickupLife (SOLARSYS_STATE *, PLANET_DESC *world, + COUNT whichNode); + + void + checkSupplementRequirements( const std::optional< std::string > ¶m ) override + { + if( not param.has_value() ) + { + throw std::runtime_error{ "VUX solar system did not have any supplementary " + "argument." }; + } + if( not checkRequired( param.value() ) ) + { + throw std::runtime_error{ "VUX 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( "VUX", std::make_unique< GenerateVux >() ); + + return 0xDEADBEEF; + }(); +} -const GenerateFunctions generateVuxFunctions = { - /* .initNpcs = */ GenerateDefault_initNpcs, - /* .reinitNpcs = */ GenerateDefault_reinitNpcs, - /* .uninitNpcs = */ GenerateDefault_uninitNpcs, - /* .generatePlanets = */ GenerateVux_generatePlanets, - /* .generateMoons = */ GenerateDefault_generateMoons, - /* .generateName = */ GenerateDefault_generateName, - /* .generateOrbital = */ GenerateVux_generateOrbital, - /* .generateMinerals = */ GenerateDefault_generateMinerals, - /* .generateEnergy = */ GenerateVux_generateEnergy, - /* .generateLife = */ GenerateVux_generateLife, - /* .pickupMinerals = */ GenerateDefault_pickupMinerals, - /* .pickupEnergy = */ GenerateVux_pickupEnergy, - /* .pickupLife = */ GenerateVux_pickupLife, -}; - - -static bool -GenerateVux_generatePlanets (SOLARSYS_STATE *solarSys) +bool +GenerateVux::generatePlanets( SolarSystem *const solarSys ) { COUNT angle; - GenerateDefault_generatePlanets (solarSys); + DefaultGenerator::generatePlanets (solarSys); - if (CurStarDescPtr->Index == MAIDENS_DEFINED) + if (CurStarDescPtr->supArg == "ZEX"_a) { GenerateDefault_generatePlanets (solarSys); // XXX: this is the second time that this function is @@ -87,14 +159,14 @@ GenerateVux_generatePlanets (SOLARSYS_STATE *solarSys) } else { - if (CurStarDescPtr->Index == VUX_DEFINED) + if (CurStarDescPtr->supArg == "Homeworld"_a) { solarSys->PlanetDesc[0].data_index = REDUX_WORLD; solarSys->PlanetDesc[0].NumPlanets = 1; solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 42L / 100; angle = HALF_CIRCLE + OCTANT; } - else /* if (CurStarDescPtr->Index == VUX_BEAST_DEFINED) */ + else if (CurStarDescPtr->supArg == "Beast"_a) { memmove (&solarSys->PlanetDesc[1], &solarSys->PlanetDesc[0], sizeof (solarSys->PlanetDesc[0]) @@ -106,6 +178,7 @@ GenerateVux_generatePlanets (SOLARSYS_STATE *solarSys) solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 110L / 100; solarSys->PlanetDesc[0].NumPlanets = 0; } + else throw std::runtime_error{ "Got unexpected `"s + CurStarDescPtr->supArg + "`" }; solarSys->PlanetDesc[0].location.x = COSINE (angle, solarSys->PlanetDesc[0].radius); @@ -118,12 +191,12 @@ GenerateVux_generatePlanets (SOLARSYS_STATE *solarSys) return true; } -static bool -GenerateVux_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) +bool +GenerateVux::generateOrbital( SolarSystem *const solarSys, PLANET_DESC *const world ) { if ((matchWorld (solarSys, world, 0, MATCH_PLANET) - && (CurStarDescPtr->Index == VUX_DEFINED - || (CurStarDescPtr->Index == MAIDENS_DEFINED + && (CurStarDescPtr->supArg == "Homeworld"_a + || (CurStarDescPtr->supArg == "ZEX"_a && !GET_GAME_STATE (ZEX_IS_DEAD)))) && StartSphereTracking (VUX_SHIP)) { @@ -134,7 +207,7 @@ GenerateVux_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) CloneShipFragment (VUX_SHIP, &GLOBAL (npc_built_ship_q), INFINITE_FLEET); - if (CurStarDescPtr->Index == VUX_DEFINED) + if (CurStarDescPtr->supArg == "Homeworld"_a) { SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7); } @@ -154,7 +227,7 @@ GenerateVux_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) ReinitQueue (&GLOBAL (npc_built_ship_q)); GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP); - if (CurStarDescPtr->Index == VUX_DEFINED + if (CurStarDescPtr->supArg == "Homeworld"_a || !GET_GAME_STATE (ZEX_IS_DEAD)) return true; @@ -164,7 +237,7 @@ GenerateVux_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - if (CurStarDescPtr->Index == MAIDENS_DEFINED) + if (CurStarDescPtr->supArg == "ZEX"_a) { if (!GET_GAME_STATE (SHOFIXTI_MAIDENS)) { @@ -176,7 +249,7 @@ GenerateVux_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) LoadStringTable (MAIDENS_STRTAB)); } } - else if (CurStarDescPtr->Index == VUX_BEAST_DEFINED) + else if (CurStarDescPtr->supArg == "Beast"_a) { if (!GET_GAME_STATE (VUX_BEAST)) { @@ -187,7 +260,7 @@ GenerateVux_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) LoadStringTable (BEAST_STRTAB)); } } - else + else if (CurStarDescPtr->supArg == "Homeworld"_a) { LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo); solarSys->PlanetSideFrame[1] = @@ -195,9 +268,14 @@ GenerateVux_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) solarSys->SysInfo.PlanetInfo.DiscoveryString = CaptureStringTable (LoadStringTable (RUINS_STRTAB)); } + else + { + throw std::runtime_error{ "Unexpected world (`"s + CurStarDescPtr->supArg + + " for landing." }; + } } - GenerateDefault_generateOrbital (solarSys, world); + DefaultGenerator::generateOrbital (solarSys, world); if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { @@ -208,11 +286,11 @@ GenerateVux_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) return true; } -static COUNT -GenerateVux_generateEnergy (const SOLARSYS_STATE *solarSys, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) +COUNT +GenerateVux::generateEnergy( const SolarSystem *const solarSys, + const PLANET_DESC *const world, const COUNT whichNode, NODE_INFO *const info ) { - if (CurStarDescPtr->Index == MAIDENS_DEFINED + if (CurStarDescPtr->supArg == "ZEX"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { // This check is redundant since the retrieval bit will keep the @@ -231,7 +309,7 @@ GenerateVux_generateEnergy (const SOLARSYS_STATE *solarSys, return 1; // only matters when count is requested } - if (CurStarDescPtr->Index == VUX_DEFINED + if (CurStarDescPtr->supArg == "Homeworld"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { return GenerateDefault_generateRuins (solarSys, whichNode, info); @@ -240,11 +318,11 @@ GenerateVux_generateEnergy (const SOLARSYS_STATE *solarSys, return 0; } -static bool -GenerateVux_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +bool +GenerateVux::pickupEnergy( SolarSystem *const solarSys, PLANET_DESC *const world, + const COUNT whichNode ) { - if (CurStarDescPtr->Index == MAIDENS_DEFINED + if (CurStarDescPtr->supArg == "ZEX"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { assert (!GET_GAME_STATE (SHOFIXTI_MAIDENS) && whichNode == 0); @@ -258,7 +336,7 @@ GenerateVux_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return true; // picked up } - if (CurStarDescPtr->Index == VUX_DEFINED + if (CurStarDescPtr->supArg == "Homeworld"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { // Standard ruins report @@ -270,11 +348,11 @@ GenerateVux_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return false; } -static COUNT -GenerateVux_generateLife (const SOLARSYS_STATE *solarSys, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) +COUNT +GenerateVux::generateLife( const SolarSystem *const solarSys, + const PLANET_DESC *const world, const COUNT whichNode, NODE_INFO *const info ) { - if (CurStarDescPtr->Index == MAIDENS_DEFINED + if (CurStarDescPtr->supArg == "ZEX"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { static const SBYTE life[] = @@ -287,7 +365,7 @@ GenerateVux_generateLife (const SOLARSYS_STATE *solarSys, return GeneratePresetLife (&solarSys->SysInfo, life, whichNode, info); } - if (CurStarDescPtr->Index == VUX_BEAST_DEFINED + if (CurStarDescPtr->supArg == "Beast"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { static const SBYTE life[] = @@ -301,14 +379,14 @@ GenerateVux_generateLife (const SOLARSYS_STATE *solarSys, return GeneratePresetLife (&solarSys->SysInfo, life, whichNode, info); } - return GenerateDefault_generateLife (solarSys, world, whichNode, info); + return DefaultGenerator::generateLife (solarSys, world, whichNode, info); } -static bool -GenerateVux_pickupLife (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +bool +GenerateVux::pickupLife( SolarSystem *const solarSys, PLANET_DESC *const world, + const COUNT whichNode) { - if (CurStarDescPtr->Index == VUX_BEAST_DEFINED + if (CurStarDescPtr->supArg == "Beast"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { if (whichNode == 0) @@ -325,5 +403,5 @@ GenerateVux_pickupLife (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return true; // picked up } - return GenerateDefault_pickupLife (solarSys, world, whichNode); + return DefaultGenerator::pickupLife (solarSys, world, whichNode); }