From faba9ea713b8022f3b6328cec40b0ac288db5a6c Mon Sep 17 00:00:00 2001 From: Flugente Date: Thu, 19 Dec 2013 22:01:44 +0000 Subject: [PATCH] Helicopter features (by anv): - Waldo can now repair the helicopter for money - alternative fuel system - damage to helicopter can damage passengers Appropriate Data in GameDir r1897. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6695 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- GameSettings.cpp | 55 +++ GameSettings.h | 48 +++ GameVersion.h | 3 +- Laptop/history.cpp | 5 +- Laptop/history.h | 2 + MainMenuScreen.cpp | 2 + SaveLoadGame.cpp | 44 ++- Strategic/Game Event Hook.cpp | 6 + Strategic/Game Event Hook.h | 3 + Strategic/Game Events.cpp | 2 + Strategic/Hourly Update.cpp | 41 +++ Strategic/Map Screen Helicopter.cpp | 441 +++++++++++++++++++++---- Strategic/Map Screen Helicopter.h | 42 ++- Strategic/Map Screen Interface Map.cpp | 69 +++- Strategic/Map Screen Interface Map.h | 4 + Strategic/Quests.cpp | 40 +++ Strategic/Quests.h | 20 ++ Strategic/mapscreen.cpp | 32 +- Tactical/Civ Quotes.cpp | 5 +- Tactical/Dialogue Control.cpp | 25 ++ Tactical/Dialogue Control.h | 1 + Tactical/Interface Dialogue.cpp | 29 ++ Tactical/Morale.cpp | 8 +- Tactical/Vehicles.cpp | 27 ++ Tactical/Vehicles.h | 3 + Tactical/interface Dialogue.h | 4 + TacticalAI/NPC.cpp | 27 +- Utils/ExportStrings.cpp | 3 +- Utils/Text.h | 68 +++- Utils/_ChineseText.cpp | 14 + Utils/_DutchText.cpp | 14 + Utils/_EnglishText.cpp | 24 +- Utils/_FrenchText.cpp | 14 + Utils/_GermanText.cpp | 14 + Utils/_ItalianText.cpp | 14 + Utils/_PolishText.cpp | 23 +- Utils/_RussianText.cpp | 14 + Utils/_TaiwaneseText.cpp | 14 + gameloop.cpp | 2 + 39 files changed, 1075 insertions(+), 131 deletions(-) diff --git a/GameSettings.cpp b/GameSettings.cpp index 6d97b934..ca461647 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -70,6 +70,9 @@ // anv: externalised taunt settings #define TAUNTS_SETTINGS_FILE "Taunts_Settings.ini" +// anv: helicopter repair settings - enough of these to put them in own file +#define HELICOPTER_SETTINGS_FILE "Helicopter_Settings.ini" + #define CD_ROOT_DIR "DATA\\" GAME_SETTINGS gGameSettings; @@ -78,6 +81,7 @@ GAME_OPTIONS gGameOptions; GAME_EXTERNAL_OPTIONS gGameExternalOptions; SKILL_TRAIT_VALUES gSkillTraitValues; // SANDRO - added this one TAUNTS_SETTINGS gTauntsSettings; +HELICOPTER_SETTINGS gHelicopterSettings; CTH_CONSTANTS gGameCTHConstants; // HEADROCK HAM 4: CTH constants MOD_SETTINGS gModSettings; //DBrot: mod specific settings @@ -911,6 +915,16 @@ void LoadGameExternalOptions() gGameExternalOptions.usHelicopterBaseCostPerGreenTile = iniReader.ReadInteger("Financial Settings","HELICOPTER_BASE_COST_PER_GREEN_TILE", 100, 0, 60000); gGameExternalOptions.usHelicopterBaseCostPerRedTile = iniReader.ReadInteger("Financial Settings","HELICOPTER_BASE_COST_PER_RED_TILE", 1000, 0, 60000); + // anv: for alternative helicopter fuel system - cost for hovering long enough to burn 1 fuel unit. GREEN = Free airspace, RED = Enemy-controlled airspace. + gGameExternalOptions.usHelicopterHoverCostOnGreenTile = iniReader.ReadInteger("Financial Settings","HELICOPTER_HOVER_COST_ON_GREEN_TILE", 50, 0, 60000); + gGameExternalOptions.usHelicopterHoverCostOnRedTile = iniReader.ReadInteger("Financial Settings","HELICOPTER_HOVER_COST_ON_RED_TILE", 500, 0, 60000); + + // anv: if TRUE, player will have to pay Skyrider even if he returns to base automatically - no more hovering until he runs out of fuel to save money + gGameExternalOptions.fHelicopterReturnToBaseIsNotFree = iniReader.ReadBoolean("Financial Settings","HELICOPTER_RETURN_TO_BASE_IS_NOT_FREE", TRUE); + + // anv: if TRUE, Skyrider will demand money only after safely landing in base + gGameExternalOptions.fPaySkyriderInBase = iniReader.ReadBoolean("Financial Settings","HELICOPTER_PAY_SKYRIDER_IN_BASE", FALSE ); + //tais: percentage that the merc's salary rises when he/she levels up gGameExternalOptions.gMercLevelUpSalaryIncreasePercentage = (FLOAT)iniReader.ReadInteger("Financial Settings","MERC_LEVEL_UP_SALARY_INCREASE_PERCENTAGE",25, 0, 1000); @@ -1738,6 +1752,15 @@ void LoadGameExternalOptions() //Madd: override map item appearance chance gGameExternalOptions.ubMapItemChanceOverride = iniReader.ReadInteger("Strategic Gameplay Settings","MAP_ITEM_CHANCE_OVERRIDE", 0, 0, 100); + // anv: helicopter repairs + gGameExternalOptions.fWaldoCanRepairHelicopter = iniReader.ReadBoolean("Strategic Gameplay Settings","WALDO_CAN_REPAIR_HELICOPTER", TRUE); + gGameExternalOptions.fAllowWaldoToOfferRepairInStrategic = iniReader.ReadBoolean("Strategic Gameplay Settings","WALDO_OFFERS_REPAIR_IN_STRATEGIC", TRUE); + gGameExternalOptions.fWaldoSubsequentRepairsIncreaseCosts = iniReader.ReadBoolean("Strategic Gameplay Settings","WALDO_SUBSEQUENT_REPAIRS_COST_INCREASE", TRUE); + gGameExternalOptions.fSeriouslyDamagedSkyriderWontFly = iniReader.ReadBoolean("Strategic Gameplay Settings","SERIOUSLY_DAMAGED_SKYRIDER_WONT_FLY", TRUE); + + gGameExternalOptions.fAlternativeHelicopterFuelSystem = iniReader.ReadBoolean("Strategic Gameplay Settings","ALTERNATIVE_HELICOPTER_FUEL_SYSTEM", TRUE); + gGameExternalOptions.fHelicopterPassengersCanGetHit = iniReader.ReadBoolean("Strategic Gameplay Settings","HELICOPTER_PASSENGERS_CAN_GET_HIT", TRUE); + //################# Morale Settings ################## gGameExternalOptions.sMoraleModAppearance = iniReader.ReadInteger("Morale Settings","MORALE_MOD_APPEARANCE", 1, 0, 5); gGameExternalOptions.sMoraleModRefinement = iniReader.ReadInteger("Morale Settings","MORALE_MOD_REFINEMENT", 2, 0, 5); @@ -3291,6 +3314,38 @@ void LoadTauntsSettings() } + +void LoadHelicopterRepairRefuelSettings() +{ + CIniReader iniReader(HELICOPTER_SETTINGS_FILE); + + gHelicopterSettings.usHelicopterBasicRepairCost = iniReader.ReadInteger("Helicopter Repair Settings","HELICOPTER_BASIC_REPAIR_COST", 2500, 0, 100000); + gHelicopterSettings.usHelicopterSeriousRepairCost = iniReader.ReadInteger("Helicopter Repair Settings","HELICOPTER_SERIOUS_REPAIR_COST", 7500, 0, 100000); + gHelicopterSettings.ubHelicopterBasicRepairTime = iniReader.ReadInteger("Helicopter Repair Settings","HELICOPTER_BASIC_REPAIR_TIME", 8, 1, 255); + gHelicopterSettings.ubHelicopterBasicRepairTimeVariation = iniReader.ReadInteger("Helicopter Repair Settings","HELICOPTER_BASIC_REPAIR_TIME_VARIATION", 2, 0, 255); + gHelicopterSettings.ubHelicopterSeriousRepairTime = iniReader.ReadInteger("Helicopter Repair Settings","HELICOPTER_SERIOUS_REPAIR_TIME", 24, 1, 255); + gHelicopterSettings.ubHelicopterSeriousRepairTimeVariation = iniReader.ReadInteger("Helicopter Repair Settings","HELICOPTER_SERIOUS_REPAIR_TIME_VARIATION", 6, 0, 255); + gHelicopterSettings.usHelicopterBasicCostIncreaseAfterBasicRepair = iniReader.ReadInteger("Helicopter Repair Settings","HELICOPTER_BASIC_COST_INCREASE_AFTER_BASIC_REPAIR", 500, 0, 100000); + gHelicopterSettings.usHelicopterBasicCostIncreaseAfterSeriousRepair = iniReader.ReadInteger("Helicopter Repair Settings","HELICOPTER_BASIC_COST_INCREASE_AFTER_SERIOUS_REPAIR", 1000, 0, 100000); + gHelicopterSettings.usHelicopterSeriousCostIncreaseAfterBasicRepair = iniReader.ReadInteger("Helicopter Repair Settings","HELICOPTER_SERIOUS_COST_INCREASE_AFTER_BASIC_REPAIR", 1500, 0, 100000); + gHelicopterSettings.usHelicopterSeriousCostIncreaseAfterSeriousRepair = iniReader.ReadInteger("Helicopter Repair Settings","HELICOPTER_SERIOUS_COST_INCREASE_AFTER_SERIOUS_REPAIR", 3000, 0, 100000); + gHelicopterSettings.usHelicopterBasicRepairCostMax = iniReader.ReadInteger("Helicopter Repair Settings","HELICOPTER_BASIC_REPAIR_COST_MAX", 10000, 0, 100000); + gHelicopterSettings.usHelicopterSeriousRepairCostMax = iniReader.ReadInteger("Helicopter Repair Settings","HELICOPTER_SERIOUS_REPAIR_COST_MAX", 25000, 0, 100000); + + gHelicopterSettings.ubHelicopterDistanceWithoutRefuel = iniReader.ReadInteger("Helicopter Refuel Settings","HELICOPTER_DISTANCE_WITHOUT_REFUEL", 25, 0, 255); + gHelicopterSettings.ubHelicopterHoverTimePerFuelUnit = iniReader.ReadInteger("Helicopter Refuel Settings","HELICOPTER_DISTANCE_WITHOUT_REFUEL", 10, 0, 255); + gHelicopterSettings.ubHelicopterRefuelTime = iniReader.ReadInteger("Helicopter Refuel Settings","HELICOPTER_DISTANCE_WITHOUT_REFUEL", 30, 0, 255); + gHelicopterSettings.ubHelicopterTimeDelayForHoverWait = iniReader.ReadInteger("Helicopter Refuel Settings","HELICOPTER_TIME_DELAY_FOR_HOVER_WAIT", 10, 0, 255); + gHelicopterSettings.ubHelicopterTimeDelayForHoverWaitTooLong = iniReader.ReadInteger("Helicopter Refuel Settings","HELICOPTER_TIME_DELAY_FOR_HOVER_WAIT_TOO_LONG", 20, 0, 255); + + gHelicopterSettings.fAskBeforeKickingPassengersOut = iniReader.ReadBoolean("Helicopter Refuel Settings","HELICOPTER_ASK_BEFORE_KICKING_PASSENGERS_OUT", FALSE ); + + gHelicopterSettings.ubHelicopterSAMSiteAccuracy = iniReader.ReadInteger("Helicopter SAM Settings","HELICOPTER_SAM_SITE_ACCURACY", 33, 0, 100); + gHelicopterSettings.ubHelicopterPassengerHitChance = iniReader.ReadInteger("Helicopter SAM Settings","HELICOPTER_PASSENGER_HIT_CHANCE", 25, 0, 100); + gHelicopterSettings.ubHelicopterPassengerHitMaxDamage = iniReader.ReadInteger("Helicopter SAM Settings","HELICOPTER_PASSENGER_HIT_MAX_DAMAGE", 10, 0, 100); + gHelicopterSettings.ubHelicopterPassengerHitMinDamage = iniReader.ReadInteger("Helicopter SAM Settings","HELICOPTER_PASSENGER_HIT_MIN_DAMAGE", 1, 0, 100); +} + void FreeGameExternalOptions() { if (gGameExternalOptions.iaIMPSlots != NULL) // OJW - 20081129 - Fix memory leak when calling LoadGameExternalOptions twice diff --git a/GameSettings.h b/GameSettings.h index 3872fa6e..764112d5 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -1353,6 +1353,21 @@ typedef struct BOOLEAN fNoRemoveRandomSectorItems;//dnl ch68 090913 + // anv: helicopter repair settings + BOOLEAN fWaldoCanRepairHelicopter; + BOOLEAN fAllowWaldoToOfferRepairInStrategic; + BOOLEAN fWaldoSubsequentRepairsIncreaseCosts; + BOOLEAN fSeriouslyDamagedSkyriderWontFly; + + BOOLEAN fAlternativeHelicopterFuelSystem; + BOOLEAN fHelicopterPassengersCanGetHit; + + UINT16 usHelicopterHoverCostOnGreenTile; + UINT16 usHelicopterHoverCostOnRedTile; + + BOOLEAN fHelicopterReturnToBaseIsNotFree; + BOOLEAN fPaySkyriderInBase; + } GAME_EXTERNAL_OPTIONS; typedef struct @@ -1400,6 +1415,36 @@ typedef struct } TAUNTS_SETTINGS; +typedef struct +{ + UINT16 usHelicopterBasicRepairCost; + UINT16 usHelicopterSeriousRepairCost; + UINT8 ubHelicopterBasicRepairTime; + UINT8 ubHelicopterBasicRepairTimeVariation; + UINT8 ubHelicopterSeriousRepairTime; + UINT8 ubHelicopterSeriousRepairTimeVariation; + UINT16 usHelicopterBasicCostIncreaseAfterBasicRepair; + UINT16 usHelicopterBasicCostIncreaseAfterSeriousRepair; + UINT16 usHelicopterSeriousCostIncreaseAfterBasicRepair; + UINT16 usHelicopterSeriousCostIncreaseAfterSeriousRepair; + UINT16 usHelicopterBasicRepairCostMax; + UINT16 usHelicopterSeriousRepairCostMax; + + UINT8 ubHelicopterDistanceWithoutRefuel; + UINT8 ubHelicopterHoverTimePerFuelUnit; + UINT8 ubHelicopterRefuelTime; + UINT8 ubHelicopterTimeDelayForHoverWait; + UINT8 ubHelicopterTimeDelayForHoverWaitTooLong; + BOOLEAN fAskBeforeKickingPassengersOut; + + + UINT8 ubHelicopterSAMSiteAccuracy; + UINT8 ubHelicopterPassengerHitChance; + UINT8 ubHelicopterPassengerHitMinDamage; + UINT8 ubHelicopterPassengerHitMaxDamage; + +} HELICOPTER_SETTINGS; + typedef struct { UINT8 ubMaxNumberOfTraits; @@ -2086,6 +2131,8 @@ extern SKILL_TRAIT_VALUES gSkillTraitValues; // SANDRO - added this one extern TAUNTS_SETTINGS gTauntsSettings; +extern HELICOPTER_SETTINGS gHelicopterSettings; + // HEADROCK HAM 4: CTH constants read from a separate INI file extern CTH_CONSTANTS gGameCTHConstants; @@ -2103,6 +2150,7 @@ void LoadGameAPBPConstants(); // HEADROCK HAM 4: Read CTH/Shooting coefficients from file void LoadCTHConstants(); void LoadTauntsSettings(); +void LoadHelicopterRepairRefuelSettings(); void FreeGameExternalOptions(); void InitGameOptions(); diff --git a/GameVersion.h b/GameVersion.h index a13f9529..64edc72b 100644 --- a/GameVersion.h +++ b/GameVersion.h @@ -21,6 +21,7 @@ extern CHAR16 zTrackingNumber[16]; // Keeps track of the saved game version. Increment the saved game version whenever // you will invalidate the saved game file +#define WALDO_CAN_REPAIR_HELICOPTER 149 // anv: have to refresh Waldo records #define ENCYCLOPEDIA_ITEM_VISIBILITY 148 // Moa: Items discovered during compain have to be saved. #define TRAIT_RADIO_OPERATOR 147 // Flugente: new trait radio operator #define BACKGROUNDS_FIX_UINT8 146 // Flugente: had to change usBackground-vars from UINT8 to UINT16 @@ -67,7 +68,7 @@ extern CHAR16 zTrackingNumber[16]; #define AP100_SAVEGAME_DATATYPE_CHANGE 105 // Before this, we didn't have the 100AP structure changes #define NIV_SAVEGAME_DATATYPE_CHANGE 102 // Before this, we used the old structure system -#define SAVE_GAME_VERSION ENCYCLOPEDIA_ITEM_VISIBILITY +#define SAVE_GAME_VERSION WALDO_CAN_REPAIR_HELICOPTER //#define RUSSIANGOLD #ifdef __cplusplus diff --git a/Laptop/history.cpp b/Laptop/history.cpp index f3803a31..cf580f1b 100644 --- a/Laptop/history.cpp +++ b/Laptop/history.cpp @@ -1178,8 +1178,11 @@ void ProcessHistoryTransactionString(STR16 pString, HistoryUnitPtr pHistory) case HISTORY_SLAUGHTEREDBLOODCATS: case HISTORY_GAVE_CARMEN_HEAD: case HISTORY_SLAY_MYSTERIOUSLY_LEFT: - swprintf( pString, pHistoryStrings[ pHistory->ubCode ] ); + case HISTORY_WALDO: + case HISTORY_HELICOPTER_REPAIR_STARTED: + swprintf( pString, pHistoryStrings[ pHistory->ubCode ], pHistory->ubSecondCode ); break; + } } diff --git a/Laptop/history.h b/Laptop/history.h index 027e14cb..8f0be18b 100644 --- a/Laptop/history.h +++ b/Laptop/history.h @@ -103,6 +103,8 @@ enum{ HISTORY_GAVE_CARMEN_HEAD, HISTORY_SLAY_MYSTERIOUSLY_LEFT, HISTORY_MERC_KILLED_CHARACTER, + HISTORY_WALDO, + HISTORY_HELICOPTER_REPAIR_STARTED, TEXT_NUM_HISTORY }; diff --git a/MainMenuScreen.cpp b/MainMenuScreen.cpp index 88a9cf6f..67bae2f7 100644 --- a/MainMenuScreen.cpp +++ b/MainMenuScreen.cpp @@ -385,6 +385,8 @@ void InitDependingGameStyleOptions() LoadCTHConstants(); // Load externalised taunts settings LoadTauntsSettings(); + // Load helicopter repair settings + LoadHelicopterRepairRefuelSettings(); #ifdef JA2UB LoadGameUBOptions(); // JA25 UB diff --git a/SaveLoadGame.cpp b/SaveLoadGame.cpp index 13e6e006..c631d715 100644 --- a/SaveLoadGame.cpp +++ b/SaveLoadGame.cpp @@ -255,7 +255,7 @@ typedef struct INT32 iHelicopterVehicleId; // total distance travelled - INT32 UNUSEDiTotalHeliDistanceSinceRefuel; + INT32 iTotalHeliDistanceSinceRefuel; // total owed to player INT32 iTotalAccumulatedCostByPlayer; @@ -481,7 +481,14 @@ typedef struct BOOLEAN HiddenNames[500]; //legion by Jazz - UINT8 ubFiller[278]; //This structure should be 1588 bytes + // anv: amount of hours to repair completion + UINT8 ubHelicopterHoursToRepair; + UINT8 ubHelicopterBasicRepairsSoFar; + UINT8 ubHelicopterSeriousRepairsSoFar; + UINT8 ubHelicopterHoverTime; + UINT8 ubHelicopterTimeToFullRefuel; + + UINT8 ubFiller[273]; //This structure should be 1588 bytes } GENERAL_SAVE_INFO; @@ -7912,7 +7919,7 @@ BOOLEAN SaveGeneralInfo( HWFILE hFile ) sGeneralInfo.iHelicopterVehicleId = iHelicopterVehicleId; // total distance travelled -// sGeneralInfo.iTotalHeliDistanceSinceRefuel = iTotalHeliDistanceSinceRefuel; + sGeneralInfo.iTotalHeliDistanceSinceRefuel = iTotalHeliDistanceSinceRefuel; // total owed by player sGeneralInfo.iTotalAccumulatedCostByPlayer = iTotalAccumulatedCostByPlayer; @@ -7948,6 +7955,17 @@ BOOLEAN SaveGeneralInfo( HWFILE hFile ) sGeneralInfo.fSkyriderEmptyHelpGiven = gfSkyriderEmptyHelpGiven; sGeneralInfo.ubHelicopterHitsTaken = gubHelicopterHitsTaken; + + // anv: amount of hours to repair completion + sGeneralInfo.ubHelicopterHoursToRepair = gubHelicopterHoursToRepair; + // repairs so far (for dynamic cost increase) + sGeneralInfo.ubHelicopterBasicRepairsSoFar = gubHelicopterBasicRepairsSoFar; + sGeneralInfo.ubHelicopterSeriousRepairsSoFar = gubHelicopterSeriousRepairsSoFar; + // hover time + sGeneralInfo.ubHelicopterHoverTime = gubHelicopterHoverTime; + // time to full refuel + sGeneralInfo.ubHelicopterTimeToFullRefuel = gubHelicopterTimeToFullRefuel; + sGeneralInfo.fSkyriderSaidCongratsOnTakingSAM = gfSkyriderSaidCongratsOnTakingSAM; sGeneralInfo.ubPlayerProgressSkyriderLastCommentedOn = gubPlayerProgressSkyriderLastCommentedOn; @@ -8219,7 +8237,7 @@ BOOLEAN LoadGeneralInfo( HWFILE hFile ) numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fShowMobileRestrictionsFlag, sizeof(sGeneralInfo.fShowMobileRestrictionsFlag), sizeof(BOOLEAN), numBytesRead); numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fHelicopterAvailable, sizeof(sGeneralInfo.fHelicopterAvailable), sizeof(BOOLEAN), numBytesRead); numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.iHelicopterVehicleId, sizeof(sGeneralInfo.iHelicopterVehicleId), sizeof(INT32), numBytesRead); - numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.UNUSEDiTotalHeliDistanceSinceRefuel, sizeof(sGeneralInfo.UNUSEDiTotalHeliDistanceSinceRefuel), sizeof(INT32), numBytesRead); + numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.iTotalHeliDistanceSinceRefuel, sizeof(sGeneralInfo.iTotalHeliDistanceSinceRefuel), sizeof(INT32), numBytesRead); numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.iTotalAccumulatedCostByPlayer, sizeof(sGeneralInfo.iTotalAccumulatedCostByPlayer), sizeof(INT32), numBytesRead); numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fSkyRiderAvailable, sizeof(sGeneralInfo.fSkyRiderAvailable), sizeof(BOOLEAN), numBytesRead); numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.UNUSEDfSkyriderMonologue, sizeof(sGeneralInfo.UNUSEDfSkyriderMonologue), sizeof(BOOLEAN), numBytesRead); @@ -8361,6 +8379,11 @@ BOOLEAN LoadGeneralInfo( HWFILE hFile ) if ( guiCurrentSaveGameVersion >= NEW_GENERAL_SAVE_INFO_DATA ){ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubManualRestrictMilitia, sizeof(sGeneralInfo.ubManualRestrictMilitia), sizeof(UINT8), numBytesRead); numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.HiddenNames, sizeof(sGeneralInfo.HiddenNames), sizeof(BOOLEAN), numBytesRead); + numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubHelicopterHoursToRepair, sizeof(sGeneralInfo.ubHelicopterHoursToRepair), sizeof(UINT8), numBytesRead); + numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubHelicopterBasicRepairsSoFar, sizeof(sGeneralInfo.ubHelicopterBasicRepairsSoFar), sizeof(UINT8), numBytesRead); + numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubHelicopterSeriousRepairsSoFar, sizeof(sGeneralInfo.ubHelicopterSeriousRepairsSoFar), sizeof(UINT8), numBytesRead); + numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubHelicopterHoverTime, sizeof(sGeneralInfo.ubHelicopterHoverTime), sizeof(UINT8), numBytesRead); + numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubHelicopterTimeToFullRefuel, sizeof(sGeneralInfo.ubHelicopterTimeToFullRefuel), sizeof(UINT8), numBytesRead); numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubFiller, sizeof(sGeneralInfo.ubFiller), sizeof(UINT8), numBytesRead); } else { numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.HiddenNames, sizeof(sGeneralInfo.HiddenNames), sizeof(BOOLEAN), numBytesRead); @@ -8414,7 +8437,7 @@ BOOLEAN LoadGeneralInfo( HWFILE hFile ) iHelicopterVehicleId = sGeneralInfo.iHelicopterVehicleId; // total distance travelled -// iTotalHeliDistanceSinceRefuel = sGeneralInfo.iTotalHeliDistanceSinceRefuel; + iTotalHeliDistanceSinceRefuel = sGeneralInfo.iTotalHeliDistanceSinceRefuel; // total owed to player iTotalAccumulatedCostByPlayer = sGeneralInfo.iTotalAccumulatedCostByPlayer; @@ -8458,6 +8481,17 @@ BOOLEAN LoadGeneralInfo( HWFILE hFile ) gfSkyriderEmptyHelpGiven = sGeneralInfo.fSkyriderEmptyHelpGiven; gubHelicopterHitsTaken = sGeneralInfo.ubHelicopterHitsTaken; + + // anv: amount of hours to repair completion + gubHelicopterHoursToRepair = sGeneralInfo.ubHelicopterHoursToRepair; + // repairs so far (for dynamic cost increase) + gubHelicopterBasicRepairsSoFar = sGeneralInfo.ubHelicopterBasicRepairsSoFar; + gubHelicopterSeriousRepairsSoFar = sGeneralInfo.ubHelicopterSeriousRepairsSoFar; + // hover time + gubHelicopterHoverTime = sGeneralInfo.ubHelicopterHoverTime; + // time to full refuel + gubHelicopterTimeToFullRefuel = sGeneralInfo.ubHelicopterTimeToFullRefuel; + gfSkyriderSaidCongratsOnTakingSAM = sGeneralInfo.fSkyriderSaidCongratsOnTakingSAM; gubPlayerProgressSkyriderLastCommentedOn = sGeneralInfo.ubPlayerProgressSkyriderLastCommentedOn; diff --git a/Strategic/Game Event Hook.cpp b/Strategic/Game Event Hook.cpp index f9866167..787f3d94 100644 --- a/Strategic/Game Event Hook.cpp +++ b/Strategic/Game Event Hook.cpp @@ -311,6 +311,12 @@ BOOLEAN ExecuteStrategicEvent( STRATEGICEVENT *pEvent ) case EVENT_HELICOPTER_HOVER_WAY_TOO_LONG: HandleHeliHoverTooLong( ); break; + case EVENT_HELICOPTER_HOVER_FOR_A_MINUTE: + HandleHeliHoverForAMinute( ); + break; + case EVENT_HELICOPTER_REFUEL_FOR_A_MINUTE: + ReFuelHelicopterForAMinute( ); + break; case EVENT_MERC_LEAVE_EQUIP_IN_DRASSEN: HandleEquipmentLeftInDrassen( pEvent->uiParam ); break; diff --git a/Strategic/Game Event Hook.h b/Strategic/Game Event Hook.h index d66894c4..ba30d008 100644 --- a/Strategic/Game Event Hook.h +++ b/Strategic/Game Event Hook.h @@ -109,6 +109,9 @@ enum !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + EVENT_HELICOPTER_HOVER_FOR_A_MINUTE, + EVENT_HELICOPTER_REFUEL_FOR_A_MINUTE, + NUMBER_OF_EVENT_TYPES_PLUS_ONE, NUMBER_OF_EVENT_TYPES = NUMBER_OF_EVENT_TYPES_PLUS_ONE - 1 }; diff --git a/Strategic/Game Events.cpp b/Strategic/Game Events.cpp index 79a44b71..0c8ddc5f 100644 --- a/Strategic/Game Events.cpp +++ b/Strategic/Game Events.cpp @@ -107,6 +107,8 @@ CHAR16 gEventName[NUMBER_OF_EVENT_TYPES_PLUS_ONE][40]={ #ifdef CRIPPLED_VERSION L"Crippled version end game check", #endif + L"HelicopterHoverForAMinute", + L"HelicopterRefuelForAMinute", }; #endif diff --git a/Strategic/Hourly Update.cpp b/Strategic/Hourly Update.cpp index 78ebb6d1..feea55bf 100644 --- a/Strategic/Hourly Update.cpp +++ b/Strategic/Hourly Update.cpp @@ -32,6 +32,9 @@ // HEADROCK HAM 3.5: Add facility code for hourly update of detection levels #include "Facilities.h" #include "Food.h" // added by Flugente +// anv: for hourly heli repair +#include "Vehicles.h" +#include "Map Screen Helicopter.h" void HourlyQuestUpdate(); void HourlyLarryUpdate(); @@ -45,6 +48,12 @@ extern void PayOffSkyriderDebtIfAny( ); void HourlyCheckIfSlayAloneSoHeCanLeave(); #endif +#if (defined JA2UB) +//no UB +#else +void HourlyHelicopterRepair(); +#endif + void UpdateRegenCounters( void ); void HandleMinuteUpdate() @@ -114,6 +123,8 @@ CHAR16 zString[128]; PayOffSkyriderDebtIfAny(); + HourlyHelicopterRepair(); + if ( GetWorldHour() % 6 == 0 ) // 4 times a day { UpdateRegenCounters(); @@ -566,3 +577,33 @@ void HourlyCheckIfSlayAloneSoHeCanLeave() } } #endif + +#if (defined JA2UB) +// no JA25 UB +#else +void HourlyHelicopterRepair() +{ + if( gubHelicopterHoursToRepair == 0 ) + { + return; + } + MERCPROFILESTRUCT *pMechanic; + pMechanic = &(gMercProfiles[ WALDO ]); + if( !pMechanic ) + { + return; + } + if( !pMechanic->bLife ) + { + return; + } + if( pVehicleList[ iHelicopterVehicleId ].sSectorX == gMercProfiles[ WALDO ].sSectorX && pVehicleList[ iHelicopterVehicleId ].sSectorX == gMercProfiles[ WALDO ].sSectorX ) + { + gubHelicopterHoursToRepair--; + } + if( gubHelicopterHoursToRepair == 0 ) + { + FinishHelicopterRepair(); + } +} +#endif diff --git a/Strategic/Map Screen Helicopter.cpp b/Strategic/Map Screen Helicopter.cpp index 271b79f0..248d0299 100644 --- a/Strategic/Map Screen Helicopter.cpp +++ b/Strategic/Map Screen Helicopter.cpp @@ -45,23 +45,33 @@ #endif #include "Vehicles.h" +#include "NPC.h" +#include "history.h" // the amounts of time to wait for hover stuff -#define TIME_DELAY_FOR_HOVER_WAIT 10 // minutes -#define TIME_DELAY_FOR_HOVER_WAIT_TOO_LONG 20 // mintues +// externalised, use gHelicopterSettings.ubHelicopterTimeDelayForHoverWait instead +//#define TIME_DELAY_FOR_HOVER_WAIT 10 // minutes +// externalised, use gHelicopterSettings.ubHelicopterTimeDelayForHoverWaitTooLong instead +//#define TIME_DELAY_FOR_HOVER_WAIT_TOO_LONG 20 // mintues #define MIN_DAYS_BETWEEN_SKYRIDER_MONOLOGUES 1 // refuel delay -#define REFUEL_HELICOPTER_DELAY 30 // minutes +// externalised, use gHelicopterSettings.ubHelicopterRefuelTime instead +//#define REFUEL_HELICOPTER_DELAY 30 // minutes // total number of sectors one can go -//#define MAX_HELICOPTER_DISTANCE 25 +// externalised, use gHelicopterSettings.ubHelicopterDistanceWithoutRefuel instead +//#define MAX_HELICOPTER_DISTANCE 25 // maximum chance out of a hundred per unsafe sector that a SAM site in decent working condition will hit Skyrider -#define MAX_SAM_SITE_ACCURACY 33 +// externalised, use gHelicopterSettings.ubHelicopterSAMSiteAccuracy instead +//#define MAX_SAM_SITE_ACCURACY 33 +#define HELICOPTER_RETURN_REASON_NONE 0 +#define HELICOPTER_RETURN_REASON_LOW_FUEL 1 +#define HELICOPTER_RETURN_REASON_DAMAGE 2 extern FACETYPE *gpCurrentTalkingFace; extern UINT8 gubCurrentTalkingID; @@ -97,7 +107,7 @@ INT32 iHelicopterVehicleId = -1; UINT32 guiHelicopterIcon; // total distance travelled -//INT32 iTotalHeliDistanceSinceRefuel = 0; +INT32 iTotalHeliDistanceSinceRefuel = 0; // total owed to player INT32 iTotalAccumulatedCostByPlayer = 0; @@ -153,6 +163,13 @@ UINT32 guiTimeOfLastSkyriderMonologue = 0; UINT8 gubHelicopterHitsTaken = 0; +UINT8 gubHelicopterHoursToRepair = 0; +UINT8 gubHelicopterBasicRepairsSoFar = 0; +UINT8 gubHelicopterSeriousRepairsSoFar = 0; + +UINT8 gubHelicopterHoverTime = 0; +UINT8 gubHelicopterTimeToFullRefuel = 0; + BOOLEAN gfSkyriderSaidCongratsOnTakingSAM = FALSE; UINT8 gubPlayerProgressSkyriderLastCommentedOn = 0; @@ -173,14 +190,14 @@ BOOLEAN DoesSkyriderNoticeEnemiesInSector( UINT8 ubNumEnemies ); BOOLEAN EndOfHelicoptersPath( void ); // find the location sector of closest refuel point for heli..and the criteria if the sector must be under the players control -INT32 FindLocationOfClosestRefuelSite( BOOLEAN fMustBeAvailable ); +INT32 FindLocationOfClosestRefuelSite( BOOLEAN fMustBeAvailable, INT16 sX, INT16 sY ); // add the tactical heli graphic void AddHelicopterToMaps( BOOLEAN fAdd, UINT8 ubSite ); void PaySkyriderBill( void ); -void MakeHeliReturnToBase( void ); +void MakeHeliReturnToBase( UINT8 ubReturnReason ); void HandleSkyRiderMonologueAboutDrassenSAMSite( UINT32 uiSpecialCode ); void HandleSkyRiderMonologueAboutCambriaHospital( UINT32 uiSpecialCode ); @@ -558,7 +575,7 @@ void InitializeHelicopter( void ) fPlotForHelicopter = FALSE; pTempHelicopterPath = NULL; -// iTotalHeliDistanceSinceRefuel = 0; + iTotalHeliDistanceSinceRefuel = 0; iTotalAccumulatedCostByPlayer = 0; fHelicopterDestroyed = FALSE; @@ -691,14 +708,14 @@ BOOLEAN HandleHeliEnteringSector( INT16 sX, INT16 sY ) // player pays for travel if Skyrider is NOT returning to base (even if empty while scouting/going for pickup) - if ( fHeliReturnStraightToBase == FALSE ) + if ( fHeliReturnStraightToBase == FALSE || gGameExternalOptions.fHelicopterReturnToBaseIsNotFree ) { // charge cost for flying another sector iTotalAccumulatedCostByPlayer += GetCostOfPassageForHelicopter( sX, sY ); } // accumulate distance travelled -// AddSectorToHelicopterDistanceTravelled( ); + AddSectorToHelicopterDistanceTravelled( ); // check if heli has any real path left @@ -720,7 +737,8 @@ BOOLEAN HandleHeliEnteringSector( INT16 sX, INT16 sY ) } // destination reached, payment due. If player can't pay, mercs get kicked off and heli flies to base! - PaySkyriderBill(); + if( gGameExternalOptions.fPaySkyriderInBase == FALSE || CheckForArrivalAtRefuelPoint( ) ) + PaySkyriderBill(); // WANNE: Fix by Headrock: Always stop time! StopTimeCompression(); @@ -735,23 +753,55 @@ BOOLEAN HandleHeliEnteringSector( INT16 sX, INT16 sY ) else HeliCharacterDialogue( pSkyRider, HELI_HOT_DROP ); - PaySkyriderBill(); + if( gGameExternalOptions.fPaySkyriderInBase == FALSE || CheckForArrivalAtRefuelPoint( ) ) + PaySkyriderBill(); StopTimeCompression(); } if( CheckForArrivalAtRefuelPoint( ) ) { ReFuelHelicopter( ); + OfferHelicopterRepair(); } } + CheckIfHelicopterHasEnoughFuelToReturn( sX, sY ); + return( FALSE ); } -/* +BOOLEAN CheckIfHelicopterHasEnoughFuelToReturn( INT16 sX, INT16 sY ) +{ + // anv: check if we didn't come too far + if( !CheckForArrivalAtRefuelPoint() && fHeliReturnStraightToBase == FALSE && gHelicopterSettings.ubHelicopterDistanceWithoutRefuel - iTotalHeliDistanceSinceRefuel < DistanceToNearestRefuelPoint(sX, sY) ) + { + // hovered too long, inform player heli is returning to base + HeliCharacterDialogue( pSkyRider, RETURN_TO_BASE ); + + // If the sector is safe + if ( NumEnemiesInSector( pVehicleList[ iHelicopterVehicleId ].sSectorX, pVehicleList[ iHelicopterVehicleId ].sSectorY ) == 0 ) + { + // kick everyone out! + // anv: possibly show prompt, if option is on, and heli has any passengers + if( gHelicopterSettings.fAskBeforeKickingPassengersOut == FALSE || GetNumberInVehicle( iHelicopterVehicleId ) == 0 ) + { + MoveAllInHelicopterToFootMovementGroup( ); + MakeHeliReturnToBase( HELICOPTER_RETURN_REASON_LOW_FUEL ); + } + else + DoMessageBox( MSG_BOX_BASIC_STYLE, pHelicopterEtaStrings[ STR_HELI_ETA_KICK_OUT_PASSENGERS_PROMPT ], guiCurrentScreen, ( UINT8 )MSG_BOX_FLAG_YESNO, KickOutPassengersBoxCallBack, NULL ); + } + else + MakeHeliReturnToBase( HELICOPTER_RETURN_REASON_LOW_FUEL ); + + return ( FALSE ); + } + return ( TRUE ); +} + INT32 GetTotalDistanceHelicopterCanTravel( void ) { - return( MAX_HELICOPTER_DISTANCE ); + return( gHelicopterSettings.ubHelicopterDistanceWithoutRefuel ); } INT32 HowFarHelicopterhasTravelledSinceRefueling( void ) @@ -763,7 +813,7 @@ INT32 HowFarHelicopterhasTravelledSinceRefueling( void ) INT32 HowFurtherCanHelicopterTravel( void ) { // how many sectors further can we go on remaining fuel? - return( MAX_HELICOPTER_DISTANCE - ( HowFarHelicopterhasTravelledSinceRefueling( ) + DistanceOfIntendedHelicopterPath( ) ) ); + return( gHelicopterSettings.ubHelicopterDistanceWithoutRefuel - ( HowFarHelicopterhasTravelledSinceRefueling( ) + DistanceOfIntendedHelicopterPath( ) ) ); } void AddSectorToHelicopterDistanceTravelled( void ) @@ -776,26 +826,38 @@ void AddSectorToHelicopterDistanceTravelled( void ) return; } -*/ -INT32 LocationOfNearestRefuelPoint( BOOLEAN fNotifyPlayerIfNoSafeLZ ) + +INT32 LocationOfNearestRefuelPoint( BOOLEAN fNotifyPlayerIfNoSafeLZ, UINT8 ubReturnReason, INT16 sX, INT16 sY ) { INT32 iClosestLocation = -1; + // anv: update availability before check + UpdateRefuelSiteAvailability(); // try to find one, any one under the players control - iClosestLocation = FindLocationOfClosestRefuelSite( TRUE ); + iClosestLocation = FindLocationOfClosestRefuelSite( TRUE, sX, sY ); // no go?...then find if( iClosestLocation == -1 ) { if( fNotifyPlayerIfNoSafeLZ ) { - // no refueling sites available, might wanna warn player about this - ScreenMsg( FONT_MCOLOR_DKRED, MSG_INTERFACE, pHelicopterEtaStrings[ 5 ] ); + switch( ubReturnReason ) + { + case HELICOPTER_RETURN_REASON_LOW_FUEL: + // no refueling sites available, might wanna warn player about this + ScreenMsg( FONT_MCOLOR_DKRED, MSG_INTERFACE, pHelicopterEtaStrings[ STR_HELI_ETA_LOW_ON_FUEL_HOSTILE_TERRITORY ] ); + break; + case HELICOPTER_RETURN_REASON_DAMAGE: + // no refueling sites available, might wanna warn player about this + ScreenMsg( FONT_MCOLOR_DKRED, MSG_INTERFACE, pHelicopterEtaStrings[ STR_HELI_ETA_HELI_DAMAGED_HOSTILE_TERRITORY ] ); + break; + } + } // find the closest location regardless - iClosestLocation = FindLocationOfClosestRefuelSite( FALSE ); + iClosestLocation = FindLocationOfClosestRefuelSite( FALSE, sX, sY ); } // always returns a valid refuel point, picking a hostile one if unavoidable @@ -804,7 +866,7 @@ INT32 LocationOfNearestRefuelPoint( BOOLEAN fNotifyPlayerIfNoSafeLZ ) return( iClosestLocation ); } -INT32 FindLocationOfClosestRefuelSite( BOOLEAN fMustBeAvailable ) +INT32 FindLocationOfClosestRefuelSite( BOOLEAN fMustBeAvailable, INT16 sX, INT16 sY ) { INT32 iShortestDistance = 9999; INT32 iCounter = 0; @@ -815,10 +877,10 @@ INT32 FindLocationOfClosestRefuelSite( BOOLEAN fMustBeAvailable ) for( iCounter = 0; iCounter < NUMBER_OF_REFUEL_SITES; iCounter++ ) { // if this refuelling site is available - if( ( fRefuelingSiteAvailable[ iCounter ] ) || ( fMustBeAvailable == FALSE ) ) + if( ( fRefuelingSiteAvailable[ iCounter ] ) || ( fMustBeAvailable == FALSE && !( ( iCounter == ESTONI_REFUELING_SITE ) && ( CheckFact( FACT_ESTONI_REFUELLING_POSSIBLE, 0 ) == FALSE ) ) ) ) { // find if sector is under control, find distance from heli to it - iDistance = ( INT32 )FindStratPath( ( INT16 )( CALCULATE_STRATEGIC_INDEX( pVehicleList[ iHelicopterVehicleId ].sSectorX , pVehicleList[ iHelicopterVehicleId ].sSectorY ) ), ( INT16 )( CALCULATE_STRATEGIC_INDEX( sRefuelSectorX[ iCounter ], sRefuelSectorY[ iCounter ] ) ) , pVehicleList[ iHelicopterVehicleId ].ubMovementGroup, FALSE ); + iDistance = ( INT32 )FindStratPath( ( INT16 )( CALCULATE_STRATEGIC_INDEX( sX , sY ) ), ( INT16 )( CALCULATE_STRATEGIC_INDEX( sRefuelSectorX[ iCounter ], sRefuelSectorY[ iCounter ] ) ) , pVehicleList[ iHelicopterVehicleId ].ubMovementGroup, FALSE ); if( iDistance < iShortestDistance ) { @@ -840,14 +902,14 @@ INT32 DistanceToNearestRefuelPoint( INT16 sX, INT16 sY ) INT32 iDistance; // don't notify player during these checks! - iClosestLocation = LocationOfNearestRefuelPoint( FALSE ); + iClosestLocation = LocationOfNearestRefuelPoint( FALSE, HELICOPTER_RETURN_REASON_NONE, sX, sY ); iDistance = ( INT32 )FindStratPath( ( INT16 )( CALCULATE_STRATEGIC_INDEX( sX, sY ) ), ( INT16 )( CALCULATE_STRATEGIC_INDEX( sRefuelSectorX[ iClosestLocation ], sRefuelSectorY[ iClosestLocation ] ) ) , pVehicleList[ iHelicopterVehicleId ].ubMovementGroup, FALSE ); return( iDistance ); } -/* + BOOLEAN IsSectorOutOfTheWay( INT16 sX, INT16 sY ) { // check distance to nearest refuel point @@ -859,7 +921,6 @@ BOOLEAN IsSectorOutOfTheWay( INT16 sX, INT16 sY ) return( FALSE ); } -*/ @@ -869,17 +930,194 @@ void ReFuelHelicopter( void ) LandHelicopter( ); -/* - AddStrategicEvent( EVENT_HELICOPTER_DONE_REFUELING, GetWorldTotalMin() + REFUEL_HELICOPTER_DELAY, 0 ); - - // reset distance traveled - iTotalHeliDistanceSinceRefuel = 0; -*/ + if(gGameExternalOptions.fAlternativeHelicopterFuelSystem) + { + gubHelicopterTimeToFullRefuel = ( gHelicopterSettings.ubHelicopterRefuelTime * ( iTotalHeliDistanceSinceRefuel ) ) / gHelicopterSettings.ubHelicopterDistanceWithoutRefuel; + //AddStrategicEvent( EVENT_HELICOPTER_DONE_REFUELING, GetWorldTotalMin() + gHelicopterSettings.ubHelicopterRefuelTime, 0 ); + AddStrategicEvent( EVENT_HELICOPTER_REFUEL_FOR_A_MINUTE, GetWorldTotalMin() + 1, 0 ); + // reset distance traveled + //iTotalHeliDistanceSinceRefuel = 0; + // reset hover time + gubHelicopterHoverTime = 0; + } return; } +void ReFuelHelicopterForAMinute( void ) +{ + if( CheckForArrivalAtRefuelPoint() == FALSE ) + { + return; + } + if( iTotalHeliDistanceSinceRefuel <= 0 ) + { + gubHelicopterTimeToFullRefuel = 0; + iTotalHeliDistanceSinceRefuel = 0; + ScreenMsg( FONT_GRAY2, MSG_INTERFACE, L"%s", pHelicopterRepairRefuelStrings[ STR_HELI_RR_REFUEL_FINISHED ]); + + } + else + { + gubHelicopterTimeToFullRefuel--; + iTotalHeliDistanceSinceRefuel = ( gubHelicopterTimeToFullRefuel * gHelicopterSettings.ubHelicopterDistanceWithoutRefuel ) / gHelicopterSettings.ubHelicopterRefuelTime ; + AddStrategicEvent( EVENT_HELICOPTER_REFUEL_FOR_A_MINUTE, GetWorldTotalMin() + 1, 0 ); + } + + return; +} + +void OfferHelicopterRepair( void ) +{ + CHAR16 sHelicopterRepairPromptText[ 320 ]; + if( !gGameExternalOptions.fAllowWaldoToOfferRepairInStrategic ) + { + return; + } + if( CheckFact(FACT_HELI_DAMAGED_CAN_START_REPAIR, 0 ) == TRUE ) + { + if( gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] == FALSE ) + { + CharacterDialogue( WALDO, WALDO_REPAIR_PROPOSITION, uiExternalStaticNPCFaces[ WALDO_EXTERNAL_FACE ], DIALOGUE_EXTERNAL_NPC_UI, FALSE, FALSE ); + // popup will be called from HandleDialogueEnd() + } + else + { + // no dialogue, show popup right away + swprintf( sHelicopterRepairPromptText, pHelicopterRepairRefuelStrings[ STR_HELI_RR_REPAIR_PROMPT ], gMercProfiles[ WALDO ].zNickname, CalculateHelicopterRepairCost( FALSE ), gHelicopterSettings.ubHelicopterBasicRepairTime ); + DoMessageBox( MSG_BOX_BASIC_STYLE, sHelicopterRepairPromptText, guiCurrentScreen, ( UINT8 )MSG_BOX_FLAG_YESNO, OfferHelicopterRepairBoxCallBack, NULL ); + } + } + else if( CheckFact(FACT_HELI_SERIOUSLY_DAMAGED_CAN_START_REPAIR, 0 ) == TRUE ) + { + if( gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] == FALSE ) + { + CharacterDialogue( WALDO, WALDO_SERIOUS_REPAIR_PROPOSITION, uiExternalStaticNPCFaces[ WALDO_EXTERNAL_FACE ], DIALOGUE_EXTERNAL_NPC_UI, FALSE, FALSE ); + } + else + { + swprintf( sHelicopterRepairPromptText, pHelicopterRepairRefuelStrings[ STR_HELI_RR_REPAIR_PROMPT ], gMercProfiles[ WALDO ].zNickname, CalculateHelicopterRepairCost( TRUE ), gHelicopterSettings.ubHelicopterSeriousRepairTime ); + DoMessageBox( MSG_BOX_BASIC_STYLE, sHelicopterRepairPromptText, guiCurrentScreen, ( UINT8 )MSG_BOX_FLAG_YESNO, OfferHelicopterRepairBoxCallBack, NULL ); + } + } + + return; +} + +void OfferHelicopterRepairBoxCallBack( UINT8 ubExitValue ) +{ + if ( ubExitValue == MSG_BOX_RETURN_YES ) + { + StartHelicopterRepair( TRUE, FALSE ); + } + else + { + if( gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] == FALSE ) + CharacterDialogue( WALDO, WALDO_REPAIR_REFUSED, uiExternalStaticNPCFaces[ WALDO_EXTERNAL_FACE ], DIALOGUE_EXTERNAL_NPC_UI, FALSE, FALSE ); + } + return; +} + +void KickOutPassengersBoxCallBack( UINT8 ubExitValue ) +{ + if ( ubExitValue == MSG_BOX_RETURN_YES ) + { + MoveAllInHelicopterToFootMovementGroup(); + } + else + { + } + MakeHeliReturnToBase( HELICOPTER_RETURN_REASON_LOW_FUEL ); + return; +} + +UINT16 CalculateHelicopterRepairCost( BOOLEAN fSeriousRepair ) +{ + if( gGameExternalOptions.fWaldoSubsequentRepairsIncreaseCosts ) + { + if( fSeriousRepair ) + { + return min( gHelicopterSettings.usHelicopterSeriousRepairCost + gHelicopterSettings.usHelicopterSeriousCostIncreaseAfterBasicRepair * gubHelicopterBasicRepairsSoFar + + + gHelicopterSettings.usHelicopterSeriousCostIncreaseAfterSeriousRepair * gubHelicopterSeriousRepairsSoFar, gHelicopterSettings.usHelicopterSeriousRepairCostMax ); + } + else + { + return min( gHelicopterSettings.usHelicopterBasicRepairCost + gHelicopterSettings.usHelicopterBasicCostIncreaseAfterBasicRepair * gubHelicopterBasicRepairsSoFar + + + gHelicopterSettings.usHelicopterBasicCostIncreaseAfterSeriousRepair * gubHelicopterSeriousRepairsSoFar, gHelicopterSettings.usHelicopterBasicRepairCostMax ); + } + + } + else + { + if( fSeriousRepair ) + { + return min( gHelicopterSettings.usHelicopterSeriousRepairCost, gHelicopterSettings.usHelicopterSeriousRepairCostMax ); + } + else + { + return min( gHelicopterSettings.usHelicopterBasicRepairCost, gHelicopterSettings.usHelicopterBasicRepairCostMax ); + } + + } +} + +void StartHelicopterRepair( BOOLEAN fInStrategic, BOOLEAN fCalledByGivingMoney ) +{ + MoveAllInHelicopterToFootMovementGroup( ); + if( CheckFact( FACT_HELI_DAMAGED_CAN_START_REPAIR, 0 ) == TRUE ) + { + gubHelicopterHoursToRepair = min( max( 1, ( gHelicopterSettings.ubHelicopterBasicRepairTime - gHelicopterSettings.ubHelicopterBasicRepairTimeVariation + 2*Random(gHelicopterSettings.ubHelicopterBasicRepairTimeVariation) ) ), 255 ); + AddTransactionToPlayersBook( PAYMENT_TO_NPC, WALDO, GetWorldTotalMin(), -CalculateHelicopterRepairCost(FALSE) ); + AddHistoryToPlayersLog( HISTORY_HELICOPTER_REPAIR_STARTED, gHelicopterSettings.ubHelicopterBasicRepairTime, GetWorldTotalMin(), pVehicleList[ iHelicopterVehicleId ].sSectorX, pVehicleList[ iHelicopterVehicleId ].sSectorY ); + gubHelicopterBasicRepairsSoFar++; + } + else if( CheckFact( FACT_HELI_SERIOUSLY_DAMAGED_CAN_START_REPAIR, 0 ) == TRUE ) + { + gubHelicopterHoursToRepair = min( max( 1, ( gHelicopterSettings.ubHelicopterSeriousRepairTime - gHelicopterSettings.ubHelicopterSeriousRepairTimeVariation + 2*Random(gHelicopterSettings.ubHelicopterSeriousRepairTimeVariation) ) ), 255 ); + AddTransactionToPlayersBook( PAYMENT_TO_NPC, WALDO, GetWorldTotalMin(), -CalculateHelicopterRepairCost(TRUE) ); + AddHistoryToPlayersLog( HISTORY_HELICOPTER_REPAIR_STARTED, gHelicopterSettings.ubHelicopterSeriousRepairTime, GetWorldTotalMin(), pVehicleList[ iHelicopterVehicleId ].sSectorX, pVehicleList[ iHelicopterVehicleId ].sSectorY ); + gubHelicopterSeriousRepairsSoFar++; + } + + if( gubHelicopterHoursToRepair > 18 && gubHelicopterHoursToRepair < 30 ) + { + if( fInStrategic == TRUE ) + { + if( gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] == FALSE ) + CharacterDialogue( WALDO, WALDO_COME_BACK_TOMORROW, uiExternalStaticNPCFaces[ WALDO_EXTERNAL_FACE ], DIALOGUE_EXTERNAL_NPC_UI, FALSE, FALSE ); + } + else + { + if( !fCalledByGivingMoney ) + TriggerNPCRecord( WALDO, 15 ); + } + } + else + { + if( fInStrategic == TRUE ) + { + if( gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] == FALSE ) + CharacterDialogue( WALDO, WALDO_COME_BACK_IN_SOME_TIME, uiExternalStaticNPCFaces[ WALDO_EXTERNAL_FACE ], DIALOGUE_EXTERNAL_NPC_UI, FALSE, FALSE ); + } + else + { + if( !fCalledByGivingMoney ) + TriggerNPCRecord( WALDO, 16 ); + } + } + return; +} + +void FinishHelicopterRepair() +{ + gubHelicopterHoursToRepair = 0; + gubHelicopterHitsTaken = 0; + if( gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] == FALSE ) + CharacterDialogue( WALDO, WALDO_REPAIR_COMPLETED, uiExternalStaticNPCFaces[ WALDO_EXTERNAL_FACE ], DIALOGUE_EXTERNAL_NPC_UI, FALSE, FALSE ); + ScreenMsg( FONT_GRAY2, MSG_INTERFACE, L"%s", pHelicopterRepairRefuelStrings[ STR_HELI_RR_REPAIR_FINISHED ]); + return; +} INT32 GetCostOfPassageForHelicopter( INT16 sX, INT16 sY ) { @@ -928,7 +1166,7 @@ void SkyriderDestroyed( void ) // zero out balance due gMercProfiles[ SKYRIDER ].iBalance = 0; -// iTotalHeliDistanceSinceRefuel = 0; + iTotalHeliDistanceSinceRefuel = 0; iTotalAccumulatedCostByPlayer = 0; // remove vehicle and reset @@ -954,13 +1192,14 @@ BOOLEAN CanHelicopterFly( void ) return( FALSE ); } -/* // travelled too far? - if( iTotalHeliDistanceSinceRefuel > MAX_HELICOPTER_DISTANCE ) + if( gGameExternalOptions.fAlternativeHelicopterFuelSystem ) { - return( FALSE ); + if( iTotalHeliDistanceSinceRefuel > gHelicopterSettings.ubHelicopterDistanceWithoutRefuel ) + { + return( FALSE ); + } } -*/ // is the pilot alive, well, and willing to help us? if( IsHelicopterPilotAvailable( ) == FALSE ) @@ -979,6 +1218,12 @@ BOOLEAN CanHelicopterFly( void ) return ( FALSE ); } + // repair in progress? + if( gubHelicopterHoursToRepair > 0 ) + { + return ( FALSE ); + } + // everything A-OK! return( TRUE ); } @@ -1003,6 +1248,12 @@ BOOLEAN IsHelicopterPilotAvailable( void ) return ( FALSE ); } + // anv - helicopter too damaged? + if ( gGameExternalOptions.fSeriouslyDamagedSkyriderWontFly == TRUE && gubHelicopterHitsTaken > 1 ) + { + return ( FALSE ); + } + return( TRUE ); } @@ -1062,19 +1313,61 @@ void StartHoverTime( void ) // post event for x mins in future, save start time, if event time - delay = start time, then hover has gone on too long uiStartHoverTime = GetWorldTotalMin( ); - // post event..to call handle hover - AddStrategicEvent( EVENT_HELICOPTER_HOVER_TOO_LONG, GetWorldTotalMin() + TIME_DELAY_FOR_HOVER_WAIT, 0 ); + if( gGameExternalOptions.fAlternativeHelicopterFuelSystem ) + { + AddStrategicEvent( EVENT_HELICOPTER_HOVER_FOR_A_MINUTE, GetWorldTotalMin() + 1, 0 ); + } + else + { + // post event..to call handle hover + AddStrategicEvent( EVENT_HELICOPTER_HOVER_TOO_LONG, GetWorldTotalMin() + gHelicopterSettings.ubHelicopterTimeDelayForHoverWait, 0 ); + } return; } +void HandleHeliHoverForAMinute( void ) +{ + INT16 sX = pVehicleList[ iHelicopterVehicleId ].sSectorX; + INT16 sY = pVehicleList[ iHelicopterVehicleId ].sSectorY; + if( fHoveringHelicopter == FALSE ) + { + return; + } + gubHelicopterHoverTime++; + if( gubHelicopterHoverTime == 10 ) + { + gubHelicopterHoverTime = 0; + + iTotalHeliDistanceSinceRefuel++; + if( StrategicMap[ CALCULATE_STRATEGIC_INDEX( sX, sY ) ].fEnemyAirControlled == FALSE ) + { + iTotalAccumulatedCostByPlayer += gGameExternalOptions.usHelicopterHoverCostOnGreenTile; + } + else + { + iTotalAccumulatedCostByPlayer += gGameExternalOptions.usHelicopterHoverCostOnRedTile; + } + + if( CheckIfHelicopterHasEnoughFuelToReturn( sX, sY ) == TRUE ) + { + // since now heli can stay hovering longer, reminder every 10 minutes would get irritating + if( iTotalHeliDistanceSinceRefuel % 3 == 0 && iTotalHeliDistanceSinceRefuel < gHelicopterSettings.ubHelicopterDistanceWithoutRefuel ) + // inform player + HeliCharacterDialogue( pSkyRider, HOVERING_A_WHILE ); + } + + } + AddStrategicEvent( EVENT_HELICOPTER_HOVER_FOR_A_MINUTE, GetWorldTotalMin() + 1, 0 ); +} + void HandleHeliHoverLong( void ) { // post message about hovering too long if( fHoveringHelicopter ) { // proper event, post next one - AddStrategicEvent( EVENT_HELICOPTER_HOVER_WAY_TOO_LONG, uiStartHoverTime + TIME_DELAY_FOR_HOVER_WAIT_TOO_LONG, 0 ); + AddStrategicEvent( EVENT_HELICOPTER_HOVER_WAY_TOO_LONG, uiStartHoverTime + gHelicopterSettings.ubHelicopterTimeDelayForHoverWaitTooLong, 0 ); // inform player HeliCharacterDialogue( pSkyRider, HOVERING_A_WHILE ); @@ -1107,11 +1400,17 @@ void HandleHeliHoverTooLong( void ) // If the sector is safe if ( NumEnemiesInSector( pVehicleList[ iHelicopterVehicleId ].sSectorX, pVehicleList[ iHelicopterVehicleId ].sSectorY ) == 0 ) { - // kick everyone out! - MoveAllInHelicopterToFootMovementGroup( ); + // anv: possibly show prompt, if option is on, and heli has any passengers + if( gHelicopterSettings.fAskBeforeKickingPassengersOut == FALSE || GetNumberInVehicle( iHelicopterVehicleId ) == 0 ) + { + MoveAllInHelicopterToFootMovementGroup( ); + MakeHeliReturnToBase( HELICOPTER_RETURN_REASON_LOW_FUEL ); + } + else + DoMessageBox( MSG_BOX_BASIC_STYLE, pHelicopterEtaStrings[ STR_HELI_ETA_KICK_OUT_PASSENGERS_PROMPT ], guiCurrentScreen, ( UINT8 )MSG_BOX_FLAG_YESNO, KickOutPassengersBoxCallBack, NULL ); } - - MakeHeliReturnToBase(); + else + MakeHeliReturnToBase( HELICOPTER_RETURN_REASON_LOW_FUEL ); } @@ -1275,12 +1574,14 @@ void UpdateRefuelSiteAvailability( void ) // Generally, only Drassen is initially available for refuelling // Estoni must first be captured (although player may already have it when he gets Skyrider!) + // anv: Estoni should only available after Jake-Shank quest + // site availability should not be dependent on SAM zones, or weird things will happen after controlling Estoni (like inability to land in base if it's in SAM zone) for( iCounter = 0; iCounter < NUMBER_OF_REFUEL_SITES; iCounter++ ) { // if enemy controlled sector (ground OR air, don't want to fly into enemy air territory) if( ( StrategicMap[ CALCULATE_STRATEGIC_INDEX( sRefuelSectorX[ iCounter ], sRefuelSectorY[ iCounter ] ) ].fEnemyControlled == TRUE ) || - ( StrategicMap[ CALCULATE_STRATEGIC_INDEX( sRefuelSectorX[ iCounter ], sRefuelSectorY[ iCounter ] ) ].fEnemyAirControlled == TRUE ) || + //( StrategicMap[ CALCULATE_STRATEGIC_INDEX( sRefuelSectorX[ iCounter ], sRefuelSectorY[ iCounter ] ) ].fEnemyAirControlled == TRUE ) || ( ( iCounter == ESTONI_REFUELING_SITE ) && ( CheckFact( FACT_ESTONI_REFUELLING_POSSIBLE, 0 ) == FALSE ) ) ) { // mark refueling site as unavailable @@ -2123,9 +2424,9 @@ BOOLEAN WillAirRaidBeStopped( INT16 sSectorX, INT16 sSectorY ) ubChance = bSAMCondition; // there's a fair chance of a miss even if the SAM site is in perfect working order - if (ubChance > MAX_SAM_SITE_ACCURACY * 3) // Madd - since this is only used for enemy air raids, we'll say that good guy SAMs can have a max of 99% to hit instead of 33% + if (ubChance > gHelicopterSettings.ubHelicopterSAMSiteAccuracy * 3) // Madd - since this is only used for enemy air raids, we'll say that good guy SAMs can have a max of 99% to hit instead of 33% { - ubChance = MAX_SAM_SITE_ACCURACY * 3; + ubChance = gHelicopterSettings.ubHelicopterSAMSiteAccuracy * 3; } if( PreRandom( 100 ) < ubChance) @@ -2189,9 +2490,9 @@ BOOLEAN HandleSAMSiteAttackOfHelicopterInSector( INT16 sSectorX, INT16 sSectorY ubChance = bSAMCondition; // there's a fair chance of a miss even if the SAM site is in perfect working order - if (ubChance > MAX_SAM_SITE_ACCURACY) + if (ubChance > gHelicopterSettings.ubHelicopterSAMSiteAccuracy) { - ubChance = MAX_SAM_SITE_ACCURACY; + ubChance = gHelicopterSettings.ubHelicopterSAMSiteAccuracy; } if( PreRandom( 100 ) < ubChance) @@ -2206,13 +2507,17 @@ BOOLEAN HandleSAMSiteAttackOfHelicopterInSector( INT16 sSectorX, INT16 sSectorY if ( gubHelicopterHitsTaken == 1 ) { HeliCharacterDialogue( pSkyRider, HELI_TOOK_MINOR_DAMAGE ); + if( gGameExternalOptions.fHelicopterPassengersCanGetHit == TRUE ) + HurtPassengersInHelicopter( iHelicopterVehicleId ); } // second hit? else if ( gubHelicopterHitsTaken == 2 ) { // going back to base (no choice, dialogue says so) HeliCharacterDialogue( pSkyRider, HELI_TOOK_MAJOR_DAMAGE ); - MakeHeliReturnToBase(); + MakeHeliReturnToBase( HELICOPTER_RETURN_REASON_DAMAGE ); + if( gGameExternalOptions.fHelicopterPassengersCanGetHit == TRUE ) + HurtPassengersInHelicopter( iHelicopterVehicleId ); } // third hit! else @@ -2222,17 +2527,21 @@ BOOLEAN HandleSAMSiteAttackOfHelicopterInSector( INT16 sSectorX, INT16 sSectorY // everyone die die die // play sound - if ( PlayJA2StreamingSampleFromFile( "stsounds\\blah2.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN, HeliCrashSoundStopCallback ) == SOUND_ERROR ) - { - // Destroy here if we cannot play streamed sound sample.... - SkyriderDestroyed( ); - } - else - { - // otherwise it's handled in the callback - // remove any arrival events for the helicopter's group - DeleteStrategicEvent( EVENT_GROUP_ARRIVAL, pVehicleList[ iHelicopterVehicleId ].ubMovementGroup ); - } + // if ( PlayJA2StreamingSampleFromFile( "stsounds\\blah2.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN, HeliCrashSoundStopCallback ) == SOUND_ERROR ) + //{ + //// Destroy here if we cannot play streamed sound sample.... + // SkyriderDestroyed( ); + //} + //else + //{ + //// otherwise it's handled in the callback + //// remove any arrival events for the helicopter's group + //DeleteStrategicEvent( EVENT_GROUP_ARRIVAL, pVehicleList[ iHelicopterVehicleId ].ubMovementGroup ); + //} + // anv - calling SkyriderDestroyed() in callback from playing sound causes sound system to crash, as SkyriderDestroyed causes new sounds (hit battlesnds) to play while blah2 is not removed yet + // + if there's a pause while falling heli sound is played, it's possible to cheat by changing passengers assignments + PlayJA2StreamingSampleFromFile( "stsounds\\blah2.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN, HeliCrashSoundStopCallback ); + SkyriderDestroyed( ); // special return code indicating heli was destroyed return( TRUE ); @@ -2593,7 +2902,7 @@ void PaySkyriderBill( void) //CHRISL: This may no longer be the case but I'm not sure of a better way to handle things. MoveAllInHelicopterToFootMovementGroup( ); - MakeHeliReturnToBase(); + MakeHeliReturnToBase( HELICOPTER_RETURN_REASON_NONE ); } iTotalAccumulatedCostByPlayer = 0; @@ -2635,7 +2944,7 @@ void PayOffSkyriderDebtIfAny( ) -void MakeHeliReturnToBase( void ) +void MakeHeliReturnToBase( UINT8 ubReturnReason ) { INT32 iLocation = 0; @@ -2648,7 +2957,7 @@ void MakeHeliReturnToBase( void ) else { // choose destination (closest refueling sector) - iLocation = LocationOfNearestRefuelPoint( TRUE ); + iLocation = LocationOfNearestRefuelPoint( TRUE, ubReturnReason, pVehicleList[ iHelicopterVehicleId ].sSectorX, pVehicleList[ iHelicopterVehicleId ].sSectorY ); // null out path pVehicleList[ iHelicopterVehicleId ].pMercPath = ClearStrategicPathList( pVehicleList[ iHelicopterVehicleId ].pMercPath, pVehicleList[ iHelicopterVehicleId ].ubMovementGroup ); diff --git a/Strategic/Map Screen Helicopter.h b/Strategic/Map Screen Helicopter.h index 87a12441..4056a112 100644 --- a/Strategic/Map Screen Helicopter.h +++ b/Strategic/Map Screen Helicopter.h @@ -23,7 +23,7 @@ #define SPIEL_ABOUT_ESTONI_AIRSPACE 26 #define CONFIRM_DESTINATION 27 -//#define DESTINATION_TOO_FAR 28 // unused +#define DESTINATION_TOO_FAR 28 // unused // anv: used now #define ALTERNATE_FUEL_SITE 26 #define ARRIVED_IN_HOSTILE_SECTOR 29 #define BELIEVED_ENEMY_SECTOR 30 // may become unused @@ -42,6 +42,15 @@ #define HELI_GOING_DOWN 54 #define HELI_PATH_THROUGH_ENEMEY_AIRSPACE 55 #define HELI_HOT_DROP 56 +#define HELI_TOO_DAMAGED_TO_FLY 57 + +// anv: Waldo quotes +#define WALDO_REPAIR_PROPOSITION 22 +#define WALDO_SERIOUS_REPAIR_PROPOSITION 23 +#define WALDO_COME_BACK_TOMORROW 24 +#define WALDO_COME_BACK_IN_SOME_TIME 25 +#define WALDO_REPAIR_REFUSED 26 +#define WALDO_REPAIR_COMPLETED 27 // drassen airport sector #define AIRPORT_X gModSettings.ubAirportX //13 @@ -102,10 +111,10 @@ extern BOOLEAN fHelicopterIsAirBorne; // total distance travelled -//extern INT32 iTotalHeliDistanceSinceRefuel; +extern INT32 iTotalHeliDistanceSinceRefuel; // total owed to player -//extern INT32 iTotalAccumlatedCostByPlayer; +extern INT32 iTotalAccumlatedCostByPlayer; // whether or not skyrider is alive and well? and on our side yet? extern BOOLEAN fSkyRiderAvailable; @@ -133,6 +142,13 @@ extern BOOLEAN fRefuelingSiteAvailable[ MAX_NUMBER_OF_REFUEL_SITES ]; extern BOOLEAN fRefuelingSiteHidden[ MAX_NUMBER_OF_REFUEL_SITES ]; extern UINT8 gubHelicopterHitsTaken; +extern UINT8 gubHelicopterHoursToRepair; +extern UINT8 gubHelicopterBasicRepairsSoFar; +extern UINT8 gubHelicopterSeriousRepairsSoFar; + +extern UINT8 gubHelicopterHoverTime; +extern UINT8 gubHelicopterTimeToFullRefuel; + extern BOOLEAN gfSkyriderSaidCongratsOnTakingSAM; extern UINT8 gubPlayerProgressSkyriderLastCommentedOn; @@ -145,7 +161,7 @@ extern BOOLEAN fSAMSitesDisabledFromAttackingPlayer; #endif -/* ARM: Max. fuel range system removed +// ARM: Max. fuel range system removed // add another sector to how far helictoper has travelled void AddSectorToHelicopterDistanceTravelled( void ); @@ -161,16 +177,25 @@ INT32 HowFurtherCanHelicopterTravel( void ); // check if this sector is out of the way BOOLEAN IsSectorOutOfTheWay( INT16 sX, INT16 sY ); -*/ + // how far to nearest refuel point from this sector? INT32 DistanceToNearestRefuelPoint( INT16 sX, INT16 sY ); // location of closest -INT32 LocationOfNearestRefuelPoint( BOOLEAN fNotifyPlayerIfNoSafeLZ ); +INT32 LocationOfNearestRefuelPoint( BOOLEAN fNotifyPlayerIfNoSafeLZ, UINT8 ubReturnReason, INT16 sX, INT16 sY ); // refuel helicopter void ReFuelHelicopter( void ); +void ReFuelHelicopterForAMinute( void ); + +void OfferHelicopterRepair( void ); +void OfferHelicopterRepairBoxCallBack( UINT8 ubExitValue ); +void KickOutPassengersBoxCallBack( UINT8 ubExitValue ); + +UINT16 CalculateHelicopterRepairCost( BOOLEAN fSeriousRepair ); +void StartHelicopterRepair( BOOLEAN fInStrategic, BOOLEAN fCalledByGivingMoney ); +void FinishHelicopterRepair(); // how much will it cost for helicopter to travel through this sector? INT32 GetCostOfPassageForHelicopter( INT16 sX, INT16 sY ); @@ -211,6 +236,9 @@ void HandleHeliHoverLong( void ); // handle a LONG wait in hover mode void HandleHeliHoverTooLong( void ); +// anv: for alternative fuel system +void HandleHeliHoverForAMinute( void ); + // start the heli hover time void StartHoverTime( void ); @@ -220,6 +248,8 @@ void DropOffEveryOneInHelicopter( void ); // handle heli entering this sector BOOLEAN HandleHeliEnteringSector( INT16 sX, INT16 sY ); +BOOLEAN CheckIfHelicopterHasEnoughFuelToReturn( INT16 sX, INT16 sY ); + // check for arrival at refuel BOOLEAN CheckForArrivalAtRefuelPoint( void ); diff --git a/Strategic/Map Screen Interface Map.cpp b/Strategic/Map Screen Interface Map.cpp index 7d0d7b4b..1346e506 100644 --- a/Strategic/Map Screen Interface Map.cpp +++ b/Strategic/Map Screen Interface Map.cpp @@ -53,6 +53,8 @@ #include "Facilities.h" #include "MilitiaSquads.h" +#include "LaptopSave.h" + UINT16 MAP_GRID_X; UINT16 MAP_GRID_Y; @@ -88,6 +90,7 @@ UINT16 MAP_HELICOPTER_ETA_POPUP_Y; UINT16 MAP_HELICOPTER_UPPER_ETA_POPUP_Y; UINT16 MAP_HELICOPTER_ETA_POPUP_WIDTH; UINT16 MAP_HELICOPTER_ETA_POPUP_HEIGHT; +UINT16 MAP_HELICOPTER_ETA_POPUP_ALTERNATE_HEIGHT; // sublevel text string position UINT16 MAP_LEVEL_STRING_X; @@ -413,6 +416,9 @@ UINT32 guiMapBorderEtaPopUp; // heli pop up UINT32 guiMapBorderHeliSectors; +// anv: alternate heli pop up for alternative fuel system +UINT32 guiMapBorderHeliSectorsAlternate; + // list of map sectors that player isn't allowed to even highlight BOOLEAN sBadSectorsList[ WORLD_MAP_X ][ WORLD_MAP_X ]; @@ -4577,7 +4583,8 @@ void DisplayDistancesForHelicopter( void ) { // calculate the distance travelled, the proposed distance, and total distance one can go // display these on screen - INT16 sDistanceToGo = 0;//, sDistanceSoFar = 0, sTotalCanTravel = 0; + INT16 sDistanceToGo = 0, sDistanceSoFar = 0, sTotalCanTravel = 0; + INT16 sRemainingFuel = 0, sDistToRefuelSite = 0; INT16 sX = 0, sY = 0; CHAR16 sString[ 32 ]; HVOBJECT hHandle; @@ -4591,6 +4598,7 @@ void DisplayDistancesForHelicopter( void ) UINT32 uiTripCost; + if ( GetMouseMapXY( &sMapX, &sMapY ) && !fZoomFlag && ( sMapY >= 13 ) ) { sYPosition = MAP_HELICOPTER_UPPER_ETA_POPUP_Y; @@ -4602,14 +4610,20 @@ void DisplayDistancesForHelicopter( void ) if( ( sOldYPosition != 0 ) && ( sOldYPosition != sYPosition ) ) { - RestoreExternBackgroundRect( MAP_HELICOPTER_ETA_POPUP_X, sOldYPosition, MAP_HELICOPTER_ETA_POPUP_WIDTH + 20, MAP_HELICOPTER_ETA_POPUP_HEIGHT ); + if( !gGameExternalOptions.fAlternativeHelicopterFuelSystem ) + RestoreExternBackgroundRect( MAP_HELICOPTER_ETA_POPUP_X, sOldYPosition, MAP_HELICOPTER_ETA_POPUP_WIDTH + 20, MAP_HELICOPTER_ETA_POPUP_HEIGHT ); + else + RestoreExternBackgroundRect( MAP_HELICOPTER_ETA_POPUP_X, sOldYPosition, MAP_HELICOPTER_ETA_POPUP_WIDTH + 20, MAP_HELICOPTER_ETA_POPUP_ALTERNATE_HEIGHT ); } sOldYPosition = sYPosition; // blit in background UINT8 imageIndex = 0; - GetVideoObject( &hHandle, guiMapBorderHeliSectors ); + if( gGameExternalOptions.fAlternativeHelicopterFuelSystem ) + GetVideoObject( &hHandle, guiMapBorderHeliSectorsAlternate ); + else + GetVideoObject( &hHandle, guiMapBorderHeliSectors ); if (iResolution >= _640x480 && iResolution < _800x600) imageIndex = 0; @@ -4620,14 +4634,16 @@ void DisplayDistancesForHelicopter( void ) BltVideoObject( FRAME_BUFFER, hHandle, imageIndex, MAP_HELICOPTER_ETA_POPUP_X, sYPosition, VO_BLT_SRCTRANSPARENCY, NULL ); -// sTotalCanTravel = ( INT16 )GetTotalDistanceHelicopterCanTravel( ); + sTotalCanTravel = ( INT16 )GetTotalDistanceHelicopterCanTravel( ); sDistanceToGo = ( INT16 )DistanceOfIntendedHelicopterPath( ); sTotalOfTrip = sDistanceToGo; // + ( INT16 ) ( DistanceToNearestRefuelPoint( ( INT16 )( LastSectorInHelicoptersPath() % MAP_WORLD_X ), ( INT16 ) ( LastSectorInHelicoptersPath() / MAP_WORLD_X ) ) ); sNumSafeSectors = GetNumSafeSectorsInPath( ); sNumUnSafeSectors = GetNumUnSafeSectorsInPath( ); -// sDistanceSoFar = ( INT16 )HowFarHelicopterhasTravelledSinceRefueling( ); -// sTotalDistanceOfTrip = ( INT16 )DistanceToNearestRefuelPoint( ) + //sDistanceSoFar = ( INT16 )HowFarHelicopterhasTravelledSinceRefueling( ); + //sTotalDistanceOfTrip = ( INT16 )DistanceToNearestRefuelPoint( ); + sRemainingFuel = ( INT16 )(gHelicopterSettings.ubHelicopterDistanceWithoutRefuel - iTotalHeliDistanceSinceRefuel - sDistanceToGo); + sDistToRefuelSite = ( INT16 )DistanceToNearestRefuelPoint( sMapX, sMapY ); if( sDistanceToGo == 9999) { @@ -4639,7 +4655,7 @@ void DisplayDistancesForHelicopter( void ) SetFontForeground( FONT_LTGREEN ); SetFontBackground( FONT_BLACK ); - swprintf( sString, L"%s", pHelicopterEtaStrings[ 0 ] ); + swprintf( sString, L"%s", pHelicopterEtaStrings[ STR_HELI_ETA_TOTAL_DISTANCE ] ); mprintf( MAP_HELICOPTER_ETA_POPUP_X + 5, sYPosition + 5, sString ); /* @@ -4659,21 +4675,21 @@ void DisplayDistancesForHelicopter( void ) SetFontForeground( FONT_LTGREEN ); - swprintf( sString, L"%s", pHelicopterEtaStrings[ 1 ] ); + swprintf( sString, L"%s", pHelicopterEtaStrings[ STR_HELI_ETA_SAFE ] ); mprintf( MAP_HELICOPTER_ETA_POPUP_X + 5, sYPosition + 5 + GetFontHeight( MAP_FONT ), sString ); swprintf( sString, L"%d", sNumSafeSectors ); FindFontRightCoordinates( MAP_HELICOPTER_ETA_POPUP_X + 5, ( INT16 ) ( MAP_HELICOPTER_ETA_POPUP_Y + 5 + 2 * GetFontHeight( MAP_FONT ) ), MAP_HELICOPTER_ETA_POPUP_WIDTH, 0, sString, MAP_FONT, &sX, &sY ); mprintf( sX, ( INT16 ) ( sYPosition + 5 + GetFontHeight( MAP_FONT ) ), sString ); - swprintf( sString, L"%s", pHelicopterEtaStrings[ 2 ] ); + swprintf( sString, L"%s", pHelicopterEtaStrings[ STR_HELI_ETA_UNSAFE ] ); mprintf( MAP_HELICOPTER_ETA_POPUP_X + 5, sYPosition + 5 + 2 * GetFontHeight( MAP_FONT ), sString ); swprintf( sString, L"%d", sNumUnSafeSectors ); FindFontRightCoordinates( MAP_HELICOPTER_ETA_POPUP_X + 5, ( INT16 ) ( MAP_HELICOPTER_ETA_POPUP_Y + 5 + 2 * GetFontHeight( MAP_FONT ) ), MAP_HELICOPTER_ETA_POPUP_WIDTH, 0, sString, MAP_FONT, &sX, &sY ); mprintf( sX, ( INT16 ) ( sYPosition + 5 + 2 * GetFontHeight( MAP_FONT ) ), sString ); - swprintf( sString, L"%s", pHelicopterEtaStrings[ 3 ] ); + swprintf( sString, L"%s", pHelicopterEtaStrings[ STR_HELI_ETA_TOTAL_COST ] ); mprintf( MAP_HELICOPTER_ETA_POPUP_X + 5, sYPosition + 5 + 3 * GetFontHeight( MAP_FONT ), sString ); @@ -4683,15 +4699,19 @@ void DisplayDistancesForHelicopter( void ) UINT32 uiCostRed = __max(0,gGameExternalOptions.usHelicopterBaseCostPerRedTile + gsSkyriderCostModifier); uiTripCost = ( sNumSafeSectors * uiCostGreen ) + ( sNumUnSafeSectors * uiCostRed ); + if( uiTripCost > LaptopSaveInfo.iCurrentBalance ) + SetFontForeground( FONT_LTRED ); + swprintf( sString, L"%d", uiTripCost ); InsertCommasForDollarFigure( sString ); InsertDollarSignInToString( sString ); FindFontRightCoordinates( MAP_HELICOPTER_ETA_POPUP_X + 5, ( INT16 ) ( MAP_HELICOPTER_ETA_POPUP_Y + 5 + 3 * GetFontHeight( MAP_FONT ) ), MAP_HELICOPTER_ETA_POPUP_WIDTH, 0, sString, MAP_FONT, &sX, &sY ); mprintf( sX, ( INT16 ) ( sYPosition + 5 + 3 * GetFontHeight( MAP_FONT ) ), sString ); - swprintf( sString, L"%s", pHelicopterEtaStrings[ 4 ] ); - mprintf( MAP_HELICOPTER_ETA_POPUP_X + 5, sYPosition + 5 + 4 * GetFontHeight( MAP_FONT ), sString ); + SetFontForeground( FONT_LTGREEN ); + swprintf( sString, L"%s", pHelicopterEtaStrings[ STR_HELI_ETA_ETA ] ); + mprintf( MAP_HELICOPTER_ETA_POPUP_X + 5, sYPosition + 5 + 4 * GetFontHeight( MAP_FONT ), sString ); // get travel time for the last path segment iTime = GetPathTravelTimeDuringPlotting( pTempHelicopterPath ); @@ -4705,13 +4725,34 @@ void DisplayDistancesForHelicopter( void ) // show # of passengers aboard the chopper - mprintf( MAP_HELICOPTER_ETA_POPUP_X + 5, sYPosition + 5 + 5 * GetFontHeight( MAP_FONT ), pHelicopterEtaStrings[ 6 ] ); + mprintf( MAP_HELICOPTER_ETA_POPUP_X + 5, sYPosition + 5 + 5 * GetFontHeight( MAP_FONT ), pHelicopterEtaStrings[ STR_HELI_ETA_PASSENGERS ] ); swprintf( sString, L"%d", GetNumberOfPassengersInHelicopter() ); FindFontRightCoordinates( MAP_HELICOPTER_ETA_POPUP_X + 5, ( INT16 ) ( MAP_HELICOPTER_ETA_POPUP_Y + 5 + 5 * GetFontHeight( MAP_FONT ) ), MAP_HELICOPTER_ETA_POPUP_WIDTH, 0, sString, MAP_FONT, &sX, &sY ); mprintf( sX, ( INT16 ) ( sYPosition + 5 + 5 * GetFontHeight( MAP_FONT ) ), sString ); + // show remaining fuel + mprintf( MAP_HELICOPTER_ETA_POPUP_X + 5, sYPosition + 5 + 6 * GetFontHeight( MAP_FONT ), pHelicopterEtaStrings[ STR_HELI_ETA_REMAINING_FUEL ] ); + swprintf( sString, L"%d", sRemainingFuel ); + FindFontRightCoordinates( MAP_HELICOPTER_ETA_POPUP_X + 5, ( INT16 ) ( MAP_HELICOPTER_ETA_POPUP_Y + 5 + 6 * GetFontHeight( MAP_FONT ) ), MAP_HELICOPTER_ETA_POPUP_WIDTH, 0, sString, MAP_FONT, &sX, &sY ); + if( sRemainingFuel < sDistToRefuelSite ) + SetFontForeground( FONT_LTRED ); + mprintf( sX, ( INT16 ) ( sYPosition + 5 + 6 * GetFontHeight( MAP_FONT ) ), sString ); + SetFontForeground( FONT_LTGREEN ); + + // show distance to the nearest refuel site + mprintf( MAP_HELICOPTER_ETA_POPUP_X + 5, sYPosition + 5 + 7 * GetFontHeight( MAP_FONT ), pHelicopterEtaStrings[ STR_HELI_ETA_DISTANCE_TO_REFUEL_SITE ] ); + swprintf( sString, L"%d", sDistToRefuelSite ); + FindFontRightCoordinates( MAP_HELICOPTER_ETA_POPUP_X + 5, ( INT16 ) ( MAP_HELICOPTER_ETA_POPUP_Y + 5 + 7 * GetFontHeight( MAP_FONT ) ), MAP_HELICOPTER_ETA_POPUP_WIDTH, 0, sString, MAP_FONT, &sX, &sY ); + if( sRemainingFuel < sDistToRefuelSite ) + SetFontForeground( FONT_LTRED ); + mprintf( sX, ( INT16 ) ( sYPosition + 5 + 7 * GetFontHeight( MAP_FONT ) ), sString ); + SetFontForeground( FONT_LTGREEN ); + + if( !gGameExternalOptions.fAlternativeHelicopterFuelSystem ) + InvalidateRegion( MAP_HELICOPTER_ETA_POPUP_X, sOldYPosition, MAP_HELICOPTER_ETA_POPUP_X + MAP_HELICOPTER_ETA_POPUP_WIDTH + 20, sOldYPosition + MAP_HELICOPTER_ETA_POPUP_HEIGHT ); + else + InvalidateRegion( MAP_HELICOPTER_ETA_POPUP_X, sOldYPosition, MAP_HELICOPTER_ETA_POPUP_X + MAP_HELICOPTER_ETA_POPUP_WIDTH + 20, sOldYPosition + MAP_HELICOPTER_ETA_POPUP_ALTERNATE_HEIGHT ); - InvalidateRegion( MAP_HELICOPTER_ETA_POPUP_X, sOldYPosition, MAP_HELICOPTER_ETA_POPUP_X + MAP_HELICOPTER_ETA_POPUP_WIDTH + 20, sOldYPosition + MAP_HELICOPTER_ETA_POPUP_HEIGHT ); return; } diff --git a/Strategic/Map Screen Interface Map.h b/Strategic/Map Screen Interface Map.h index 5c705315..de6a977e 100644 --- a/Strategic/Map Screen Interface Map.h +++ b/Strategic/Map Screen Interface Map.h @@ -218,6 +218,7 @@ extern UINT16 MAP_HELICOPTER_ETA_POPUP_Y; extern UINT16 MAP_HELICOPTER_UPPER_ETA_POPUP_Y; extern UINT16 MAP_HELICOPTER_ETA_POPUP_WIDTH; extern UINT16 MAP_HELICOPTER_ETA_POPUP_HEIGHT; +extern UINT16 MAP_HELICOPTER_ETA_POPUP_ALTERNATE_HEIGHT; // sublevel text string position extern UINT16 MAP_LEVEL_STRING_X; @@ -326,6 +327,9 @@ extern UINT32 guiMapBorderEtaPopUp; // heli pop up extern UINT32 guiMapBorderHeliSectors; +// anv: alternate heli pop up for alternative fuel system +extern UINT32 guiMapBorderHeliSectorsAlternate; + // the currently selected town militia extern INT16 sSelectedMilitiaTown; diff --git a/Strategic/Quests.cpp b/Strategic/Quests.cpp index 9ddb00df..7789d8c3 100644 --- a/Strategic/Quests.cpp +++ b/Strategic/Quests.cpp @@ -49,6 +49,9 @@ #include "Luaglobal.h" +// anv: Waldo The Mechanic - for fact checking with helicopter +#include "Vehicles.h" + #define TESTQUESTS extern SOLDIERTYPE * gpSrcSoldier; @@ -1307,6 +1310,43 @@ BOOLEAN CheckFact( UINT16 usFact, UINT8 ubProfileID ) gubFact[usFact] = ; break; */ + // anv: facts for checking if Waldo can repair helicopter + + case FACT_HELI_DAMAGED_CAN_START_REPAIR: + gubFact[usFact] = ( gGameExternalOptions.fWaldoCanRepairHelicopter && + !fHelicopterDestroyed && !fHelicopterIsAirBorne && gubHelicopterHitsTaken == 1 && + pVehicleList[ iHelicopterVehicleId ].sSectorX == gMercProfiles[ WALDO ].sSectorX && pVehicleList[ iHelicopterVehicleId ].sSectorY == gMercProfiles[ WALDO ].sSectorY && + LaptopSaveInfo.iCurrentBalance >= CalculateHelicopterRepairCost( FALSE ) && + gubHelicopterHoursToRepair == 0 && CheckFact( FACT_WALDO_MET, 0 ) ); + break; + + case FACT_HELI_SERIOUSLY_DAMAGED_CAN_START_REPAIR: + gubFact[usFact] = ( gGameExternalOptions.fWaldoCanRepairHelicopter && + !fHelicopterDestroyed && !fHelicopterIsAirBorne && gubHelicopterHitsTaken == 2 && + pVehicleList[ iHelicopterVehicleId ].sSectorX == gMercProfiles[ WALDO ].sSectorX && pVehicleList[ iHelicopterVehicleId ].sSectorY == gMercProfiles[ WALDO ].sSectorY && + LaptopSaveInfo.iCurrentBalance >= CalculateHelicopterRepairCost( TRUE ) && + gubHelicopterHoursToRepair == 0 && CheckFact( FACT_WALDO_MET, 0 ) ); + break; + + case FACT_HELI_GIVEN_MONEY_CAN_START_REPAIR: + gubFact[usFact] = ( ( gGameExternalOptions.fWaldoCanRepairHelicopter && + !fHelicopterDestroyed && !fHelicopterIsAirBorne && gubHelicopterHitsTaken > 0 && + pVehicleList[ iHelicopterVehicleId ].sSectorX == gMercProfiles[ WALDO ].sSectorX && pVehicleList[ iHelicopterVehicleId ].sSectorY == gMercProfiles[ WALDO ].sSectorY && + gubHelicopterHoursToRepair == 0 ) && + ( CheckFact(FACT_GIVEN_ENOUGH_TO_REPAIR_HELI, 0) || CheckFact(FACT_GIVEN_ENOUGH_TO_SERIOUSLY_REPAIR_HELI, 0) ) && CheckFact( FACT_WALDO_MET, 0 ) ); + break; + + case FACT_HELI_CANT_START_REPAIR: + gubFact[usFact] = ( !CheckFact(FACT_HELI_GIVEN_MONEY_CAN_START_REPAIR, 0) && !CheckFact(FACT_HELICOPTER_IN_PERFECT_CONDITION, 0)); + break; + + case FACT_HELICOPTER_IN_PERFECT_CONDITION: + gubFact[usFact] = ( gubHelicopterHitsTaken == 0 ); + break; + + case FACT_HELICOPTER_LOST: + gubFact[usFact] = fHelicopterDestroyed; + break; default: break; diff --git a/Strategic/Quests.h b/Strategic/Quests.h index f86fd3cf..e2ab4339 100644 --- a/Strategic/Quests.h +++ b/Strategic/Quests.h @@ -331,9 +331,15 @@ enum Facts FACT_PABLO_WONT_STEAL = 124, FACT_AGENTS_PREVENTED_SHIPMENT,// 125 + // anv: it was 126 in Waldo script + FACT_HELICOPTER_IN_PERFECT_CONDITION = 126, + FACT_LARGE_AMOUNT_OF_MONEY = 127, FACT_SMALL_AMOUNT_OF_MONEY,// 128 + // anv: it was 130 in Waldo script + FACT_HELICOPTER_LOST = 130, + FACT_LOYALTY_OKAY = 135, FACT_LOYALTY_LOW,// 136 FACT_LOYALTY_HIGH,// 137 @@ -530,6 +536,20 @@ enum Facts FACT_PLAYER_KILLED_BOXERS = 368, // HEADROCK HAM 4: Seen Mobile Militia screen after having at least one mobile unit? FACT_MOBILE_RESTRICTIONS_VIEWED = 369, + + // anv: Waldo The Mechanic, facts for his dialogue + FACT_HELI_DAMAGED_CAN_START_REPAIR, + FACT_HELI_SERIOUSLY_DAMAGED_CAN_START_REPAIR, + + FACT_GIVEN_ENOUGH_TO_REPAIR_HELI, + FACT_GIVEN_ENOUGH_TO_SERIOUSLY_REPAIR_HELI, + + FACT_HELI_GIVEN_MONEY_CAN_START_REPAIR, + FACT_HELI_CANT_START_REPAIR, + + FACT_WALDO_MET, + + #ifdef JA2UB //Ja25 UB FACT_IMPORTED_SAVE_AND_MARY_WAS_DEAD = 400, diff --git a/Strategic/mapscreen.cpp b/Strategic/mapscreen.cpp index 3116d95e..fbbdbce9 100644 --- a/Strategic/mapscreen.cpp +++ b/Strategic/mapscreen.cpp @@ -4617,6 +4617,7 @@ UINT32 MapScreenHandle(void) MAP_HELICOPTER_UPPER_ETA_POPUP_Y = (50 + iScreenHeightOffset) - yResOffset; MAP_HELICOPTER_ETA_POPUP_WIDTH = 120; MAP_HELICOPTER_ETA_POPUP_HEIGHT = 68; + MAP_HELICOPTER_ETA_POPUP_ALTERNATE_HEIGHT = 74; // Map Level string MAP_LEVEL_STRING_X = (SCREEN_WIDTH - 208); @@ -4669,6 +4670,7 @@ UINT32 MapScreenHandle(void) MAP_HELICOPTER_UPPER_ETA_POPUP_Y = (50 + iScreenHeightOffset - 40) - yResOffset; MAP_HELICOPTER_ETA_POPUP_WIDTH = 120; MAP_HELICOPTER_ETA_POPUP_HEIGHT = 68; + MAP_HELICOPTER_ETA_POPUP_ALTERNATE_HEIGHT = 74; // Map Level string MAP_LEVEL_STRING_X = (SCREEN_WIDTH - 800)/ 2 + (800 - 208 - 80); @@ -4720,6 +4722,7 @@ UINT32 MapScreenHandle(void) MAP_HELICOPTER_UPPER_ETA_POPUP_Y = (50 + iScreenHeightOffset - 100) - yResOffset; MAP_HELICOPTER_ETA_POPUP_WIDTH = 120; MAP_HELICOPTER_ETA_POPUP_HEIGHT = 76; + MAP_HELICOPTER_ETA_POPUP_ALTERNATE_HEIGHT = 97; // Map Level string MAP_LEVEL_STRING_X = (SCREEN_WIDTH - 1024)/ 2 + (1024 - 208 - 187); @@ -4958,6 +4961,9 @@ UINT32 MapScreenHandle(void) FilenameForBPP("INTERFACE\\pos2.sti", VObjectDesc.ImageFile); CHECKF(AddVideoObject(&VObjectDesc, &guiMapBorderHeliSectors)); + VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; + FilenameForBPP("INTERFACE\\pos2_alternate.sti", VObjectDesc.ImageFile); + CHECKF(AddVideoObject(&VObjectDesc, &guiMapBorderHeliSectorsAlternate)); VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; FilenameForBPP("INTERFACE\\secondary_gun_hidden.sti", VObjectDesc.ImageFile); @@ -6407,7 +6413,7 @@ UINT32 HandleMapUI( ) // plotting for the chopper? if( fPlotForHelicopter == TRUE ) { -/* + if( IsSectorOutOfTheWay( sMapX, sMapY ) == TRUE ) { if( gfAllowSkyriderTooFarQuote == TRUE ) @@ -6417,7 +6423,7 @@ UINT32 HandleMapUI( ) return( MAP_SCREEN ); } -*/ + PlotPathForHelicopter( sMapX, sMapY ); fTeamPanelDirty = TRUE; @@ -8546,6 +8552,7 @@ INT32 iCounter2 = 0; DeleteVideoObjectFromIndex( guiSecItemHiddenVO ); DeleteVideoObjectFromIndex( guiSelectedCharArrow ); DeleteVideoObjectFromIndex( guiMapBorderHeliSectors ); + DeleteVideoObjectFromIndex( guiMapBorderHeliSectorsAlternate ); DeleteVideoObjectFromIndex( guiHelicopterIcon ); DeleteVideoObjectFromIndex( guiMINEICON ); DeleteVideoObjectFromIndex( guiSectorLocatorGraphicID ); @@ -13322,6 +13329,7 @@ INT32 iCounter2 = 0; DeleteVideoObjectFromIndex( guiSecItemHiddenVO ); DeleteVideoObjectFromIndex( guiSelectedCharArrow ); DeleteVideoObjectFromIndex( guiMapBorderHeliSectors ); + DeleteVideoObjectFromIndex( guiMapBorderHeliSectorsAlternate ); DeleteVideoObjectFromIndex( guiHelicopterIcon ); DeleteVideoObjectFromIndex( guiMINEICON ); DeleteVideoObjectFromIndex( guiSectorLocatorGraphicID ); @@ -15217,6 +15225,20 @@ void ExplainWhySkyriderCantFly( void ) return; } + // repairs in progress + if ( gubHelicopterHoursToRepair > 0 ) + { + DoMapMessageBox( MSG_BOX_BASIC_STYLE, pHelicopterRepairRefuelStrings[ STR_HELI_RR_REPAIR_IN_PROGRESS ], MAP_SCREEN, MSG_BOX_FLAG_OK, MapScreenDefaultOkBoxCallback ); + return; + } + + // anv - helicopter too damaged? + if ( gGameExternalOptions.fSeriouslyDamagedSkyriderWontFly == TRUE && gubHelicopterHitsTaken > 1 ) + { + SkyRiderTalk( HELI_TOO_DAMAGED_TO_FLY ); + return; + } + // no explainable reason } @@ -15511,11 +15533,11 @@ BOOLEAN CanMoveBullseyeAndClickedOnIt( INT16 sMapX, INT16 sMapY ) void CreateBullsEyeOrChopperSelectionPopup( void ) { - wcscpy( gzUserDefinedButton1, pHelicopterEtaStrings[ 8 ] ); - wcscpy( gzUserDefinedButton2, pHelicopterEtaStrings[ 9 ] ); + wcscpy( gzUserDefinedButton1, pHelicopterEtaStrings[ STR_HELI_ETA_SKYRIDER ] ); + wcscpy( gzUserDefinedButton2, pHelicopterEtaStrings[ STR_HELI_ETA_ARRIVALS ] ); // do a BULLSEYE/CHOPPER message box - DoScreenIndependantMessageBox( pHelicopterEtaStrings[ 7 ], MSG_BOX_FLAG_GENERIC_TWO_BUTTONS, BullsEyeOrChopperSelectionPopupCallback ); + DoScreenIndependantMessageBox( pHelicopterEtaStrings[ STR_HELI_ETA_SELECT_SKYRIDER_OR_ARRIVALS ], MSG_BOX_FLAG_GENERIC_TWO_BUTTONS, BullsEyeOrChopperSelectionPopupCallback ); } diff --git a/Tactical/Civ Quotes.cpp b/Tactical/Civ Quotes.cpp index f3c22bb3..5d0d8667 100644 --- a/Tactical/Civ Quotes.cpp +++ b/Tactical/Civ Quotes.cpp @@ -1716,14 +1716,15 @@ void StartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTYPE *pTar if( pTarget != NULL ) { -#ifdef ENABLE_ZOMBIES // target should be zombie if( zTaunt[ i ].uiFlags2 & TAUNT_T_ZOMBIE ) { + // anv: moved ifdef - if zombies are off, we want to skip any taunts with TAUNT_T_ZOMBIE flag +#ifdef ENABLE_ZOMBIES if( pTarget->IsZombie() == FALSE ) +#endif continue; } -#endif // target merc profile if( zTaunt[ i ].value[TAUNT_TARGET_MERC_PROFILE] != -1 ) diff --git a/Tactical/Dialogue Control.cpp b/Tactical/Dialogue Control.cpp index 29662784..30e84321 100644 --- a/Tactical/Dialogue Control.cpp +++ b/Tactical/Dialogue Control.cpp @@ -70,6 +70,8 @@ #include "ub_config.h" +#include "history.h" + //forward declarations of common classes to eliminate includes class OBJECTTYPE; class SOLDIERTYPE; @@ -354,6 +356,8 @@ void InitalizeStaticExternalNPCFaces( void ) //} // ... put Skyrider's face at index 0 uiExternalStaticNPCFaces.push_back(( UINT32 )InitFace( ( UINT8 )( SKYRIDER ), NOBODY, FACE_FORCE_SMALL )); + // anv: and put Waldo too + uiExternalStaticNPCFaces.push_back(( UINT32 )InitFace( ( UINT8 )( WALDO ), NOBODY, FACE_FORCE_SMALL )); return; } @@ -2682,6 +2686,21 @@ void HandleDialogueEnd( FACETYPE *pFace ) MSYS_RemoveRegion( &gTextBoxMouseRegion ); fTextBoxMouseRegionCreated = FALSE; } + // anv: show repair prompt afer Waldo offered repairs + if ( gbUIHandlerID == DIALOGUE_EXTERNAL_NPC_UI && gTacticalStatus.ubLastQuoteProfileNUm == WALDO && + ( gTacticalStatus.ubLastQuoteSaid == WALDO_REPAIR_PROPOSITION || gTacticalStatus.ubLastQuoteSaid == WALDO_SERIOUS_REPAIR_PROPOSITION ) ) + { + CHAR16 sHelicopterRepairPromptText[ 320 ]; + if( CheckFact(FACT_HELI_DAMAGED_CAN_START_REPAIR, 0) == TRUE ) + { + swprintf( sHelicopterRepairPromptText, pHelicopterRepairRefuelStrings[ STR_HELI_RR_REPAIR_PROMPT ], gMercProfiles[ WALDO ].zNickname, CalculateHelicopterRepairCost( FALSE ), gHelicopterSettings.ubHelicopterBasicRepairTime ); + } + else + { + swprintf( sHelicopterRepairPromptText, pHelicopterRepairRefuelStrings[ STR_HELI_RR_REPAIR_PROMPT ], gMercProfiles[ WALDO ].zNickname, CalculateHelicopterRepairCost( TRUE ), gHelicopterSettings.ubHelicopterSeriousRepairTime ); + } + DoMessageBox( MSG_BOX_BASIC_STYLE, sHelicopterRepairPromptText, guiCurrentScreen, ( UINT8 )MSG_BOX_FLAG_YESNO, OfferHelicopterRepairBoxCallBack, NULL ); + } // anv: after merc finishes his quote, we want enemy to answer if ( gbUIHandlerID == DIALOGUE_TACTICAL_UI ) @@ -2720,6 +2739,12 @@ void HandleDialogueEnd( FACETYPE *pFace ) case DIALOGUE_NPC_UI: + // anv: "meet" Waldo when speaking with him first time + if ( gTacticalStatus.ubLastQuoteProfileNUm == WALDO && CheckFact( FACT_WALDO_MET, 0 ) == FALSE && gTacticalStatus.ubLastQuoteSaid == 0 ) + { + AddHistoryToPlayersLog( HISTORY_WALDO, 0, GetWorldTotalMin(), gWorldSectorX, gWorldSectorY ); + SetFactTrue( FACT_WALDO_MET ); + } // Remove region if ( gTalkPanel.fTextRegionOn ) diff --git a/Tactical/Dialogue Control.h b/Tactical/Dialogue Control.h index 62cce999..0408fe73 100644 --- a/Tactical/Dialogue Control.h +++ b/Tactical/Dialogue Control.h @@ -287,6 +287,7 @@ enum{ enum{ SKYRIDER_EXTERNAL_FACE =0, + WALDO_EXTERNAL_FACE, //MINER_FRED_EXTERNAL_FACE, //MINER_MATT_EXTERNAL_FACE, //MINER_OSWALD_EXTERNAL_FACE, diff --git a/Tactical/Interface Dialogue.cpp b/Tactical/Interface Dialogue.cpp index d6d6c6b0..58f1b37a 100644 --- a/Tactical/Interface Dialogue.cpp +++ b/Tactical/Interface Dialogue.cpp @@ -2402,6 +2402,7 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum case NPC_ACTION_MEDICAL_REQUESTOR_2: // at hospital case NPC_ACTION_BUY_VEHICLE_REQUESTOR: // from Dave case NPC_ACTION_KROTT_REQUESTOR: + case NPC_ACTION_WALDO_REPAIR_REQUESTOR: // Vince or Willis asks about payment? for medical attention if (ubTargetNPC != gpDestSoldier->ubProfile) { @@ -4478,6 +4479,11 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum // } break; + case NPC_ACTION_WALDO_START_REPAIRS: + // it's called after giving him money + StartHelicopterRepair( FALSE, TRUE ); + break; + default: ScreenMsg( FONT_MCOLOR_RED, MSG_TESTVERSION, L"No code support for NPC action %d", usActionCode ); break; @@ -4670,6 +4676,19 @@ void StartDialogueMessageBox( UINT8 ubProfileID, UINT16 usMessageBoxType ) swprintf( zTemp, TacticalStr[ SPARE_KROTT_PROMPT ], gMercProfiles[ubProfileID].zNickname ); DoMessageBox( MSG_BOX_BASIC_STYLE, zTemp, GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, DialogueMessageBoxCallBack, NULL ); break; + // anv: Waldo The Mechanic + case NPC_ACTION_WALDO_REPAIR_REQUESTOR: + swprintf( zTemp, TacticalStr[ STR_HELI_RR_REPAIR_PROMPT ], gMercProfiles[ubProfileID].zNickname ); + if( CheckFact(FACT_HELI_DAMAGED_CAN_START_REPAIR, 0) == TRUE ) + { + swprintf( zTemp, pHelicopterRepairRefuelStrings[ STR_HELI_RR_REPAIR_PROMPT ], gMercProfiles[ WALDO ].zNickname, CalculateHelicopterRepairCost( FALSE ), gHelicopterSettings.ubHelicopterBasicRepairTime); + } + else + { + swprintf( zTemp, pHelicopterRepairRefuelStrings[ STR_HELI_RR_REPAIR_PROMPT ], gMercProfiles[ WALDO ].zNickname, CalculateHelicopterRepairCost( TRUE ), gHelicopterSettings.ubHelicopterSeriousRepairTime ); + } + DoMessageBox( MSG_BOX_BASIC_STYLE, zTemp, GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, DialogueMessageBoxCallBack, NULL ); + break; default: break; } @@ -4953,6 +4972,16 @@ void DialogueMessageBoxCallBack( UINT8 ubExitValue ) TriggerNPCRecord( SERGEANT, 6 ); } break; + case NPC_ACTION_WALDO_REPAIR_REQUESTOR: + if ( ubExitValue == MSG_BOX_RETURN_YES ) + { + StartHelicopterRepair( FALSE, FALSE ); + } + else + { + TriggerNPCRecord( WALDO, 17 ); + } + break; case NPC_ACTION_TRIGGER_MARRY_DARYL_PROMPT: gMercProfiles[ gpSrcSoldier->ubProfile ].ubMiscFlags2 |= PROFILE_MISC_FLAG2_ASKED_BY_HICKS; if ( ubExitValue == MSG_BOX_RETURN_YES ) diff --git a/Tactical/Morale.cpp b/Tactical/Morale.cpp index eebed70e..ac42a017 100644 --- a/Tactical/Morale.cpp +++ b/Tactical/Morale.cpp @@ -1055,10 +1055,10 @@ void HourlyMoraleUpdate( void ) { // skip past ourselves and all inactive mercs if (bOtherID != bMercID && pOtherSoldier->bActive && pOtherSoldier->ubProfile != NO_PROFILE && - !(pOtherSoldier->bAssignment == IN_TRANSIT || - pOtherSoldier->flags.fMercAsleep == TRUE || - pOtherSoldier->bAssignment == ASSIGNMENT_DEAD || - pOtherSoldier->bAssignment == ASSIGNMENT_POW)) + !(pOtherSoldier->bAssignment == IN_TRANSIT || + pOtherSoldier->flags.fMercAsleep == TRUE || + pOtherSoldier->bAssignment == ASSIGNMENT_DEAD || + pOtherSoldier->bAssignment == ASSIGNMENT_POW)) { if (fSameGroupOnly) { diff --git a/Tactical/Vehicles.cpp b/Tactical/Vehicles.cpp index f5058457..a18061b4 100644 --- a/Tactical/Vehicles.cpp +++ b/Tactical/Vehicles.cpp @@ -1380,7 +1380,34 @@ BOOLEAN KillAllInVehicle( INT32 iId ) } } } + return ( TRUE ); +} +// anv: for hurting heli passengers on SAM attack +BOOLEAN HurtPassengersInHelicopter( INT32 iId ) +{ + INT32 iCounter = 0; + // find if vehicle is valid + if( VehicleIdIsValid( iId ) == FALSE ) + { + return ( FALSE ); + } + + // go through list of occupants and hurt them + for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ ) + { + if( pVehicleList[ iId ].pPassengers[ iCounter ] != NULL ) + { + if( PreRandom(100) < gHelicopterSettings.ubHelicopterPassengerHitChance ) + { + if( InjurePersonInVehicle( iId , pVehicleList[ iId ].pPassengers[ iCounter ], + gHelicopterSettings.ubHelicopterPassengerHitMinDamage + PreRandom( gHelicopterSettings.ubHelicopterPassengerHitMaxDamage - gHelicopterSettings.ubHelicopterPassengerHitMinDamage ) ) == FALSE ) + { + return( FALSE ); + } + } + } + } return ( TRUE ); } diff --git a/Tactical/Vehicles.h b/Tactical/Vehicles.h index c9d63fc5..66e81c5f 100644 --- a/Tactical/Vehicles.h +++ b/Tactical/Vehicles.h @@ -355,6 +355,9 @@ BOOLEAN KillPersonInVehicle( INT32 iId, SOLDIERTYPE *pSoldier ); // kill everyone in vehicle BOOLEAN KillAllInVehicle( INT32 iId ); +// anv: for hurting heli passengers on SAM attack +BOOLEAN HurtPassengersInHelicopter( INT32 iId ); + #ifdef JA2TESTVERSION // test vehicle stuff void VehicleTest( void ); diff --git a/Tactical/interface Dialogue.h b/Tactical/interface Dialogue.h index d456c420..2ddc0605 100644 --- a/Tactical/interface Dialogue.h +++ b/Tactical/interface Dialogue.h @@ -205,6 +205,7 @@ enum NPC_ACTION_REMOVE_DOREEN, NPC_ACTION_RESET_SHIPMENT_ARRIVAL_STUFF, // 153 Fix helicopter by next morning? + NPC_ACTION_WALDO_START_REPAIRS = 153,// anv: added this NPC_ACTION_DECIDE_ACTIVE_TERRORISTS = 154, NPC_ACTION_TRIGGER_FATHER_18_20_OR_15, NPC_ACTION_CHECK_LAST_TERRORIST_HEAD, @@ -369,6 +370,9 @@ enum NPC_ACTION_SEND_WEIGHTED_ASSAULT_TO_LOCATION, // 1st optional parm is "direness: rating NPC_ACTION_SEND_SPECIFIC_ASSAULT_TO_LOCATION, // 1st option parm is # of soldiers to send, 2nd is composition + // anv: Waldo The Mechanic + NPC_ACTION_WALDO_REPAIR_REQUESTOR, + NPC_ACTION_TURN_TO_FACE_NEAREST_MERC = 500, NPC_ACTION_TURN_TO_FACE_PROFILE_ID_0, diff --git a/TacticalAI/NPC.cpp b/TacticalAI/NPC.cpp index ae135c3e..5812fa47 100644 --- a/TacticalAI/NPC.cpp +++ b/TacticalAI/NPC.cpp @@ -52,6 +52,8 @@ #include "Soldier Profile.h" #include "BriefingRoom_Data.h" + + #include "Map Screen Helicopter.h" #ifdef JA2UB #include "Ja25_Tactical.h" @@ -1194,7 +1196,16 @@ UINT8 NPCConsiderReceivingItemFromMerc( UINT8 ubNPC, UINT8 ubMerc, OBJECTTYPE * { SetFactTrue( FACT_LARGE_AMOUNT_OF_MONEY ); } - usItemToConsider = MONEY; + + // anv: Waldo! + if ((*pObj)[0]->data.money.uiMoneyAmount >= CalculateHelicopterRepairCost( FALSE ) ) + { + SetFactTrue( FACT_GIVEN_ENOUGH_TO_REPAIR_HELI ); + } + if ((*pObj)[0]->data.money.uiMoneyAmount >= CalculateHelicopterRepairCost( TRUE ) ) + { + SetFactTrue( FACT_GIVEN_ENOUGH_TO_SERIOUSLY_REPAIR_HELI ); + } break; case WINE: case BEER: @@ -3461,6 +3472,20 @@ BOOLEAN LoadNPCInfoFromSavedGameFile( HWFILE hFile, UINT32 uiSaveGameVersion ) RefreshNPCScriptRecord( SKYRIDER, 22 ); } + // anv: + if ( uiSaveGameVersion < WALDO_CAN_REPAIR_HELICOPTER ) + { + RefreshNPCScriptRecord( WALDO, 5 ); + RefreshNPCScriptRecord( WALDO, 6 ); + RefreshNPCScriptRecord( WALDO, 7 ); + RefreshNPCScriptRecord( WALDO, 13 ); + RefreshNPCScriptRecord( WALDO, 14 ); + RefreshNPCScriptRecord( WALDO, 15 ); + RefreshNPCScriptRecord( WALDO, 16 ); + RefreshNPCScriptRecord( WALDO, 17 ); + RefreshNPCScriptRecord( WALDO, 18 ); + } + return( TRUE ); } diff --git a/Utils/ExportStrings.cpp b/Utils/ExportStrings.cpp index 35acef85..a25c0dec 100644 --- a/Utils/ExportStrings.cpp +++ b/Utils/ExportStrings.cpp @@ -173,7 +173,8 @@ bool Loc::ExportStrings() ExportSection(props, L"Repair", Loc::pRepairStrings, 0, 4); ExportSection(props, L"PreStatBuild", Loc::sPreStatBuildString, 0, 6); ExportSection(props, L"StatGain", Loc::sStatGainStrings, 0, 11); - ExportSection(props, L"HelicopterEta", Loc::pHelicopterEtaStrings, 0, 10); + ExportSection(props, L"HelicopterEta", Loc::pHelicopterEtaStrings, 0, TEXT_NUM_STR_HELI_ETA); + ExportSection(props, L"HelicopterRepair", Loc::pHelicopterRepairRefuelStrings, 0, TEXT_NUM_STR_HELI_REPAIRS); ExportSection(props, L"MapLevel", Loc::sMapLevelString, 0, 1); ExportSection(props, L"Loyal", Loc::gsLoyalString, 0, 1); ExportSection(props, L"Underground", Loc::gsUndergroundString, 0, 1); diff --git a/Utils/Text.h b/Utils/Text.h index 1e6335ad..76330c88 100644 --- a/Utils/Text.h +++ b/Utils/Text.h @@ -195,6 +195,7 @@ extern STR16 pRepairStrings[]; extern STR16 sPreStatBuildString[]; extern STR16 sStatGainStrings[]; extern STR16 pHelicopterEtaStrings[]; +extern STR16 pHelicopterRepairRefuelStrings[]; extern STR16 sMapLevelString[]; extern STR16 gsLoyalString[]; extern STR16 pMapHeliErrorString[]; @@ -617,6 +618,39 @@ enum TEXT_NUM_STR_TT }; +enum +{ + STR_HELI_ETA_TOTAL_DISTANCE, + STR_HELI_ETA_SAFE, + STR_HELI_ETA_UNSAFE, + STR_HELI_ETA_TOTAL_COST, + STR_HELI_ETA_ETA, + + STR_HELI_ETA_LOW_ON_FUEL_HOSTILE_TERRITORY, + STR_HELI_ETA_PASSENGERS, + STR_HELI_ETA_SELECT_SKYRIDER_OR_ARRIVALS, + STR_HELI_ETA_SKYRIDER, + STR_HELI_ETA_ARRIVALS, + + STR_HELI_ETA_HELI_DAMAGED_HOSTILE_TERRITORY, + STR_HELI_ETA_KICK_OUT_PASSENGERS_PROMPT, + STR_HELI_ETA_REMAINING_FUEL, + STR_HELI_ETA_DISTANCE_TO_REFUEL_SITE, + + TEXT_NUM_STR_HELI_ETA, +}; + +// anv: helicopter repairs +enum +{ + STR_HELI_RR_REPAIR_PROMPT, + STR_HELI_RR_REPAIR_IN_PROGRESS, + STR_HELI_RR_REPAIR_FINISHED, + STR_HELI_RR_REFUEL_FINISHED, + + TEXT_NUM_STR_HELI_REPAIRS, +}; + #define LARGE_STRING_LENGTH 200 #define MED_STRING_LENGTH 80 #define SMALL_STRING_LENGTH 20 @@ -1018,23 +1052,23 @@ enum PRISONER_OFFER_SURRENDER_STR, PRISONER_TALK_STR, - // sevenfm: new disarm trap dialog, new messages for wrong mines when arming - DISARM_DIALOG_DISARM, - DISARM_DIALOG_INSPECT, - DISARM_DIALOG_REMOVE_BLUEFLAG, - DISARM_DIALOG_BLOWUP, - DISARM_DIALOG_ACTIVATE_TRIPWIRE, - DISARM_DIALOG_DEACTIVATE_TRIPWIRE, - DISARM_DIALOG_REVEAL_TRIPWIRE, - ARM_MESSAGE_NO_DETONATOR, - ARM_MESSAGE_ALREADY_ARMED, - INSPECT_RESULT_SAFE, - INSPECT_RESULT_MOSTLY_SAFE, - INSPECT_RESULT_RISKY, - INSPECT_RESULT_DANGEROUS, - INSPECT_RESULT_HIGH_DANGER, - - TEXT_NUM_TACTICAL_STR, + // sevenfm: new disarm trap dialog, new messages for wrong mines when arming + DISARM_DIALOG_DISARM, + DISARM_DIALOG_INSPECT, + DISARM_DIALOG_REMOVE_BLUEFLAG, + DISARM_DIALOG_BLOWUP, + DISARM_DIALOG_ACTIVATE_TRIPWIRE, + DISARM_DIALOG_DEACTIVATE_TRIPWIRE, + DISARM_DIALOG_REVEAL_TRIPWIRE, + ARM_MESSAGE_NO_DETONATOR, + ARM_MESSAGE_ALREADY_ARMED, + INSPECT_RESULT_SAFE, + INSPECT_RESULT_MOSTLY_SAFE, + INSPECT_RESULT_RISKY, + INSPECT_RESULT_DANGEROUS, + INSPECT_RESULT_HIGH_DANGER, + + TEXT_NUM_TACTICAL_STR }; enum{ diff --git a/Utils/_ChineseText.cpp b/Utils/_ChineseText.cpp index 1674d39b..03fffd76 100644 --- a/Utils/_ChineseText.cpp +++ b/Utils/_ChineseText.cpp @@ -3304,6 +3304,17 @@ STR16 pHelicopterEtaStrings[] = L"选择Skyrider还是“着陆点”?", L"Skyrider", L"着陆点", + L"Helicopter is seriously damaged and must land in hostile territory!", // warning that the sector the helicopter is going to use for refueling is under enemy control -> + L"Helicopter will now return straight to base, do you want to drop down passengers before?" +}; + +STR16 pHelicopterRepairRefuelStrings[]= +{ + // anv: Waldo The Mechanic - prompt and notifications + L"Do you want %s to start repairs? It will cost $%d, and helicopter will be unavailable for around %d hour(s).", + L"Helicopter is currently disassembled. Wait until repairs are finished.", + L"Repairs completed. Helicopter is available again.", + L"Helicopter is fully refueled.", }; STR16 sMapLevelString[] = @@ -4105,8 +4116,11 @@ STR16 pHistoryStrings[] = L"宰掉了血猫", L"%s被干掉了", L"把一个恐怖分子的头颅给了Carmen。", + //76-80 L"Slay走了", L"干掉了%s", + L"Met Waldo - aircraft mechanic.", + L"Helicopter repairs started. Estimated time: %d hour(s).", }; STR16 pHistoryLocations[] = diff --git a/Utils/_DutchText.cpp b/Utils/_DutchText.cpp index d470d0a0..2239ffa6 100644 --- a/Utils/_DutchText.cpp +++ b/Utils/_DutchText.cpp @@ -3299,6 +3299,17 @@ STR16 pHelicopterEtaStrings[] = L"Selecteer Skyrider of Aanvoer Drop-plaats?", // L"Select Skyrider or the Arrivals Drop-off?", L"Skyrider", L"Aanvoer", // L"Arrivals", + L"Helicopter is seriously damaged and must land in hostile territory!", // warning that the sector the helicopter is going to use for refueling is under enemy control -> + L"Helicopter will now return straight to base, do you want to drop down passengers before?" +}; + +STR16 pHelicopterRepairRefuelStrings[]= +{ + // anv: Waldo The Mechanic - prompt and notifications + L"Do you want %s to start repairs? It will cost $%d, and helicopter will be unavailable for around %d hour(s).", + L"Helicopter is currently disassembled. Wait until repairs are finished.", + L"Repairs completed. Helicopter is available again.", + L"Helicopter is fully refueled.", }; STR16 sMapLevelString[] = @@ -4104,8 +4115,11 @@ STR16 pHistoryStrings[] = L"Afgeslacht door bloodcats", // ("Slaughtered bloodcats") L"%s was gedood", // ("%s was killed") L"Carmen kop v.e. terrorist gegeven", // ("Gave Carmen a terrorist's head") + //76-80 L"Slay vertrok", // ("Slay left") L"%s vermoord", // ("Killed %s") + L"Met Waldo - aircraft mechanic.", + L"Helicopter repairs started. Estimated time: %d hour(s).", }; STR16 pHistoryLocations[] = diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp index 09f08208..6dffb121 100644 --- a/Utils/_EnglishText.cpp +++ b/Utils/_EnglishText.cpp @@ -3299,10 +3299,23 @@ STR16 pHelicopterEtaStrings[] = L"Total Cost: ", // total cost of trip by helicopter L"ETA: ", // ETA is an acronym for "estimated time of arrival" L"Helicopter is low on fuel and must land in hostile territory!", // warning that the sector the helicopter is going to use for refueling is under enemy control -> - L"Passengers: ", - L"Select Skyrider or the Arrivals Drop-off?", - L"Skyrider", - L"Arrivals", + L"Passengers: ", + L"Select Skyrider or the Arrivals Drop-off?", + L"Skyrider", + L"Arrivals", + L"Helicopter is seriously damaged and must land in hostile territory!", // warning that the sector the helicopter is going to use for refueling is under enemy control -> + L"Helicopter will now return straight to base, do you want to drop down passengers before?", + L"Remaining Fuel:", + L"Dist. To Refuel Site:", +}; + +STR16 pHelicopterRepairRefuelStrings[]= +{ + // anv: Waldo The Mechanic - prompt and notifications + L"Do you want %s to start repairs? It will cost $%d, and helicopter will be unavailable for around %d hour(s).", + L"Helicopter is currently disassembled. Wait until repairs are finished.", + L"Repairs completed. Helicopter is available again.", + L"Helicopter is fully refueled.", }; STR16 sMapLevelString[] = @@ -4104,8 +4117,11 @@ STR16 pHistoryStrings[] = L"Slaughtered bloodcats", L"%s was killed", L"Gave Carmen a terrorist's head", + //76-80 L"Slay left", L"Killed %s", + L"Met Waldo - aircraft mechanic.", + L"Helicopter repairs started. Estimated time: %d hour(s).", }; STR16 pHistoryLocations[] = diff --git a/Utils/_FrenchText.cpp b/Utils/_FrenchText.cpp index 3c23788f..3279937d 100644 --- a/Utils/_FrenchText.cpp +++ b/Utils/_FrenchText.cpp @@ -3308,6 +3308,17 @@ STR16 pHelicopterEtaStrings[] = L"Sélectionner Skyrider ou l'aire d'atterrissage ?", L"Skyrider", L"Arrivée", + L"Helicopter is seriously damaged and must land in hostile territory!", // warning that the sector the helicopter is going to use for refueling is under enemy control -> + L"Helicopter will now return straight to base, do you want to drop down passengers before?" +}; + +STR16 pHelicopterRepairRefuelStrings[]= +{ + // anv: Waldo The Mechanic - prompt and notifications + L"Do you want %s to start repairs? It will cost $%d, and helicopter will be unavailable for around %d hour(s).", + L"Helicopter is currently disassembled. Wait until repairs are finished.", + L"Repairs completed. Helicopter is available again.", + L"Helicopter is fully refueled.", }; STR16 sMapLevelString[] = @@ -4112,8 +4123,11 @@ STR16 pHistoryStrings[] = L"Élimination des chats sauvages", L"%s a été tué(e)", L"Tête de terroriste donnée à Carmen", + //76-80 L"Reste Slay", L"%s a été tué(e)", + L"Met Waldo - aircraft mechanic.", + L"Helicopter repairs started. Estimated time: %d hour(s).", }; STR16 pHistoryLocations[] = diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp index 4fb1e516..96b0cc92 100644 --- a/Utils/_GermanText.cpp +++ b/Utils/_GermanText.cpp @@ -3300,6 +3300,17 @@ STR16 pHelicopterEtaStrings[] = L"Skyrider oder Absprungsort auswählen?", L"Skyrider", L"Absprung", //make sure length doesn't exceed 8 characters (used to be "Absprungsort") + L"Helicopter is seriously damaged and must land in hostile territory!", // warning that the sector the helicopter is going to use for refueling is under enemy control -> + L"Helicopter will now return straight to base, do you want to drop down passengers before?" +}; + +STR16 pHelicopterRepairRefuelStrings[]= +{ + // anv: Waldo The Mechanic - prompt and notifications + L"Do you want %s to start repairs? It will cost $%d, and helicopter will be unavailable for around %d hour(s).", + L"Helicopter is currently disassembled. Wait until repairs are finished.", + L"Repairs completed. Helicopter is available again.", + L"Helicopter is fully refueled.", }; STR16 sMapLevelString[] = @@ -4054,8 +4065,11 @@ STR16 pHistoryStrings[] = L"Bloodcats getötet", L"%s wurde getötet", L"Carmen den Kopf eines Terroristen gegeben", + //76-80 L"Slay ist gegangen", //Slay is a merc and has left the team L"%s getötet", //History log for when a merc kills an NPC or PC + L"Met Waldo - aircraft mechanic.", + L"Helicopter repairs started. Estimated time: %d hour(s).", }; STR16 pHistoryLocations[] = diff --git a/Utils/_ItalianText.cpp b/Utils/_ItalianText.cpp index a2b55d60..a74f51c7 100644 --- a/Utils/_ItalianText.cpp +++ b/Utils/_ItalianText.cpp @@ -3294,6 +3294,17 @@ STR16 pHelicopterEtaStrings[] = L"Seleziona Skyrider o gli Arrivi Drop-off?", L"Skyrider", L"Arrivi", + L"Helicopter is seriously damaged and must land in hostile territory!", // warning that the sector the helicopter is going to use for refueling is under enemy control -> + L"Helicopter will now return straight to base, do you want to drop down passengers before?" +}; + +STR16 pHelicopterRepairRefuelStrings[]= +{ + // anv: Waldo The Mechanic - prompt and notifications + L"Do you want %s to start repairs? It will cost $%d, and helicopter will be unavailable for around %d hour(s).", + L"Helicopter is currently disassembled. Wait until repairs are finished.", + L"Repairs completed. Helicopter is available again.", + L"Helicopter is fully refueled.", }; STR16 sMapLevelString[] = @@ -4094,8 +4105,11 @@ STR16 pHistoryStrings[] = L"Massacrati dai Bloodcat", L"%s è stato ucciso", L"Data a Carmen la testa di un terrorista", + //76-80 L"Massacro sinistro", L"Ucciso %s", + L"Met Waldo - aircraft mechanic.", + L"Helicopter repairs started. Estimated time: %d hour(s).", }; STR16 pHistoryLocations[] = diff --git a/Utils/_PolishText.cpp b/Utils/_PolishText.cpp index 321fba98..77885fd8 100644 --- a/Utils/_PolishText.cpp +++ b/Utils/_PolishText.cpp @@ -3306,10 +3306,22 @@ STR16 pHelicopterEtaStrings[] = L"Całkowity koszt: ", // total cost of trip by helicopter L"PCP: ", // ETA is an acronym for "estimated time of arrival" L"Helikopter ma mało paliwa i musi wylądować na terenie wroga.", // warning that the sector the helicopter is going to use for refueling is under enemy control -> - L"Pasażerowie: ", - L"Wybór Skyridera lub pasażerów?", - L"Skyrider", - L"Pasażerowie", + L"Pasażerowie: ", + L"Wybór Skyridera lub pasażerów?", + L"Skyrider", + L"Pasażerowie", + L"Helikopter został poważnie uszkodzony i musi wylądować na terenie wroga!", // warning that the sector the helicopter is going to use for refueling is under enemy control -> + L"Helikopter powróci teraz wprost do bazy, czy chcesz najpierw wysadzić pasażerów?" + +}; + +STR16 pHelicopterRepairRefuelStrings[]= +{ + // anv: Waldo The Mechanic - prompt and notifications + L"Czy chcesz aby %s rozpoczął naprawę? Będzie to kosztować %d$, a helikopter pozostanie niedostępny przez około %d godzin(y).", + L"Helikopter jest obecnie rozmontowany. Zaczekaj aż naprawa zostanie ukończona.", + L"Helikopter jest znów dostępny do lotu.", + L"Helicopter jest zatankowany do pełna.", }; STR16 sMapLevelString[] = @@ -4113,8 +4125,11 @@ STR16 pHistoryStrings[] = L"Wyrżnięto dzikie koty", L"%s zabity(ta)", L"Przekazano Carmenowi głowę terrorysty", + //76-80 L"Slay odszedł", L"Zabito: %s", + L"Spotkanie z Waldo - mechanikiem lotniczym.", + L"Rozpoczęto naprawę helikoptera. Szacowany czas: %d godzin(y).", }; STR16 pHistoryLocations[] = diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index 01aed04f..88f84408 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -3301,6 +3301,17 @@ STR16 pHelicopterEtaStrings[] = L"Выбрать вертолет или точку высадки?", L"Вертолёт", L"Высадка", + L"Helicopter is seriously damaged and must land in hostile territory!", // warning that the sector the helicopter is going to use for refueling is under enemy control -> + L"Helicopter will now return straight to base, do you want to drop down passengers before?" +}; + +STR16 pHelicopterRepairRefuelStrings[]= +{ + // anv: Waldo The Mechanic - prompt and notifications + L"Do you want %s to start repairs? It will cost $%d, and helicopter will be unavailable for around %d hour(s).", + L"Helicopter is currently disassembled. Wait until repairs are finished.", + L"Repairs completed. Helicopter is available again.", + L"Helicopter is fully refueled.", }; STR16 sMapLevelString[] = @@ -4102,8 +4113,11 @@ STR16 pHistoryStrings[] = L"Все кошки-убийцы убиты", L"%s был убит(а).", L"Отдали Кармену голову террориста.", + //76-80 L"Убийца ушёл.", L"%s убит(а) вашим отрядом.", + L"Met Waldo - aircraft mechanic.", + L"Helicopter repairs started. Estimated time: %d hour(s).", }; STR16 pHistoryLocations[] = diff --git a/Utils/_TaiwaneseText.cpp b/Utils/_TaiwaneseText.cpp index eca32101..84af2b80 100644 --- a/Utils/_TaiwaneseText.cpp +++ b/Utils/_TaiwaneseText.cpp @@ -3305,6 +3305,17 @@ STR16 pHelicopterEtaStrings[] = L"Select Skyrider or the Arrivals Drop-off?", L"Skyrider", L"Arrivals", + L"Helicopter is seriously damaged and must land in hostile territory!", // warning that the sector the helicopter is going to use for refueling is under enemy control -> + L"Helicopter will now return straight to base, do you want to drop down passengers before?" +}; + +STR16 pHelicopterRepairRefuelStrings[]= +{ + // anv: Waldo The Mechanic - prompt and notifications + L"Do you want %s to start repairs? It will cost $%d, and helicopter will be unavailable for around %d hour(s).", + L"Helicopter is currently disassembled. Wait until repairs are finished.", + L"Repairs completed. Helicopter is available again.", + L"Helicopter is fully refueled.", }; STR16 sMapLevelString[] = @@ -4108,8 +4119,11 @@ STR16 pHistoryStrings[] = L"Slaughtered bloodcats", L"%s was killed", L"Gave Carmen a terrorist's head", + //76-80 L"Slay left", L"Killed %s", + L"Met Waldo - aircraft mechanic.", + L"Helicopter repairs started. Estimated time: %d hour(s).", }; STR16 pHistoryLocations[] = diff --git a/gameloop.cpp b/gameloop.cpp index 12c19771..7cc95792 100644 --- a/gameloop.cpp +++ b/gameloop.cpp @@ -139,6 +139,8 @@ BOOLEAN InitializeGame(void) LoadItemSettings(); // Load externalised taunts settings LoadTauntsSettings(); + // Load helicopter repair settings + LoadHelicopterRepairRefuelSettings(); #ifdef JA2UB LoadGameUBOptions(); // JA25 UB