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/gameev.c | 729 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 729 insertions(+) create mode 100644 src/uqm/gameev.c (limited to 'src/uqm/gameev.c') diff --git a/src/uqm/gameev.c b/src/uqm/gameev.c new file mode 100644 index 0000000..83df601 --- /dev/null +++ b/src/uqm/gameev.c @@ -0,0 +1,729 @@ +//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 "gameev.h" + +#include "build.h" +#include "clock.h" +#include "starmap.h" +#include "gendef.h" +#include "globdata.h" +#include "hyper.h" +#include "libs/compiler.h" +#include "libs/mathlib.h" + + +static void arilou_entrance_event (void); +static void arilou_exit_event (void); +static void check_race_growth (void); +static void black_urquan_genocide (void); +static void pkunk_mission (void); +static void thradd_mission (void); +static void ilwrath_mission (void); +static void utwig_supox_mission (void); +static void mycon_mission (void); + + +void +AddInitialGameEvents (void) { + AddEvent (RELATIVE_EVENT, 0, 1, 0, HYPERSPACE_ENCOUNTER_EVENT); + AddEvent (ABSOLUTE_EVENT, 3, 17, START_YEAR, ARILOU_ENTRANCE_EVENT); + AddEvent (RELATIVE_EVENT, 0, 0, YEARS_TO_KOHRAH_VICTORY, + KOHR_AH_VICTORIOUS_EVENT); + AddEvent (RELATIVE_EVENT, 0, 0, 0, SLYLANDRO_RAMP_UP); +} + +void +EventHandler (BYTE selector) +{ + switch (selector) + { + case ARILOU_ENTRANCE_EVENT: + arilou_entrance_event (); + break; + case ARILOU_EXIT_EVENT: + arilou_exit_event (); + break; + case HYPERSPACE_ENCOUNTER_EVENT: + check_race_growth (); + if (inHyperSpace ()) + check_hyperspace_encounter (); + + AddEvent (RELATIVE_EVENT, 0, 1, 0, HYPERSPACE_ENCOUNTER_EVENT); + break; + case KOHR_AH_VICTORIOUS_EVENT: + if (GET_GAME_STATE (UTWIG_SUPOX_MISSION)) + { + AddEvent (RELATIVE_EVENT, 0, 0, 1, KOHR_AH_GENOCIDE_EVENT); + break; + } + /* FALLTHROUGH */ + case KOHR_AH_GENOCIDE_EVENT: + if (!GET_GAME_STATE (KOHR_AH_FRENZY) + && LOBYTE (GLOBAL (CurrentActivity)) == IN_INTERPLANETARY + && CurStarDescPtr + && CurStarDescPtr->Index == SAMATRA_DEFINED) + AddEvent (RELATIVE_EVENT, 0, 7, 0, KOHR_AH_GENOCIDE_EVENT); + else + black_urquan_genocide (); + break; + case ADVANCE_PKUNK_MISSION: + pkunk_mission (); + break; + case ADVANCE_THRADD_MISSION: + thradd_mission (); + break; + case ZOQFOT_DISTRESS_EVENT: + if (LOBYTE (GLOBAL (CurrentActivity)) == IN_INTERPLANETARY + && CurStarDescPtr + && CurStarDescPtr->Index == ZOQFOT_DEFINED) + AddEvent (RELATIVE_EVENT, 0, 7, 0, ZOQFOT_DISTRESS_EVENT); + else + { + SET_GAME_STATE (ZOQFOT_DISTRESS, 1); + AddEvent (RELATIVE_EVENT, 6, 0, 0, ZOQFOT_DEATH_EVENT); + } + break; + case ZOQFOT_DEATH_EVENT: + if (LOBYTE (GLOBAL (CurrentActivity)) == IN_INTERPLANETARY + && CurStarDescPtr + && CurStarDescPtr->Index == ZOQFOT_DEFINED) + AddEvent (RELATIVE_EVENT, 0, 7, 0, ZOQFOT_DEATH_EVENT); + else if (GET_GAME_STATE (ZOQFOT_DISTRESS)) + { + HFLEETINFO hZoqFot; + FLEET_INFO *ZoqFotPtr; + + hZoqFot = GetStarShipFromIndex (&GLOBAL (avail_race_q), + ZOQFOTPIK_SHIP); + ZoqFotPtr = LockFleetInfo (&GLOBAL (avail_race_q), hZoqFot); + ZoqFotPtr->actual_strength = 0; + ZoqFotPtr->allied_state = DEAD_GUY; + UnlockFleetInfo (&GLOBAL (avail_race_q), hZoqFot); + + SET_GAME_STATE (ZOQFOT_DISTRESS, 2); + } + break; + case SHOFIXTI_RETURN_EVENT: + SetRaceAllied (SHOFIXTI_SHIP, TRUE); + GLOBAL (CrewCost) -= 2; + /* crew is not an issue anymore */ + SET_GAME_STATE (CREW_PURCHASED0, 0); + SET_GAME_STATE (CREW_PURCHASED1, 0); + break; + case ADVANCE_UTWIG_SUPOX_MISSION: + utwig_supox_mission (); + break; + case SPATHI_SHIELD_EVENT: + if (LOBYTE (GLOBAL (CurrentActivity)) == IN_INTERPLANETARY + && CurStarDescPtr + && CurStarDescPtr->Index == SPATHI_DEFINED) + AddEvent (RELATIVE_EVENT, 0, 7, 0, SPATHI_SHIELD_EVENT); + else + { + HFLEETINFO hSpathi; + FLEET_INFO *SpathiPtr; + + hSpathi = GetStarShipFromIndex (&GLOBAL (avail_race_q), + SPATHI_SHIP); + SpathiPtr = LockFleetInfo (&GLOBAL (avail_race_q), hSpathi); + + if (SpathiPtr->actual_strength) + { + SetRaceAllied (SPATHI_SHIP, FALSE); + SET_GAME_STATE (SPATHI_SHIELDED_SELVES, 1); + SpathiPtr->actual_strength = 0; + } + + UnlockFleetInfo (&GLOBAL (avail_race_q), hSpathi); + } + break; + case ADVANCE_ILWRATH_MISSION: + ilwrath_mission (); + break; + case ADVANCE_MYCON_MISSION: + mycon_mission (); + break; + case ARILOU_UMGAH_CHECK: + SET_GAME_STATE (ARILOU_CHECKED_UMGAH, 2); + break; + case YEHAT_REBEL_EVENT: + { + HFLEETINFO hRebel, hRoyalist; + FLEET_INFO *RebelPtr; + FLEET_INFO *RoyalistPtr; + + hRebel = GetStarShipFromIndex (&GLOBAL (avail_race_q), + YEHAT_REBEL_SHIP); + RebelPtr = LockFleetInfo (&GLOBAL (avail_race_q), hRebel); + hRoyalist = GetStarShipFromIndex (&GLOBAL (avail_race_q), + YEHAT_SHIP); + RoyalistPtr = LockFleetInfo (&GLOBAL (avail_race_q), hRoyalist); + RoyalistPtr->actual_strength = RoyalistPtr->actual_strength * + 2 / 3; + RebelPtr->actual_strength = RoyalistPtr->actual_strength; + RebelPtr->loc.x = 5150; + RebelPtr->loc.y = 0; + UnlockFleetInfo (&GLOBAL (avail_race_q), hRoyalist); + UnlockFleetInfo (&GLOBAL (avail_race_q), hRebel); + StartSphereTracking (YEHAT_REBEL_SHIP); + break; + } + case SLYLANDRO_RAMP_UP: + if (!GET_GAME_STATE (DESTRUCT_CODE_ON_SHIP)) + { + BYTE ramp_factor; + + ramp_factor = GET_GAME_STATE (SLYLANDRO_MULTIPLIER); + if (++ramp_factor <= 4) + { + SET_GAME_STATE (SLYLANDRO_MULTIPLIER, ramp_factor); + AddEvent (RELATIVE_EVENT, 0, 182, 0, SLYLANDRO_RAMP_UP); + } + } + break; + case SLYLANDRO_RAMP_DOWN: + { + BYTE ramp_factor; + + ramp_factor = GET_GAME_STATE (SLYLANDRO_MULTIPLIER); + if (--ramp_factor) + AddEvent (RELATIVE_EVENT, 0, 23, 0, SLYLANDRO_RAMP_DOWN); + SET_GAME_STATE (SLYLANDRO_MULTIPLIER, ramp_factor); + break; + } + } +} + +void +SetRaceDest (BYTE which_race, COORD x, COORD y, BYTE days_left, BYTE + func_index) +{ + HFLEETINFO hFleet; + FLEET_INFO *FleetPtr; + + hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), which_race); + FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), hFleet); + + FleetPtr->dest_loc.x = x; + FleetPtr->dest_loc.y = y; + FleetPtr->days_left = days_left; + FleetPtr->func_index = func_index; + + UnlockFleetInfo (&GLOBAL (avail_race_q), hFleet); +} + + + +static void +arilou_entrance_event (void) +{ + SET_GAME_STATE (ARILOU_SPACE, OPENING); + AddEvent (RELATIVE_EVENT, 0, 3, 0, ARILOU_EXIT_EVENT); +} + +static void +arilou_exit_event (void) +{ + COUNT month_index, year_index; + + year_index = GLOBAL (GameClock.year_index); + if ((month_index = GLOBAL (GameClock.month_index) % 12) == 0) + ++year_index; + ++month_index; + + SET_GAME_STATE (ARILOU_SPACE, CLOSING); + AddEvent (ABSOLUTE_EVENT, + month_index, 17, year_index, ARILOU_ENTRANCE_EVENT); +} + +static void +check_race_growth (void) +{ + HFLEETINFO hStarShip, hNextShip; + + for (hStarShip = GetHeadLink (&GLOBAL (avail_race_q)); + hStarShip; hStarShip = hNextShip) + { + FLEET_INFO *FleetPtr; + + FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), hStarShip); + hNextShip = _GetSuccLink (FleetPtr); + + if (FleetPtr->actual_strength + && FleetPtr->actual_strength != INFINITE_RADIUS) + { + SIZE delta_strength; + + delta_strength = (SBYTE)FleetPtr->growth; + if (FleetPtr->growth_err_term <= FleetPtr->growth_fract) + { + if (delta_strength <= 0) + --delta_strength; + else + ++delta_strength; + } + FleetPtr->growth_err_term -= FleetPtr->growth_fract; + + delta_strength += FleetPtr->actual_strength; + if (delta_strength <= 0) + { + delta_strength = 0; + FleetPtr->allied_state = DEAD_GUY; + } + else if (delta_strength > MAX_FLEET_STRENGTH) + delta_strength = MAX_FLEET_STRENGTH; + + FleetPtr->actual_strength = (COUNT)delta_strength; + if (FleetPtr->actual_strength && FleetPtr->days_left) + { + FleetPtr->loc.x += (FleetPtr->dest_loc.x - FleetPtr->loc.x) + / FleetPtr->days_left; + FleetPtr->loc.y += (FleetPtr->dest_loc.y - FleetPtr->loc.y) + / FleetPtr->days_left; + + if (--FleetPtr->days_left == 0 + && FleetPtr->func_index != (BYTE) ~0) + EventHandler (FleetPtr->func_index); + } + } + + UnlockFleetInfo (&GLOBAL (avail_race_q), hStarShip); + } +} + +static void +black_urquan_genocide (void) +{ + BYTE Index; + long best_dist; + SIZE best_dx, best_dy; + HFLEETINFO hStarShip, hNextShip; + HFLEETINFO hBlackUrquan; + FLEET_INFO *BlackUrquanPtr; + + hBlackUrquan = GetStarShipFromIndex (&GLOBAL (avail_race_q), + BLACK_URQUAN_SHIP); + BlackUrquanPtr = LockFleetInfo (&GLOBAL (avail_race_q), hBlackUrquan); + + best_dist = -1; + best_dx = SOL_X - BlackUrquanPtr->loc.x; + best_dy = SOL_Y - BlackUrquanPtr->loc.y; + for (Index = 0, hStarShip = GetHeadLink (&GLOBAL (avail_race_q)); + hStarShip; ++Index, hStarShip = hNextShip) + { + FLEET_INFO *FleetPtr; + + FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), hStarShip); + hNextShip = _GetSuccLink (FleetPtr); + + if (Index != BLACK_URQUAN_SHIP + && Index != URQUAN_SHIP + && FleetPtr->actual_strength != INFINITE_RADIUS) + { + SIZE dx, dy; + + dx = FleetPtr->loc.x - BlackUrquanPtr->loc.x; + dy = FleetPtr->loc.y - BlackUrquanPtr->loc.y; + if (dx == 0 && dy == 0) + { + // Arrived at the victim's home world. Cleanse it. + FleetPtr->allied_state = DEAD_GUY; + FleetPtr->actual_strength = 0; + } + else if (FleetPtr->actual_strength) + { + long dist; + + dist = (long)dx * dx + (long)dy * dy; + if (best_dist < 0 || dist < best_dist || Index == DRUUGE_SHIP) + { + best_dist = dist; + best_dx = dx; + best_dy = dy; + + if (Index == DRUUGE_SHIP) + hNextShip = 0; + } + } + } + + UnlockFleetInfo (&GLOBAL (avail_race_q), hStarShip); + } + + if (best_dist < 0 && best_dx == 0 && best_dy == 0) + { + // All spheres of influence are gone - game over. + GLOBAL (CurrentActivity) &= ~IN_BATTLE; + GLOBAL_SIS (CrewEnlisted) = (COUNT)~0; + + SET_GAME_STATE (KOHR_AH_KILLED_ALL, 1); + } + else + { + // Moving towards new race to cleanse. + COUNT speed; + + if (best_dist < 0) + best_dist = (long)best_dx * best_dx + (long)best_dy * best_dy; + + speed = square_root (best_dist) / 158; + if (speed == 0) + speed = 1; + else if (speed > 255) + speed = 255; + + SET_GAME_STATE (KOHR_AH_FRENZY, 1); + SET_GAME_STATE (KOHR_AH_VISITS, 0); + SET_GAME_STATE (KOHR_AH_REASONS, 0); + SET_GAME_STATE (KOHR_AH_PLEAD, 0); + SET_GAME_STATE (KOHR_AH_INFO, 0); + SET_GAME_STATE (URQUAN_VISITS, 0); + SetRaceDest (BLACK_URQUAN_SHIP, + BlackUrquanPtr->loc.x + best_dx, + BlackUrquanPtr->loc.y + best_dy, + (BYTE)speed, KOHR_AH_GENOCIDE_EVENT); + } + + UnlockFleetInfo (&GLOBAL (avail_race_q), hBlackUrquan); +} + +static void +pkunk_mission (void) +{ + HFLEETINFO hPkunk; + FLEET_INFO *PkunkPtr; + + hPkunk = GetStarShipFromIndex (&GLOBAL (avail_race_q), PKUNK_SHIP); + PkunkPtr = LockFleetInfo (&GLOBAL (avail_race_q), hPkunk); + + if (PkunkPtr->actual_strength) + { + BYTE MissionState; + + MissionState = GET_GAME_STATE (PKUNK_MISSION); + if (PkunkPtr->days_left == 0 && MissionState) + { + if ((MissionState & 1) + /* made it to Yehat space */ + || (PkunkPtr->loc.x == 4970 + && PkunkPtr->loc.y == 400)) + PkunkPtr->actual_strength = 0; + else if (PkunkPtr->loc.x == 502 + && PkunkPtr->loc.y == 401 + && GET_GAME_STATE (PKUNK_ON_THE_MOVE)) + { + SET_GAME_STATE (PKUNK_ON_THE_MOVE, 0); + AddEvent (RELATIVE_EVENT, 3, 0, 0, ADVANCE_PKUNK_MISSION); + UnlockFleetInfo (&GLOBAL (avail_race_q), hPkunk); + return; + } + } + + if (PkunkPtr->actual_strength == 0) + { + SET_GAME_STATE (YEHAT_ABSORBED_PKUNK, 1); + PkunkPtr->allied_state = DEAD_GUY; + StartSphereTracking (YEHAT_SHIP); + } + else + { + COORD x, y; + + if (!(MissionState & 1)) + { + x = 4970; + y = 400; + } + else + { + x = 502; + y = 401; + } + SET_GAME_STATE (PKUNK_ON_THE_MOVE, 1); + SET_GAME_STATE (PKUNK_SWITCH, 0); + SetRaceDest (PKUNK_SHIP, x, y, + (BYTE)((365 >> 1) - PkunkPtr->days_left), + ADVANCE_PKUNK_MISSION); + } + SET_GAME_STATE (PKUNK_MISSION, MissionState + 1); + } + + UnlockFleetInfo (&GLOBAL (avail_race_q), hPkunk); +} + +static void +thradd_mission (void) +{ + BYTE MissionState; + HFLEETINFO hThradd; + FLEET_INFO *ThraddPtr; + + hThradd = GetStarShipFromIndex (&GLOBAL (avail_race_q), THRADDASH_SHIP); + ThraddPtr = LockFleetInfo (&GLOBAL (avail_race_q), hThradd); + + MissionState = GET_GAME_STATE (THRADD_MISSION); + if (ThraddPtr->actual_strength && MissionState < 3) + { + COORD x, y; + + if (MissionState < 2) + { /* attacking */ + x = 4879; + y = 7201; + } + else + { /* returning */ + x = 2535; + y = 8358; + } + + if (MissionState == 1) + { /* arrived at Kohr-Ah, engaging */ + SIZE strength_loss; + + strength_loss = (SIZE)(ThraddPtr->actual_strength >> 1); + ThraddPtr->growth = (BYTE)(-strength_loss / 14); + ThraddPtr->growth_fract = (BYTE)(((strength_loss % 14) << 8) / 14); + ThraddPtr->growth_err_term = 255 >> 1; + } + else + { + if (MissionState != 0) + { /* stop losses */ + ThraddPtr->growth = 0; + ThraddPtr->growth_fract = 0; + } + } + SetRaceDest (THRADDASH_SHIP, x, y, 14, ADVANCE_THRADD_MISSION); + } + ++MissionState; + SET_GAME_STATE (THRADD_MISSION, MissionState); + + if (MissionState == 4 && GET_GAME_STATE (ILWRATH_FIGHT_THRADDASH)) + { /* returned home - notify the Ilwrath */ + AddEvent (RELATIVE_EVENT, 0, 0, 0, ADVANCE_ILWRATH_MISSION); + } + + UnlockFleetInfo (&GLOBAL (avail_race_q), hThradd); +} + +static void +ilwrath_mission (void) +{ + BYTE ThraddState; + HFLEETINFO hIlwrath, hThradd; + FLEET_INFO *IlwrathPtr; + FLEET_INFO *ThraddPtr; + + hIlwrath = GetStarShipFromIndex (&GLOBAL (avail_race_q), ILWRATH_SHIP); + IlwrathPtr = LockFleetInfo (&GLOBAL (avail_race_q), hIlwrath); + hThradd = GetStarShipFromIndex (&GLOBAL (avail_race_q), THRADDASH_SHIP); + ThraddPtr = LockFleetInfo (&GLOBAL (avail_race_q), hThradd); + + if (IlwrathPtr->loc.x == ((2500 + 2535) >> 1) + && IlwrathPtr->loc.y == ((8070 + 8358) >> 1)) + { + IlwrathPtr->actual_strength = 0; + ThraddPtr->actual_strength = 0; + IlwrathPtr->allied_state = DEAD_GUY; + ThraddPtr->allied_state = DEAD_GUY; + } + else if (IlwrathPtr->actual_strength) + { + if (!GET_GAME_STATE (ILWRATH_FIGHT_THRADDASH) + && (IlwrathPtr->dest_loc.x != 2500 + || IlwrathPtr->dest_loc.y != 8070)) + { + SetRaceDest (ILWRATH_SHIP, 2500, 8070, 90, + ADVANCE_ILWRATH_MISSION); + } + else + { +#define MADD_LENGTH 128 + SIZE strength_loss; + + if (IlwrathPtr->days_left == 0) + { /* arrived for battle */ + SET_GAME_STATE (ILWRATH_FIGHT_THRADDASH, 1); + SET_GAME_STATE (HELIX_UNPROTECTED, 1); + strength_loss = (SIZE)IlwrathPtr->actual_strength; + IlwrathPtr->growth = (BYTE)(-strength_loss / MADD_LENGTH); + IlwrathPtr->growth_fract = + (BYTE)(((strength_loss % MADD_LENGTH) << 8) / MADD_LENGTH); + SetRaceDest (ILWRATH_SHIP, + (2500 + 2535) >> 1, (8070 + 8358) >> 1, + MADD_LENGTH - 1, ADVANCE_ILWRATH_MISSION); + + strength_loss = (SIZE)ThraddPtr->actual_strength; + ThraddPtr->growth = (BYTE)(-strength_loss / MADD_LENGTH); + ThraddPtr->growth_fract = + (BYTE)(((strength_loss % MADD_LENGTH) << 8) / MADD_LENGTH); + + SET_GAME_STATE (THRADD_VISITS, 0); + if (ThraddPtr->allied_state == GOOD_GUY) + SetRaceAllied (THRADDASH_SHIP, FALSE); + } + + ThraddState = GET_GAME_STATE (THRADD_MISSION); + if (ThraddState == 0 || ThraddState > 3) + { /* never went to Kohr-Ah or returned */ + SetRaceDest (THRADDASH_SHIP, + (2500 + 2535) >> 1, (8070 + 8358) >> 1, + IlwrathPtr->days_left + 1, (BYTE)~0); + } + else if (ThraddState < 3) + { /* recall on the double */ + SetRaceDest (THRADDASH_SHIP, 2535, 8358, 10, + ADVANCE_THRADD_MISSION); + SET_GAME_STATE (THRADD_MISSION, 3); + } + } + } + + UnlockFleetInfo (&GLOBAL (avail_race_q), hThradd); + UnlockFleetInfo (&GLOBAL (avail_race_q), hIlwrath); +} + +static void +utwig_supox_mission (void) +{ + BYTE MissionState; + HFLEETINFO hUtwig, hSupox; + FLEET_INFO *UtwigPtr; + FLEET_INFO *SupoxPtr; + + hUtwig = GetStarShipFromIndex (&GLOBAL (avail_race_q), UTWIG_SHIP); + UtwigPtr = LockFleetInfo (&GLOBAL (avail_race_q), hUtwig); + hSupox = GetStarShipFromIndex (&GLOBAL (avail_race_q), SUPOX_SHIP); + SupoxPtr = LockFleetInfo (&GLOBAL (avail_race_q), hSupox); + + MissionState = GET_GAME_STATE (UTWIG_SUPOX_MISSION); + if (UtwigPtr->actual_strength && MissionState < 5) + { + if (MissionState == 1) + { + SIZE strength_loss; + + AddEvent (RELATIVE_EVENT, 0, (160 >> 1), 0, + ADVANCE_UTWIG_SUPOX_MISSION); + + strength_loss = (SIZE)(UtwigPtr->actual_strength >> 1); + UtwigPtr->growth = (BYTE)(-strength_loss / 160); + UtwigPtr->growth_fract = + (BYTE)(((strength_loss % 160) << 8) / 160); + UtwigPtr->growth_err_term = 255 >> 1; + + strength_loss = (SIZE)(SupoxPtr->actual_strength >> 1); + if (strength_loss) + { + SupoxPtr->growth = (BYTE)(-strength_loss / 160); + SupoxPtr->growth_fract = + (BYTE)(((strength_loss % 160) << 8) / 160); + SupoxPtr->growth_err_term = 255 >> 1; + } + + SET_GAME_STATE (UTWIG_WAR_NEWS, 0); + SET_GAME_STATE (SUPOX_WAR_NEWS, 0); + } + else if (MissionState == 2) + { + AddEvent (RELATIVE_EVENT, 0, (160 >> 1), 0, + ADVANCE_UTWIG_SUPOX_MISSION); + ++MissionState; + } + else + { + COORD ux, uy, sx, sy; + + if (MissionState == 0) + { + ux = 7208; + uy = 7000; + + sx = 6479; + sy = 7541; + } + else + { + ux = 8534; + uy = 8797; + + sx = 7468; + sy = 9246; + + UtwigPtr->growth = 0; + UtwigPtr->growth_fract = 0; + SupoxPtr->growth = 0; + SupoxPtr->growth_fract = 0; + + SET_GAME_STATE (UTWIG_WAR_NEWS, 0); + SET_GAME_STATE (SUPOX_WAR_NEWS, 0); + } + SET_GAME_STATE (UTWIG_VISITS, 0); + SET_GAME_STATE (UTWIG_INFO, 0); + SET_GAME_STATE (SUPOX_VISITS, 0); + SET_GAME_STATE (SUPOX_INFO, 0); + SetRaceDest (UTWIG_SHIP, ux, uy, 21, ADVANCE_UTWIG_SUPOX_MISSION); + SetRaceDest (SUPOX_SHIP, sx, sy, 21, (BYTE)~0); + } + } + SET_GAME_STATE (UTWIG_SUPOX_MISSION, MissionState + 1); + + UnlockFleetInfo (&GLOBAL (avail_race_q), hSupox); + UnlockFleetInfo (&GLOBAL (avail_race_q), hUtwig); +} + +static void +mycon_mission (void) +{ + HFLEETINFO hMycon; + FLEET_INFO *MyconPtr; + + hMycon = GetStarShipFromIndex (&GLOBAL (avail_race_q), MYCON_SHIP); + MyconPtr = LockFleetInfo (&GLOBAL (avail_race_q), hMycon); + + if (MyconPtr->actual_strength) + { + if (MyconPtr->growth) + { + // Head back. + SET_GAME_STATE (MYCON_KNOW_AMBUSH, 1); + SetRaceDest (MYCON_SHIP, 6392, 2200, 30, (BYTE)~0); + + MyconPtr->growth = 0; + MyconPtr->growth_fract = 0; + } + else if (MyconPtr->loc.x != 6858 || MyconPtr->loc.y != 577) + SetRaceDest (MYCON_SHIP, 6858, 577, 30, ADVANCE_MYCON_MISSION); + // To Organon. + else + { + // Endure losses at Organon. + SIZE strength_loss; + + AddEvent (RELATIVE_EVENT, 0, 14, 0, ADVANCE_MYCON_MISSION); + strength_loss = (SIZE)(MyconPtr->actual_strength >> 1); + MyconPtr->growth = (BYTE)(-strength_loss / 14); + MyconPtr->growth_fract = (BYTE)(((strength_loss % 14) << 8) / 14); + MyconPtr->growth_err_term = 255 >> 1; + } + } + + UnlockFleetInfo (&GLOBAL (avail_race_q), hMycon); +} + -- cgit v1.2.3