- New prisoner class: Civilians can be interrogated. Does not work for profile-based charcters.

- Capturing civilians is possible if their faction has <fCanBeCaptured> set to 1.

Requires GameDir >= r2215.

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7762 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2015-02-28 22:35:30 +00:00
parent 4b70b1e400
commit 9d8e5a4c3a
22 changed files with 321 additions and 99 deletions
+61 -37
View File
@@ -6764,6 +6764,11 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
++numinterrogators[PRISONER_GENERAL];
interrogationpoints[PRISONER_GENERAL] += points;
}
else if ( pSoldier->usSoldierFlagMask2 & SOLDIER_INTERROGATE_CIVILIAN )
{
++numinterrogators[PRISONER_CIVILIAN];
interrogationpoints[PRISONER_CIVILIAN] += points;
}
// admin is default
else
{
@@ -6846,16 +6851,18 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
return;
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_PROCESSED],
interrogatedprisoners[PRISONER_OFFICER], interrogatedprisoners[PRISONER_ELITE], interrogatedprisoners[PRISONER_REGULAR], interrogatedprisoners[PRISONER_ADMIN] );
interrogatedprisoners[PRISONER_OFFICER], interrogatedprisoners[PRISONER_ELITE], interrogatedprisoners[PRISONER_REGULAR],
interrogatedprisoners[PRISONER_ADMIN], interrogatedprisoners[PRISONER_GENERAL], interrogatedprisoners[PRISONER_CIVILIAN] );
UINT16 turnedmilitia[PRISONER_MAX] = { 0 };
UINT16 volunteers = 0;
UINT32 revealedpositions = 0;
UINT32 ransomscollected = 0;
UINT32 ransommoney = 0;
for ( UINT32 i = 0; i < prisonersinterrogated; ++i )
{
// what kind of a prisoner is this?
UINT8 prisonertype = PRISONER_THUG;
UINT8 prisonertype = PRISONER_CIVILIAN;
if ( i < interrogatedprisoners[PRISONER_ADMIN] )
prisonertype = PRISONER_ADMIN;
else if ( i < interrogatedprisoners[PRISONER_ADMIN] + interrogatedprisoners[PRISONER_REGULAR] )
@@ -6877,8 +6884,9 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
if ( prisonertype == PRISONER_GENERAL )
chances[PRISONER_INTERROGATION_DEFECT] = 0;
if ( prisonertype == PRISONER_THUG )
chances[PRISONER_INTERROGATION_DEFECT] = 0;
// civilians know nothing about army movement
if ( prisonertype == PRISONER_CIVILIAN )
chances[PRISONER_INTERROGATION_INFO] = 0;
// for normalisation, get sum of chances
UINT16 sumchance = 0;
@@ -6903,14 +6911,21 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
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 ( prisonertype >= PRISONER_OFFICER && Chance( 80 ) )
// civilians need to receive basic training - these are volunteers
if ( prisonertype == PRISONER_CIVILIAN )
++volunteers;
else if ( prisonertype >= PRISONER_OFFICER && Chance( 80 ) )
++turnedmilitia[PRISONER_OFFICER];
else if ( prisonertype >= PRISONER_ELITE && Chance( 80 ) )
++turnedmilitia[PRISONER_ELITE];
else if ( prisonertype >= PRISONER_REGULAR && Chance( 80 ) )
++turnedmilitia[PRISONER_REGULAR];
else
else if ( prisonertype >= PRISONER_ADMIN && Chance( 80 ) )
++turnedmilitia[PRISONER_ADMIN];
else
// some might even fail to qualify as admins, these are volunteers - we have to 'retrain' them
++volunteers;
// we continue so that this guy cannot also run back to the queen
continue;
@@ -6918,30 +6933,8 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
// chance that prisoner will give us random info about enemy positions
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 ( prisonertype == PRISONER_ADMIN )
{
if ( Chance( gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_ADMIN] ) )
fGetInfoOnHiddenVIPs = TRUE;
}
else if ( prisonertype == PRISONER_REGULAR )
{
if ( Chance( gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_REGULAR] ) )
fGetInfoOnHiddenVIPs = TRUE;
}
else if ( prisonertype == PRISONER_ELITE )
{
if ( Chance( gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_ELITE] ) )
fGetInfoOnHiddenVIPs = TRUE;
}
else if ( prisonertype == PRISONER_OFFICER )
{
if ( Chance( gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[PRISONER_OFFICER] ) )
fGetInfoOnHiddenVIPs = TRUE;
}
if ( fGetInfoOnHiddenVIPs )
// there is a chance this guy might tell us about high-value targets!
if ( Chance( gGameExternalOptions.ubPrisonerInterrogationEnemyGeneralInfoChance[prisonertype] ) )
{
UINT16 unknownvipector = 0;
if ( GetRandomUnknownVIPSector( unknownvipector ) )
@@ -7006,8 +6999,8 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
ransom *= 3;
else if ( prisonertype == PRISONER_GENERAL )
ransom *= 10;
else if ( prisonertype == PRISONER_THUG )
ransom *= 0.7f;
else if ( prisonertype == PRISONER_CIVILIAN )
ransom *= 0.5f;
ransommoney += ransom;
@@ -7021,7 +7014,11 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
// there is a chance that escaped prisoners may return to the queen...
if ( Random( 100 ) < gGameExternalOptions.ubPrisonerReturntoQueenChance )
++giReinforcementPool;
{
// but not for civilians
if ( prisonertype != PRISONER_CIVILIAN )
++giReinforcementPool;
}
}
if ( turnedmilitia[PRISONER_ADMIN] + turnedmilitia[PRISONER_REGULAR] + turnedmilitia[PRISONER_ELITE] + turnedmilitia[PRISONER_OFFICER] )
@@ -7034,6 +7031,15 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_TURN_MILITIA], turnedmilitia[PRISONER_OFFICER], turnedmilitia[PRISONER_ELITE], turnedmilitia[PRISONER_REGULAR], turnedmilitia[PRISONER_ADMIN] );
}
if ( volunteers )
{
AddVolunteers( volunteers );
// we add the volunteers anyway, but only show the message if this feature is on
if ( gGameExternalOptions.fMilitiaVolunteerPool )
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_TURN_VOLUNTEER], volunteers );
}
if ( revealedpositions )
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_DETECTION], revealedpositions );
@@ -7046,7 +7052,12 @@ void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
// give experience rewards to the interrogators
// 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 totalexp = (FLOAT)(4 * interrogatedprisoners[PRISONER_ADMIN]
+ 5 * interrogatedprisoners[PRISONER_REGULAR]
+ 7 * interrogatedprisoners[PRISONER_ELITE]
+ 10 * interrogatedprisoners[PRISONER_OFFICER]
+ 30 * interrogatedprisoners[PRISONER_GENERAL]
+ 3 * interrogatedprisoners[PRISONER_CIVILIAN]);
FLOAT expratio = totalexp / sum_points;
// award experience
@@ -7165,7 +7176,7 @@ void HandlePrison( INT16 sMapX, INT16 sMapY, INT8 bZ )
fBeginRiot = TRUE;
// we now have to determine the combined strength of the prisoners
UINT32 prisonerriotvalue = 100 * aPrisoners[PRISONER_THUG]
UINT32 prisonerriotvalue = 60 * aPrisoners[PRISONER_CIVILIAN]
+ 200 * aPrisoners[PRISONER_GENERAL]
+ 200 * aPrisoners[PRISONER_OFFICER]
+ 125 * aPrisoners[PRISONER_ELITE]
@@ -7189,8 +7200,8 @@ void HandlePrison( INT16 sMapX, INT16 sMapY, INT8 bZ )
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 + escapedprisoners[PRISONER_REGULAR] + escapedprisoners[PRISONER_THUG] );
// add enemies (PRISONER_CIVILIAN just flee)
pSectorInfo->ubNumTroops = min( 512, pSectorInfo->ubNumTroops + escapedprisoners[PRISONER_REGULAR] );
pSectorInfo->ubNumElites = min( 512, pSectorInfo->ubNumElites + escapedprisoners[PRISONER_ELITE] + escapedprisoners[PRISONER_OFFICER] + escapedprisoners[PRISONER_GENERAL] );
pSectorInfo->ubNumAdmins = min( 512, pSectorInfo->ubNumAdmins + escapedprisoners[PRISONER_ADMIN] );
@@ -12066,6 +12077,14 @@ void PrisonerMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason )
fShowAssignmentMenu = FALSE;
giAssignHighLine = -1;
}
else if ( iValue == PRISONER_MENU_CIVILIAN )
{
pSoldier->usSoldierFlagMask2 &= ~SOLDIER_INTERROGATE_ALL;
pSoldier->usSoldierFlagMask2 |= SOLDIER_INTERROGATE_CIVILIAN;
fShowPrisonerMenu = FALSE;
fShowAssignmentMenu = FALSE;
giAssignHighLine = -1;
}
// rerender tactical stuff
gfRenderPBInterface = TRUE;
@@ -15959,6 +15978,7 @@ void HandleShadingOfLinesForPrisonerMenu( void )
UnShadeStringInBox( ghPrisonerBox, PRISONER_MENU_ELITE );
UnShadeStringInBox( ghPrisonerBox, PRISONER_MENU_OFFICER );
UnShadeStringInBox( ghPrisonerBox, PRISONER_MENU_GENERAL );
UnShadeStringInBox( ghPrisonerBox, PRISONER_MENU_CIVILIAN );
if ( pSoldier->usSoldierFlagMask2 & SOLDIER_INTERROGATE_ADMIN )
{
@@ -15980,6 +16000,10 @@ void HandleShadingOfLinesForPrisonerMenu( void )
{
ShadeStringInBox( ghPrisonerBox, PRISONER_MENU_GENERAL );
}
else if ( pSoldier->usSoldierFlagMask2 & SOLDIER_INTERROGATE_CIVILIAN )
{
ShadeStringInBox( ghPrisonerBox, PRISONER_MENU_CIVILIAN );
}
}
void HandleShadingOfLinesForSnitchSectorMenu( void )
+1 -1
View File
@@ -432,7 +432,7 @@ typedef enum
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_CIVILIAN, // captured civilians (Kingpin, Hicks...)
PRISONER_SECRET1, // tbA
PRISONER_SECRET2, // tbA
PRISONER_MAX,
@@ -458,8 +458,19 @@ void AddTextToTownBox( void )
// prisoners
swprintf( wString, L"%s:", pwTownInfoStrings[ 13 ] );
AddMonoString( &hStringHandle, wString );
swprintf( wString, pwTownInfoStrings[ 14 ], numprisoners, capacity, aPrisoners[PRISONER_ADMIN], aPrisoners[PRISONER_REGULAR], aPrisoners[PRISONER_ELITE], aPrisoners[PRISONER_OFFICER], aPrisoners[PRISONER_GENERAL] );
swprintf( wString, pwTownInfoStrings[14], numprisoners, capacity );
AddSecondColumnMonoString( &hStringHandle, wString );
for ( int i = 0; i < PRISONER_MAX; ++i )
{
if ( aPrisoners[i] )
{
swprintf( wString, L"" );
AddMonoString( &hStringHandle, wString );
swprintf( wString, pwTownInfoStrings[15 + i], aPrisoners[i] );
AddSecondColumnMonoString( &hStringHandle, wString );
}
}
}
}
+1
View File
@@ -166,6 +166,7 @@ enum {
PRISONER_MENU_ELITE,
PRISONER_MENU_OFFICER,
PRISONER_MENU_GENERAL,
PRISONER_MENU_CIVILIAN,
PRISONER_MENU_CANCEL,
MAX_PRISONER_MENU_STRING_COUNT,
};
+2 -2
View File
@@ -5367,11 +5367,11 @@ BOOLEAN LoadStrategicInfoFromSavedFile( HWFILE hFile )
if ( guiCurrentSaveGameVersion < PRISONER_EXPANSION )
{
SectorInfo[sectorID].uiNumberOfPrisonersOfWar[PRISONER_GENERAL] = 0;
SectorInfo[sectorID].uiNumberOfPrisonersOfWar[PRISONER_THUG] = 0;
SectorInfo[sectorID].uiNumberOfPrisonersOfWar[PRISONER_CIVILIAN] = 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];
SectorInfo[sectorID].ubTanksInBattle = SectorInfo[sectorID].uiInterrogationHundredsLeft[PRISONER_CIVILIAN];
}
}
// uiSize = sizeof( SECTORINFO ) * 256;