From 0efc3b72415a591a215089d32166c740c59978dc Mon Sep 17 00:00:00 2001 From: Flugente Date: Thu, 10 Jul 2014 21:19:26 +0000 Subject: [PATCH] - When ordering a merc to interrogate, one can now select what type of prisoners should be interrogated primarily. Thus one no longer has to empty the prison just to get to the one remaining officer. - Generals are now a separate prisoner type. They cannot join militia, but yield an impressive ransom. - various prisoner fixes git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7327 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- GameSettings.cpp | 23 +- GameSettings.h | 19 +- GameVersion.cpp | 18 +- GameVersion.h | 5 +- Laptop/DynamicDialogueWidget.h | 4 +- Laptop/LaptopSave.h | 4 +- Laptop/merccompare.cpp | 29 +- Laptop/merccompare.h | 5 +- Strategic/Assignments.cpp | 775 ++++++++++++++---- Strategic/Assignments.h | 8 + Strategic/Campaign Types.h | 13 +- .../Map Screen Interface TownMine Info.cpp | 6 +- Strategic/Map Screen Interface.cpp | 20 +- Strategic/Map Screen Interface.h | 19 + Strategic/strategicmap.cpp | 19 +- Tactical/Overhead.cpp | 98 +-- Tactical/Overhead.h | 8 +- Tactical/Soldier Control.cpp | 4 +- Tactical/Soldier Control.h | 8 + Tactical/Soldier Init List.cpp | 4 +- Utils/ExportStrings.cpp | 2 + Utils/PopUpBox.cpp | 54 +- Utils/Text.h | 2 + Utils/_ChineseText.cpp | 20 + Utils/_DutchText.cpp | 20 + Utils/_EnglishText.cpp | 22 +- Utils/_FrenchText.cpp | 20 + Utils/_GermanText.cpp | 20 + Utils/_ItalianText.cpp | 21 + Utils/_PolishText.cpp | 20 + Utils/_RussianText.cpp | 20 + 31 files changed, 1000 insertions(+), 310 deletions(-) diff --git a/GameSettings.cpp b/GameSettings.cpp index d47bee0e7..bf6164b27 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -1832,21 +1832,30 @@ void LoadGameExternalOptions() gGameExternalOptions.fSurrenderMultiplier = iniReader.ReadFloat("Strategic Gameplay Settings", "SURRENDER_MULTIPLIER", 5.0f, 2.0f, 10.0f); gGameExternalOptions.fPlayerCanAsktoSurrender = iniReader.ReadBoolean("Strategic Gameplay Settings","PLAYER_CAN_ASK_TO_SURRENDER", TRUE); gGameExternalOptions.ubPrisonerReturntoQueenChance = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_RETURN_TO_ARMY_CHANCE", 50, 0, 100); - gGameExternalOptions.ubPrisonerProcessDefectChance = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_DEFECT_CHANCE", 25, 0, 100); - gGameExternalOptions.ubPrisonerProcessInfoBaseChance = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_INFO_BASECHANCE", 25, 0, 100); + gGameExternalOptions.ubPrisonerProcessChance[PRISONER_INTERROGATION_DEFECT] = iniReader.ReadInteger( "Strategic Gameplay Settings", "PRISONER_DEFECT_CHANCE", 25, 0, 100 ); + gGameExternalOptions.ubPrisonerProcessChance[PRISONER_INTERROGATION_INFO] = iniReader.ReadInteger( "Strategic Gameplay Settings", "PRISONER_INFO_BASECHANCE", 25, 0, 100 ); gGameExternalOptions.ubPrisonerProcessInfoNumberChance = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_INFO_NUMBER_CHANCE", 30, 0, 100); gGameExternalOptions.ubPrisonerProcessInfoDirectionChance = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_INFO_DIRECTION_CHANCE", 40, 0, 100); - gGameExternalOptions.ubPrisonerProcessRansomBaseChance = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_RANSOM_CHANCE", 25, 0, 100); + gGameExternalOptions.ubPrisonerProcessChance[PRISONER_INTERROGATION_RANSOM] = iniReader.ReadInteger( "Strategic Gameplay Settings", "PRISONER_RANSOM_CHANCE", 25, 0, 100 ); + gGameExternalOptions.ubPrisonerProcessChance[PRISONER_INTERROGATION_NOTHING] = iniReader.ReadInteger( "Strategic Gameplay Settings", "PRISONER_NOTHING_CHANCE", 25, 0, 100 ); - gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_ADMIN] = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_INTERROGATION_POINTS_ADMIN", 80, 30, 1000); - gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_REGULAR] = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_INTERROGATION_POINTS_REGULAR", 100, gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_ADMIN], 1000); - gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_ELITE] = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_INTERROGATION_POINTS_ELITE", 100, gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_REGULAR], 1000); - gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_OFFICER] = iniReader.ReadInteger( "Strategic Gameplay Settings", "PRISONER_INTERROGATION_POINTS_OFFICER", 100, gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_ELITE], 1000 ); + gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_ADMIN] = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_INTERROGATION_POINTS_ADMIN", 30, 10, 1000); + gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_REGULAR] = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_INTERROGATION_POINTS_REGULAR", 50, gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_ADMIN], 1000); + gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_ELITE] = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_INTERROGATION_POINTS_ELITE", 80, gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_REGULAR], 1000); + gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_OFFICER] = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_INTERROGATION_POINTS_OFFICER", 150, gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_ELITE], 1000 ); + gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_GENERAL] = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_INTERROGATION_POINTS_GENERAL", 250, gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_OFFICER], 1000 ); + gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_THUG] = 100; + gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_SECRET1] = 100; + gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_SECRET2] = 100; gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_ADMIN] = iniReader.ReadInteger( "Strategic Gameplay Settings", "PRISONER_INTERROGATION_ENEMY_GENERAL_CHANCE_ADMIN", 0, 0, 100 ); gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_REGULAR] = iniReader.ReadInteger( "Strategic Gameplay Settings", "PRISONER_INTERROGATION_ENEMY_GENERAL_CHANCE_REGULAR", 1, gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_ADMIN], 100 ); gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_ELITE] = iniReader.ReadInteger( "Strategic Gameplay Settings", "PRISONER_INTERROGATION_ENEMY_GENERAL_CHANCE_ELITE", 10, gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_REGULAR], 100 ); gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_OFFICER] = iniReader.ReadInteger( "Strategic Gameplay Settings", "PRISONER_INTERROGATION_ENEMY_GENERAL_CHANCE_OFFICER", 60, gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_ELITE], 100 ); + gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_GENERAL] = iniReader.ReadInteger( "Strategic Gameplay Settings", "PRISONER_INTERROGATION_ENEMY_GENERAL_CHANCE_GENERAL", 80, gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_OFFICER], 100 ); + gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_THUG] = 0; + gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_SECRET1] = 0; + gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_SECRET2] = 0; // CHRISL: Determine how Skyrider should handle landing in enemy occupied sectors gGameExternalOptions.ubSkyriderHotLZ = iniReader.ReadInteger("Strategic Gameplay Settings", "ALLOW_SKYRIDER_HOT_LZ", 0, 0, 3); diff --git a/GameSettings.h b/GameSettings.h index bf080e161..3ccf4befe 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -213,6 +213,17 @@ enum ITEM_PROGRESS_VERY_FAST, }; +// Flugente: prisoner interrogation results +enum +{ + PRISONER_INTERROGATION_DEFECT = 0, + PRISONER_INTERROGATION_INFO, + PRISONER_INTERROGATION_RANSOM, + PRISONER_INTERROGATION_NOTHING, + + PRISONER_INTERROGATION_MAX +}; + typedef struct { BOOLEAN fGunNut; @@ -1372,13 +1383,11 @@ typedef struct FLOAT fSurrenderMultiplier; BOOLEAN fPlayerCanAsktoSurrender; UINT8 ubPrisonerReturntoQueenChance; - UINT8 ubPrisonerProcessDefectChance; - UINT8 ubPrisonerProcessInfoBaseChance; + UINT8 ubPrisonerProcessChance[PRISONER_INTERROGATION_MAX]; UINT8 ubPrisonerProcessInfoNumberChance; UINT8 ubPrisonerProcessInfoDirectionChance; - UINT8 ubPrisonerProcessRansomBaseChance; - UINT16 ubPrisonerInterrogationPoints[4]; // points needed to interrogate a prisoner of a specific type - UINT8 ubPrisonerInterrogationEnemyGeneralInfoChance[4]; // chance that when getting info from interrogation, this prisoner will tell us about general we do not yet know about + UINT16 ubPrisonerInterrogationPoints[8]; // points needed to interrogate a prisoner of a specific type + UINT8 ubPrisonerInterrogationEnemyGeneralInfoChance[8]; // chance that when getting info from interrogation, this prisoner will tell us about general we do not yet know about // Flugente: sexism/racism/etc. INT8 sMoraleModAppearance; diff --git a/GameVersion.cpp b/GameVersion.cpp index fa6dfd4e6..995630398 100644 --- a/GameVersion.cpp +++ b/GameVersion.cpp @@ -15,9 +15,9 @@ #ifdef JA2EDITOR #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.7297 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.7327 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.7297 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.7327 (Development Build)" }; #endif // ------------------------------ @@ -27,11 +27,11 @@ //DEBUG BUILD VERSION #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.7297 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.7327 (Development Build)" }; #elif defined (JA113DEMO) - CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.7297 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.7327 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Debug: v1.13.7297 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: v1.13.7327 (Development Build)" }; #endif #elif defined CRIPPLED_VERSION @@ -46,16 +46,16 @@ //RELEASE BUILD VERSION #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.7297 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.7327 (Development Build)" }; #elif defined (JA113DEMO) - CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.7297 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.7327 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Release v1.13.7297 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release v1.13.7327 (Development Build)" }; #endif #endif -CHAR8 czVersionNumber[16] = { "Build 14.06.27" }; //YY.MM.DD +CHAR8 czVersionNumber[16] = { "Build 14.07.10" }; //YY.MM.DD CHAR16 zTrackingNumber[16] = { L"Z" }; // SAVE_GAME_VERSION is defined in header, change it there diff --git a/GameVersion.h b/GameVersion.h index b9992217c..6ac50713a 100644 --- a/GameVersion.h +++ b/GameVersion.h @@ -21,7 +21,8 @@ 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 DYNAMIC_DIALOGUE 157 // Flugente: mercs have dynamic dialogue depending on nely formed opinions, an the player can interact with them +#define PRISONER_EXPANSION 158 // Flugente: more types of prisoners +#define DYNAMIC_DIALOGUE 157 // Flugente: mercs have dynamic dialogue depending on newly formed opinions, an the player can interact with them #define DYNAMIC_OPINIONS 156 // Flugente: mercs can form opinions on other people depending on their behaviour #define INCREASED_REFUEL_SITES 155 // Flugente: increased the number of helicopter refuel sites #define ENEMY_VIPS 154 // Flugente: enemy generals are placed randomly in the map @@ -76,7 +77,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 DYNAMIC_DIALOGUE +#define SAVE_GAME_VERSION PRISONER_EXPANSION //#define RUSSIANGOLD #ifdef __cplusplus diff --git a/Laptop/DynamicDialogueWidget.h b/Laptop/DynamicDialogueWidget.h index dcbb05de8..bed1db175 100644 --- a/Laptop/DynamicDialogueWidget.h +++ b/Laptop/DynamicDialogueWidget.h @@ -273,6 +273,7 @@ private: DynamicOpinionSpeechEvent mEvent; }; +// due to the way callbacks on mouse regions are handled, we need a static object that we can 'hook' on. Thus we use this singleton class IMPDialogueChooseBox_Static : public IMPDialogueChooseBox { public: @@ -287,7 +288,7 @@ public: static void SelectRegionDropDown_DropDown( MOUSE_REGION * pRegion, INT32 iReason ) { return static_cast(mpSelf)->SelectDropDownRegionCallBack( pRegion, iReason ); } MOUSE_CALLBACK - CallBackWrapper( void* pt2Object, UINT8 arg, void( *pt2Function )(MOUSE_REGION * pRegion, INT32 iReason) ) + CallBackWrapper( void* pt2Object, UINT8 arg, void( *pt2Function )(MOUSE_REGION * pRegion, INT32 iReason) ) { mpSelf = pt2Object; @@ -318,5 +319,4 @@ BOOLEAN DynamicDialogueBoxesActive( ); // used fo example when we load a game - dialogue has to start anew, so all boxes must be wiped void DestroyAllDynamicDialogueBoxes( ); - #endif diff --git a/Laptop/LaptopSave.h b/Laptop/LaptopSave.h index 66108c176..fa4ec109e 100644 --- a/Laptop/LaptopSave.h +++ b/Laptop/LaptopSave.h @@ -73,10 +73,10 @@ typedef struct //General Laptop Info BOOLEAN gfNewGameLaptop; //Is it the firs time in Laptop BOOLEAN fVisitedBookmarkAlready[20]; // have we visitied this site already? - INT32 iBookMarkList[MAX_BOOKMARKS]; + INT32 iBookMarkList[MAX_BOOKMARKS]; - INT32 iCurrentBalance; // current players balance + INT32 iCurrentBalance; // current players balance //IMP Information diff --git a/Laptop/merccompare.cpp b/Laptop/merccompare.cpp index 16d0ef7b4..b2111c9c4 100644 --- a/Laptop/merccompare.cpp +++ b/Laptop/merccompare.cpp @@ -170,28 +170,28 @@ void RenderMercCompareMain( ) } -BOOLEAN InitMercCompareDefaults( ) +void InitMercCompareDefaults( ) { VOBJECT_DESC VObjectDesc; // load the Insurance bullet graphic and add it VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; FilenameForBPP( "LAPTOP\\bullet.sti", VObjectDesc.ImageFile ); - CHECKF( AddVideoObject( &VObjectDesc, &guiMercCompareBulletImage ) ); + CHECKV( AddVideoObject( &VObjectDesc, &guiMercCompareBulletImage ) ); // load the Flower Account Box graphic and add it VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; FilenameForBPP( "LAPTOP\\BackGroundTile.sti", VObjectDesc.ImageFile ); - CHECKF( AddVideoObject( &VObjectDesc, &guiInsuranceBackGround ) ); + CHECKV( AddVideoObject( &VObjectDesc, &guiInsuranceBackGround ) ); // load the red bar on the side of the page and add it VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; FilenameForBPP( "LAPTOP\\LargeBar.sti", VObjectDesc.ImageFile ); - CHECKF( AddVideoObject( &VObjectDesc, &guiInsuranceBigRedLineImage ) ); + CHECKV( AddVideoObject( &VObjectDesc, &guiInsuranceBigRedLineImage ) ); VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; FilenameForBPP( "LAPTOP\\PressLogos.sti", VObjectDesc.ImageFile ); - CHECKF( AddVideoObject( &VObjectDesc, &guiMercCompareLogoImage ) ); + CHECKV( AddVideoObject( &VObjectDesc, &guiMercCompareLogoImage ) ); UINT16 usPosX = CAMPAIGN_HISTORY_LINK_START_X; UINT16 usPosY = CAMPAIGN_HISTORY_LINK_START_Y; @@ -204,8 +204,6 @@ BOOLEAN InitMercCompareDefaults( ) usPosY += CAMPAIGN_HISTORY_LINK_STEP_Y; } - - return(TRUE); } void DisplayMercCompareDefaults( ) @@ -298,11 +296,6 @@ void SelectMercCompareRegionCallBack( MOUSE_REGION * pRegion, INT32 iReason ) ////////////////////////// MERC COMPARE CUSTOMERS //////////////////////////////// -void GameInitMercCompareCustomers( ) -{ - -} - BOOLEAN EnterMercCompareCustomers( ) { InitMercCompareDefaults( ); @@ -388,11 +381,6 @@ BOOLEAN fMercCompareRedraw = FALSE; template<> void DropDownTemplate::SetRefresh( ) { fMercCompareRedraw = TRUE; } template<> void DropDownTemplate::SetRefresh( ) { fMercCompareRedraw = TRUE; } -void GameInitMercCompareAnalyze() -{ - -} - BOOLEAN EnterMercCompareAnalyze() { InitMercCompareDefaults( ); @@ -988,11 +976,6 @@ template<> void DropDownTemplate::SetRefr fMercCompareMatrixRedraw = TRUE; } -void GameInitMercCompareMatrix( ) -{ - -} - BOOLEAN EnterMercCompareMatrix( ) { InitMercCompareDefaults( ); @@ -1183,7 +1166,7 @@ void RenderMercCompareMatrix( ) CURSOR_WWW, MSYS_NO_CALLBACK, SelectMercCompareMatrixRegionCallBack ); MSYS_AddRegion( &gMercCompareMatrixLinkRegion[currentmouseregion] ); - // both profilenumbers are combined to a single value which cn later be reinterpreted. + // both profilenumbers are combined to a single value which can later be reinterpreted. // Note: this will fail if the profile IDs are bigger than UINT16 (currently UINT8) MSYS_SetRegionUserData( &gMercCompareMatrixLinkRegion[currentmouseregion], 0, ((pSoldierA->ubProfile << 8) | pSoldierB->ubProfile) ); gMercCompareMatrixLinkDefined[currentmouseregion] = TRUE; diff --git a/Laptop/merccompare.h b/Laptop/merccompare.h index 753e9efaf..e907c5105 100644 --- a/Laptop/merccompare.h +++ b/Laptop/merccompare.h @@ -12,20 +12,18 @@ void ExitMercCompareMain( ); void HandleMercCompareMain( ); void RenderMercCompareMain( ); -BOOLEAN InitMercCompareDefaults( ); +void InitMercCompareDefaults( ); void DisplayMercCompareDefaults( ); void RemoveMercCompareDefaults( ); void GetMercCompareText( UINT8 ubNumber, STR16 pString ); // displays a few quotes of customers -void GameInitMercCompareCustomers( ); BOOLEAN EnterMercCompareCustomers( ); void ExitMercCompareCustomers( ); void HandleMercCompareCustomers( ); void RenderMercCompareCustomers( ); // comparison of characters -void GameInitMercCompareAnalyze( ); BOOLEAN EnterMercCompareAnalyze( ); void ExitMercCompareAnalyze( ); void HandleMercCompareAnalyze( ); @@ -34,7 +32,6 @@ void RenderMercCompareAnalyze( ); BOOLEAN DisplayMercData( UINT8 usProfileA, UINT8 usProfileB ); // squad opinion overview -void GameInitMercCompareMatrix( ); BOOLEAN EnterMercCompareMatrix( ); void ExitMercCompareMatrix( ); void HandleMercCompareMatrix( ); diff --git a/Strategic/Assignments.cpp b/Strategic/Assignments.cpp index 04da2c99d..82b73a451 100644 --- a/Strategic/Assignments.cpp +++ b/Strategic/Assignments.cpp @@ -201,6 +201,9 @@ INT32 ghSnitchBox = -1; INT32 ghSnitchToggleBox = -1; INT32 ghSnitchSectorBox = -1; +// Flugente: prisoner menu +INT32 ghPrisonerBox = -1; + // the x,y position of assignment pop up in tactical INT16 gsAssignmentBoxesX, gsAssignmentBoxesY; @@ -229,6 +232,8 @@ MOUSE_REGION gSnitchMenuRegion[ MAX_SNITCH_MENU_STRING_COUNT ]; MOUSE_REGION gSnitchToggleMenuRegion[ MAX_SNITCH_TOGGLE_MENU_STRING_COUNT ]; MOUSE_REGION gSnitchSectorMenuRegion[ MAX_SNITCH_SECTOR_MENU_STRING_COUNT ]; +MOUSE_REGION gPrisonerMenuRegion[ MAX_PRISONER_MENU_STRING_COUNT ]; + MOUSE_REGION gAssignmentScreenMaskRegion; BOOLEAN fShownAssignmentMenu = FALSE; @@ -241,6 +246,9 @@ BOOLEAN fShowSnitchMenu = FALSE; BOOLEAN fShowSnitchToggleMenu = FALSE; BOOLEAN fShowSnitchSectorMenu = FALSE; +// Flugente: prisoner menu +BOOLEAN fShowPrisonerMenu = FALSE; + BOOLEAN fFirstClickInAssignmentScreenMask = FALSE; // render pre battle interface? @@ -497,6 +505,9 @@ void HandleShadingOfLinesForSnitchMenu( void ); void HandleShadingOfLinesForSnitchToggleMenu( void ); void HandleShadingOfLinesForSnitchSectorMenu( void ); +// Flugente: prisoner menu +void HandleShadingOfLinesForPrisonerMenu( void ); + // post message about contract void PostContractMessage( SOLDIERTYPE *pCharacter, INT32 iContract ); @@ -525,6 +536,9 @@ void CreateFacilityAssignmentBox( void ); void CreateSnitchBox( void ); void CreateSnitchToggleBox( void ); void CreateSnitchSectorBox( void ); + +// Flugente: prisoner menu +void CreatePrisonerBox(); /* // get how fast the person regains sleep INT8 GetRegainDueToSleepNeeded( SOLDIERTYPE *pSoldier, INT32 iRateOfReGain ); @@ -2331,8 +2345,8 @@ BOOLEAN CanCharacterSnitchInPrison( SOLDIERTYPE *pSoldier ) { SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ] ); - UINT8 tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0; - if ( GetNumberOfPrisoners(pSectorInfo, &tmp1, &tmp2, &tmp3, &tmp4) > 0 ) + INT16 aPrisoners[PRISONER_MAX] = {0}; + if ( GetNumberOfPrisoners( pSectorInfo, aPrisoners ) > 0 ) return TRUE; } } @@ -2826,14 +2840,14 @@ UINT32 CalculateInterrogationValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts ) SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ] ); - UINT8 prisonersspecial = 0, prisonerselite = 0, prisonersregular = 0, prisonersadmin = 0; - *pusMaxPts = GetNumberOfPrisoners( pSectorInfo, &prisonersspecial, &prisonerselite, &prisonersregular, &prisonersadmin ); + INT16 aPrisoners[PRISONER_MAX] = {0}; + *pusMaxPts = GetNumberOfPrisoners( pSectorInfo, aPrisoners ); // no prisoners -> no interrogation (this should not happen) if ( !*pusMaxPts ) return 0; - usInterrogationPoints = 50 + 10 * EffectiveExpLevel( pSoldier ) + EffectiveLeadership( pSoldier ); + usInterrogationPoints = 20 + 3 * EffectiveExpLevel( pSoldier ) + EffectiveLeadership( pSoldier ) / 2; // adjust for threatening value INT32 threatenvalue = CalcThreateningEffectiveness( pSoldier->ubProfile ) * gMercProfiles[pSoldier->ubProfile].usApproachFactor[2] ; @@ -2861,7 +2875,7 @@ UINT32 CalculateInterrogationValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts ) performancemodifier = min(1000, max(10, performancemodifier) ); - usInterrogationPoints = (usInterrogationPoints * performancemodifier) / (650000); + usInterrogationPoints = (usInterrogationPoints * performancemodifier) / (700000); // adjust for fatigue ReducePointsForFatigue( pSoldier, &usInterrogationPoints ); @@ -3037,14 +3051,14 @@ UINT32 CalculateSnitchInterrogationValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPt SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ] ); - UINT8 prisonersspecial = 0, prisonerselite = 0, prisonersregular = 0, prisonersadmin = 0; - *pusMaxPts = GetNumberOfPrisoners( pSectorInfo, &prisonersspecial, &prisonerselite, &prisonersregular, &prisonersadmin ); + INT16 aPrisoners[PRISONER_MAX] = {0}; + *pusMaxPts = GetNumberOfPrisoners( pSectorInfo, aPrisoners ); // no prisoners -> no interrogation (this should not happen) if ( !*pusMaxPts ) return 0; - usInterrogationPoints = 50 + 10 * EffectiveExpLevel( pSoldier ) + EffectiveLeadership( pSoldier ) + EffectiveWisdom( pSoldier ); + usInterrogationPoints = 20 + 3 * EffectiveExpLevel( pSoldier ) + EffectiveLeadership( pSoldier )/2 + EffectiveWisdom( pSoldier )/2; // no bonuses for snitch trait, as merc has to have it to take this assignment anyway if (gGameOptions.fNewTraitSystem) @@ -3065,8 +3079,6 @@ UINT32 CalculateSnitchInterrogationValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPt usInterrogationPoints *= friendlyvalue; - //usInterrogationPoints = (usInterrogationPoints * (100 + pSoldier->GetBackgroundValue(BG_PERC_INTERROGATION))) / 100; - UINT16 performancemodifier = 100; for (UINT16 cnt = 0; cnt < NUM_FACILITY_TYPES; ++cnt) { @@ -3134,12 +3146,12 @@ BOOL HandleSnitchExposition(SOLDIERTYPE *pSoldier) UINT32 uiSuspicion = 0; UINT32 uiCoverQuality = 0; SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ] ); - UINT8 prisonersspecial = 0, prisonerselite = 0, prisonersregular = 0, prisonersadmin = 0; - UINT16 numprisoners = GetNumberOfPrisoners( pSectorInfo, &prisonersspecial, &prisonerselite, &prisonersregular, &prisonersadmin ); + INT16 aPrisoners[PRISONER_MAX] = {0}; + UINT16 numprisoners = GetNumberOfPrisoners( pSectorInfo, aPrisoners ); uiCoverQuality = ( 10 * EffectiveExpLevel( pSoldier ) + 2 * EffectiveLeadership( pSoldier ) + EffectiveWisdom( pSoldier ) ) / 4; - uiSuspicion = 10 + prisonerselite + prisonersspecial; + uiSuspicion = 10 + aPrisoners[PRISONER_ELITE] + aPrisoners[PRISONER_OFFICER]; // no bonuses for snitch trait, as merc has to have it to take this assignment anyway if (gGameOptions.fNewTraitSystem) @@ -3314,11 +3326,6 @@ BOOL HandleSnitchExposition(SOLDIERTYPE *pSoldier) void MakeSoldierKnownAsMercInPrison(SOLDIERTYPE *pSoldier, INT16 sMapX, INT16 sMapY) { - //SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] ); - //UINT8 prisonersspecial = 0, prisonerselite = 0, prisonersregular = 0, prisonersadmin = 0; - //UINT16 numprisoners = GetNumberOfPrisoners( pSectorInfo, &prisonersspecial, &prisonerselite, &prisonersregular, &prisonersadmin ); - //gMercProfiles[pSoldier->ubProfile].ubExposedInSector[ SECTOR(sMapX, sMapY)] = numprisoners; - gMercProfiles[pSoldier->ubProfile].ubSnitchExposedCooldown += 24; } @@ -6519,6 +6526,10 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ ) if ( bZ ) return; + // if sector not under our control, has enemies in it, or is currently in combat mode + if ( !SectorOursAndPeaceful( sMapX, sMapY, bZ ) ) + return; + // Is there a prison in this sector? UINT16 prisonerbaselimit = 0; for (UINT16 cnt = 0; cnt < NUM_FACILITY_TYPES; ++cnt) @@ -6538,85 +6549,141 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ ) if ( !prisonerbaselimit ) return; - // Are there any prisoners in this prison? - SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] ); + // Are there any prisoners in this prison? + SECTORINFO *pSectorInfo = &(SectorInfo[SECTOR( sMapX, sMapY )]); + INT16 aPrisoners[PRISONER_MAX] = {0}; + UINT16 numprisoners = GetNumberOfPrisoners( pSectorInfo, aPrisoners ); - UINT8 prisoners[PRISONER_MAX] = {0}; - UINT16 numprisoners = GetNumberOfPrisoners( pSectorInfo, &prisoners[PRISONER_OFFICER], &prisoners[PRISONER_ELITE], &prisoners[PRISONER_REGULAR], &prisoners[PRISONER_ADMIN] ); - - // add interrogation progress from last hour and erase it in data - UINT32 interrogationpoints = pSectorInfo->uiInterrogationHundredsLeft; - pSectorInfo->uiInterrogationHundredsLeft = 0; - - // remember old interrogation points for exp distribution later - UINT32 oldinterrogationpoints = interrogationpoints; - if ( !numprisoners ) return; - // if sector not under our control, has enemies in it, or is currently in combat mode - if (!SectorOursAndPeaceful( sMapX, sMapY, bZ )) - return; + // add interrogation progress from last hour + UINT32 interrogationpoints[PRISONER_MAX] = {0}; + for ( int i = PRISONER_ADMIN; i < PRISONER_MAX; ++i ) + { + interrogationpoints[i] = pSectorInfo->uiInterrogationHundredsLeft[i]; + } - // loop over all mercs in this sector that are on the FACILITY_INTERROGATE_PRISONERS assignment and determine their interrogation progress - UINT8 numinterrogators = 0; + // loop over all mercs in this sector that are interrogating or are snitching on prisoners and determine their interrogation progress + UINT8 numinterrogators[PRISONER_MAX] = {0}; // count any interrogators found here, and sum up their interrogation values SOLDIERTYPE *pSoldier = NULL; - UINT32 uiCnt=0; - for ( uiCnt = 0, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++uiCnt, ++pSoldier) + UINT32 uiCnt = 0; + for ( uiCnt = 0, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ++uiCnt, ++pSoldier) { if( pSoldier->bActive && ( pSoldier->sSectorX == sMapX ) && ( pSoldier->sSectorY == sMapY ) && ( pSoldier->bSectorZ == bZ) ) { - if( ( pSoldier->bAssignment == FACILITY_INTERROGATE_PRISONERS ) && ( EnoughTimeOnAssignment( pSoldier ) ) && ( pSoldier->flags.fMercAsleep == FALSE ) ) + if ( !pSoldier->flags.fMercAsleep && EnoughTimeOnAssignment( pSoldier ) ) { - ++numinterrogators; - - UINT16 tmp; - interrogationpoints += CalculateInterrogationValue(pSoldier, &tmp ); - } - else if( ( pSoldier->bAssignment == FACILITY_PRISON_SNITCH ) && CanCharacterSnitchInPrison(pSoldier) && EnoughTimeOnAssignment( pSoldier ) && ( pSoldier->flags.fMercAsleep == FALSE ) ) - { - // first check if he wasn't exposed - //exposition fallout handled in HandleSnitchExposition - if( !HandleSnitchExposition(pSoldier) ) + if( pSoldier->bAssignment == FACILITY_INTERROGATE_PRISONERS ) { - ++numinterrogators; - UINT16 tmp; - interrogationpoints += CalculateSnitchInterrogationValue(pSoldier, &tmp ); + UINT32 points = CalculateInterrogationValue( pSoldier, &tmp ); + + if ( pSoldier->usSoldierFlagMask2 & SOLDIER_INTERROGATE_TROOP ) + { + ++numinterrogators[PRISONER_REGULAR]; + interrogationpoints[PRISONER_REGULAR] += points; + } + else if ( pSoldier->usSoldierFlagMask2 & SOLDIER_INTERROGATE_ELITE ) + { + ++numinterrogators[PRISONER_ELITE]; + interrogationpoints[PRISONER_ELITE] += points; + } + else if ( pSoldier->usSoldierFlagMask2 & SOLDIER_INTERROGATE_OFFICER ) + { + ++numinterrogators[PRISONER_OFFICER]; + interrogationpoints[PRISONER_OFFICER] += points; + } + else if ( pSoldier->usSoldierFlagMask2 & SOLDIER_INTERROGATE_GENERAL ) + { + ++numinterrogators[PRISONER_GENERAL]; + interrogationpoints[PRISONER_GENERAL] += points; + } + // admin is default + else + { + ++numinterrogators[PRISONER_ADMIN]; + interrogationpoints[PRISONER_ADMIN] += points; + } + } + else if( pSoldier->bAssignment == FACILITY_PRISON_SNITCH && CanCharacterSnitchInPrison(pSoldier) ) + { + // first check if he wasn't exposed + //exposition fallout handled in HandleSnitchExposition + if( !HandleSnitchExposition(pSoldier) ) + { + // as long as we cannot order snitches to target a specific prisoner class, add progress to default + ++numinterrogators[PRISONER_ADMIN]; + + UINT16 tmp; + interrogationpoints[PRISONER_ADMIN] += CalculateSnitchInterrogationValue( pSoldier, &tmp ); + } } } } } - if ( !numinterrogators ) + UINT16 sum_interrogators = 0; + UINT32 sum_points = 0; + for ( int i = PRISONER_ADMIN; i < PRISONER_MAX ; ++i) + { + sum_interrogators += numinterrogators[i]; + sum_points += interrogationpoints[i]; + } + + if ( !sum_interrogators || !sum_points ) return; // we first interrogate admins, then troops, then elites, then specials (once we figure out who those are :-) ) // higher quality prisoners require more effort, but yield better rewards - UINT8 interrogatedprisoners[PRISONER_MAX] = {0}; + INT16 interrogatedprisoners[PRISONER_MAX] = {0}; + // use up interrogation points for (int i = PRISONER_ADMIN; i < PRISONER_MAX; ++i) { - while ( prisoners[i] && interrogationpoints >= gGameExternalOptions.ubPrisonerInterrogationPoints[i] ) + while ( aPrisoners[i] > 0 && interrogationpoints[i] >= gGameExternalOptions.ubPrisonerInterrogationPoints[i] ) { - interrogationpoints -= gGameExternalOptions.ubPrisonerInterrogationPoints[i]; - --prisoners[i]; + interrogationpoints[i] -= gGameExternalOptions.ubPrisonerInterrogationPoints[i]; + --aPrisoners[i]; ++interrogatedprisoners[i]; } + + // if no prisoners are left, move points to next type, or lose them + if ( aPrisoners[i] <= 0 ) + { + if ( i == PRISONER_MAX -1 ) + interrogationpoints[0] += interrogationpoints[i]; + else + interrogationpoints[i + 1] += interrogationpoints[i]; + + interrogationpoints[i] = 0; + } } + + // do first type again, as it might have gotten enough points again + while ( aPrisoners[PRISONER_ADMIN] > 0 && interrogationpoints[PRISONER_ADMIN] >= gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_ADMIN] ) + { + interrogationpoints[PRISONER_ADMIN] -= gGameExternalOptions.ubPrisonerInterrogationPoints[PRISONER_ADMIN]; + --aPrisoners[PRISONER_ADMIN]; + ++interrogatedprisoners[PRISONER_ADMIN]; + } + + UINT16 prisonersinterrogated = 0; - UINT16 prisonersinterrogated = interrogatedprisoners[PRISONER_ADMIN] + interrogatedprisoners[PRISONER_REGULAR] + interrogatedprisoners[PRISONER_ELITE] + interrogatedprisoners[PRISONER_OFFICER]; - - // the part that gets left behind is saved to the map (but not the part that gets lost due to there not being enough prisoners) - UINT32 losthundreds = interrogationpoints / 100; - pSectorInfo->uiInterrogationHundredsLeft = (UINT8)(interrogationpoints - losthundreds * 100); + // save what points are left + for ( int i = PRISONER_ADMIN; i < PRISONER_MAX; ++i ) + { + prisonersinterrogated += interrogatedprisoners[i]; + pSectorInfo->uiInterrogationHundredsLeft[i] = min(255, interrogationpoints[i]); + } if ( !prisonersinterrogated ) return; - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_PROCESSED], interrogatedprisoners[PRISONER_OFFICER], interrogatedprisoners[PRISONER_ELITE], interrogatedprisoners[PRISONER_REGULAR], interrogatedprisoners[PRISONER_ADMIN] ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_PROCESSED], + interrogatedprisoners[PRISONER_OFFICER], interrogatedprisoners[PRISONER_ELITE], interrogatedprisoners[PRISONER_REGULAR], interrogatedprisoners[PRISONER_ADMIN] ); UINT16 turnedmilitia[PRISONER_MAX] = { 0 }; UINT32 revealedpositions = 0; @@ -6624,18 +6691,60 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ ) UINT32 ransommoney = 0; for ( UINT32 i = 0; i < prisonersinterrogated; ++i ) { + // what kind of a prisoner is this? + UINT8 prisonertype = PRISONER_THUG; + if ( i < interrogatedprisoners[PRISONER_ADMIN] ) + prisonertype = PRISONER_ADMIN; + else if ( i < interrogatedprisoners[PRISONER_ADMIN] + interrogatedprisoners[PRISONER_REGULAR] ) + prisonertype = PRISONER_REGULAR; + else if ( i < interrogatedprisoners[PRISONER_ADMIN] + interrogatedprisoners[PRISONER_REGULAR] + interrogatedprisoners[PRISONER_ELITE] ) + prisonertype = PRISONER_ELITE; + else if ( i < interrogatedprisoners[PRISONER_ADMIN] + interrogatedprisoners[PRISONER_REGULAR] + interrogatedprisoners[PRISONER_ELITE] + interrogatedprisoners[PRISONER_OFFICER] ) + prisonertype = PRISONER_OFFICER; + else if ( i < interrogatedprisoners[PRISONER_ADMIN] + interrogatedprisoners[PRISONER_REGULAR] + interrogatedprisoners[PRISONER_ELITE] + interrogatedprisoners[PRISONER_OFFICER] + interrogatedprisoners[PRISONER_GENERAL] ) + prisonertype = PRISONER_GENERAL; + + // get base chance + UINT8 chances[PRISONER_INTERROGATION_MAX] = {0}; + for ( int j = PRISONER_INTERROGATION_DEFECT; j < PRISONER_INTERROGATION_MAX; ++j ) + chances[j] = gGameExternalOptions.ubPrisonerProcessChance[j]; + + // depending on prisoner type, the chances for different results may differ + // for example, generals cannot be recruited + if ( prisonertype == PRISONER_GENERAL ) + chances[PRISONER_INTERROGATION_DEFECT] = 0; + + if ( prisonertype == PRISONER_THUG ) + chances[PRISONER_INTERROGATION_DEFECT] = 0; + + // for normalisation, get sum of chances + UINT16 sumchance = 0; + for ( int j = PRISONER_INTERROGATION_DEFECT; j < PRISONER_INTERROGATION_MAX; ++j ) + sumchance += chances[j]; + + // if nothing is set, 100% chance to get nothing + if ( !sumchance ) + { + chances[PRISONER_INTERROGATION_NOTHING] = 100; + sumchance = 100; + } + + // normalize to 100 + for ( int j = PRISONER_INTERROGATION_DEFECT; j < PRISONER_INTERROGATION_MAX; ++j ) + chances[j] = (chances[j] * 100) / sumchance; + // we determine what happens to the prisoners UINT8 result = Random( 100 ); // chance that prisoner will work on our side as militia - if ( result < gGameExternalOptions.ubPrisonerProcessDefectChance ) + if ( result < chances[PRISONER_INTERROGATION_DEFECT] ) { // troops are converted to militia, but there is a chance that they will be demoted in the process - if ( i >= interrogatedprisoners[PRISONER_ADMIN] + interrogatedprisoners[PRISONER_REGULAR] + interrogatedprisoners[PRISONER_ELITE] && Chance( 80 ) ) + if ( prisonertype >= PRISONER_OFFICER && Chance( 80 ) ) ++turnedmilitia[PRISONER_OFFICER]; - if ( i >= interrogatedprisoners[PRISONER_ADMIN] + interrogatedprisoners[PRISONER_REGULAR] && Chance( 80 ) ) + else if ( prisonertype >= PRISONER_ELITE && Chance( 80 ) ) ++turnedmilitia[PRISONER_ELITE]; - else if ( i >= interrogatedprisoners[PRISONER_ADMIN] && Chance( 80 ) ) + else if ( prisonertype >= PRISONER_REGULAR && Chance( 80 ) ) ++turnedmilitia[PRISONER_REGULAR]; else ++turnedmilitia[PRISONER_ADMIN]; @@ -6644,26 +6753,26 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ ) continue; } // chance that prisoner will give us random info about enemy positions - else if ( result < gGameExternalOptions.ubPrisonerProcessDefectChance + gGameExternalOptions.ubPrisonerProcessInfoBaseChance ) + else if ( result < chances[PRISONER_INTERROGATION_DEFECT] + chances[PRISONER_INTERROGATION_INFO] ) { // if this guy is an elite or a special prisoner, there is a chance he might tell us about high-value targets! BOOLEAN fGetInfoOnHiddenVIPs = FALSE; - if ( i < interrogatedprisoners[PRISONER_ADMIN] ) + if ( prisonertype == PRISONER_ADMIN ) { if ( Chance( gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_ADMIN] ) ) fGetInfoOnHiddenVIPs = TRUE; } - else if ( i < interrogatedprisoners[PRISONER_REGULAR] ) + else if ( prisonertype == PRISONER_REGULAR ) { if ( Chance( gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_REGULAR] ) ) fGetInfoOnHiddenVIPs = TRUE; } - else if ( i < interrogatedprisoners[PRISONER_ELITE] ) + else if ( prisonertype == PRISONER_ELITE ) { if ( Chance( gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_ELITE] ) ) fGetInfoOnHiddenVIPs = TRUE; } - else if ( i < interrogatedprisoners[PRISONER_OFFICER] ) + else if ( prisonertype == PRISONER_OFFICER ) { if ( Chance( gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_OFFICER] ) ) fGetInfoOnHiddenVIPs = TRUE; @@ -6723,10 +6832,22 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ ) } } // chance prisoner will grant us ransom money - else if ( result < gGameExternalOptions.ubPrisonerProcessDefectChance + gGameExternalOptions.ubPrisonerProcessInfoBaseChance + gGameExternalOptions.ubPrisonerProcessRansomBaseChance ) + else if ( result < chances[PRISONER_INTERROGATION_DEFECT] + chances[PRISONER_INTERROGATION_INFO] + chances[PRISONER_INTERROGATION_RANSOM] ) { - ransommoney += (Random(5) + 1) * 100; + UINT32 ransom = (1 + Random( 5 )) * 100; + // different prisoners give a different amount of ransom + if ( prisonertype == PRISONER_ADMIN ) + ransom *= 0.5f; + else if ( prisonertype == PRISONER_OFFICER ) + ransom *= 3; + else if ( prisonertype == PRISONER_GENERAL ) + ransom *= 10; + else if ( prisonertype == PRISONER_THUG ) + ransom *= 0.7f; + + ransommoney += ransom; + ++ransomscollected; } // we have to let him go without any benefits @@ -6759,35 +6880,47 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ ) ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_RANSOM], ransomscollected ); } - - // remove interrogated prisoners... - ChangeNumberOfPrisoners( pSectorInfo, -interrogatedprisoners[PRISONER_OFFICER], -interrogatedprisoners[PRISONER_ELITE], -interrogatedprisoners[PRISONER_REGULAR], -interrogatedprisoners[PRISONER_ADMIN], sMapX, sMapY ); - + // give experience rewards to the interrogators - // total experience to share - if ( !oldinterrogationpoints ) - return; - - FLOAT totalexp = (FLOAT) (1 * prisonersinterrogated); - FLOAT expratio = totalexp / (oldinterrogationpoints * 33); // TODO + // exp gained depends on prisoner type + FLOAT totalexp = (FLOAT)(4 * interrogatedprisoners[PRISONER_ADMIN] + 5 * interrogatedprisoners[PRISONER_REGULAR] + 7 * interrogatedprisoners[PRISONER_ELITE] + 10 * interrogatedprisoners[PRISONER_OFFICER]); + FLOAT expratio = totalexp / sum_points; // award experience - for ( uiCnt = 0, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++uiCnt, ++pSoldier) + for ( uiCnt = 0, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ++uiCnt, ++pSoldier) { if( pSoldier->bActive && ( pSoldier->sSectorX == sMapX ) && ( pSoldier->sSectorY == sMapY ) && ( pSoldier->bSectorZ == bZ) ) { - // if he's training teammates in this stat - if( ( pSoldier->bAssignment == FACILITY_INTERROGATE_PRISONERS ) && ( EnoughTimeOnAssignment( pSoldier ) ) && ( pSoldier->flags.fMercAsleep == FALSE ) ) + if ( !pSoldier->flags.fMercAsleep && EnoughTimeOnAssignment( pSoldier ) ) { - UINT16 tmp; - UINT16 exppoints = (UINT16)(expratio * CalculateInterrogationValue(pSoldier, &tmp ) ); + if ( (pSoldier->bAssignment == FACILITY_INTERROGATE_PRISONERS) ) + { + UINT16 tmp; + UINT16 exppoints = (UINT16)(expratio * CalculateInterrogationValue(pSoldier, &tmp ) ); - StatChange( pSoldier, LDRAMT, exppoints, TRUE ); - StatChange( pSoldier, WISDOMAMT, max(0, exppoints - 1), TRUE ); - StatChange( pSoldier, EXPERAMT, max(0, exppoints - 2), TRUE ); + StatChange( pSoldier, LDRAMT, exppoints, TRUE ); + StatChange( pSoldier, WISDOMAMT, max(0, exppoints - 1), TRUE ); + StatChange( pSoldier, EXPERAMT, max(0, exppoints - 2), TRUE ); + } + else if( pSoldier->bAssignment == FACILITY_PRISON_SNITCH && CanCharacterSnitchInPrison(pSoldier) ) + { + UINT16 tmp; + UINT16 exppoints = (UINT16)(expratio * CalculateSnitchInterrogationValue( pSoldier, &tmp )); + + // no leaership gain, but higher wisdom and experience gain + StatChange( pSoldier, WISDOMAMT, max( 0, exppoints ), TRUE ); + StatChange( pSoldier, EXPERAMT, max( 0, exppoints - 1 ), TRUE ); + } } } } + + // remove interrogated prisoners... + // careful: we have to change the sign here! + for ( int i = PRISONER_ADMIN; i < PRISONER_MAX; ++i ) + interrogatedprisoners[i] = -interrogatedprisoners[i]; + + ChangeNumberOfPrisoners( pSectorInfo, interrogatedprisoners ); } // Flugente: prisons can riot if there aren't enough guards around @@ -6824,8 +6957,8 @@ void HandlePrison( INT16 sMapX, INT16 sMapY, INT8 bZ ) // Are there any prisoners in this prison? SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] ); - UINT8 prisonersofficer = 0, prisonerselite = 0, prisonersregular = 0, prisonersadmin = 0; - UINT16 numprisoners = GetNumberOfPrisoners( pSectorInfo, &prisonersofficer, &prisonerselite, &prisonersregular, &prisonersadmin ); + INT16 aPrisoners[PRISONER_MAX] = {0}; + UINT16 numprisoners = GetNumberOfPrisoners( pSectorInfo, aPrisoners ); if ( !numprisoners ) return; @@ -6837,10 +6970,9 @@ void HandlePrison( INT16 sMapX, INT16 sMapY, INT8 bZ ) if( StrategicMap[ sMapX + sMapY * MAP_WORLD_X ].fEnemyControlled == TRUE ) { // add enemies - pSectorInfo->ubNumTroops = min(255, pSectorInfo->ubNumTroops + prisonersregular); - pSectorInfo->ubNumElites = min(255, pSectorInfo->ubNumElites + prisonerselite + prisonersofficer); - pSectorInfo->ubNumAdmins = min(255, pSectorInfo->ubNumAdmins + prisonersadmin); - pSectorInfo->ubNumTanks = min(255, pSectorInfo->ubNumTanks ); + pSectorInfo->ubNumTroops = min( 255, pSectorInfo->ubNumTroops + aPrisoners[PRISONER_REGULAR] ); + pSectorInfo->ubNumElites = min( 255, pSectorInfo->ubNumElites + aPrisoners[PRISONER_ELITE] + aPrisoners[PRISONER_OFFICER] ); + pSectorInfo->ubNumAdmins = min( 255, pSectorInfo->ubNumAdmins + aPrisoners[PRISONER_ADMIN] ); // all prisoners are free, reduce count! DeleteAllPrisoners(pSectorInfo); @@ -6870,7 +7002,12 @@ void HandlePrison( INT16 sMapX, INT16 sMapY, INT8 bZ ) fBeginRiot = TRUE; // we now have to determine the combined strength of the prisoners - UINT32 prisonerriotvalue = 200 * prisonersofficer + 125 * prisonerselite + 100 * prisonersregular + 75 * prisonersadmin; + UINT32 prisonerriotvalue = 100 * aPrisoners[PRISONER_THUG] + + 200 * aPrisoners[PRISONER_GENERAL] + + 200 * aPrisoners[PRISONER_OFFICER] + + 125 * aPrisoners[PRISONER_ELITE] + + 100 * aPrisoners[PRISONER_REGULAR] + + 75 * aPrisoners[PRISONER_ADMIN]; if ( prisonerriotvalue > prisonguardvalue ) { @@ -6885,19 +7022,21 @@ void HandlePrison( INT16 sMapX, INT16 sMapY, INT8 bZ ) prisonertoguardratio = (FLOAT)(prisonerriotvalue / prisonguardvalue); // in a riot, prisoners escape and are added to the sector as enemies. Not all might escape - the worse the prisoner/guard ratio, the more escape - INT16 escapedadmins = min( Random( prisonersadmin * prisonertoguardratio ), prisonersadmin ); - INT16 escapedregulars = min( Random( prisonersregular * prisonertoguardratio ), prisonersregular ); - INT16 escapedelites = min( Random( prisonerselite * prisonertoguardratio ), prisonerselite ); - INT16 escapedofficers = min( Random( prisonersofficer * prisonertoguardratio ), prisonersofficer ); + INT16 escapedprisoners[PRISONER_MAX] = {0}; + for (int i = PRISONER_ADMIN; i < PRISONER_MAX; ++i ) + escapedprisoners[i] = min( Random( aPrisoners[i] * prisonertoguardratio ), aPrisoners[i] ); // add enemies - pSectorInfo->ubNumTroops = min( 512, pSectorInfo->ubNumTroops + escapedregulars ); - pSectorInfo->ubNumElites = min( 512, pSectorInfo->ubNumElites + escapedelites + escapedofficers ); - pSectorInfo->ubNumAdmins = min( 512, pSectorInfo->ubNumAdmins + escapedadmins ); - pSectorInfo->ubNumTanks = min( 512, pSectorInfo->ubNumTanks ); + pSectorInfo->ubNumTroops = min( 512, pSectorInfo->ubNumTroops + escapedprisoners[PRISONER_REGULAR] + escapedprisoners[PRISONER_THUG] ); + pSectorInfo->ubNumElites = min( 512, pSectorInfo->ubNumElites + escapedprisoners[PRISONER_ELITE] + escapedprisoners[PRISONER_OFFICER] + escapedprisoners[PRISONER_GENERAL] ); + pSectorInfo->ubNumAdmins = min( 512, pSectorInfo->ubNumAdmins + escapedprisoners[PRISONER_ADMIN] ); // reduce prisoner count! - ChangeNumberOfPrisoners( pSectorInfo, -escapedofficers, -escapedelites, -escapedregulars, -escapedadmins, sMapX, sMapY ); + // we have to change the sign + for ( int i = PRISONER_ADMIN; i < PRISONER_MAX; ++i ) + escapedprisoners[i] = -escapedprisoners[i]; + + ChangeNumberOfPrisoners( pSectorInfo, escapedprisoners ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_RIOT], wSectorName ); } @@ -8853,6 +8992,9 @@ void HandleShadingOfLinesForAssignmentMenus( void ) HandleShadingOfLinesForSnitchMenu( ); HandleShadingOfLinesForSnitchToggleMenu( ); HandleShadingOfLinesForSnitchSectorMenu( ); + + // Flugente: prisoner menu + HandleShadingOfLinesForPrisonerMenu(); } @@ -8925,6 +9067,9 @@ void DetermineWhichAssignmentMenusCanBeShown( void ) CreateDestroyMouseRegionsForSnitchToggleMenu( ); CreateDestroyMouseRegionsForSnitchSectorMenu( ); + // Flugente: prisoner menu + CreateDestroyMouseRegionsForPrisonerMenu(); + // hide all boxes being shown if ( IsBoxShown( ghEpcBox ) ) { @@ -9001,6 +9146,14 @@ void DetermineWhichAssignmentMenusCanBeShown( void ) fTeamPanelDirty = TRUE; gfRenderPBInterface = TRUE; } + + if ( IsBoxShown( ghPrisonerBox ) ) + { + HideBox( ghPrisonerBox ); + fTeamPanelDirty = TRUE; + gfRenderPBInterface = TRUE; + } + // do we really want ot hide this box? if( fShowContractMenu == FALSE ) { @@ -9036,6 +9189,7 @@ void DetermineWhichAssignmentMenusCanBeShown( void ) CreateDestroyMouseRegionsForSnitchMenu( ); CreateDestroyMouseRegionsForSnitchToggleMenu( ); CreateDestroyMouseRegionsForSnitchSectorMenu( ); + CreateDestroyMouseRegionsForPrisonerMenu( ); if( ( ( Menptr[gCharactersList[ bSelectedInfoChar ].usSolID].stats.bLife == 0 )||( Menptr[gCharactersList[bSelectedInfoChar].usSolID].bAssignment == ASSIGNMENT_POW ) ) && ( (guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) ) ) { @@ -9240,6 +9394,26 @@ void DetermineWhichAssignmentMenusCanBeShown( void ) // SetRenderFlags(RENDER_FLAG_FULL); } } + + // Flugente: prisoner menu + if ( fShowPrisonerMenu ) + { + HandleShadingOfLinesForPrisonerMenu( ); + ShowBox( ghPrisonerBox ); + } + else + { + if ( IsBoxShown( ghPrisonerBox ) ) + { + HideBox( ghPrisonerBox ); + fTeamPanelDirty = TRUE; + fMapPanelDirty = TRUE; + gfRenderPBInterface = TRUE; + // SetRenderFlags(RENDER_FLAG_FULL); + } + } + + CreateDestroyMouseRegionsForPrisonerMenu( ); } @@ -9338,6 +9512,7 @@ void ClearScreenMaskForMapScreenExit( void ) CreateDestroyMouseRegionsForSnitchMenu( ); CreateDestroyMouseRegionsForSnitchToggleMenu( ); CreateDestroyMouseRegionsForSnitchSectorMenu( ); + CreateDestroyMouseRegionsForPrisonerMenu( ); } void CreateDestroyMouseRegions( void ) @@ -10273,6 +10448,98 @@ void CreateDestroyMouseRegionsForSnitchSectorMenu( void ) } } +void CreateDestroyMouseRegionsForPrisonerMenu( void ) +{ + static BOOLEAN fCreated = FALSE; + UINT32 iCounter = 0; + INT32 iFontHeight = 0; + INT32 iBoxXPosition = 0; + INT32 iBoxYPosition = 0; + SGPPoint pPosition; + INT32 iBoxWidth = 0; + SGPRect pDimensions; + + // will create/destroy mouse regions for the map screen assignment main menu + + if ( (fShowPrisonerMenu == TRUE) && (fCreated == FALSE) ) + { + // grab height of font + iFontHeight = GetLineSpace( ghPrisonerBox ) + GetFontHeight( GetBoxFont( ghPrisonerBox ) ); + + // get x.y position of box + GetBoxPosition( ghPrisonerBox, &pPosition ); + + // grab box x and y position + iBoxXPosition = pPosition.iX; + iBoxYPosition = pPosition.iY; + + // get dimensions..mostly for width + GetBoxSize( ghPrisonerBox, &pDimensions ); + SetBoxSecondaryShade( ghPrisonerBox, FONT_YELLOW ); + + // get width + iBoxWidth = pDimensions.iRight; + + SetCurrentBox( ghPrisonerBox ); + + // define regions + for ( iCounter = 0; iCounter < GetNumberOfLinesOfTextInBox( ghPrisonerBox ); ++iCounter ) + { + // add mouse region for each line of text..and set user data + MSYS_DefineRegion( &gPrisonerMenuRegion[iCounter], (INT16)(iBoxXPosition), (INT16)(iBoxYPosition + GetTopMarginSize( ghPrisonerBox ) + (iFontHeight)* iCounter), (INT16)(iBoxXPosition + iBoxWidth), (INT16)(iBoxYPosition + GetTopMarginSize( ghPrisonerBox ) + (iFontHeight)* (iCounter + 1)), MSYS_PRIORITY_HIGHEST - 3, + MSYS_NO_CURSOR, PrisonerMenuMvtCallBack, PrisonerMenuBtnCallback ); + + // set user defines + MSYS_SetRegionUserData( &gPrisonerMenuRegion[iCounter], 0, iCounter ); + + // Add tooltip for region + if ( wcscmp( pPrisonerMenuDescStrings[iCounter], L"" ) != 0 ) + { + SetRegionFastHelpText( &gPrisonerMenuRegion[iCounter], pPrisonerMenuDescStrings[iCounter] ); + } + } + + // created + fCreated = TRUE; + + // unhighlight all strings in box + UnHighLightBox( ghPrisonerBox ); + + } + else if ( (!fShowAssignmentMenu || !fShowFacilityMenu || !fShowFacilityAssignmentMenu || !fShowPrisonerMenu) && (fCreated == TRUE) ) + { + // destroy + for ( iCounter = 0; iCounter < GetNumberOfLinesOfTextInBox( ghPrisonerBox ); ++iCounter ) + { + MSYS_RemoveRegion( &gPrisonerMenuRegion[iCounter] ); + } + + // stop showing training menu + if ( !fShowAssignmentMenu || !fShowFacilityMenu || !fShowFacilityAssignmentMenu ) + { + fShowPrisonerMenu = FALSE; + } + + RestorePopUpBoxes( ); + + fMapPanelDirty = TRUE; + fCharacterInfoPanelDirty = TRUE; + fTeamPanelDirty = TRUE; + fMapScreenBottomDirty = TRUE; + HideBox( ghPrisonerBox ); + SetRenderFlags( RENDER_FLAG_FULL ); + + // not created + fCreated = FALSE; + + if ( fShowAssignmentMenu ) + { + // remove highlight on the parent menu + UnHighLightBox( ghAssignmentBox ); + } + } +} + void AssignmentMenuMvtCallBack(MOUSE_REGION * pRegion, INT32 iReason ) { // mvt callback handler for assignment region @@ -10999,6 +11266,29 @@ void SnitchSectorMenuMvtCallBack(MOUSE_REGION * pRegion, INT32 iReason ) } } +void PrisonerMenuMvtCallBack( MOUSE_REGION * pRegion, INT32 iReason ) +{ + // mvt callback handler for assignment region + INT32 iValue = MSYS_GetRegionUserData( pRegion, 0 ); + + if ( iReason & MSYS_CALLBACK_REASON_GAIN_MOUSE ) + { + // highlight string + + // do not highlight current balance + if ( !GetBoxShadeFlag( ghPrisonerBox, iValue ) ) + { + // get the string line handle + HighLightBoxLine( ghPrisonerBox, iValue ); + } + } + else if ( iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) + { + // unhighlight all strings in box + UnHighLightBox( ghPrisonerBox ); + } +} + void TrainingMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) { // btn callback handler for assignment region @@ -11474,6 +11764,71 @@ void SnitchSectorMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) } } +void PrisonerMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) +{ + INT32 iValue = MSYS_GetRegionUserData( pRegion, 0 ); + SOLDIERTYPE* pSoldier = GetSelectedAssignSoldier( FALSE ); + + if ( iReason & MSYS_CALLBACK_REASON_LBUTTON_UP ) + { + if ( iValue == PRISONER_MENU_CANCEL ) + { + // cancel, leave + // stop showing menu + fShowPrisonerMenu = FALSE; + + // unhighlight the training box + UnHighLightBox( ghPrisonerBox ); + } + else if ( iValue == PRISONER_MENU_ADMIN ) + { + pSoldier->usSoldierFlagMask2 &= ~SOLDIER_INTERROGATE_ALL; + pSoldier->usSoldierFlagMask2 |= SOLDIER_INTERROGATE_ADMIN; + fShowPrisonerMenu = FALSE; + fShowAssignmentMenu = FALSE; + giAssignHighLine = -1; + } + else if ( iValue == PRISONER_MENU_TROOP ) + { + pSoldier->usSoldierFlagMask2 &= ~SOLDIER_INTERROGATE_ALL; + pSoldier->usSoldierFlagMask2 |= SOLDIER_INTERROGATE_TROOP; + fShowPrisonerMenu = FALSE; + fShowAssignmentMenu = FALSE; + giAssignHighLine = -1; + } + else if ( iValue == PRISONER_MENU_ELITE ) + { + pSoldier->usSoldierFlagMask2 &= ~SOLDIER_INTERROGATE_ALL; + pSoldier->usSoldierFlagMask2 |= SOLDIER_INTERROGATE_ELITE; + fShowPrisonerMenu = FALSE; + fShowAssignmentMenu = FALSE; + giAssignHighLine = -1; + } + else if ( iValue == PRISONER_MENU_OFFICER ) + { + pSoldier->usSoldierFlagMask2 &= ~SOLDIER_INTERROGATE_ALL; + pSoldier->usSoldierFlagMask2 |= SOLDIER_INTERROGATE_OFFICER; + fShowPrisonerMenu = FALSE; + fShowAssignmentMenu = FALSE; + giAssignHighLine = -1; + } + else if ( iValue == PRISONER_MENU_GENERAL ) + { + pSoldier->usSoldierFlagMask2 &= ~SOLDIER_INTERROGATE_ALL; + pSoldier->usSoldierFlagMask2 |= SOLDIER_INTERROGATE_GENERAL; + fShowPrisonerMenu = FALSE; + fShowAssignmentMenu = FALSE; + giAssignHighLine = -1; + } + + // rerender tactical stuff + gfRenderPBInterface = TRUE; + + fTeamPanelDirty = TRUE; + fMapScreenBottomDirty = TRUE; + } +} + void SetShowAllMenus( BOOLEAN fShowMenu ) { //fShowAssignmentMenu = fShowMenu; @@ -11511,16 +11866,17 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) { case( EPC_MENU_ON_DUTY ): if( CanCharacterOnDuty( pSoldier ) ) - { - // put character on a team - fShowSquadMenu = TRUE; - fShowTrainingMenu = FALSE; - fShowVehicleMenu = FALSE; - fShowFacilityMenu = FALSE; // HEADROCK HAM 3.6: Facility Menu - fTeamPanelDirty = TRUE; - fMapScreenBottomDirty = TRUE; + { + // put character on a team + fShowSquadMenu = TRUE; + fShowTrainingMenu = FALSE; + fShowVehicleMenu = FALSE; + fShowFacilityMenu = FALSE; // HEADROCK HAM 3.6: Facility Menu + fShowPrisonerMenu = FALSE; + fTeamPanelDirty = TRUE; + fMapScreenBottomDirty = TRUE; - } + } break; case( EPC_MENU_PATIENT ): // can character doctor? @@ -11653,18 +12009,19 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) switch( iValue ) { case( ASSIGN_MENU_ON_DUTY ): - if( CanCharacterOnDuty( pSoldier ) ) - { - // put character on a team - fShowSquadMenu = TRUE; - fShowTrainingMenu = FALSE; - fShowVehicleMenu = FALSE; - fShowFacilityMenu = FALSE; // HEADROCK HAM 3.6: Facility Menu - fTeamPanelDirty = TRUE; - fMapScreenBottomDirty = TRUE; - fShowRepairMenu = FALSE; - fShowMoveItemMenu = FALSE; - } + if( CanCharacterOnDuty( pSoldier ) ) + { + // put character on a team + fShowSquadMenu = TRUE; + fShowTrainingMenu = FALSE; + fShowVehicleMenu = FALSE; + fShowFacilityMenu = FALSE; // HEADROCK HAM 3.6: Facility Menu + fShowPrisonerMenu = FALSE; + fTeamPanelDirty = TRUE; + fMapScreenBottomDirty = TRUE; + fShowRepairMenu = FALSE; + fShowMoveItemMenu = FALSE; + } break; case( ASSIGN_MENU_DOCTOR ): @@ -11844,6 +12201,7 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) fShowTrainingMenu = FALSE; fShowVehicleMenu = FALSE; fShowFacilityMenu = FALSE; // HEADROCK HAM 3.6: Facility Menu + fShowPrisonerMenu = FALSE; fShowMoveItemMenu = FALSE; fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; @@ -11922,6 +12280,7 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) fShowTrainingMenu = FALSE; fShowMoveItemMenu = FALSE; fShowFacilityMenu = FALSE; + fShowPrisonerMenu = FALSE; fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; @@ -11937,6 +12296,7 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) fShowRepairMenu = FALSE; fShowMoveItemMenu = FALSE; fShowFacilityMenu = FALSE; // HEADROCK HAM 3.6: Facility Menu + fShowPrisonerMenu = FALSE; fShowSnitchMenu = FALSE; fTeamPanelDirty = TRUE; @@ -11952,6 +12312,7 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) fShowTrainingMenu = FALSE; fShowVehicleMenu = FALSE; fShowFacilityMenu = FALSE; // HEADROCK HAM 3.6: Facility Menu + fShowPrisonerMenu = FALSE; //fShownAssignmentMenu = FALSE; fShowRepairMenu = FALSE; fShownContractMenu = FALSE; @@ -11992,9 +12353,10 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) fShowRepairMenu = FALSE; fShowMoveItemMenu = FALSE; fShowFacilityMenu = TRUE; // HEADROCK HAM 3.6: Facility Menu + fShowPrisonerMenu = FALSE; fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; - + if( DisplayFacilityMenu( pSoldier ) ) { fShowFacilityMenu = TRUE; @@ -12483,9 +12845,8 @@ void CreateSnitchToggleBox() // set current box to this one SetCurrentBox( ghSnitchToggleBox ); - // add strings for box - for(uiCounter=0; uiCounter < MAX_SNITCH_TOGGLE_MENU_STRING_COUNT; uiCounter++) + for(uiCounter=0; uiCounter < MAX_SNITCH_TOGGLE_MENU_STRING_COUNT; ++uiCounter) { AddMonoString(&hStringHandle, pSnitchToggleMenuStrings[uiCounter]); @@ -12579,6 +12940,72 @@ void CreateSnitchSectorBox() DetermineBoxPositions( ); } +void CreatePrisonerBox( ) +{ + UINT32 hStringHandle; + UINT32 uiCounter; + + // will create attribute pop up menu for mapscreen assignments + PrisonerPosition.iX = OrigPrisonerPosition.iX; + + PrisonerPosition.iX = FacilityAssignmentPosition.iX + 80; + + if ( giBoxY != 0 ) + { + PrisonerPosition.iY = giBoxY + (ASSIGN_MENU_FACILITY * GetFontHeight( MAP_SCREEN_FONT )); + } + + // create basic box + CreatePopUpBox( &ghPrisonerBox, PrisonerDimensions, PrisonerPosition, (POPUP_BOX_FLAG_CLIP_TEXT | POPUP_BOX_FLAG_CENTER_TEXT | POPUP_BOX_FLAG_RESIZE) ); + + // which buffer will box render to + SetBoxBuffer( ghPrisonerBox, FRAME_BUFFER ); + + // border type? + SetBorderType( ghPrisonerBox, guiPOPUPBORDERS ); + + // background texture + SetBackGroundSurface( ghPrisonerBox, guiPOPUPTEX ); + + // margin sizes + SetMargins( ghPrisonerBox, 6, 6, 4, 4 ); + + // space between lines + SetLineSpace( ghPrisonerBox, 2 ); + + // set current box to this one + SetCurrentBox( ghPrisonerBox ); + + // add strings for box + for ( uiCounter = 0; uiCounter < MAX_PRISONER_MENU_STRING_COUNT; ++uiCounter ) + { + AddMonoString( &hStringHandle, pPrisonerMenuStrings[uiCounter] ); + + // make sure it is unhighlighted + UnHighLightLine( hStringHandle ); + } + + // set font type + SetBoxFont( ghPrisonerBox, MAP_SCREEN_FONT ); + + // set highlight color + SetBoxHighLight( ghPrisonerBox, FONT_WHITE ); + + // unhighlighted color + SetBoxForeground( ghPrisonerBox, FONT_LTGREEN ); + + // background color + SetBoxBackground( ghPrisonerBox, FONT_BLACK ); + + // shaded color..for darkened text + SetBoxShade( ghPrisonerBox, FONT_GRAY7 ); + + // resize box to text + ResizeBoxToText( ghPrisonerBox ); + + DetermineBoxPositions( ); +} + void CreateContractBox( SOLDIERTYPE *pCharacter ) { UINT32 hStringHandle; @@ -13013,6 +13440,8 @@ BOOLEAN CreateDestroyAssignmentPopUpBoxes( void ) CreateSnitchBox( ); CreateSnitchToggleBox( ); CreateSnitchSectorBox( ); + // Flugente: prisoner menu + CreatePrisonerBox( ); UpdateMapScreenAssignmentPositions( ); fCreated = TRUE; @@ -13064,6 +13493,9 @@ BOOLEAN CreateDestroyAssignmentPopUpBoxes( void ) RemoveBox(ghSnitchSectorBox); ghSnitchSectorBox = -1; + RemoveBox( ghPrisonerBox ); + ghPrisonerBox = -1; + fCreated = FALSE; gfIgnoreScrolling = FALSE; RebuildCurrentSquad( ); @@ -13081,8 +13513,7 @@ void DetermineBoxPositions( void ) SGPPoint pNewPoint; SGPRect pDimensions; SOLDIERTYPE *pSoldier = NULL; - - + if( ( fShowAssignmentMenu == FALSE ) || ( ghAssignmentBox == -1 ) ) { return; @@ -13116,7 +13547,6 @@ void DetermineBoxPositions( void ) GetBoxSize( ghAssignmentBox, &pDimensions ); } - // hang it right beside the assignment/EPC box menu pNewPoint.iX = pPoint.iX + pDimensions.iRight; pNewPoint.iY = pPoint.iY; @@ -13222,9 +13652,31 @@ void DetermineBoxPositions( void ) } } - return; -} + if ( fShowPrisonerMenu && (ghPrisonerBox != -1) ) + { + // this should be next to the facility assignemtn menu, so get the coordinates for that + if ( (fShowFacilityAssignmentMenu == TRUE) && (ghFacilityAssignmentBox != -1) ) + { + GetBoxPosition( ghFacilityAssignmentBox, &pPoint ); + GetBoxSize( ghFacilityAssignmentBox, &pDimensions ); + pNewPoint.iX = pPoint.iX + pDimensions.iRight; + } + + pNewPoint.iY += ((GetFontHeight( MAP_SCREEN_FONT ) + 2) * ASSIGN_MENU_FACILITY); + + SetBoxPosition( ghPrisonerBox, pNewPoint ); + PrisonerPosition.iX = pNewPoint.iX; + PrisonerPosition.iY = pNewPoint.iY; + OrigPrisonerPosition.iY = pNewPoint.iY; + OrigPrisonerPosition.iX = pNewPoint.iX; + + ResizeBoxToText( ghPrisonerBox ); + + GetBoxSize( ghPrisonerBox, &pDimensions ); + GetBoxPosition( ghPrisonerBox, &pPoint ); + } +} void SetTacticalPopUpAssignmentBoxXY( void ) @@ -14444,6 +14896,9 @@ void SetSoldierAssignment( SOLDIERTYPE *pSoldier, INT8 bAssignment, INT32 iParam MakeSoldierKnownAsMercInPrison( pSoldier, pSoldier->sSectorX, pSoldier->sSectorY ); ChangeSoldiersAssignment( pSoldier, FACILITY_INTERROGATE_PRISONERS ); AssignMercToAMovementGroup( pSoldier ); + + fShowPrisonerMenu = TRUE; + DetermineBoxPositions( ); } break; case( FACILITY_PRISON_SNITCH ): @@ -15084,20 +15539,53 @@ void HandleShadingOfLinesForSnitchToggleMenu( void ) ShadeStringInBox( ghSnitchToggleBox, SNITCH_MENU_MISBEHAVIOUR_ON ); UnShadeStringInBox( ghSnitchToggleBox, SNITCH_MENU_MISBEHAVIOUR_OFF ); } - return; +} + +void HandleShadingOfLinesForPrisonerMenu( void ) +{ + // check if valid + if ( !fShowPrisonerMenu || (ghPrisonerBox == -1) ) + return; + + SOLDIERTYPE* pSoldier = GetSelectedAssignSoldier( FALSE ); + + UnShadeStringInBox( ghPrisonerBox, PRISONER_MENU_ADMIN ); + UnShadeStringInBox( ghPrisonerBox, PRISONER_MENU_TROOP ); + UnShadeStringInBox( ghPrisonerBox, PRISONER_MENU_ELITE ); + UnShadeStringInBox( ghPrisonerBox, PRISONER_MENU_OFFICER ); + UnShadeStringInBox( ghPrisonerBox, PRISONER_MENU_GENERAL ); + + if ( pSoldier->usSoldierFlagMask2 & SOLDIER_INTERROGATE_ADMIN ) + { + ShadeStringInBox( ghPrisonerBox, PRISONER_MENU_ADMIN ); + } + else if ( pSoldier->usSoldierFlagMask2 & SOLDIER_INTERROGATE_TROOP ) + { + ShadeStringInBox( ghPrisonerBox, PRISONER_MENU_TROOP ); + } + else if ( pSoldier->usSoldierFlagMask2 & SOLDIER_INTERROGATE_ELITE ) + { + ShadeStringInBox( ghPrisonerBox, PRISONER_MENU_ELITE ); + } + else if ( pSoldier->usSoldierFlagMask2 & SOLDIER_INTERROGATE_OFFICER ) + { + ShadeStringInBox( ghPrisonerBox, PRISONER_MENU_OFFICER ); + } + else if ( pSoldier->usSoldierFlagMask2 & SOLDIER_INTERROGATE_GENERAL ) + { + ShadeStringInBox( ghPrisonerBox, PRISONER_MENU_GENERAL ); + } } void HandleShadingOfLinesForSnitchSectorMenu( void ) { - SOLDIERTYPE *pSoldier = NULL; - // check if valid if( ( fShowSnitchSectorMenu == FALSE ) || ( ghSnitchSectorBox == - 1 ) ) { return; } - pSoldier = GetSelectedAssignSoldier( FALSE ); + SOLDIERTYPE *pSoldier = GetSelectedAssignSoldier( FALSE ); if( !CanCharacterSpreadPropaganda(pSoldier) ) { @@ -15108,8 +15596,6 @@ void HandleShadingOfLinesForSnitchSectorMenu( void ) { ShadeStringInBox( ghSnitchSectorBox, SNITCH_MENU_SECTOR_GATHER_RUMOURS ); } - - return; } /*void ResetAssignmentsForAllSoldiersInSectorWhoAreTrainingTown( SOLDIERTYPE *pSoldier ) @@ -19608,6 +20094,9 @@ void FacilityAssignmentMenuBtnCallback ( MOUSE_REGION * pRegion, INT32 iReason ) case FAC_INTERROGATE_PRISONERS: MakeSoldierKnownAsMercInPrison( pSoldier, pSoldier->sSectorX, pSoldier->sSectorY ); ChangeSoldiersAssignment( pSoldier, FACILITY_INTERROGATE_PRISONERS ); + fShowAssignmentMenu = TRUE; + fShowPrisonerMenu = TRUE; + DetermineBoxPositions( ); break; case FAC_PRISON_SNITCH: ChangeSoldiersAssignment( pSoldier, FACILITY_PRISON_SNITCH ); diff --git a/Strategic/Assignments.h b/Strategic/Assignments.h index 2ae2a1915..e3b1b379d 100644 --- a/Strategic/Assignments.h +++ b/Strategic/Assignments.h @@ -275,6 +275,9 @@ extern INT32 ghSnitchBox; extern INT32 ghSnitchToggleBox; extern INT32 ghSnitchSectorBox; +// Flugente: prisoner menu +extern INT32 ghPrisonerBox; + extern MOUSE_REGION gAssignmentScreenMaskRegion; @@ -356,6 +359,11 @@ void CreateDestroyMouseRegionsForSnitchSectorMenu( void ); void SnitchSectorMenuMvtCallBack(MOUSE_REGION * pRegion, INT32 iReason ); void SnitchSectorMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ); +// Flugente: prisoner menu +void CreateDestroyMouseRegionsForPrisonerMenu(); +void PrisonerMenuMvtCallBack( MOUSE_REGION * pRegion, INT32 iReason ); +void PrisonerMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ); + // contract menu void CreateDestroyMouseRegionsForContractMenu( void ); void ContractMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ); diff --git a/Strategic/Campaign Types.h b/Strategic/Campaign Types.h index 83de0b2a0..29ced08ce 100644 --- a/Strategic/Campaign Types.h +++ b/Strategic/Campaign Types.h @@ -425,6 +425,11 @@ typedef enum PRISONER_REGULAR, PRISONER_ELITE, PRISONER_OFFICER, + + PRISONER_GENERAL, // generals can be captured too, interogating them gives special rewards + PRISONER_THUG, // captured enemies not affiliated to the army fall into this category + PRISONER_SECRET1, // tbA + PRISONER_SECRET2, // tbA PRISONER_MAX, } PrisonerType; @@ -495,15 +500,15 @@ typedef struct SECTORINFO BOOLEAN fCampaignSector; #endif - UINT8 uiNumberOfPrisonersOfWar[PRISONER_MAX]; - UINT8 uiInterrogationHundredsLeft; + UINT8 uiNumberOfPrisonersOfWar[PRISONER_MAX]; // TODO: PRISONER_MAX got expanded - Varaiblen werden falsch ausgelesen!!! + UINT8 uiInterrogationHundredsLeft[PRISONER_MAX]; UINT32 uiTimeAIArtillerywasOrdered; // Flugente: updated every time an artillery strike is ordered from the militia UINT8 ubNumTanks; UINT8 ubTanksInBattle; - INT8 bPadding[ 27 ]; + INT8 bPadding[ 20 ]; }SECTORINFO; @@ -545,7 +550,7 @@ typedef struct UNDERGROUND_SECTORINFO UINT8 ubNumTanks; UINT8 ubTanksInBattle; - INT8 bPadding[30]; + INT8 bPadding[26]; //no padding left! }UNDERGROUND_SECTORINFO; diff --git a/Strategic/Map Screen Interface TownMine Info.cpp b/Strategic/Map Screen Interface TownMine Info.cpp index 77b00ab51..6131f24bc 100644 --- a/Strategic/Map Screen Interface TownMine Info.cpp +++ b/Strategic/Map Screen Interface TownMine Info.cpp @@ -434,8 +434,8 @@ void AddTextToTownBox( void ) } // Flugente: if this is a prison we control, display number of prisoners here - UINT8 prisoners[PRISONER_MAX] = { 0 }; - UINT16 numprisoners = GetNumberOfPrisoners( &(SectorInfo[SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY )]), &prisoners[PRISONER_OFFICER], &prisoners[PRISONER_ELITE], &prisoners[PRISONER_REGULAR], &prisoners[PRISONER_ADMIN] ); + INT16 aPrisoners[PRISONER_MAX] = {0}; + UINT16 numprisoners = GetNumberOfPrisoners( &(SectorInfo[SECTOR( bCurrentTownMineSectorX, bCurrentTownMineSectorY )]), aPrisoners ); if ( numprisoners ) { // determine prison capacity @@ -457,7 +457,7 @@ void AddTextToTownBox( void ) // prisoners swprintf( wString, L"%s:", pwTownInfoStrings[13] ); AddMonoString( &hStringHandle, wString ); - swprintf( wString, L"%d/%d - %dA %dR %dE %dO", numprisoners, capacity, prisoners[PRISONER_ADMIN], prisoners[PRISONER_REGULAR], prisoners[PRISONER_ELITE], prisoners[PRISONER_OFFICER] ); + swprintf( wString, L"%d/%d - %dA %dR %dE %dO %dG", numprisoners, capacity, aPrisoners[PRISONER_ADMIN], aPrisoners[PRISONER_REGULAR], aPrisoners[PRISONER_ELITE], aPrisoners[PRISONER_OFFICER], aPrisoners[PRISONER_GENERAL] ); AddSecondColumnMonoString( &hStringHandle, wString ); } } diff --git a/Strategic/Map Screen Interface.cpp b/Strategic/Map Screen Interface.cpp index 70012811c..926ab2780 100644 --- a/Strategic/Map Screen Interface.cpp +++ b/Strategic/Map Screen Interface.cpp @@ -349,6 +349,9 @@ SGPRect SnitchToggleDimensions={0,0,80,80}; SGPPoint SnitchSectorPosition={320,150}; SGPRect SnitchSectorDimensions={0,0,80,80}; +SGPPoint PrisonerPosition = {320, 150}; +SGPRect PrisonerDimensions = {0, 0, 80, 80}; + //lal SGPPoint MilitiaControlPosition={120,150}; SGPRect MilitiaControlDimensions={0,0,100,95}; @@ -377,6 +380,8 @@ SGPPoint OrigSnitchPosition={160,150}; SGPPoint OrigSnitchTogglePosition={320,150}; SGPPoint OrigSnitchSectorPosition={320,150}; +SGPPoint OrigPrisonerPosition = {320, 150}; + SQUAD_NAMES SquadNames[20]; //extern BOOLEAN fMapExitDueToMessageBox; @@ -939,6 +944,10 @@ void RestoreBackgroundForAssignmentGlowRegionList( void ) ForceUpDateOfBox( ghSnitchSectorBox ); } } + else if ( fShowPrisonerMenu ) + { + ForceUpDateOfBox( ghPrisonerBox ); + } } if( fDisableDueToBattleRoster ) @@ -959,9 +968,6 @@ void RestoreBackgroundForAssignmentGlowRegionList( void ) // set old to current iOldAssignmentLine = giAssignHighLine; } - - // leave - return; } void RestoreBackgroundForDestinationGlowRegionList( void ) @@ -2336,7 +2342,13 @@ void UpdateMapScreenAssignmentPositions( void ) SetBoxPosition( ghFacilityAssignmentBox, pPoint ); } - return; + if ( fShowPrisonerMenu ) + { + GetBoxPosition( ghPrisonerBox, &pPoint ); + pPoint.iY = giBoxY + (GetFontHeight( MAP_SCREEN_FONT ) + 2) * ASSIGN_MENU_FACILITY; + + SetBoxPosition( ghPrisonerBox, pPoint ); + } } diff --git a/Strategic/Map Screen Interface.h b/Strategic/Map Screen Interface.h index 5291eb561..06d2397e1 100644 --- a/Strategic/Map Screen Interface.h +++ b/Strategic/Map Screen Interface.h @@ -158,6 +158,17 @@ enum { MAX_SNITCH_SECTOR_MENU_STRING_COUNT, }; +// Flugente: prisoner menu defines +enum { + PRISONER_MENU_ADMIN = 0, + PRISONER_MENU_TROOP, + PRISONER_MENU_ELITE, + PRISONER_MENU_OFFICER, + PRISONER_MENU_GENERAL, + PRISONER_MENU_CANCEL, + MAX_PRISONER_MENU_STRING_COUNT, +}; + // training assignment menu defines enum { TRAIN_MENU_SELF, @@ -305,6 +316,9 @@ extern BOOLEAN fShowSnitchMenu; extern BOOLEAN fShowSnitchToggleMenu; extern BOOLEAN fShowSnitchSectorMenu; +// Flugente: prisoner menu +extern BOOLEAN fShowPrisonerMenu; + extern BOOLEAN fFirstTimeInMapScreen; extern BOOLEAN fLockOutMapScreenInterface; @@ -365,6 +379,9 @@ extern SGPRect SnitchToggleDimensions; extern SGPPoint SnitchSectorPosition; extern SGPRect SnitchSectorDimensions; +extern SGPPoint PrisonerPosition; +extern SGPRect PrisonerDimensions; + extern SGPPoint MilitiaControlPosition; //lal extern SGPRect MilitiaControlDimensions; @@ -385,6 +402,8 @@ extern SGPPoint OrigSnitchPosition; extern SGPPoint OrigSnitchTogglePosition; extern SGPPoint OrigSnitchSectorPosition; +extern SGPPoint OrigPrisonerPosition; + // disble team info panel due to showing of battle roster extern BOOLEAN fDisableDueToBattleRoster; diff --git a/Strategic/strategicmap.cpp b/Strategic/strategicmap.cpp index 0b52d12e8..f7ef9c1e6 100644 --- a/Strategic/strategicmap.cpp +++ b/Strategic/strategicmap.cpp @@ -5403,13 +5403,26 @@ BOOLEAN LoadStrategicInfoFromSavedFile( HWFILE hFile ) StrategicMap[i].usFlags = 0; } } - + // Load the Sector Info - for (int sectorID = 0; sectorID <= 255; ++ sectorID) { + for (int sectorID = 0; sectorID <= 255; ++sectorID) + { FileRead( hFile, &SectorInfo[sectorID], sizeof( SECTORINFO ), &uiNumBytesRead ); - if( uiNumBytesRead != sizeof( SECTORINFO )) { + if( uiNumBytesRead != sizeof( SECTORINFO )) + { return(FALSE); } + + // Flugente: changes in SECTORINFO require a weird-looking remapping + if ( guiCurrentSaveGameVersion < PRISONER_EXPANSION ) + { + SectorInfo[sectorID].uiNumberOfPrisonersOfWar[PRISONER_GENERAL] = 0; + SectorInfo[sectorID].uiNumberOfPrisonersOfWar[PRISONER_THUG] = 0; + SectorInfo[sectorID].uiNumberOfPrisonersOfWar[PRISONER_SECRET1] = 0; + SectorInfo[sectorID].uiNumberOfPrisonersOfWar[PRISONER_SECRET2] = 0; + SectorInfo[sectorID].ubNumTanks = SectorInfo[sectorID].uiInterrogationHundredsLeft[PRISONER_GENERAL]; + SectorInfo[sectorID].ubTanksInBattle = SectorInfo[sectorID].uiInterrogationHundredsLeft[PRISONER_THUG]; + } } // uiSize = sizeof( SECTORINFO ) * 256; // FileRead( hFile, SectorInfo, uiSize, &uiNumBytesRead ); diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp index 5e1b7f464..c823b9de2 100644 --- a/Tactical/Overhead.cpp +++ b/Tactical/Overhead.cpp @@ -6693,10 +6693,7 @@ BOOLEAN GetPlayerControlledPrisonList( std::vector& arSectorIDVector ) extern INT32 giReinforcementPool; // we cannot simply move all prisoners of a sector. It might be a prison we are already using, so we would move all inmates, not just the new ones -UINT16 gusPrisonersOfficer = 0; -UINT16 gusPrisonersElite = 0; -UINT16 gusPrisonersRegular = 0; -UINT16 gusPrisonersAdmin = 0; +INT16 gsNumPrisoner[PRISONER_MAX] = {0}; void PrisonerMessageBoxCallBack( UINT8 ubExitValue ) { @@ -6727,7 +6724,9 @@ void PrisonerMessageBoxCallBack( UINT8 ubExitValue ) } BOOLEAN success = FALSE; - UINT16 prisonerstobemoved = gusPrisonersOfficer + gusPrisonersElite + gusPrisonersRegular + gusPrisonersAdmin; + INT16 prisonerstobemoved = 0; + for ( int i = PRISONER_ADMIN; i < PRISONER_MAX; ++i ) + prisonerstobemoved += gsNumPrisoner[i]; if ( usSectorID > 0 ) { @@ -6737,7 +6736,7 @@ void PrisonerMessageBoxCallBack( UINT8 ubExitValue ) { success = TRUE; - ChangeNumberOfPrisoners( pPrisonSectorInfo, gusPrisonersOfficer, gusPrisonersElite, gusPrisonersRegular, gusPrisonersAdmin ); + ChangeNumberOfPrisoners( pPrisonSectorInfo, gsNumPrisoner ); CHAR16 wString[64]; GetShortSectorString( SECTORX( usSectorID ), SECTORY( usSectorID ), wString ); @@ -6745,10 +6744,8 @@ void PrisonerMessageBoxCallBack( UINT8 ubExitValue ) } } - gusPrisonersOfficer = 0; - gusPrisonersElite = 0; - gusPrisonersRegular = 0; - gusPrisonersAdmin = 0; + for ( int i = PRISONER_ADMIN; i < PRISONER_MAX; ++i ) + gsNumPrisoner[i] = 0; if ( !success ) { @@ -6760,13 +6757,10 @@ void PrisonerMessageBoxCallBack( UINT8 ubExitValue ) void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) { - SOLDIERTYPE *pTeamSoldier; - INT32 cnt = 0; - UINT16 ubNumPrisoners = 0; - UINT16 ubNumPrisonerAdmin = 0; - UINT16 ubNumPrisonerTroop = 0; - UINT16 ubNumPrisonerElite = 0; - UINT16 ubNumPrisonerOfficer = 0; + SOLDIERTYPE* pTeamSoldier; + INT32 cnt = 0; + UINT16 ubNumPrisoners = 0; + INT16 sNumPrisoner[PRISONER_MAX] = {0}; // Check if the battle is won! // Loop through all mercs and make go @@ -6781,18 +6775,18 @@ void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) // if we arrive here and the guy has lifepoints < OKLIFE, something is very odd... better take him prisoner and remove him anyway //if ( pTeamSoldier->stats.bLife > OKLIFE && pTeamSoldier->stats.bLife != 0 ) { - // officers are 'special' prisoners... - if ( pTeamSoldier->usSoldierFlagMask & SOLDIER_ENEMY_OFFICER ) - { - ++ubNumPrisonerOfficer; - } + // officers and generals are 'special' prisoners... + if ( pTeamSoldier->usSoldierFlagMask & SOLDIER_VIP ) + ++sNumPrisoner[PRISONER_GENERAL]; + else if ( pTeamSoldier->usSoldierFlagMask & SOLDIER_ENEMY_OFFICER ) + ++sNumPrisoner[PRISONER_OFFICER]; else { switch ( pTeamSoldier->ubSoldierClass ) { - case SOLDIER_CLASS_ADMINISTRATOR: ++ubNumPrisonerAdmin; break; - case SOLDIER_CLASS_ARMY: ++ubNumPrisonerTroop; break; - case SOLDIER_CLASS_ELITE: ++ubNumPrisonerElite; break; + case SOLDIER_CLASS_ADMINISTRATOR: ++sNumPrisoner[PRISONER_ADMIN]; break; + case SOLDIER_CLASS_ARMY: ++sNumPrisoner[PRISONER_REGULAR]; break; + case SOLDIER_CLASS_ELITE: ++sNumPrisoner[PRISONER_ELITE]; break; default: // if none of the above classes, ignore this one continue; @@ -6802,9 +6796,7 @@ void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) // Flugente: VIPs if ( pTeamSoldier->usSoldierFlagMask & SOLDIER_VIP ) - { DeleteVIP( pTeamSoldier->sSectorX, pTeamSoldier->sSectorY ); - } // Flugente: campaign stats gCurrentIncident.AddStat( pTeamSoldier, CAMPAIGNHISTORY_TYPE_PRISONER ); @@ -6911,10 +6903,8 @@ void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) } // remember all prisoners... - gusPrisonersOfficer = ubNumPrisonerOfficer; - gusPrisonersElite = ubNumPrisonerElite; - gusPrisonersRegular = ubNumPrisonerTroop; - gusPrisonersAdmin = ubNumPrisonerAdmin; + for ( int i = PRISONER_ADMIN; i < PRISONER_MAX; ++i ) + gsNumPrisoner[i] = sNumPrisoner[i]; DoMessageBox( MSG_BOX_BASIC_MEDIUM_BUTTONS, TacticalStr[ PRISONER_DECIDE_STR ], GAME_SCREEN, MSG_BOX_FLAG_GENERIC_EIGHT_BUTTONS, PrisonerMessageBoxCallBack, NULL ); } @@ -10637,52 +10627,54 @@ BOOLEAN IsProfileInUse(UINT8 usTeam, INT8 aType, UINT16 aNr) return FALSE; } -UINT16 GetNumberOfPrisoners( SECTORINFO *pSectorInfo, UINT8* aOfficer, UINT8* apElite, UINT8* apRegular, UINT8* apAdmin ) +UINT16 GetNumberOfPrisoners( SECTORINFO *pSectorInfo, INT16 aPrisoners[] ) { if ( !pSectorInfo ) return 0; - *aOfficer = pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_OFFICER]; - *apElite = pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ELITE]; - *apRegular = pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_REGULAR]; - *apAdmin = pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ADMIN]; + UINT16 sum = 0; + for ( int i = PRISONER_ADMIN; i < PRISONER_MAX; ++i ) + { + aPrisoners[i] = pSectorInfo->uiNumberOfPrisonersOfWar[i]; - return (UINT16)(pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_OFFICER] + pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ELITE] + pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_REGULAR] + pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ADMIN]); + sum += pSectorInfo->uiNumberOfPrisonersOfWar[i]; + } + + return sum; } -UINT16 GetNumberOfPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo, UINT8* aOfficer, UINT8* apElite, UINT8* apRegular, UINT8* apAdmin ) +UINT16 GetNumberOfPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo, INT16 aPrisoners[] ) { if ( !pSectorInfo ) return 0; - *aOfficer = pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_OFFICER]; - *apElite = pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ELITE]; - *apRegular = pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_REGULAR]; - *apAdmin = pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ADMIN]; + UINT16 sum = 0; + for ( int i = PRISONER_ADMIN; i < PRISONER_MAX; ++i ) + { + aPrisoners[i] = pSectorInfo->uiNumberOfPrisonersOfWar[i]; - return (UINT16)(pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_OFFICER] + pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ELITE] + pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_REGULAR] + pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ADMIN]); + sum += pSectorInfo->uiNumberOfPrisonersOfWar[i]; + } + + return sum; } -void ChangeNumberOfPrisoners( SECTORINFO *pSectorInfo, INT16 aOfficer, INT16 aElite, INT16 aRegular, INT16 aAdmin, INT16 sX, INT16 sY ) +void ChangeNumberOfPrisoners( SECTORINFO *pSectorInfo, INT16 aPrisoners[] ) { if ( !pSectorInfo ) return; - pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_OFFICER] = max(0, min(255, pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_OFFICER] + aOfficer ) ); - pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ELITE] = max(0, min(255, pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ELITE] + aElite) ); - pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_REGULAR] = max(0, min(255, pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_REGULAR] + aRegular) ); - pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ADMIN] = max(0, min(255, pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ADMIN] + aAdmin) ); + for ( int i = PRISONER_ADMIN; i < PRISONER_MAX; ++i ) + pSectorInfo->uiNumberOfPrisonersOfWar[i] = max( 0, min( 255, pSectorInfo->uiNumberOfPrisonersOfWar[i] + aPrisoners[i] ) ); } -void ChangeNumberOfPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo, INT16 aOfficer, INT16 aElite, INT16 aRegular, INT16 aAdmin ) +void ChangeNumberOfPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo, INT16 aPrisoners[] ) { if ( !pSectorInfo ) return; - pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_OFFICER] = max(0, min(255, pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_OFFICER] + aOfficer ) ); - pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ELITE] = max(0, min(255, pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ELITE] + aElite) ); - pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_REGULAR] = max(0, min(255, pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_REGULAR] + aRegular) ); - pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ADMIN] = max(0, min(255, pSectorInfo->uiNumberOfPrisonersOfWar[PRISONER_ADMIN] + aAdmin) ); + for ( int i = PRISONER_ADMIN; i < PRISONER_MAX; ++i ) + pSectorInfo->uiNumberOfPrisonersOfWar[i] = max( 0, min( 255, pSectorInfo->uiNumberOfPrisonersOfWar[i] + aPrisoners[i] ) ); } void DeleteAllPrisoners( SECTORINFO *pSectorInfo ) diff --git a/Tactical/Overhead.h b/Tactical/Overhead.h index a127df052..0d2b180f1 100644 --- a/Tactical/Overhead.h +++ b/Tactical/Overhead.h @@ -373,11 +373,11 @@ BOOLEAN AllowedToStealFromTeamMate( UINT8 aAccessorID, UINT8 aTargetID ); BOOLEAN IsProfileInUse(UINT8 usTeam, INT8 aType, UINT16 aNr); // Flugente: functions altering a sector's prisoners -UINT16 GetNumberOfPrisoners( SECTORINFO *pSectorInfo, UINT8* aOfficer, UINT8* apElite, UINT8* apRegular, UINT8* apAdmin ); -UINT16 GetNumberOfPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo, UINT8* aOfficer, UINT8* apElite, UINT8* apRegular, UINT8* apAdmin ); +UINT16 GetNumberOfPrisoners( SECTORINFO *pSectorInfo, INT16 aPrisoners[] ); +UINT16 GetNumberOfPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo, INT16 aPrisoners[] ); -void ChangeNumberOfPrisoners( SECTORINFO *pSectorInfo, INT16 aOfficer, INT16 aElite, INT16 aRegular, INT16 aAdmin, INT16 sX = 0, INT16 sY = 0 ); -void ChangeNumberOfPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo, INT16 aOfficer, INT16 aElite, INT16 aRegular, INT16 aAdmin ); +void ChangeNumberOfPrisoners( SECTORINFO *pSectorInfo, INT16 aPrisoners[] ); +void ChangeNumberOfPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo, INT16 aPrisoners[] ); void DeleteAllPrisoners( SECTORINFO *pSectorInfo ); void DeleteAllPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo ); diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 3a0e14d03..f3a970274 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -16085,8 +16085,8 @@ BOOLEAN SOLDIERTYPE::CanProcessPrisoners( ) { SECTORINFO *pSectorInfo = &(SectorInfo[SECTOR( this->sSectorX, this->sSectorY )]); - UINT8 tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0; - if ( GetNumberOfPrisoners( pSectorInfo, &tmp1, &tmp2, &tmp3, &tmp4 ) > 0 ) + INT16 aPrisoners[PRISONER_MAX] = {0}; + if ( GetNumberOfPrisoners( pSectorInfo, aPrisoners ) > 0 ) return TRUE; } diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index 4ef7455c6..c1333c752 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -399,6 +399,14 @@ enum #define SOLDIER_SNITCHING_OFF 0x00000001 //1 // isn't allowed to snitch #define SOLDIER_PREVENT_MISBEHAVIOUR_OFF 0x00000002 //2 // isn't allowed to prevent misbehaviour #define SOLDIER_RAM_THROUGH_OBSTACLES 0x00000004 //4 // vehicle +#define SOLDIER_INTERROGATE_ADMIN 0x00000008 //8 // interrogate admins. Flags might not be the best solution, but I won't add an extra variable for this + +#define SOLDIER_INTERROGATE_TROOP 0x00000010 //16 // interrogate troops +#define SOLDIER_INTERROGATE_ELITE 0x00000020 //32 // interrogate elites +#define SOLDIER_INTERROGATE_OFFICER 0x00000040 //64 // interrogate officers +#define SOLDIER_INTERROGATE_GENERAL 0x00000080 //128 // interrogate generals + +#define SOLDIER_INTERROGATE_ALL 0x000000F8 // all interrogation flags // ---------------------------------------------------------------- // -------- added by Flugente: background property flags -------- diff --git a/Tactical/Soldier Init List.cpp b/Tactical/Soldier Init List.cpp index cd96517a8..797ecb9f8 100644 --- a/Tactical/Soldier Init List.cpp +++ b/Tactical/Soldier Init List.cpp @@ -2875,8 +2875,8 @@ void SectorAddPrisonersofWar( INT16 sMapX, INT16 sMapY, INT16 sMapZ ) return; // only continue if there are prisoners in this sector that need to be placed - UINT8 tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0; - UINT16 numprisoners = GetNumberOfPrisoners(pSector, &tmp1, &tmp2, &tmp3, &tmp4); + INT16 aPrisoners[PRISONER_MAX] = {0}; + UINT16 numprisoners = GetNumberOfPrisoners( pSector, aPrisoners ); if ( !numprisoners ) return; diff --git a/Utils/ExportStrings.cpp b/Utils/ExportStrings.cpp index f5def486e..104dd9c38 100644 --- a/Utils/ExportStrings.cpp +++ b/Utils/ExportStrings.cpp @@ -139,6 +139,8 @@ bool Loc::ExportStrings() ExportSection(props, L"SnitchToggleMenuDesc", Loc::pSnitchToggleMenuDescStrings, 0, MAX_SNITCH_TOGGLE_MENU_STRING_COUNT-1); ExportSection(props, L"SnitchSectorMenu", Loc::pSnitchSectorMenuStrings, 0, MAX_SNITCH_SECTOR_MENU_STRING_COUNT); ExportSection(props, L"SnitchSectorMenuDesc", Loc::pSnitchSectorMenuDescStrings, 0, MAX_SNITCH_SECTOR_MENU_STRING_COUNT-1); + ExportSection(props, L"PrisonerMenu", Loc::pPrisonerMenuStrings, 0, MAX_PRISONER_MENU_STRING_COUNT ); + ExportSection(props, L"PrisonerMenuDesc", Loc::pPrisonerMenuDescStrings, 0, MAX_PRISONER_MENU_STRING_COUNT - 1 ); ExportSection(props, L"SnitchPrisonExposed", Loc::pSnitchPrisonExposedStrings, 0, NUM_SNITCH_PRISON_EXPOSED); ExportSection(props, L"SnitchGatheringRumoursResult", Loc::pSnitchGatheringRumoursResultStrings, 0, NUM_SNITCH_GATHERING_RUMOURS_RESULT); diff --git a/Utils/PopUpBox.cpp b/Utils/PopUpBox.cpp index 56b7583d2..577c11cf5 100644 --- a/Utils/PopUpBox.cpp +++ b/Utils/PopUpBox.cpp @@ -196,8 +196,6 @@ void ShadeStringInBox( INT32 hBoxHandle, INT32 iLineNumber ) // shade line PopUpBoxList[hBoxHandle]->Text[iLineNumber]->fShadeFlag = TRUE; } - - return; } void UnShadeStringInBox( INT32 hBoxHandle, INT32 iLineNumber ) @@ -217,8 +215,6 @@ void UnShadeStringInBox( INT32 hBoxHandle, INT32 iLineNumber ) // shade line PopUpBoxList[hBoxHandle]->Text[iLineNumber]->fShadeFlag = FALSE; } - - return; } @@ -239,8 +235,6 @@ void SecondaryShadeStringInBox( INT32 hBoxHandle, INT32 iLineNumber ) // shade line PopUpBoxList[hBoxHandle]->Text[iLineNumber]->fSecondaryShadeFlag = TRUE; } - - return; } void UnSecondaryShadeStringInBox( INT32 hBoxHandle, INT32 iLineNumber ) @@ -260,8 +254,6 @@ void UnSecondaryShadeStringInBox( INT32 hBoxHandle, INT32 iLineNumber ) // shade line PopUpBoxList[hBoxHandle]->Text[iLineNumber]->fSecondaryShadeFlag = FALSE; } - - return; } @@ -271,13 +263,11 @@ void SetBoxBuffer(INT32 hBoxHandle, UINT32 uiBuffer) if ( ( hBoxHandle < 0 ) || ( hBoxHandle >= MAX_POPUP_BOX_COUNT ) ) return; - Assert( PopUpBoxList[ hBoxHandle ] ); + Assert( PopUpBoxList[ hBoxHandle ] ); - PopUpBoxList[hBoxHandle]->uiBuffer=uiBuffer; + PopUpBoxList[hBoxHandle]->uiBuffer=uiBuffer; - PopUpBoxList[hBoxHandle]->fUpdated = FALSE; - - return; + PopUpBoxList[hBoxHandle]->fUpdated = FALSE; } @@ -286,14 +276,12 @@ void SetBoxPosition( INT32 hBoxHandle,SGPPoint Position ) if ( ( hBoxHandle < 0 ) || ( hBoxHandle >= MAX_POPUP_BOX_COUNT ) ) return; - Assert( PopUpBoxList[ hBoxHandle ] ); + Assert( PopUpBoxList[ hBoxHandle ] ); - PopUpBoxList[hBoxHandle]->Position.iX=Position.iX; - PopUpBoxList[hBoxHandle]->Position.iY=Position.iY; + PopUpBoxList[hBoxHandle]->Position.iX=Position.iX; + PopUpBoxList[hBoxHandle]->Position.iY=Position.iY; - PopUpBoxList[hBoxHandle]->fUpdated = FALSE; - - return; + PopUpBoxList[hBoxHandle]->fUpdated = FALSE; } @@ -306,8 +294,6 @@ void GetBoxPosition( INT32 hBoxHandle, SGPPoint *Position ) Position->iX = PopUpBoxList[hBoxHandle]->Position.iX; Position->iY = PopUpBoxList[hBoxHandle]->Position.iY; - - return; } void SetBoxSize(INT32 hBoxHandle,SGPRect Dimensions) @@ -315,16 +301,14 @@ void SetBoxSize(INT32 hBoxHandle,SGPRect Dimensions) if ( ( hBoxHandle < 0 ) || ( hBoxHandle >= MAX_POPUP_BOX_COUNT ) ) return; - Assert( PopUpBoxList[ hBoxHandle ] ); + Assert( PopUpBoxList[ hBoxHandle ] ); - PopUpBoxList[hBoxHandle]->Dimensions.iLeft=Dimensions.iLeft; - PopUpBoxList[hBoxHandle]->Dimensions.iBottom=Dimensions.iBottom; - PopUpBoxList[hBoxHandle]->Dimensions.iRight=Dimensions.iRight; - PopUpBoxList[hBoxHandle]->Dimensions.iTop=Dimensions.iTop; + PopUpBoxList[hBoxHandle]->Dimensions.iLeft=Dimensions.iLeft; + PopUpBoxList[hBoxHandle]->Dimensions.iBottom=Dimensions.iBottom; + PopUpBoxList[hBoxHandle]->Dimensions.iRight=Dimensions.iRight; + PopUpBoxList[hBoxHandle]->Dimensions.iTop=Dimensions.iTop; - PopUpBoxList[hBoxHandle]->fUpdated = FALSE; - - return; + PopUpBoxList[hBoxHandle]->fUpdated = FALSE; } @@ -339,8 +323,6 @@ void GetBoxSize( INT32 hBoxHandle, SGPRect *Dimensions ) Dimensions->iBottom = PopUpBoxList[hBoxHandle]->Dimensions.iBottom; Dimensions->iRight = PopUpBoxList[hBoxHandle]->Dimensions.iRight; Dimensions->iTop = PopUpBoxList[hBoxHandle]->Dimensions.iTop; - - return; } @@ -349,9 +331,8 @@ void SetBorderType(INT32 hBoxHandle, INT32 iBorderObjectIndex) if ( ( hBoxHandle < 0 ) || ( hBoxHandle >= MAX_POPUP_BOX_COUNT ) ) return; - Assert( PopUpBoxList[ hBoxHandle ] ); - PopUpBoxList[hBoxHandle]->iBorderObjectIndex=iBorderObjectIndex; - return; + Assert( PopUpBoxList[ hBoxHandle ] ); + PopUpBoxList[hBoxHandle]->iBorderObjectIndex=iBorderObjectIndex; } void SetBackGroundSurface(INT32 hBoxHandle, INT32 iBackGroundSurfaceIndex) @@ -359,9 +340,8 @@ void SetBackGroundSurface(INT32 hBoxHandle, INT32 iBackGroundSurfaceIndex) if ( ( hBoxHandle < 0 ) || ( hBoxHandle >= MAX_POPUP_BOX_COUNT ) ) return; - Assert( PopUpBoxList[ hBoxHandle ] ); - PopUpBoxList[hBoxHandle]->iBackGroundSurface=iBackGroundSurfaceIndex; - return; + Assert( PopUpBoxList[ hBoxHandle ] ); + PopUpBoxList[hBoxHandle]->iBackGroundSurface=iBackGroundSurfaceIndex; } diff --git a/Utils/Text.h b/Utils/Text.h index d000de1e1..6b458ec04 100644 --- a/Utils/Text.h +++ b/Utils/Text.h @@ -175,6 +175,8 @@ extern STR16 pSnitchToggleMenuStrings[]; extern STR16 pSnitchToggleMenuDescStrings[]; extern STR16 pSnitchSectorMenuStrings[]; extern STR16 pSnitchSectorMenuDescStrings[]; +extern STR16 pPrisonerMenuStrings[]; +extern STR16 pPrisonerMenuDescStrings[]; extern STR16 pSnitchPrisonExposedStrings[]; extern STR16 pSnitchGatheringRumoursResultStrings[]; extern STR16 pAssignMenuStrings[]; diff --git a/Utils/_ChineseText.cpp b/Utils/_ChineseText.cpp index 4dc215173..a4b987f0a 100644 --- a/Utils/_ChineseText.cpp +++ b/Utils/_ChineseText.cpp @@ -2263,6 +2263,26 @@ STR16 pSnitchSectorMenuDescStrings[] = L"", }; +STR16 pPrisonerMenuStrings[] = // TODO.Translate +{ + L"Interrogate admins", + L"Interrogate troops", + L"Interrogate elites", + L"Interrogate officers", + L"Interrogate generals", + L"Cancel", +}; + +STR16 pPrisonerMenuDescStrings[] = +{ + L"Administrators are easy to process, but give only poor results", + L"Regular troops are common an don't give you high rewards.", + L"If elite troops defect to you, they can become veteran militia.", + L"Interrogating enemy officers can lead you to find enemy generals.", + L"Generals cannot join your militia, but lead to high ransoms.", + L"Cancel", +}; + STR16 pSnitchPrisonExposedStrings[] = { L"%s告发者的身份暴露,但是及时注意到并成功逃脱。", diff --git a/Utils/_DutchText.cpp b/Utils/_DutchText.cpp index 22c8b9ab3..af09ec3cb 100644 --- a/Utils/_DutchText.cpp +++ b/Utils/_DutchText.cpp @@ -2261,6 +2261,26 @@ STR16 pSnitchSectorMenuDescStrings[] = L"", }; +STR16 pPrisonerMenuStrings[] = // TODO.Translate +{ + L"Interrogate admins", + L"Interrogate troops", + L"Interrogate elites", + L"Interrogate officers", + L"Interrogate generals", + L"Cancel", +}; + +STR16 pPrisonerMenuDescStrings[] = +{ + L"Administrators are easy to process, but give only poor results", + L"Regular troops are common an don't give you high rewards.", + L"If elite troops defect to you, they can become veteran militia.", + L"Interrogating enemy officers can lead you to find enemy generals.", + L"Generals cannot join your militia, but lead to high ransoms.", + L"Cancel", +}; + STR16 pSnitchPrisonExposedStrings[] = { L"%s was exposed as a snitch but managed to notice it and get out alive.", diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp index 09169620e..a634e7ae5 100644 --- a/Utils/_EnglishText.cpp +++ b/Utils/_EnglishText.cpp @@ -2264,6 +2264,26 @@ STR16 pSnitchSectorMenuDescStrings[] = L"", }; +STR16 pPrisonerMenuStrings[] = +{ + L"Interrogate admins", + L"Interrogate troops", + L"Interrogate elites", + L"Interrogate officers", + L"Interrogate generals", + L"Cancel", +}; + +STR16 pPrisonerMenuDescStrings[] = +{ + L"Administrators are easy to process, but give only poor results", + L"Regular troops are common an don't give you high rewards.", + L"If elite troops defect to you, they can become veteran militia.", + L"Interrogating enemy officers can lead you to find enemy generals.", + L"Generals cannot join your militia, but lead to high ransoms.", + L"Cancel", +}; + STR16 pSnitchPrisonExposedStrings[] = { L"%s was exposed as a snitch but managed to notice it and get out alive.", @@ -8227,7 +8247,7 @@ STR16 szPersonalityHelpText[]= L"What are your manners?", L"How important are the manners of other people to you?", L"What is your nationality?", - L"What nation o you dislike?", + L"What nation do you dislike?", L"How much do you dislike that nation?", L"How racist are you?", L"What is your race? You will be\nracist against all other races.", diff --git a/Utils/_FrenchText.cpp b/Utils/_FrenchText.cpp index 78a0efa3d..2e872e69e 100644 --- a/Utils/_FrenchText.cpp +++ b/Utils/_FrenchText.cpp @@ -2270,6 +2270,26 @@ STR16 pSnitchSectorMenuDescStrings[] = L"", }; +STR16 pPrisonerMenuStrings[] = // TODO.Translate +{ + L"Interrogate admins", + L"Interrogate troops", + L"Interrogate elites", + L"Interrogate officers", + L"Interrogate generals", + L"Cancel", +}; + +STR16 pPrisonerMenuDescStrings[] = +{ + L"Administrators are easy to process, but give only poor results", + L"Regular troops are common an don't give you high rewards.", + L"If elite troops defect to you, they can become veteran militia.", + L"Interrogating enemy officers can lead you to find enemy generals.", + L"Generals cannot join your militia, but lead to high ransoms.", + L"Cancel", +}; + STR16 pSnitchPrisonExposedStrings[] = { L"%s s'est exposé(e) comme mouchard, mais s'en est rendu compte et a pu s'en sortir vivant.", diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp index 550015cf0..cb05fde74 100644 --- a/Utils/_GermanText.cpp +++ b/Utils/_GermanText.cpp @@ -2266,6 +2266,26 @@ STR16 pSnitchSectorMenuDescStrings[] = L"", }; +STR16 pPrisonerMenuStrings[] = // TODO.Translate +{ + L"Interrogate admins", + L"Interrogate troops", + L"Interrogate elites", + L"Interrogate officers", + L"Interrogate generals", + L"Cancel", +}; + +STR16 pPrisonerMenuDescStrings[] = +{ + L"Administrators are easy to process, but give only poor results", + L"Regular troops are common an don't give you high rewards.", + L"If elite troops defect to you, they can become veteran militia.", + L"Interrogating enemy officers can lead you to find enemy generals.", + L"Generals cannot join your militia, but lead to high ransoms.", + L"Cancel", +}; + STR16 pSnitchPrisonExposedStrings[] = { L"%s was exposed as a snitch but managed to notice it and get out alive.", diff --git a/Utils/_ItalianText.cpp b/Utils/_ItalianText.cpp index 895654096..28240c23e 100644 --- a/Utils/_ItalianText.cpp +++ b/Utils/_ItalianText.cpp @@ -2257,6 +2257,27 @@ STR16 pSnitchSectorMenuDescStrings[] = L"", }; +STR16 pPrisonerMenuStrings[] = // TODO.Translate +{ + // toggle snitching + L"Interrogate admins", + L"Interrogate troops", + L"Interrogate elites", + L"Interrogate officers", + L"Interrogate generals", + L"Cancel", +}; + +STR16 pPrisonerMenuDescStrings[] = +{ + L"Administrators are easy to process, but give only poor results", + L"Regular troops are common an don't give you high rewards.", + L"If elite troops defect to you, they can become veteran militia.", + L"Interrogating enemy officers can lead you to find enemy generals.", + L"Generals cannot join your militia, but lead to high ransoms.", + L"Cancel", +}; + STR16 pSnitchPrisonExposedStrings[] = { L"%s was exposed as a snitch but managed to notice it and get out alive.", diff --git a/Utils/_PolishText.cpp b/Utils/_PolishText.cpp index 64da97df9..a3e27db1d 100644 --- a/Utils/_PolishText.cpp +++ b/Utils/_PolishText.cpp @@ -2272,6 +2272,26 @@ STR16 pSnitchSectorMenuDescStrings[] = L"", }; +STR16 pPrisonerMenuStrings[] = // TODO.Translate +{ + L"Interrogate admins", + L"Interrogate troops", + L"Interrogate elites", + L"Interrogate officers", + L"Interrogate generals", + L"Cancel", +}; + +STR16 pPrisonerMenuDescStrings[] = +{ + L"Administrators are easy to process, but give only poor results", + L"Regular troops are common an don't give you high rewards.", + L"If elite troops defect to you, they can become veteran militia.", + L"Interrogating enemy officers can lead you to find enemy generals.", + L"Generals cannot join your militia, but lead to high ransoms.", + L"Cancel", +}; + STR16 pSnitchPrisonExposedStrings[] = { L"%s został zdemaskowany jako kapuś, ale w porę to spostrzegł i zdołał ujść z życiem.", diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index bc5acbc55..889dbef86 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -2265,6 +2265,26 @@ STR16 pSnitchSectorMenuDescStrings[] = L"", }; +STR16 pPrisonerMenuStrings[] = // TODO.Translate +{ + L"Interrogate admins", + L"Interrogate troops", + L"Interrogate elites", + L"Interrogate officers", + L"Interrogate generals", + L"Cancel", +}; + +STR16 pPrisonerMenuDescStrings[] = +{ + L"Administrators are easy to process, but give only poor results", + L"Regular troops are common an don't give you high rewards.", + L"If elite troops defect to you, they can become veteran militia.", + L"Interrogating enemy officers can lead you to find enemy generals.", + L"Generals cannot join your militia, but lead to high ransoms.", + L"Cancel", +}; + STR16 pSnitchPrisonExposedStrings[] = { L"%s was exposed as a snitch but managed to notice it and get out alive.",