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); }
static void ExitConversation (RESPONSE_REF R) { if (PLAYER_SAID (R, no_trade_now)) NPCPhrase (OK_NO_TRADE_NOW_BYE); else if (PLAYER_SAID (R, youre_on)) { NPCPhrase (YOU_GIVE_US_NO_CHOICE); SET_GAME_STATE (MELNORME_ANGER, 1); SET_GAME_STATE (BATTLE_SEGUE, 1); } else if (PLAYER_SAID (R, so_we_can_attack)) { NPCPhrase (DECEITFUL_HUMAN); SET_GAME_STATE (MELNORME_ANGER, 2); SET_GAME_STATE (BATTLE_SEGUE, 1); } else if (PLAYER_SAID (R, bye_melnorme_slightly_angry)) NPCPhrase (MELNORME_SLIGHTLY_ANGRY_GOODBYE); else if (PLAYER_SAID (R, ok_strip_me)) { if (ShipWorth () < 4000 / MODULE_COST_SCALE) /* is ship worth stripping */ NPCPhrase (NOT_WORTH_STRIPPING); else { SET_GAME_STATE (MELNORME_ANGER, 0); StripShip ((COUNT)~0); NPCPhrase (FAIR_JUSTICE); } } else if (PLAYER_SAID (R, fight_some_more)) { NPCPhrase (OK_FIGHT_SOME_MORE); SET_GAME_STATE (MELNORME_ANGER, 3); SET_GAME_STATE (BATTLE_SEGUE, 1); } else if (PLAYER_SAID (R, bye_melnorme_pissed_off)) NPCPhrase (MELNORME_PISSED_OFF_GOODBYE); else if (PLAYER_SAID (R, well_if_thats_the_way_you_feel)) { NPCPhrase (WE_FIGHT_AGAIN); SET_GAME_STATE (BATTLE_SEGUE, 1); } else if (PLAYER_SAID (R, you_hate_us_so_we_go_away)) NPCPhrase (HATE_YOU_GOODBYE); else if (PLAYER_SAID (R, take_it)) { StripShip (0); NPCPhrase (HAPPY_TO_HAVE_RESCUED); } else if (PLAYER_SAID (R, leave_it)) { SET_GAME_STATE (MELNORME_RESCUE_REFUSED, 1); NPCPhrase (MAYBE_SEE_YOU_LATER); } else if (PLAYER_SAID (R, no_help)) { SET_GAME_STATE (MELNORME_RESCUE_REFUSED, 1); NPCPhrase (GOODBYE_AND_GOODLUCK); } else if (PLAYER_SAID (R, no_changed_mind)) { NPCPhrase (GOODBYE_AND_GOODLUCK_AGAIN); } else if (PLAYER_SAID (R, be_leaving_now) || PLAYER_SAID (R, goodbye)) { NPCPhrase (FRIENDLY_GOODBYE); } }
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); }