summaryrefslogtreecommitdiff
path: root/src/uqm/planets/generate
diff options
context:
space:
mode:
Diffstat (limited to 'src/uqm/planets/generate')
-rw-r--r--src/uqm/planets/generate/Makeinfo6
-rw-r--r--src/uqm/planets/generate/genall.h27
-rw-r--r--src/uqm/planets/generate/genand.c164
-rw-r--r--src/uqm/planets/generate/genburv.c192
-rw-r--r--src/uqm/planets/generate/genchmmr.c154
-rw-r--r--src/uqm/planets/generate/gencol.c126
-rw-r--r--src/uqm/planets/generate/gendefault.c373
-rw-r--r--src/uqm/planets/generate/gendefault.h66
-rw-r--r--src/uqm/planets/generate/gendru.c169
-rw-r--r--src/uqm/planets/generate/genilw.c150
-rw-r--r--src/uqm/planets/generate/genmel.c114
-rw-r--r--src/uqm/planets/generate/genmyc.c286
-rw-r--r--src/uqm/planets/generate/genorz.c222
-rw-r--r--src/uqm/planets/generate/genpet.c257
-rw-r--r--src/uqm/planets/generate/genpku.c159
-rw-r--r--src/uqm/planets/generate/genrain.c102
-rw-r--r--src/uqm/planets/generate/gensam.c324
-rw-r--r--src/uqm/planets/generate/genshof.c178
-rw-r--r--src/uqm/planets/generate/gensly.c70
-rw-r--r--src/uqm/planets/generate/gensol.c671
-rw-r--r--src/uqm/planets/generate/genspa.c283
-rw-r--r--src/uqm/planets/generate/gensup.c159
-rw-r--r--src/uqm/planets/generate/gensyr.c102
-rw-r--r--src/uqm/planets/generate/genthrad.c217
-rw-r--r--src/uqm/planets/generate/gentrap.c80
-rw-r--r--src/uqm/planets/generate/genutw.c269
-rw-r--r--src/uqm/planets/generate/genvault.c130
-rw-r--r--src/uqm/planets/generate/genvux.c329
-rw-r--r--src/uqm/planets/generate/genwreck.c111
-rw-r--r--src/uqm/planets/generate/genyeh.c140
-rw-r--r--src/uqm/planets/generate/genzfpscout.c96
-rw-r--r--src/uqm/planets/generate/genzoq.c170
32 files changed, 5896 insertions, 0 deletions
diff --git a/src/uqm/planets/generate/Makeinfo b/src/uqm/planets/generate/Makeinfo
new file mode 100644
index 0000000..520af9d
--- /dev/null
+++ b/src/uqm/planets/generate/Makeinfo
@@ -0,0 +1,6 @@
+uqm_CFILES="gendefault.c genand.c genburv.c genchmmr.c gencol.c gendru.c
+ genilw.c genmel.c genmyc.c genorz.c genpet.c genpku.c genrain.c
+ gensam.c genshof.c gensly.c gensol.c genspa.c gensup.c gensyr.c
+ genthrad.c gentrap.c genutw.c genvault.c genvux.c genwreck.c
+ genyeh.c genzfpscout.c genzoq.c"
+uqm_HFILES="genall.h gendefault.h"
diff --git a/src/uqm/planets/generate/genall.h b/src/uqm/planets/generate/genall.h
new file mode 100644
index 0000000..3776cff
--- /dev/null
+++ b/src/uqm/planets/generate/genall.h
@@ -0,0 +1,27 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef UQM_PLANETS_GENERATE_GENALL_H_
+#define UQM_PLANETS_GENERATE_GENALL_H_
+
+#include "gendefault.h"
+#include "types.h"
+#include "../generate.h"
+#include "libs/compiler.h"
+
+
+#endif /* UQM_PLANETS_GENERATE_GENALL_H_ */
+
diff --git a/src/uqm/planets/generate/genand.c b/src/uqm/planets/generate/genand.c
new file mode 100644
index 0000000..457b5ff
--- /dev/null
+++ b/src/uqm/planets/generate/genand.c
@@ -0,0 +1,164 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../lander.h"
+#include "../planets.h"
+#include "../scan.h"
+#include "../../globdata.h"
+#include "../../nameref.h"
+#include "../../resinst.h"
+#include "../../sounds.h"
+#include "libs/mathlib.h"
+
+
+static bool GenerateAndrosynth_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateAndrosynth_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+static COUNT GenerateAndrosynth_generateEnergy (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+static bool GenerateAndrosynth_pickupEnergy (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world, COUNT whichNode);
+
+
+const GenerateFunctions generateAndrosynthFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateAndrosynth_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateAndrosynth_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateAndrosynth_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateAndrosynth_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateAndrosynth_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+
+ solarSys->PlanetDesc[1].data_index = TELLURIC_WORLD;
+ solarSys->PlanetDesc[1].radius = EARTH_RADIUS * 204L / 100;
+ angle = ARCTAN (solarSys->PlanetDesc[1].location.x,
+ solarSys->PlanetDesc[1].location.y);
+ solarSys->PlanetDesc[1].location.x =
+ COSINE (angle, solarSys->PlanetDesc[1].radius);
+ solarSys->PlanetDesc[1].location.y =
+ SINE (angle, solarSys->PlanetDesc[1].radius);
+
+ return true;
+}
+
+static bool
+GenerateAndrosynth_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 1, MATCH_PLANET))
+ {
+ COUNT i;
+ COUNT visits = 0;
+
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (RUINS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (
+ LoadStringTable (ANDROSYNTH_RUINS_STRTAB));
+ // Androsynth ruins are a special case. The DiscoveryString contains
+ // several lander reports which form a story. Each report is given
+ // when the player collides with a new city ruin. Ruins previously
+ // visited are marked in the upper 16 bits of ScanRetrieveMask, and
+ // the lower bits are cleared to keep the ruin nodes on the map.
+ for (i = 16; i < 32; ++i)
+ {
+ if (isNodeRetrieved (&solarSys->SysInfo.PlanetInfo, ENERGY_SCAN, i))
+ ++visits;
+ }
+ if (visits >= GetStringTableCount (
+ solarSys->SysInfo.PlanetInfo.DiscoveryString))
+ { // All the reports were already given
+ DestroyStringTable (ReleaseStringTable (
+ solarSys->SysInfo.PlanetInfo.DiscoveryString));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString = 0;
+ }
+ else
+ { // Advance the report sequence to the first unread
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ SetRelStringTableIndex (
+ solarSys->SysInfo.PlanetInfo.DiscoveryString, visits);
+ }
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+
+ if (matchWorld (solarSys, world, 1, MATCH_PLANET))
+ {
+ solarSys->SysInfo.PlanetInfo.AtmoDensity =
+ EARTH_ATMOSPHERE * 144 / 100;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = 28;
+ solarSys->SysInfo.PlanetInfo.Weather = 1;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 1;
+ }
+
+ return true;
+}
+
+static bool
+GenerateAndrosynth_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (matchWorld (solarSys, world, 1, MATCH_PLANET))
+ {
+ PLANET_INFO *planetInfo = &solarSys->SysInfo.PlanetInfo;
+
+ // Ruins previously visited are marked in the upper 16 bits
+ if (isNodeRetrieved (planetInfo, ENERGY_SCAN, whichNode + 16))
+ return false; // already visited this ruin, do not remove
+
+ setNodeRetrieved (planetInfo, ENERGY_SCAN, whichNode + 16);
+ // We set the retrieved bit manually here and need to indicate
+ // the change to the solar system state functions
+ SET_GAME_STATE (PLANETARY_CHANGE, 1);
+
+ // Androsynth ruins have several lander reports which form a story
+ GenerateDefault_landerReportCycle (solarSys);
+
+ return false; // do not remove the node from the surface
+ }
+
+ return false;
+}
+
+static COUNT
+GenerateAndrosynth_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (matchWorld (solarSys, world, 1, MATCH_PLANET))
+ {
+ return GenerateDefault_generateRuins (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
diff --git a/src/uqm/planets/generate/genburv.c b/src/uqm/planets/generate/genburv.c
new file mode 100644
index 0000000..aa5b6bd
--- /dev/null
+++ b/src/uqm/planets/generate/genburv.c
@@ -0,0 +1,192 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../lander.h"
+#include "../planets.h"
+#include "../../globdata.h"
+#include "../../nameref.h"
+#include "../../resinst.h"
+#include "libs/mathlib.h"
+
+
+static bool GenerateBurvixese_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateBurvixese_generateMoons (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *planet);
+static bool GenerateBurvixese_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+static COUNT GenerateBurvixese_generateEnergy (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+static bool GenerateBurvixese_pickupEnergy (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world, COUNT whichNode);
+
+
+const GenerateFunctions generateBurvixeseFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateBurvixese_generatePlanets,
+ /* .generateMoons = */ GenerateBurvixese_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateBurvixese_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateBurvixese_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateBurvixese_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateBurvixese_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+
+ solarSys->PlanetDesc[0].data_index = REDUX_WORLD;
+ solarSys->PlanetDesc[0].NumPlanets = 1;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 39L / 100;
+ angle = ARCTAN (solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+ return true;
+}
+
+static bool
+GenerateBurvixese_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet)
+{
+ GenerateDefault_generateMoons (solarSys, planet);
+
+ if (matchWorld (solarSys, planet, 0, MATCH_PLANET))
+ {
+ COUNT angle;
+ DWORD rand_val;
+
+ solarSys->MoonDesc[0].data_index = SELENIC_WORLD;
+ solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS
+ + (MAX_MOONS - 1) * MOON_DELTA;
+ rand_val = RandomContext_Random (SysGenRNG);
+ angle = NORMALIZE_ANGLE (LOWORD (rand_val));
+ solarSys->MoonDesc[0].location.x =
+ COSINE (angle, solarSys->MoonDesc[0].radius);
+ solarSys->MoonDesc[0].location.y =
+ SINE (angle, solarSys->MoonDesc[0].radius);
+ }
+ return true;
+}
+
+static bool
+GenerateBurvixese_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ DWORD rand_val;
+
+ DoPlanetaryAnalysis (&solarSys->SysInfo, world);
+ rand_val = RandomContext_GetSeed (SysGenRNG);
+
+ solarSys->SysInfo.PlanetInfo.ScanSeed[BIOLOGICAL_SCAN] = rand_val;
+ GenerateLifeForms (&solarSys->SysInfo, GENERATE_ALL, NULL);
+ rand_val = RandomContext_GetSeed (SysGenRNG);
+
+ solarSys->SysInfo.PlanetInfo.ScanSeed[MINERAL_SCAN] = rand_val;
+ GenerateMineralDeposits (&solarSys->SysInfo, GENERATE_ALL, NULL);
+
+ solarSys->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN] = rand_val;
+
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (
+ LoadGraphic (RUINS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (
+ LoadStringTable (BURV_RUINS_STRTAB));
+ solarSys->SysInfo.PlanetInfo.Weather = 0;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 0;
+ }
+ else if (matchWorld (solarSys, world, 0, 0)
+ && !GET_GAME_STATE (BURVIXESE_BROADCASTERS))
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] = CaptureDrawable (
+ LoadGraphic (BURV_BCS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (BURV_BCS_STRTAB));
+ }
+
+ LoadPlanet (NULL);
+
+ return true;
+}
+
+static COUNT
+GenerateBurvixese_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ return GenerateDefault_generateRuins (solarSys, whichNode, info);
+ }
+
+ if (matchWorld (solarSys, world, 0, 0))
+ {
+ // This check is redundant since the retrieval bit will keep the
+ // node from showing up again
+ if (GET_GAME_STATE (BURVIXESE_BROADCASTERS))
+ { // already picked up
+ return 0;
+ }
+
+ return GenerateDefault_generateArtifact (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
+static bool
+GenerateBurvixese_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ // Standard ruins report
+ GenerateDefault_landerReportCycle (solarSys);
+ return false;
+ }
+
+ if (matchWorld (solarSys, world, 0, 0))
+ {
+ assert (!GET_GAME_STATE (BURVIXESE_BROADCASTERS) && whichNode == 0);
+
+ GenerateDefault_landerReport (solarSys);
+ SetLanderTakeoff ();
+
+ SET_GAME_STATE (BURVIXESE_BROADCASTERS, 1);
+ SET_GAME_STATE (BURV_BROADCASTERS_ON_SHIP, 1);
+
+ return true; // picked up
+ }
+
+ (void) whichNode;
+ return false;
+}
diff --git a/src/uqm/planets/generate/genchmmr.c b/src/uqm/planets/generate/genchmmr.c
new file mode 100644
index 0000000..672d977
--- /dev/null
+++ b/src/uqm/planets/generate/genchmmr.c
@@ -0,0 +1,154 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../lander.h"
+#include "../planets.h"
+#include "../../build.h"
+#include "../../comm.h"
+#include "../../globdata.h"
+#include "../../nameref.h"
+#include "../../setup.h"
+#include "../../sounds.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+static bool GenerateChmmr_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateChmmr_generateMoons (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *planet);
+static bool GenerateChmmr_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+
+
+const GenerateFunctions generateChmmrFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateChmmr_generatePlanets,
+ /* .generateMoons = */ GenerateChmmr_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateChmmr_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateDefault_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateDefault_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateChmmr_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ GenerateDefault_generatePlanets (solarSys);
+
+ solarSys->PlanetDesc[1].data_index = SAPPHIRE_WORLD;
+ if (!GET_GAME_STATE (CHMMR_UNLEASHED))
+ solarSys->PlanetDesc[1].data_index |= PLANET_SHIELDED;
+ solarSys->PlanetDesc[1].NumPlanets = 1;
+
+ return true;
+}
+
+static bool
+GenerateChmmr_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet)
+{
+ GenerateDefault_generateMoons (solarSys, planet);
+
+ if (matchWorld (solarSys, planet, 1, MATCH_PLANET))
+ {
+ COUNT angle;
+ DWORD rand_val;
+
+ solarSys->MoonDesc[0].data_index = HIERARCHY_STARBASE;
+ solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS;
+ rand_val = RandomContext_Random (SysGenRNG);
+ angle = NORMALIZE_ANGLE (LOWORD (rand_val));
+ solarSys->MoonDesc[0].location.x =
+ COSINE (angle, solarSys->MoonDesc[0].radius);
+ solarSys->MoonDesc[0].location.y =
+ SINE (angle, solarSys->MoonDesc[0].radius);
+ }
+
+ return true;
+}
+
+static bool
+GenerateChmmr_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 1, MATCH_PLANET))
+ {
+ if (GET_GAME_STATE (CHMMR_UNLEASHED))
+ {
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ InitCommunication (CHMMR_CONVERSATION);
+
+ if (GET_GAME_STATE (CHMMR_BOMB_STATE) == 2)
+ {
+ GLOBAL (CurrentActivity) |= END_INTERPLANETARY;
+ }
+
+ return true;
+ }
+ else if (GET_GAME_STATE (SUN_DEVICE_ON_SHIP)
+ && !GET_GAME_STATE (ILWRATH_DECEIVED)
+ && StartSphereTracking (ILWRATH_SHIP))
+ {
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ CloneShipFragment (ILWRATH_SHIP,
+ &GLOBAL (npc_built_ship_q), INFINITE_FLEET);
+
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 6);
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ InitCommunication (ILWRATH_CONVERSATION);
+
+ if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)))
+ {
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+ }
+
+ return true;
+ }
+ }
+ else if (matchWorld (solarSys, world, 1, 0))
+ {
+ /* Starbase */
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (CHMMR_BASE_STRTAB));
+
+ DoDiscoveryReport (MenuSounds);
+
+ DestroyStringTable (ReleaseStringTable (
+ solarSys->SysInfo.PlanetInfo.DiscoveryString));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString = 0;
+ FreeLanderFont (&solarSys->SysInfo.PlanetInfo);
+
+ return true;
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+
+ return true;
+}
+
diff --git a/src/uqm/planets/generate/gencol.c b/src/uqm/planets/generate/gencol.c
new file mode 100644
index 0000000..27e4d5b
--- /dev/null
+++ b/src/uqm/planets/generate/gencol.c
@@ -0,0 +1,126 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../planets.h"
+#include "../../build.h"
+#include "../../globdata.h"
+#include "../../grpinfo.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+
+static bool GenerateColony_initNpcs (SOLARSYS_STATE *solarSys);
+static bool GenerateColony_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateColony_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+
+
+const GenerateFunctions generateColonyFunctions = {
+ /* .initNpcs = */ GenerateColony_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateColony_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateColony_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateDefault_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateDefault_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateColony_initNpcs (SOLARSYS_STATE *solarSys)
+{
+ HIPGROUP hGroup;
+
+ GLOBAL (BattleGroupRef) = GET_GAME_STATE_32 (COLONY_GRPOFFS0);
+ if (GLOBAL (BattleGroupRef) == 0)
+ {
+ CloneShipFragment (URQUAN_SHIP,
+ &GLOBAL (npc_built_ship_q), 0);
+ GLOBAL (BattleGroupRef) = PutGroupInfo (GROUPS_ADD_NEW, 1);
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ SET_GAME_STATE_32 (COLONY_GRPOFFS0, GLOBAL (BattleGroupRef));
+ }
+
+ GenerateDefault_initNpcs (solarSys);
+
+ if (GLOBAL (BattleGroupRef)
+ && (hGroup = GetHeadLink (&GLOBAL (ip_group_q))))
+ {
+ IP_GROUP *GroupPtr;
+
+ GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ GroupPtr->task = IN_ORBIT;
+ GroupPtr->sys_loc = 0 + 1; /* orbitting colony */
+ GroupPtr->dest_loc = 0 + 1; /* orbitting colony */
+ GroupPtr->loc.x = 0;
+ GroupPtr->loc.y = 0;
+ GroupPtr->group_counter = 0;
+ UnlockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ }
+
+ return true;
+}
+
+static bool
+GenerateColony_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT angle;
+ PLANET_DESC *pMinPlanet;
+
+ pMinPlanet = &solarSys->PlanetDesc[0];
+ FillOrbits (solarSys, (BYTE)~0, pMinPlanet, FALSE);
+
+ pMinPlanet->radius = EARTH_RADIUS * 115L / 100;
+ angle = ARCTAN (pMinPlanet->location.x, pMinPlanet->location.y);
+ pMinPlanet->location.x = COSINE (angle, pMinPlanet->radius);
+ pMinPlanet->location.y = SINE (angle, pMinPlanet->radius);
+ pMinPlanet->data_index = WATER_WORLD | PLANET_SHIELDED;
+
+ return true;
+}
+
+static bool
+GenerateColony_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ DoPlanetaryAnalysis (&solarSys->SysInfo, world);
+
+ solarSys->SysInfo.PlanetInfo.AtmoDensity =
+ EARTH_ATMOSPHERE * 98 / 100;
+ solarSys->SysInfo.PlanetInfo.Weather = 0;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 0;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = 28;
+
+ LoadPlanet (NULL);
+
+ return true;
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+
+ return true;
+}
+
diff --git a/src/uqm/planets/generate/gendefault.c b/src/uqm/planets/generate/gendefault.c
new file mode 100644
index 0000000..a88b89c
--- /dev/null
+++ b/src/uqm/planets/generate/gendefault.c
@@ -0,0 +1,373 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../planets.h"
+#include "../lander.h"
+#include "../../encount.h"
+#include "../../gamestr.h"
+#include "../../globdata.h"
+#include "../../grpinfo.h"
+#include "../../races.h"
+#include "../../state.h"
+#include "../../sounds.h"
+#include "libs/mathlib.h"
+
+
+static void GeneratePlanets (SOLARSYS_STATE *system);
+static void check_yehat_rebellion (void);
+
+
+const GenerateFunctions generateDefaultFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateDefault_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateDefault_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateDefault_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateDefault_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+bool
+GenerateDefault_initNpcs (SOLARSYS_STATE *solarSys)
+{
+ if (!GetGroupInfo (GLOBAL (BattleGroupRef), GROUP_INIT_IP))
+ {
+ GLOBAL (BattleGroupRef) = 0;
+ BuildGroups ();
+ }
+
+ (void) solarSys;
+ return true;
+}
+
+bool
+GenerateDefault_reinitNpcs (SOLARSYS_STATE *solarSys)
+{
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+ // This is not a great place to do the Yehat rebellion check, but
+ // since you can start the rebellion in any star system (not just
+ // the Homeworld), I could not find a better place for it.
+ // At least it is better than where it was originally.
+ check_yehat_rebellion ();
+
+ (void) solarSys;
+ return true;
+}
+
+bool
+GenerateDefault_uninitNpcs (SOLARSYS_STATE *solarSys)
+{
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ ReinitQueue (&GLOBAL (ip_group_q));
+
+ (void) solarSys;
+ return true;
+}
+
+bool
+GenerateDefault_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ FillOrbits (solarSys, (BYTE)~0, solarSys->PlanetDesc, FALSE);
+ GeneratePlanets (solarSys);
+ return true;
+}
+
+bool
+GenerateDefault_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet)
+{
+ FillOrbits (solarSys, planet->NumPlanets, solarSys->MoonDesc, FALSE);
+ return true;
+}
+
+bool
+GenerateDefault_generateName (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world)
+{
+ COUNT i = planetIndex (solarSys, world);
+ utf8StringCopy (GLOBAL_SIS (PlanetName), sizeof (GLOBAL_SIS (PlanetName)),
+ GAME_STRING (PLANET_NUMBER_BASE + (9 + 7) + i));
+ SET_GAME_STATE (BATTLE_PLANET, world->data_index);
+
+ return true;
+}
+
+bool
+GenerateDefault_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ DWORD rand_val;
+ SYSTEM_INFO *sysInfo;
+
+#ifdef DEBUG_SOLARSYS
+ if (worldIsPlanet (solarSys, world))
+ {
+ log_add (log_Debug, "Planet index = %d",
+ planetIndex (solarSys, world));
+ }
+ else
+ {
+ log_add (log_Debug, "Planet index = %d, Moon index = %d",
+ planetIndex (solarSys, world),
+ moonIndex (solarSys, world));
+ }
+#endif /* DEBUG_SOLARSYS */
+
+ sysInfo = &solarSys->SysInfo;
+
+ DoPlanetaryAnalysis (sysInfo, world);
+ rand_val = RandomContext_GetSeed (SysGenRNG);
+
+ sysInfo->PlanetInfo.ScanSeed[BIOLOGICAL_SCAN] = rand_val;
+ GenerateLifeForms (sysInfo, GENERATE_ALL, NULL);
+ rand_val = RandomContext_GetSeed (SysGenRNG);
+
+ sysInfo->PlanetInfo.ScanSeed[MINERAL_SCAN] = rand_val;
+ GenerateMineralDeposits (sysInfo, GENERATE_ALL, NULL);
+
+ sysInfo->PlanetInfo.ScanSeed[ENERGY_SCAN] = rand_val;
+ LoadPlanet (NULL);
+
+ return true;
+}
+
+COUNT
+GenerateDefault_generateMinerals (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ return GenerateMineralDeposits (&solarSys->SysInfo, whichNode, info);
+ (void) world;
+}
+
+bool
+GenerateDefault_pickupMinerals (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ // Minerals do not need any extra handling as of now
+ (void) solarSys;
+ (void) world;
+ (void) whichNode;
+ return true;
+}
+
+COUNT
+GenerateDefault_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ (void) whichNode;
+ (void) solarSys;
+ (void) world;
+ (void) info;
+ return 0;
+}
+
+bool
+GenerateDefault_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ // This should never be called since every energy node needs
+ // special handling and the function should be overridden
+ assert (false);
+ (void) solarSys;
+ (void) world;
+ (void) whichNode;
+ return false;
+}
+
+COUNT
+GenerateDefault_generateLife (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ return GenerateLifeForms (&solarSys->SysInfo, whichNode, info);
+ (void) world;
+}
+
+bool
+GenerateDefault_pickupLife (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ // Bio does not need any extra handling as of now
+ (void) solarSys;
+ (void) world;
+ (void) whichNode;
+ return true;
+}
+
+COUNT
+GenerateDefault_generateArtifact (const SOLARSYS_STATE *solarSys,
+ COUNT whichNode, NODE_INFO *info)
+{
+ // Generate an energy node at a random location
+ return GenerateRandomNodes (&solarSys->SysInfo, ENERGY_SCAN, 1, 0,
+ whichNode, info);
+}
+
+COUNT
+GenerateDefault_generateRuins (const SOLARSYS_STATE *solarSys,
+ COUNT whichNode, NODE_INFO *info)
+{
+ // Generate a standard spread of city ruins of a destroyed civilization
+ return GenerateRandomNodes (&solarSys->SysInfo, ENERGY_SCAN, NUM_RACE_RUINS,
+ 0, whichNode, info);
+}
+
+static inline void
+runLanderReport (void)
+{
+ UnbatchGraphics ();
+ DoDiscoveryReport (MenuSounds);
+ BatchGraphics ();
+}
+
+bool
+GenerateDefault_landerReport (SOLARSYS_STATE *solarSys)
+{
+ PLANET_INFO *planetInfo = &solarSys->SysInfo.PlanetInfo;
+
+ if (!planetInfo->DiscoveryString)
+ return false;
+
+ runLanderReport ();
+
+ // XXX: A non-cycling report is given only once and has to be deleted
+ // in some circumstances (like the Syreen Vault). It does not
+ // hurt to simply delete it in all cases. Nothing should rely on
+ // the presence of DiscoveryString, but the Syreen Vault and the
+ // Mycon Egg Cases rely on its absence.
+ DestroyStringTable (ReleaseStringTable (planetInfo->DiscoveryString));
+ planetInfo->DiscoveryString = 0;
+
+ return true;
+}
+
+bool
+GenerateDefault_landerReportCycle (SOLARSYS_STATE *solarSys)
+{
+ PLANET_INFO *planetInfo = &solarSys->SysInfo.PlanetInfo;
+
+ if (!planetInfo->DiscoveryString)
+ return false;
+
+ runLanderReport ();
+ // Advance to the next report
+ planetInfo->DiscoveryString = SetRelStringTableIndex (
+ planetInfo->DiscoveryString, 1);
+
+ // If our discovery strings have cycled, we're done
+ if (GetStringTableIndex (planetInfo->DiscoveryString) == 0)
+ {
+ DestroyStringTable (ReleaseStringTable (planetInfo->DiscoveryString));
+ planetInfo->DiscoveryString = 0;
+ }
+
+ return true;
+}
+
+// NB. This function modifies the RNG state.
+static void
+GeneratePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT i;
+ PLANET_DESC *planet;
+
+ for (i = solarSys->SunDesc[0].NumPlanets,
+ planet = &solarSys->PlanetDesc[0]; i; --i, ++planet)
+ {
+ DWORD rand_val;
+ BYTE byte_val;
+ BYTE num_moons;
+ BYTE type;
+
+ rand_val = RandomContext_Random (SysGenRNG);
+ byte_val = LOBYTE (rand_val);
+
+ num_moons = 0;
+ type = PlanData[planet->data_index & ~PLANET_SHIELDED].Type;
+ switch (PLANSIZE (type))
+ {
+ case LARGE_ROCKY_WORLD:
+ if (byte_val < 0x00FF * 25 / 100)
+ {
+ if (byte_val < 0x00FF * 5 / 100)
+ ++num_moons;
+ ++num_moons;
+ }
+ break;
+ case GAS_GIANT:
+ if (byte_val < 0x00FF * 90 / 100)
+ {
+ if (byte_val < 0x00FF * 75 / 100)
+ {
+ if (byte_val < 0x00FF * 50 / 100)
+ {
+ if (byte_val < 0x00FF * 25 / 100)
+ ++num_moons;
+ ++num_moons;
+ }
+ ++num_moons;
+ }
+ ++num_moons;
+ }
+ break;
+ }
+ planet->NumPlanets = num_moons;
+ }
+}
+
+static void
+check_yehat_rebellion (void)
+{
+ HIPGROUP hGroup, hNextGroup;
+
+ // XXX: Is there a better way to do this? I could not find one.
+ // When you talk to a Yehat ship (YEHAT_SHIP) and start the rebellion,
+ // there is no battle following the comm. There is *never* a battle in
+ // an encounter with Rebels, but the group race_id (YEHAT_REBEL_SHIP)
+ // is different from Royalists (YEHAT_SHIP). There is *always* a battle
+ // in an encounter with Royalists.
+ // TRANSLATION: "If the civil war has not started yet, or the player
+ // battled a ship -- bail."
+ if (!GET_GAME_STATE (YEHAT_CIVIL_WAR) || EncounterRace >= 0)
+ return; // not this time
+
+ // Send Yehat groups to flee the system, but only if the player
+ // has actually talked to a ship.
+ for (hGroup = GetHeadLink (&GLOBAL (ip_group_q)); hGroup;
+ hGroup = hNextGroup)
+ {
+ IP_GROUP *GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ hNextGroup = _GetSuccLink (GroupPtr);
+ // IGNORE_FLAGSHIP was set in ipdisp.c:ip_group_collision()
+ // during a collision with the flagship.
+ if (GroupPtr->race_id == YEHAT_SHIP
+ && (GroupPtr->task & IGNORE_FLAGSHIP))
+ {
+ GroupPtr->task &= REFORM_GROUP;
+ GroupPtr->task |= FLEE | IGNORE_FLAGSHIP;
+ GroupPtr->dest_loc = 0;
+ }
+ UnlockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ }
+}
+
+
diff --git a/src/uqm/planets/generate/gendefault.h b/src/uqm/planets/generate/gendefault.h
new file mode 100644
index 0000000..a6d0e71
--- /dev/null
+++ b/src/uqm/planets/generate/gendefault.h
@@ -0,0 +1,66 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GENDEFAULT_H
+#define GENDEFAULT_H
+
+#include "types.h"
+#include "../planets.h"
+#include "libs/compiler.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+bool GenerateDefault_initNpcs (SOLARSYS_STATE *solarSys);
+bool GenerateDefault_reinitNpcs (SOLARSYS_STATE *solarSys);
+bool GenerateDefault_uninitNpcs (SOLARSYS_STATE *solarSys);
+bool GenerateDefault_generatePlanets (SOLARSYS_STATE *solarSys);
+bool GenerateDefault_generateMoons (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *planet);
+bool GenerateDefault_generateName (const SOLARSYS_STATE *,
+ const PLANET_DESC *world);
+bool GenerateDefault_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+COUNT GenerateDefault_generateMinerals (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+COUNT GenerateDefault_generateEnergy (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+COUNT GenerateDefault_generateLife (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+bool GenerateDefault_pickupMinerals (SOLARSYS_STATE *, PLANET_DESC *world,
+ COUNT whichNode);
+bool GenerateDefault_pickupEnergy (SOLARSYS_STATE *, PLANET_DESC *world,
+ COUNT whichNode);
+bool GenerateDefault_pickupLife (SOLARSYS_STATE *, PLANET_DESC *world,
+ COUNT whichNode);
+
+COUNT GenerateDefault_generateArtifact (const SOLARSYS_STATE *,
+ COUNT whichNode, NODE_INFO *info);
+COUNT GenerateDefault_generateRuins (const SOLARSYS_STATE *,
+ COUNT whichNode, NODE_INFO *info);
+bool GenerateDefault_landerReport (SOLARSYS_STATE *);
+bool GenerateDefault_landerReportCycle (SOLARSYS_STATE *);
+
+
+extern const GenerateFunctions generateDefaultFunctions;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* GENDEFAULT_H */
+
diff --git a/src/uqm/planets/generate/gendru.c b/src/uqm/planets/generate/gendru.c
new file mode 100644
index 0000000..7202010
--- /dev/null
+++ b/src/uqm/planets/generate/gendru.c
@@ -0,0 +1,169 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../lander.h"
+#include "../planets.h"
+#include "../../build.h"
+#include "../../comm.h"
+#include "../../globdata.h"
+#include "../../ipdisp.h"
+#include "../../nameref.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+#include <string.h>
+
+
+static bool GenerateDruuge_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateDruuge_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+static COUNT GenerateDruuge_generateEnergy (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+static bool GenerateDruuge_pickupEnergy (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world, COUNT whichNode);
+
+
+const GenerateFunctions generateDruugeFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateDruuge_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateDruuge_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateDruuge_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateDruuge_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateDruuge_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+
+ memmove (&solarSys->PlanetDesc[1], &solarSys->PlanetDesc[0],
+ sizeof (solarSys->PlanetDesc[0])
+ * solarSys->SunDesc[0].NumPlanets);
+ ++solarSys->SunDesc[0].NumPlanets;
+
+ solarSys->PlanetDesc[0].data_index = DUST_WORLD;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 50L / 100;
+ solarSys->PlanetDesc[0].NumPlanets = 0;
+ angle = HALF_CIRCLE - OCTANT;
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].rand_seed = MAKE_DWORD (
+ solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+
+ return true;
+}
+
+static bool
+GenerateDruuge_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ if (StartSphereTracking (DRUUGE_SHIP))
+ {
+ NotifyOthers (DRUUGE_SHIP, IPNL_ALL_CLEAR);
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ CloneShipFragment (DRUUGE_SHIP,
+ &GLOBAL (npc_built_ship_q), INFINITE_FLEET);
+
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ InitCommunication (DRUUGE_CONVERSATION);
+ if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)))
+ {
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+ }
+ return true;
+ }
+ else
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (RUINS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (
+ LoadStringTable (DRUUGE_RUINS_STRTAB));
+ if (GET_GAME_STATE (ROSY_SPHERE))
+ { // Already picked up Rosy Sphere, skip the report
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ SetAbsStringTableIndex (
+ solarSys->SysInfo.PlanetInfo.DiscoveryString, 1);
+ }
+ }
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+
+ return true;
+}
+
+static bool
+GenerateDruuge_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ GenerateDefault_landerReportCycle (solarSys);
+
+ // The artifact can be picked up from any ruin
+ if (!GET_GAME_STATE (ROSY_SPHERE))
+ { // Just picked up the Rosy Sphere from a ruin
+ SetLanderTakeoff ();
+
+ SET_GAME_STATE (ROSY_SPHERE, 1);
+ SET_GAME_STATE (ROSY_SPHERE_ON_SHIP, 1);
+ }
+
+ return false; // do not remove the node
+ }
+
+ (void) whichNode;
+ return false;
+}
+
+static COUNT
+GenerateDruuge_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ return GenerateDefault_generateRuins (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
diff --git a/src/uqm/planets/generate/genilw.c b/src/uqm/planets/generate/genilw.c
new file mode 100644
index 0000000..31a8fc4
--- /dev/null
+++ b/src/uqm/planets/generate/genilw.c
@@ -0,0 +1,150 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../planets.h"
+#include "../../build.h"
+#include "../../comm.h"
+#include "../../globdata.h"
+#include "../../ipdisp.h"
+#include "../../nameref.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+
+static bool GenerateIlwrath_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateIlwrath_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+static COUNT GenerateIlwrath_generateEnergy (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+static bool GenerateIlwrath_pickupEnergy (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world, COUNT whichNode);
+
+
+const GenerateFunctions generateIlwrathFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateIlwrath_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateIlwrath_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateIlwrath_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateIlwrath_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateIlwrath_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+
+ solarSys->PlanetDesc[0].data_index = PRIMORDIAL_WORLD;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 204L / 100;
+ angle = ARCTAN (
+ solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+
+ return true;
+}
+
+static bool
+GenerateIlwrath_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ if (StartSphereTracking (ILWRATH_SHIP))
+ {
+ NotifyOthers (ILWRATH_SHIP, IPNL_ALL_CLEAR);
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ CloneShipFragment (ILWRATH_SHIP,
+ &GLOBAL (npc_built_ship_q), INFINITE_FLEET);
+
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ InitCommunication (ILWRATH_CONVERSATION);
+
+ if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)))
+ {
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+ }
+ return true;
+ }
+ else
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (
+ LoadGraphic (RUINS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (RUINS_STRTAB));
+ }
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ solarSys->SysInfo.PlanetInfo.Weather = 2;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 3;
+ }
+
+ return true;
+}
+
+static COUNT
+GenerateIlwrath_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ return GenerateDefault_generateRuins (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
+static bool
+GenerateIlwrath_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ // Standard ruins report
+ GenerateDefault_landerReportCycle (solarSys);
+ return false;
+ }
+
+ (void) whichNode;
+ return false;
+}
diff --git a/src/uqm/planets/generate/genmel.c b/src/uqm/planets/generate/genmel.c
new file mode 100644
index 0000000..27f31b6
--- /dev/null
+++ b/src/uqm/planets/generate/genmel.c
@@ -0,0 +1,114 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../../build.h"
+#include "../../gendef.h"
+#include "../../starmap.h"
+#include "../../globdata.h"
+#include "../../state.h"
+#include "libs/log.h"
+
+
+static bool GenerateMelnorme_initNpcs (SOLARSYS_STATE *solarSys);
+
+static int SelectMelnormeRefVar (void);
+static DWORD GetMelnormeRef (void);
+static void SetMelnormeRef (DWORD Ref);
+
+
+const GenerateFunctions generateMelnormeFunctions = {
+ /* .initNpcs = */ GenerateMelnorme_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateDefault_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateDefault_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateDefault_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateDefault_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateMelnorme_initNpcs (SOLARSYS_STATE *solarSys)
+{
+ GLOBAL (BattleGroupRef) = GetMelnormeRef ();
+ if (GLOBAL (BattleGroupRef) == 0)
+ {
+ CloneShipFragment (MELNORME_SHIP, &GLOBAL (npc_built_ship_q), 0);
+ GLOBAL (BattleGroupRef) = PutGroupInfo (GROUPS_ADD_NEW, 1);
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ SetMelnormeRef (GLOBAL (BattleGroupRef));
+ }
+
+ GenerateDefault_initNpcs (solarSys);
+
+ return true;
+}
+
+
+static int
+SelectMelnormeRefVar (void)
+{
+ switch (CurStarDescPtr->Index)
+ {
+ case MELNORME0_DEFINED: return MELNORME0_GRPOFFS0;
+ case MELNORME1_DEFINED: return MELNORME1_GRPOFFS0;
+ case MELNORME2_DEFINED: return MELNORME2_GRPOFFS0;
+ case MELNORME3_DEFINED: return MELNORME3_GRPOFFS0;
+ case MELNORME4_DEFINED: return MELNORME4_GRPOFFS0;
+ case MELNORME5_DEFINED: return MELNORME5_GRPOFFS0;
+ case MELNORME6_DEFINED: return MELNORME6_GRPOFFS0;
+ case MELNORME7_DEFINED: return MELNORME7_GRPOFFS0;
+ case MELNORME8_DEFINED: return MELNORME8_GRPOFFS0;
+ default:
+ return -1;
+ }
+}
+
+static DWORD
+GetMelnormeRef (void)
+{
+ int RefVar = SelectMelnormeRefVar ();
+ if (RefVar < 0)
+ {
+ log_add (log_Warning, "GetMelnormeRef(): reference unknown");
+ return 0;
+ }
+
+ return GET_GAME_STATE_32 (RefVar);
+}
+
+static void
+SetMelnormeRef (DWORD Ref)
+{
+ int RefVar = SelectMelnormeRefVar ();
+ if (RefVar < 0)
+ {
+ log_add (log_Warning, "SetMelnormeRef(): reference unknown");
+ return;
+ }
+
+ SET_GAME_STATE_32 (RefVar, Ref);
+}
+
diff --git a/src/uqm/planets/generate/genmyc.c b/src/uqm/planets/generate/genmyc.c
new file mode 100644
index 0000000..ead32c7
--- /dev/null
+++ b/src/uqm/planets/generate/genmyc.c
@@ -0,0 +1,286 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../lander.h"
+#include "../planets.h"
+#include "../scan.h"
+#include "../../build.h"
+#include "../../comm.h"
+#include "../../gendef.h"
+#include "../../starmap.h"
+#include "../../globdata.h"
+#include "../../ipdisp.h"
+#include "../../nameref.h"
+#include "../../setup.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+
+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)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+
+ solarSys->PlanetDesc[0].data_index = SHATTERED_WORLD;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 80L / 100;
+ if (solarSys->PlanetDesc[0].NumPlanets > 2)
+ solarSys->PlanetDesc[0].NumPlanets = 2;
+ angle = ARCTAN (
+ solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+
+ return true;
+}
+
+static bool
+GenerateMycon_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ if ((CurStarDescPtr->Index == MYCON_DEFINED
+ || CurStarDescPtr->Index == SUN_DEVICE_DEFINED)
+ && StartSphereTracking (MYCON_SHIP))
+ {
+ if (CurStarDescPtr->Index == MYCON_DEFINED
+ || !GET_GAME_STATE (SUN_DEVICE_UNGUARDED))
+ {
+ NotifyOthers (MYCON_SHIP, IPNL_ALL_CLEAR);
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ if (CurStarDescPtr->Index == MYCON_DEFINED
+ || !GET_GAME_STATE (MYCON_FELL_FOR_AMBUSH))
+ {
+ CloneShipFragment (MYCON_SHIP,
+ &GLOBAL (npc_built_ship_q), INFINITE_FLEET);
+ }
+ else
+ {
+ COUNT i;
+
+ for (i = 0; i < 5; ++i)
+ CloneShipFragment (MYCON_SHIP,
+ &GLOBAL (npc_built_ship_q), 0);
+ }
+
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ if (CurStarDescPtr->Index == MYCON_DEFINED)
+ {
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ }
+ else
+ {
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 6);
+ }
+ InitCommunication (MYCON_CONVERSATION);
+
+ if (GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))
+ return true;
+
+ {
+ BOOLEAN MyconSurvivors;
+
+ MyconSurvivors =
+ GetHeadLink (&GLOBAL (npc_built_ship_q)) != 0;
+
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+
+ if (MyconSurvivors)
+ return true;
+
+ SET_GAME_STATE (SUN_DEVICE_UNGUARDED, 1);
+ RepairSISBorder ();
+ }
+ }
+ }
+
+ switch (CurStarDescPtr->Index)
+ {
+ case SUN_DEVICE_DEFINED:
+ if (!GET_GAME_STATE (SUN_DEVICE))
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (
+ LoadGraphic (SUN_DEVICE_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (
+ LoadStringTable (SUN_DEVICE_STRTAB));
+ }
+ break;
+ case EGG_CASE0_DEFINED:
+ case EGG_CASE1_DEFINED:
+ case EGG_CASE2_DEFINED:
+ if (GET_GAME_STATE (KNOW_ABOUT_SHATTERED) == 0)
+ SET_GAME_STATE (KNOW_ABOUT_SHATTERED, 1);
+
+ if (!isNodeRetrieved (&solarSys->SysInfo.PlanetInfo,
+ ENERGY_SCAN, 0))
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (
+ LoadGraphic (EGG_CASE_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (
+ LoadStringTable (EGG_CASE_STRTAB));
+ }
+ break;
+ }
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+ return true;
+}
+
+static COUNT
+GenerateMycon_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (CurStarDescPtr->Index == SUN_DEVICE_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ // This check is redundant since the retrieval bit will keep the
+ // node from showing up again
+ if (GET_GAME_STATE (SUN_DEVICE))
+ { // already picked up
+ return 0;
+ }
+
+ return GenerateDefault_generateArtifact (solarSys, whichNode, info);
+ }
+
+ if ((CurStarDescPtr->Index == EGG_CASE0_DEFINED
+ || CurStarDescPtr->Index == EGG_CASE1_DEFINED
+ || CurStarDescPtr->Index == EGG_CASE2_DEFINED)
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ // This check is redundant since the retrieval bit will keep the
+ // node from showing up again
+ // XXX: DiscoveryString is set by generateOrbital() only when the
+ // node has not been picked up yet
+ if (!solarSys->SysInfo.PlanetInfo.DiscoveryString)
+ { // already picked up
+ return 0;
+ }
+
+ return GenerateDefault_generateArtifact (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
+static bool
+GenerateMycon_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (CurStarDescPtr->Index == SUN_DEVICE_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ assert (!GET_GAME_STATE (SUN_DEVICE) && whichNode == 0);
+
+ GenerateDefault_landerReport (solarSys);
+ SetLanderTakeoff ();
+
+ SET_GAME_STATE (SUN_DEVICE, 1);
+ SET_GAME_STATE (SUN_DEVICE_ON_SHIP, 1);
+ SET_GAME_STATE (MYCON_VISITS, 0);
+
+ return true; // picked up
+ }
+
+ if ((CurStarDescPtr->Index == EGG_CASE0_DEFINED
+ || CurStarDescPtr->Index == EGG_CASE1_DEFINED
+ || CurStarDescPtr->Index == EGG_CASE2_DEFINED)
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ assert (whichNode == 0);
+
+ 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;
+ }
+
+ return true; // picked up
+ }
+
+ (void) whichNode;
+ return false;
+}
+
+static COUNT
+GenerateMycon_generateLife (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ // Gee, I wonder why there isn't any life in Mycon systems...
+ (void) whichNode;
+ (void) solarSys;
+ (void) world;
+ (void) info;
+ return 0;
+}
+
diff --git a/src/uqm/planets/generate/genorz.c b/src/uqm/planets/generate/genorz.c
new file mode 100644
index 0000000..a50f318
--- /dev/null
+++ b/src/uqm/planets/generate/genorz.c
@@ -0,0 +1,222 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../lander.h"
+#include "../planets.h"
+#include "../../build.h"
+#include "../../comm.h"
+#include "../../gendef.h"
+#include "../../starmap.h"
+#include "../../globdata.h"
+#include "../../ipdisp.h"
+#include "../../nameref.h"
+#include "../../setup.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+
+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);
+
+
+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)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+
+ if (CurStarDescPtr->Index == ORZ_DEFINED)
+ {
+ solarSys->PlanetDesc[0].data_index = WATER_WORLD;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 156L / 100;
+ solarSys->PlanetDesc[0].NumPlanets = 0;
+ angle = ARCTAN (solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+ }
+
+ return true;
+}
+
+static bool
+GenerateOrz_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if ((CurStarDescPtr->Index == ORZ_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ || (CurStarDescPtr->Index == TAALO_PROTECTOR_DEFINED
+ && matchWorld (solarSys, world, 1, 2)
+ && !GET_GAME_STATE (TAALO_PROTECTOR)))
+ {
+ COUNT i;
+
+ if ((CurStarDescPtr->Index == ORZ_DEFINED
+ || !GET_GAME_STATE (TAALO_UNPROTECTED))
+ && StartSphereTracking (ORZ_SHIP))
+ {
+ NotifyOthers (ORZ_SHIP, IPNL_ALL_CLEAR);
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ if (CurStarDescPtr->Index == ORZ_DEFINED)
+ {
+ CloneShipFragment (ORZ_SHIP,
+ &GLOBAL (npc_built_ship_q), INFINITE_FLEET);
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ }
+ else
+ {
+ for (i = 0; i < 14; ++i)
+ {
+ CloneShipFragment (ORZ_SHIP,
+ &GLOBAL (npc_built_ship_q), 0);
+ }
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 6);
+ }
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ InitCommunication (ORZ_CONVERSATION);
+
+ if (GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))
+ return true;
+
+ {
+ BOOLEAN OrzSurvivors;
+
+ OrzSurvivors = GetHeadLink (&GLOBAL (npc_built_ship_q))
+ && (CurStarDescPtr->Index == ORZ_DEFINED
+ || !GET_GAME_STATE (TAALO_UNPROTECTED));
+
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+
+ if (OrzSurvivors)
+ return true;
+
+ RepairSISBorder ();
+ }
+ }
+
+ SET_GAME_STATE (TAALO_UNPROTECTED, 1);
+ if (CurStarDescPtr->Index == TAALO_PROTECTOR_DEFINED)
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (
+ LoadGraphic (TAALO_DEVICE_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (
+ LoadStringTable (TAALO_DEVICE_STRTAB));
+ }
+ else
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (RUINS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (RUINS_STRTAB));
+ }
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+
+ return true;
+}
+
+static COUNT
+GenerateOrz_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (CurStarDescPtr->Index == TAALO_PROTECTOR_DEFINED
+ && matchWorld (solarSys, world, 1, 2))
+ {
+ // This check is redundant since the retrieval bit will keep the
+ // node from showing up again
+ if (GET_GAME_STATE (TAALO_PROTECTOR))
+ { // already picked up
+ return 0;
+ }
+
+ return GenerateDefault_generateArtifact (solarSys, whichNode, info);
+ }
+
+ if (CurStarDescPtr->Index == ORZ_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ return GenerateDefault_generateRuins (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
+static bool
+GenerateOrz_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (CurStarDescPtr->Index == TAALO_PROTECTOR_DEFINED
+ && matchWorld (solarSys, world, 1, 2))
+ {
+ assert (!GET_GAME_STATE (TAALO_PROTECTOR) && whichNode == 0);
+
+ GenerateDefault_landerReport (solarSys);
+ SetLanderTakeoff ();
+
+ SET_GAME_STATE (TAALO_PROTECTOR, 1);
+ SET_GAME_STATE (TAALO_PROTECTOR_ON_SHIP, 1);
+
+ return true; // picked up
+ }
+
+ if (CurStarDescPtr->Index == ORZ_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ // Standard ruins report
+ GenerateDefault_landerReportCycle (solarSys);
+ return false;
+ }
+
+ (void) whichNode;
+ return false;
+}
diff --git a/src/uqm/planets/generate/genpet.c b/src/uqm/planets/generate/genpet.c
new file mode 100644
index 0000000..4c5515c
--- /dev/null
+++ b/src/uqm/planets/generate/genpet.c
@@ -0,0 +1,257 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../planets.h"
+#include "../../build.h"
+#include "../../comm.h"
+#include "../../encount.h"
+#include "../../starmap.h"
+#include "../../globdata.h"
+#include "../../ipdisp.h"
+#include "../../nameref.h"
+#include "../../setup.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+
+static bool GenerateTalkingPet_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateTalkingPet_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+static COUNT GenerateTalkingPet_generateEnergy (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+static bool GenerateTalkingPet_pickupEnergy (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world, COUNT whichNode);
+
+static void ZapToUrquanEncounter (void);
+
+
+const GenerateFunctions generateTalkingPetFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateTalkingPet_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateTalkingPet_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateTalkingPet_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateTalkingPet_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateTalkingPet_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+
+ solarSys->PlanetDesc[0].data_index = TELLURIC_WORLD;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 204L / 100;
+ angle = ARCTAN (solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+
+ return true;
+}
+
+static bool
+GenerateTalkingPet_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET)
+ && (GET_GAME_STATE (UMGAH_ZOMBIE_BLOBBIES)
+ || !GET_GAME_STATE (TALKING_PET)
+ || StartSphereTracking (UMGAH_SHIP)))
+ {
+ NotifyOthers (UMGAH_SHIP, IPNL_ALL_CLEAR);
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ if (StartSphereTracking (UMGAH_SHIP))
+ {
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ if (!GET_GAME_STATE (UMGAH_ZOMBIE_BLOBBIES))
+ {
+ CloneShipFragment (UMGAH_SHIP,
+ &GLOBAL (npc_built_ship_q), INFINITE_FLEET);
+ InitCommunication (UMGAH_CONVERSATION);
+ }
+ else
+ {
+ COUNT i;
+
+ for (i = 0; i < 10; ++i)
+ {
+ CloneShipFragment (UMGAH_SHIP,
+ &GLOBAL (npc_built_ship_q), 0);
+ }
+ InitCommunication (TALKING_PET_CONVERSATION);
+ }
+ }
+
+ if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)))
+ {
+ BOOLEAN UmgahSurvivors;
+
+ UmgahSurvivors = GetHeadLink (
+ &GLOBAL (npc_built_ship_q)) != 0;
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+
+ if (GET_GAME_STATE (PLAYER_HYPNOTIZED))
+ ZapToUrquanEncounter ();
+ else if (GET_GAME_STATE (UMGAH_ZOMBIE_BLOBBIES)
+ && !UmgahSurvivors)
+ {
+ // Defeated the zombie fleet.
+ InitCommunication (TALKING_PET_CONVERSATION);
+ }
+ else if (!(StartSphereTracking (UMGAH_SHIP)))
+ {
+ // The Kohr-Ah have destroyed the Umgah, but the
+ // talking pet survived.
+ InitCommunication (TALKING_PET_CONVERSATION);
+ }
+
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+ }
+
+ return true;
+ }
+
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (RUINS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (RUINS_STRTAB));
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ solarSys->SysInfo.PlanetInfo.Weather = 0;
+
+ return true;
+}
+
+static COUNT
+GenerateTalkingPet_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ return GenerateDefault_generateRuins (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
+static bool
+GenerateTalkingPet_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ // Standard ruins report
+ GenerateDefault_landerReportCycle (solarSys);
+ return false;
+ }
+
+ (void) whichNode;
+ return false;
+}
+
+static void
+ZapToUrquanEncounter (void)
+{
+ HENCOUNTER hEncounter;
+
+ if ((hEncounter = AllocEncounter ()) || (hEncounter = GetHeadEncounter ()))
+ {
+ SIZE dx, dy;
+ ENCOUNTER *EncounterPtr;
+ HFLEETINFO hStarShip;
+ FLEET_INFO *TemplatePtr;
+ BRIEF_SHIP_INFO *BSIPtr;
+
+ LockEncounter (hEncounter, &EncounterPtr);
+
+ if (hEncounter == GetHeadEncounter ())
+ RemoveEncounter (hEncounter);
+ memset (EncounterPtr, 0, sizeof (*EncounterPtr));
+
+ InsertEncounter (hEncounter, GetHeadEncounter ());
+
+ hStarShip = GetStarShipFromIndex (&GLOBAL (avail_race_q), URQUAN_SHIP);
+ TemplatePtr = LockFleetInfo (&GLOBAL (avail_race_q), hStarShip);
+ EncounterPtr->origin = TemplatePtr->loc;
+ EncounterPtr->radius = TemplatePtr->actual_strength;
+ EncounterPtr->race_id = URQUAN_SHIP;
+ EncounterPtr->num_ships = 1;
+ EncounterPtr->flags = ONE_SHOT_ENCOUNTER;
+ BSIPtr = &EncounterPtr->ShipList[0];
+ BSIPtr->race_id = URQUAN_SHIP;
+ BSIPtr->crew_level = TemplatePtr->crew_level;
+ BSIPtr->max_crew = TemplatePtr->max_crew;
+ BSIPtr->max_energy = TemplatePtr->max_energy;
+ EncounterPtr->loc_pt.x = 5288;
+ EncounterPtr->loc_pt.y = 4892;
+ EncounterPtr->log_x = UNIVERSE_TO_LOGX (EncounterPtr->loc_pt.x);
+ EncounterPtr->log_y = UNIVERSE_TO_LOGY (EncounterPtr->loc_pt.y);
+ GLOBAL_SIS (log_x) = EncounterPtr->log_x;
+ GLOBAL_SIS (log_y) = EncounterPtr->log_y;
+ UnlockFleetInfo (&GLOBAL (avail_race_q), hStarShip);
+
+ {
+#define LOST_DAYS 15
+ SleepThreadUntil (FadeScreen (FadeAllToBlack, ONE_SECOND * 2));
+ MoveGameClockDays (LOST_DAYS);
+ }
+
+ GLOBAL (CurrentActivity) = MAKE_WORD (IN_HYPERSPACE, 0) | START_ENCOUNTER;
+
+ dx = CurStarDescPtr->star_pt.x - EncounterPtr->loc_pt.x;
+ dy = CurStarDescPtr->star_pt.y - EncounterPtr->loc_pt.y;
+ dx = (SIZE)square_root ((long)dx * dx + (long)dy * dy)
+ + (FUEL_TANK_SCALE >> 1);
+
+ DeltaSISGauges (0, -dx, 0);
+ if (GLOBAL_SIS (FuelOnBoard) < 5 * FUEL_TANK_SCALE)
+ {
+ dx = ((5 + ((COUNT)TFB_Random () % 5)) * FUEL_TANK_SCALE)
+ - (SIZE)GLOBAL_SIS (FuelOnBoard);
+ DeltaSISGauges (0, dx, 0);
+ }
+ DrawSISMessage (NULL);
+ DrawHyperCoords (EncounterPtr->loc_pt);
+
+ UnlockEncounter (hEncounter);
+ }
+}
+
diff --git a/src/uqm/planets/generate/genpku.c b/src/uqm/planets/generate/genpku.c
new file mode 100644
index 0000000..64b9965
--- /dev/null
+++ b/src/uqm/planets/generate/genpku.c
@@ -0,0 +1,159 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../lander.h"
+#include "../planets.h"
+#include "../../build.h"
+#include "../../comm.h"
+#include "../../globdata.h"
+#include "../../ipdisp.h"
+#include "../../nameref.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+
+static bool GeneratePkunk_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GeneratePkunk_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+static COUNT GeneratePkunk_generateEnergy (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+static bool GeneratePkunk_pickupEnergy (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world, COUNT whichNode);
+
+
+const GenerateFunctions generatePkunkFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GeneratePkunk_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GeneratePkunk_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GeneratePkunk_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GeneratePkunk_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GeneratePkunk_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+
+ solarSys->PlanetDesc[0].data_index = WATER_WORLD;
+ solarSys->PlanetDesc[0].NumPlanets = 1;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 104L / 100;
+ angle = ARCTAN (solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+
+ return true;
+}
+
+static bool
+GeneratePkunk_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ if (StartSphereTracking (PKUNK_SHIP))
+ {
+ NotifyOthers (PKUNK_SHIP, IPNL_ALL_CLEAR);
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ CloneShipFragment (PKUNK_SHIP,
+ &GLOBAL (npc_built_ship_q), INFINITE_FLEET);
+
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ InitCommunication (PKUNK_CONVERSATION);
+
+ if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)))
+ {
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+ }
+ return true;
+ }
+ else
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (RUINS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (PKUNK_RUINS_STRTAB));
+ if (GET_GAME_STATE (CLEAR_SPINDLE))
+ { // Already picked up the Clear Spindle, skip the report
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ SetAbsStringTableIndex (
+ solarSys->SysInfo.PlanetInfo.DiscoveryString, 1);
+ }
+ }
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+ return true;
+}
+
+static bool
+GeneratePkunk_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ GenerateDefault_landerReportCycle (solarSys);
+
+ // The artifact can be picked up from any ruin
+ if (!GET_GAME_STATE (CLEAR_SPINDLE))
+ { // Just picked up the Clear Spindle from a ruin
+ SetLanderTakeoff ();
+
+ SET_GAME_STATE (CLEAR_SPINDLE, 1);
+ SET_GAME_STATE (CLEAR_SPINDLE_ON_SHIP, 1);
+ }
+
+ return false; // do not remove the node
+ }
+
+ (void) whichNode;
+ return false;
+}
+
+static COUNT
+GeneratePkunk_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ return GenerateDefault_generateRuins (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
diff --git a/src/uqm/planets/generate/genrain.c b/src/uqm/planets/generate/genrain.c
new file mode 100644
index 0000000..c149b29
--- /dev/null
+++ b/src/uqm/planets/generate/genrain.c
@@ -0,0 +1,102 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../planets.h"
+#include "../../gendef.h"
+#include "../../starmap.h"
+#include "../../globdata.h"
+#include "libs/mathlib.h"
+
+
+static bool GenerateRainbowWorld_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateRainbowWorld_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+
+
+const GenerateFunctions generateRainbowWorldFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateRainbowWorld_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateRainbowWorld_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateDefault_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateDefault_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateRainbowWorld_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+
+ solarSys->PlanetDesc[0].data_index = RAINBOW_WORLD;
+ solarSys->PlanetDesc[0].NumPlanets = 0;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 50L / 100;
+ angle = ARCTAN (solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ if (angle <= QUADRANT)
+ angle += QUADRANT;
+ else if (angle >= FULL_CIRCLE - QUADRANT)
+ angle -= QUADRANT;
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+
+ return true;
+}
+
+static bool
+GenerateRainbowWorld_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ BYTE which_rainbow;
+ UWORD rainbow_mask;
+ STAR_DESC *SDPtr;
+
+ rainbow_mask = MAKE_WORD (
+ GET_GAME_STATE (RAINBOW_WORLD0),
+ GET_GAME_STATE (RAINBOW_WORLD1));
+
+ which_rainbow = 0;
+ SDPtr = &star_array[0];
+ while (SDPtr != CurStarDescPtr)
+ {
+ if (SDPtr->Index == RAINBOW_DEFINED)
+ ++which_rainbow;
+ ++SDPtr;
+ }
+ rainbow_mask |= 1 << which_rainbow;
+ SET_GAME_STATE (RAINBOW_WORLD0, LOBYTE (rainbow_mask));
+ SET_GAME_STATE (RAINBOW_WORLD1, HIBYTE (rainbow_mask));
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+ return true;
+}
+
diff --git a/src/uqm/planets/generate/gensam.c b/src/uqm/planets/generate/gensam.c
new file mode 100644
index 0000000..b2398b3
--- /dev/null
+++ b/src/uqm/planets/generate/gensam.c
@@ -0,0 +1,324 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../planets.h"
+#include "../../build.h"
+#include "../../comm.h"
+#include "../../encount.h"
+#include "../../globdata.h"
+#include "../../grpinfo.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+
+static bool GenerateSaMatra_initNpcs (SOLARSYS_STATE *solarSys);
+static bool GenerateSaMatra_reinitNpcs (SOLARSYS_STATE *solarSys);
+static bool GenerateSaMatra_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateSaMatra_generateMoons (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *planet);
+static bool GenerateSaMatra_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+
+static void BuildUrquanGuard (SOLARSYS_STATE *solarSys);
+
+
+const GenerateFunctions generateSaMatraFunctions = {
+ /* .initNpcs = */ GenerateSaMatra_initNpcs,
+ /* .reinitNpcs = */ GenerateSaMatra_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateSaMatra_generatePlanets,
+ /* .generateMoons = */ GenerateSaMatra_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateSaMatra_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateDefault_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateDefault_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateSaMatra_initNpcs (SOLARSYS_STATE *solarSys)
+{
+ if (!GET_GAME_STATE (URQUAN_MESSED_UP))
+ {
+ BuildUrquanGuard (solarSys);
+ }
+ else
+ { // Exorcise Ur-Quan ghosts upon system reentry
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ // wipe out the group
+ }
+
+ (void) solarSys;
+ return true;
+}
+
+static bool
+GenerateSaMatra_reinitNpcs (SOLARSYS_STATE *solarSys)
+{
+ BOOLEAN GuardEngaged;
+ HIPGROUP hGroup;
+ HIPGROUP hNextGroup;
+
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+ EncounterGroup = 0;
+ EncounterRace = -1;
+ // Do not want guards to chase the player
+
+ GuardEngaged = FALSE;
+ for (hGroup = GetHeadLink (&GLOBAL (ip_group_q));
+ hGroup; hGroup = hNextGroup)
+ {
+ IP_GROUP *GroupPtr;
+
+ GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ hNextGroup = _GetSuccLink (GroupPtr);
+
+ if (GET_GAME_STATE (URQUAN_MESSED_UP))
+ {
+ GroupPtr->task &= REFORM_GROUP;
+ GroupPtr->task |= FLEE | IGNORE_FLAGSHIP;
+ GroupPtr->dest_loc = 0;
+ }
+ else if (GroupPtr->task & REFORM_GROUP)
+ {
+ // REFORM_GROUP was set in ipdisp.c:ip_group_collision
+ // during a collision with the flagship.
+ GroupPtr->task &= ~REFORM_GROUP;
+ GroupPtr->group_counter = 0;
+
+ GuardEngaged = TRUE;
+ }
+
+ UnlockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ }
+
+ if (GuardEngaged)
+ {
+ COUNT angle;
+ POINT org;
+
+ org = planetOuterLocation (4);
+ angle = ARCTAN (GLOBAL (ip_location.x) - org.x,
+ GLOBAL (ip_location.y) - org.y);
+ GLOBAL (ip_location.x) = org.x + COSINE (angle, 3000);
+ GLOBAL (ip_location.y) = org.y + SINE (angle, 3000);
+ XFormIPLoc (&GLOBAL (ip_location),
+ &GLOBAL (ShipStamp.origin), TRUE);
+ }
+
+ (void) solarSys;
+ return true;
+}
+
+static bool
+GenerateSaMatra_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ GenerateDefault_generatePlanets (solarSys);
+ solarSys->PlanetDesc[4].NumPlanets = 1;
+ return true;
+}
+
+static bool
+GenerateSaMatra_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet)
+{
+ GenerateDefault_generateMoons (solarSys, planet);
+
+ if (matchWorld (solarSys, planet, 4, MATCH_PLANET))
+ {
+ COUNT angle;
+ DWORD rand_val;
+
+ solarSys->MoonDesc[0].data_index = SA_MATRA;
+ solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS + (2 * MOON_DELTA);
+ rand_val = RandomContext_Random (SysGenRNG);
+ angle = NORMALIZE_ANGLE (LOWORD (rand_val));
+ solarSys->MoonDesc[0].location.x =
+ COSINE (angle, solarSys->MoonDesc[0].radius);
+ solarSys->MoonDesc[0].location.y =
+ SINE (angle, solarSys->MoonDesc[0].radius);
+ }
+
+ return true;
+}
+
+static bool
+GenerateSaMatra_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ /* Samatra */
+ if (matchWorld (solarSys, world, 4, 0))
+ {
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ if (!GET_GAME_STATE (URQUAN_MESSED_UP))
+ {
+ CloneShipFragment (!GET_GAME_STATE (KOHR_AH_FRENZY) ?
+ URQUAN_SHIP : BLACK_URQUAN_SHIP,
+ &GLOBAL (npc_built_ship_q), INFINITE_FLEET);
+ }
+ else
+ {
+#define URQUAN_REMNANTS 3
+ BYTE i;
+
+ for (i = 0; i < URQUAN_REMNANTS; ++i)
+ {
+ CloneShipFragment (URQUAN_SHIP,
+ &GLOBAL (npc_built_ship_q), 0);
+ CloneShipFragment (BLACK_URQUAN_SHIP,
+ &GLOBAL (npc_built_ship_q), 0);
+ }
+ }
+
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ SET_GAME_STATE (URQUAN_PROTECTING_SAMATRA, 1);
+ InitCommunication (URQUAN_CONVERSATION);
+
+ if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)))
+ {
+ BOOLEAN UrquanSurvivors;
+
+ UrquanSurvivors = GetHeadLink (&GLOBAL (npc_built_ship_q)) != 0;
+
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+ if (UrquanSurvivors)
+ {
+ SET_GAME_STATE (URQUAN_PROTECTING_SAMATRA, 0);
+ }
+ else
+ {
+ EncounterGroup = 0;
+ EncounterRace = -1;
+ GLOBAL (CurrentActivity) = IN_LAST_BATTLE | START_ENCOUNTER;
+ if (GET_GAME_STATE (YEHAT_CIVIL_WAR)
+ && StartSphereTracking (YEHAT_SHIP)
+ && EscortFeasibilityStudy (YEHAT_REBEL_SHIP))
+ InitCommunication (YEHAT_REBEL_CONVERSATION);
+ }
+ }
+ return true;
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+ return true;
+}
+
+static void
+BuildUrquanGuard (SOLARSYS_STATE *solarSys)
+{
+ BYTE ship1, ship2;
+ BYTE b0, b1;
+ POINT org;
+ HIPGROUP hGroup, hNextGroup;
+
+ GLOBAL (BattleGroupRef) = GET_GAME_STATE_32 (SAMATRA_GRPOFFS0);
+
+ if (!GET_GAME_STATE (KOHR_AH_FRENZY))
+ {
+ ship1 = URQUAN_SHIP;
+ ship2 = BLACK_URQUAN_SHIP;
+ }
+ else
+ {
+ ship1 = BLACK_URQUAN_SHIP;
+ ship2 = URQUAN_SHIP;
+ }
+
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ for (b0 = 0; b0 < MAX_SHIPS_PER_SIDE; ++b0)
+ CloneShipFragment (ship1, &GLOBAL (npc_built_ship_q), 0);
+
+ if (GLOBAL (BattleGroupRef) == 0)
+ {
+ GLOBAL (BattleGroupRef) = PutGroupInfo (GROUPS_ADD_NEW, 1);
+ SET_GAME_STATE_32 (SAMATRA_GRPOFFS0, GLOBAL (BattleGroupRef));
+ }
+
+#define NUM_URQUAN_GUARDS0 12
+ for (b0 = 1; b0 <= NUM_URQUAN_GUARDS0; ++b0)
+ PutGroupInfo (GLOBAL (BattleGroupRef), b0);
+
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ for (b0 = 0; b0 < MAX_SHIPS_PER_SIDE; ++b0)
+ CloneShipFragment (ship2, &GLOBAL (npc_built_ship_q), 0);
+
+#define NUM_URQUAN_GUARDS1 4
+ for (b0 = 1; b0 <= NUM_URQUAN_GUARDS1; ++b0)
+ PutGroupInfo (GLOBAL (BattleGroupRef),
+ (BYTE)(NUM_URQUAN_GUARDS0 + b0));
+
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+
+ GetGroupInfo (GLOBAL (BattleGroupRef), GROUP_INIT_IP);
+
+ org = planetOuterLocation (4);
+ hGroup = GetHeadLink (&GLOBAL (ip_group_q));
+ for (b0 = 0, b1 = 0;
+ b0 < NUM_URQUAN_GUARDS0;
+ ++b0, b1 += FULL_CIRCLE / (NUM_URQUAN_GUARDS0 + NUM_URQUAN_GUARDS1))
+ {
+ IP_GROUP *GroupPtr;
+
+ if (b1 % (FULL_CIRCLE / NUM_URQUAN_GUARDS1) == 0)
+ b1 += FULL_CIRCLE / (NUM_URQUAN_GUARDS0 + NUM_URQUAN_GUARDS1);
+
+ GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ hNextGroup = _GetSuccLink (GroupPtr);
+ GroupPtr->task = ON_STATION | IGNORE_FLAGSHIP;
+ GroupPtr->sys_loc = 0;
+ GroupPtr->dest_loc = 4 + 1;
+ GroupPtr->orbit_pos = NORMALIZE_FACING (ANGLE_TO_FACING (b1));
+ GroupPtr->group_counter = 0;
+ GroupPtr->loc.x = org.x + COSINE (b1, STATION_RADIUS);
+ GroupPtr->loc.y = org.y + SINE (b1, STATION_RADIUS);
+ UnlockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ hGroup = hNextGroup;
+ }
+
+ for (b0 = 0, b1 = 0;
+ b0 < NUM_URQUAN_GUARDS1;
+ ++b0, b1 += FULL_CIRCLE / NUM_URQUAN_GUARDS1)
+ {
+ IP_GROUP *GroupPtr;
+
+ GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ hNextGroup = _GetSuccLink (GroupPtr);
+ GroupPtr->task = ON_STATION | IGNORE_FLAGSHIP;
+ GroupPtr->sys_loc = 0;
+ GroupPtr->dest_loc = 4 + 1;
+ GroupPtr->orbit_pos = NORMALIZE_FACING (ANGLE_TO_FACING (b1));
+ GroupPtr->group_counter = 0;
+ GroupPtr->loc.x = org.x + COSINE (b1, STATION_RADIUS);
+ GroupPtr->loc.y = org.y + SINE (b1, STATION_RADIUS);
+ UnlockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ hGroup = hNextGroup;
+ }
+
+ (void) solarSys;
+}
+
diff --git a/src/uqm/planets/generate/genshof.c b/src/uqm/planets/generate/genshof.c
new file mode 100644
index 0000000..7025f6a
--- /dev/null
+++ b/src/uqm/planets/generate/genshof.c
@@ -0,0 +1,178 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../../build.h"
+#include "../../globdata.h"
+#include "../../grpinfo.h"
+#include "../../state.h"
+#include "../planets.h"
+
+
+static bool GenerateShofixti_initNpcs (SOLARSYS_STATE *solarSys);
+static bool GenerateShofixti_reinitNpcs (SOLARSYS_STATE *solarSys);
+static bool GenerateShofixti_uninitNpcs (SOLARSYS_STATE *solarSys);
+static bool GenerateShofixti_generatePlanets (SOLARSYS_STATE *solarSys);
+
+static void check_old_shofixti (void);
+
+
+const GenerateFunctions generateShofixtiFunctions = {
+ /* .initNpcs = */ GenerateShofixti_initNpcs,
+ /* .reinitNpcs = */ GenerateShofixti_reinitNpcs,
+ /* .uninitNpcs = */ GenerateShofixti_uninitNpcs,
+ /* .generatePlanets = */ GenerateShofixti_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateDefault_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateDefault_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateDefault_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateShofixti_initNpcs (SOLARSYS_STATE *solarSys)
+{
+ if (!GET_GAME_STATE (SHOFIXTI_RECRUITED)
+ && (!GET_GAME_STATE (SHOFIXTI_KIA)
+ || (!GET_GAME_STATE (SHOFIXTI_BRO_KIA)
+ && GET_GAME_STATE (MAIDENS_ON_SHIP))))
+ {
+ GLOBAL (BattleGroupRef) = GET_GAME_STATE_32 (SHOFIXTI_GRPOFFS0);
+ if (GLOBAL (BattleGroupRef) == 0
+ || !GetGroupInfo (GLOBAL (BattleGroupRef), GROUP_INIT_IP))
+ {
+ HSHIPFRAG hStarShip;
+
+ if (GLOBAL (BattleGroupRef) == 0)
+ GLOBAL (BattleGroupRef) = ~0L;
+
+ hStarShip = CloneShipFragment (SHOFIXTI_SHIP,
+ &GLOBAL (npc_built_ship_q), 1);
+ if (hStarShip)
+ { /* Set old Shofixti name; his brother if Tanaka died */
+ SHIP_FRAGMENT *FragPtr = LockShipFrag (
+ &GLOBAL (npc_built_ship_q), hStarShip);
+ /* Name Tanaka or Katana (+1) */
+ FragPtr->captains_name_index =
+ NAME_OFFSET + NUM_CAPTAINS_NAMES +
+ (GET_GAME_STATE (SHOFIXTI_KIA) & 1);
+ UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip);
+ }
+
+ GLOBAL (BattleGroupRef) = PutGroupInfo (
+ GLOBAL (BattleGroupRef), 1);
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ SET_GAME_STATE_32 (SHOFIXTI_GRPOFFS0, GLOBAL (BattleGroupRef));
+ }
+ }
+
+ // This was originally a fallthrough to REINIT_NPCS.
+ // XXX: is the call to check_old_shofixti() needed?
+ GenerateDefault_initNpcs (solarSys);
+ check_old_shofixti ();
+
+ return true;
+}
+
+static bool
+GenerateShofixti_reinitNpcs (SOLARSYS_STATE *solarSys)
+{
+ GenerateDefault_reinitNpcs (solarSys);
+ check_old_shofixti ();
+
+ (void) solarSys;
+ return true;
+}
+
+static bool
+GenerateShofixti_uninitNpcs (SOLARSYS_STATE *solarSys)
+{
+ if (GLOBAL (BattleGroupRef)
+ && !GET_GAME_STATE (SHOFIXTI_RECRUITED)
+ && GetHeadLink (&GLOBAL (ip_group_q)) == 0)
+ {
+ if (!GET_GAME_STATE (SHOFIXTI_KIA))
+ {
+ SET_GAME_STATE (SHOFIXTI_KIA, 1);
+ SET_GAME_STATE (SHOFIXTI_VISITS, 0);
+ }
+ else if (GET_GAME_STATE (MAIDENS_ON_SHIP))
+ {
+ SET_GAME_STATE (SHOFIXTI_BRO_KIA, 1);
+ }
+ }
+
+ GenerateDefault_uninitNpcs (solarSys);
+ return true;
+}
+
+static bool
+GenerateShofixti_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT i;
+
+#define NUM_PLANETS 6
+ solarSys->SunDesc[0].NumPlanets = NUM_PLANETS;
+ for (i = 0; i < NUM_PLANETS; ++i)
+ {
+ PLANET_DESC *pCurDesc = &solarSys->PlanetDesc[i];
+
+ pCurDesc->NumPlanets = 0;
+ if (i < (NUM_PLANETS >> 1))
+ pCurDesc->data_index = SELENIC_WORLD;
+ else
+ pCurDesc->data_index = METAL_WORLD;
+ }
+
+ FillOrbits (solarSys, NUM_PLANETS, solarSys->PlanetDesc, TRUE);
+
+ return true;
+}
+
+
+static void
+check_old_shofixti (void)
+{
+ HIPGROUP hGroup;
+ IP_GROUP *GroupPtr;
+
+ if (!GLOBAL (BattleGroupRef))
+ return; // nothing to check
+
+ hGroup = GetHeadLink (&GLOBAL (ip_group_q));
+ if (!hGroup)
+ return; // still nothing to check
+
+ GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ // REFORM_GROUP was set in ipdisp.c:ip_group_collision()
+ // during a collision with the flagship.
+ if (GroupPtr->race_id == SHOFIXTI_SHIP
+ && (GroupPtr->task & REFORM_GROUP)
+ && GET_GAME_STATE (SHOFIXTI_RECRUITED))
+ {
+ GroupPtr->task = FLEE | IGNORE_FLAGSHIP | REFORM_GROUP;
+ GroupPtr->dest_loc = 0;
+ }
+ UnlockIpGroup (&GLOBAL (ip_group_q), hGroup);
+}
+
diff --git a/src/uqm/planets/generate/gensly.c b/src/uqm/planets/generate/gensly.c
new file mode 100644
index 0000000..48ed100
--- /dev/null
+++ b/src/uqm/planets/generate/gensly.c
@@ -0,0 +1,70 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../planets.h"
+#include "../../comm.h"
+
+
+static bool GenerateSlylandro_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateSlylandro_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+
+
+const GenerateFunctions generateSlylandroFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateSlylandro_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateSlylandro_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateDefault_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateDefault_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateSlylandro_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ GenerateDefault_generatePlanets (solarSys);
+
+ solarSys->PlanetDesc[3].data_index = RED_GAS_GIANT;
+ solarSys->PlanetDesc[3].NumPlanets = 1;
+
+ return true;
+}
+
+static bool
+GenerateSlylandro_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 3, MATCH_PLANET))
+ {
+ InitCommunication (SLYLANDRO_HOME_CONVERSATION);
+ return true;
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+ return true;
+}
+
diff --git a/src/uqm/planets/generate/gensol.c b/src/uqm/planets/generate/gensol.c
new file mode 100644
index 0000000..d6041f3
--- /dev/null
+++ b/src/uqm/planets/generate/gensol.c
@@ -0,0 +1,671 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../lander.h"
+#include "../lifeform.h"
+#include "../planets.h"
+#include "../../build.h"
+#include "../../encount.h"
+#include "../../globdata.h"
+#include "../../gamestr.h"
+#include "../../grpinfo.h"
+#include "../../nameref.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+
+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);
+
+static int init_probe (void);
+static void check_probe (void);
+
+
+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,
+};
+
+
+static bool
+GenerateSol_initNpcs (SOLARSYS_STATE *solarSys)
+{
+ GLOBAL (BattleGroupRef) = GET_GAME_STATE_32 (URQUAN_PROBE_GRPOFFS0);
+ if (GLOBAL (BattleGroupRef) == 0)
+ {
+ CloneShipFragment (URQUAN_DRONE_SHIP, &GLOBAL (npc_built_ship_q), 0);
+ GLOBAL (BattleGroupRef) = PutGroupInfo (GROUPS_ADD_NEW, 1);
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ SET_GAME_STATE_32 (URQUAN_PROBE_GRPOFFS0, GLOBAL (BattleGroupRef));
+ }
+
+ if (!init_probe ())
+ GenerateDefault_initNpcs (solarSys);
+
+ return true;
+}
+
+static bool
+GenerateSol_reinitNpcs (SOLARSYS_STATE *solarSys)
+{
+ if (GET_GAME_STATE (CHMMR_BOMB_STATE) != 3)
+ {
+ GenerateDefault_reinitNpcs (solarSys);
+ check_probe ();
+ }
+ else
+ {
+ GLOBAL (BattleGroupRef) = 0;
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+ }
+ return true;
+}
+
+static bool
+GenerateSol_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT planetI;
+
+#define SOL_SEED 334241042L
+ RandomContext_SeedRandom (SysGenRNG, SOL_SEED);
+
+ solarSys->SunDesc[0].NumPlanets = 9;
+ for (planetI = 0; planetI < 9; ++planetI)
+ {
+ COUNT angle;
+ DWORD rand_val;
+ UWORD word_val;
+ PLANET_DESC *pCurDesc = &solarSys->PlanetDesc[planetI];
+
+ pCurDesc->rand_seed = RandomContext_Random (SysGenRNG);
+ rand_val = pCurDesc->rand_seed;
+ word_val = LOWORD (rand_val);
+ angle = NORMALIZE_ANGLE ((COUNT)HIBYTE (word_val));
+
+ switch (planetI)
+ {
+ case 0: /* MERCURY */
+ pCurDesc->data_index = METAL_WORLD;
+ pCurDesc->radius = EARTH_RADIUS * 39L / 100;
+ pCurDesc->NumPlanets = 0;
+ break;
+ case 1: /* VENUS */
+ pCurDesc->data_index = PRIMORDIAL_WORLD;
+ pCurDesc->radius = EARTH_RADIUS * 72L / 100;
+ pCurDesc->NumPlanets = 0;
+ angle = NORMALIZE_ANGLE (FULL_CIRCLE - angle);
+ break;
+ case 2: /* EARTH */
+ pCurDesc->data_index = WATER_WORLD | PLANET_SHIELDED;
+ pCurDesc->radius = EARTH_RADIUS;
+ pCurDesc->NumPlanets = 2;
+ break;
+ case 3: /* MARS */
+ pCurDesc->data_index = DUST_WORLD;
+ pCurDesc->radius = EARTH_RADIUS * 152L / 100;
+ pCurDesc->NumPlanets = 0;
+ break;
+ case 4: /* JUPITER */
+ pCurDesc->data_index = RED_GAS_GIANT;
+ pCurDesc->radius = EARTH_RADIUS * 500L /* 520L */ / 100;
+ pCurDesc->NumPlanets = 4;
+ break;
+ case 5: /* SATURN */
+ pCurDesc->data_index = ORA_GAS_GIANT;
+ pCurDesc->radius = EARTH_RADIUS * 750L /* 952L */ / 100;
+ pCurDesc->NumPlanets = 1;
+ break;
+ case 6: /* URANUS */
+ pCurDesc->data_index = GRN_GAS_GIANT;
+ pCurDesc->radius = EARTH_RADIUS * 1000L /* 1916L */ / 100;
+ pCurDesc->NumPlanets = 0;
+ break;
+ case 7: /* NEPTUNE */
+ pCurDesc->data_index = BLU_GAS_GIANT;
+ pCurDesc->radius = EARTH_RADIUS * 1250L /* 2999L */ / 100;
+ pCurDesc->NumPlanets = 1;
+ break;
+ case 8: /* PLUTO */
+ pCurDesc->data_index = PELLUCID_WORLD;
+ pCurDesc->radius = EARTH_RADIUS * 1550L /* 3937L */ / 100;
+ pCurDesc->NumPlanets = 0;
+ angle = FULL_CIRCLE - OCTANT;
+ break;
+ }
+
+ pCurDesc->location.x = COSINE (angle, pCurDesc->radius);
+ pCurDesc->location.y = SINE (angle, pCurDesc->radius);
+ }
+
+ return true;
+}
+
+static bool
+GenerateSol_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet)
+{
+ COUNT planetNr;
+ DWORD rand_val;
+
+ GenerateDefault_generateMoons (solarSys, planet);
+
+ planetNr = planetIndex (solarSys, planet);
+ switch (planetNr)
+ {
+ case 2: /* moons of EARTH */
+ {
+ COUNT angle;
+
+ /* Starbase: */
+ solarSys->MoonDesc[0].data_index = HIERARCHY_STARBASE;
+ solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS;
+ angle = HALF_CIRCLE + QUADRANT;
+ solarSys->MoonDesc[0].location.x =
+ COSINE (angle, solarSys->MoonDesc[0].radius);
+ solarSys->MoonDesc[0].location.y =
+ SINE (angle, solarSys->MoonDesc[0].radius);
+
+ /* Luna: */
+ solarSys->MoonDesc[1].data_index = SELENIC_WORLD;
+ solarSys->MoonDesc[1].radius = MIN_MOON_RADIUS
+ + (MAX_MOONS - 1) * MOON_DELTA;
+ rand_val = RandomContext_Random (SysGenRNG);
+ angle = NORMALIZE_ANGLE (LOWORD (rand_val));
+ solarSys->MoonDesc[1].location.x =
+ COSINE (angle, solarSys->MoonDesc[1].radius);
+ solarSys->MoonDesc[1].location.y =
+ SINE (angle, solarSys->MoonDesc[1].radius);
+ break;
+ }
+ case 4: /* moons of JUPITER */
+ solarSys->MoonDesc[0].data_index = RADIOACTIVE_WORLD;
+ /* Io */
+ solarSys->MoonDesc[1].data_index = HALIDE_WORLD;
+ /* Europa */
+ solarSys->MoonDesc[2].data_index = CYANIC_WORLD;
+ /* Ganymede */
+ solarSys->MoonDesc[3].data_index = PELLUCID_WORLD;
+ /* Callisto */
+ break;
+ case 5: /* moons of SATURN */
+ solarSys->MoonDesc[0].data_index = ALKALI_WORLD;
+ /* Titan */
+ break;
+ case 7: /* moons of NEPTUNE */
+ solarSys->MoonDesc[0].data_index = VINYLOGOUS_WORLD;
+ /* Triton */
+ break;
+ }
+
+ return true;
+}
+
+static bool
+GenerateSol_generateName (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world)
+{
+ COUNT planetNr = planetIndex (solarSys, world);
+ utf8StringCopy (GLOBAL_SIS (PlanetName), sizeof (GLOBAL_SIS (PlanetName)),
+ GAME_STRING (PLANET_NUMBER_BASE + planetNr));
+ SET_GAME_STATE (BATTLE_PLANET, solarSys->PlanetDesc[planetNr].data_index);
+
+ return true;
+}
+
+static bool
+GenerateSol_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ DWORD rand_val;
+ COUNT planetNr;
+
+ if (matchWorld (solarSys, world, 2, 0))
+ {
+ /* Starbase */
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ EncounterGroup = 0;
+ GLOBAL (CurrentActivity) |= START_ENCOUNTER;
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, (BYTE)~0);
+ return true;
+ }
+
+ DoPlanetaryAnalysis (&solarSys->SysInfo, world);
+ rand_val = RandomContext_GetSeed (SysGenRNG);
+
+ solarSys->SysInfo.PlanetInfo.ScanSeed[MINERAL_SCAN] = rand_val;
+ GenerateMineralDeposits (&solarSys->SysInfo, GENERATE_ALL, NULL);
+ rand_val = RandomContext_GetSeed (SysGenRNG);
+
+ planetNr = planetIndex (solarSys, world);
+ if (worldIsPlanet (solarSys, world))
+ {
+ switch (planetNr)
+ {
+ case 0: /* MERCURY */
+ solarSys->SysInfo.PlanetInfo.AtmoDensity = 0;
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 98;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 38;
+ solarSys->SysInfo.PlanetInfo.AxialTilt = 3;
+ solarSys->SysInfo.PlanetInfo.Weather = 0;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 2;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 59 * 240;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = 165;
+ break;
+ case 1: /* VENUS */
+ solarSys->SysInfo.PlanetInfo.AtmoDensity = 90 *
+ EARTH_ATMOSPHERE;
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 95;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 95;
+ solarSys->SysInfo.PlanetInfo.AxialTilt = 177;
+ solarSys->SysInfo.PlanetInfo.Weather = 7;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 1;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 243 * 240;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = 457;
+ break;
+ case 2: /* EARTH */
+ solarSys->SysInfo.PlanetInfo.AtmoDensity =
+ EARTH_ATMOSPHERE;
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 100;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 100;
+ solarSys->SysInfo.PlanetInfo.AxialTilt = 23;
+ solarSys->SysInfo.PlanetInfo.Weather = 1;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 1;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 240;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = 22;
+ break;
+ case 3: /* MARS */
+ // XXX: Mars atmo should actually be 1/2 in current units
+ solarSys->SysInfo.PlanetInfo.AtmoDensity = 1;
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 72;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 53;
+ solarSys->SysInfo.PlanetInfo.AxialTilt = 24;
+ solarSys->SysInfo.PlanetInfo.Weather = 1;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 1;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 246;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = -53;
+ break;
+ case 4: /* JUPITER */
+ solarSys->SysInfo.PlanetInfo.AtmoDensity =
+ GAS_GIANT_ATMOSPHERE;
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 24;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 1120;
+ solarSys->SysInfo.PlanetInfo.AxialTilt = 3;
+ solarSys->SysInfo.PlanetInfo.Weather = 7;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 0;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 98;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = -143;
+ solarSys->SysInfo.PlanetInfo.PlanetToSunDist =
+ EARTH_RADIUS * 520L / 100;
+ break;
+ case 5: /* SATURN */
+ solarSys->SysInfo.PlanetInfo.AtmoDensity =
+ GAS_GIANT_ATMOSPHERE;
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 13;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 945;
+ solarSys->SysInfo.PlanetInfo.AxialTilt = 27;
+ solarSys->SysInfo.PlanetInfo.Weather = 7;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 0;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 102;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = -197;
+ solarSys->SysInfo.PlanetInfo.PlanetToSunDist =
+ EARTH_RADIUS * 952L / 100;
+ break;
+ case 6: /* URANUS */
+ solarSys->SysInfo.PlanetInfo.AtmoDensity =
+ GAS_GIANT_ATMOSPHERE;
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 21;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 411;
+ solarSys->SysInfo.PlanetInfo.AxialTilt = 98;
+ solarSys->SysInfo.PlanetInfo.Weather = 7;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 0;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 172;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = -217;
+ solarSys->SysInfo.PlanetInfo.PlanetToSunDist =
+ EARTH_RADIUS * 1916L / 100;
+ break;
+ case 7: /* NEPTUNE */
+ solarSys->SysInfo.PlanetInfo.AtmoDensity =
+ GAS_GIANT_ATMOSPHERE;
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 28;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 396;
+ solarSys->SysInfo.PlanetInfo.AxialTilt = 30;
+ solarSys->SysInfo.PlanetInfo.Weather = 7;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 0;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 182;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = -229;
+ solarSys->SysInfo.PlanetInfo.PlanetToSunDist =
+ EARTH_RADIUS * 2999L / 100;
+ break;
+ case 8: /* PLUTO */
+ if (!GET_GAME_STATE (FOUND_PLUTO_SPATHI))
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (
+ LoadGraphic (SPAPLUTO_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (
+ LoadStringTable (SPAPLUTO_STRTAB));
+ }
+
+ solarSys->SysInfo.PlanetInfo.AtmoDensity = 0;
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 33;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 18;
+ solarSys->SysInfo.PlanetInfo.AxialTilt = 119;
+ solarSys->SysInfo.PlanetInfo.Weather = 0;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 0;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 1533;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = -235;
+ solarSys->SysInfo.PlanetInfo.PlanetToSunDist =
+ EARTH_RADIUS * 3937L / 100;
+ break;
+ }
+
+ solarSys->SysInfo.PlanetInfo.SurfaceGravity =
+ CalcGravity (&solarSys->SysInfo.PlanetInfo);
+ LoadPlanet (planetNr == 2 ?
+ CaptureDrawable (LoadGraphic (EARTH_MASK_ANIM)) : NULL);
+ }
+ else
+ {
+ // World is a moon.
+ COUNT moonNr = moonIndex (solarSys, world);
+
+ solarSys->SysInfo.PlanetInfo.AxialTilt = 0;
+ solarSys->SysInfo.PlanetInfo.AtmoDensity = 0;
+ solarSys->SysInfo.PlanetInfo.Weather = 0;
+ switch (planetNr)
+ {
+ case 2: /* moons of EARTH */
+ // NOTE: Even though we save the seed here, it is irrelevant.
+ // The seed will be used to randomly place the tractors, but
+ // since they are mobile, they will be moved to different
+ // locations not governed by this seed.
+ solarSys->SysInfo.PlanetInfo.ScanSeed[BIOLOGICAL_SCAN] =
+ rand_val;
+
+ if (!GET_GAME_STATE (MOONBASE_DESTROYED))
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (
+ LoadGraphic (MOONBASE_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (
+ LoadStringTable (MOONBASE_STRTAB));
+ }
+
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 60;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 25;
+ solarSys->SysInfo.PlanetInfo.AxialTilt = 0;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 0;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 240 * 29;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = -18;
+ break;
+
+ case 4: /* moons of JUPITER */
+ solarSys->SysInfo.PlanetInfo.PlanetToSunDist =
+ EARTH_RADIUS * 520L / 100;
+ switch (moonNr)
+ {
+ case 0: /* Io */
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 69;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 25;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 3;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 390;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = -163;
+ break;
+ case 1: /* Europa */
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 54;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 25;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 1;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 840;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = -161;
+ break;
+ case 2: /* Ganymede */
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 35;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 41;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 0;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 1728;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = -164;
+ break;
+ case 3: /* Callisto */
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 35;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 38;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 1;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 4008;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = -167;
+ break;
+ }
+ break;
+
+ case 5: /* moon of SATURN: Titan */
+ solarSys->SysInfo.PlanetInfo.PlanetToSunDist =
+ EARTH_RADIUS * 952L / 100;
+ solarSys->SysInfo.PlanetInfo.AtmoDensity = 160;
+ solarSys->SysInfo.PlanetInfo.Weather = 2;
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 34;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 40;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 1;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 3816;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = -178;
+ break;
+
+ case 7: /* moon of NEPTUNE: Triton */
+ solarSys->SysInfo.PlanetInfo.PlanetToSunDist =
+ EARTH_RADIUS * 2999L / 100;
+ solarSys->SysInfo.PlanetInfo.AtmoDensity = 10;
+ solarSys->SysInfo.PlanetInfo.Weather = 1;
+ solarSys->SysInfo.PlanetInfo.PlanetDensity = 95;
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 27;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 0;
+ solarSys->SysInfo.PlanetInfo.RotationPeriod = 4300;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = -216;
+ break;
+ }
+
+ solarSys->SysInfo.PlanetInfo.SurfaceGravity =
+ CalcGravity (&solarSys->SysInfo.PlanetInfo);
+ LoadPlanet (NULL);
+ }
+
+ return true;
+}
+
+static COUNT
+GenerateSol_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (matchWorld (solarSys, world, 8, MATCH_PLANET))
+ {
+ /* Pluto */
+ // This check is needed because the retrieval bit is not set for
+ // this node to keep it on the surface while the lander is taking off
+ if (GET_GAME_STATE (FOUND_PLUTO_SPATHI))
+ { // already picked up
+ return 0;
+ }
+
+ if (info)
+ {
+ info->loc_pt.x = 20;
+ info->loc_pt.y = MAP_HEIGHT - 8;
+ }
+
+ return 1; // only matters when count is requested
+ }
+
+ if (matchWorld (solarSys, world, 2, 1))
+ {
+ /* Earth Moon */
+ // This check is redundant since the retrieval bit will keep the
+ // node from showing up again
+ if (GET_GAME_STATE (MOONBASE_DESTROYED))
+ { // already picked up
+ return 0;
+ }
+
+ if (info)
+ {
+ info->loc_pt.x = MAP_WIDTH * 3 / 4;
+ info->loc_pt.y = MAP_HEIGHT * 1 / 4;
+ }
+
+ return 1; // only matters when count is requested
+ }
+
+ (void) whichNode;
+ return 0;
+}
+
+static bool
+GenerateSol_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (matchWorld (solarSys, world, 8, MATCH_PLANET))
+ { // Pluto
+ assert (!GET_GAME_STATE (FOUND_PLUTO_SPATHI) && whichNode == 0);
+
+ // Ran into Fwiffo on Pluto
+ #define FWIFFO_FRAGS 8
+ if (!KillLanderCrewSeq (FWIFFO_FRAGS, ONE_SECOND / 20))
+ return false; // lander probably died
+
+ SET_GAME_STATE (FOUND_PLUTO_SPATHI, 1);
+
+ GenerateDefault_landerReport (solarSys);
+ SetLanderTakeoff ();
+
+ // Do not remove the node from the surface while the lander is
+ // taking off. FOUND_PLUTO_SPATHI bit will keep the node from
+ // showing up on subsequent visits.
+ return false;
+ }
+
+ if (matchWorld (solarSys, world, 2, 1))
+ { // Earth Moon
+ assert (!GET_GAME_STATE (MOONBASE_DESTROYED) && whichNode == 0);
+
+ GenerateDefault_landerReport (solarSys);
+ SetLanderTakeoff ();
+
+ SET_GAME_STATE (MOONBASE_DESTROYED, 1);
+ SET_GAME_STATE (MOONBASE_ON_SHIP, 1);
+
+ return true; // picked up
+ }
+
+ (void) whichNode;
+ return false;
+}
+
+static COUNT
+GenerateSol_generateLife (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (matchWorld (solarSys, world, 2, 1))
+ {
+ /* Earth Moon */
+ return GenerateRandomNodes (&solarSys->SysInfo, BIOLOGICAL_SCAN, 10,
+ NUM_CREATURE_TYPES + 1, whichNode, info);
+ }
+
+ return 0;
+}
+
+
+static int
+init_probe (void)
+{
+ HIPGROUP hGroup;
+
+ if (!GET_GAME_STATE (PROBE_MESSAGE_DELIVERED)
+ && GetGroupInfo (GLOBAL (BattleGroupRef), GROUP_INIT_IP)
+ && (hGroup = GetHeadLink (&GLOBAL (ip_group_q))))
+ {
+ IP_GROUP *GroupPtr;
+
+ GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ GroupPtr->task = IN_ORBIT;
+ GroupPtr->sys_loc = 2 + 1; /* orbitting earth */
+ GroupPtr->dest_loc = 2 + 1; /* orbitting earth */
+ GroupPtr->loc.x = 0;
+ GroupPtr->loc.y = 0;
+ GroupPtr->group_counter = 0;
+ UnlockIpGroup (&GLOBAL (ip_group_q), hGroup);
+
+ return 1;
+ }
+ else
+ return 0;
+}
+
+static void
+check_probe (void)
+{
+ HIPGROUP hGroup;
+ IP_GROUP *GroupPtr;
+
+ if (!GLOBAL (BattleGroupRef))
+ return; // nothing to check
+
+ hGroup = GetHeadLink (&GLOBAL (ip_group_q));
+ if (!hGroup)
+ return; // still nothing to check
+
+ GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ // REFORM_GROUP was set in ipdisp.c:ip_group_collision()
+ // during a collision with the flagship.
+ if (GroupPtr->race_id == URQUAN_DRONE_SHIP
+ && (GroupPtr->task & REFORM_GROUP))
+ {
+ // We just want the probe to take off as fast as possible,
+ // so clear out REFORM_GROUP
+ GroupPtr->task = FLEE | IGNORE_FLAGSHIP;
+ GroupPtr->dest_loc = 0;
+ }
+ UnlockIpGroup (&GLOBAL (ip_group_q), hGroup);
+}
+
diff --git a/src/uqm/planets/generate/genspa.c b/src/uqm/planets/generate/genspa.c
new file mode 100644
index 0000000..26bc412
--- /dev/null
+++ b/src/uqm/planets/generate/genspa.c
@@ -0,0 +1,283 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../lifeform.h"
+#include "../lander.h"
+#include "../planets.h"
+#include "../scan.h"
+#include "../../build.h"
+#include "../../comm.h"
+#include "../../globdata.h"
+#include "../../ipdisp.h"
+#include "../../nameref.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+
+static bool GenerateSpathi_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateSpathi_generateMoons (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *planet);
+static bool GenerateSpathi_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+static COUNT GenerateSpathi_generateEnergy (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+static COUNT GenerateSpathi_generateLife (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+static bool GenerateSpathi_pickupEnergy (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world, COUNT whichNode);
+static bool GenerateSpathi_pickupLife (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world, COUNT whichNode);
+
+
+const GenerateFunctions generateSpathiFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateSpathi_generatePlanets,
+ /* .generateMoons = */ GenerateSpathi_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateSpathi_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateSpathi_generateEnergy,
+ /* .generateLife = */ GenerateSpathi_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateSpathi_pickupEnergy,
+ /* .pickupLife = */ GenerateSpathi_pickupLife,
+};
+
+
+static bool
+GenerateSpathi_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ PLANET_DESC *pMinPlanet;
+ COUNT angle;
+
+ pMinPlanet = &solarSys->PlanetDesc[0];
+ solarSys->SunDesc[0].NumPlanets = 1;
+ FillOrbits (solarSys,
+ solarSys->SunDesc[0].NumPlanets, pMinPlanet, FALSE);
+
+ pMinPlanet->radius = EARTH_RADIUS * 1150L / 100;
+ angle = ARCTAN (pMinPlanet->location.x, pMinPlanet->location.y);
+ pMinPlanet->location.x = COSINE (angle, pMinPlanet->radius);
+ pMinPlanet->location.y = SINE (angle, pMinPlanet->radius);
+ pMinPlanet->data_index = WATER_WORLD;
+ if (GET_GAME_STATE (SPATHI_SHIELDED_SELVES))
+ pMinPlanet->data_index |= PLANET_SHIELDED;
+ pMinPlanet->NumPlanets = 1;
+
+ return true;
+}
+
+static bool
+GenerateSpathi_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet)
+{
+ COUNT angle;
+
+ GenerateDefault_generateMoons (solarSys, planet);
+
+ if (matchWorld (solarSys, planet, 0, MATCH_PLANET))
+ {
+#ifdef NOTYET
+ utf8StringCopy (GLOBAL_SIS (PlanetName),
+ sizeof (GLOBAL_SIS (PlanetName)),
+ "Spathiwa");
+#endif /* NOTYET */
+
+ solarSys->MoonDesc[0].data_index = PELLUCID_WORLD;
+ solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS + MOON_DELTA;
+ angle = NORMALIZE_ANGLE (LOWORD (RandomContext_Random (SysGenRNG)));
+ solarSys->MoonDesc[0].location.x =
+ COSINE (angle, solarSys->MoonDesc[0].radius);
+ solarSys->MoonDesc[0].location.y =
+ SINE (angle, solarSys->MoonDesc[0].radius);
+ }
+
+ return true;
+}
+
+static bool
+GenerateSpathi_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ DWORD rand_val;
+
+ if (matchWorld (solarSys, world, 0, 0))
+ {
+ /* Spathiwa's moon */
+ if (!GET_GAME_STATE (SPATHI_SHIELDED_SELVES)
+ && StartSphereTracking (SPATHI_SHIP))
+ {
+ NotifyOthers (SPATHI_SHIP, IPNL_ALL_CLEAR);
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ CloneShipFragment (SPATHI_SHIP, &GLOBAL (npc_built_ship_q),
+ INFINITE_FLEET);
+
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ InitCommunication (SPATHI_CONVERSATION);
+
+ if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)))
+ {
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+ }
+ return true;
+ }
+
+ DoPlanetaryAnalysis (&solarSys->SysInfo, world);
+ rand_val = RandomContext_GetSeed (SysGenRNG);
+
+ solarSys->SysInfo.PlanetInfo.ScanSeed[BIOLOGICAL_SCAN] = rand_val;
+ GenerateLifeForms (&solarSys->SysInfo, GENERATE_ALL, NULL);
+ rand_val = RandomContext_GetSeed (SysGenRNG);
+
+ solarSys->SysInfo.PlanetInfo.ScanSeed[MINERAL_SCAN] = rand_val;
+ GenerateMineralDeposits (&solarSys->SysInfo, GENERATE_ALL, NULL);
+
+ solarSys->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN] = rand_val;
+
+ solarSys->SysInfo.PlanetInfo.Weather = 0;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 0;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = 28;
+ if (!GET_GAME_STATE (UMGAH_BROADCASTERS))
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (UMGAH_BCS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (UMGAH_BCS_STRTAB));
+ if (!GET_GAME_STATE (SPATHI_SHIELDED_SELVES))
+ { // The first report talks extensively about Spathi
+ // slave-shielding selves. If they never did so, the report
+ // makes no sense, so use an alternate.
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ SetAbsStringTableIndex (
+ solarSys->SysInfo.PlanetInfo.DiscoveryString, 1);
+ }
+ }
+ LoadPlanet (NULL);
+ return true;
+ }
+ else if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ /* visiting Spathiwa */
+ DoPlanetaryAnalysis (&solarSys->SysInfo, world);
+ rand_val = RandomContext_GetSeed (SysGenRNG);
+
+ solarSys->SysInfo.PlanetInfo.ScanSeed[MINERAL_SCAN] = rand_val;
+ GenerateMineralDeposits (&solarSys->SysInfo, GENERATE_ALL, NULL);
+ rand_val = RandomContext_GetSeed (SysGenRNG);
+
+ solarSys->SysInfo.PlanetInfo.ScanSeed[BIOLOGICAL_SCAN] = rand_val;
+
+ solarSys->SysInfo.PlanetInfo.PlanetRadius = 120;
+ solarSys->SysInfo.PlanetInfo.SurfaceGravity =
+ CalcGravity (&solarSys->SysInfo.PlanetInfo);
+ solarSys->SysInfo.PlanetInfo.Weather = 0;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 0;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = 31;
+
+ LoadPlanet (NULL);
+ return true;
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+
+ return true;
+}
+
+static COUNT
+GenerateSpathi_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (matchWorld (solarSys, world, 0, 0))
+ {
+ // This check is redundant since the retrieval bit will keep the
+ // node from showing up again
+ if (GET_GAME_STATE (UMGAH_BROADCASTERS))
+ { // already picked up
+ return 0;
+ }
+
+ return GenerateDefault_generateArtifact (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
+static bool
+GenerateSpathi_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (matchWorld (solarSys, world, 0, 0))
+ {
+ assert (!GET_GAME_STATE (UMGAH_BROADCASTERS) && whichNode == 0);
+
+ GenerateDefault_landerReport (solarSys);
+ SetLanderTakeoff ();
+
+ SET_GAME_STATE (UMGAH_BROADCASTERS, 1);
+ SET_GAME_STATE (UMGAH_BROADCASTERS_ON_SHIP, 1);
+
+ return true; // picked up
+ }
+
+ (void) whichNode;
+ return false;
+}
+
+static COUNT
+GenerateSpathi_generateLife (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ #define NUM_EVIL_ONES 32
+ return GenerateRandomNodes (&solarSys->SysInfo, BIOLOGICAL_SCAN, NUM_EVIL_ONES,
+ NUM_CREATURE_TYPES, whichNode, info);
+ }
+
+ return 0;
+}
+
+static bool
+GenerateSpathi_pickupLife (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ assert (!GET_GAME_STATE (SPATHI_CREATURES_ELIMINATED) &&
+ !GET_GAME_STATE (SPATHI_SHIELDED_SELVES));
+
+ SET_GAME_STATE (SPATHI_CREATURES_EXAMINED, 1);
+ if (countNodesRetrieved (&solarSys->SysInfo.PlanetInfo, BIOLOGICAL_SCAN)
+ + 1 == NUM_EVIL_ONES)
+ { // last creature picked up
+ SET_GAME_STATE (SPATHI_CREATURES_ELIMINATED, 1);
+ }
+
+ return true; // picked up
+ }
+
+ return GenerateDefault_pickupLife (solarSys, world, whichNode);
+}
diff --git a/src/uqm/planets/generate/gensup.c b/src/uqm/planets/generate/gensup.c
new file mode 100644
index 0000000..a618c89
--- /dev/null
+++ b/src/uqm/planets/generate/gensup.c
@@ -0,0 +1,159 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../lander.h"
+#include "../planets.h"
+#include "../../build.h"
+#include "../../comm.h"
+#include "../../globdata.h"
+#include "../../ipdisp.h"
+#include "../../nameref.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+
+static bool GenerateSupox_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateSupox_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+static COUNT GenerateSupox_generateEnergy (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+static bool GenerateSupox_pickupEnergy (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world, COUNT whichNode);
+
+
+const GenerateFunctions generateSupoxFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateSupox_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateSupox_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateSupox_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateSupox_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateSupox_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+
+ solarSys->PlanetDesc[0].data_index = WATER_WORLD;
+ solarSys->PlanetDesc[0].NumPlanets = 2;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 152L / 100;
+ angle = ARCTAN (solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+
+ return true;
+}
+
+static bool
+GenerateSupox_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ if (StartSphereTracking (SUPOX_SHIP))
+ {
+ NotifyOthers (SUPOX_SHIP, IPNL_ALL_CLEAR);
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ CloneShipFragment (SUPOX_SHIP, &GLOBAL (npc_built_ship_q),
+ INFINITE_FLEET);
+
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ InitCommunication (SUPOX_CONVERSATION);
+
+ if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)))
+ {
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+ }
+ return true;
+ }
+ else
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (RUINS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (SUPOX_RUINS_STRTAB));
+ if (GET_GAME_STATE (ULTRON_CONDITION))
+ { // Already picked up the Ultron, skip the report
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ SetAbsStringTableIndex (
+ solarSys->SysInfo.PlanetInfo.DiscoveryString, 1);
+ }
+ }
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+
+ return true;
+}
+
+static bool
+GenerateSupox_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ GenerateDefault_landerReportCycle (solarSys);
+
+ // The artifact can be picked up from any ruin
+ if (!GET_GAME_STATE (ULTRON_CONDITION))
+ { // Just picked up the Ultron from a ruin
+ SetLanderTakeoff ();
+
+ SET_GAME_STATE (ULTRON_CONDITION, 1);
+ }
+
+ return false; // do not remove the node
+ }
+
+ (void) whichNode;
+ return false;
+}
+
+static COUNT
+GenerateSupox_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ return GenerateDefault_generateRuins (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
diff --git a/src/uqm/planets/generate/gensyr.c b/src/uqm/planets/generate/gensyr.c
new file mode 100644
index 0000000..ebf3be4
--- /dev/null
+++ b/src/uqm/planets/generate/gensyr.c
@@ -0,0 +1,102 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../planets.h"
+#include "../../comm.h"
+
+static bool GenerateSyreen_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateSyreen_generateMoons (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *planet);
+static bool GenerateSyreen_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+
+
+const GenerateFunctions generateSyreenFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateSyreen_generatePlanets,
+ /* .generateMoons = */ GenerateSyreen_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateSyreen_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateDefault_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateDefault_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateSyreen_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ GenerateDefault_generatePlanets (solarSys);
+
+ solarSys->PlanetDesc[0].data_index = WATER_WORLD | PLANET_SHIELDED;
+ solarSys->PlanetDesc[0].NumPlanets = 1;
+
+ return true;
+}
+
+static bool
+GenerateSyreen_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet)
+{
+ GenerateDefault_generateMoons (solarSys, planet);
+
+ if (matchWorld (solarSys, planet, 0, MATCH_PLANET))
+ {
+ solarSys->MoonDesc[0].data_index = HIERARCHY_STARBASE;
+ solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS;
+ solarSys->MoonDesc[0].location.x =
+ COSINE (QUADRANT, solarSys->MoonDesc[0].radius);
+ solarSys->MoonDesc[0].location.y =
+ SINE (QUADRANT, solarSys->MoonDesc[0].radius);
+ }
+
+ return true;
+}
+
+static bool
+GenerateSyreen_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ /* Syreen home planet */
+ GenerateDefault_generateOrbital (solarSys, world);
+
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = 19;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 0;
+ solarSys->SysInfo.PlanetInfo.Weather = 0;
+ solarSys->SysInfo.PlanetInfo.AtmoDensity = EARTH_ATMOSPHERE * 9 / 10;
+ return true;
+ }
+
+ if (matchWorld (solarSys, world, 0, 0))
+ {
+ /* Starbase */
+ InitCommunication (SYREEN_CONVERSATION);
+ return true;
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+
+ return true;
+}
+
diff --git a/src/uqm/planets/generate/genthrad.c b/src/uqm/planets/generate/genthrad.c
new file mode 100644
index 0000000..875e582
--- /dev/null
+++ b/src/uqm/planets/generate/genthrad.c
@@ -0,0 +1,217 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../lander.h"
+#include "../planets.h"
+#include "../../build.h"
+#include "../../comm.h"
+#include "../../gendef.h"
+#include "../../starmap.h"
+#include "../../globdata.h"
+#include "../../ipdisp.h"
+#include "../../nameref.h"
+#include "../../setup.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+
+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);
+
+
+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)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+
+ if (CurStarDescPtr->Index == AQUA_HELIX_DEFINED)
+ {
+ solarSys->PlanetDesc[0].data_index = PRIMORDIAL_WORLD;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 65L / 100;
+ angle = ARCTAN (solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+ }
+ else /* CurStarDescPtr->Index == THRADD_DEFINED */
+ {
+ solarSys->PlanetDesc[0].data_index = WATER_WORLD;
+ solarSys->PlanetDesc[0].NumPlanets = 0;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 98L / 100;
+ angle = ARCTAN (solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+ }
+ return true;
+}
+
+static bool
+GenerateThraddash_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ if (StartSphereTracking (THRADDASH_SHIP)
+ && (CurStarDescPtr->Index == THRADD_DEFINED
+ || (!GET_GAME_STATE (HELIX_UNPROTECTED)
+ && (BYTE)(GET_GAME_STATE (THRADD_MISSION) - 1) >= 3)))
+ {
+ NotifyOthers (THRADDASH_SHIP, IPNL_ALL_CLEAR);
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ CloneShipFragment (THRADDASH_SHIP, &GLOBAL (npc_built_ship_q),
+ INFINITE_FLEET);
+
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ if (CurStarDescPtr->Index == THRADD_DEFINED)
+ {
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ }
+ else
+ {
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 6);
+ }
+ InitCommunication (THRADD_CONVERSATION);
+
+ if (GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))
+ return true;
+
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+
+ if (CurStarDescPtr->Index == THRADD_DEFINED
+ || (!GET_GAME_STATE (HELIX_UNPROTECTED)
+ && (BYTE)(GET_GAME_STATE (THRADD_MISSION) - 1) >= 3))
+ return true;
+
+ RepairSISBorder ();
+ }
+
+ if (CurStarDescPtr->Index == AQUA_HELIX_DEFINED
+ && !GET_GAME_STATE (AQUA_HELIX))
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (AQUA_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (AQUA_STRTAB));
+ }
+ else if (CurStarDescPtr->Index == THRADD_DEFINED)
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (RUINS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (RUINS_STRTAB));
+ }
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+ return true;
+}
+
+static COUNT
+GenerateThraddash_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (CurStarDescPtr->Index == THRADD_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ return GenerateDefault_generateRuins (solarSys, whichNode, info);
+ }
+
+ if (CurStarDescPtr->Index == AQUA_HELIX_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ // This check is redundant since the retrieval bit will keep the
+ // node from showing up again
+ if (GET_GAME_STATE (AQUA_HELIX))
+ { // already picked up
+ return 0;
+ }
+
+ return GenerateDefault_generateArtifact (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
+static bool
+GenerateThraddash_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (CurStarDescPtr->Index == THRADD_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ // Standard ruins report
+ GenerateDefault_landerReportCycle (solarSys);
+ return false;
+ }
+
+ if (CurStarDescPtr->Index == AQUA_HELIX_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ assert (!GET_GAME_STATE (AQUA_HELIX) && whichNode == 0);
+
+ GenerateDefault_landerReport (solarSys);
+ SetLanderTakeoff ();
+
+ SET_GAME_STATE (HELIX_VISITS, 0);
+ SET_GAME_STATE (AQUA_HELIX, 1);
+ SET_GAME_STATE (AQUA_HELIX_ON_SHIP, 1);
+ SET_GAME_STATE (HELIX_UNPROTECTED, 1);
+
+ return true; // picked up
+ }
+
+ (void) whichNode;
+ return false;
+}
diff --git a/src/uqm/planets/generate/gentrap.c b/src/uqm/planets/generate/gentrap.c
new file mode 100644
index 0000000..e8451cd
--- /dev/null
+++ b/src/uqm/planets/generate/gentrap.c
@@ -0,0 +1,80 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../planets.h"
+
+
+static bool GenerateTrap_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateTrap_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+
+
+const GenerateFunctions generateTrapFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateTrap_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateTrap_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateDefault_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateDefault_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateTrap_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+
+ solarSys->PlanetDesc[0].data_index = TELLURIC_WORLD;
+ solarSys->PlanetDesc[0].NumPlanets = 1;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 203L / 100;
+ angle = ARCTAN (solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+
+ return true;
+}
+
+static bool
+GenerateTrap_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ GenerateDefault_generateOrbital (solarSys, world);
+
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ solarSys->SysInfo.PlanetInfo.AtmoDensity = EARTH_ATMOSPHERE * 2;
+ solarSys->SysInfo.PlanetInfo.SurfaceTemperature = 35;
+ solarSys->SysInfo.PlanetInfo.Weather = 3;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 1;
+ }
+
+ return true;
+}
+
diff --git a/src/uqm/planets/generate/genutw.c b/src/uqm/planets/generate/genutw.c
new file mode 100644
index 0000000..71ac2aa
--- /dev/null
+++ b/src/uqm/planets/generate/genutw.c
@@ -0,0 +1,269 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../lander.h"
+#include "../planets.h"
+#include "../../build.h"
+#include "../../comm.h"
+#include "../../gendef.h"
+#include "../../starmap.h"
+#include "../../globdata.h"
+#include "../../ipdisp.h"
+#include "../../nameref.h"
+#include "../../setup.h"
+#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);
+
+
+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)
+{
+ if (CurStarDescPtr->Index == BOMB_DEFINED
+ && !GET_GAME_STATE (UTWIG_BOMB))
+ {
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+ }
+ else
+ {
+ GenerateDefault_initNpcs (solarSys);
+ }
+
+ return true;
+}
+
+static bool
+GenerateUtwig_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+
+ if (CurStarDescPtr->Index == UTWIG_DEFINED)
+ {
+ solarSys->PlanetDesc[0].data_index = WATER_WORLD;
+ solarSys->PlanetDesc[0].NumPlanets = 1;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 174L / 100;
+ angle = ARCTAN (solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+ }
+
+ return true;
+}
+
+static bool
+GenerateUtwig_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if ((CurStarDescPtr->Index == UTWIG_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ || (CurStarDescPtr->Index == BOMB_DEFINED
+ && matchWorld (solarSys, world, 5, 1)
+ && !GET_GAME_STATE (UTWIG_BOMB)))
+ {
+ if ((CurStarDescPtr->Index == UTWIG_DEFINED
+ || !GET_GAME_STATE (UTWIG_HAVE_ULTRON))
+ && StartSphereTracking (UTWIG_SHIP))
+ {
+ NotifyOthers (UTWIG_SHIP, IPNL_ALL_CLEAR);
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ CloneShipFragment (UTWIG_SHIP,
+ &GLOBAL (npc_built_ship_q), INFINITE_FLEET);
+
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ if (CurStarDescPtr->Index == UTWIG_DEFINED)
+ {
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ }
+ else
+ {
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 6);
+ }
+ InitCommunication (UTWIG_CONVERSATION);
+
+ if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)))
+ {
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+ }
+ return true;
+ }
+
+ if (CurStarDescPtr->Index == BOMB_DEFINED
+ && !GET_GAME_STATE (BOMB_UNPROTECTED)
+ && StartSphereTracking (DRUUGE_SHIP))
+ {
+ COUNT i;
+
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ for (i = 0; i < 5; ++i)
+ {
+ CloneShipFragment (DRUUGE_SHIP,
+ &GLOBAL (npc_built_ship_q), 0);
+ }
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 6);
+ InitCommunication (DRUUGE_CONVERSATION);
+
+ if (GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))
+ return true;
+
+ {
+ BOOLEAN DruugeSurvivors;
+
+ DruugeSurvivors =
+ GetHeadLink (&GLOBAL (npc_built_ship_q)) != 0;
+
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+
+ if (DruugeSurvivors)
+ return true;
+
+ RepairSISBorder ();
+ SET_GAME_STATE (BOMB_UNPROTECTED, 1);
+ }
+ }
+
+ if (CurStarDescPtr->Index == BOMB_DEFINED)
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (BOMB_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (BOMB_STRTAB));
+ }
+ else
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (RUINS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (RUINS_STRTAB));
+ }
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+
+ if (CurStarDescPtr->Index == UTWIG_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ solarSys->SysInfo.PlanetInfo.Weather = 1;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 1;
+ }
+
+ return true;
+}
+
+static COUNT
+GenerateUtwig_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (CurStarDescPtr->Index == UTWIG_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ return GenerateDefault_generateRuins (solarSys, whichNode, info);
+ }
+
+ if (CurStarDescPtr->Index == BOMB_DEFINED
+ && matchWorld (solarSys, world, 5, 1))
+ {
+ // This check is redundant since the retrieval bit will keep the
+ // node from showing up again
+ if (GET_GAME_STATE (UTWIG_BOMB))
+ { // already picked up
+ return 0;
+ }
+
+ return GenerateDefault_generateArtifact (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
+static bool
+GenerateUtwig_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (CurStarDescPtr->Index == UTWIG_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ // Standard ruins report
+ GenerateDefault_landerReportCycle (solarSys);
+ return false;
+ }
+
+ if (CurStarDescPtr->Index == BOMB_DEFINED
+ && matchWorld (solarSys, world, 5, 1))
+ {
+ assert (!GET_GAME_STATE (UTWIG_BOMB) && whichNode == 0);
+
+ GenerateDefault_landerReport (solarSys);
+ SetLanderTakeoff ();
+
+ SET_GAME_STATE (UTWIG_BOMB, 1);
+ SET_GAME_STATE (UTWIG_BOMB_ON_SHIP, 1);
+ SET_GAME_STATE (DRUUGE_MANNER, 1);
+ SET_GAME_STATE (DRUUGE_VISITS, 0);
+ SET_GAME_STATE (DRUUGE_HOME_VISITS, 0);
+
+ return true; // picked up
+ }
+
+ (void) whichNode;
+ return false;
+}
diff --git a/src/uqm/planets/generate/genvault.c b/src/uqm/planets/generate/genvault.c
new file mode 100644
index 0000000..e189897
--- /dev/null
+++ b/src/uqm/planets/generate/genvault.c
@@ -0,0 +1,130 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../lander.h"
+#include "../planets.h"
+#include "../../globdata.h"
+#include "../../nameref.h"
+#include "../../resinst.h"
+#include "libs/mathlib.h"
+
+
+static bool GenerateVault_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+static COUNT GenerateVault_generateEnergy (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+static bool GenerateVault_pickupEnergy (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world, COUNT whichNode);
+
+
+const GenerateFunctions generateVaultFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateDefault_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateVault_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateVault_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateVault_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateVault_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 0, 0))
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (VAULT_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (VAULT_STRTAB));
+ if (GET_GAME_STATE (SHIP_VAULT_UNLOCKED))
+ {
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ SetAbsStringTableIndex (
+ solarSys->SysInfo.PlanetInfo.DiscoveryString, 2);
+ }
+ else if (GET_GAME_STATE (SYREEN_SHUTTLE_ON_SHIP))
+ {
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ SetAbsStringTableIndex (
+ solarSys->SysInfo.PlanetInfo.DiscoveryString, 1);
+ }
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+ return true;
+}
+
+static COUNT
+GenerateVault_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (matchWorld (solarSys, world, 0, 0))
+ {
+ return GenerateDefault_generateArtifact (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
+static bool
+GenerateVault_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (matchWorld (solarSys, world, 0, 0))
+ {
+ assert (whichNode == 0);
+
+ if (GET_GAME_STATE (SHIP_VAULT_UNLOCKED))
+ { // Give the final report, "omg empty" and whatnot
+ GenerateDefault_landerReportCycle (solarSys);
+ }
+ else if (GET_GAME_STATE (SYREEN_SHUTTLE_ON_SHIP))
+ {
+ GenerateDefault_landerReportCycle (solarSys);
+ SetLanderTakeoff ();
+
+ SET_GAME_STATE (SHIP_VAULT_UNLOCKED, 1);
+ SET_GAME_STATE (SYREEN_SHUTTLE_ON_SHIP, 0);
+ SET_GAME_STATE (SYREEN_HOME_VISITS, 0);
+ }
+ else
+ {
+ GenerateDefault_landerReport (solarSys);
+
+ if (!GET_GAME_STATE (KNOW_SYREEN_VAULT))
+ {
+ SET_GAME_STATE (KNOW_SYREEN_VAULT, 1);
+ }
+ }
+
+ // The Vault cannot be "picked up". It is always on the surface.
+ return false;
+ }
+
+ (void) whichNode;
+ return false;
+}
diff --git a/src/uqm/planets/generate/genvux.c b/src/uqm/planets/generate/genvux.c
new file mode 100644
index 0000000..d4a0642
--- /dev/null
+++ b/src/uqm/planets/generate/genvux.c
@@ -0,0 +1,329 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../lander.h"
+#include "../lifeform.h"
+#include "../planets.h"
+#include "../../build.h"
+#include "../../comm.h"
+#include "../../gendef.h"
+#include "../../starmap.h"
+#include "../../globdata.h"
+#include "../../ipdisp.h"
+#include "../../nameref.h"
+#include "../../setup.h"
+#include "../../sounds.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+
+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);
+
+
+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)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+
+ if (CurStarDescPtr->Index == MAIDENS_DEFINED)
+ {
+ GenerateDefault_generatePlanets (solarSys);
+ // XXX: this is the second time that this function is
+ // called. Is it safe to remove one, or does this change
+ // the RNG so that the outcome is different?
+ solarSys->PlanetDesc[0].data_index = REDUX_WORLD;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 212L / 100;
+ angle = ARCTAN (solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+ }
+ else
+ {
+ if (CurStarDescPtr->Index == VUX_DEFINED)
+ {
+ 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) */
+ {
+ memmove (&solarSys->PlanetDesc[1], &solarSys->PlanetDesc[0],
+ sizeof (solarSys->PlanetDesc[0])
+ * solarSys->SunDesc[0].NumPlanets);
+ ++solarSys->SunDesc[0].NumPlanets;
+
+ angle = HALF_CIRCLE - OCTANT;
+ solarSys->PlanetDesc[0].data_index = WATER_WORLD;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 110L / 100;
+ solarSys->PlanetDesc[0].NumPlanets = 0;
+ }
+
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].rand_seed = MAKE_DWORD (
+ solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ }
+ return true;
+}
+
+static bool
+GenerateVux_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if ((matchWorld (solarSys, world, 0, MATCH_PLANET)
+ && (CurStarDescPtr->Index == VUX_DEFINED
+ || (CurStarDescPtr->Index == MAIDENS_DEFINED
+ && !GET_GAME_STATE (ZEX_IS_DEAD))))
+ && StartSphereTracking (VUX_SHIP))
+ {
+ NotifyOthers (VUX_SHIP, IPNL_ALL_CLEAR);
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ CloneShipFragment (VUX_SHIP,
+ &GLOBAL (npc_built_ship_q), INFINITE_FLEET);
+ if (CurStarDescPtr->Index == VUX_DEFINED)
+ {
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ }
+ else
+ {
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 6);
+ }
+
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ InitCommunication (VUX_CONVERSATION);
+
+ if (GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))
+ return true;
+
+ {
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+
+ if (CurStarDescPtr->Index == VUX_DEFINED
+ || !GET_GAME_STATE (ZEX_IS_DEAD))
+ return true;
+
+ RepairSISBorder ();
+ }
+ }
+
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ if (CurStarDescPtr->Index == MAIDENS_DEFINED)
+ {
+ if (!GET_GAME_STATE (SHOFIXTI_MAIDENS))
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] = CaptureDrawable (
+ LoadGraphic (MAIDENS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (
+ LoadStringTable (MAIDENS_STRTAB));
+ }
+ }
+ else if (CurStarDescPtr->Index == VUX_BEAST_DEFINED)
+ {
+ if (!GET_GAME_STATE (VUX_BEAST))
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] = 0;
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (
+ LoadStringTable (BEAST_STRTAB));
+ }
+ }
+ else
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (RUINS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (RUINS_STRTAB));
+ }
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ solarSys->SysInfo.PlanetInfo.Weather = 2;
+ solarSys->SysInfo.PlanetInfo.Tectonics = 0;
+ }
+
+ return true;
+}
+
+static COUNT
+GenerateVux_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (CurStarDescPtr->Index == MAIDENS_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ // This check is redundant since the retrieval bit will keep the
+ // node from showing up again
+ if (GET_GAME_STATE (SHOFIXTI_MAIDENS))
+ { // already picked up
+ return 0;
+ }
+
+ if (info)
+ {
+ info->loc_pt.x = MAP_WIDTH / 3;
+ info->loc_pt.y = MAP_HEIGHT * 5 / 8;
+ }
+
+ return 1; // only matters when count is requested
+ }
+
+ if (CurStarDescPtr->Index == VUX_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ return GenerateDefault_generateRuins (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
+static bool
+GenerateVux_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (CurStarDescPtr->Index == MAIDENS_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ assert (!GET_GAME_STATE (SHOFIXTI_MAIDENS) && whichNode == 0);
+
+ GenerateDefault_landerReport (solarSys);
+ SetLanderTakeoff ();
+
+ SET_GAME_STATE (SHOFIXTI_MAIDENS, 1);
+ SET_GAME_STATE (MAIDENS_ON_SHIP, 1);
+
+ return true; // picked up
+ }
+
+ if (CurStarDescPtr->Index == VUX_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ // Standard ruins report
+ GenerateDefault_landerReportCycle (solarSys);
+ return false;
+ }
+
+ (void) whichNode;
+ return false;
+}
+
+static COUNT
+GenerateVux_generateLife (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (CurStarDescPtr->Index == MAIDENS_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ static const SBYTE life[] =
+ {
+ 9, 9, 9, 9, /* Carousel Beast */
+ 14, 14, 14, 14, /* Amorphous Trandicula */
+ 18, 18, 18, 18, /* Penguin Cyclops */
+ -1 /* term */
+ };
+ return GeneratePresetLife (&solarSys->SysInfo, life, whichNode, info);
+ }
+
+ if (CurStarDescPtr->Index == VUX_BEAST_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ static const SBYTE life[] =
+ {
+ NUM_CREATURE_TYPES + 2, /* VUX Beast */
+ // Must be the first node, see pickupLife() below
+ 3, 3, 3, 3, 3, /* Whackin' Bush */
+ 8, 8, 8, 8, 8, /* Glowing Medusa */
+ -1 /* term */
+ };
+ return GeneratePresetLife (&solarSys->SysInfo, life, whichNode, info);
+ }
+
+ return GenerateDefault_generateLife (solarSys, world, whichNode, info);
+}
+
+static bool
+GenerateVux_pickupLife (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (CurStarDescPtr->Index == VUX_BEAST_DEFINED
+ && matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ if (whichNode == 0)
+ { // Picked up Zex' Beauty
+ assert (!GET_GAME_STATE (VUX_BEAST));
+
+ GenerateDefault_landerReport (solarSys);
+ SetLanderTakeoff ();
+
+ SET_GAME_STATE (VUX_BEAST, 1);
+ SET_GAME_STATE (VUX_BEAST_ON_SHIP, 1);
+ }
+
+ return true; // picked up
+ }
+
+ return GenerateDefault_pickupLife (solarSys, world, whichNode);
+}
diff --git a/src/uqm/planets/generate/genwreck.c b/src/uqm/planets/generate/genwreck.c
new file mode 100644
index 0000000..05e956e
--- /dev/null
+++ b/src/uqm/planets/generate/genwreck.c
@@ -0,0 +1,111 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../lander.h"
+#include "../planets.h"
+#include "../../globdata.h"
+#include "../../nameref.h"
+#include "../../resinst.h"
+#include "libs/mathlib.h"
+
+
+static bool GenerateWreck_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+static COUNT GenerateWreck_generateEnergy (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+static bool GenerateWreck_pickupEnergy (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world, COUNT whichNode);
+
+
+const GenerateFunctions generateWreckFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateDefault_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateWreck_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateWreck_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateWreck_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateWreck_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 6, MATCH_PLANET))
+ {
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (WRECK_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (WRECK_STRTAB));
+ if (GET_GAME_STATE (PORTAL_KEY))
+ { // Already picked it up, skip the first report
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ SetAbsStringTableIndex (
+ solarSys->SysInfo.PlanetInfo.DiscoveryString, 1);
+ }
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+ return true;
+}
+
+static COUNT
+GenerateWreck_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (matchWorld (solarSys, world, 6, MATCH_PLANET))
+ {
+ return GenerateDefault_generateArtifact (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
+static bool
+GenerateWreck_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (matchWorld (solarSys, world, 6, MATCH_PLANET))
+ {
+ assert (whichNode == 0);
+
+ GenerateDefault_landerReportCycle (solarSys);
+
+ if (!GET_GAME_STATE (PORTAL_KEY))
+ {
+ SetLanderTakeoff ();
+
+ SET_GAME_STATE (PORTAL_KEY, 1);
+ SET_GAME_STATE (PORTAL_KEY_ON_SHIP, 1);
+ }
+
+ // The Wreck cannot be "picked up". It is always on the surface.
+ return false;
+ }
+
+ (void) whichNode;
+ return false;
+}
diff --git a/src/uqm/planets/generate/genyeh.c b/src/uqm/planets/generate/genyeh.c
new file mode 100644
index 0000000..caae543
--- /dev/null
+++ b/src/uqm/planets/generate/genyeh.c
@@ -0,0 +1,140 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../planets.h"
+#include "../../build.h"
+#include "../../comm.h"
+#include "../../globdata.h"
+#include "../../ipdisp.h"
+#include "../../nameref.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+
+static bool GenerateYehat_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateYehat_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+static COUNT GenerateYehat_generateEnergy (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+static bool GenerateYehat_pickupEnergy (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world, COUNT whichNode);
+
+
+const GenerateFunctions generateYehatFunctions = {
+ /* .initNpcs = */ GenerateDefault_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateYehat_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateYehat_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateYehat_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateYehat_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateYehat_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+ solarSys->PlanetDesc[0].data_index = WATER_WORLD;
+ solarSys->PlanetDesc[0].NumPlanets = 1;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 106L / 100;
+ angle = ARCTAN (solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+
+ return true;
+}
+
+static bool
+GenerateYehat_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ if (StartSphereTracking (YEHAT_SHIP))
+ {
+ NotifyOthers (YEHAT_SHIP, IPNL_ALL_CLEAR);
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ CloneShipFragment (YEHAT_SHIP, &GLOBAL (npc_built_ship_q),
+ INFINITE_FLEET);
+
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ InitCommunication (YEHAT_CONVERSATION);
+
+ if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)))
+ {
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+ }
+
+ return true;
+ }
+
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (RUINS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (RUINS_STRTAB));
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+ return true;
+}
+
+static COUNT
+GenerateYehat_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ return GenerateDefault_generateRuins (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
+static bool
+GenerateYehat_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ // Standard ruins report
+ GenerateDefault_landerReportCycle (solarSys);
+ return false;
+ }
+
+ (void) whichNode;
+ return false;
+}
diff --git a/src/uqm/planets/generate/genzfpscout.c b/src/uqm/planets/generate/genzfpscout.c
new file mode 100644
index 0000000..93a6d5d
--- /dev/null
+++ b/src/uqm/planets/generate/genzfpscout.c
@@ -0,0 +1,96 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../../build.h"
+#include "../../globdata.h"
+#include "../../grpinfo.h"
+#include "../../state.h"
+
+
+static bool GenerateZoqFotPikScout_initNpcs (SOLARSYS_STATE *solarSys);
+static bool GenerateZoqFotPikScout_reinitNpcs (SOLARSYS_STATE *solarSys);
+
+
+const GenerateFunctions generateZoqFotPikScoutFunctions = {
+ /* .initNpcs = */ GenerateZoqFotPikScout_initNpcs,
+ /* .reinitNpcs = */ GenerateZoqFotPikScout_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateDefault_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateDefault_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateDefault_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateDefault_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateZoqFotPikScout_initNpcs (SOLARSYS_STATE *solarSys)
+{
+ if (!GET_GAME_STATE (MET_ZOQFOT))
+ {
+ GLOBAL (BattleGroupRef) = GET_GAME_STATE_32 (ZOQFOT_GRPOFFS0);
+ if (GLOBAL (BattleGroupRef) == 0)
+ {
+ CloneShipFragment (ZOQFOTPIK_SHIP,
+ &GLOBAL (npc_built_ship_q), 0);
+ GLOBAL (BattleGroupRef) = PutGroupInfo (GROUPS_ADD_NEW, 1);
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ SET_GAME_STATE_32 (ZOQFOT_GRPOFFS0, GLOBAL (BattleGroupRef));
+ }
+ }
+
+ GenerateDefault_initNpcs (solarSys);
+
+ return true;
+}
+
+static bool
+GenerateZoqFotPikScout_reinitNpcs (SOLARSYS_STATE *solarSys)
+{
+ HIPGROUP hGroup;
+ IP_GROUP *GroupPtr;
+
+ GenerateDefault_reinitNpcs (solarSys);
+
+ if (!GLOBAL (BattleGroupRef))
+ return true; // nothing to check
+
+ hGroup = GetHeadLink (&GLOBAL (ip_group_q));
+ if (!hGroup)
+ return true; // still nothing to check
+
+ GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ // REFORM_GROUP was set in ipdisp.c:ip_group_collision()
+ // during a collision with the flagship.
+ if (GroupPtr->race_id == ZOQFOTPIK_SHIP
+ && (GroupPtr->task & REFORM_GROUP))
+ {
+ GroupPtr->task = FLEE | IGNORE_FLAGSHIP | REFORM_GROUP;
+ GroupPtr->dest_loc = 0;
+ }
+ UnlockIpGroup (&GLOBAL (ip_group_q), hGroup);
+
+ return true;
+}
+
diff --git a/src/uqm/planets/generate/genzoq.c b/src/uqm/planets/generate/genzoq.c
new file mode 100644
index 0000000..9b30f89
--- /dev/null
+++ b/src/uqm/planets/generate/genzoq.c
@@ -0,0 +1,170 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "genall.h"
+#include "../planets.h"
+#include "../../build.h"
+#include "../../comm.h"
+#include "../../globdata.h"
+#include "../../nameref.h"
+#include "../../state.h"
+#include "libs/mathlib.h"
+
+
+static bool GenerateZoqFotPik_initNpcs (SOLARSYS_STATE *solarSys);
+static bool GenerateZoqFotPik_generatePlanets (SOLARSYS_STATE *solarSys);
+static bool GenerateZoqFotPik_generateOrbital (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world);
+static COUNT GenerateZoqFotPik_generateEnergy (const SOLARSYS_STATE *,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *);
+static bool GenerateZoqFotPik_pickupEnergy (SOLARSYS_STATE *solarSys,
+ PLANET_DESC *world, COUNT whichNode);
+
+
+const GenerateFunctions generateZoqFotPikFunctions = {
+ /* .initNpcs = */ GenerateZoqFotPik_initNpcs,
+ /* .reinitNpcs = */ GenerateDefault_reinitNpcs,
+ /* .uninitNpcs = */ GenerateDefault_uninitNpcs,
+ /* .generatePlanets = */ GenerateZoqFotPik_generatePlanets,
+ /* .generateMoons = */ GenerateDefault_generateMoons,
+ /* .generateName = */ GenerateDefault_generateName,
+ /* .generateOrbital = */ GenerateZoqFotPik_generateOrbital,
+ /* .generateMinerals = */ GenerateDefault_generateMinerals,
+ /* .generateEnergy = */ GenerateZoqFotPik_generateEnergy,
+ /* .generateLife = */ GenerateDefault_generateLife,
+ /* .pickupMinerals = */ GenerateDefault_pickupMinerals,
+ /* .pickupEnergy = */ GenerateZoqFotPik_pickupEnergy,
+ /* .pickupLife = */ GenerateDefault_pickupLife,
+};
+
+
+static bool
+GenerateZoqFotPik_initNpcs (SOLARSYS_STATE *solarSys)
+{
+ if (GET_GAME_STATE (ZOQFOT_DISTRESS) != 1)
+ GenerateDefault_initNpcs (solarSys);
+
+ return true;
+}
+
+static bool
+GenerateZoqFotPik_generatePlanets (SOLARSYS_STATE *solarSys)
+{
+ COUNT angle;
+
+ GenerateDefault_generatePlanets (solarSys);
+
+ solarSys->PlanetDesc[0].data_index = REDUX_WORLD;
+ solarSys->PlanetDesc[0].NumPlanets = 1;
+ solarSys->PlanetDesc[0].radius = EARTH_RADIUS * 138L / 100;
+ angle = ARCTAN (solarSys->PlanetDesc[0].location.x,
+ solarSys->PlanetDesc[0].location.y);
+ solarSys->PlanetDesc[0].location.x =
+ COSINE (angle, solarSys->PlanetDesc[0].radius);
+ solarSys->PlanetDesc[0].location.y =
+ SINE (angle, solarSys->PlanetDesc[0].radius);
+
+ return true;
+}
+
+static bool
+GenerateZoqFotPik_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ if (StartSphereTracking (ZOQFOTPIK_SHIP))
+ {
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ if (GET_GAME_STATE (ZOQFOT_DISTRESS))
+ {
+ CloneShipFragment (BLACK_URQUAN_SHIP,
+ &GLOBAL (npc_built_ship_q), 0);
+
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ InitCommunication (BLACKURQ_CONVERSATION);
+
+ if (GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))
+ return true;
+
+ if (GetHeadLink (&GLOBAL (npc_built_ship_q)))
+ {
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+ return true;
+ }
+ }
+
+ CloneShipFragment (ZOQFOTPIK_SHIP, &GLOBAL (npc_built_ship_q),
+ INFINITE_FLEET);
+
+ GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ InitCommunication (ZOQFOTPIK_CONVERSATION);
+
+ if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)))
+ {
+ GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
+ ReinitQueue (&GLOBAL (npc_built_ship_q));
+ GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
+ }
+
+ return true;
+ }
+
+ LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo);
+ solarSys->PlanetSideFrame[1] =
+ CaptureDrawable (LoadGraphic (RUINS_MASK_PMAP_ANIM));
+ solarSys->SysInfo.PlanetInfo.DiscoveryString =
+ CaptureStringTable (LoadStringTable (RUINS_STRTAB));
+ }
+
+ GenerateDefault_generateOrbital (solarSys, world);
+ return true;
+}
+
+static COUNT
+GenerateZoqFotPik_generateEnergy (const SOLARSYS_STATE *solarSys,
+ const PLANET_DESC *world, COUNT whichNode, NODE_INFO *info)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ return GenerateDefault_generateRuins (solarSys, whichNode, info);
+ }
+
+ return 0;
+}
+
+static bool
+GenerateZoqFotPik_pickupEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
+ COUNT whichNode)
+{
+ if (matchWorld (solarSys, world, 0, MATCH_PLANET))
+ {
+ // Standard ruins report
+ GenerateDefault_landerReportCycle (solarSys);
+ return false;
+ }
+
+ (void) whichNode;
+ return false;
+}