- 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
+12
View File
@@ -1551,6 +1551,17 @@ void LoadGameExternalOptions()
gGameExternalOptions.fOnlyRepairGunsArmour = iniReader.ReadBoolean("Strategic Gameplay Settings","ONLY_REPAIR_GUNS_AND_ARMOUR", FALSE);
gGameExternalOptions.fDirtSystem = iniReader.ReadBoolean("Strategic Gameplay Settings","DIRT_SYSTEM", FALSE);
gGameExternalOptions.usSectorDirtDivider = iniReader.ReadInteger("Strategic Gameplay Settings","SECTOR_DIRT_DIVIDER", 1000, 1, 100000);
// Flugente: prisoner system
gGameExternalOptions.fAllowPrisonerSystem = iniReader.ReadBoolean("Strategic Gameplay Settings","ALLOW_TAKE_PRISONERS", TRUE);
gGameExternalOptions.fEnemyCanSurrender = iniReader.ReadBoolean("Strategic Gameplay Settings","ENEMY_CAN_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", 10, 0, 100);
gGameExternalOptions.ubPrisonerProcessInfoBaseChance = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_INFO_BASECHANCE", 10, 0, 100);
gGameExternalOptions.ubPrisonerProcessInfoDetectChance = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_INFO_DETECT_CHANCE", 5, 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", 10, 0, 100);
// CHRISL: Determine how Skyrider should handle landing in enemy occupied sectors
gGameExternalOptions.ubSkyriderHotLZ = iniReader.ReadInteger("Strategic Gameplay Settings", "ALLOW_SKYRIDER_HOT_LZ", 0);
@@ -2452,6 +2463,7 @@ void LoadGameAPBPConstants()
APBPConstants[AP_CLEANINGKIT] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_CLEANINGKIT",80),80);
APBPConstants[AP_INVENTORY_EXPLOSIVE_ACTIVATE] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_INVENTORY_EXPLOSIVE_ACTIVATE",20),20);
APBPConstants[AP_DISGUISE] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_DISGUISE",80),80);
APBPConstants[AP_HANDCUFF] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_HANDCUFF",50),50);
SetupMaxActionPointsAnimation();
#undef ReadInteger
+13 -2
View File
@@ -1130,8 +1130,8 @@ typedef struct
// Flugente: Weapon Overheating
BOOLEAN fDisplayOverheatThermometer; // Should a 'thermometer' for guns and replacable barrels be displayed?
UINT8 ubOverheatThermometerRedOffset; // amount of red colour while temperature is below threshold
FLOAT iCooldownModificatorLonelyBarrel; // Cooldown modificator for barrels alone in the landscape ;-)
FLOAT iOverheatTemperatureGlobalModfier; // a global modifier to the singel shot temperatuer value, if one feels that all values hould be lower/higher
FLOAT iCooldownModificatorLonelyBarrel; // Cooldown modificator for barrels left alone in the landscape ;-)
FLOAT iOverheatTemperatureGlobalModfier; // a global modifier to the singel shot temperature value, if one feels that all values should be lower/higher
// Flugente: Weapon Mounting
BOOLEAN fWeaponResting; // Should it be possible to rest your weapon on structures in crouched position?
@@ -1150,6 +1150,17 @@ typedef struct
BOOLEAN fOnlyRepairGunsArmour; // we can only repair guns and armour
BOOLEAN fDirtSystem; // allow dirt on items increase the chance for weapon jamming
UINT32 usSectorDirtDivider; // divide a guns dirt factor by this to get dirt increase for every turn
// Flugente: prisoner related settings
BOOLEAN fAllowPrisonerSystem;
BOOLEAN fEnemyCanSurrender;
UINT8 ubPrisonerReturntoQueenChance;
UINT8 ubPrisonerProcessDefectChance;
UINT8 ubPrisonerProcessInfoBaseChance;
UINT8 ubPrisonerProcessInfoDetectChance;
UINT8 ubPrisonerProcessInfoNumberChance;
UINT8 ubPrisonerProcessInfoDirectionChance;
UINT8 ubPrisonerProcessRansomBaseChance;
// Sandro: Alternative weapon holding (rifles fired from hip / pistols fired one-handed)
UINT8 ubAllowAlternativeWeaponHolding;
+2 -1
View File
@@ -20,8 +20,9 @@ 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 SAVE_GAME_VERSION 135 // 134 // 133 // 132 //131 //125 //124 //114 //113 //112 //111 //110 //109 //108 //107 //106 //105 //104 //103 //102 //101 //100 // 99
#define SAVE_GAME_VERSION 136 // 134 // 133 // 132 //131 //125 //124 //114 //113 //112 //111 //110 //109 //108 //107 //106 //105 //104 //103 //102 //101 //100 // 99
#define PRISON_SYSTEM 136 // Flugente: added var to the sector structure. Shouldn't break compatibility, but let's be safe
#define DUAL_BURST_ADDED 135
#define MORE_ROOMS 134 // changed room numbers from 8 to 16 bit by DBrot
#define FOOD_CHANGES 133 // changes for food system
+1
View File
@@ -202,6 +202,7 @@ AP_EAT,
AP_CLEANINGKIT,
AP_INVENTORY_EXPLOSIVE_ACTIVATE,
AP_DISGUISE,
AP_HANDCUFF,
TOTAL_APBP_VALUES
};
#endif
+5
View File
@@ -1571,6 +1571,11 @@ void ProcessTransactionString(STR16 pString, FinanceUnitPtr pFinance)
swprintf(pString, L"%s", pTransactionText[ MILITIA_UPKEEP ]);
break;
// Flugente: ransom from released prisoners
case PRISONER_RANSOM:
swprintf(pString, L"%s", pTransactionText[ PRISONER_RANSOM ]);
break;
}
+1
View File
@@ -53,6 +53,7 @@ enum
SOLD_ITEMS,
FACILITY_OPERATIONS, // HEADROCK HAM 3.6: Facility costs (daily payment)
MILITIA_UPKEEP, // HEADROCK HAM 3.6: Militia Upkeep Costs (daily payment)
PRISONER_RANSOM, // Flugente: ransom for released prisoners
TEXT_NUM_FINCANCES
};
+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);
}
//////////////////////////////////////////////
+8
View File
@@ -2404,6 +2404,14 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
}
break;
case FACILITY_INTERROGATE_PRISONERS:
sIconIndex = 23;
fDoIcon = TRUE;
sPtsAvailable = (INT16)( CalculateInterrogationValue(pSoldier, &usMaximumPts ) ) / 100;
fShowNumber = TRUE;
fShowMaximum = TRUE;
break;
}
// Check for being serviced...
+82 -1
View File
@@ -1215,6 +1215,87 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
}
}
// Flugente: handcuffing people
if ( HasItemFlag(usHandItem, HANDCUFFS ) )
{
// ATE: AI CANNOT GO THROUGH HERE!
INT32 usMapPos;
BOOLEAN fHadToUseCursorPos = FALSE;
GetMouseMapPos( &usMapPos );
// See if we can get there to stab
sActionGridNo = FindAdjacentGridEx( pSoldier, sGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
if ( sActionGridNo == -1 )
{
// Try another location...
sActionGridNo = FindAdjacentGridEx( pSoldier, usMapPos, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
if ( sActionGridNo == -1 )
{
return( ITEM_HANDLE_CANNOT_GETTO_LOCATION );
}
/*if ( !gTacticalStatus.fAutoBandageMode )
{
fHadToUseCursorPos = TRUE;
}*/
}
// Calculate AP costs...
sAPCost = GetAPsToHandcuff( pSoldier, sActionGridNo );
sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints);
if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) )
{
// OK, set UI
SetUIBusy( pSoldier->ubID );
// CHECK IF WE ARE AT THIS GRIDNO NOW
if ( pSoldier->sGridNo != sActionGridNo )
{
// SEND PENDING ACTION
pSoldier->aiData.ubPendingAction = MERC_HANDCUFF_PERSON;
if ( fHadToUseCursorPos )
{
pSoldier->aiData.sPendingActionData2 = usMapPos;
}
else
{
if ( pTargetSoldier != NULL )
{
pSoldier->aiData.sPendingActionData2 = pTargetSoldier->sGridNo;
}
else
{
pSoldier->aiData.sPendingActionData2 = sGridNo;
}
}
pSoldier->aiData.bPendingActionData3 = ubDirection;
pSoldier->aiData.ubPendingActionAnimCount = 0;
// WALK UP TO DEST FIRST
pSoldier->EVENT_InternalGetNewSoldierPath( sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE );
}
else
{
pSoldier->EVENT_SoldierHandcuffPerson( sAdjustedGridNo, ubDirection );
}
if ( fFromUI )
{
guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
}
return( ITEM_HANDLE_OK );
}
else
{
return( ITEM_HANDLE_NOAPS );
}
}
if ( Item[usHandItem].canandstring )
{
STRUCTURE *pStructure;
@@ -4574,7 +4655,7 @@ void CleanWeapons( BOOLEAN fCleanAll )
if ( pSoldier->bActive )
pSoldier->CleanWeapon(fCleanAll);
}
else // peform action for every merc in this sector
else // perform action for every merc in this sector
{
UINT8 bMercID, bLastTeamID;
SOLDIERTYPE* pSoldier = NULL;
+33
View File
@@ -4142,6 +4142,24 @@ INT8 DrawUIMovementPath( SOLDIERTYPE *pSoldier, INT32 usMapPos, UINT32 uiFlags )
gsUIHandleShowMoveGridLocation = sActionGridNo;
}
}
else if ( uiFlags == MOVEUI_TARGET_HANDCUFF )
{
sActionGridNo = FindAdjacentGridEx( pSoldier, usMapPos, &ubDirection, NULL, FALSE, TRUE );
if ( sActionGridNo == -1 )
{
sActionGridNo = usMapPos;
}
sAPCost = GetAPsToHandcuff( pSoldier, sActionGridNo );
sAPCost += UIPlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, fPlot, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints);
if ( sActionGridNo != pSoldier->sGridNo )
{
gfUIHandleShowMoveGrid = TRUE;
gsUIHandleShowMoveGridLocation = sActionGridNo;
}
}
else if ( uiFlags == MOVEUI_TARGET_MERCS )
{
INT32 sGotLocation = NOWHERE;
@@ -4494,6 +4512,21 @@ BOOLEAN UIMouseOnValidAttackLocation( SOLDIERTYPE *pSoldier )
return( FALSE );
}
if ( ubItemCursor == HANDCUFFCURS )
{
if ( HasItemFlag( (&(pSoldier->inv[HANDPOS]))->usItem, HANDCUFFS ) )
{
if ( gfUIFullTargetFound )
{
usMapPos = MercPtrs[ gusUIFullTargetID ]->sGridNo;
return( TRUE );
}
}
return( FALSE );
}
if ( ubItemCursor == BOMBCURS )
{
if ( usMapPos == pSoldier->sGridNo )
+1
View File
@@ -30,6 +30,7 @@
#define MOVEUI_TARGET_CAN 11
#define MOVEUI_TARGET_REFUEL 12
#define MOVEUI_TARGET_FORTIFICATION 13
#define MOVEUI_TARGET_HANDCUFF 14
#define MOVEUI_RETURN_ON_TARGET_MERC 1
+3
View File
@@ -215,6 +215,9 @@ UICursor gUICursors[ NUM_UI_CURSORS ] =
FORTIFICATION_GREY_UICURSOR, UICURSOR_FREEFLOWING, CURSOR_FORTIFICATION, 0,
FORTIFICATION_RED_UICURSOR, UICURSOR_FREEFLOWING, CURSOR_FORTIFICATION_RED, 0,
HANDCUFF_GREY_UICURSOR, UICURSOR_FREEFLOWING, CURSOR_HANDCUFF, 0,
HANDCUFF_RED_UICURSOR, UICURSOR_FREEFLOWING, CURSOR_HANDCUFF_RED, 0,
};
+3
View File
@@ -189,6 +189,9 @@ typedef enum
FORTIFICATION_GREY_UICURSOR,
FORTIFICATION_RED_UICURSOR,
HANDCUFF_GREY_UICURSOR,
HANDCUFF_RED_UICURSOR,
NUM_UI_CURSORS
} UICursorDefines;
+4
View File
@@ -5043,6 +5043,10 @@ STR16 GetSoldierHealthString( SOLDIERTYPE *pSoldier )
}
else
{
// Flugente: display if we are a prisoner of war
if ( pSoldier->bSoldierFlagMask & SOLDIER_POW )
return zHealthStr[ 7 ];
INT32 cnt, cntStart;
if( pSoldier->stats.bLife == pSoldier->stats.bLifeMax )
{
+5 -4
View File
@@ -174,6 +174,7 @@ typedef enum ATTACHMENT_SLOT{
#define TINCANCURS 22
#define REFUELCURS 23
#define FORTICURS 24
#define HANDCUFFCURS 25
#define CAMERARANGE 10
@@ -728,7 +729,7 @@ extern OBJECTTYPE gTempObject;
// note that these should not be used to determine what kind of an attachment an item is, that is determined by attachmentclass and the AC_xxx flags above
#define EMPTY_SANDBAG 0x00000001 //1
#define FULL_SANDBAG 0x00000002 //2
#define SHOVEL 0x00000004 //4
#define SHOVEL 0x00000004 //4 // a shovel is used for filling sandbags and other building-related tasks
#define CONCERTINA 0x00000008 //8
#define WATER_DRUM 0x00000010 //16 // water drums allow to refill canteens in the sector they are in
@@ -743,15 +744,15 @@ extern OBJECTTYPE gTempObject;
#define ATTENTION_ITEM 0x00001000 //4096 // this item is 'interesting' to the AI. Dumb soldiers may try to pick it up
#define GAROTTE 0x00002000 //8192 // this item is a garotte
#define COVERT 0x00004000 //16384 // if LBE, any gun inside will be covert. On a gun, it will covert in any LBE, even if the LBE does not have that tag itself
#define COVERT 0x00004000 //16384 // if LBE, any gun inside will be covert. On a gun, it will be covert in any LBE, even if the LBE does not have that tag itself
#define CORPSE 0x00008000 //32768 // a dead body
#define SKIN_BLOODCAT 0x00010000 //65536 // retrieve this by skinning (=decapitating) a bloodcat
#define NO_METAL_DETECTION 0x00020000 //131072 // a planted bomb with this flag can NOT be detected via metal detector. Use sparingly!
#define JUMP_GRENADE 0x00040000 //262144 // add +25 heigth to explosion, used for bouncing grenades and jumping mines
/*#define PLAYER_NET_4_LVL_1 0x00080000 //524288
#define HANDCUFFS 0x00080000 //524288 // item can be used to capture soldiers
#define PLAYER_NET_1_LVL_2 0x00100000 //1048576
/*#define PLAYER_NET_1_LVL_2 0x00100000 //1048576
#define PLAYER_NET_2_LVL_2 0x00200000 //2097152
#define PLAYER_NET_3_LVL_2 0x00400000 //4194304
#define PLAYER_NET_4_LVL_2 0x00800000 //8388608
+1 -1
View File
@@ -711,7 +711,7 @@ void HandleMoraleEvent( SOLDIERTYPE *pSoldier, INT8 bMoraleEvent, INT16 sMapX, I
if ( gGameOptions.fNewTraitSystem )
{
// Flugente: if we have the covert trait and are covert, we might simply be returning from a reconnaissance mission in enemy territory. No need for a morale drop in this case
if ( !HAS_SKILL_TRAIT( pTeamSoldier, COVERT_NT ) || ( pTeamSoldier->bSoldierFlagMask & (SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER) == 0) )
if ( !HAS_SKILL_TRAIT( pTeamSoldier, COVERT_NT ) || ( (pTeamSoldier->bSoldierFlagMask & (SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER)) == 0) )
{
// SANDRO - no penalty for pacifists to run away
if ( gMercProfiles[pTeamSoldier->ubProfile].bCharacterTrait != CHAR_TRAIT_PACIFIST )
+247 -1
View File
@@ -1660,6 +1660,11 @@ BOOLEAN ExecuteOverhead( )
pSoldier->EVENT_SoldierBuildStructure( pSoldier->aiData.sPendingActionData2, pSoldier->aiData.bPendingActionData3 );
pSoldier->aiData.ubPendingAction = NO_PENDING_ACTION;
}
else if ( pSoldier->aiData.ubPendingAction == MERC_HANDCUFF_PERSON )
{
pSoldier->EVENT_SoldierHandcuffPerson( pSoldier->aiData.sPendingActionData2, pSoldier->aiData.bPendingActionData3 );
pSoldier->aiData.ubPendingAction = NO_PENDING_ACTION;
}
else if ( pSoldier->aiData.ubPendingAction == MERC_GIVEITEM )
{
pSoldier->EVENT_SoldierBeginGiveItem( );
@@ -4040,7 +4045,7 @@ UINT8 LastActiveTeamMember( UINT8 ubTeam )
void CheckForPotentialAddToBattleIncrement( SOLDIERTYPE *pSoldier )
{
UINT16 iCounter2;
//UINT16 iCounter2;
// Check if we are a threat!
if ( !pSoldier->aiData.bNeutral && (pSoldier->bSide != gbPlayerNum ) )
{
@@ -6632,6 +6637,240 @@ void DeathNoMessageTimerCallback( void )
}
}
BOOLEAN GetPlayerControlledPrisonSectorId(UINT32& auSectorID)
{
auSectorID = 0;
UINT16 highestprisonsize = 0;
for(INT16 sX = 1; sX < MAP_WORLD_X - 1; ++sX )
{
for(INT16 sY = 1; sY < MAP_WORLD_X - 1; ++sY )
{
if ( !SectorOursAndPeaceful( sX, sY, 0 ) )
continue;
// Is there a prison in this sector?
for (UINT16 cnt = 0; cnt < NUM_FACILITY_TYPES; ++cnt)
{
// Is this facility here?
if (gFacilityLocations[SECTOR(sX, sY)][cnt].fFacilityHere)
{
// we determine wether this is a prison by checking for usPrisonBaseLimit
if ( gFacilityTypes[cnt].AssignmentData[FAC_INTERROGATE_PRISONERS].usPrisonBaseLimit > highestprisonsize )
{
highestprisonsize = gFacilityTypes[cnt].AssignmentData[FAC_INTERROGATE_PRISONERS].usPrisonBaseLimit;
auSectorID = SECTOR(sX, sY);
break;
}
}
}
}
}
return (highestprisonsize > 0);
}
extern INT32 giReinforcementPool;
void PrisonerMessageBoxCallBack( UINT8 ubExitValue )
{
if ( !gbWorldSectorZ )
{
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ] );
UINT32 prisonerstobemoved = pSectorInfo->uiNumberOfPrisonersOfWar;
pSectorInfo->uiNumberOfPrisonersOfWar = 0;
if (ubExitValue == MSG_BOX_RETURN_YES)
{
UINT32 uSectorID = 0;
if ( GetPlayerControlledPrisonSectorId(uSectorID) )
{
SECTORINFO *pPrisonSectorInfo = &( SectorInfo[ uSectorID ] );
if ( pPrisonSectorInfo )
pPrisonSectorInfo->uiNumberOfPrisonersOfWar += prisonerstobemoved;
}
}
else
{
// send some prisoners back to queen's pool
// there is a chance that escaped prisoners may return to the queen...
giReinforcementPool += (prisonerstobemoved * gGameExternalOptions.ubPrisonerReturntoQueenChance) / 100;
}
}
else
{
UNDERGROUND_SECTORINFO *pSectorInfo = FindUnderGroundSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
UINT32 prisonerstobemoved = pSectorInfo->uiNumberOfPrisonersOfWar;
pSectorInfo->uiNumberOfPrisonersOfWar = 0;
if (ubExitValue == MSG_BOX_RETURN_YES)
{
UINT32 uSectorID = 0;
if ( GetPlayerControlledPrisonSectorId(uSectorID) )
{
SECTORINFO *pPrisonSectorInfo = &( SectorInfo[ uSectorID ] );
if ( pPrisonSectorInfo )
pPrisonSectorInfo->uiNumberOfPrisonersOfWar += prisonerstobemoved;
}
}
else
{
// send some prisoners back to queen's pool
// there is a chance that escaped prisoners may return to the queen...
giReinforcementPool += (prisonerstobemoved * gGameExternalOptions.ubPrisonerReturntoQueenChance) / 100;
}
}
}
void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
SOLDIERTYPE *pTeamSoldier;
INT32 cnt = 0;
UINT8 ubNumPrisoners = 0;
UINT8 ubNumPrisonerAdmin = 0;
UINT8 ubNumPrisonerTroop = 0;
UINT8 ubNumPrisonerElite = 0;
// Check if the battle is won!
// Loop through all mercs and make go
for ( pTeamSoldier = Menptr, cnt = 0; cnt < TOTAL_SOLDIERS; ++pTeamSoldier, ++cnt )
{
// Kill those not already dead.,...
if ( pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->bTeam == ENEMY_TEAM )
{
// For sure for flag thet they are dead is not set
if ( ( pTeamSoldier->bSoldierFlagMask & SOLDIER_POW ) && !( pTeamSoldier->flags.uiStatusFlags & SOLDIER_DEAD ) )
{
if ( pTeamSoldier->stats.bLife > OKLIFE && pTeamSoldier->stats.bLife != 0 )
{
switch ( pTeamSoldier->ubSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR: ubNumPrisonerAdmin++; break;
case SOLDIER_CLASS_ARMY: ubNumPrisonerTroop++; break;
case SOLDIER_CLASS_ELITE: ubNumPrisonerElite++; break;
default:
// if none of the above classes, ignore this one
continue;
break;
}
++ubNumPrisoners;
// place items on the floor
INT8 bVisible = 0;
UINT16 usItemFlags = 0;
UINT8 size = pTeamSoldier->inv.size();
for ( UINT8 cnt = 0; cnt < size; ++cnt )
{
OBJECTTYPE* pObj = &( pTeamSoldier->inv[ cnt ] );
if ( pObj->exists() == true )
{
// Check if it's supposed to be dropped
if ( !( (*pObj).fFlags & OBJECT_UNDROPPABLE ) || pTeamSoldier->bTeam == gbPlayerNum )
{
if ( !(Item[ pObj->usItem ].defaultundroppable ) )
{
//ReduceAmmoDroppedByNonPlayerSoldiers( pTeamSoldier, cnt );
//if this soldier was an enemy
// Kaiden: Added from UB's reveal all items after combat feature!
// HEADROCK HAM B2.8: Now also reveals equipment dropped by militia, if requirement is met.
if( pTeamSoldier->bTeam == ENEMY_TEAM ||
( gGameExternalOptions.ubMilitiaDropEquipment == 2 && pTeamSoldier->bTeam == MILITIA_TEAM ) ||
( gGameExternalOptions.ubMilitiaDropEquipment == 1 && pTeamSoldier->bTeam == MILITIA_TEAM && Menptr[ pTeamSoldier->ubAttackerID ].bTeam != OUR_TEAM ))
{
//add a flag to the item so when all enemies are killed, we can run through and reveal all the enemies items
usItemFlags |= WORLD_ITEM_DROPPED_FROM_ENEMY;
if ( Item[pObj->usItem].damageable && Item[pObj->usItem].usItemClass != IC_THROWING_KNIFE ) // Madd: drop crappier items from enemies on higher difficulty levels - note the quick fix for throwing knives
{
(*pObj)[0]->data.objectStatus -= (gGameOptions.ubDifficultyLevel - 1) * Random(20);
(*pObj)[0]->data.objectStatus = min(max((*pObj)[0]->data.objectStatus,1),100); // never below 1% or above 100%
(*pObj)[0]->data.sRepairThreshold = max(1, min(100, ((*pObj)[0]->data.objectStatus + 200)/3 ));
}
}
//if(UsingNewAttachmentSystem()==true)
//ReduceAttachmentsOnGunForNonPlayerChars(pTeamSoldier, pObj);
// HEADROCK HAM B2.8: Militia will drop items only if allowed.
if (!(gGameExternalOptions.ubMilitiaDropEquipment == 0 && pTeamSoldier->bTeam == MILITIA_TEAM ) &&
!(gGameExternalOptions.ubMilitiaDropEquipment == 1 && pTeamSoldier->bTeam == MILITIA_TEAM && Menptr[ pTeamSoldier->ubAttackerID ].bTeam == OUR_TEAM ))
{
AddItemToPool( pTeamSoldier->sGridNo, pObj, bVisible , pTeamSoldier->pathing.bLevel, usItemFlags, -1 );
}
}
}
}
}
DropKeysInKeyRing( pTeamSoldier, pTeamSoldier->sGridNo, pTeamSoldier->pathing.bLevel, bVisible, FALSE, 0, FALSE );
// Make team look for items
AllSoldiersLookforItems( TRUE );
if ( pTeamSoldier->bTeam != gbPlayerNum )
// Remove merc!
// ATE: Remove merc slot first - will disappear if no corpse data found!
TacticalRemoveSoldier( pTeamSoldier->ubID );
else
pTeamSoldier->RemoveSoldierFromGridNo( );
// Remove as target
RemoveManAsTarget( pTeamSoldier );
}
}
}
}
if (!bMapZ) // Battle ended Above-ground
{
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] );
pSectorInfo->uiNumberOfPrisonersOfWar += ubNumPrisoners;
pSectorInfo->ubNumAdmins -= ubNumPrisonerAdmin;
pSectorInfo->ubNumTroops -= ubNumPrisonerTroop;
pSectorInfo->ubNumElites -= ubNumPrisonerElite;
pSectorInfo->ubAdminsInBattle -= ubNumPrisonerAdmin;
pSectorInfo->ubTroopsInBattle -= ubNumPrisonerTroop;
pSectorInfo->ubElitesInBattle -= ubNumPrisonerElite;
}
else
{
UNDERGROUND_SECTORINFO *pSectorInfo = FindUnderGroundSector( sMapX, sMapY, bMapZ );
pSectorInfo->uiNumberOfPrisonersOfWar += ubNumPrisoners;
pSectorInfo->ubNumAdmins -= ubNumPrisonerAdmin;
pSectorInfo->ubNumTroops -= ubNumPrisonerTroop;
pSectorInfo->ubNumElites -= ubNumPrisonerElite;
pSectorInfo->ubAdminsInBattle -= ubNumPrisonerAdmin;
pSectorInfo->ubTroopsInBattle -= ubNumPrisonerTroop;
pSectorInfo->ubElitesInBattle -= ubNumPrisonerElite;
}
if ( ubNumPrisoners )
{
//if ( guiCurrentScreen == GAME_SCREEN )
UINT32 uSectorID = 0;
if ( GetPlayerControlledPrisonSectorId(uSectorID) )
DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ PRISONER_DECIDE_STR ], guiCurrentScreen, ( UINT8 )MSG_BOX_FLAG_YESNO, PrisonerMessageBoxCallBack, NULL );
else
DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ PRISONER_NO_PRISONS_STR ], guiCurrentScreen, ( UINT8 )MSG_BOX_FLAG_OK, NULL, NULL );
}
}
void RemoveStaticEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
if (!bMapZ) // Battle ended Above-ground
@@ -6829,6 +7068,9 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated )
}
}
// Flugente: remove those enemies that are captured and add them to the prisoner pool
RemoveCapturedEnemiesFromSectorInfo( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
// Kill all enemies. Sometime even after killing all the enemies, there appeares "in battle" enemies in sector info
RemoveStaticEnemiesFromSectorInfo( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
@@ -7431,6 +7673,10 @@ UINT8 NumCapableEnemyInSector( )
}
else
{
// Flugente: captured soldiers also do not count
if ( pTeamSoldier->bSoldierFlagMask & SOLDIER_POW )
continue;
// Check for any more badguys
if ( !pTeamSoldier->aiData.bNeutral && (pTeamSoldier->bSide != 0 ) )
{
+10 -1
View File
@@ -3663,9 +3663,18 @@ INT16 GetAPsToBuildFortification( SOLDIERTYPE *pSoldier, INT32 usMapPos )
sAPCost += APBPConstants[AP_FORTIFICATION];
return sAPCost;
}
INT16 GetAPsToHandcuff( SOLDIERTYPE *pSoldier, INT32 usMapPos )
{
INT16 sAPCost = 0;
sAPCost = PlotPath( pSoldier, usMapPos, NO_COPYROUTE, NO_PLOT, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints );
sAPCost += APBPConstants[AP_HANDCUFF];
return sAPCost;
}
INT16 GetAPsToJumpOver( SOLDIERTYPE *pSoldier )
{
+1
View File
@@ -357,6 +357,7 @@ INT16 GetAPsToUseCan( SOLDIERTYPE *pSoldier, INT32 usMapPos );
INT16 GetBPsTouseJar( SOLDIERTYPE *pSoldier );
INT16 GetAPsToBuildFortification( SOLDIERTYPE *pSoldier, INT32 usMapPos ); // added by Flugente
INT16 GetAPsToHandcuff( SOLDIERTYPE *pSoldier, INT32 usMapPos ); // added by Flugente
INT16 GetAPsToJumpOver( SOLDIERTYPE *pSoldier );
+142
View File
@@ -15217,6 +15217,51 @@ void SOLDIERTYPE::Strip()
}
}
// can we process prisoners in this sector?
BOOLEAN SOLDIERTYPE::CanProcessPrisoners()
{
if ( !bInSector || stats.bLife < OKLIFE )
return FALSE;
// Is there a prison in this sector?
BOOLEAN prisonhere = FALSE;
for (UINT16 cnt = 0; cnt < NUM_FACILITY_TYPES; ++cnt)
{
// Is this facility here?
if (gFacilityLocations[SECTOR(this->sSectorX, this->sSectorY)][cnt].fFacilityHere)
{
// we determine wether this is a prison by checking for usPrisonBaseLimit
if (gFacilityTypes[cnt].AssignmentData[FAC_INTERROGATE_PRISONERS].usPrisonBaseLimit > 0)
{
prisonhere = TRUE;
break;
}
}
}
if ( !prisonhere )
return FALSE;
// Are there any prisoners in this prison?
if ( !this->bSectorZ )
{
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ] );
if ( pSectorInfo->uiNumberOfPrisonersOfWar > 0 )
return TRUE;
}
// no underground prisons anyway
/*else
{
UNDERGROUND_SECTORINFO *pSectorInfo = FindUnderGroundSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
if ( pSectorInfo->uiNumberOfPrisonersOfWar > 0 )
return TRUE;
}*/
return FALSE;
}
INT32 CheckBleeding( SOLDIERTYPE *pSoldier )
{
INT8 bBandaged; //,savedOurTurn;
@@ -16115,6 +16160,103 @@ void SOLDIERTYPE::EVENT_SoldierBuildStructure( INT32 sGridNo, UINT8 ubDirection
}
}
void SOLDIERTYPE::EVENT_SoldierHandcuffPerson( INT32 sGridNo, UINT8 ubDirection )
{
UINT8 ubPerson = WhoIsThere2( sGridNo, this->pathing.bLevel );
if ( ubPerson != NOBODY && MercPtrs[ ubPerson ]->bTeam == ENEMY_TEAM && !(MercPtrs[ ubPerson ]->bSoldierFlagMask & SOLDIER_POW) )
{
// we found someone we can handcuff
SOLDIERTYPE* pSoldier = MercPtrs[ ubPerson ];
// check wether we will be successful
BOOLEAN success = FALSE;
if ( pSoldier->flags.fMercAsleep || pSoldier->bCollapsed )
success = TRUE;
else
{
// check wether we can forcefully handcuff the other soldier, but this will be hard
UINT32 attackrating = 10 * EffectiveExpLevel( this ) + EffectiveStrength( this, FALSE ) + 2 * EffectiveDexterity( this, FALSE ) + EffectiveAgility( this, FALSE );
UINT32 defenserating = 10 * EffectiveExpLevel( pSoldier ) + 2 * EffectiveStrength( pSoldier, FALSE ) + EffectiveDexterity( pSoldier, FALSE ) + 2 * EffectiveAgility( pSoldier, FALSE );
ReducePointsForFatigue( this, &attackrating );
ReducePointsForFatigue( pSoldier, &defenserating );
if ( Random(attackrating) > Random(defenserating) + 50 )
success = TRUE;
}
if ( success )
{
// arrest this guy
pSoldier->bSoldierFlagMask |= SOLDIER_POW;
// move the items in his hands to the floor and move our handcuff into his hands
if ( pSoldier->inv[ HANDPOS ].exists() == true && !( pSoldier->inv[ HANDPOS ].fFlags & OBJECT_UNDROPPABLE ))
{
// ATE: if our guy, make visible....
INT8 bVisible = (pSoldier->bTeam == gbPlayerNum) ? 1 : 0;
UINT16 itemflags = ( pSoldier->bTeam == ENEMY_TEAM ) ? 0 : WORLD_ITEM_DROPPED_FROM_ENEMY;
if(UsingNewAttachmentSystem()==true)
ReduceAttachmentsOnGunForNonPlayerChars(pSoldier, &(pSoldier->inv[ HANDPOS ]));
AddItemToPool( pSoldier->sGridNo, &(pSoldier->inv[ HANDPOS ]), bVisible, pSoldier->pathing.bLevel, itemflags, -1 ); //Madd: added usItemFlags to function arguments
DeleteObj( &(pSoldier->inv[HANDPOS]) );
}
if ( pSoldier->inv[ SECONDHANDPOS ].exists() == true && !( pSoldier->inv[ SECONDHANDPOS ].fFlags & OBJECT_UNDROPPABLE ))
{
// ATE: if our guy, make visible....
INT8 bVisible = (pSoldier->bTeam == gbPlayerNum) ? 1 : 0;
UINT16 itemflags = ( pSoldier->bTeam == ENEMY_TEAM ) ? 0 : WORLD_ITEM_DROPPED_FROM_ENEMY;
if(UsingNewAttachmentSystem()==true)
ReduceAttachmentsOnGunForNonPlayerChars(pSoldier, &(pSoldier->inv[ SECONDHANDPOS ]));
AddItemToPool( pSoldier->sGridNo, &(pSoldier->inv[ SECONDHANDPOS ]), bVisible, pSoldier->pathing.bLevel, itemflags, -1 ); //Madd: added usItemFlags to function arguments
DeleteObj( &(pSoldier->inv[SECONDHANDPOS]) );
}
// move handcuffs to his hands
if ( HasItemFlag( (&(this->inv[HANDPOS]))->usItem, HANDCUFFS ) )
{
AutoPlaceObject( pSoldier, &(this->inv[HANDPOS]), FALSE );
DeleteObj( &(this->inv[HANDPOS]) );
}
// CHANGE DIRECTION AND GOTO ANIMATION NOW
this->EVENT_SetSoldierDesiredDirection( ubDirection );
this->EVENT_SetSoldierDirection( ubDirection );
// CHANGE TO ANIMATION
this->EVENT_InitNewSoldierAnim( RELOAD_ROBOT, 0 , FALSE );
// we gain a bit of experience...
StatChange( this, STRAMT, 2, TRUE );
StatChange( this, DEXTAMT, 3, TRUE );
StatChange( this, EXPERAMT, 2, TRUE );
DeductPoints( this, GetAPsToHandcuff( this, sGridNo ), 0, AFTERACTION_INTERRUPT );
}
else
{
// we gain a bit of experience...
StatChange( this, DEXTAMT, 2, TRUE );
DeductPoints( this, GetAPsToHandcuff( this, sGridNo ), 0, AFTERACTION_INTERRUPT );
// curses!
this->DoMercBattleSound( BATTLE_SOUND_CURSE1 );
}
}
else
{
// Say NOTHING quote...
this->DoMercBattleSound( BATTLE_SOUND_NOTHING );
}
}
void SOLDIERTYPE::EVENT_SoldierBeginReloadRobot( INT32 sGridNo, UINT8 ubDirection, UINT8 ubMercSlot )
{
+8 -3
View File
@@ -223,6 +223,7 @@ enum
MERC_ATTACH_CAN,
MERC_FUEL_VEHICLE,
MERC_BUILD_FORTIFICATION,
MERC_HANDCUFF_PERSON,
};
// ENUMERATIONS FOR THROW ACTIONS
@@ -356,8 +357,8 @@ enum
#define SOLDIER_DAMAGED_PANTS 0x00000100 //256 // Soldier's vest is damaged (and thus can't be taken off)
#define SOLDIER_HEADSHOT 0x00000200 //512 // last hit received was a headshot (attack to the head, so knifes/punches also work)
/*#define WH40K_POWER_WEAPON 0x00000400 //1024
#define ENEMY_NET_4_LVL_3 0x00000800 //2048
#define SOLDIER_POW 0x00000400 //1024 // we are a prisoner of war
/*#define ENEMY_NET_4_LVL_3 0x00000800 //2048
#define ENEMY_NET_1_LVL_4 0x00001000 //4096
#define ENEMY_NET_2_LVL_4 0x00002000 //8192
@@ -411,7 +412,7 @@ extern CLOTHES_STRUCT Clothes[CLOTHES_MAX];
// This macro should be used whenever we want to see if someone is neutral
// IF WE ARE CONSIDERING ATTACKING THEM. Creatures & bloodcats will attack neutrals
// but they can't attack empty vehicles!!
#define CONSIDERED_NEUTRAL( me, them ) ( (them->aiData.bNeutral || them->bSoldierFlagMask & (SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER)) && ( me->bTeam != CREATURE_TEAM || (them->flags.uiStatusFlags & SOLDIER_VEHICLE) ) )
#define CONSIDERED_NEUTRAL( me, them ) ( (them->aiData.bNeutral || them->bSoldierFlagMask & (SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER|SOLDIER_POW)) && ( me->bTeam != CREATURE_TEAM || (them->flags.uiStatusFlags & SOLDIER_VEHICLE) ) )
typedef struct
{
@@ -1322,6 +1323,7 @@ public:
void EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCounter );
void EVENT_SoldierBuildStructure( INT32 sGridNo, UINT8 ubDirection ); // added by Flugente
void EVENT_SoldierHandcuffPerson( INT32 sGridNo, UINT8 ubDirection ); // added by Flugente
BOOLEAN EVENT_InternalGetNewSoldierPath( INT32 sDestGridNo, UINT16 usMovementAnim, BOOLEAN fFromUI, BOOLEAN fForceRestart );
void EVENT_InternalSetSoldierDestination( UINT16 usNewDirection, BOOLEAN fFromMove, UINT16 usAnimState );
@@ -1494,6 +1496,9 @@ public:
// lose disguise or take off any clothes item and switch back to original clothes
void Strip();
// Flugente: prisoner system
BOOLEAN CanProcessPrisoners();
//////////////////////////////////////////////////////////////////////////////
}; // SOLDIERTYPE;
+29
View File
@@ -54,6 +54,7 @@ UINT8 HandleBombCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fActivated
UINT8 HandleJarCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT32 uiCursorFlags );
UINT8 HandleTinCanCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT32 uiCursorFlags );
UINT8 HandleFortificationCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT32 uiCursorFlags ); //added by Flugente
UINT8 HandleHandcuffCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT32 uiCursorFlags ); //added by Flugente
extern BOOLEAN HandleCheckForBadChangeToGetThrough( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pTargetSoldier, INT32 sTargetGridNo , INT8 bLevel );
@@ -304,6 +305,11 @@ UINT8 GetProperItemCursor( UINT8 ubSoldierID, UINT16 ubItemIndex, INT32 usMapPos
ubCursorID = HandleFortificationCursor( pSoldier, sTargetGridNo, uiCursorFlags );
break;
case HANDCUFFCURS:
ubCursorID = HandleHandcuffCursor( pSoldier, sTargetGridNo, uiCursorFlags );
break;
case INVALIDCURS:
ubCursorID = INVALID_ACTION_UICURSOR;
@@ -2208,7 +2214,26 @@ UINT8 HandleFortificationCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT32 ui
return( FORTIFICATION_RED_UICURSOR );
}
UINT8 HandleHandcuffCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT32 uiCursorFlags )
{
// DRAW PATH TO GUY
HandleUIMovementCursor( pSoldier, uiCursorFlags, sGridNo, MOVEUI_TARGET_HANDCUFF );
// do we have handcuffs in our hand?
if ( HasItemFlag( (&(pSoldier->inv[HANDPOS]))->usItem, HANDCUFFS ) )
{
// is there a person here?
UINT8 usSoldierIndex = WhoIsThere2( sGridNo, pSoldier->pathing.bLevel );
if ( usSoldierIndex != NOBODY )
{
// no handcuffing if the guy is already caught...
if ( !(MercPtrs[usSoldierIndex]->bSoldierFlagMask & SOLDIER_POW) )
return( HANDCUFF_GREY_UICURSOR );
}
}
return( HANDCUFF_RED_UICURSOR );
}
void HandleEndConfirmCursor( SOLDIERTYPE *pSoldier )
{
@@ -2685,6 +2710,10 @@ UINT8 GetActionModeCursor( SOLDIERTYPE *pSoldier )
if ( HasItemFlag(usInHand, (EMPTY_SANDBAG|FULL_SANDBAG|SHOVEL|CONCERTINA)) )
ubCursor = FORTICURS;
// Flugente: cursor for handcuffs
if ( HasItemFlag(usInHand, HANDCUFFS) )
ubCursor = HANDCUFFCURS;
// Now check our terrain to see if we cannot do the action now...
if ( WaterTooDeepForAttacks( pSoldier->sGridNo) )
{
+5 -2
View File
@@ -3012,9 +3012,12 @@ IAN COMMENTED THIS OUT MAY 1997 - DO WE NEED THIS?
if (pOpponent)
{
// check to see if OPPONENT considers US neutral
if ( (pOpponent->aiData.bOppList[ubTarget] == SEEN_CURRENTLY) && !pOpponent->aiData.bNeutral && !CONSIDERED_NEUTRAL( pOpponent, pSoldier ) && (pSoldier->bSide != pOpponent->bSide) && pOpponent->RecognizeAsCombatant(pSoldier->ubID) )
if ( (pOpponent->aiData.bOppList[ubTarget] == SEEN_CURRENTLY) && !pOpponent->aiData.bNeutral && (pSoldier->bSide != pOpponent->bSide) )
{
RemoveOneOpponent(pOpponent);
// Flugente: we consider enemies to be neutral if they are prisoners of war (otherwise the AI would kill prisoners). Bu as we want to remove them, we have to account for that
// we also move RecognizeAsCombatant to be the last condition checked, because it is the most computationally expensive one
if ( ( !CONSIDERED_NEUTRAL( pOpponent, pSoldier ) || pSoldier->bSoldierFlagMask & SOLDIER_POW ) && pOpponent->RecognizeAsCombatant(pSoldier->ubID) )
RemoveOneOpponent(pOpponent);
}
UpdatePersonal(pOpponent,ubTarget,NOT_HEARD_OR_SEEN,NOWHERE,0);
gbSeenOpponents[ubLoop][ubTarget] = FALSE;
+6 -1
View File
@@ -1789,7 +1789,12 @@ void TurnBasedHandleNPCAI(SOLDIERTYPE *pSoldier)
}
*/
// Flugente: pows don't do anything
if ( pSoldier->bSoldierFlagMask & SOLDIER_POW )
{
EndAIGuysTurn( pSoldier);
return;
}
if ((pSoldier->aiData.bAction != AI_ACTION_NONE) && pSoldier->aiData.bActionInProgress)
{
+45
View File
@@ -2971,3 +2971,48 @@ INT32 CalcStraightThreatValue( SOLDIERTYPE *pEnemy )
return(iThreatValue);
}
// Flugente: get the id of the closest soldier with a specific flag that we can currently see
UINT8 GetClosestFlaggedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam, UINT32 aFlag )
{
UINT8 id = NOBODY;
UINT32 uiLoop;
BOOLEAN fRangeRestricted = FALSE, fFound = FALSE;
SOLDIERTYPE * pFriend;
INT16 range = aRange;
// go through each soldier, looking for "friends" (soldiers on same side)
for (uiLoop = 0; uiLoop < guiNumMercSlots; ++uiLoop)
{
pFriend = MercSlots[ uiLoop ];
// if this merc is inactive, not in sector, or dead
if (!pFriend)
continue;
if ( auTeam != pFriend->bTeam )
continue;
// check for flag
if ( !(pFriend->bSoldierFlagMask & aFlag) )
continue;
// skip ourselves
if (pFriend->ubID == pSoldier->ubID)
continue;
// if we're not already neighbors
if (SpacesAway(pSoldier->sGridNo, pFriend->sGridNo) < range)
{
// can we see this guy?
if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pFriend->sGridNo, pSoldier->pathing.bLevel, 3, TRUE, CALC_FROM_WANTED_DIR ) )
{
range = SpacesAway(pSoldier->sGridNo,pFriend->sGridNo);
id = pFriend->ubID;
}
}
}
return id;
}
+38 -21
View File
@@ -869,32 +869,42 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
}
//ddd{
if(gGameExternalOptions.bNewTacticalAIBehavior
&& !( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) )
&& pSoldier->bTeam == ENEMY_TEAM)
if(gGameExternalOptions.bNewTacticalAIBehavior && pSoldier->bTeam == ENEMY_TEAM )
{
INT32 cnt;
ROTTING_CORPSE * pCorpse;
for ( cnt = 0; cnt < giNumRottingCorpse; cnt++ )
if ( !(gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) )
{
pCorpse = &(gRottingCorpse[ cnt ] );
INT32 cnt;
ROTTING_CORPSE * pCorpse;
for ( cnt = 0; cnt < giNumRottingCorpse; cnt++ )
{
pCorpse = &(gRottingCorpse[ cnt ] );
if ( pCorpse->fActivated && pCorpse->def.ubAIWarningValue > 0 )
if ( PythSpacesAway( pSoldier->sGridNo, pCorpse->def.sGridNo ) <= 5 )//ïðèäåëàòü ñðàâíåíèå ïåðåìåííî äàëüíîñòè âèäåíèÿ (smaxvid ?)
{
//ïðîâåðèòü, íàõîäèòñÿ ëè òðóï â ïîëå çðåíèÿ äðàíèêà.ìåíòà?
//CHRISL: Shouldn't we be using the corpse's bLevel? Otherwise a soldier inside a building can see a corpse on the roof of that building
//if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pCorpse->def.sGridNo, pSoldier->pathing.bLevel, 3, TRUE, CALC_FROM_WANTED_DIR ) )
if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pCorpse->def.sGridNo, pCorpse->def.bLevel, 3, TRUE, CALC_FROM_WANTED_DIR ) )
if ( pCorpse->fActivated && pCorpse->def.ubAIWarningValue > 0 )
if ( PythSpacesAway( pSoldier->sGridNo, pCorpse->def.sGridNo ) <= 5 )//ïðèäåëàòü ñðàâíåíèå ïåðåìåííî äàëüíîñòè âèäåíèÿ (smaxvid ?)
{
ScreenMsg( MSG_FONT_YELLOW, MSG_INTERFACE, New113Message[MSG113_ENEMY_FOUND_DEAD_BODY]);
//pCorpse->def.ubAIWarningValue=0;
gRottingCorpse[ cnt ].def.ubAIWarningValue=0;
return( AI_ACTION_RED_ALERT );
//ïðîâåðèòü, íàõîäèòñÿ ëè òðóï â ïîëå çðåíèÿ äðàíèêà.ìåíòà?
//CHRISL: Shouldn't we be using the corpse's bLevel? Otherwise a soldier inside a building can see a corpse on the roof of that building
//if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pCorpse->def.sGridNo, pSoldier->pathing.bLevel, 3, TRUE, CALC_FROM_WANTED_DIR ) )
if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pCorpse->def.sGridNo, pCorpse->def.bLevel, 3, TRUE, CALC_FROM_WANTED_DIR ) )
{
ScreenMsg( MSG_FONT_YELLOW, MSG_INTERFACE, New113Message[MSG113_ENEMY_FOUND_DEAD_BODY]);
//pCorpse->def.ubAIWarningValue=0;
gRottingCorpse[ cnt ].def.ubAIWarningValue=0;
return( AI_ACTION_RED_ALERT );
}
}
}
}
}
// Flugente: if we see one of our buddies in handcuffs, its a clear sign of enemy activity!
if ( pSoldier->bTeam == ENEMY_TEAM )
{
UINT8 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 10, ENEMY_TEAM, SOLDIER_POW );
if ( ubPerson != NOBODY )
return( AI_ACTION_RED_ALERT );
}
}
//ddd}
@@ -1462,7 +1472,14 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
return(AI_ACTION_NONE);
}
// Flugente: if we see one of our buddies in handcuffs, its a clear sign of enemy activity!
if ( pSoldier->bTeam == ENEMY_TEAM )
{
UINT8 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 10, ENEMY_TEAM, SOLDIER_POW );
if ( ubPerson != NOBODY )
return( AI_ACTION_RED_ALERT );
}
////////////////////////////////////////////////////////////////////////////
// LOOK AROUND TOWARD NOISE: determine %chance for man to turn towards noise
+5 -1
View File
@@ -132,8 +132,12 @@ void RTHandleAI( SOLDIERTYPE * pSoldier )
#endif
// let it continue
return;
}
}
}
// Flugente: prisoners of war don't do anything
if ( pSoldier->bSoldierFlagMask & SOLDIER_POW )
return;
// if man has nothing to do
if (pSoldier->aiData.bAction == AI_ACTION_NONE)
+3
View File
@@ -256,4 +256,7 @@ INT8 CalcBestCTGT( SOLDIERTYPE *pSoldier, UINT8 ubOppID, INT32 sOppGridNo, INT8
INT8 CalcAverageCTGTForPosition( SOLDIERTYPE * pSoldier, UINT8 ubOppID, INT32 sOppGridNo, INT8 bLevel, INT32 iMyAPsLeft );
UINT8 NumberOfTeamMatesAdjacent( SOLDIERTYPE * pSoldier, INT32 sGridNo );
// Flugente: get the id of the closest soldier (coser than x tiles) of a specific team with a specific flag that we can currently see
UINT8 GetClosestFlaggedSoldierID( SOLDIERTYPE * pSoldier, INT16 aRange, UINT8 auTeam, UINT32 aFlag );
#endif
+19
View File
@@ -122,6 +122,9 @@ CursorFileData CursorFileDatabase[] =
{ "CURSORS\\hammer.sti" , FALSE, 0, ANIMATED_CURSOR, 3, NULL }, // Flugente: fortification stuff
{ "CURSORS\\hammer_r.sti" , FALSE, 0, ANIMATED_CURSOR, 3, NULL },
{ "CURSORS\\handcuffs.sti" , FALSE, 0, ANIMATED_CURSOR, 3, NULL }, // Flugente: handcuffs stuff
{ "CURSORS\\handcuffs_r.sti" , FALSE, 0, ANIMATED_CURSOR, 3, NULL },
{ "CURSORS\\can_01.sti" , FALSE, 0, 0, 0, NULL },
{ "CURSORS\\can_02.sti" , FALSE, 0, 0, 0, NULL },
{ "CURSORS\\cur_tagr_ncth.sti" , FALSE, 0, ANIMATED_CURSOR, 7, NULL },
@@ -1182,6 +1185,7 @@ CursorData CursorDatabase[] =
0, 0, 0, 0, 0,
2, CENTER_CURSOR, CENTER_CURSOR , 0, 0 , 0, 0 },
// Flugente: fortification
{ C_TRINGS, 6, 0, HIDE_SUBCURSOR, HIDE_SUBCURSOR,
C_FORTIFICATION , 0, 0, CENTER_SUBCURSOR, CENTER_SUBCURSOR,
0, 0, 0, 0, 0,
@@ -1196,6 +1200,21 @@ CursorData CursorDatabase[] =
0, 0, 0, 0, 0,
2, CENTER_CURSOR, CENTER_CURSOR, 0, 0 , 0, 0 },
// Flugente: handcuffs
{ C_TRINGS, 6, 0, HIDE_SUBCURSOR, HIDE_SUBCURSOR,
C_HANDCUFFS , 0, 0, CENTER_SUBCURSOR, CENTER_SUBCURSOR,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
2, CENTER_CURSOR, CENTER_CURSOR, 0, 0 , 0, 0 },
{ C_TRINGS, 6, 0, HIDE_SUBCURSOR, HIDE_SUBCURSOR,
C_HANDCUFFS_RED , 0, 0, CENTER_SUBCURSOR, CENTER_SUBCURSOR,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
2, CENTER_CURSOR, CENTER_CURSOR, 0, 0 , 0, 0 },
{ C_TRINGS, 6, 0, HIDE_SUBCURSOR, HIDE_SUBCURSOR,
C_FUEL , 0, 0, CENTER_SUBCURSOR, CENTER_SUBCURSOR,
0, 0, 0, 0, 0,
+5
View File
@@ -156,6 +156,9 @@ typedef enum
CURSOR_FORTIFICATION,
CURSOR_FORTIFICATION_RED,
CURSOR_HANDCUFF,
CURSOR_HANDCUFF_RED,
CURSOR_FUEL,
CURSOR_FUEL_RED,
@@ -231,6 +234,8 @@ typedef enum
C_JUMPOVER,
C_FORTIFICATION,
C_FORTIFICATION_RED,
C_HANDCUFFS,
C_HANDCUFFS_RED,
C_FUEL,
C_FUEL_RED,
C_ACTIONMODERED_NCTH,
+15
View File
@@ -728,6 +728,19 @@ enum
extern STR16 szFoodTextStr[];
enum
{
STR_PRISONER_PROCESSED,
STR_PRISONER_RANSOM,
STR_PRISONER_DETECTION,
STR_PRISONER_TURN_MILITIA,
STR_PRISONER_RIOT,
TEXT_NUM_PRISONER_STR
};
extern STR16 szPrisonerTextStr[];
enum
{
AIR_RAID_TURN_STR,
@@ -897,6 +910,8 @@ enum
FUNCTION_SELECTION_STR,
CORPSE_SELECTION_STR,
WEAPON_CLEANING_STR,
PRISONER_NO_PRISONS_STR,
PRISONER_DECIDE_STR,
TEXT_NUM_TACTICAL_STR
};
+22 -3
View File
@@ -1635,13 +1635,14 @@ STR16 pAssignmentStrings[] =
L"在途中",// in transit - abbreviated form
L"修理", // repairing
L"锻炼", // training themselves
L"民兵", // training a town to revolt
L"游击队", //L"M.Militia", //training moving militia units //ham3.6
L"民兵", // training a town to revolt
L"游击队", //L"M.Militia", //training moving militia units //ham3.6
L"教练", // training a teammate
L"学员", // being trained by someone else
L"工作", // L"Staff", // operating a strategic facility //ham3.6
L"饮食", // eating at a facility (cantina etc.)
L"休息", //L"Rest",// Resting at a facility //ham3.6
L"Prison", // Flugente: interrogate prisoners
L"死亡", // dead
L"无力中", // abbreviation for incapacitated
L"战俘", // Prisoner of war - captured
@@ -1727,6 +1728,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"设施职员",
L"饮食", // eating at a facility (cantina etc.)
L"在设施里休养",
L"Interrogate prisoners", // Flugente: interrogate prisoners TODO.Translate
L"休息",
L"无力中",
L"战俘",
@@ -1772,6 +1774,7 @@ STR16 pLongAssignmentStrings[] =
L"学员",
L"设施职员", //L"Staff Facility",
L"休息", //L"Rest at Facility",
L"Interrogate prisoners", // Flugente: interrogate prisoners TODO.Translate
L"死亡",
L"无力中",
L"战俘",
@@ -2598,7 +2601,8 @@ CHAR16 zHealthStr[][13] =
L"受伤", //"WOUNDED", // >= 45
L"健康", //"HEALTHY", // >= 60
L"强壮", //"STRONG", // >= 75
L"极好", //"EXCELLENT", // >= 90
L"极好", //"EXCELLENT", // >= 90
L"CAPTURED", // added by Flugente TODO.Translate
};
STR16 gzHiddenHitCountStr[1] =
@@ -2911,6 +2915,10 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
// Flugente: weapon cleaning // TODO.Translate
L"%s cleaned %s",
// added by Flugente: decide what to do with prisoners
L"You have no prison for these prisoners, you have to let them go",
L"Yes - Send prisoners to jail No - Let them go",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
@@ -3409,6 +3417,7 @@ STR16 pTransactionText[] =
L"将装备卖给了当地人",
L"工厂使用", // L"Facility Use", // HEADROCK HAM 3.6
L"民兵保养", // L"Militia upkeep", // HEADROCK HAM 3.6
L"Ransom for released prisoners", // Flugente: prisoner system TODO.Translate
};
STR16 pTransactionAlternateText[] =
@@ -6711,6 +6720,7 @@ STR16 gzFacilityAssignmentStrings[]=
L"训练医疗",
L"训练领导",
L"训练爆破",
L"Interrogate Prisoners", // added by Flugente TODO.Translate
};
STR16 Additional113Text[]=
{
@@ -7476,4 +7486,13 @@ STR16 szFoodTextStr[]=
L"Sectorwide canteen filling not possible, Food System is off!"
};
STR16 szPrisonerTextStr[]=
{
L"%d prisoners were interrogated.",
L"%d prisoners paid ransom money.",
L"%d prisoners revealed enemy positions.",
L"%d prisoners joined our cause.",
L"Prisoners start a massive riot in %s!",
};
#endif //CHINESE
+19
View File
@@ -1638,6 +1638,7 @@ STR16 pAssignmentStrings[] =
L"Staff", // operating a strategic facility // TODO.Translate
L"Eat", // eating at a facility (cantina etc.) // TODO.Translate
L"Rest", // Resting at a facility // TODO.Translate
L"Prison", // Flugente: interrogate prisoners
L"Dood", // dead
L"Uitgesc.", // abbreviation for incapacitated
L"POW", // Prisoner of war - captured
@@ -1723,6 +1724,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Facility Staff", // TODO.Translate
L"Eat", // eating at a facility (cantina etc.) // TODO.Translate
L"Resting at Facility", // TODO.Translate
L"Interrogate prisoners", // Flugente: interrogate prisoners TODO.Translate
L"Dood", // dead
L"Uitgesc.", // abbreviation for incapacitated
L"POW", // Prisoner of war - captured
@@ -1768,6 +1770,7 @@ STR16 pLongAssignmentStrings[] =
L"Student", // being trained by someone else
L"Staff Facility", // TODO.Translate
L"Rest at Facility", // TODO.Translate
L"Interrogate prisoners", // Flugente: interrogate prisoners TODO.Translate
L"Dood", // dead
L"Uitgesc.", // abbreviation for incapacitated
L"POW", // Prisoner of war - captured
@@ -2596,6 +2599,7 @@ CHAR16 zHealthStr[][13] =
L"GEZOND", // >= 60
L"STERK", // >= 75
L"EXCELLENT", // >= 90
L"CAPTURED", // added by Flugente TODO.Translate
};
STR16 gzHiddenHitCountStr[1] =
@@ -2908,6 +2912,10 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
// Flugente: weapon cleaning // TODO.Translate
L"%s cleaned %s",
// added by Flugente: decide what to do with prisoners
L"You have no prison for these prisoners, you have to let them go",
L"Yes - Send prisoners to jail No - Let them go",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
@@ -3407,6 +3415,7 @@ STR16 pTransactionText[] =
L"%s heeft geld gestort.",
L"Facility Use", // HEADROCK HAM 3.6 // TODO.Translate
L"Militia upkeep", // HEADROCK HAM 3.6 // TODO.Translate
L"Ransom for released prisoners", // Flugente: prisoner system TODO.Translate
};
STR16 pTransactionAlternateText[] =
@@ -6703,6 +6712,7 @@ STR16 gzFacilityAssignmentStrings[]=
L"Trainer Mechanical",
L"Trainer Leadership",
L"Trainer Explosives",
L"Interrogate Prisoners", // added by Flugente TODO.Translate
};
STR16 Additional113Text[]=
@@ -7469,4 +7479,13 @@ STR16 szFoodTextStr[]=
L"Sectorwide canteen filling not possible, Food System is off!"
};
STR16 szPrisonerTextStr[]=
{
L"%d prisoners were interrogated.",
L"%d prisoners paid ransom money.",
L"%d prisoners revealed enemy positions.",
L"%d prisoners joined our cause.",
L"Prisoners start a massive riot in %s!",
};
#endif //DUTCH
+22 -3
View File
@@ -1635,13 +1635,14 @@ STR16 pAssignmentStrings[] =
L"In Trans", // in transit - abbreviated form
L"Repair", // repairing
L"Practice", // training themselves
L"Militia", // training a town to revolt
L"Militia", // training a town to revolt
L"M.Militia", //training moving militia units
L"Trainer", // training a teammate
L"Student", // being trained by someone else
L"Staff", // operating a strategic facility
L"Eat", // eating at a facility (cantina etc.)
L"Rest", // Resting at a facility
L"Prison", // Flugente: interrogate prisoners
L"Dead", // dead
L"Incap.", // abbreviation for incapacitated
L"POW", // Prisoner of war - captured
@@ -1727,6 +1728,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Facility Staff", // Missing
L"Eat", // eating at a facility (cantina etc.)
L"Resting at Facility", // Missing
L"Interrogate prisoners", // Flugente: interrogate prisoners
L"Dead",
L"Incap.",
L"POW",
@@ -1772,6 +1774,7 @@ STR16 pLongAssignmentStrings[] =
L"Student",
L"Staff Facility", // Missing
L"Rest at Facility", // Missing
L"Interrogate prisoners", // Flugente: interrogate prisoners
L"Dead",
L"Incap.",
L"POW",
@@ -2592,12 +2595,13 @@ CHAR16 gMoneyStatsDesc[][ 14 ] =
CHAR16 zHealthStr[][13] =
{
L"DYING", // >= 0
L"CRITICAL", // >= 15
L"CRITICAL", // >= 15
L"POOR", // >= 30
L"WOUNDED", // >= 45
L"HEALTHY", // >= 60
L"STRONG", // >= 75
L"EXCELLENT", // >= 90
L"EXCELLENT", // >= 90
L"CAPTURED", // added by Flugente
};
STR16 gzHiddenHitCountStr[1] =
@@ -2910,6 +2914,10 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
// Flugente: weapon cleaning
L"%s cleaned %s",
// added by Flugente: decide what to do with prisoners
L"You have no prison for these prisoners, you have to let them go",
L"Yes - Send prisoners to jail No - Let them go",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
@@ -3408,6 +3416,7 @@ STR16 pTransactionText[] =
L"Sold Item(s) to the Locals",
L"Facility Use", // HEADROCK HAM 3.6
L"Militia upkeep", // HEADROCK HAM 3.6
L"Ransom for released prisoners", // Flugente: prisoner system
};
STR16 pTransactionAlternateText[] =
@@ -6693,6 +6702,7 @@ STR16 gzFacilityAssignmentStrings[]=
L"Trainer Mechanical",
L"Trainer Leadership",
L"Trainer Explosives",
L"Interrogate Prisoners", // added by Flugente
};
STR16 Additional113Text[]=
{
@@ -7457,4 +7467,13 @@ STR16 szFoodTextStr[]=
L"Sectorwide canteen filling not possible, Food System is off!"
};
STR16 szPrisonerTextStr[]=
{
L"%d prisoners were interrogated.",
L"%d prisoners paid ransom money.",
L"%d prisoners revealed enemy positions.",
L"%d prisoners joined our cause.",
L"Prisoners start a massive riot in %s!",
};
#endif //ENGLISH
+19
View File
@@ -1641,6 +1641,7 @@ STR16 pAssignmentStrings[] =
L"Exploitation", // operating a strategic facility
L"Eat", // eating at a facility (cantina etc.) // TODO.Translate
L"Repos", // Resting at a facility
L"Prison", // Flugente: interrogate prisoners
L"Mort(e)", // dead
L"Incap.", // abbreviation for incapacitated
L"Capturé", // Prisoner of war - captured
@@ -1726,6 +1727,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Exploitation infras.",
L"Eat", // eating at a facility (cantina etc.) // TODO.Translate
L"Repos infras.",
L"Interrogate prisoners", // Flugente: interrogate prisoners TODO.Translate
L"Mort(e)",
L"Incap.",
L"Capturé(e)",
@@ -1771,6 +1773,7 @@ STR16 pLongAssignmentStrings[] =
L"Elève",
L"Exploitation infras.",
L"Repos infras.",
L"Interrogate prisoners", // Flugente: interrogate prisoners TODO.Translate
L"Mort(e)",
L"Incap.",
L"Capturé(e)",
@@ -2598,6 +2601,7 @@ CHAR16 zHealthStr[][13] =
L"EN FORME", // >= 60
L"BON", // >= 75
L"EXCELLENT", // >= 90
L"CAPTURED", // added by Flugente TODO.Translate
};
STR16 gzHiddenHitCountStr[1] =
@@ -2910,6 +2914,10 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
// Flugente: weapon cleaning // TODO.Translate
L"%s cleaned %s",
// added by Flugente: decide what to do with prisoners
L"You have no prison for these prisoners, you have to let them go",
L"Yes - Send prisoners to jail No - Let them go",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
@@ -3411,6 +3419,7 @@ STR16 pTransactionText[] =
L"Materiel vendu à la population",
L"Infrastucture utilisée", // HEADROCK HAM 3.6
L"Entretien de la milice", // HEADROCK HAM 3.6
L"Ransom for released prisoners", // Flugente: prisoner system TODO.Translate
};
STR16 pTransactionAlternateText[] =
@@ -6679,6 +6688,7 @@ STR16 gzFacilityAssignmentStrings[]=
L"Entraineur Mécanique",
L"Entraineur Commandement",
L"Entraineur Explosif",
L"Interrogate Prisoners", // added by Flugente TODO.Translate
};
STR16 Additional113Text[]=
{
@@ -7443,4 +7453,13 @@ STR16 szFoodTextStr[]=
L"Sectorwide canteen filling not possible, Food System is off!"
};
STR16 szPrisonerTextStr[]=
{
L"%d prisoners were interrogated.",
L"%d prisoners paid ransom money.",
L"%d prisoners revealed enemy positions.",
L"%d prisoners joined our cause.",
L"Prisoners start a massive riot in %s!",
};
#endif //FRENCH
+20 -1
View File
@@ -1651,6 +1651,7 @@ STR16 pAssignmentStrings[] =
L"Betrieb", // operating a strategic facility
L"Essen", // eating at a facility (cantina etc.)
L"Pause", // Resting at a facility
L"Verhör", // Flugente: interrogate prisoners
L"Tot", // dead
L"Koma", // abbreviation for incapacitated //LOOTF - "Unfähig" klingt schlimm. Geändert auf Koma. Vorschläge?
L"Gefangen", // Prisoner of war - captured
@@ -1732,6 +1733,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Betriebspersonal",
L"Essen", // eating at a facility (cantina etc.)
L"Betriebspause",
L"Gefangene verhören", // Flugente: interrogate prisoners
L"Tot",
L"Koma", //LOOTF - s.o.
L"Gefangen",
@@ -1775,6 +1777,7 @@ STR16 pLongAssignmentStrings[] =
L"Rekrut",
L"Betriebspersonal",
L"Betriebspause",
L"Gefangene verhören", // Flugente: interrogate prisoners
L"Tot",
L"Unfähig",
L"Gefangen",
@@ -2601,7 +2604,8 @@ CHAR16 zHealthStr[][13] = //used to be 10
L"VERWUNDET", // >= 45
L"GESUND", // >= 60
L"STARK", // >= 75
L"SEHR GUT", // >= 90
L"SEHR GUT", // >= 90
L"GEFANGEN", // added by Flugente
};
STR16 gzHiddenHitCountStr[1] =
@@ -2913,6 +2917,10 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
// Flugente: weapon cleaning // TODO.Translate
L"%s cleaned %s",
// added by Flugente: decide what to do with prisoners
L"You have no prison for these prisoners, you have to let them go",
L"Yes - Send prisoners to jail No - Let them go",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
@@ -3382,6 +3390,7 @@ STR16 pTransactionText[] =
L"%s hat Geld angelegt.",
L"Betriebskosten", // HEADROCK HAM 3.6
L"Unterhaltskosten für Miliz", // HEADROCK HAM 3.6
L"Lösegeld erpresst", // Flugente: prisoner system
};
STR16 pTransactionAlternateText[] =
@@ -6521,6 +6530,7 @@ STR16 gzFacilityAssignmentStrings[]=
L"Trainer Technik",
L"Trainer Führungsqualität",
L"Trainer Sprengstoff",
L"Gefangene verhören", // added by Flugente
};
STR16 Additional113Text[]=
@@ -7284,4 +7294,13 @@ STR16 szFoodTextStr[]=
L"Sectorwide canteen filling not possible, Food System is off!"
};
STR16 szPrisonerTextStr[]=
{
L"%d prisoners were interrogated.",
L"%d prisoners paid ransom money.",
L"%d prisoners revealed enemy positions.",
L"%d prisoners joined our cause.",
L"Prisoners start a massive riot in %s!",
};
#endif //GERMAN
+21 -2
View File
@@ -1627,13 +1627,14 @@ STR16 pAssignmentStrings[] =
L"Transito", // in transit - abbreviated form
L"Riparare", // repairing
L"Esercit.", // training themselves
L"Esercit.", // training a town to revolt
L"Esercit.", // training a town to revolt
L"M.Militia", //training moving militia units // TODO.Translate
L"Istrutt.", // training a teammate
L"Studente", // being trained by someone else
L"Staff", // operating a strategic facility // TODO.Translate
L"Eat", // eating at a facility (cantina etc.) // TODO.Translate
L"Rest", // Resting at a facility // TODO.Translate
L"Prison", // Flugente: interrogate prisoners
L"Morto", // dead
L"Incap.", // abbreviation for incapacitated
L"PDG", // Prisoner of war - captured
@@ -1719,6 +1720,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Facility Staff", // TODO.Translate
L"Eat", // eating at a facility (cantina etc.) // TODO.Translate
L"Resting at Facility", // TODO.Translate
L"Interrogate prisoners", // Flugente: interrogate prisoners TODO.Translate
L"Morto",
L"Incap.",
L"PDG",
@@ -1764,6 +1766,7 @@ STR16 pLongAssignmentStrings[] =
L"Studente",
L"Staff Facility", // TODO.Translate
L"Rest at Facility", // TODO.Translate
L"Interrogate prisoners", // Flugente: interrogate prisoners TODO.Translate
L"Morto",
L"Incap.",
L"PDG",
@@ -2590,7 +2593,8 @@ CHAR16 zHealthStr[][13] =
L"FERITO", // >= 45
L"SANO", // >= 60
L"FORTE", // >= 75
L"ECCELLENTE", // >= 90
L"ECCELLENTE", // >= 90
L"CAPTURED", // added by Flugente TODO.Translate
};
STR16 gzHiddenHitCountStr[1] =
@@ -2903,6 +2907,10 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
// Flugente: weapon cleaning // TODO.Translate
L"%s cleaned %s",
// added by Flugente: decide what to do with prisoners
L"You have no prison for these prisoners, you have to let them go",
L"Yes - Send prisoners to jail No - Let them go",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
@@ -3402,6 +3410,7 @@ STR16 pTransactionText[] =
L"%s soldi depositati.",
L"Facility Use", // HEADROCK HAM 3.6 // TODO.Translate
L"Militia upkeep", // HEADROCK HAM 3.6 // TODO.Translate
L"Ransom for released prisoners", // Flugente: prisoner system TODO.Translate
};
STR16 pTransactionAlternateText[] =
@@ -6690,6 +6699,7 @@ STR16 gzFacilityAssignmentStrings[]=
L"Trainer Mechanical",
L"Trainer Leadership",
L"Trainer Explosives",
L"Interrogate Prisoners", // added by Flugente TODO.Translate
};
STR16 Additional113Text[]=
@@ -7456,4 +7466,13 @@ STR16 szFoodTextStr[]=
L"Sectorwide canteen filling not possible, Food System is off!"
};
STR16 szPrisonerTextStr[]=
{
L"%d prisoners were interrogated.",
L"%d prisoners paid ransom money.",
L"%d prisoners revealed enemy positions.",
L"%d prisoners joined our cause.",
L"Prisoners start a massive riot in %s!",
};
#endif //ITALIAN
+19
View File
@@ -1649,6 +1649,7 @@ STR16 pAssignmentStrings[] =
L"Staff", // operating a strategic facility // TODO.Translate
L"Eat", // eating at a facility (cantina etc.) // TODO.Translate
L"Rest", // Resting at a facility // TODO.Translate
L"Prison", // Flugente: interrogate prisoners
L"Nie żyje", // dead
L"Obezwł.", // abbreviation for incapacitated
L"Jeniec", // Prisoner of war - captured
@@ -1734,6 +1735,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Facility Staff", // TODO.Translate
L"Eat", // eating at a facility (cantina etc.) // TODO.Translate
L"Resting at Facility", // TODO.Translate
L"Interrogate prisoners", // Flugente: interrogate prisoners TODO.Translate
L"Nie żyje",
L"Obezwładniony",
L"Jeniec",
@@ -1779,6 +1781,7 @@ STR16 pLongAssignmentStrings[] =
L"Uczeń",
L"Staff Facility", // TODO.Translate
L"Rest at Facility", // TODO.Translate
L"Interrogate prisoners", // Flugente: interrogate prisoners TODO.Translate
L"Nie żyje",
L"Obezwładniony",
L"Jeniec",
@@ -2606,6 +2609,7 @@ CHAR16 zHealthStr[][13] =
L"ZDROWY", // >= 60
L"SILNY", // >= 75
L"DOSKONAŁY", // >= 90
L"CAPTURED", // added by Flugente TODO.Translate
};
STR16 gzHiddenHitCountStr[1] =
@@ -2918,6 +2922,10 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
// Flugente: weapon cleaning // TODO.Translate
L"%s cleaned %s",
// added by Flugente: decide what to do with prisoners
L"You have no prison for these prisoners, you have to let them go",
L"Yes - Send prisoners to jail No - Let them go",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
@@ -3418,6 +3426,7 @@ STR16 pTransactionText[] =
L"Sprzedano rzecz(y) miejscowym",
L"Wykorzystanie Placówki", // HEADROCK HAM 3.6
L"Utrzymanie Samoobr.", // HEADROCK HAM 3.6
L"Ransom for released prisoners", // Flugente: prisoner system TODO.Translate
};
STR16 pTransactionAlternateText[] =
@@ -6702,6 +6711,7 @@ STR16 gzFacilityAssignmentStrings[]=
L"Instruktor zn. mechaniki",
L"Instruktor um. dowodzenia",
L"Instruktor zn. mat. wybuchowych",
L"Interrogate Prisoners", // added by Flugente TODO.Translate
};
STR16 Additional113Text[]=
@@ -7470,4 +7480,13 @@ STR16 szFoodTextStr[]=
L"Sectorwide canteen filling not possible, Food System is off!"
};
STR16 szPrisonerTextStr[]=
{
L"%d prisoners were interrogated.",
L"%d prisoners paid ransom money.",
L"%d prisoners revealed enemy positions.",
L"%d prisoners joined our cause.",
L"Prisoners start a massive riot in %s!",
};
#endif //POLISH
+19
View File
@@ -1642,6 +1642,7 @@ STR16 pAssignmentStrings[] =
L"Штат", // operating a strategic facility //Staff
L"Eat", // eating at a facility (cantina etc.) // TODO.Translate
L"Отдых", // Resting at a facility //Rest
L"Prison", // Flugente: interrogate prisoners
L"Мертв", // dead
L"Недеесп.", // abbreviation for incapacitated
L"В плену", // Prisoner of war - captured
@@ -1727,6 +1728,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Работает с населением", //Facility Staff
L"Eat", // eating at a facility (cantina etc.) // TODO.Translate
L"Отдыхает", //Resting at Facility
L"Interrogate prisoners", // Flugente: interrogate prisoners TODO.Translate
L"Мертв",
L"Недеесп.",
L"В плену",
@@ -1772,6 +1774,7 @@ STR16 pLongAssignmentStrings[] =
L"Обучается",
L"Работает с населением", //Staff Facility
L"Отдыхает в заведении", //Resting at Facility
L"Interrogate prisoners", // Flugente: interrogate prisoners TODO.Translate
L"Мертв",
L"Недееспособен",
L"В плену",
@@ -2599,6 +2602,7 @@ CHAR16 zHealthStr[][13] =
L"ЗДОРОВ", // >= 60
L"СИЛЕН", // >= 75
L"ОТЛИЧНО", // >= 90
L"CAPTURED", // added by Flugente TODO.Translate
};
STR16 gzHiddenHitCountStr[1] =
@@ -2911,6 +2915,10 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
// Flugente: weapon cleaning // TODO.Translate
L"%s cleaned %s",
// added by Flugente: decide what to do with prisoners
L"You have no prison for these prisoners, you have to let them go",
L"Yes - Send prisoners to jail No - Let them go",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
@@ -3411,6 +3419,7 @@ STR16 pTransactionText[] =
L"Снаряжение продано населению",
L"Оснащение персонала", // HEADROCK HAM 3.6 //Facility Use
L"Содержание ополчения", // HEADROCK HAM 3.6 //Militia upkeep
L"Ransom for released prisoners", // Flugente: prisoner system TODO.Translate
};
STR16 pTransactionAlternateText[] =
@@ -6657,6 +6666,7 @@ STR16 gzFacilityAssignmentStrings[]=
L"Тренер на Механику",
L"Тренер на Лидерство",
L"Тренер на Взрывчатку",
L"Interrogate Prisoners", // added by Flugente TODO.Translate
};
STR16 Additional113Text[]=
@@ -7422,4 +7432,13 @@ STR16 szFoodTextStr[]=
L"Sectorwide canteen filling not possible, Food System is off!"
};
STR16 szPrisonerTextStr[]=
{
L"%d prisoners were interrogated.",
L"%d prisoners paid ransom money.",
L"%d prisoners revealed enemy positions.",
L"%d prisoners joined our cause.",
L"Prisoners start a massive riot in %s!",
};
#endif //RUSSIAN
+21 -2
View File
@@ -1635,13 +1635,14 @@ STR16 pAssignmentStrings[] =
L"In Trans", // in transit - abbreviated form
L"Repair", // repairing
L"Practice", // training themselves
L"Militia", // training a town to revolt
L"Militia", // training a town to revolt
L"M.Militia", //training moving militia units // TODO.Translate
L"Trainer", // training a teammate
L"Student", // being trained by someone else
L"Staff", // operating a strategic facility // TODO.Translate
L"Eat", // eating at a facility (cantina etc.) // TODO.Translate
L"Rest", // Resting at a facility // TODO.Translate
L"Prison", // Flugente: interrogate prisoners
L"Dead", // dead
L"Incap.", // abbreviation for incapacitated
L"POW", // Prisoner of war - captured
@@ -1727,6 +1728,7 @@ STR16 pPersonnelAssignmentStrings[] =
L"Facility Staff", // TODO.Translate
L"Eat", // eating at a facility (cantina etc.) // TODO.Translate
L"Resting at Facility", // TODO.Translate
L"Interrogate prisoners", // Flugente: interrogate prisoners TODO.Translate
L"Dead",
L"Incap.",
L"POW",
@@ -1772,6 +1774,7 @@ STR16 pLongAssignmentStrings[] =
L"Student",
L"Staff Facility", // TODO.Translate
L"Rest at Facility", // TODO.Translate
L"Interrogate prisoners", // Flugente: interrogate prisoners TODO.Translate
L"Dead",
L"Incap.",
L"POW",
@@ -2599,7 +2602,8 @@ CHAR16 zHealthStr[][13] =
L"WOUNDED", // >= 45
L"HEALTHY", // >= 60
L"STRONG", // >= 75
L"EXCELLENT", // >= 90
L"EXCELLENT", // >= 90
L"CAPTURED", // added by Flugente TODO.Translate
};
STR16 gzHiddenHitCountStr[1] =
@@ -2912,6 +2916,10 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
// Flugente: weapon cleaning // TODO.Translate
L"%s cleaned %s",
// added by Flugente: decide what to do with prisoners
L"You have no prison for these prisoners, you have to let them go",
L"Yes - Send prisoners to jail No - Let them go",
};
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
@@ -3412,6 +3420,7 @@ STR16 pTransactionText[] =
L"Sold Item(s) to the Locals",
L"Facility Use", // HEADROCK HAM 3.6 // TODO.Translate
L"Militia upkeep", // HEADROCK HAM 3.6 // TODO.Translate
L"Ransom for released prisoners", // Flugente: prisoner system TODO.Translate
};
STR16 pTransactionAlternateText[] =
@@ -6707,6 +6716,7 @@ STR16 gzFacilityAssignmentStrings[]=
L"Trainer Mechanical",
L"Trainer Leadership",
L"Trainer Explosives",
L"Interrogate Prisoners", // added by Flugente TODO.Translate
};
STR16 Additional113Text[]=
@@ -7473,4 +7483,13 @@ STR16 szFoodTextStr[]=
L"Sectorwide canteen filling not possible, Food System is off!"
};
STR16 szPrisonerTextStr[]=
{
L"%d prisoners were interrogated.",
L"%d prisoners paid ransom money.",
L"%d prisoners revealed enemy positions.",
L"%d prisoners joined our cause.",
L"Prisoners start a massive riot in %s!",
};
#endif //TAIWANESE