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 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); } }