- 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:
Flugente
2012-12-03 00:50:48 +00:00
parent 33f3fefc3b
commit cb9c217bb1
46 changed files with 1472 additions and 57 deletions
+475 -2
View File
@@ -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
+4
View File
@@ -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)
+12 -2
View File
@@ -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;
+10
View File
@@ -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;
+2 -1
View File
@@ -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
+18
View File
@@ -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)
+17 -2
View File
@@ -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);
}
//////////////////////////////////////////////