summaryrefslogtreecommitdiff
path: root/src/uqm/encount.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/uqm/encount.c')
-rw-r--r--src/uqm/encount.c844
1 files changed, 844 insertions, 0 deletions
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;
+
+}
+