From e9366ac9864c73ed795288aa9daeb56c964641c3 Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Sun, 28 Apr 2024 02:25:23 -0400 Subject: [PATCH] The Mycon worlds are now dynamic. --- sc2/src/uqm/gendef.c | 14 +- sc2/src/uqm/plandata.c | 5 + sc2/src/uqm/planets/generate/Makeinfo | 4 +- .../generate/{genmyc.c => genmyc-modern.cpp} | 228 ++++++++++++------ 4 files changed, 161 insertions(+), 90 deletions(-) rename sc2/src/uqm/planets/generate/{genmyc.c => genmyc-modern.cpp} (51%) diff --git a/sc2/src/uqm/gendef.c b/sc2/src/uqm/gendef.c index 7339af808..3f9b316b8 100644 --- a/sc2/src/uqm/gendef.c +++ b/sc2/src/uqm/gendef.c @@ -22,7 +22,6 @@ #include -extern GenerateFunctions generateMyconFunctions; extern GenerateFunctions generateOrzFunctions; extern GenerateFunctions generateSolFunctions; extern GenerateFunctions generateThraddashFunctions; @@ -36,6 +35,12 @@ getGenerateFunctions (STAR_DESC *const star) switch (star->Index) { // Legacy ones are disabled... + 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: @@ -45,7 +50,6 @@ getGenerateFunctions (STAR_DESC *const star) case MELNORME6_DEFINED: case MELNORME7_DEFINED: case MELNORME8_DEFINED: - case RAINBOW_DEFINED: case SAMATRA_DEFINED: case ILWRATH_DEFINED: @@ -79,12 +83,6 @@ getGenerateFunctions (STAR_DESC *const star) case AQUA_HELIX_DEFINED: case THRADD_DEFINED: return &generateThraddashFunctions; - case SUN_DEVICE_DEFINED: - case MYCON_DEFINED: - case EGG_CASE0_DEFINED: - case EGG_CASE1_DEFINED: - case EGG_CASE2_DEFINED: - return &generateMyconFunctions; case TAALO_PROTECTOR_DEFINED: case ORZ_DEFINED: return &generateOrzFunctions; diff --git a/sc2/src/uqm/plandata.c b/sc2/src/uqm/plandata.c index 99fb260be..825436283 100644 --- a/sc2/src/uqm/plandata.c +++ b/sc2/src/uqm/plandata.c @@ -556,10 +556,15 @@ STAR_DESC starmap_array[] = {{1707, 1501}, MAKE_STAR (DWARF_STAR, GREEN_BODY, -1), 0, 0, 52}, {{3352, 1940}, MAKE_STAR (SUPER_GIANT_STAR, WHITE_BODY, -1), 0, 0, 97, "Melnorme", "2"}, + {{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"}, + {{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"}, {{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"}, + {{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"}, {{6020, 2979}, MAKE_STAR (DWARF_STAR, ORANGE_BODY, -1), 0, 3, 13, "Rainbow"}, diff --git a/sc2/src/uqm/planets/generate/Makeinfo b/sc2/src/uqm/planets/generate/Makeinfo index 5e15d7d1e..30f986d88 100644 --- a/sc2/src/uqm/planets/generate/Makeinfo +++ b/sc2/src/uqm/planets/generate/Makeinfo @@ -1,5 +1,5 @@ uqm_CFILES="gendefault.c - genmyc.c genorz.c + genorz.c gensol.c genthrad.c genutw.c genvux.c" uqm_HFILES="genall.h gendefault.h" @@ -10,4 +10,4 @@ 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 - genrain-modern.cpp genmel-modern.cpp" + genmyc-modern.cpp genrain-modern.cpp genmel-modern.cpp" diff --git a/sc2/src/uqm/planets/generate/genmyc.c b/sc2/src/uqm/planets/generate/genmyc-modern.cpp similarity index 51% rename from sc2/src/uqm/planets/generate/genmyc.c rename to sc2/src/uqm/planets/generate/genmyc-modern.cpp index ead32c71a..acc35ad37 100644 --- a/sc2/src/uqm/planets/generate/genmyc.c +++ b/sc2/src/uqm/planets/generate/genmyc-modern.cpp @@ -31,41 +31,120 @@ #include "../../state.h" #include "libs/mathlib.h" +#include +#include +#include +#include +#include +#include +#include +#include -static bool GenerateMycon_generatePlanets (SOLARSYS_STATE *solarSys); -static bool GenerateMycon_generateOrbital (SOLARSYS_STATE *solarSys, - PLANET_DESC *world); -static COUNT GenerateMycon_generateEnergy (const SOLARSYS_STATE *, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); -static COUNT GenerateMycon_generateLife (const SOLARSYS_STATE *, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *); -static bool GenerateMycon_pickupEnergy (SOLARSYS_STATE *solarSys, - PLANET_DESC *world, COUNT whichNode); - - -const GenerateFunctions generateMyconFunctions = { - /* .initNpcs = */ GenerateDefault_initNpcs, - /* .reinitNpcs = */ GenerateDefault_reinitNpcs, - /* .uninitNpcs = */ GenerateDefault_uninitNpcs, - /* .generatePlanets = */ GenerateMycon_generatePlanets, - /* .generateMoons = */ GenerateDefault_generateMoons, - /* .generateName = */ GenerateDefault_generateName, - /* .generateOrbital = */ GenerateMycon_generateOrbital, - /* .generateMinerals = */ GenerateDefault_generateMinerals, - /* .generateEnergy = */ GenerateMycon_generateEnergy, - /* .generateLife = */ GenerateMycon_generateLife, - /* .pickupMinerals = */ GenerateDefault_pickupMinerals, - /* .pickupEnergy = */ GenerateMycon_pickupEnergy, - /* .pickupLife = */ GenerateDefault_pickupLife, -}; - - -static bool -GenerateMycon_generatePlanets (SOLARSYS_STATE *solarSys) +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, 5 > required + { + "Homeworld", + "Sun Device", + "Egg Case 0", + "Egg Case 1", + "Egg Case 2", + }; + + 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 GenerateMycon + : 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; + COUNT generateLife( 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{ "Mycon solar system did not have any supplementary " + "argument." }; + } + if( not checkRequired( param.value() ) ) + { + throw std::runtime_error{ "Mycon 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( "Mycon Worlds", std::make_unique< GenerateMycon >() ); + + return 0xDEADBEEF; + }(); +} + + +bool +GenerateMycon::generatePlanets( SolarSystem *const solarSys ) +{ + // TODO: This shattered world generator needs to be + // hoisted... + COUNT angle; - GenerateDefault_generatePlanets (solarSys); + DefaultGenerator::generatePlanets (solarSys); solarSys->PlanetDesc[0].data_index = SHATTERED_WORLD; solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 80L / 100; @@ -82,16 +161,16 @@ GenerateMycon_generatePlanets (SOLARSYS_STATE *solarSys) return true; } -static bool -GenerateMycon_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) +bool +GenerateMycon::generateOrbital( SolarSystem *const solarSys, PLANET_DESC *const world ) { if (matchWorld (solarSys, world, 0, MATCH_PLANET)) { - if ((CurStarDescPtr->Index == MYCON_DEFINED - || CurStarDescPtr->Index == SUN_DEVICE_DEFINED) + if ((CurStarDescPtr->supArg == "Homeworld"_a + || CurStarDescPtr->supArg == "Sun Device"_a) && StartSphereTracking (MYCON_SHIP)) { - if (CurStarDescPtr->Index == MYCON_DEFINED + if (CurStarDescPtr->supArg == "Homeworld"_a || !GET_GAME_STATE (SUN_DEVICE_UNGUARDED)) { NotifyOthers (MYCON_SHIP, IPNL_ALL_CLEAR); @@ -99,7 +178,7 @@ GenerateMycon_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) ReinitQueue (&GLOBAL (ip_group_q)); assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); - if (CurStarDescPtr->Index == MYCON_DEFINED + if (CurStarDescPtr->supArg == "Homeworld"_a || !GET_GAME_STATE (MYCON_FELL_FOR_AMBUSH)) { CloneShipFragment (MYCON_SHIP, @@ -115,7 +194,7 @@ GenerateMycon_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } GLOBAL (CurrentActivity) |= START_INTERPLANETARY; - if (CurStarDescPtr->Index == MYCON_DEFINED) + if (CurStarDescPtr->supArg == "Homeworld"_a) { SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7); } @@ -129,7 +208,7 @@ GenerateMycon_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) return true; { - BOOLEAN MyconSurvivors; + bool MyconSurvivors; MyconSurvivors = GetHeadLink (&GLOBAL (npc_built_ship_q)) != 0; @@ -147,9 +226,10 @@ GenerateMycon_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) } } - switch (CurStarDescPtr->Index) + { - case SUN_DEVICE_DEFINED: + if( CurStarDescPtr->supArg == "Sun Device"_a ) + { if (!GET_GAME_STATE (SUN_DEVICE)) { LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo); @@ -160,10 +240,12 @@ GenerateMycon_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) CaptureStringTable ( LoadStringTable (SUN_DEVICE_STRTAB)); } - break; - case EGG_CASE0_DEFINED: - case EGG_CASE1_DEFINED: - case EGG_CASE2_DEFINED: + } + else if( false + or CurStarDescPtr->supArg == "Egg Case 0"_a + or CurStarDescPtr->supArg == "Egg Case 1"_a + or CurStarDescPtr->supArg == "Egg Case 2"_a ) + { if (GET_GAME_STATE (KNOW_ABOUT_SHATTERED) == 0) SET_GAME_STATE (KNOW_ABOUT_SHATTERED, 1); @@ -178,19 +260,19 @@ GenerateMycon_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) CaptureStringTable ( LoadStringTable (EGG_CASE_STRTAB)); } - break; + } } } - GenerateDefault_generateOrbital (solarSys, world); + DefaultGenerator::generateOrbital (solarSys, world); return true; } -static COUNT -GenerateMycon_generateEnergy (const SOLARSYS_STATE *solarSys, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) +COUNT +GenerateMycon::generateEnergy( const SolarSystem *const solarSys, + const PLANET_DESC *const world, const COUNT whichNode, NODE_INFO *const info ) { - if (CurStarDescPtr->Index == SUN_DEVICE_DEFINED + if (CurStarDescPtr->supArg == "Sun Device"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { // This check is redundant since the retrieval bit will keep the @@ -203,9 +285,8 @@ GenerateMycon_generateEnergy (const SOLARSYS_STATE *solarSys, return GenerateDefault_generateArtifact (solarSys, whichNode, info); } - if ((CurStarDescPtr->Index == EGG_CASE0_DEFINED - || CurStarDescPtr->Index == EGG_CASE1_DEFINED - || CurStarDescPtr->Index == EGG_CASE2_DEFINED) + else if (std::set< std::string_view >{ "Egg Case 0"_a, "Egg Case 1"_a, "Egg Case 2"_a } + .count( CurStarDescPtr->supArg ) && matchWorld (solarSys, world, 0, MATCH_PLANET)) { // This check is redundant since the retrieval bit will keep the @@ -223,11 +304,11 @@ GenerateMycon_generateEnergy (const SOLARSYS_STATE *solarSys, return 0; } -static bool -GenerateMycon_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, - COUNT whichNode) +bool +GenerateMycon::pickupEnergy( SolarSystem *const solarSys, PLANET_DESC *const world, + const COUNT whichNode) { - if (CurStarDescPtr->Index == SUN_DEVICE_DEFINED + if (CurStarDescPtr->supArg == "Sun Device"_a && matchWorld (solarSys, world, 0, MATCH_PLANET)) { assert (!GET_GAME_STATE (SUN_DEVICE) && whichNode == 0); @@ -242,9 +323,8 @@ GenerateMycon_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return true; // picked up } - if ((CurStarDescPtr->Index == EGG_CASE0_DEFINED - || CurStarDescPtr->Index == EGG_CASE1_DEFINED - || CurStarDescPtr->Index == EGG_CASE2_DEFINED) + if (std::set{ "Egg Case 0"_a, "Egg Case 1"_a, "Egg Case 2"_a } + .count( CurStarDescPtr->supArg ) && matchWorld (solarSys, world, 0, MATCH_PLANET)) { assert (whichNode == 0); @@ -252,18 +332,11 @@ GenerateMycon_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, GenerateDefault_landerReport (solarSys); SetLanderTakeoff (); - switch (CurStarDescPtr->Index) - { - case EGG_CASE0_DEFINED: - SET_GAME_STATE (EGG_CASE0_ON_SHIP, 1); - break; - case EGG_CASE1_DEFINED: - SET_GAME_STATE (EGG_CASE1_ON_SHIP, 1); - break; - case EGG_CASE2_DEFINED: - SET_GAME_STATE (EGG_CASE2_ON_SHIP, 1); - break; - } + const std::string arg= CurStarDescPtr->supArg; + if( false ); + else if( arg == "Egg Case 0"_a) SET_GAME_STATE (EGG_CASE0_ON_SHIP, 1); + else if( arg == "Egg Case 1"_a) SET_GAME_STATE (EGG_CASE1_ON_SHIP, 1); + else if( arg == "Egg Case 2"_a) SET_GAME_STATE (EGG_CASE2_ON_SHIP, 1); return true; // picked up } @@ -272,15 +345,10 @@ GenerateMycon_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world, return false; } -static COUNT -GenerateMycon_generateLife (const SOLARSYS_STATE *solarSys, - const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info) +COUNT +GenerateMycon::generateLife( const SolarSystem *, const PLANET_DESC *, COUNT, NODE_INFO * ) { // Gee, I wonder why there isn't any life in Mycon systems... - (void) whichNode; - (void) solarSys; - (void) world; - (void) info; return 0; }