From 7f6002caba3f0a6749820c2772161caf55b8d267 Mon Sep 17 00:00:00 2001 From: neonloop Date: Fri, 7 May 2021 20:00:12 +0000 Subject: Initial commit (uqm-0.8.0) --- src/uqm/encount.c | 844 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 844 insertions(+) create mode 100644 src/uqm/encount.c (limited to 'src/uqm/encount.c') diff --git a/src/uqm/encount.c b/src/uqm/encount.c new file mode 100644 index 0000000..9ab75c5 --- /dev/null +++ b/src/uqm/encount.c @@ -0,0 +1,844 @@ +//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 "encount.h" + +#include "battle.h" +#include "battlecontrols.h" +#include "build.h" +#include "colors.h" +#include "starmap.h" +#include "cons_res.h" +#include "controls.h" +#include "menustat.h" +#include "gameopt.h" +#include "gamestr.h" +#include "globdata.h" +#include "sis.h" + // for DrawStatusMessage(), SetStatusMessageMode() +#include "init.h" +#include "pickship.h" +#include "intel.h" +#include "nameref.h" +#include "resinst.h" +#include "settings.h" +#include "setup.h" +#include "sounds.h" +#include "libs/graphics/gfx_common.h" +#include "libs/log.h" +#include "libs/mathlib.h" +#include "libs/inplib.h" +#include "libs/misc.h" + + +static void DrawFadeText (const UNICODE *str1, const UNICODE *str2, + BOOLEAN fade_in, RECT *pRect); + + +static BOOLEAN +DoSelectAction (MENU_STATE *pMS) +{ + SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); + if (GLOBAL (CurrentActivity) & CHECK_ABORT) + { + pMS->CurState = ATTACK + 1; + return (FALSE); + } + if (!pMS->Initialized) + { + pMS->Initialized = TRUE; + pMS->InputFunc = DoSelectAction; + } + else if (PulsedInputState.menu[KEY_MENU_SELECT]) + { + switch (pMS->CurState) + { + case HAIL: + case ATTACK: + if (LOBYTE (GLOBAL (CurrentActivity)) == IN_LAST_BATTLE) + pMS->CurState = HAIL; + return (FALSE); + case ATTACK + 1: + // Clearing FlashRect is not necessary + if (!GameOptions ()) + return FALSE; + DrawMenuStateStrings (PM_CONVERSE, pMS->CurState); + SetFlashRect (SFR_MENU_3DO); + break; + default: + printf ("Unknown option: %d\n", pMS->CurState); + } + } + DoMenuChooser (pMS, PM_CONVERSE); + return (TRUE); +} + +static QUEUE * +GetShipFragQueueForPlayer (COUNT playerNr) +{ + if (playerNr == RPG_PLAYER_NUM) + return &GLOBAL (built_ship_q); + else + return &GLOBAL (npc_built_ship_q); +} + +// Called by comm code to intialize battle fleets during encounter +void +BuildBattle (COUNT which_player) +{ + QUEUE *pQueue; + HSHIPFRAG hStarShip, hNextShip; + HSTARSHIP hBuiltShip; + STARSHIP *BuiltShipPtr; + + EncounterRace = -1; + + if (GetHeadLink (&GLOBAL (npc_built_ship_q)) == 0) + { + SET_GAME_STATE (BATTLE_SEGUE, 0); + return; + } + + if (which_player != RPG_PLAYER_NUM) + { // This function is called first for the NPC character + // and this is when a centerpiece is loaded + switch (LOBYTE (GLOBAL (CurrentActivity))) + { + case IN_LAST_BATTLE: + load_gravity_well (NUMBER_OF_PLANET_TYPES); + break; + case IN_HYPERSPACE: + load_gravity_well ((BYTE)((COUNT)TFB_Random () + % NUMBER_OF_PLANET_TYPES)); + break; + default: + SET_GAME_STATE (ESCAPE_COUNTER, 110); + load_gravity_well (GET_GAME_STATE (BATTLE_PLANET)); + break; + } + } + pQueue = GetShipFragQueueForPlayer (which_player); + + ReinitQueue (&race_q[which_player]); + for (hStarShip = GetHeadLink (pQueue); + hStarShip != 0; hStarShip = hNextShip) + { + SHIP_FRAGMENT *FragPtr; + + FragPtr = LockShipFrag (pQueue, hStarShip); + hNextShip = _GetSuccLink (FragPtr); + + hBuiltShip = Build (&race_q[which_player], + FragPtr->race_id == SAMATRA_SHIP ? + SA_MATRA_ID : FragPtr->SpeciesID); + if (hBuiltShip) + { + BuiltShipPtr = LockStarShip (&race_q[which_player], hBuiltShip); + BuiltShipPtr->captains_name_index = FragPtr->captains_name_index; + BuiltShipPtr->playerNr = which_player; + if (FragPtr->crew_level != INFINITE_FLEET) + BuiltShipPtr->crew_level = FragPtr->crew_level; + else /* if infinite ships */ + BuiltShipPtr->crew_level = FragPtr->max_crew; + BuiltShipPtr->max_crew = FragPtr->max_crew; + BuiltShipPtr->race_strings = FragPtr->race_strings; + BuiltShipPtr->icons = FragPtr->icons; + BuiltShipPtr->index = FragPtr->index; + BuiltShipPtr->ship_cost = 0; + BuiltShipPtr->RaceDescPtr = 0; + + UnlockStarShip (&race_q[which_player], hBuiltShip); + } + + UnlockShipFrag (pQueue, hStarShip); + } + + if (which_player == RPG_PLAYER_NUM + && (hBuiltShip = Build (&race_q[0], SIS_SHIP_ID))) + { + BuiltShipPtr = LockStarShip (&race_q[0], hBuiltShip); + BuiltShipPtr->captains_name_index = 0; + BuiltShipPtr->playerNr = RPG_PLAYER_NUM; + BuiltShipPtr->crew_level = 0; + BuiltShipPtr->max_crew = 0; + // Crew will be copied directly from + // GLOBAL_SIS (CrewEnlisted) later. + BuiltShipPtr->race_strings = 0; + BuiltShipPtr->icons = 0; + BuiltShipPtr->index = -1; + BuiltShipPtr->ship_cost = 0; + BuiltShipPtr->energy_counter = MAX_ENERGY_SIZE; + BuiltShipPtr->RaceDescPtr = 0; + UnlockStarShip (&race_q[0], hBuiltShip); + } +} + +BOOLEAN +FleetIsInfinite (COUNT playerNr) +{ + QUEUE *pQueue; + HSHIPFRAG hShipFrag; + SHIP_FRAGMENT *FragPtr; + BOOLEAN ret; + + pQueue = GetShipFragQueueForPlayer (playerNr); + hShipFrag = GetHeadLink (pQueue); + if (!hShipFrag) + { // Ship queue is empty in SuperMelee or for RPG player w/o escorts + return FALSE; + } + + FragPtr = LockShipFrag (pQueue, hShipFrag); + ret = (FragPtr->crew_level == INFINITE_FLEET); + UnlockShipFrag (pQueue, hShipFrag); + + return ret; +} + +void +UpdateShipFragCrew (STARSHIP *StarShipPtr) +{ + QUEUE *frag_q; + HSHIPFRAG hShipFrag, hNextFrag; + SHIP_FRAGMENT *frag; + QUEUE *ship_q; + HSTARSHIP hStarShip, hNextShip; + STARSHIP *ship; + + frag_q = GetShipFragQueueForPlayer (StarShipPtr->playerNr); + ship_q = &race_q[StarShipPtr->playerNr]; + + // Find a SHIP_FRAGMENT that corresponds to the given STARSHIP + // The ships and fragments are in the same order in two queues + // XXX: It would probably be simpler to keep HSHIPFRAG in STARSHIP struct + for (hShipFrag = GetHeadLink (frag_q), hStarShip = GetHeadLink (ship_q); + hShipFrag != 0 && hStarShip != 0; + hShipFrag = hNextFrag, hStarShip = hNextShip) + { + ship = LockStarShip (ship_q, hStarShip); + hNextShip = _GetSuccLink (ship); + frag = LockShipFrag (frag_q, hShipFrag); + hNextFrag = _GetSuccLink (frag); + + if (ship == StarShipPtr) + { + assert (frag->crew_level != INFINITE_FLEET); + + // Record crew left after the battle */ + frag->crew_level = ship->crew_level; + + UnlockShipFrag (frag_q, hShipFrag); + UnlockStarShip (ship_q, hStarShip); + break; + } + + UnlockShipFrag (frag_q, hShipFrag); + UnlockStarShip (ship_q, hStarShip); + } +} + +/* + * Encountering an alien. + * Draws the encounter screen, plays the red alert music, and + * waits for a decision of the player on how to handle the situation. + * Returns either HAIL or ATTACK. + */ +COUNT +InitEncounter (void) +{ + COUNT i; + FRAME SegueFrame; + STAMP s; + TEXT t; + extern FRAME planet[]; + MUSIC_REF MR; + + + SetContext (SpaceContext); + SetContextFont (TinyFont); + + MR = LoadMusic (REDALERT_MUSIC); + PlayMusic (MR, FALSE, 1); + SegueFrame = CaptureDrawable (LoadGraphic (SEGUE_PMAP_ANIM)); + WaitForSoundEnd (TFBSOUND_WAIT_ALL); + StopMusic (); + DestroyMusic (MR); + s.origin.x = s.origin.y = 0; + + SetTransitionSource (NULL); + BatchGraphics (); + + SetContextBackGroundColor (BLACK_COLOR); + ClearDrawable (); + s.frame = SegueFrame; + DrawStamp (&s); + +// t.baseline.x = SIS_SCREEN_WIDTH >> 1; + t.baseline.x = (SIS_SCREEN_WIDTH >> 1) + 1; + t.baseline.y = 10; + t.align = ALIGN_CENTER; + + SetContextFont (MicroFont); + SetContextForeGroundColor ( + BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01)); + if (inHQSpace ()) + { + t.pStr = GAME_STRING (ENCOUNTER_STRING_BASE + 0); + // "ENCOUNTER IN" + t.CharCount = (COUNT)~0; + font_DrawText (&t); + t.baseline.y += 12; + t.pStr = GAME_STRING (ENCOUNTER_STRING_BASE + 1); + // "DEEP SPACE" + t.CharCount = (COUNT)~0; + font_DrawText (&t); + } + else + { + UNICODE buf[256]; + + t.pStr = GAME_STRING (ENCOUNTER_STRING_BASE + 2); + // "ENCOUNTER AT" + t.CharCount = (COUNT)~0; + font_DrawText (&t); + t.baseline.y += 12; + GetClusterName (CurStarDescPtr, buf); + t.pStr = buf; + t.CharCount = (COUNT)~0; + font_DrawText (&t); + t.baseline.y += 12; + t.pStr = GLOBAL_SIS (PlanetName); + t.CharCount = (COUNT)~0; + font_DrawText (&t); + } + DrawSISMessage (NULL); + + s.origin.x = SIS_SCREEN_WIDTH >> 1; + s.origin.y = SIS_SCREEN_HEIGHT >> 1; + s.frame = planet[0]; + DrawStamp (&s); + + if (LOBYTE (GLOBAL (CurrentActivity)) != IN_LAST_BATTLE) + { +#define NUM_DISPLAY_PTS (sizeof (display_pt) / sizeof (display_pt[0])) + HSHIPFRAG hStarShip, hNextShip; + POINT display_pt[] = + { + { 10, 51}, + {-10, 51}, + { 33, 40}, + {-33, 40}, + { 49, 18}, + {-49, 18}, + { 52, -6}, + {-52, -6}, + { 44, -27}, + {-44, -27}, + }; + + for (hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q)), i = 0; + hStarShip && i < 60; hStarShip = hNextShip, ++i) + { + RECT r; + SHIP_FRAGMENT *FragPtr; + + FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + if (FragPtr->crew_level != INFINITE_FLEET) + hNextShip = _GetSuccLink (FragPtr); + else /* if infinite ships */ + hNextShip = hStarShip; + + s.origin = display_pt[i % NUM_DISPLAY_PTS]; + if (i >= NUM_DISPLAY_PTS) + { + COUNT angle, radius; + + radius = square_root ((long)s.origin.x * s.origin.x + + (long)s.origin.y * s.origin.y) + + ((i / NUM_DISPLAY_PTS) * 18); + + angle = ARCTAN (s.origin.x, s.origin.y); + s.origin.x = COSINE (angle, radius); + s.origin.y = SINE (angle, radius); + } + s.frame = SetAbsFrameIndex (FragPtr->icons, 0); + GetFrameRect (s.frame, &r); + s.origin.x += (SIS_SCREEN_WIDTH >> 1) - (r.extent.width >> 1); + s.origin.y += (SIS_SCREEN_HEIGHT >> 1) - (r.extent.height >> 1); + DrawStamp (&s); + + UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + } + } + + UnbatchGraphics (); + DestroyDrawable (ReleaseDrawable (SegueFrame)); + ScreenTransition (3, NULL); + + + { + MENU_STATE MenuState; + + MenuState.InputFunc = DoSelectAction; + MenuState.Initialized = FALSE; + + DrawMenuStateStrings (PM_CONVERSE, MenuState.CurState = HAIL); + SetFlashRect (SFR_MENU_3DO); + + DoInput (&MenuState, TRUE); + + SetFlashRect (NULL); + + return (MenuState.CurState); + } +} + +static void +DrawFadeText (const UNICODE *str1, const UNICODE *str2, BOOLEAN fade_in, + RECT *pRect) +{ + SIZE i; + DWORD TimeIn; + TEXT t1, t2; + static const Color fade_cycle[] = + { + BUILD_COLOR (MAKE_RGB15_INIT (0x0A, 0x0A, 0x0A), 0x1D), + BUILD_COLOR (MAKE_RGB15_INIT (0x09, 0x09, 0x09), 0x1E), + BUILD_COLOR (MAKE_RGB15_INIT (0x08, 0x08, 0x08), 0x1F), + BUILD_COLOR (MAKE_RGB15_INIT (0x06, 0x06, 0x06), 0x20), + BUILD_COLOR (MAKE_RGB15_INIT (0x05, 0x05, 0x05), 0x21), + BUILD_COLOR (MAKE_RGB15_INIT (0x04, 0x04, 0x04), 0x22), + BUILD_COLOR (MAKE_RGB15_INIT (0x03, 0x03, 0x03), 0x23), + }; +#define NUM_FADES (sizeof (fade_cycle) / sizeof (fade_cycle[0])) + + t1.baseline.x = pRect->corner.x + 100; + t1.baseline.y = pRect->corner.y + 45; + t1.align = ALIGN_CENTER; + t1.pStr = str1; + t1.CharCount = (COUNT)~0; + t2 = t1; + t2.baseline.y += 11; + t2.pStr = str2; + + FlushInput (); + TimeIn = GetTimeCounter (); + if (fade_in) + { + for (i = 0; i < (SIZE) NUM_FADES; ++i) + { + if (AnyButtonPress (TRUE)) + i = NUM_FADES - 1; + + SetContextForeGroundColor (fade_cycle[i]); + font_DrawText (&t1); + font_DrawText (&t2); + SleepThreadUntil (TimeIn + (ONE_SECOND / 20)); + TimeIn = GetTimeCounter (); + } + } + else + { + for (i = NUM_FADES - 1; i >= 0; --i) + { + if (AnyButtonPress (TRUE)) + i = 0; + + SetContextForeGroundColor (fade_cycle[i]); + font_DrawText (&t1); + font_DrawText (&t2); + SleepThreadUntil (TimeIn + (ONE_SECOND / 20)); + TimeIn = GetTimeCounter (); + } + SetContextForeGroundColor ( + BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x0A), 0x08)); + font_DrawText (&t1); + font_DrawText (&t2); + } +} + +COUNT +UninitEncounter (void) +{ + COUNT ships_killed; + + ships_killed = 0; + + free_gravity_well (); + + if ((GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)) + || GLOBAL_SIS (CrewEnlisted) == (COUNT)~0 + || LOBYTE (GLOBAL (CurrentActivity)) == IN_LAST_BATTLE + || LOBYTE (GLOBAL (CurrentActivity)) == WON_LAST_BATTLE) + goto ExitUninitEncounter; + + if (GET_GAME_STATE (BATTLE_SEGUE) == 0) + { + ReinitQueue (&race_q[0]); + ReinitQueue (&race_q[1]); + } + else + { + BOOLEAN Sleepy; + SIZE VictoryState; + COUNT RecycleAmount = 0; + SIZE i; + RECT r; + RECT scavenge_r = {{0, 0}, {0, 0}}; + TEXT t; + STAMP ship_s; + const UNICODE *str1 = NULL; + const UNICODE *str2 = NULL; + StatMsgMode prevMsgMode; + UNICODE buf[80]; + HSHIPFRAG hStarShip; + SHIP_FRAGMENT *FragPtr; + static const Color fade_ship_cycle[] = + { + BUILD_COLOR (MAKE_RGB15_INIT (0x07, 0x00, 0x00), 0x2F), + BUILD_COLOR (MAKE_RGB15_INIT (0x0F, 0x00, 0x00), 0x2D), + BUILD_COLOR (MAKE_RGB15_INIT (0x17, 0x00, 0x00), 0x2B), + BUILD_COLOR (MAKE_RGB15_INIT (0x1F, 0x0A, 0x0A), 0x27), + BUILD_COLOR (MAKE_RGB15_INIT (0x1F, 0x14, 0x14), 0x25), + BUILD_COLOR (MAKE_RGB15_INIT (0x1F, 0x1F, 0x1F), 0x0F), + BUILD_COLOR (MAKE_RGB15_INIT (0x1F, 0x14, 0x14), 0x25), + BUILD_COLOR (MAKE_RGB15_INIT (0x1F, 0x0A, 0x0A), 0x27), + BUILD_COLOR (MAKE_RGB15_INIT (0x1B, 0x00, 0x00), 0x2A), + BUILD_COLOR (MAKE_RGB15_INIT (0x17, 0x00, 0x00), 0x2B), + }; +#define NUM_SHIP_FADES (sizeof (fade_ship_cycle) / \ + sizeof (fade_ship_cycle[0])) + + COUNT race_bounty[] = + { + RACE_SHIP_COST + }; + + SET_GAME_STATE (BATTLE_SEGUE, 0); + SET_GAME_STATE (BOMB_CARRIER, 0); + + VictoryState = ( + battle_counter[1] || !battle_counter[0] + || GET_GAME_STATE (URQUAN_PROTECTING_SAMATRA) + ) ? 0 : 1; + + hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q)); + FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + EncounterRace = FragPtr->race_id; + if (GetStarShipFromIndex (&GLOBAL (avail_race_q), EncounterRace) == 0) + { + /* Suppress the final tally and salvage info */ + VictoryState = -1; + InitSISContexts (); + } + UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + + prevMsgMode = SetStatusMessageMode (SMM_RES_UNITS); + ship_s.origin.x = 0; + ship_s.origin.y = 0; + Sleepy = TRUE; + for (i = 0; i < NUM_SIDES; ++i) + { + QUEUE *pQueue; + HSHIPFRAG hNextShip; + + if (i == 0) + pQueue = &GLOBAL (built_ship_q); + else + { + if (VictoryState < 0) + VictoryState = 0; + else + { + DrawSISFrame (); + DrawSISMessage (NULL); + if (inHQSpace ()) + DrawHyperCoords (GLOBAL (ShipStamp.origin)); + else if (GLOBAL (ip_planet) == 0) + DrawHyperCoords (CurStarDescPtr->star_pt); + else + DrawSISTitle(GLOBAL_SIS (PlanetName)); + + SetContext (SpaceContext); + if (VictoryState) + DrawArmadaPickShip (TRUE, &scavenge_r); + } + pQueue = &GLOBAL (npc_built_ship_q); + } + + ReinitQueue (&race_q[(NUM_SIDES - 1) - i]); + + for (hStarShip = GetHeadLink (pQueue); hStarShip; + hStarShip = hNextShip) + { + FragPtr = LockShipFrag (pQueue, hStarShip); + hNextShip = _GetSuccLink (FragPtr); + + if (FragPtr->crew_level == 0 + || (VictoryState && i == NUM_SIDES - 1)) + { + if (i == NUM_SIDES - 1) + { + ++ships_killed; + if (VictoryState) + { +#define MAX_DEAD_DISPLAYED 5 + COUNT j; + + if (ships_killed == 1) + { + RecycleAmount = 0; + + DrawStatusMessage (NULL); + + ship_s.origin.x = scavenge_r.corner.x + 32; + ship_s.origin.y = scavenge_r.corner.y + 56; + ship_s.frame = IncFrameIndex (FragPtr->icons); + DrawStamp (&ship_s); + SetContextForeGroundColor ( + BUILD_COLOR (MAKE_RGB15 (0x08, 0x08, 0x08), 0x1F)); + SetContextFont (TinyFont); + + utf8StringCopy (buf, sizeof buf, + GetStringAddress (FragPtr->race_strings)); + // XXX: this will not work with UTF-8 strings + strupr (buf); + + t.baseline.x = scavenge_r.corner.x + 100; + t.baseline.y = scavenge_r.corner.y + 68; + t.align = ALIGN_CENTER; + t.pStr = buf; + t.CharCount = (COUNT)~0; + font_DrawText (&t); + t.baseline.y += 6; + t.pStr = GAME_STRING ( + ENCOUNTER_STRING_BASE + 3); + // "BATTLE GROUP" + t.CharCount = (COUNT)~0; + font_DrawText (&t); + + ship_s.frame = FragPtr->icons; + + SetContextFont (MicroFont); + str1 = GAME_STRING ( + ENCOUNTER_STRING_BASE + 4); + // "Enemy Ships" + str2 = GAME_STRING ( + ENCOUNTER_STRING_BASE + 5), + // "Destroyed" + DrawFadeText (str1, str2, TRUE, &scavenge_r); + } + + r.corner.y = scavenge_r.corner.y + 9; + r.extent.height = 22; + + SetContextForeGroundColor (BLACK_COLOR); + + r.extent.width = 34; + r.corner.x = scavenge_r.corner.x + + scavenge_r.extent.width + - (10 + r.extent.width); + DrawFilledRectangle (&r); + + /* collect bounty ResUnits */ + j = race_bounty[EncounterRace] >> 3; + RecycleAmount += j; + sprintf (buf, "%u", RecycleAmount); + t.baseline.x = r.corner.x + r.extent.width - 1; + t.baseline.y = r.corner.y + 14; + t.align = ALIGN_RIGHT; + t.pStr = buf; + t.CharCount = (COUNT)~0; + SetContextForeGroundColor ( + BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x18), 0x50)); + font_DrawText (&t); + DeltaSISGauges (0, 0, j); + + if ((VictoryState++ - 1) % MAX_DEAD_DISPLAYED) + ship_s.origin.x += 17; + else + { + SetContextForeGroundColor (BLACK_COLOR); + + r.corner.x = scavenge_r.corner.x + 10; + r.extent.width = 104; + DrawFilledRectangle (&r); + + ship_s.origin.x = r.corner.x + 2; + ship_s.origin.y = scavenge_r.corner.y + 12; + } + + if (Sleepy) + { + TimeCount Time = GetTimeCounter (); + for (j = 0; j < NUM_SHIP_FADES; ++j) + { + Sleepy = (BOOLEAN)!AnyButtonPress (TRUE) && + !(GLOBAL (CurrentActivity) & CHECK_ABORT); + if (!Sleepy) + break; + + SetContextForeGroundColor (fade_ship_cycle[j]); + DrawFilledStamp (&ship_s); + + SleepThreadUntil (Time + (ONE_SECOND / 15)); + Time = GetTimeCounter (); + } + } + DrawStamp (&ship_s); + } + } + + UnlockShipFrag (pQueue, hStarShip); + RemoveQueue (pQueue, hStarShip); + FreeShipFrag (pQueue, hStarShip); + + continue; + } + + UnlockShipFrag (pQueue, hStarShip); + } + } + SetStatusMessageMode (prevMsgMode); + + if (VictoryState) + { +#ifdef NEVER + DestroyDrawable (ReleaseDrawable (s.frame)); +#endif /* NEVER */ + + WaitForAnyButton (TRUE, ONE_SECOND * 3, FALSE); + if (!CurrentInputState.key[PlayerControls[0]][KEY_ESCAPE]) + { + DrawFadeText (str1, str2, FALSE, &scavenge_r); + if (!CurrentInputState.key[PlayerControls[0]][KEY_ESCAPE]) + { + SetContextForeGroundColor (BLACK_COLOR); + r.corner.x = scavenge_r.corner.x + 10; + r.extent.width = 132; + DrawFilledRectangle (&r); + sprintf (buf, "%u %s", RecycleAmount, + GAME_STRING (STATUS_STRING_BASE + 1)); // "RU" + t.baseline.x = r.corner.x + (r.extent.width >> 1); + t.baseline.y = r.corner.y + 14; + t.align = ALIGN_CENTER; + t.pStr = buf; + t.CharCount = (COUNT)~0; + SetContextForeGroundColor ( + BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x18), 0x50)); + font_DrawText (&t); + + str1 = GAME_STRING (ENCOUNTER_STRING_BASE + 6); + // "Debris" + str2 = GAME_STRING (ENCOUNTER_STRING_BASE + 7); + // "Scavenged" + DrawFadeText (str1, str2, TRUE, &scavenge_r); + WaitForAnyButton (TRUE, ONE_SECOND * 2, FALSE); + if (!CurrentInputState.key[PlayerControls[0]][KEY_ESCAPE]) + DrawFadeText (str1, str2, FALSE, &scavenge_r); + } + } + + DrawStatusMessage (NULL); + } + + if (ships_killed && EncounterRace == THRADDASH_SHIP + && !GET_GAME_STATE (THRADD_MANNER)) + { + if ((ships_killed += GET_GAME_STATE (THRADDASH_BODY_COUNT)) > + THRADDASH_BODY_THRESHOLD) + ships_killed = THRADDASH_BODY_THRESHOLD; + SET_GAME_STATE (THRADDASH_BODY_COUNT, ships_killed); + } + } +ExitUninitEncounter: + + return (ships_killed); +} + +void +EncounterBattle (void) +{ + ACTIVITY OldActivity; + extern UWORD nth_frame; + InputContext *savedPlayerInput = NULL; + + + SET_GAME_STATE (BATTLE_SEGUE, 1); + + OldActivity = GLOBAL (CurrentActivity); + if (LOBYTE (OldActivity) == IN_LAST_BATTLE) + GLOBAL (CurrentActivity) = MAKE_WORD (IN_LAST_BATTLE, 0); + else + GLOBAL (CurrentActivity) = MAKE_WORD (IN_ENCOUNTER, 0); + +// FreeSC2Data (); +// DestroyFont (ReleaseFont (MicroFont)); + WaitForSoundEnd (TFBSOUND_WAIT_ALL); +// DestroySound (ReleaseSound (MenuSounds)); + + if (GLOBAL (glob_flags) & CYBORG_ENABLED) + { + BYTE cur_speed; + + cur_speed = (BYTE)(GLOBAL (glob_flags) & COMBAT_SPEED_MASK) + >> COMBAT_SPEED_SHIFT; + if (cur_speed == 1) + cur_speed = 0; /* normal speed */ + else if (cur_speed == 2) + ++cur_speed; /* 4x speed, 3 of 4 frames skipped */ + else /* if (cur_speed == 3) */ + cur_speed = (BYTE)~0; /* maximum speed - no rendering */ + nth_frame = MAKE_WORD (1, cur_speed); + PlayerControl[0] = CYBORG_CONTROL | AWESOME_RATING; + savedPlayerInput = PlayerInput[0]; + PlayerInput[0] = NULL; + if (!SetPlayerInput (0)) { + log_add (log_Fatal, "Could not set cyborg player input."); + explode (); // Does not return; + } + } + + GameSounds = CaptureSound (LoadSound (GAME_SOUNDS)); + + Battle (NULL); + + DestroySound (ReleaseSound (GameSounds)); + GameSounds = 0; + + if (GLOBAL (CurrentActivity) & CHECK_ABORT) + GLOBAL_SIS (CrewEnlisted) = (COUNT)~0; + + if (GLOBAL (glob_flags) & CYBORG_ENABLED) + { + nth_frame = MAKE_WORD (0, 0); + PlayerControl[0] = HUMAN_CONTROL | STANDARD_RATING; + ClearPlayerInput (0); + PlayerInput[0] = savedPlayerInput; + } + +// MicroFont = CaptureFont ( +// LoadFont (MICRO_FONT) +// ); +// MenuSounds = CaptureSound (LoadSound (MENU_SOUNDS)); +// LoadSC2Data (); + + GLOBAL (CurrentActivity) = OldActivity; + +} + -- cgit v1.2.3