static BOOLEAN DeltaSupportCrew (SIZE crew_delta) { BOOLEAN ret = FALSE; UNICODE buf[40]; HSTARSHIP hTemplate; SHIP_FRAGMENTPTR StarShipPtr, TemplatePtr; StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), (HSTARSHIP)pMenuState->CurFrame); hTemplate = GetStarShipFromIndex (&GLOBAL (avail_race_q), GET_RACE_ID (StarShipPtr)); TemplatePtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (avail_race_q), hTemplate); StarShipPtr->ShipInfo.crew_level += crew_delta; if (StarShipPtr->ShipInfo.crew_level == 0) StarShipPtr->ShipInfo.crew_level = 1; else if (StarShipPtr->ShipInfo.crew_level > TemplatePtr->RaceDescPtr->ship_info.crew_level && crew_delta > 0) StarShipPtr->ShipInfo.crew_level -= crew_delta; else { if (StarShipPtr->ShipInfo.crew_level >= TemplatePtr->RaceDescPtr->ship_info.crew_level) sprintf (buf, "%u", StarShipPtr->ShipInfo.crew_level); else sprintf (buf, "%u/%u", StarShipPtr->ShipInfo.crew_level, TemplatePtr->RaceDescPtr->ship_info.crew_level); DrawStatusMessage (buf); DeltaSISGauges (-crew_delta, 0, 0); if (crew_delta) { RECT r; r.corner.x = 2; r.corner.y = 130; r.extent.width = STATUS_MESSAGE_WIDTH; r.extent.height = STATUS_MESSAGE_HEIGHT; SetContext (StatusContext); SetFlashRect (&r, (FRAME)0); } ret = TRUE; } UnlockStarShip (&GLOBAL (avail_race_q), hTemplate); UnlockStarShip (&GLOBAL (built_ship_q), (HSTARSHIP)pMenuState->CurFrame); return ret; }
static BOOLEAN DeltaSupportCrew (ROSTER_STATE *rosterState, SIZE crew_delta) { BOOLEAN ret = FALSE; UNICODE buf[40]; HFLEETINFO hTemplate; HSHIPFRAG hShipFrag; SHIP_FRAGMENT *StarShipPtr; FLEET_INFO *TemplatePtr; StarShipPtr = LockSupportShip (rosterState, &hShipFrag); if (!StarShipPtr) return FALSE; hTemplate = GetStarShipFromIndex (&GLOBAL (avail_race_q), StarShipPtr->race_id); TemplatePtr = LockFleetInfo (&GLOBAL (avail_race_q), hTemplate); StarShipPtr->crew_level += crew_delta; if (StarShipPtr->crew_level == 0) StarShipPtr->crew_level = 1; else if (StarShipPtr->crew_level > TemplatePtr->crew_level && crew_delta > 0) StarShipPtr->crew_level -= crew_delta; else { if (StarShipPtr->crew_level >= TemplatePtr->crew_level) sprintf (buf, "%u", StarShipPtr->crew_level); else sprintf (buf, "%u/%u", StarShipPtr->crew_level, TemplatePtr->crew_level); PreUpdateFlashRect (); DrawStatusMessage (buf); PostUpdateFlashRect (); DeltaSISGauges (-crew_delta, 0, 0); if (crew_delta) { flashSupportShipCrew (); } ret = TRUE; } UnlockFleetInfo (&GLOBAL (avail_race_q), hTemplate); UnlockShipFrag (&GLOBAL (built_ship_q), hShipFrag); return ret; }
/* * Give the player 'count' ships of the specified race, * limited by the number of free slots. * Returns the number of ships added. */ COUNT AddEscortShips (COUNT race, SIZE count) { HFLEETINFO hFleet; BYTE which_window; COUNT i; hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), race); if (!hFleet) return 0; assert (count > 0); which_window = 0; for (i = 0; i < (COUNT) count; i++) { HSHIPFRAG hStarShip; HSHIPFRAG hOldShip; SHIP_FRAGMENT *StarShipPtr; hStarShip = CloneShipFragment (race, &GLOBAL (built_ship_q), 0); if (!hStarShip) break; RemoveQueue (&GLOBAL (built_ship_q), hStarShip); /* Find first available escort window */ while ((hOldShip = GetStarShipFromIndex ( &GLOBAL (built_ship_q), which_window++))) { BYTE win_loc; StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hOldShip); win_loc = StarShipPtr->index; UnlockShipFrag (&GLOBAL (built_ship_q), hOldShip); if (which_window <= win_loc) break; } StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); StarShipPtr->index = which_window - 1; UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); InsertQueue (&GLOBAL (built_ship_q), hStarShip, hOldShip); } DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); return i; }
void clearEscorts (void) { HSHIPFRAG hStarShip, hNextShip; for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); hStarShip; hStarShip = hNextShip) { SHIP_FRAGMENT *StarShipPtr; StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); hNextShip = _GetSuccLink (StarShipPtr); UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); RemoveQueue (&GLOBAL (built_ship_q), hStarShip); FreeShipFrag (&GLOBAL (built_ship_q), hStarShip); } DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); }
/* * Remove a number of escort ships of the specified race (if present). * Returns the number of escort ships removed. */ COUNT RemoveSomeEscortShips (COUNT race, COUNT count) { HSHIPFRAG hStarShip; HSHIPFRAG hNextShip; if (count == 0) return 0; for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); hStarShip; hStarShip = hNextShip) { BOOLEAN RemoveShip; SHIP_FRAGMENT *StarShipPtr; StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); hNextShip = _GetSuccLink (StarShipPtr); RemoveShip = (StarShipPtr->race_id == race); UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); if (RemoveShip) { RemoveQueue (&GLOBAL (built_ship_q), hStarShip); FreeShipFrag (&GLOBAL (built_ship_q), hStarShip); count--; if (count == 0) break; } } if (count > 0) { // Update the display. DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); } return count; }
static void NoRadioactives (RESPONSE_REF R) { if (PLAYER_SAID (R, yes_this_is_supply_ship)) { NPCPhrase (ABOUT_TIME); if (GLOBAL_SIS (ElementAmounts[RADIOACTIVE])) GiveRadios (0); else { Response (i_lied, NoRadioactives); Response (plumb_out, NoRadioactives); } } else { if (PLAYER_SAID (R, where_can_i_get_radios)) { NPCPhrase (RADIOS_ON_MERCURY); DISABLE_PHRASE (where_can_i_get_radios); } else if (PLAYER_SAID (R, no_but_well_help0)) NPCPhrase (THE_WHAT_FROM_WHERE); else if (PLAYER_SAID (R, what_slave_planet) || PLAYER_SAID (R, i_lied)) NPCPhrase (DONT_KNOW_WHO_YOU_ARE); else if (PLAYER_SAID (R, plumb_out)) NPCPhrase (WHAT_KIND_OF_IDIOT); else if (PLAYER_SAID (R, i_lost_my_lander)) { NPCPhrase (HERE_IS_A_NEW_LANDER); ++GLOBAL_SIS (NumLanders); LockMutex (GraphicsLock); DrawLanders (); DeltaSISGauges (4, 0, 0); UnlockMutex (GraphicsLock); SET_GAME_STATE (LANDERS_LOST, 1); } else if (PLAYER_SAID (R, i_lost_another_lander)) { NPCPhrase (HERE_IS_ANOTHER_LANDER); ++GLOBAL_SIS (NumLanders); LockMutex (GraphicsLock); DrawLanders (); DeltaSISGauges (4, 0, 0); UnlockMutex (GraphicsLock); } else if (PLAYER_SAID (R, need_fuel_mercury) || PLAYER_SAID (R, need_fuel_luna)) { NPCPhrase (GIVE_FUEL); LockMutex (GraphicsLock); DeltaSISGauges (0, 5 * FUEL_TANK_SCALE, 0); UnlockMutex (GraphicsLock); SET_GAME_STATE (GIVEN_FUEL_BEFORE, 1); } else if (PLAYER_SAID (R, need_fuel_again)) { NPCPhrase (GIVE_FUEL_AGAIN); LockMutex (GraphicsLock); DeltaSISGauges (0, 5 * FUEL_TANK_SCALE, 0); UnlockMutex (GraphicsLock); } if (GLOBAL_SIS (ElementAmounts[RADIOACTIVE])) GiveRadios (0); else { if (GLOBAL_SIS (NumLanders) == 0 && GET_GAME_STATE (CHMMR_BOMB_STATE) < 2) { if (GET_GAME_STATE (LANDERS_LOST)) Response (i_lost_another_lander, NoRadioactives); else Response (i_lost_my_lander, NoRadioactives); } if (GLOBAL_SIS (FuelOnBoard) < 2 * FUEL_TANK_SCALE) { if (GET_GAME_STATE (GIVEN_FUEL_BEFORE)) Response (need_fuel_again, NoRadioactives); else Response (need_fuel_mercury, NoRadioactives); } Response (ok_i_will_get_radios, ByeBye); if (PHRASE_ENABLED (where_can_i_get_radios)) { Response (where_can_i_get_radios, NoRadioactives); } } } }
static BOOLEAN DeltaSupportCrew (SIZE crew_delta) { BOOLEAN ret = FALSE; UNICODE buf[40]; HFLEETINFO hTemplate; SHIP_FRAGMENT *StarShipPtr; FLEET_INFO *TemplatePtr; StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), (HSHIPFRAG)pMenuState->CurFrame); hTemplate = GetStarShipFromIndex (&GLOBAL (avail_race_q), StarShipPtr->race_id); TemplatePtr = LockFleetInfo (&GLOBAL (avail_race_q), hTemplate); if (crew_delta > 0) { while (crew_delta && (StarShipPtr->crew_level + crew_delta) > StarShipPtr->max_crew) crew_delta--; } else if (crew_delta < 0) { while (crew_delta && (StarShipPtr->crew_level + crew_delta) < 1) crew_delta++; } StarShipPtr->crew_level += crew_delta; if (StarShipPtr->crew_level == 0) StarShipPtr->crew_level = 1; else if (StarShipPtr->crew_level > TemplatePtr->crew_level && crew_delta > 0) StarShipPtr->crew_level -= crew_delta; else { if (StarShipPtr->crew_level >= TemplatePtr->crew_level) sprintf (buf, "%u", StarShipPtr->crew_level); else sprintf (buf, "%u/%u", StarShipPtr->crew_level, TemplatePtr->crew_level); DrawStatusMessage (buf); DeltaSISGauges (-crew_delta, 0, 0); if (crew_delta) { RECT r; r.corner.x = 2; r.corner.y = 130; r.extent.width = STATUS_MESSAGE_WIDTH; r.extent.height = STATUS_MESSAGE_HEIGHT; SetContext (StatusContext); SetFlashRect (&r, (FRAME)0); } ret = TRUE; } UnlockFleetInfo (&GLOBAL (avail_race_q), hTemplate); UnlockShipFrag (&GLOBAL (built_ship_q), (HSHIPFRAG)pMenuState->CurFrame); return ret; }
static void DoTransaction (RESPONSE_REF R) { if (PLAYER_SAID (R, sell_maidens)) { SET_GAME_STATE (MAIDENS_ON_SHIP, 0); } else if (PLAYER_SAID (R, sell_fragments)) { BYTE num_frags; if (GET_GAME_STATE (EGG_CASE0_ON_SHIP)) { SET_GAME_STATE (EGG_CASE0_ON_SHIP, 0); } else if (GET_GAME_STATE (EGG_CASE1_ON_SHIP)) { SET_GAME_STATE (EGG_CASE1_ON_SHIP, 0); } else if (GET_GAME_STATE (EGG_CASE2_ON_SHIP)) { SET_GAME_STATE (EGG_CASE2_ON_SHIP, 0); } num_frags = GET_GAME_STATE (FRAGMENTS_BOUGHT) + 1; SET_GAME_STATE (FRAGMENTS_BOUGHT, num_frags); } else if (PLAYER_SAID (R, sell_caster)) { SET_GAME_STATE (BURV_BROADCASTERS_ON_SHIP, 0); } else if (PLAYER_SAID (R, sell_spawner)) { SET_GAME_STATE (PORTAL_SPAWNER_ON_SHIP, 0); } if (!GET_GAME_STATE (ROSY_SPHERE) && GET_GAME_STATE (ROSY_SPHERE_ON_SHIP)) { SET_GAME_STATE (ROSY_SPHERE, 1); } else { BYTE trade_gas; BYTE ship_slots, ships_to_trade; trade_gas = 0; ships_to_trade = 0; ship_slots = EscortFeasibilityStudy (DRUUGE_SHIP); if (PLAYER_SAID (R, sell_maidens)) { NPCPhrase (BOUGHT_MAIDENS); ships_to_trade = 6; } else if (PLAYER_SAID (R, sell_fragments)) { NPCPhrase (BOUGHT_FRAGMENTS); ships_to_trade = 1; } else if (PLAYER_SAID (R, sell_caster)) { NPCPhrase (BOUGHT_CASTER); ships_to_trade = 0; trade_gas = 1; } else if (PLAYER_SAID (R, sell_spawner)) { NPCPhrase (BOUGHT_SPAWNER); ships_to_trade = 3; trade_gas = 1; } NPCPhrase (YOU_GET); if (ships_to_trade) { AddEscortShips (DRUUGE_SHIP, ships_to_trade); if (ship_slots >= ships_to_trade) NPCPhrase (DEAL_FOR_STATED_SHIPS); else if (ship_slots == 0) NPCPhrase (DEAL_FOR_NO_SHIPS); else NPCPhrase (DEAL_FOR_LESS_SHIPS); if (trade_gas) NPCPhrase (YOU_ALSO_GET); } if (trade_gas) { BYTE slot; COUNT f; DWORD capacity; capacity = FUEL_RESERVE; slot = NUM_MODULE_SLOTS - 1; do { if (GLOBAL_SIS (ModuleSlots[slot]) == FUEL_TANK || GLOBAL_SIS (ModuleSlots[slot]) == HIGHEFF_FUELSYS) { COUNT volume; volume = GLOBAL_SIS (ModuleSlots[slot]) == FUEL_TANK ? FUEL_TANK_CAPACITY : HEFUEL_TANK_CAPACITY; capacity += volume; } } while (slot--); capacity -= GLOBAL_SIS (FuelOnBoard); f = (COUNT)((capacity + (FUEL_TANK_SCALE >> 1)) / FUEL_TANK_SCALE); while (capacity > 0x3FFFL) { DeltaSISGauges (0, 0x3FFF, 0); capacity -= 0x3FFF; } DeltaSISGauges (0, (SIZE)capacity, 0); NPCPhrase (FUEL0); NPCNumber (f, NULL); NPCPhrase (FUEL1); if (f >= 250) NPCPhrase (HIDEOUS_DEAL); else if (f >= 100) NPCPhrase (BAD_DEAL); else if (f >= 50) NPCPhrase (FAIR_DEAL); else if (f >= 10) NPCPhrase (GOOD_DEAL); else NPCPhrase (FINE_DEAL); } } }
static void DoBuy (RESPONSE_REF R) { COUNT credit; SIZE needed_credit; BYTE slot; DWORD capacity; credit = GetAvailableCredits (); capacity = FUEL_RESERVE; slot = NUM_MODULE_SLOTS - 1; do { if (GLOBAL_SIS (ModuleSlots[slot]) == FUEL_TANK || GLOBAL_SIS (ModuleSlots[slot]) == HIGHEFF_FUELSYS) { COUNT volume; volume = GLOBAL_SIS (ModuleSlots[slot]) == FUEL_TANK ? FUEL_TANK_CAPACITY : HEFUEL_TANK_CAPACITY; capacity += volume; } } while (slot--); // If they're out of credits, educate them on how commerce works. if (credit == 0) { AskedToBuy = TRUE; NPCPhrase (NEED_CREDIT); NatureOfConversation (R); } else if (PLAYER_SAID (R, buy_fuel) || PLAYER_SAID (R, buy_1_fuel) || PLAYER_SAID (R, buy_5_fuel) || PLAYER_SAID (R, buy_10_fuel) || PLAYER_SAID (R, buy_25_fuel) || PLAYER_SAID (R, fill_me_up)) { needed_credit = 0; if (PLAYER_SAID (R, buy_1_fuel)) needed_credit = 1; else if (PLAYER_SAID (R, buy_5_fuel)) needed_credit = 5; else if (PLAYER_SAID (R, buy_10_fuel)) needed_credit = 10; else if (PLAYER_SAID (R, buy_25_fuel)) needed_credit = 25; else if (PLAYER_SAID (R, fill_me_up)) needed_credit = (capacity - GLOBAL_SIS (FuelOnBoard) + FUEL_TANK_SCALE - 1) / FUEL_TANK_SCALE; if (needed_credit == 0) { if (!GET_GAME_STATE (MELNORME_FUEL_PROCEDURE)) { NPCPhrase (BUY_FUEL_INTRO); SET_GAME_STATE (MELNORME_FUEL_PROCEDURE, 1); } } else { if (GLOBAL_SIS (FuelOnBoard) / FUEL_TANK_SCALE + needed_credit > capacity / FUEL_TANK_SCALE) { NPCPhrase (NO_ROOM_FOR_FUEL); goto TryFuelAgain; } if ((int)(needed_credit * (BIO_CREDIT_VALUE / 2)) <= (int)credit) { DWORD f; NPCPhrase (GOT_FUEL); f = (DWORD)needed_credit * FUEL_TANK_SCALE; while (f > 0x3FFFL) { DeltaSISGauges (0, 0x3FFF, 0); f -= 0x3FFF; } DeltaSISGauges (0, (SIZE)f, 0); } needed_credit *= (BIO_CREDIT_VALUE / 2); } if (needed_credit) { DeltaCredit (-needed_credit); if (GLOBAL_SIS (FuelOnBoard) >= capacity) goto BuyBuyBuy; } TryFuelAgain: NPCPhrase (HOW_MUCH_FUEL); Response (buy_1_fuel, DoBuy); Response (buy_5_fuel, DoBuy); Response (buy_10_fuel, DoBuy); Response (buy_25_fuel, DoBuy); Response (fill_me_up, DoBuy); Response (done_buying_fuel, DoBuy); } else if (PLAYER_SAID (R, buy_technology) || PLAYER_SAID (R, buy_new_tech)) { // Note that this code no longer uses the MELNORME_TECH_STACK state // buts, as they're not needed; we can tell what technologies the // player has by using the technology API above. This opens the // possibility of the player acquiring tech from someplace other than // the Melnorme. const TechSaleData* nextTech; // If it's our first time, give an introduction. if (!GET_GAME_STATE (MELNORME_TECH_PROCEDURE)) { NPCPhrase (BUY_NEW_TECH_INTRO); SET_GAME_STATE (MELNORME_TECH_PROCEDURE, 1); } // Did the player just attempt to buy a tech? if (PLAYER_SAID (R, buy_new_tech)) { nextTech = GetNextTechForSale (); if (!nextTech) goto BuyBuyBuy; // No tech left to buy if (!DeltaCredit (-nextTech->price)) goto BuyBuyBuy; // Can't afford it // Make the sale GrantTech (nextTech->techId); NPCPhrase (nextTech->sold_line); } nextTech = GetNextTechForSale (); if (!nextTech) { NPCPhrase (NEW_TECH_ALL_GONE); goto BuyBuyBuy; // No tech left to buy } NPCPhrase (nextTech->sale_line); Response (buy_new_tech, DoBuy); Response (no_buy_new_tech, DoBuy); } else if (PLAYER_SAID (R, buy_info) || PLAYER_SAID (R, buy_current_events) || PLAYER_SAID (R, buy_alien_races) || PLAYER_SAID (R, buy_history)) { if (!GET_GAME_STATE (MELNORME_INFO_PROCEDURE)) { NPCPhrase (BUY_INFO_INTRO); SET_GAME_STATE (MELNORME_INFO_PROCEDURE, 1); } else if (PLAYER_SAID (R, buy_info)) { NPCPhrase (OK_BUY_INFO); } else { #define INFO_COST 75 if (!DeltaCredit (-INFO_COST)) goto BuyBuyBuy; if (PLAYER_SAID (R, buy_current_events)) CurrentEvents (); else if (PLAYER_SAID (R, buy_alien_races)) AlienRaces (); else if (PLAYER_SAID (R, buy_history)) History (); } if (!AnyInfoLeftToSell ()) { NPCPhrase (INFO_ALL_GONE); goto BuyBuyBuy; } if (GET_GAME_STATE (MELNORME_EVENTS_INFO_STACK) < NUM_EVENT_ITEMS) Response (buy_current_events, DoBuy); if (GET_GAME_STATE (MELNORME_ALIEN_INFO_STACK) < NUM_ALIEN_RACE_ITEMS) Response (buy_alien_races, DoBuy); if (GET_GAME_STATE (MELNORME_HISTORY_INFO_STACK) < NUM_HISTORY_ITEMS) Response (buy_history, DoBuy); Response (done_buying_info, DoBuy); } else { if (PLAYER_SAID (R, done_buying_fuel)) NPCPhrase (OK_DONE_BUYING_FUEL); else if (PLAYER_SAID (R, no_buy_new_tech)) NPCPhrase (OK_NO_BUY_NEW_TECH); else if (PLAYER_SAID (R, done_buying_info)) NPCPhrase (OK_DONE_BUYING_INFO); else NPCPhrase (WHAT_TO_BUY); BuyBuyBuy: if (GLOBAL_SIS (FuelOnBoard) < capacity) Response (buy_fuel, DoBuy); if (GetNextTechForSale ()) Response (buy_technology, DoBuy); if (AnyInfoLeftToSell ()) Response (buy_info, DoBuy); Response (done_buying, NatureOfConversation); Response (be_leaving_now, ExitConversation); } }
// NB: Ship maximum speed and turning rate aren't updated in // HyperSpace/QuasiSpace or in melee. void equipShip (void) { int i; // Don't do anything unless in the full game. if (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE) return; // Thrusters: for (i = 0; i < NUM_DRIVE_SLOTS; i++) GLOBAL_SIS (DriveSlots[i]) = FUSION_THRUSTER; // Turning jets: for (i = 0; i < NUM_JET_SLOTS; i++) GLOBAL_SIS (JetSlots[i]) = TURNING_JETS; // Shields: SET_GAME_STATE (LANDER_SHIELDS, (1 << EARTHQUAKE_DISASTER) | (1 << BIOLOGICAL_DISASTER) | (1 << LIGHTNING_DISASTER) | (1 << LAVASPOT_DISASTER)); // Lander upgrades: SET_GAME_STATE (IMPROVED_LANDER_SPEED, 1); SET_GAME_STATE (IMPROVED_LANDER_CARGO, 1); SET_GAME_STATE (IMPROVED_LANDER_SHOT, 1); // Modules: if (GET_GAME_STATE (CHMMR_BOMB_STATE) < 2) { // The Precursor bomb has not been installed. // This is the original TFB testing layout. i = 0; GLOBAL_SIS (ModuleSlots[i++]) = HIGHEFF_FUELSYS; GLOBAL_SIS (ModuleSlots[i++]) = HIGHEFF_FUELSYS; GLOBAL_SIS (ModuleSlots[i++]) = CREW_POD; GLOBAL_SIS (ModuleSlots[i++]) = CREW_POD; GLOBAL_SIS (ModuleSlots[i++]) = CREW_POD; GLOBAL_SIS (ModuleSlots[i++]) = CREW_POD; GLOBAL_SIS (ModuleSlots[i++]) = CREW_POD; GLOBAL_SIS (ModuleSlots[i++]) = STORAGE_BAY; GLOBAL_SIS (ModuleSlots[i++]) = SHIVA_FURNACE; GLOBAL_SIS (ModuleSlots[i++]) = SHIVA_FURNACE; GLOBAL_SIS (ModuleSlots[i++]) = DYNAMO_UNIT; GLOBAL_SIS (ModuleSlots[i++]) = TRACKING_SYSTEM; GLOBAL_SIS (ModuleSlots[i++]) = TRACKING_SYSTEM; GLOBAL_SIS (ModuleSlots[i++]) = SHIVA_FURNACE; GLOBAL_SIS (ModuleSlots[i++]) = CANNON_WEAPON; GLOBAL_SIS (ModuleSlots[i++]) = CANNON_WEAPON; // Landers: GLOBAL_SIS (NumLanders) = MAX_LANDERS; } else { // The Precursor bomb has been installed. i = NUM_BOMB_MODULES; GLOBAL_SIS (ModuleSlots[i++]) = HIGHEFF_FUELSYS; GLOBAL_SIS (ModuleSlots[i++]) = CREW_POD; GLOBAL_SIS (ModuleSlots[i++]) = SHIVA_FURNACE; GLOBAL_SIS (ModuleSlots[i++]) = SHIVA_FURNACE; GLOBAL_SIS (ModuleSlots[i++]) = CANNON_WEAPON; GLOBAL_SIS (ModuleSlots[i++]) = SHIVA_FURNACE; } assert (i <= NUM_MODULE_SLOTS); // Fill the fuel and crew compartments to the maximum. GLOBAL_SIS (FuelOnBoard) = FUEL_RESERVE; GLOBAL_SIS (CrewEnlisted) = 0; for (i = 0; i < NUM_MODULE_SLOTS; i++) { switch (GLOBAL_SIS (ModuleSlots[i])) { case CREW_POD: GLOBAL_SIS (CrewEnlisted) += CREW_POD_CAPACITY; break; case FUEL_TANK: GLOBAL_SIS (FuelOnBoard) += FUEL_TANK_CAPACITY; break; case HIGHEFF_FUELSYS: GLOBAL_SIS (FuelOnBoard) += HEFUEL_TANK_CAPACITY; break; } } // Update the maximum speed and turning rate when in interplanetary. if (pSolarSysState != NULL) { // Thrusters: pSolarSysState->max_ship_speed = 5 * IP_SHIP_THRUST_INCREMENT; for (i = 0; i < NUM_DRIVE_SLOTS; i++) if (GLOBAL_SIS (DriveSlots[i] == FUSION_THRUSTER)) pSolarSysState->max_ship_speed += IP_SHIP_THRUST_INCREMENT; // Turning jets: pSolarSysState->turn_wait = IP_SHIP_TURN_WAIT; for (i = 0; i < NUM_JET_SLOTS; i++) if (GLOBAL_SIS (JetSlots[i]) == TURNING_JETS) pSolarSysState->turn_wait -= IP_SHIP_TURN_DECREMENT; } // Make sure everything is redrawn: if (inHQSpace () || LOBYTE (GLOBAL (CurrentActivity)) == IN_INTERPLANETARY) { DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); } }
COUNT ActivateStarShip (COUNT which_ship, SIZE state) { HSTARSHIP hStarShip, hNextShip; hStarShip = GetStarShipFromIndex ( &GLOBAL (avail_race_q), which_ship ); if (hStarShip) { switch (state) { case SPHERE_TRACKING: case SPHERE_KNOWN: { EXTENDED_SHIP_FRAGMENTPTR StarShipPtr; StarShipPtr = (EXTENDED_SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (avail_race_q), hStarShip ); if (state == SPHERE_KNOWN) which_ship = StarShipPtr->ShipInfo.known_strength; else if (StarShipPtr->ShipInfo.actual_strength == 0) { if (!(StarShipPtr->ShipInfo.ship_flags & (GOOD_GUY | BAD_GUY))) which_ship = 0; } else if (StarShipPtr->ShipInfo.known_strength == 0 && StarShipPtr->ShipInfo.actual_strength != (COUNT)~0) { StarShipPtr->ShipInfo.known_strength = 1; StarShipPtr->ShipInfo.known_loc = StarShipPtr->ShipInfo.loc; } UnlockStarShip ( &GLOBAL (avail_race_q), hStarShip ); return (which_ship); } case ESCORT_WORTH: which_ship = 0; case ESCORTING_FLAGSHIP: { COUNT ShipCost[] = { RACE_SHIP_COST }; for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); hStarShip; hStarShip = hNextShip) { BYTE ship_type; SHIP_FRAGMENTPTR StarShipPtr; StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), hStarShip ); hNextShip = _GetSuccLink (StarShipPtr); if (state == ESCORT_WORTH) which_ship += ShipCost[GET_RACE_ID (StarShipPtr)]; else ship_type = GET_RACE_ID (StarShipPtr); UnlockStarShip ( &GLOBAL (built_ship_q), hStarShip ); if (state != ESCORT_WORTH && (COUNT)ship_type == which_ship) return (1); } return (state == ESCORTING_FLAGSHIP ? 0 : which_ship); } case FEASIBILITY_STUDY: return (MAX_BUILT_SHIPS - CountLinks (&GLOBAL (built_ship_q))); default: { SHIP_FRAGMENTPTR StarShipPtr; if (state <= 0) { StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (avail_race_q), hStarShip ); if (state == CHECK_ALLIANCE) { state = StarShipPtr->ShipInfo.ship_flags & (GOOD_GUY | BAD_GUY); UnlockStarShip ( &GLOBAL (avail_race_q), hStarShip ); return ((COUNT)state); } else if (StarShipPtr->ShipInfo.ship_flags & (GOOD_GUY | BAD_GUY)) { StarShipPtr->ShipInfo.ship_flags &= ~(GOOD_GUY | BAD_GUY); if (state == 0) StarShipPtr->ShipInfo.ship_flags |= GOOD_GUY; else { StarShipPtr->ShipInfo.ship_flags |= BAD_GUY; if (which_ship == ORZ_SHIP) { BOOLEAN ShipRemoved; ShipRemoved = FALSE; for (hStarShip = GetHeadLink ( &GLOBAL (built_ship_q )); hStarShip; hStarShip = hNextShip) { BOOLEAN RemoveShip; SHIP_FRAGMENTPTR StarShipPtr; StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), hStarShip ); hNextShip = _GetSuccLink (StarShipPtr); RemoveShip = (BOOLEAN)( GET_RACE_ID (StarShipPtr) == ORZ_SHIP ); UnlockStarShip ( &GLOBAL (built_ship_q), hStarShip ); if (RemoveShip) { ShipRemoved = TRUE; RemoveQueue ( &GLOBAL (built_ship_q), hStarShip ); FreeStarShip ( &GLOBAL (built_ship_q), hStarShip ); } } if (ShipRemoved) { SetSemaphore (GraphicsSem); DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); ClearSemaphore (GraphicsSem); } } } } UnlockStarShip ( &GLOBAL (avail_race_q), hStarShip ); } else { BYTE which_window; COUNT i; which_window = 0; for ( i = 0; i < (COUNT)state && ( hStarShip = CloneShipFragment ( (COUNT)which_ship, (PQUEUE)(&GLOBAL (built_ship_q)), (BYTE) ( ( which_ship == SPATHI_SHIP && GET_GAME_STATE (FOUND_PLUTO_SPATHI) ) == 1 ? 1 : 0 ) ) ); i++ ) { HSTARSHIP hOldShip; RemoveQueue ( &GLOBAL (built_ship_q), hStarShip ); while ((hOldShip = GetStarShipFromIndex ( &GLOBAL (built_ship_q), which_window++ ))) { BYTE win_loc; StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), hOldShip ); win_loc = GET_GROUP_LOC (StarShipPtr); UnlockStarShip ( &GLOBAL (built_ship_q), hOldShip ); if (which_window <= win_loc) break; } StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), hStarShip ); SET_GROUP_LOC (StarShipPtr, which_window - 1); if (which_ship == SPATHI_SHIP && GET_GAME_STATE (FOUND_PLUTO_SPATHI) == 1) { OwnStarShip (StarShipPtr, GOOD_GUY, NAME_OFFSET + NUM_CAPTAINS_NAMES); } UnlockStarShip ( &GLOBAL (built_ship_q), hStarShip ); InsertQueue ( &GLOBAL (built_ship_q), hStarShip, hOldShip ); } SetSemaphore (GraphicsSem); DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); ClearSemaphore (GraphicsSem); return (i); } break; } } return (1); } return (0); }
static void DoBuy (RESPONSE_REF R) { COUNT credit; SIZE needed_credit; BYTE slot; DWORD capacity; credit = MAKE_WORD ( GET_GAME_STATE (MELNORME_CREDIT0), GET_GAME_STATE (MELNORME_CREDIT1) ); capacity = FUEL_RESERVE; slot = NUM_MODULE_SLOTS - 1; do { if (GLOBAL_SIS (ModuleSlots[slot]) == FUEL_TANK || GLOBAL_SIS (ModuleSlots[slot]) == HIGHEFF_FUELSYS) { COUNT volume; volume = GLOBAL_SIS (ModuleSlots[slot]) == FUEL_TANK ? FUEL_TANK_CAPACITY : HEFUEL_TANK_CAPACITY; capacity += volume; } } while (slot--); if (credit == 0) { AskedToBuy = TRUE; NPCPhrase (NEED_CREDIT); NatureOfConversation (R); } else if (PLAYER_SAID (R, buy_fuel) || PLAYER_SAID (R, buy_1_fuel) || PLAYER_SAID (R, buy_5_fuel) || PLAYER_SAID (R, buy_10_fuel) || PLAYER_SAID (R, buy_25_fuel) || PLAYER_SAID (R, fill_me_up)) { needed_credit = 0; if (PLAYER_SAID (R, buy_1_fuel)) needed_credit = 1; else if (PLAYER_SAID (R, buy_5_fuel)) needed_credit = 5; else if (PLAYER_SAID (R, buy_10_fuel)) needed_credit = 10; else if (PLAYER_SAID (R, buy_25_fuel)) needed_credit = 25; else if (PLAYER_SAID (R, fill_me_up)) needed_credit = (capacity - GLOBAL_SIS (FuelOnBoard) + FUEL_TANK_SCALE - 1) / FUEL_TANK_SCALE; if (needed_credit == 0) { if (!GET_GAME_STATE (MELNORME_FUEL_PROCEDURE)) { NPCPhrase (BUY_FUEL_INTRO); SET_GAME_STATE (MELNORME_FUEL_PROCEDURE, 1); } } else { if (GLOBAL_SIS (FuelOnBoard) / FUEL_TANK_SCALE + needed_credit > capacity / FUEL_TANK_SCALE) { NPCPhrase (NO_ROOM_FOR_FUEL); goto TryFuelAgain; } if ((int)(needed_credit * (BIO_CREDIT_VALUE / 2)) <= (int)credit) { DWORD f; NPCPhrase (GOT_FUEL); f = (DWORD)needed_credit * FUEL_TANK_SCALE; LockMutex (GraphicsLock); while (f > 0x3FFFL) { DeltaSISGauges (0, 0x3FFF, 0); f -= 0x3FFF; } DeltaSISGauges (0, (SIZE)f, 0); UnlockMutex (GraphicsLock); } needed_credit *= (BIO_CREDIT_VALUE / 2); } if (needed_credit) { DeltaCredit (-needed_credit); if (GLOBAL_SIS (FuelOnBoard) >= capacity) goto BuyBuyBuy; } TryFuelAgain: NPCPhrase (HOW_MUCH_FUEL); Response (buy_1_fuel, DoBuy); Response (buy_5_fuel, DoBuy); Response (buy_10_fuel, DoBuy); Response (buy_25_fuel, DoBuy); Response (fill_me_up, DoBuy); Response (done_buying_fuel, DoBuy); } else if (PLAYER_SAID (R, buy_technology) || PLAYER_SAID (R, buy_new_tech)) { BYTE stack; needed_credit = 0; if (PLAYER_SAID (R, buy_technology)) { if (!GET_GAME_STATE (MELNORME_TECH_PROCEDURE)) { NPCPhrase (BUY_NEW_TECH_INTRO); SET_GAME_STATE (MELNORME_TECH_PROCEDURE, 1); } stack = 0; } else { RESPONSE_REF pStr; stack = GET_GAME_STATE (MELNORME_TECH_STACK); switch (stack) { case 0: pStr = OK_BUY_NEW_TECH_1; needed_credit = 75 * BIO_CREDIT_VALUE; break; case 1: pStr = OK_BUY_NEW_TECH_2; needed_credit = 75 * BIO_CREDIT_VALUE; break; case 2: pStr = OK_BUY_NEW_TECH_3; needed_credit = 75 * BIO_CREDIT_VALUE; break; case 3: pStr = OK_BUY_NEW_TECH_4; needed_credit = 75 * BIO_CREDIT_VALUE; break; case 4: pStr = OK_BUY_NEW_TECH_5; needed_credit = 75 * BIO_CREDIT_VALUE; break; case 5: pStr = OK_BUY_NEW_TECH_6; needed_credit = 75 * BIO_CREDIT_VALUE; break; case 6: pStr = OK_BUY_NEW_TECH_7; needed_credit = 75 * BIO_CREDIT_VALUE; break; case 7: pStr = OK_BUY_NEW_TECH_8; needed_credit = 75 * BIO_CREDIT_VALUE; break; case 8: pStr = OK_BUY_NEW_TECH_9; needed_credit = 75 * BIO_CREDIT_VALUE; break; case 9: pStr = OK_BUY_NEW_TECH_10; needed_credit = 75 * BIO_CREDIT_VALUE; break; case 10: pStr = OK_BUY_NEW_TECH_11; needed_credit = 75 * BIO_CREDIT_VALUE; break; case 11: pStr = OK_BUY_NEW_TECH_12; needed_credit = 75 * BIO_CREDIT_VALUE; break; case 12: pStr = OK_BUY_NEW_TECH_13; needed_credit = 75 * BIO_CREDIT_VALUE; break; } if ((int)needed_credit > (int)credit) { DeltaCredit (-needed_credit); goto BuyBuyBuy; } else { ++stack; NPCPhrase (pStr); DeltaCredit (-needed_credit); } } switch (stack) { case 0: if (GLOBAL (ModuleCost[BLASTER_WEAPON]) == 0) { NPCPhrase (NEW_TECH_1); break; } ++stack; case 1: GLOBAL (ModuleCost[BLASTER_WEAPON]) = 4000 / MODULE_COST_SCALE; if (!GET_GAME_STATE (IMPROVED_LANDER_SPEED)) { NPCPhrase (NEW_TECH_2); break; } ++stack; case 2: SET_GAME_STATE (IMPROVED_LANDER_SPEED, 1); if (GLOBAL (ModuleCost[ANTIMISSILE_DEFENSE]) == 0) { NPCPhrase (NEW_TECH_3); break; } ++stack; case 3: GLOBAL (ModuleCost[ANTIMISSILE_DEFENSE]) = 4000 / MODULE_COST_SCALE; if (!(GET_GAME_STATE (LANDER_SHIELDS) & (1 << BIOLOGICAL_DISASTER))) { NPCPhrase (NEW_TECH_4); break; } ++stack; case 4: credit = GET_GAME_STATE (LANDER_SHIELDS) | (1 << BIOLOGICAL_DISASTER); SET_GAME_STATE (LANDER_SHIELDS, credit); if (!GET_GAME_STATE (IMPROVED_LANDER_CARGO)) { NPCPhrase (NEW_TECH_5); break; } ++stack; case 5: SET_GAME_STATE (IMPROVED_LANDER_CARGO, 1); if (GLOBAL (ModuleCost[HIGHEFF_FUELSYS]) == 0) { NPCPhrase (NEW_TECH_6); break; } ++stack; case 6: GLOBAL (ModuleCost[HIGHEFF_FUELSYS]) = 1000 / MODULE_COST_SCALE; if (!GET_GAME_STATE (IMPROVED_LANDER_SHOT)) { NPCPhrase (NEW_TECH_7); break; } ++stack; case 7: SET_GAME_STATE (IMPROVED_LANDER_SHOT, 1); if (!(GET_GAME_STATE (LANDER_SHIELDS) & (1 << EARTHQUAKE_DISASTER))) { NPCPhrase (NEW_TECH_8); break; } ++stack; case 8: credit = GET_GAME_STATE (LANDER_SHIELDS) | (1 << EARTHQUAKE_DISASTER); SET_GAME_STATE (LANDER_SHIELDS, credit); if (GLOBAL (ModuleCost[TRACKING_SYSTEM]) == 0) { NPCPhrase (NEW_TECH_9); break; } ++stack; case 9: GLOBAL (ModuleCost[TRACKING_SYSTEM]) = 5000 / MODULE_COST_SCALE; if (!(GET_GAME_STATE (LANDER_SHIELDS) & (1 << LIGHTNING_DISASTER))) { NPCPhrase (NEW_TECH_10); break; } ++stack; case 10: credit = GET_GAME_STATE (LANDER_SHIELDS) | (1 << LIGHTNING_DISASTER); SET_GAME_STATE (LANDER_SHIELDS, credit); if (!(GET_GAME_STATE (LANDER_SHIELDS) & (1 << LAVASPOT_DISASTER))) { NPCPhrase (NEW_TECH_11); break; } ++stack; case 11: credit = GET_GAME_STATE (LANDER_SHIELDS) | (1 << LAVASPOT_DISASTER); SET_GAME_STATE (LANDER_SHIELDS, credit); if (GLOBAL (ModuleCost[CANNON_WEAPON]) == 0) { NPCPhrase (NEW_TECH_12); break; } ++stack; case 12: GLOBAL (ModuleCost[CANNON_WEAPON]) = 6000 / MODULE_COST_SCALE; if (GLOBAL (ModuleCost[SHIVA_FURNACE]) == 0) { NPCPhrase (NEW_TECH_13); break; } ++stack; case 13: GLOBAL (ModuleCost[SHIVA_FURNACE]) = 4000 / MODULE_COST_SCALE; NPCPhrase (NEW_TECH_ALL_GONE); SET_GAME_STATE (MELNORME_TECH_STACK, stack); goto BuyBuyBuy; } SET_GAME_STATE (MELNORME_TECH_STACK, stack); Response (buy_new_tech, DoBuy); Response (no_buy_new_tech, DoBuy); } else if (PLAYER_SAID (R, buy_info) || PLAYER_SAID (R, buy_current_events) || PLAYER_SAID (R, buy_alien_races) || PLAYER_SAID (R, buy_history)) { needed_credit = 0; if (PLAYER_SAID (R, buy_info)) { if (GET_GAME_STATE (MELNORME_INFO_PROCEDURE)) NPCPhrase (OK_BUY_INFO); else { NPCPhrase (BUY_INFO_INTRO); SET_GAME_STATE (MELNORME_INFO_PROCEDURE, 1); } } else { #define INFO_COST 75 needed_credit = INFO_COST; if ((int)credit >= (int)needed_credit) { if (PLAYER_SAID (R, buy_current_events)) CurrentEvents (); else if (PLAYER_SAID (R, buy_alien_races)) AlienRaces (); else /* if (R == buy_history) */ History (); } DeltaCredit (-needed_credit); if (GET_GAME_STATE (MELNORME_EVENTS_INFO_STACK) < NUM_EVENT_ITEMS || GET_GAME_STATE (MELNORME_ALIEN_INFO_STACK) < NUM_ALIEN_RACE_ITEMS || GET_GAME_STATE (MELNORME_HISTORY_INFO_STACK) < NUM_HISTORY_ITEMS) { } else { NPCPhrase (INFO_ALL_GONE); goto BuyBuyBuy; } } if (GET_GAME_STATE (MELNORME_EVENTS_INFO_STACK) < NUM_EVENT_ITEMS) Response (buy_current_events, DoBuy); if (GET_GAME_STATE (MELNORME_ALIEN_INFO_STACK) < NUM_ALIEN_RACE_ITEMS) Response (buy_alien_races, DoBuy); if (GET_GAME_STATE (MELNORME_HISTORY_INFO_STACK) < NUM_HISTORY_ITEMS) Response (buy_history, DoBuy); Response (done_buying_info, DoBuy); } else { if (PLAYER_SAID (R, done_buying_fuel)) NPCPhrase (OK_DONE_BUYING_FUEL); else if (PLAYER_SAID (R, no_buy_new_tech)) NPCPhrase (OK_NO_BUY_NEW_TECH); else if (PLAYER_SAID (R, done_buying_info)) NPCPhrase (OK_DONE_BUYING_INFO); else NPCPhrase (WHAT_TO_BUY); BuyBuyBuy: if (GLOBAL_SIS (FuelOnBoard) < capacity) Response (buy_fuel, DoBuy); if (GET_GAME_STATE (MELNORME_TECH_STACK) < NUM_TECH_ITEMS) Response (buy_technology, DoBuy); if (GET_GAME_STATE (MELNORME_ALIEN_INFO_STACK) < NUM_ALIEN_RACE_ITEMS || GET_GAME_STATE (MELNORME_HISTORY_INFO_STACK) < NUM_HISTORY_ITEMS || GET_GAME_STATE (MELNORME_EVENTS_INFO_STACK) < NUM_EVENT_ITEMS) Response (buy_info, DoBuy); Response (done_buying, NatureOfConversation); Response (be_leaving_now, ExitConversation); } }
static BOOLEAN StripShip (COUNT fuel_required) { BYTE i, which_module; SBYTE crew_pods; SET_GAME_STATE (MELNORME_RESCUE_REFUSED, 0); crew_pods = -(SBYTE)( (GLOBAL_SIS (CrewEnlisted) + CREW_POD_CAPACITY - 1) / CREW_POD_CAPACITY ); if (fuel_required == 0) { GlobData.SIS_state = SIS_copy; LockMutex (GraphicsLock); DeltaSISGauges (UNDEFINED_DELTA, rescue_fuel, UNDEFINED_DELTA); UnlockMutex (GraphicsLock); } else if (fuel_required == (COUNT)~0) { GLOBAL_SIS (NumLanders) = 0; for (i = 0; i < NUM_DRIVE_SLOTS; ++i) GLOBAL_SIS (DriveSlots[i]) = EMPTY_SLOT + 0; for (i = 0; i < NUM_JET_SLOTS; ++i) GLOBAL_SIS (JetSlots[i]) = EMPTY_SLOT + 1; if (GLOBAL_SIS (FuelOnBoard) > FUEL_RESERVE) GLOBAL_SIS (FuelOnBoard) = FUEL_RESERVE; GLOBAL_SIS (TotalBioMass) = 0; GLOBAL_SIS (TotalElementMass) = 0; for (i = 0; i < NUM_ELEMENT_CATEGORIES; ++i) GLOBAL_SIS (ElementAmounts[i]) = 0; for (i = 0; i < NUM_MODULE_SLOTS; ++i) { which_module = GLOBAL_SIS (ModuleSlots[i]); if (which_module < BOMB_MODULE_0 && (which_module != CREW_POD || ++crew_pods > 0)) GLOBAL_SIS (ModuleSlots[i]) = EMPTY_SLOT + 2; } LockMutex (GraphicsLock); DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); UnlockMutex (GraphicsLock); } else if (fuel_required) { SBYTE bays; BYTE num_searches, beg_mod, end_mod; COUNT worth, total; BYTE module_count[BOMB_MODULE_0]; BYTE slot; DWORD capacity; SIS_copy = GlobData.SIS_state; for (i = PLANET_LANDER; i < BOMB_MODULE_0; ++i) module_count[i] = 0; capacity = FUEL_RESERVE; slot = NUM_MODULE_SLOTS - 1; do { if (SIS_copy.ModuleSlots[slot] == FUEL_TANK || SIS_copy.ModuleSlots[slot] == HIGHEFF_FUELSYS) { COUNT volume; volume = SIS_copy.ModuleSlots[slot] == FUEL_TANK ? FUEL_TANK_CAPACITY : HEFUEL_TANK_CAPACITY; capacity += volume; } } while (slot--); if (fuel_required > capacity) fuel_required = capacity; bays = -(SBYTE)( (SIS_copy.TotalElementMass + STORAGE_BAY_CAPACITY - 1) / STORAGE_BAY_CAPACITY ); for (i = 0; i < NUM_MODULE_SLOTS; ++i) { which_module = SIS_copy.ModuleSlots[i]; if (which_module == CREW_POD) ++crew_pods; else if (which_module == STORAGE_BAY) ++bays; } worth = fuel_required / FUEL_TANK_SCALE; total = 0; num_searches = 0; beg_mod = end_mod = (BYTE)~0; while (total < worth && ShipWorth () && ++num_searches) { DWORD rand_val; rand_val = TFB_Random (); switch (which_module = LOBYTE (LOWORD (rand_val)) % (CREW_POD + 1)) { case PLANET_LANDER: if (SIS_copy.NumLanders == 0) continue; --SIS_copy.NumLanders; break; case FUSION_THRUSTER: for (i = 0; i < NUM_DRIVE_SLOTS; ++i) { if (SIS_copy.DriveSlots[i] < EMPTY_SLOT) break; } if (i == NUM_DRIVE_SLOTS) continue; SIS_copy.DriveSlots[i] = EMPTY_SLOT + 0; break; case TURNING_JETS: for (i = 0; i < NUM_JET_SLOTS; ++i) { if (SIS_copy.JetSlots[i] < EMPTY_SLOT) break; } if (i == NUM_JET_SLOTS) continue; SIS_copy.JetSlots[i] = EMPTY_SLOT + 1; break; case CREW_POD: i = HIBYTE (LOWORD (rand_val)) % NUM_MODULE_SLOTS; which_module = SIS_copy.ModuleSlots[i]; if (which_module >= BOMB_MODULE_0 || which_module == FUEL_TANK || which_module == HIGHEFF_FUELSYS || (which_module == STORAGE_BAY && module_count[STORAGE_BAY] >= bays) || (which_module == CREW_POD && module_count[CREW_POD] >= crew_pods)) continue; SIS_copy.ModuleSlots[i] = EMPTY_SLOT + 2; break; } if (beg_mod == (BYTE)~0) beg_mod = end_mod = which_module; else if (which_module > end_mod) end_mod = which_module; ++module_count[which_module]; total += GLOBAL (ModuleCost[which_module]); } if (total == 0) { NPCPhrase (CHARITY); LockMutex (GraphicsLock); DeltaSISGauges (0, fuel_required, 0); UnlockMutex (GraphicsLock); return (FALSE); } else { NPCPhrase (RESCUE_OFFER); rescue_fuel = fuel_required; if (rescue_fuel == capacity) NPCPhrase (RESCUE_TANKS); else NPCPhrase (RESCUE_HOME); for (i = PLANET_LANDER; i < BOMB_MODULE_0; ++i) { if (module_count[i]) { RESPONSE_REF pStr; switch (i) { case PLANET_LANDER: pStr = LANDERS; break; case FUSION_THRUSTER: pStr = THRUSTERS; break; case TURNING_JETS: pStr = JETS; break; case CREW_POD: pStr = PODS; break; case STORAGE_BAY: pStr = BAYS; break; case DYNAMO_UNIT: pStr = DYNAMOS; break; case SHIVA_FURNACE: pStr = FURNACES; break; case GUN_WEAPON: pStr = GUNS; break; case BLASTER_WEAPON: pStr = BLASTERS; break; case CANNON_WEAPON: pStr = CANNONS; break; case TRACKING_SYSTEM: pStr = TRACKERS; break; case ANTIMISSILE_DEFENSE: pStr = DEFENSES; break; } if (i == end_mod && i != beg_mod) NPCPhrase (END_LIST_WITH_AND); NPCPhrase (ENUMERATE_ONE + (module_count[i] - 1)); NPCPhrase (pStr); } } } } return (TRUE); }
/* * What this function does depends on the value of the 'state' argument: * SPHERE_TRACKING: * The sphere of influence for the race for 'which_ship' will be shown * on the starmap in the future. * The value returned is 'which_ship', unless the type of ship is only * available in SuperMelee, in which case 0 is returned. * SPHERE_KNOWN: * The size of the fleet of the race of 'which_ship' when the starmap was * last checked is returned. * ESCORT_WORTH: * The total value of all the ships escorting the SIS is returned. * 'which_ship' is ignored. * ESCORTING_FLAGSHIP: * Test if a ship of type 'which_ship' is among the escorts of the SIS * 0 is returned if false, 1 if true. * FEASIBILITY_STUDY: * Test if the SIS can have an escort of type 'which_ship'. * 0 is returned if 'which_ship' is not available. * Otherwise, the number of ships that can be added is returned. * CHECK_ALLIANCE: * Test the alliance status of the race of 'which_ship'. * Either GOOD_GUY (allied) or BAD_GUY (not allied) is returned. * 0: * Ally with the race of 'which_ship'. This makes their ship available * for building in the shipyard. * -1: * End an alliance with the race of 'which_ship'. This ends the possibility * of building their ships in the shipyard. For the Orz also the ships the * player has with him will disappear. * any other positive number: * Give the player this much ships of type 'which_ship'. If it's */ COUNT ActivateStarShip (COUNT which_ship, SIZE state) { HSTARSHIP hStarShip, hNextShip; hStarShip = GetStarShipFromIndex ( &GLOBAL (avail_race_q), which_ship ); if (hStarShip) { switch (state) { case SPHERE_TRACKING: case SPHERE_KNOWN: { EXTENDED_SHIP_FRAGMENTPTR StarShipPtr; StarShipPtr = (EXTENDED_SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (avail_race_q), hStarShip); if (state == SPHERE_KNOWN) which_ship = StarShipPtr->ShipInfo.known_strength; else if (StarShipPtr->ShipInfo.actual_strength == 0) { if (!(StarShipPtr->ShipInfo.ship_flags & (GOOD_GUY | BAD_GUY))) which_ship = 0; } else if (StarShipPtr->ShipInfo.known_strength == 0 && StarShipPtr->ShipInfo.actual_strength != (COUNT)~0) { StarShipPtr->ShipInfo.known_strength = 1; StarShipPtr->ShipInfo.known_loc = StarShipPtr->ShipInfo.loc; } UnlockStarShip (&GLOBAL (avail_race_q), hStarShip); return (which_ship); } case ESCORT_WORTH: { COUNT ShipCost[] = { RACE_SHIP_COST }; COUNT total = 0; for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); hStarShip; hStarShip = hNextShip) { SHIP_FRAGMENTPTR StarShipPtr; StarShipPtr = (SHIP_FRAGMENTPTR) LockStarShip ( &GLOBAL (built_ship_q), hStarShip); hNextShip = _GetSuccLink (StarShipPtr); total += ShipCost[GET_RACE_ID (StarShipPtr)]; UnlockStarShip (&GLOBAL (built_ship_q), hStarShip); } return total; } case ESCORTING_FLAGSHIP: { for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); hStarShip; hStarShip = hNextShip) { BYTE ship_type; SHIP_FRAGMENTPTR StarShipPtr; StarShipPtr = (SHIP_FRAGMENTPTR) LockStarShip ( &GLOBAL (built_ship_q), hStarShip); hNextShip = _GetSuccLink (StarShipPtr); ship_type = GET_RACE_ID (StarShipPtr); UnlockStarShip (&GLOBAL (built_ship_q), hStarShip); if ((COUNT) ship_type == which_ship) return 1; } return 0; } case FEASIBILITY_STUDY: return (MAX_BUILT_SHIPS - CountLinks (&GLOBAL (built_ship_q))); default: { SHIP_FRAGMENTPTR StarShipPtr; if (state <= 0) { StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (avail_race_q), hStarShip ); if (state == CHECK_ALLIANCE) { state = StarShipPtr->ShipInfo.ship_flags & (GOOD_GUY | BAD_GUY); UnlockStarShip (&GLOBAL (avail_race_q), hStarShip); return ((COUNT)state); } else if (StarShipPtr->ShipInfo.ship_flags & (GOOD_GUY | BAD_GUY)) { StarShipPtr->ShipInfo.ship_flags &= ~(GOOD_GUY | BAD_GUY); if (state == 0) StarShipPtr->ShipInfo.ship_flags |= GOOD_GUY; else { StarShipPtr->ShipInfo.ship_flags |= BAD_GUY; if (which_ship == ORZ_SHIP) { BOOLEAN ShipRemoved; ShipRemoved = FALSE; for (hStarShip = GetHeadLink ( &GLOBAL (built_ship_q)); hStarShip; hStarShip = hNextShip) { BOOLEAN RemoveShip; SHIP_FRAGMENTPTR StarShipPtr2; StarShipPtr2 = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), hStarShip); hNextShip = _GetSuccLink (StarShipPtr2); RemoveShip = (BOOLEAN) ( GET_RACE_ID (StarShipPtr2) == ORZ_SHIP); UnlockStarShip (&GLOBAL (built_ship_q), hStarShip); if (RemoveShip) { ShipRemoved = TRUE; RemoveQueue (&GLOBAL (built_ship_q), hStarShip); FreeStarShip (&GLOBAL (built_ship_q), hStarShip); } } if (ShipRemoved) { LockMutex (GraphicsLock); DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); UnlockMutex (GraphicsLock); } } } } UnlockStarShip (&GLOBAL (avail_race_q), hStarShip); } else { /* 'state > 0', add ships to the escorts */ BYTE which_window; COUNT i; which_window = 0; for (i = 0; i < (COUNT)state; i++) { HSTARSHIP hOldShip; BYTE crewLevel; if (which_ship == SPATHI_SHIP && GET_GAME_STATE (FOUND_PLUTO_SPATHI) == 1) crewLevel = 1; // Only Fwiffo is on board. else crewLevel = 0; // Crewed to the max hStarShip = CloneShipFragment((COUNT) which_ship, &GLOBAL (built_ship_q), crewLevel); if (!hStarShip) break; RemoveQueue (&GLOBAL (built_ship_q), hStarShip); while ((hOldShip = GetStarShipFromIndex ( &GLOBAL (built_ship_q), which_window++))) { BYTE win_loc; StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), hOldShip); win_loc = GET_GROUP_LOC (StarShipPtr); UnlockStarShip (&GLOBAL (built_ship_q), hOldShip); if (which_window <= win_loc) break; } StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), hStarShip); SET_GROUP_LOC (StarShipPtr, which_window - 1); if (which_ship == SPATHI_SHIP && GET_GAME_STATE (FOUND_PLUTO_SPATHI) == 1) { OwnStarShip (StarShipPtr, GOOD_GUY, NAME_OFFSET + NUM_CAPTAINS_NAMES); } UnlockStarShip (&GLOBAL (built_ship_q), hStarShip); InsertQueue (&GLOBAL (built_ship_q), hStarShip, hOldShip); } LockMutex (GraphicsLock); DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); UnlockMutex (GraphicsLock); return (i); } break; } } return 1; } return 0; }
static void AskAfterRadios (RESPONSE_REF R) { if (PLAYER_SAID (R, i_lost_my_lander)) { NPCPhrase (HERE_IS_A_NEW_LANDER); ++GLOBAL_SIS (NumLanders); LockMutex (GraphicsLock); DrawLanders (); DeltaSISGauges (4, 0, 0); UnlockMutex (GraphicsLock); SET_GAME_STATE (LANDERS_LOST, 1); } else if (PLAYER_SAID (R, i_lost_another_lander)) { NPCPhrase (HERE_IS_ANOTHER_LANDER); ++GLOBAL_SIS (NumLanders); LockMutex (GraphicsLock); DrawLanders (); DeltaSISGauges (4, 0, 0); UnlockMutex (GraphicsLock); } else if (PLAYER_SAID (R, need_fuel_mercury) || PLAYER_SAID (R, need_fuel_luna)) { NPCPhrase (GIVE_FUEL); LockMutex (GraphicsLock); DeltaSISGauges (0, 5 * FUEL_TANK_SCALE, 0); UnlockMutex (GraphicsLock); SET_GAME_STATE (GIVEN_FUEL_BEFORE, 1); } else if (PLAYER_SAID (R, need_fuel_again)) { NPCPhrase (GIVE_FUEL_AGAIN); LockMutex (GraphicsLock); DeltaSISGauges (0, 5 * FUEL_TANK_SCALE, 0); UnlockMutex (GraphicsLock); } else if (PLAYER_SAID (R, where_get_radios)) { NPCPhrase (RADIOS_ON_MERCURY); DISABLE_PHRASE (where_get_radios); } { if (GLOBAL_SIS (NumLanders) == 0 && GET_GAME_STATE (CHMMR_BOMB_STATE) < 2) { if (GET_GAME_STATE (LANDERS_LOST)) Response (i_lost_another_lander, AskAfterRadios); else Response (i_lost_my_lander, AskAfterRadios); } if (GLOBAL_SIS (FuelOnBoard) < 2 * FUEL_TANK_SCALE) { if (GET_GAME_STATE (GIVEN_FUEL_BEFORE)) Response (need_fuel_again, AskAfterRadios); else Response (need_fuel_mercury, AskAfterRadios); } Response (well_go_get_them_now, ByeBye); if (PHRASE_ENABLED (where_get_radios)) { Response (where_get_radios, AskAfterRadios); } } }
static void Buy (RESPONSE_REF R) { if (PLAYER_SAID (R, want_to_buy) || PLAYER_SAID (R, im_ready_to_buy)) { NPCPhrase (READY_TO_SELL); if (!GET_GAME_STATE (ROSY_SPHERE)) NPCPhrase (HAVE_SPHERE); if (!GET_GAME_STATE (ARTIFACT_2_ON_SHIP)) NPCPhrase (HAVE_ART_1); if (!GET_GAME_STATE (ARTIFACT_3_ON_SHIP)) NPCPhrase (HAVE_ART_2); NPCPhrase (SHIPS_AND_FUEL); SET_GAME_STATE (KNOW_DRUUGE_SLAVERS, 3); } else if (PLAYER_SAID (R, buy_druuge_ship)) { #define SHIP_CREW_COST 100 if (GLOBAL_SIS (CrewEnlisted) < SHIP_CREW_COST) NPCPhrase (NOT_ENOUGH_CREW); else if (EscortFeasibilityStudy (DRUUGE_SHIP) == 0) NPCPhrase (NOT_ENOUGH_ROOM); else { DeltaSISGauges (-SHIP_CREW_COST, 0, 0); SlaveryCount += SHIP_CREW_COST; AddEscortShips (DRUUGE_SHIP, 1); NPCPhrase (BOUGHT_SHIP); } } #define ARTIFACT_CREW_COST 100 else if (PLAYER_SAID (R, buy_rosy_sphere)) { if (GLOBAL_SIS (CrewEnlisted) < ARTIFACT_CREW_COST) NPCPhrase (NOT_ENOUGH_CREW); else { DeltaSISGauges (-ARTIFACT_CREW_COST, 0, 0); SlaveryCount += ARTIFACT_CREW_COST; SET_GAME_STATE (ROSY_SPHERE_ON_SHIP, 1); SET_GAME_STATE (ROSY_SPHERE, 1); NPCPhrase (BOUGHT_SPHERE); } } else if (PLAYER_SAID (R, buy_art_1)) { if (GLOBAL_SIS (CrewEnlisted) < ARTIFACT_CREW_COST) NPCPhrase (NOT_ENOUGH_CREW); else { DeltaSISGauges (-ARTIFACT_CREW_COST, 0, 0); SlaveryCount += ARTIFACT_CREW_COST; SET_GAME_STATE (ARTIFACT_2_ON_SHIP, 1); NPCPhrase (BOUGHT_ART_1); } } else if (PLAYER_SAID (R, buy_art_2)) { if (GLOBAL_SIS (CrewEnlisted) < ARTIFACT_CREW_COST) NPCPhrase (NOT_ENOUGH_CREW); else { DeltaSISGauges (-ARTIFACT_CREW_COST, 0, 0); SlaveryCount += ARTIFACT_CREW_COST; SET_GAME_STATE (ARTIFACT_3_ON_SHIP, 1); NPCPhrase (BOUGHT_ART_2); } } else if (PLAYER_SAID (R, buy_fuel)) { #define FUEL_CREW_COST 10 if (GLOBAL_SIS (CrewEnlisted) < FUEL_CREW_COST) NPCPhrase (NOT_ENOUGH_CREW); else { DeltaSISGauges (-FUEL_CREW_COST, FUEL_CREW_COST * FUEL_TANK_SCALE, 0); SlaveryCount += FUEL_CREW_COST; NPCPhrase (BOUGHT_FUEL); } } Response (buy_druuge_ship, Buy); if (!GET_GAME_STATE (ROSY_SPHERE)) Response (buy_rosy_sphere, Buy); if (!GET_GAME_STATE (ARTIFACT_2_ON_SHIP)) Response (buy_art_1, Buy); if (!GET_GAME_STATE (ARTIFACT_3_ON_SHIP)) Response (buy_art_2, Buy); Response (buy_fuel, Buy); Response (done_buying, TradeWorld); }
static void TellMoonBase (RESPONSE_REF R) { if (R == 0) { NPCPhrase (DEALT_WITH_BASE_YET); } else if (PLAYER_SAID (R, i_lost_my_lander)) { NPCPhrase (HERE_IS_A_NEW_LANDER); ++GLOBAL_SIS (NumLanders); LockMutex (GraphicsLock); DrawLanders (); DeltaSISGauges (4, 0, 0); UnlockMutex (GraphicsLock); SET_GAME_STATE (LANDERS_LOST, 1); } else if (PLAYER_SAID (R, i_lost_another_lander)) { NPCPhrase (HERE_IS_ANOTHER_LANDER); ++GLOBAL_SIS (NumLanders); LockMutex (GraphicsLock); DrawLanders (); DeltaSISGauges (4, 0, 0); UnlockMutex (GraphicsLock); } else if (PLAYER_SAID (R, need_fuel_mercury) || PLAYER_SAID (R, need_fuel_luna)) { NPCPhrase (GIVE_FUEL); LockMutex (GraphicsLock); DeltaSISGauges (0, 5 * FUEL_TANK_SCALE, 0); UnlockMutex (GraphicsLock); SET_GAME_STATE (GIVEN_FUEL_BEFORE, 1); } else if (PLAYER_SAID (R, need_fuel_again)) { NPCPhrase (GIVE_FUEL_AGAIN); LockMutex (GraphicsLock); DeltaSISGauges (0, 5 * FUEL_TANK_SCALE, 0); UnlockMutex (GraphicsLock); } else if (PLAYER_SAID (R, we_are_here_to_help)) { NPCPhrase (BASE_ON_MOON); } else if (GET_GAME_STATE (STARBASE_YACK_STACK1) == 0) { NPCPhrase (ABOUT_BASE); SET_GAME_STATE (STARBASE_YACK_STACK1, 1); } else { NPCPhrase (ABOUT_BASE_AGAIN); } if (GLOBAL_SIS (NumLanders) == 0 && GET_GAME_STATE (CHMMR_BOMB_STATE) < 2) { if (GET_GAME_STATE (LANDERS_LOST)) Response (i_lost_another_lander, TellMoonBase); else Response (i_lost_my_lander, TellMoonBase); } if (GLOBAL_SIS (FuelOnBoard) < 2 * FUEL_TANK_SCALE) { if (GET_GAME_STATE (GIVEN_FUEL_BEFORE)) Response (need_fuel_again, TellMoonBase); else Response (need_fuel_luna, TellMoonBase); } if (GET_GAME_STATE (WILL_DESTROY_BASE) == 0) Response (we_will_take_care_of_base, ByeBye); else Response (take_care_of_base_again, ByeBye); if (GET_GAME_STATE (STARBASE_YACK_STACK1) == 0) Response (tell_me_about_base, TellMoonBase); else Response (tell_me_again, TellMoonBase); }
static BOOLEAN StripShip (COUNT fuel_required) { BYTE i, which_module; SBYTE crew_pods; SET_GAME_STATE (MELNORME_RESCUE_REFUSED, 0); crew_pods = -(SBYTE)( (GLOBAL_SIS (CrewEnlisted) + CREW_POD_CAPACITY - 1) / CREW_POD_CAPACITY ); if (fuel_required == 0) { GlobData.SIS_state = SIS_copy; DeltaSISGauges (UNDEFINED_DELTA, rescue_fuel, UNDEFINED_DELTA); } else if (fuel_required == (COUNT)~0) { GLOBAL_SIS (NumLanders) = 0; for (i = 0; i < NUM_DRIVE_SLOTS; ++i) GLOBAL_SIS (DriveSlots[i]) = EMPTY_SLOT + 0; for (i = 0; i < NUM_JET_SLOTS; ++i) GLOBAL_SIS (JetSlots[i]) = EMPTY_SLOT + 1; if (GLOBAL_SIS (FuelOnBoard) > FUEL_RESERVE) GLOBAL_SIS (FuelOnBoard) = FUEL_RESERVE; GLOBAL_SIS (TotalBioMass) = 0; GLOBAL_SIS (TotalElementMass) = 0; for (i = 0; i < NUM_ELEMENT_CATEGORIES; ++i) GLOBAL_SIS (ElementAmounts[i]) = 0; for (i = 0; i < NUM_MODULE_SLOTS; ++i) { which_module = GLOBAL_SIS (ModuleSlots[i]); if (which_module < BOMB_MODULE_0 && (which_module != CREW_POD || ++crew_pods > 0)) GLOBAL_SIS (ModuleSlots[i]) = EMPTY_SLOT + 2; } DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); } else if (fuel_required) { SBYTE bays; BYTE num_searches, beg_mod, end_mod; COUNT worth, total; BYTE module_count[BOMB_MODULE_0]; BYTE slot; DWORD capacity; RandomContext *rc; // Bug #567 // In order to offer the same deal each time if it is refused, we seed // the random number generator with our location, thus making the deal // a repeatable pseudo-random function of where we got stuck and what, // exactly, is on our ship. rc = RandomContext_New(); RandomContext_SeedRandom (rc, getStripRandomSeed ()); SIS_copy = GlobData.SIS_state; for (i = PLANET_LANDER; i < BOMB_MODULE_0; ++i) module_count[i] = 0; capacity = FUEL_RESERVE; slot = NUM_MODULE_SLOTS - 1; do { if (SIS_copy.ModuleSlots[slot] == FUEL_TANK || SIS_copy.ModuleSlots[slot] == HIGHEFF_FUELSYS) { COUNT volume; volume = SIS_copy.ModuleSlots[slot] == FUEL_TANK ? FUEL_TANK_CAPACITY : HEFUEL_TANK_CAPACITY; capacity += volume; } } while (slot--); if (fuel_required > capacity) fuel_required = capacity; bays = -(SBYTE)( (SIS_copy.TotalElementMass + STORAGE_BAY_CAPACITY - 1) / STORAGE_BAY_CAPACITY ); for (i = 0; i < NUM_MODULE_SLOTS; ++i) { which_module = SIS_copy.ModuleSlots[i]; if (which_module == CREW_POD) ++crew_pods; else if (which_module == STORAGE_BAY) ++bays; } worth = fuel_required / FUEL_TANK_SCALE; total = 0; num_searches = 0; beg_mod = end_mod = (BYTE)~0; while (total < worth && ShipWorth () && ++num_searches) { DWORD rand_val; rand_val = RandomContext_Random (rc); switch (which_module = LOBYTE (LOWORD (rand_val)) % (CREW_POD + 1)) { case PLANET_LANDER: if (SIS_copy.NumLanders == 0) continue; --SIS_copy.NumLanders; break; case FUSION_THRUSTER: for (i = 0; i < NUM_DRIVE_SLOTS; ++i) { if (SIS_copy.DriveSlots[i] < EMPTY_SLOT) break; } if (i == NUM_DRIVE_SLOTS) continue; SIS_copy.DriveSlots[i] = EMPTY_SLOT + 0; break; case TURNING_JETS: for (i = 0; i < NUM_JET_SLOTS; ++i) { if (SIS_copy.JetSlots[i] < EMPTY_SLOT) break; } if (i == NUM_JET_SLOTS) continue; SIS_copy.JetSlots[i] = EMPTY_SLOT + 1; break; case CREW_POD: i = HIBYTE (LOWORD (rand_val)) % NUM_MODULE_SLOTS; which_module = SIS_copy.ModuleSlots[i]; if (which_module >= BOMB_MODULE_0 || which_module == FUEL_TANK || which_module == HIGHEFF_FUELSYS || (which_module == STORAGE_BAY && module_count[STORAGE_BAY] >= bays) || (which_module == CREW_POD && module_count[CREW_POD] >= crew_pods)) continue; SIS_copy.ModuleSlots[i] = EMPTY_SLOT + 2; break; } if (beg_mod == (BYTE)~0) beg_mod = end_mod = which_module; else if (which_module > end_mod) end_mod = which_module; ++module_count[which_module]; total += GLOBAL (ModuleCost[which_module]); } RandomContext_Delete (rc); if (total == 0) { NPCPhrase (CHARITY); DeltaSISGauges (0, fuel_required, 0); return (FALSE); } else { NPCPhrase (RESCUE_OFFER); rescue_fuel = fuel_required; if (rescue_fuel == capacity) NPCPhrase (RESCUE_TANKS); else NPCPhrase (RESCUE_HOME); for (i = PLANET_LANDER; i < BOMB_MODULE_0; ++i) { if (module_count[i]) { if (i == end_mod && i != beg_mod) NPCPhrase (END_LIST_WITH_AND); NPCPhrase (ENUMERATE_ONE + (module_count[i] - 1)); NPCPhrase (GetStripModuleRef (i)); } } } } return (TRUE); }