diff options
Diffstat (limited to 'src/uqm/load.c')
-rw-r--r-- | src/uqm/load.c | 774 |
1 files changed, 774 insertions, 0 deletions
diff --git a/src/uqm/load.c b/src/uqm/load.c new file mode 100644 index 0000000..2e7dcbd --- /dev/null +++ b/src/uqm/load.c @@ -0,0 +1,774 @@ +//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 <assert.h> + +#include "build.h" +#include "encount.h" +#include "starmap.h" +#include "libs/file.h" +#include "globdata.h" +#include "options.h" +#include "save.h" +#include "setup.h" +#include "state.h" +#include "grpintrn.h" + +#include "libs/tasklib.h" +#include "libs/log.h" +#include "libs/misc.h" + +//#define DEBUG_LOAD + +ACTIVITY NextActivity; + +static inline size_t +read_8 (void *fp, BYTE *v) +{ + BYTE t; + if (!v) /* read value ignored */ + v = &t; + return ReadResFile (v, 1, 1, fp); +} + +static inline size_t +read_16 (void *fp, UWORD *v) +{ + UWORD t = 0; + int shift, i; + for (i = 0, shift = 0; i < 2; ++i, shift += 8) + { + BYTE b; + if (read_8 (fp, &b) != 1) + return 0; + t |= ((UWORD)b) << shift; + } + + if (v) + *v = t; + + return 1; +} + +static inline size_t +read_16s (void *fp, SWORD *v) +{ + return read_16 (fp, (UWORD *) v); +} + +static inline size_t +read_32 (void *fp, DWORD *v) +{ + DWORD t = 0; + int shift, i; + for (i = 0, shift = 0; i < 4; ++i, shift += 8) + { + BYTE b; + if (read_8 (fp, &b) != 1) + return 0; + t |= ((DWORD)b) << shift; + } + + if (v) + *v = t; + + return 1; +} + +static inline size_t +read_32s (void *fp, SDWORD *v) +{ + return read_32 (fp, (DWORD *) v); +} + +static inline size_t +read_a8 (void *fp, BYTE *ar, COUNT count) +{ + assert (ar != NULL); + return ReadResFile (ar, 1, count, fp) == count; +} + +static inline size_t +read_a8s (void *fp, char *ar, COUNT count) +{ + return read_a8(fp, (BYTE *) ar, count); +} + +static inline size_t +skip_8 (void *fp, COUNT count) +{ + int i; + for (i = 0; i < count; ++i) + { + if (read_8(fp, NULL) != 1) + return 0; + } + return 1; +} + +static inline size_t +read_str (void *fp, char *str, COUNT count) +{ + // no type conversion needed for strings + return read_a8 (fp, (BYTE *)str, count); +} + +static inline size_t +read_a16 (void *fp, UWORD *ar, COUNT count) +{ + assert (ar != NULL); + + for ( ; count > 0; --count, ++ar) + { + if (read_16 (fp, ar) != 1) + return 0; + } + return 1; +} + +static void +LoadShipQueue (void *fh, QUEUE *pQueue, DWORD size) +{ + COUNT num_links = size / 11; + + while (num_links--) + { + HSHIPFRAG hStarShip; + SHIP_FRAGMENT *FragPtr; + COUNT Index; + + read_16 (fh, &Index); + + hStarShip = CloneShipFragment (Index, pQueue, 0); + FragPtr = LockShipFrag (pQueue, hStarShip); + + // Read SHIP_FRAGMENT elements + read_8 (fh, &FragPtr->captains_name_index); + read_8 (fh, &FragPtr->race_id); + read_8 (fh, &FragPtr->index); + read_16 (fh, &FragPtr->crew_level); + read_16 (fh, &FragPtr->max_crew); + read_8 (fh, &FragPtr->energy_level); + read_8 (fh, &FragPtr->max_energy); + + UnlockShipFrag (pQueue, hStarShip); + } +} + +static void +LoadRaceQueue (void *fh, QUEUE *pQueue, DWORD size) +{ + COUNT num_links = size / 30; + + while (num_links--) + { + HFLEETINFO hStarShip; + FLEET_INFO *FleetPtr; + COUNT Index; + + read_16 (fh, &Index); + + hStarShip = GetStarShipFromIndex (pQueue, Index); + FleetPtr = LockFleetInfo (pQueue, hStarShip); + + // Read FLEET_INFO elements + read_16 (fh, &FleetPtr->allied_state); + read_8 (fh, &FleetPtr->days_left); + read_8 (fh, &FleetPtr->growth_fract); + read_16 (fh, &FleetPtr->crew_level); + read_16 (fh, &FleetPtr->max_crew); + read_8 (fh, &FleetPtr->growth); + read_8 (fh, &FleetPtr->max_energy); + read_16s(fh, &FleetPtr->loc.x); + read_16s(fh, &FleetPtr->loc.y); + + read_16 (fh, &FleetPtr->actual_strength); + read_16 (fh, &FleetPtr->known_strength); + read_16s(fh, &FleetPtr->known_loc.x); + read_16s(fh, &FleetPtr->known_loc.y); + read_8 (fh, &FleetPtr->growth_err_term); + read_8 (fh, &FleetPtr->func_index); + read_16s(fh, &FleetPtr->dest_loc.x); + read_16s(fh, &FleetPtr->dest_loc.y); + + UnlockFleetInfo (pQueue, hStarShip); + } +} + +static void +LoadGroupQueue (void *fh, QUEUE *pQueue, DWORD size) +{ + COUNT num_links = size / 13; + + while (num_links--) + { + HIPGROUP hGroup; + IP_GROUP *GroupPtr; + + hGroup = BuildGroup (pQueue, 0); + GroupPtr = LockIpGroup (pQueue, hGroup); + + read_16 (fh, &GroupPtr->group_counter); + read_8 (fh, &GroupPtr->race_id); + read_8 (fh, &GroupPtr->sys_loc); + read_8 (fh, &GroupPtr->task); + read_8 (fh, &GroupPtr->in_system); /* was crew_level */ + read_8 (fh, &GroupPtr->dest_loc); + read_8 (fh, &GroupPtr->orbit_pos); + read_8 (fh, &GroupPtr->group_id); /* was max_energy */ + read_16s(fh, &GroupPtr->loc.x); + read_16s(fh, &GroupPtr->loc.y); + + UnlockIpGroup (pQueue, hGroup); + } +} + +static void +LoadEncounter (ENCOUNTER *EncounterPtr, void *fh) +{ + COUNT i; + + EncounterPtr->pred = 0; + EncounterPtr->succ = 0; + EncounterPtr->hElement = 0; + read_16s (fh, &EncounterPtr->transition_state); + read_16s (fh, &EncounterPtr->origin.x); + read_16s (fh, &EncounterPtr->origin.y); + read_16 (fh, &EncounterPtr->radius); + // former STAR_DESC fields + read_16s (fh, &EncounterPtr->loc_pt.x); + read_16s (fh, &EncounterPtr->loc_pt.y); + read_8 (fh, &EncounterPtr->race_id); + read_8 (fh, &EncounterPtr->num_ships); + read_8 (fh, &EncounterPtr->flags); + + // Load each entry in the BRIEF_SHIP_INFO array + for (i = 0; i < MAX_HYPER_SHIPS; i++) + { + BRIEF_SHIP_INFO *ShipInfo = &EncounterPtr->ShipList[i]; + + read_8 (fh, &ShipInfo->race_id); + read_16 (fh, &ShipInfo->crew_level); + read_16 (fh, &ShipInfo->max_crew); + read_8 (fh, &ShipInfo->max_energy); + } + + // Load the stuff after the BRIEF_SHIP_INFO array + read_32s (fh, &EncounterPtr->log_x); + read_32s (fh, &EncounterPtr->log_y); +} + +static void +LoadEvent (EVENT *EventPtr, void *fh) +{ + EventPtr->pred = 0; + EventPtr->succ = 0; + read_8 (fh, &EventPtr->day_index); + read_8 (fh, &EventPtr->month_index); + read_16 (fh, &EventPtr->year_index); + read_8 (fh, &EventPtr->func_index); +} + +static void +LoadClockState (CLOCK_STATE *ClockPtr, void *fh) +{ + read_8 (fh, &ClockPtr->day_index); + read_8 (fh, &ClockPtr->month_index); + read_16 (fh, &ClockPtr->year_index); + read_16s (fh, &ClockPtr->tick_count); + read_16s (fh, &ClockPtr->day_in_ticks); +} + +static BOOLEAN +LoadGameState (GAME_STATE *GSPtr, void *fh) +{ + DWORD magic; + read_32 (fh, &magic); + if (magic != GLOBAL_STATE_TAG) + { + return FALSE; + } + read_32 (fh, &magic); + if (magic != 75) + { + /* Chunk is the wrong size. */ + return FALSE; + } + read_8 (fh, &GSPtr->glob_flags); + read_8 (fh, &GSPtr->CrewCost); + read_8 (fh, &GSPtr->FuelCost); + read_a8 (fh, GSPtr->ModuleCost, NUM_MODULES); + read_a8 (fh, GSPtr->ElementWorth, NUM_ELEMENT_CATEGORIES); + read_16 (fh, &GSPtr->CurrentActivity); + + LoadClockState (&GSPtr->GameClock, fh); + + read_16s (fh, &GSPtr->autopilot.x); + read_16s (fh, &GSPtr->autopilot.y); + read_16s (fh, &GSPtr->ip_location.x); + read_16s (fh, &GSPtr->ip_location.y); + /* STAMP ShipStamp */ + read_16s (fh, &GSPtr->ShipStamp.origin.x); + read_16s (fh, &GSPtr->ShipStamp.origin.y); + read_16 (fh, &GSPtr->ShipFacing); + read_8 (fh, &GSPtr->ip_planet); + read_8 (fh, &GSPtr->in_orbit); + + /* VELOCITY_DESC velocity */ + read_16 (fh, &GSPtr->velocity.TravelAngle); + read_16s (fh, &GSPtr->velocity.vector.width); + read_16s (fh, &GSPtr->velocity.vector.height); + read_16s (fh, &GSPtr->velocity.fract.width); + read_16s (fh, &GSPtr->velocity.fract.height); + read_16s (fh, &GSPtr->velocity.error.width); + read_16s (fh, &GSPtr->velocity.error.height); + read_16s (fh, &GSPtr->velocity.incr.width); + read_16s (fh, &GSPtr->velocity.incr.height); + + read_32 (fh, &magic); + if (magic != GAME_STATE_TAG) + { + return FALSE; + } + memset (GSPtr->GameState, 0, sizeof (GSPtr->GameState)); + read_32 (fh, &magic); + if (magic > sizeof (GSPtr->GameState)) + { + read_a8 (fh, GSPtr->GameState, sizeof (GSPtr->GameState)); + skip_8 (fh, magic - sizeof (GSPtr->GameState)); + } + else + { + read_a8 (fh, GSPtr->GameState, magic); + } + return TRUE; +} + +static BOOLEAN +LoadSisState (SIS_STATE *SSPtr, void *fp) +{ + if ( + read_32s (fp, &SSPtr->log_x) != 1 || + read_32s (fp, &SSPtr->log_y) != 1 || + read_32 (fp, &SSPtr->ResUnits) != 1 || + read_32 (fp, &SSPtr->FuelOnBoard) != 1 || + read_16 (fp, &SSPtr->CrewEnlisted) != 1 || + read_16 (fp, &SSPtr->TotalElementMass) != 1 || + read_16 (fp, &SSPtr->TotalBioMass) != 1 || + read_a8 (fp, SSPtr->ModuleSlots, NUM_MODULE_SLOTS) != 1 || + read_a8 (fp, SSPtr->DriveSlots, NUM_DRIVE_SLOTS) != 1 || + read_a8 (fp, SSPtr->JetSlots, NUM_JET_SLOTS) != 1 || + read_8 (fp, &SSPtr->NumLanders) != 1 || + read_a16 (fp, SSPtr->ElementAmounts, NUM_ELEMENT_CATEGORIES) != 1 || + + read_str (fp, SSPtr->ShipName, SIS_NAME_SIZE) != 1 || + read_str (fp, SSPtr->CommanderName, SIS_NAME_SIZE) != 1 || + read_str (fp, SSPtr->PlanetName, SIS_NAME_SIZE) != 1 + ) + return FALSE; + return TRUE; +} + +static BOOLEAN +LoadSummary (SUMMARY_DESC *SummPtr, void *fp) +{ + DWORD magic; + DWORD nameSize = 0; + if (!read_32 (fp, &magic)) + return FALSE; + if (magic == SAVEFILE_TAG) + { + if (read_32 (fp, &magic) != 1 || magic != SUMMARY_TAG) + return FALSE; + if (read_32 (fp, &magic) != 1 || magic < 160) + return FALSE; + nameSize = magic - 160; + } + else + { + return FALSE; + } + + if (!LoadSisState (&SummPtr->SS, fp)) + return FALSE; + + if ( read_8 (fp, &SummPtr->Activity) != 1 || + read_8 (fp, &SummPtr->Flags) != 1 || + read_8 (fp, &SummPtr->day_index) != 1 || + read_8 (fp, &SummPtr->month_index) != 1 || + read_16 (fp, &SummPtr->year_index) != 1 || + read_8 (fp, &SummPtr->MCreditLo) != 1 || + read_8 (fp, &SummPtr->MCreditHi) != 1 || + read_8 (fp, &SummPtr->NumShips) != 1 || + read_8 (fp, &SummPtr->NumDevices) != 1 || + read_a8 (fp, SummPtr->ShipList, MAX_BUILT_SHIPS) != 1 || + read_a8 (fp, SummPtr->DeviceList, MAX_EXCLUSIVE_DEVICES) != 1 + ) + return FALSE; + + if (nameSize < SAVE_NAME_SIZE) + { + if (read_a8s (fp, SummPtr->SaveName, nameSize) != 1) + return FALSE; + SummPtr->SaveName[nameSize] = 0; + } + else + { + DWORD remaining = nameSize - SAVE_NAME_SIZE + 1; + if (read_a8s (fp, SummPtr->SaveName, SAVE_NAME_SIZE-1) != 1) + return FALSE; + SummPtr->SaveName[SAVE_NAME_SIZE-1] = 0; + if (skip_8 (fp, remaining) != 1) + return FALSE; + } + return TRUE; +} + +static void +LoadStarDesc (STAR_DESC *SDPtr, void *fh) +{ + read_16s(fh, &SDPtr->star_pt.x); + read_16s(fh, &SDPtr->star_pt.y); + read_8 (fh, &SDPtr->Type); + read_8 (fh, &SDPtr->Index); + read_8 (fh, &SDPtr->Prefix); + read_8 (fh, &SDPtr->Postfix); +} + +static void +LoadScanInfo (uio_Stream *fh, DWORD flen) +{ + GAME_STATE_FILE *fp = OpenStateFile (STARINFO_FILE, "wb"); + if (fp) + { + while (flen) + { + DWORD val; + read_32 (fh, &val); + swrite_32 (fp, val); + flen -= 4; + } + CloseStateFile (fp); + } +} + +static void +LoadGroupList (uio_Stream *fh, DWORD chunksize) +{ + GAME_STATE_FILE *fp = OpenStateFile (RANDGRPINFO_FILE, "rb"); + if (fp) + { + GROUP_HEADER h; + BYTE LastEnc, NumGroups; + int i; + ReadGroupHeader (fp, &h); + /* There's only supposed to be one of these, so group 0 should be + * zero here whenever we're here. We add the group list to the + * end here. */ + h.GroupOffset[0] = LengthStateFile (fp); + SeekStateFile (fp, 0, SEEK_SET); + WriteGroupHeader (fp, &h); + SeekStateFile (fp, h.GroupOffset[0], SEEK_SET); + read_8 (fh, &LastEnc); + NumGroups = (chunksize - 1) / 14; + swrite_8 (fp, LastEnc); + swrite_8 (fp, NumGroups); + for (i = 0; i < NumGroups; ++i) + { + BYTE race_outer; + IP_GROUP ip; + read_8 (fh, &race_outer); + read_16 (fh, &ip.group_counter); + read_8 (fh, &ip.race_id); + read_8 (fh, &ip.sys_loc); + read_8 (fh, &ip.task); + read_8 (fh, &ip.in_system); + read_8 (fh, &ip.dest_loc); + read_8 (fh, &ip.orbit_pos); + read_8 (fh, &ip.group_id); + read_16s (fh, &ip.loc.x); + read_16s (fh, &ip.loc.y); + + swrite_8 (fp, race_outer); + WriteIpGroup (fp, &ip); + } + CloseStateFile (fp); + } +} + +static void +LoadBattleGroup (uio_Stream *fh, DWORD chunksize) +{ + GAME_STATE_FILE *fp; + GROUP_HEADER h; + DWORD encounter, offset; + BYTE current; + int i; + + read_32 (fh, &encounter); + read_8 (fh, ¤t); + chunksize -= 5; + if (encounter) + { + /* This is a defined group, so it's new */ + fp = OpenStateFile (DEFGRPINFO_FILE, "rb"); + offset = LengthStateFile (fp); + memset (&h, 0, sizeof (GROUP_HEADER)); + } + else + { + /* This is the random group. Load in what was there, + * as we might have already seen the Group List. */ + fp = OpenStateFile (RANDGRPINFO_FILE, "rb"); + current = FALSE; + offset = 0; + ReadGroupHeader (fp, &h); + } + if (!fp) + { + skip_8 (fh, chunksize); + return; + } + read_16 (fh, &h.star_index); + read_8 (fh, &h.day_index); + read_8 (fh, &h.month_index); + read_16 (fh, &h.year_index); + read_8 (fh, &h.NumGroups); + chunksize -= 7; + /* Write out the half-finished state file so that we can use + * the file size to compute group offsets */ + SeekStateFile (fp, offset, SEEK_SET); + WriteGroupHeader (fp, &h); + for (i = 1; i <= h.NumGroups; ++i) + { + int j; + BYTE icon, NumShips; + read_8 (fh, &icon); + read_8 (fh, &NumShips); + chunksize -= 2; + h.GroupOffset[i] = LengthStateFile (fp); + SeekStateFile (fp, h.GroupOffset[i], SEEK_SET); + swrite_8 (fp, icon); + swrite_8 (fp, NumShips); + for (j = 0; j < NumShips; ++j) + { + BYTE race_outer; + SHIP_FRAGMENT sf; + read_8 (fh, &race_outer); + read_8 (fh, &sf.captains_name_index); + read_8 (fh, &sf.race_id); + read_8 (fh, &sf.index); + read_16 (fh, &sf.crew_level); + read_16 (fh, &sf.max_crew); + read_8 (fh, &sf.energy_level); + read_8 (fh, &sf.max_energy); + chunksize -= 10; + + swrite_8 (fp, race_outer); + WriteShipFragment (fp, &sf); + } + } + /* Now that the GroupOffset array is properly initialized, + * write the header back out. */ + SeekStateFile (fp, offset, SEEK_SET); + WriteGroupHeader (fp, &h); + CloseStateFile (fp); + /* And update the gamestate accordingly, if we're a defined group. */ + if (encounter) + { + SET_GAME_STATE_32 (SHOFIXTI_GRPOFFS0 + (encounter - 1) * 32, offset); + if (current) + { + GLOBAL (BattleGroupRef) = offset; + } + } + /* Consistency check. */ + if (chunksize) + { + log_add (log_Warning, "BattleGroup chunk mis-sized!"); + } +} + +BOOLEAN +LoadGame (COUNT which_game, SUMMARY_DESC *SummPtr) +{ + uio_Stream *in_fp; + char file[PATH_MAX]; + SUMMARY_DESC loc_sd; + COUNT num_links; + STAR_DESC SD; + ACTIVITY Activity; + DWORD chunk, chunkSize; + BOOLEAN first_group_spec = TRUE; + + sprintf (file, "uqmsave.%02u", which_game); + in_fp = res_OpenResFile (saveDir, file, "rb"); + if (!in_fp) + return LoadLegacyGame (which_game, SummPtr); + + if (!LoadSummary (&loc_sd, in_fp)) + { + res_CloseResFile (in_fp); + return LoadLegacyGame (which_game, SummPtr); + } + + if (!SummPtr) + { + SummPtr = &loc_sd; + } + else + { // only need summary for displaying to user + memcpy (SummPtr, &loc_sd, sizeof (*SummPtr)); + res_CloseResFile (in_fp); + return TRUE; + } + + GlobData.SIS_state = SummPtr->SS; + + ReinitQueue (&GLOBAL (GameClock.event_q)); + ReinitQueue (&GLOBAL (encounter_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (built_ship_q)); + + memset (&GLOBAL (GameState[0]), 0, sizeof (GLOBAL (GameState))); + Activity = GLOBAL (CurrentActivity); + if (!LoadGameState (&GlobData.Game_state, in_fp)) + { + res_CloseResFile (in_fp); + return FALSE; + } + NextActivity = GLOBAL (CurrentActivity); + GLOBAL (CurrentActivity) = Activity; + + chunk = 0; + while (TRUE) + { + if (read_32(in_fp, &chunk) != 1) + { + break; + } + if (read_32(in_fp, &chunkSize) != 1) + { + res_CloseResFile (in_fp); + return FALSE; + } + switch (chunk) + { + case RACE_Q_TAG: + LoadRaceQueue (in_fp, &GLOBAL (avail_race_q), chunkSize); + break; + case IP_GRP_Q_TAG: + LoadGroupQueue (in_fp, &GLOBAL (ip_group_q), chunkSize); + break; + case ENCOUNTERS_TAG: + num_links = chunkSize / 65; + while (num_links--) + { + HENCOUNTER hEncounter; + ENCOUNTER *EncounterPtr; + + hEncounter = AllocEncounter (); + LockEncounter (hEncounter, &EncounterPtr); + + LoadEncounter (EncounterPtr, in_fp); + + UnlockEncounter (hEncounter); + PutEncounter (hEncounter); + } + break; + case EVENTS_TAG: + num_links = chunkSize / 5; +#ifdef DEBUG_LOAD + log_add (log_Debug, "EVENTS:"); +#endif /* DEBUG_LOAD */ + while (num_links--) + { + HEVENT hEvent; + EVENT *EventPtr; + + hEvent = AllocEvent (); + LockEvent (hEvent, &EventPtr); + + LoadEvent (EventPtr, in_fp); + +#ifdef DEBUG_LOAD + log_add (log_Debug, "\t%u/%u/%u -- %u", + EventPtr->month_index, + EventPtr->day_index, + EventPtr->year_index, + EventPtr->func_index); +#endif /* DEBUG_LOAD */ + UnlockEvent (hEvent); + PutEvent (hEvent); + } + break; + case STAR_TAG: + LoadStarDesc (&SD, in_fp); + break; + case NPC_SHIP_Q_TAG: + LoadShipQueue (in_fp, &GLOBAL (npc_built_ship_q), chunkSize); + break; + case SHIP_Q_TAG: + LoadShipQueue (in_fp, &GLOBAL (built_ship_q), chunkSize); + break; + case SCAN_TAG: + LoadScanInfo (in_fp, chunkSize); + break; + case GROUP_LIST_TAG: + if (first_group_spec) + { + InitGroupInfo (TRUE); + GLOBAL (BattleGroupRef) = 0; + first_group_spec = FALSE; + } + LoadGroupList (in_fp, chunkSize); + break; + case BATTLE_GROUP_TAG: + if (first_group_spec) + { + InitGroupInfo (TRUE); + GLOBAL (BattleGroupRef) = 0; + first_group_spec = FALSE; + } + LoadBattleGroup (in_fp, chunkSize); + break; + default: + log_add (log_Debug, "Skipping chunk of tag %08X (size %u)", chunk, chunkSize); + if (skip_8(in_fp, chunkSize) != 1) + { + res_CloseResFile (in_fp); + return FALSE; + } + break; + } + } + res_CloseResFile (in_fp); + + EncounterGroup = 0; + EncounterRace = -1; + + ReinitQueue (&race_q[0]); + ReinitQueue (&race_q[1]); + CurStarDescPtr = FindStar (NULL, &SD.star_pt, 0, 0); + if (!(NextActivity & START_ENCOUNTER) + && LOBYTE (NextActivity) == IN_INTERPLANETARY) + NextActivity |= START_INTERPLANETARY; + + return TRUE; +} |