diff --git a/GameSettings.cpp b/GameSettings.cpp index d47bee0e..bf6164b2 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 bf080e16..3ccf4bef 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 fa6dfd4e..99563039 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 b9992217..6ac50713 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 dcbb05de..bed1db17 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 66108c17..fa4ec109 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 16d0ef7b..b2111c9c 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 753e9efa..e907c510 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 04da2c99..82b73a45 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 2ae2a191..e3b1b379 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 83de0b2a..29ced08c 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 77b00ab5..6131f24b 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 70012811..926ab278 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 5291eb56..06d2397e 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 0b52d12e..f7ef9c1e 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 5e1b7f46..c823b9de 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 a127df05..0d2b180f 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 3a0e14d0..f3a97027 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 4ef7455c..c1333c75 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 cd96517a..797ecb9f 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 f5def486..104dd9c3 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 56b7583d..577c11cf 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 d000de1e..6b458ec0 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 4dc21517..a4b987f0 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 22c8b9ab..af09ec3c 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 09169620..a634e7ae 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 78a0efa3..2e872e69 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 550015cf..cb05fde7 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 89565409..28240c23 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 64da97df..a3e27db1 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 bc5acbc5..889dbef8 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.",