mirror of
https://github.com/1dot13/source.git
synced 2026-08-05 14:00:23 +02:00
- New Feature: The rosine system now allows to capture enemy soldeirs via using handcuffs on them. They can e transferred to a prison the player controls, and be interrogated there.
- GameDir revision 1568 is required for this feature. - Savegame compatibility is maintained. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5709 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
+475
-2
@@ -398,6 +398,12 @@ void TrainSoldierWithPts( SOLDIERTYPE *pSoldier, INT16 sTrainPts );
|
||||
// train militia in this sector with this soldier
|
||||
BOOLEAN TrainTownInSector( SOLDIERTYPE *pTrainer, INT16 sMapX, INT16 sMapY, INT16 sTrainingPts );
|
||||
|
||||
// Flugente:: handle processing of prisoners
|
||||
void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ );
|
||||
|
||||
// Flugente: prisons can riot if there aren't enough guards around
|
||||
void HandlePrison( INT16 sMapX, INT16 sMapY, INT8 bZ );
|
||||
|
||||
// is the character between secotrs in mvt
|
||||
BOOLEAN CharacterIsBetweenSectors( SOLDIERTYPE *pSoldier );
|
||||
|
||||
@@ -2220,7 +2226,9 @@ void UpdateAssignments()
|
||||
for( bZ = 0; bZ < 4; bZ++)
|
||||
{
|
||||
// handle militia squads movings and creating (not an assignment)
|
||||
if(!bZ && sX < 17 && sY < 17 && sX > 0 && sY > 0)UpdateMilitiaSquads( sX, sY );
|
||||
if(!bZ && sX < 17 && sY < 17 && sX > 0 && sY > 0)
|
||||
UpdateMilitiaSquads( sX, sY );
|
||||
|
||||
// is there anyone in this sector?
|
||||
if( fSectorsWithSoldiers[ sX + sY * MAP_WORLD_X ][ bZ ] == TRUE )
|
||||
{
|
||||
@@ -2232,7 +2240,14 @@ void UpdateAssignments()
|
||||
|
||||
// handle any training
|
||||
HandleTrainingInSector( sX, sY, bZ );
|
||||
|
||||
// handle processing of prisoners
|
||||
HandlePrisonerProcessingInSector( sX, sY, bZ );
|
||||
}
|
||||
|
||||
// Flugente: prisons can riot if there aren't enough guards around
|
||||
if ( !bZ )
|
||||
HandlePrison( sX, sY, bZ );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2596,6 +2611,84 @@ UINT8 CalculateRepairPointsForRepairman(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts
|
||||
return(( UINT8 )usRepairPts);
|
||||
}
|
||||
|
||||
extern INT32 CalcThreateningEffectiveness( UINT8 ubMerc );
|
||||
|
||||
// Flugente: calculate interrogation value
|
||||
FLOAT CalculateInterrogationValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts )
|
||||
{
|
||||
UINT32 usInterrogationPoints = 0;
|
||||
|
||||
// for max points we display the maximum amount of prisoners instead
|
||||
*pusMaxPts = 0;
|
||||
if ( !pSoldier || !pSoldier->bSectorZ )
|
||||
{
|
||||
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ] );
|
||||
|
||||
*pusMaxPts = (UINT16)(pSectorInfo->uiNumberOfPrisonersOfWar);
|
||||
}
|
||||
|
||||
// no prisoners -> no interrogation (this should not happen)
|
||||
if ( !*pusMaxPts )
|
||||
return .0f;
|
||||
|
||||
usInterrogationPoints = 50 + 10 * EffectiveExpLevel( pSoldier ) + EffectiveLeadership( pSoldier );
|
||||
|
||||
// adjust for threatening value
|
||||
INT32 threatenvalue = CalcThreateningEffectiveness( pSoldier->ubProfile ) * gMercProfiles[pSoldier->ubProfile].usApproachFactor[2] ;
|
||||
|
||||
usInterrogationPoints *= threatenvalue;
|
||||
usInterrogationPoints /= 6500;
|
||||
|
||||
// TODO: adjust for cop background
|
||||
|
||||
// adjust for fatigue
|
||||
ReducePointsForFatigue( pSoldier, &usInterrogationPoints );
|
||||
|
||||
// return current repair pts
|
||||
return( usInterrogationPoints );
|
||||
}
|
||||
|
||||
// Flugente: calculate prison guard value
|
||||
FLOAT CalculatePrisonGuardValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts )
|
||||
{
|
||||
// this is not an assignment. Simply being in the sector will allow us to be counted as guards
|
||||
UINT32 usValue = 0;
|
||||
|
||||
// for max points we display the maximum amount of prisoners instead
|
||||
*pusMaxPts = 0;
|
||||
/*if ( !pSoldier || !pSoldier->bSectorZ )
|
||||
{
|
||||
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ] );
|
||||
|
||||
*pusMaxPts = (UINT16)(pSectorInfo->uiNumberOfPrisonersOfWar);
|
||||
}
|
||||
|
||||
// no prisoners -> no interrogation (this should not happen)
|
||||
if ( !*pusMaxPts )
|
||||
return .0f;*/
|
||||
|
||||
if ( pSoldier->flags.fMercAsleep )
|
||||
return 0;
|
||||
|
||||
usValue = 15 * EffectiveExpLevel( pSoldier ) + EffectiveLeadership( pSoldier ) / 2 + 2 * EffectiveStrength( pSoldier, FALSE);
|
||||
|
||||
if (gGameOptions.fNewTraitSystem)
|
||||
{
|
||||
usValue += 25 * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ) + 10 * HAS_SKILL_TRAIT( pSoldier, MELEE_NT );
|
||||
}
|
||||
else
|
||||
{
|
||||
usValue += 25 * NUM_SKILL_TRAITS( pSoldier, MARTIALARTS_OT ) + 25 * NUM_SKILL_TRAITS( pSoldier, HANDTOHAND_OT ) + 10 * HAS_SKILL_TRAIT( pSoldier, KNIFING_OT );
|
||||
}
|
||||
|
||||
// adjust for fatigue
|
||||
ReducePointsForFatigue( pSoldier, &usValue );
|
||||
|
||||
// TODO: adjust for prison guard background
|
||||
|
||||
// return current repair pts
|
||||
return( usValue );
|
||||
}
|
||||
|
||||
UINT16 ToolKitPoints(SOLDIERTYPE *pSoldier)
|
||||
{
|
||||
@@ -5379,6 +5472,345 @@ BOOLEAN TrainTownInSector( SOLDIERTYPE *pTrainer, INT16 sMapX, INT16 sMapY, INT1
|
||||
|
||||
}
|
||||
|
||||
extern INT32 giReinforcementPool;
|
||||
|
||||
// handle processing of prisoners
|
||||
void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
|
||||
{
|
||||
// Is there a prison in this sector?
|
||||
UINT16 prisonerbaselimit = 0;
|
||||
for (UINT16 cnt = 0; cnt < NUM_FACILITY_TYPES; ++cnt)
|
||||
{
|
||||
// Is this facility here?
|
||||
if (gFacilityLocations[SECTOR(sMapX, sMapY)][cnt].fFacilityHere)
|
||||
{
|
||||
// we determine wether this is a prison by checking for usPrisonBaseLimit
|
||||
if (gFacilityTypes[cnt].AssignmentData[FAC_INTERROGATE_PRISONERS].usPrisonBaseLimit > 0)
|
||||
{
|
||||
prisonerbaselimit = gFacilityTypes[cnt].AssignmentData[FAC_INTERROGATE_PRISONERS].usPrisonBaseLimit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !prisonerbaselimit )
|
||||
return;
|
||||
|
||||
// Are there any prisoners in this prison?
|
||||
UINT32 numprisoners = 0;
|
||||
if ( !bZ )
|
||||
{
|
||||
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ] );
|
||||
|
||||
numprisoners = pSectorInfo->uiNumberOfPrisonersOfWar;
|
||||
}
|
||||
else
|
||||
{
|
||||
UNDERGROUND_SECTORINFO *pSectorInfo = FindUnderGroundSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
||||
|
||||
numprisoners = pSectorInfo->uiNumberOfPrisonersOfWar;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// loop over all mercs in this sector that are on the FACILITY_INTERROGATE_PRISONERS assignment and determine their interrogation progress
|
||||
SOLDIERTYPE *pSoldier = NULL;
|
||||
UINT32 uiCnt=0;
|
||||
UINT8 numinterrogators = 0;
|
||||
FLOAT interrogationpoints = .0f;
|
||||
|
||||
// count any interrogators found here, and sum up their interrogation values
|
||||
for ( uiCnt = 0, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= gTacticalStatus.Team[ OUR_TEAM ].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 ) )
|
||||
{
|
||||
++numinterrogators;
|
||||
|
||||
UINT16 tmp;
|
||||
interrogationpoints += CalculateInterrogationValue(pSoldier, &tmp );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !numinterrogators )
|
||||
return;
|
||||
|
||||
// for every x points, we can interrogate 1 prisoner
|
||||
// TODO: for now, we lose the remaining points
|
||||
UINT32 prisonersinterrogated = interrogationpoints / 100;
|
||||
|
||||
if ( prisonersinterrogated > numprisoners )
|
||||
prisonersinterrogated = numprisoners;
|
||||
|
||||
if ( !prisonersinterrogated )
|
||||
return;
|
||||
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_PROCESSED], prisonersinterrogated );
|
||||
|
||||
UINT32 turnedmilitia = 0;
|
||||
UINT32 revealedpositions = 0;
|
||||
UINT32 ransomscollected = 0;
|
||||
UINT32 ransommoney = 0;
|
||||
for ( UINT32 i = 0; i < prisonersinterrogated; ++i )
|
||||
{
|
||||
// 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 )
|
||||
{
|
||||
++turnedmilitia;
|
||||
|
||||
// we continue so that this guy can not also run back to the queen
|
||||
continue;
|
||||
}
|
||||
// chance that prisoner will give us random info about enemy positions
|
||||
else if ( result < gGameExternalOptions.ubPrisonerProcessDefectChance + gGameExternalOptions.ubPrisonerProcessInfoBaseChance )
|
||||
{
|
||||
BOOLEAN found = FALSE;
|
||||
// run through sectors and handle each type in sector
|
||||
for(INT16 sX = 1; sX < MAP_WORLD_X - 1; ++sX )
|
||||
{
|
||||
if ( found )
|
||||
break;
|
||||
|
||||
for(INT16 sY = 1; sY < MAP_WORLD_X - 1; ++sY )
|
||||
{
|
||||
UINT32 result = Random(100);
|
||||
if ( result < gGameExternalOptions.ubPrisonerProcessInfoDetectChance )
|
||||
{
|
||||
// there need to be enemies here...
|
||||
if ( NumStationaryEnemiesInSector( sX, sY ) == 0 )
|
||||
continue;
|
||||
|
||||
// enemy patrol detected
|
||||
SectorInfo[ SECTOR( sX, sY ) ].uiFlags |= SF_ASSIGN_NOTICED_ENEMIES_HERE;
|
||||
|
||||
if ( result < gGameExternalOptions.ubPrisonerProcessInfoNumberChance )
|
||||
{
|
||||
// we also learned the number of enemies
|
||||
SectorInfo[ SECTOR( sX, sY ) ].uiFlags |= SF_ASSIGN_NOTICED_ENEMIES_KNOW_NUMBER;
|
||||
}
|
||||
|
||||
if ( result < gGameExternalOptions.ubPrisonerProcessInfoDirectionChance )
|
||||
{
|
||||
// we also learned the direction of the patrol
|
||||
SectorInfo[ SECTOR( sX, sY ) ].uiFlags |= SF_ASSIGN_NOTICED_ENEMIES_KNOW_DIRECTION;
|
||||
}
|
||||
|
||||
++revealedpositions;
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// chance prisoner will grant us ransom money
|
||||
else if ( result < gGameExternalOptions.ubPrisonerProcessDefectChance + gGameExternalOptions.ubPrisonerProcessInfoBaseChance + gGameExternalOptions.ubPrisonerProcessRansomBaseChance )
|
||||
{
|
||||
ransommoney += (Random(5) + 1) * 100;
|
||||
|
||||
++ransomscollected;
|
||||
}
|
||||
// we have to let him go without any benefits
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// there is a chance that escaped prisoners may return to the queen...
|
||||
if ( Random( 100 ) < gGameExternalOptions.ubPrisonerReturntoQueenChance )
|
||||
++giReinforcementPool;
|
||||
}
|
||||
|
||||
if ( turnedmilitia )
|
||||
{
|
||||
// add these guys to the local garrison as green militias
|
||||
StrategicAddMilitiaToSector(sMapX, sMapY, GREEN_MILITIA, turnedmilitia);
|
||||
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_TURN_MILITIA], turnedmilitia );
|
||||
}
|
||||
|
||||
if ( revealedpositions )
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_DETECTION], revealedpositions );
|
||||
|
||||
if ( ransomscollected )
|
||||
{
|
||||
AddTransactionToPlayersBook( PRISONER_RANSOM, 0, GetWorldTotalMin(), ransommoney );
|
||||
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_RANSOM], ransomscollected );
|
||||
}
|
||||
|
||||
// give experience rewards to the interrogators
|
||||
// total experience to share
|
||||
FLOAT totalexp = 100 * prisonersinterrogated;
|
||||
FLOAT expratio = totalexp / (interrogationpoints * 33); // TODO
|
||||
|
||||
// award experience
|
||||
for ( uiCnt = 0, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= gTacticalStatus.Team[ OUR_TEAM ].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 ) )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove interrogated prisoners...
|
||||
if ( !bZ )
|
||||
{
|
||||
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ] );
|
||||
|
||||
// safety first...
|
||||
if ( prisonersinterrogated > pSectorInfo->uiNumberOfPrisonersOfWar )
|
||||
pSectorInfo->uiNumberOfPrisonersOfWar = 0;
|
||||
else
|
||||
pSectorInfo->uiNumberOfPrisonersOfWar -= prisonersinterrogated;
|
||||
}
|
||||
else
|
||||
{
|
||||
UNDERGROUND_SECTORINFO *pSectorInfo = FindUnderGroundSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
||||
|
||||
// safety first...
|
||||
if ( prisonersinterrogated > pSectorInfo->uiNumberOfPrisonersOfWar )
|
||||
pSectorInfo->uiNumberOfPrisonersOfWar = 0;
|
||||
else
|
||||
pSectorInfo->uiNumberOfPrisonersOfWar -= prisonersinterrogated;
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: prisons can riot if there aren't enough guards around
|
||||
void HandlePrison( INT16 sMapX, INT16 sMapY, INT8 bZ )
|
||||
{
|
||||
BOOLEAN fBeginRiot = FALSE;
|
||||
|
||||
// Is there a prison in this sector?
|
||||
UINT16 prisonerbaselimit = 0;
|
||||
for (UINT16 cnt = 0; cnt < NUM_FACILITY_TYPES; ++cnt)
|
||||
{
|
||||
// Is this facility here?
|
||||
if (gFacilityLocations[SECTOR(sMapX, sMapY)][cnt].fFacilityHere)
|
||||
{
|
||||
// we determine wether this is a prison by checking for usPrisonBaseLimit
|
||||
if (gFacilityTypes[cnt].AssignmentData[FAC_INTERROGATE_PRISONERS].usPrisonBaseLimit > 0)
|
||||
{
|
||||
prisonerbaselimit = gFacilityTypes[cnt].AssignmentData[FAC_INTERROGATE_PRISONERS].usPrisonBaseLimit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !prisonerbaselimit )
|
||||
return;
|
||||
|
||||
// Are there any prisoners in this prison?
|
||||
UINT32 numprisoners = 0;
|
||||
if ( !bZ )
|
||||
{
|
||||
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ] );
|
||||
|
||||
numprisoners = pSectorInfo->uiNumberOfPrisonersOfWar;
|
||||
}
|
||||
else
|
||||
{
|
||||
UNDERGROUND_SECTORINFO *pSectorInfo = FindUnderGroundSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
||||
|
||||
numprisoners = pSectorInfo->uiNumberOfPrisonersOfWar;
|
||||
}
|
||||
|
||||
if ( !numprisoners )
|
||||
return;
|
||||
|
||||
// if sector is not under our control, the prisoners are added to the local garrison
|
||||
if( !bZ && StrategicMap[ sMapX + sMapY * MAP_WORLD_X ].fEnemyControlled == TRUE )
|
||||
{
|
||||
// add enemies
|
||||
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ] );
|
||||
|
||||
pSectorInfo->ubNumTroops += numprisoners;
|
||||
|
||||
}
|
||||
|
||||
// if sector not under our control, has enemies in it, or is currently in combat mode
|
||||
if (!SectorOursAndPeaceful( sMapX, sMapY, bZ ))
|
||||
return;
|
||||
|
||||
// loop over all mercs in this sector that are on the FACILITY_INTERROGATE_PRISONERS assignment and determine their interrogation progress
|
||||
SOLDIERTYPE *pSoldier = NULL;
|
||||
UINT32 uiCnt = 0;
|
||||
UINT8 numprisonguards = 0;
|
||||
FLOAT prisonguardvalue = .0f;
|
||||
|
||||
// count any interrogators found here, and sum up their interrogation values
|
||||
UINT32 firstid = gTacticalStatus.Team[ OUR_TEAM ].bFirstID;
|
||||
UINT32 lastid = gTacticalStatus.Team[ OUR_TEAM ].bLastID;
|
||||
for ( uiCnt = firstid, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= lastid; ++uiCnt, ++pSoldier)
|
||||
{
|
||||
if( pSoldier->bActive && ( pSoldier->sSectorX == sMapX ) && ( pSoldier->sSectorY == sMapY ) && ( pSoldier->bSectorZ == bZ) && pSoldier->flags.fMercAsleep == FALSE )
|
||||
{
|
||||
++numprisonguards;
|
||||
|
||||
UINT16 tmp;
|
||||
prisonguardvalue += CalculatePrisonGuardValue(pSoldier, &tmp );
|
||||
}
|
||||
}
|
||||
// add militia strength
|
||||
if ( !bZ )
|
||||
{
|
||||
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ] );
|
||||
|
||||
prisonguardvalue += 100 * pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] + 150 * pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] + 200 * pSectorInfo->ubNumberOfCivsAtLevel[ ELITE_MILITIA ];
|
||||
}
|
||||
else
|
||||
{
|
||||
// there are no underground prisons, so screw this...
|
||||
}
|
||||
|
||||
if ( !numprisonguards )
|
||||
fBeginRiot = TRUE;
|
||||
|
||||
// we now have to determine the combined strength of the prisoners
|
||||
FLOAT prisonerriotvalue = .0f;
|
||||
for ( UINT32 i = 0; i < numprisoners; ++i )
|
||||
{
|
||||
prisonerriotvalue += 100.0f;
|
||||
}
|
||||
|
||||
if ( prisonerriotvalue > prisonguardvalue )
|
||||
{
|
||||
if ( numprisoners > prisonerbaselimit && Random( (UINT32)(prisonerriotvalue) ) > Random( (UINT32)(prisonguardvalue) ) )
|
||||
fBeginRiot = TRUE;
|
||||
}
|
||||
|
||||
if ( fBeginRiot )
|
||||
{
|
||||
// add enemies
|
||||
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ] );
|
||||
|
||||
pSectorInfo->ubNumTroops += numprisoners;
|
||||
|
||||
CHAR16 zShortTownIDString[ 50 ];
|
||||
GetShortSectorString( sMapX, sMapX, zShortTownIDString );
|
||||
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_RIOT], zShortTownIDString );
|
||||
}
|
||||
}
|
||||
|
||||
INT16 GetTownTrainPtsForCharacter( SOLDIERTYPE *pTrainer, UINT16 *pusMaxPts )
|
||||
{
|
||||
@@ -11540,6 +11972,31 @@ void SetSoldierAssignment( SOLDIERTYPE *pSoldier, INT8 bAssignment, INT32 iParam
|
||||
pSoldier->bVehicleUnderRepairID = ( INT8 )iParam3;
|
||||
}
|
||||
break;
|
||||
|
||||
case( FACILITY_INTERROGATE_PRISONERS ):
|
||||
if( pSoldier->CanProcessPrisoners() )
|
||||
{
|
||||
pSoldier->bOldAssignment = pSoldier->bAssignment;
|
||||
|
||||
// remove from squad
|
||||
RemoveCharacterFromSquads( pSoldier );
|
||||
|
||||
// remove from any vehicle
|
||||
if( pSoldier->bOldAssignment == VEHICLE )
|
||||
{
|
||||
TakeSoldierOutOfVehicle( pSoldier );
|
||||
}
|
||||
|
||||
if ( pSoldier->bAssignment != FACILITY_INTERROGATE_PRISONERS )
|
||||
{
|
||||
SetTimeOfAssignmentChangeForMerc( pSoldier );
|
||||
}
|
||||
|
||||
ChangeSoldiersAssignment( pSoldier, FACILITY_INTERROGATE_PRISONERS );
|
||||
AssignMercToAMovementGroup( pSoldier );
|
||||
}
|
||||
break;
|
||||
|
||||
case( VEHICLE ):
|
||||
if( CanCharacterVehicle( pSoldier ) && IsThisVehicleAccessibleToSoldier( pSoldier, iParam1 ) )
|
||||
{
|
||||
@@ -12610,6 +13067,10 @@ void ReEvaluateEveryonesNothingToDo()
|
||||
fNothingToDo = !CanCharacterRepair( pSoldier ) || HasCharacterFinishedRepairing( pSoldier );
|
||||
break;
|
||||
|
||||
case FACILITY_INTERROGATE_PRISONERS:
|
||||
fNothingToDo = !pSoldier->CanProcessPrisoners();
|
||||
break;
|
||||
|
||||
case TRAIN_TOWN:
|
||||
fNothingToDo = !CanCharacterTrainMilitia( pSoldier );
|
||||
break;
|
||||
@@ -12834,6 +13295,16 @@ void SetAssignmentForList( INT8 bAssignment, INT8 bParam )
|
||||
}
|
||||
break;
|
||||
|
||||
case FACILITY_INTERROGATE_PRISONERS:
|
||||
if ( CanCharacterFacility( pSoldier, bParam, FAC_INTERROGATE_PRISONERS ) && pSoldier->CanProcessPrisoners() )
|
||||
{
|
||||
pSoldier->bOldAssignment = pSoldier->bAssignment;
|
||||
ChangeSoldiersAssignment( pSoldier, FACILITY_INTERROGATE_PRISONERS );
|
||||
pSoldier->sFacilityTypeOperated = bParam;
|
||||
fItWorked = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case( SQUAD_1 ):
|
||||
case( SQUAD_2 ):
|
||||
case( SQUAD_3 ):
|
||||
@@ -16324,7 +16795,9 @@ void FacilityAssignmentMenuBtnCallback ( MOUSE_REGION * pRegion, INT32 iReason )
|
||||
pSoldier->bTrainStat = EXPLOSIVE_ASSIGN;
|
||||
ChangeSoldiersAssignment( pSoldier, TRAIN_TEAMMATE );
|
||||
break;
|
||||
|
||||
case FAC_INTERROGATE_PRISONERS:
|
||||
ChangeSoldiersAssignment( pSoldier, FACILITY_INTERROGATE_PRISONERS );
|
||||
break;
|
||||
}
|
||||
|
||||
// Flugente: I guess this piece of code is here to get a group Id for the soldier, which must not be there for movement specifically. Just my understanding, in case anybody else coming here wonders
|
||||
|
||||
@@ -64,6 +64,7 @@ enum
|
||||
FACILITY_STAFF, // HEADROCK HAM 3.6: Operating a facility for strategic gain.
|
||||
FACILITY_EAT, // added by Flugente
|
||||
FACILITY_REST, // HEADROCK HAM 3.6: Facility equivalent of resting (no assignment)
|
||||
FACILITY_INTERROGATE_PRISONERS, // added by Flugente
|
||||
ASSIGNMENT_DEAD,
|
||||
ASSIGNMENT_UNCONCIOUS, // unused
|
||||
ASSIGNMENT_POW,
|
||||
@@ -189,6 +190,9 @@ UINT16 CalculateHealingPointsForDoctor(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts,
|
||||
// find number of repair pts repairman has available
|
||||
UINT8 CalculateRepairPointsForRepairman(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts, BOOLEAN fMakeSureKitIsInHand );
|
||||
|
||||
// Flugente: calculate interrogation and prison guard values
|
||||
FLOAT CalculateInterrogationValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts );
|
||||
FLOAT CalculatePrisonGuardValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts );
|
||||
|
||||
// get bonus tarining pts due to an instructor for this student
|
||||
// HEADROCK HAM 3.5: Three functions below have lost an argument which is no longer required ("uiAtGunRange", which was "uiAtFacility" in HAM 3.4)
|
||||
|
||||
@@ -95,6 +95,10 @@ enum //strategic values for each sector
|
||||
#define SF_HAVE_SAID_PLAYER_QUOTE_NEW_SECTOR 0x00001000
|
||||
#endif
|
||||
|
||||
#define SF_ASSIGN_NOTICED_ENEMIES_HERE 0x00002000 // Flugente: info from assigment: enemies were found
|
||||
#define SF_ASSIGN_NOTICED_ENEMIES_KNOW_NUMBER 0x00004000 // Flugente: info from assigment: enemies were found, and we know their number
|
||||
#define SF_ASSIGN_NOTICED_ENEMIES_KNOW_DIRECTION 0x00008000 // Flugente: info from assigment: enemies were found, and we know the direction they are moving in
|
||||
|
||||
#define SF_SMOKE_EFFECTS_TEMP_FILE_EXISTS 0x00100000 //Temp File starts with sm_
|
||||
#define SF_LIGHTING_EFFECTS_TEMP_FILE_EXISTS 0x00200000 //Temp File starts with l_
|
||||
#define SF_REVEALED_STATUS_TEMP_FILE_EXISTS 0x01000000 //Temp File starts with v_
|
||||
@@ -182,6 +186,7 @@ enum
|
||||
FAC_TRAINER_MECHANICAL,
|
||||
FAC_TRAINER_LEADERSHIP,
|
||||
FAC_TRAINER_EXPLOSIVES,
|
||||
FAC_INTERROGATE_PRISONERS,
|
||||
NUM_FACILITY_ASSIGNMENTS,
|
||||
};
|
||||
|
||||
@@ -249,6 +254,7 @@ typedef struct FACILITYASSIGNMENTTYPE
|
||||
UINT16 usMineIncomeModifier; // Percentage income adjustment
|
||||
BOOLEAN fOnlyLocalMineAffected; // Determines whether income modifier applies to local mine only, or all mines.
|
||||
INT16 sCantinaFoodModifier; // how many food points do we get when spending time in a cantina?
|
||||
UINT16 usPrisonBaseLimit; // for how many prisoners was this prison built?
|
||||
|
||||
UINT8 ubMinimumStrength; // Minimum STR Requirement to begin this assignment
|
||||
UINT8 ubMinimumHealth; // Minimum HLT Requirement to begin this assignment
|
||||
@@ -473,7 +479,9 @@ typedef struct SECTORINFO
|
||||
BOOLEAN fCampaignSector;
|
||||
#endif
|
||||
|
||||
INT8 bPadding[ 41 ];
|
||||
UINT32 uiNumberOfPrisonersOfWar;
|
||||
|
||||
INT8 bPadding[ 37 ];
|
||||
|
||||
}SECTORINFO;
|
||||
|
||||
@@ -510,7 +518,9 @@ typedef struct UNDERGROUND_SECTORINFO
|
||||
BOOLEAN fCampaignSector;
|
||||
#endif
|
||||
|
||||
INT8 bPadding[36];
|
||||
UINT32 uiNumberOfPrisonersOfWar;
|
||||
|
||||
INT8 bPadding[32];
|
||||
//no padding left!
|
||||
}UNDERGROUND_SECTORINFO;
|
||||
|
||||
|
||||
@@ -141,12 +141,19 @@ INT16 GetFacilityModifier( UINT8 ubModifierType, UINT8 ubFacilityType, UINT8 ubA
|
||||
sAssignmentModifier = 100 + ((sAssignmentModifier-100) + (sAmbientModifier-100));
|
||||
return (sAssignmentModifier);
|
||||
|
||||
// Flugente: not needed anywhere atm
|
||||
case FACILITY_CANTINA_MOD:
|
||||
sAssignmentModifier = gFacilityTypes[ubFacilityType].AssignmentData[ubAssignmentType].sCantinaFoodModifier;
|
||||
sAmbientModifier = gFacilityTypes[ubFacilityType].AssignmentData[0].sCantinaFoodModifier;
|
||||
sAssignmentModifier = 100 + ((sAssignmentModifier-100) + (sAmbientModifier-100));
|
||||
return (sAssignmentModifier);
|
||||
|
||||
case FACILITY_PRISON_MOD:
|
||||
sAssignmentModifier = gFacilityTypes[ubFacilityType].AssignmentData[ubAssignmentType].usPrisonBaseLimit;
|
||||
sAmbientModifier = gFacilityTypes[ubFacilityType].AssignmentData[0].usPrisonBaseLimit;
|
||||
sAssignmentModifier = 100 + ((sAssignmentModifier-100) + (sAmbientModifier-100));
|
||||
return (sAssignmentModifier);
|
||||
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
@@ -906,6 +913,9 @@ INT8 GetSoldierFacilityAssignmentIndex( SOLDIERTYPE *pSoldier )
|
||||
case FACILITY_REST:
|
||||
bAssignmentIndex = FAC_REST;
|
||||
break;
|
||||
case FACILITY_INTERROGATE_PRISONERS:
|
||||
bAssignmentIndex = FAC_INTERROGATE_PRISONERS;
|
||||
break;
|
||||
default:
|
||||
bAssignmentIndex = -1;
|
||||
break;
|
||||
|
||||
@@ -47,7 +47,8 @@ enum
|
||||
FACILITY_MINE_INCOME_MOD,
|
||||
FACILITY_SKYRIDER_COST_MOD,
|
||||
|
||||
FACILITY_CANTINA_MOD
|
||||
FACILITY_CANTINA_MOD,
|
||||
FACILITY_PRISON_MOD
|
||||
};
|
||||
|
||||
// HEADROCK HAM 3.6: Different enemy detection and counting levels
|
||||
|
||||
@@ -6930,6 +6930,24 @@ UINT32 WhatPlayerKnowsAboutEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: we know that enemies are here
|
||||
if ( uiSectorFlags & SF_ASSIGN_NOTICED_ENEMIES_HERE )
|
||||
{
|
||||
fDetection = TRUE;
|
||||
|
||||
// we know how many there are
|
||||
if ( uiSectorFlags & SF_ASSIGN_NOTICED_ENEMIES_KNOW_NUMBER )
|
||||
{
|
||||
fCount = TRUE;
|
||||
}
|
||||
|
||||
// we know the direction they are moving in
|
||||
if ( uiSectorFlags & SF_ASSIGN_NOTICED_ENEMIES_KNOW_DIRECTION )
|
||||
{
|
||||
fDirection = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Facilities can set a flag that allows detection in some sectors. We can read flags directly from the sector
|
||||
// data to know whether we should show the enemies there. This overrides ANYTHING else.
|
||||
if (SectorInfo[ SECTOR( sSectorX, sSectorY ) ].ubDetectionLevel & 1)
|
||||
|
||||
@@ -99,6 +99,7 @@ void InitAssignmentDataArray( facilitytypeParseData *pData )
|
||||
pData->curAssignmentData.fOnlyLocalMineAffected = 0;
|
||||
|
||||
pData->curAssignmentData.sCantinaFoodModifier = 100;
|
||||
pData->curAssignmentData.usPrisonBaseLimit = 0;
|
||||
|
||||
pData->curAssignmentData.ubMaximumBreath = 100;
|
||||
pData->curAssignmentData.ubMaximumMorale = 100;
|
||||
@@ -220,7 +221,8 @@ facilitytypeStartElementHandle(void *userData, const XML_Char *name, const XML_C
|
||||
strcmp(name, "sSkyriderCostModifier") == 0 ||
|
||||
strcmp(name, "usMineIncomeModifier") == 0 ||
|
||||
strcmp(name, "fOnlyLocalMineAffected") == 0 ||
|
||||
strcmp(name, "sCantinaFoodModifier") == 0 ))
|
||||
strcmp(name, "sCantinaFoodModifier") == 0 ||
|
||||
strcmp(name, "usPrisonBaseLimit") == 0 ))
|
||||
{
|
||||
pData->curElement = FACILITYTYPE_ASSIGNMENT_ELEMENT;
|
||||
|
||||
@@ -453,6 +455,7 @@ facilitytypeEndElementHandle(void *userData, const XML_Char *name)
|
||||
gFacilityTypes[pData->curIndex].AssignmentData[cnt].fOnlyLocalMineAffected = pData->curFacilityTypeData.AssignmentData[cnt].fOnlyLocalMineAffected;
|
||||
|
||||
gFacilityTypes[pData->curIndex].AssignmentData[cnt].sCantinaFoodModifier = pData->curFacilityTypeData.AssignmentData[cnt].sCantinaFoodModifier;
|
||||
gFacilityTypes[pData->curIndex].AssignmentData[cnt].usPrisonBaseLimit = pData->curFacilityTypeData.AssignmentData[cnt].usPrisonBaseLimit;
|
||||
|
||||
// Conditions
|
||||
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumStrength = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumStrength;
|
||||
@@ -593,6 +596,7 @@ facilitytypeEndElementHandle(void *userData, const XML_Char *name)
|
||||
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].fOnlyLocalMineAffected = pData->curAssignmentData.fOnlyLocalMineAffected;
|
||||
|
||||
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].sCantinaFoodModifier = pData->curAssignmentData.sCantinaFoodModifier;
|
||||
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].usPrisonBaseLimit = pData->curAssignmentData.usPrisonBaseLimit;
|
||||
|
||||
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMaximumBreath = pData->curAssignmentData.ubMaximumBreath;
|
||||
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMaximumMorale = pData->curAssignmentData.ubMaximumMorale;
|
||||
@@ -823,6 +827,11 @@ facilitytypeEndElementHandle(void *userData, const XML_Char *name)
|
||||
{
|
||||
//pData->curAssignmentType = (INT16) atol(pData->szCharData);
|
||||
pData->curAssignmentType = FAC_STUDENT_EXPLOSIVES;
|
||||
}
|
||||
else if (strcmp(pData->szCharData, "INTERROGATE_PRISONERS") == 0)
|
||||
{
|
||||
//pData->curAssignmentType = (INT16) atol(pData->szCharData);
|
||||
pData->curAssignmentType = FAC_INTERROGATE_PRISONERS;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -945,7 +954,13 @@ facilitytypeEndElementHandle(void *userData, const XML_Char *name)
|
||||
else if(strcmp(name, "sCantinaFoodModifier") == 0 )
|
||||
{
|
||||
pData->curElement = FACILITYTYPE_ASSIGNMENT;
|
||||
pData->curAssignmentData.sCantinaFoodModifier = (UINT16) atol(pData->szCharData);
|
||||
pData->curAssignmentData.sCantinaFoodModifier = (INT16) atol(pData->szCharData);
|
||||
}
|
||||
|
||||
else if(strcmp(name, "usPrisonBaseLimit") == 0 )
|
||||
{
|
||||
pData->curElement = FACILITYTYPE_ASSIGNMENT;
|
||||
pData->curAssignmentData.usPrisonBaseLimit = (UINT16) atol(pData->szCharData);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user