added new option in Skills_Settings.ini: [Covert Ops] COVERT_TURNCOATS_ACTIVATE_IN_AUTORESOLVE

if enabled, turncoats will automatically activate when entering an autoresolve battle

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@9365 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
rftr
2022-04-14 06:50:44 +00:00
parent 5d98b5da8a
commit fcc21e32dc
10 changed files with 87 additions and 14 deletions
+1
View File
@@ -2834,6 +2834,7 @@ void LoadSkillTraitsExternalSettings()
gSkillTraitValues.fCOTurncoats = iniReader.ReadBoolean( "Covert Ops", "COVERT_TURNCOATS", TRUE );
gSkillTraitValues.fCOTurncoats_SectorActivationRequiresRadioOperator = iniReader.ReadBoolean( "Covert Ops", "COVERT_TURNCOATS_SECTOR_ACTIVATION_REQUIRES_RADIOOPERATOR", FALSE );
gSkillTraitValues.sCOTurncoats_PlayerConvinctionBonus = iniReader.ReadInteger( "Covert Ops", "COVERT_TURNCOATS_PLAYER_CONVINCTION_BONUS", 0, -100, 100 );
gSkillTraitValues.fCOTurncoatsActivateInAutoResolve = iniReader.ReadBoolean( "Covert Ops", "COVERT_TURNCOATS_ACTIVATE_IN_AUTORESOLVE", FALSE );
// Flugente: RADIO OPERATOR
gSkillTraitValues.fROAllowArtillery = iniReader.ReadBoolean("Radio Operator","RADIO_OPERATOR_ARTILLERY", TRUE);
+1
View File
@@ -2103,6 +2103,7 @@ typedef struct
BOOLEAN fCOTurncoats; // can we create enemy turncoats that can be ordered to betray their comrades?
BOOLEAN fCOTurncoats_SectorActivationRequiresRadioOperator; // activating turncoats sector-wide requires a radio operator
INT32 sCOTurncoats_PlayerConvinctionBonus;
BOOLEAN fCOTurncoatsActivateInAutoResolve;
// RADIO OPERATOR
BOOLEAN fROAllowArtillery; // artillery can be forbidden for all teams with this setting
+2
View File
@@ -3107,6 +3107,8 @@ void CalculateAutoResolveInfo()
}
else
{
ActivateTurncoatsForAutoResolve( gpAR->ubSectorX, gpAR->ubSectorY );
GetNumberOfEnemiesInFiveSectors( gpAR->ubSectorX, gpAR->ubSectorY,
&gpAR->ubAdmins, &gpAR->ubTroops, &gpAR->ubElites, &gpAR->ubRobots, &gpAR->ubTanks, &gpAR->ubJeeps );
+22 -7
View File
@@ -3245,7 +3245,7 @@ BOOLEAN TurncoatsInSector( INT16 sSectorX, INT16 sSectorY )
return FALSE;
}
bool RemoveOneTurncoat( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass )
bool RemoveOneTurncoat( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass, BOOLEAN alsoRemoveFromGroup )
{
// HEADROCK: This is a TEMPORARY fix to avoid the assertion error. Not sure this is the best solution,
// probably isn't. But I need this bit to work.
@@ -3315,14 +3315,20 @@ bool RemoveOneTurncoat( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR:
pSector->ubNumAdmins_Turncoat--;
if (alsoRemoveFromGroup)
pSector->ubNumAdmins--;
return true;
break;
case SOLDIER_CLASS_ARMY:
pSector->ubNumTroops_Turncoat--;
if (alsoRemoveFromGroup)
pSector->ubNumTroops--;
return true;
break;
case SOLDIER_CLASS_ELITE:
pSector->ubNumElites_Turncoat--;
if (alsoRemoveFromGroup)
pSector->ubNumElites--;
return true;
break;
default:
@@ -3342,8 +3348,11 @@ bool RemoveOneTurncoat( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass )
if ( pGroup->pEnemyGroup->ubNumAdmins_Turncoat && pGroup->ubGroupSize && pGroup->pEnemyGroup->ubNumAdmins )
{
pGroup->pEnemyGroup->ubNumAdmins_Turncoat--;
pGroup->pEnemyGroup->ubNumAdmins--;
pGroup->ubGroupSize--;
if (alsoRemoveFromGroup)
{
pGroup->pEnemyGroup->ubNumAdmins--;
pGroup->ubGroupSize--;
}
return true;
}
break;
@@ -3351,8 +3360,11 @@ bool RemoveOneTurncoat( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass )
if ( pGroup->pEnemyGroup->ubNumTroops_Turncoat && pGroup->ubGroupSize && pGroup->pEnemyGroup->ubNumTroops )
{
pGroup->pEnemyGroup->ubNumTroops_Turncoat--;
pGroup->pEnemyGroup->ubNumTroops--;
pGroup->ubGroupSize--;
if (alsoRemoveFromGroup)
{
pGroup->pEnemyGroup->ubNumTroops--;
pGroup->ubGroupSize--;
}
return true;
}
break;
@@ -3360,8 +3372,11 @@ bool RemoveOneTurncoat( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass )
if ( pGroup->pEnemyGroup->ubNumElites_Turncoat && pGroup->ubGroupSize && pGroup->pEnemyGroup->ubNumElites )
{
pGroup->pEnemyGroup->ubNumElites_Turncoat--;
pGroup->pEnemyGroup->ubNumElites--;
pGroup->ubGroupSize--;
if (alsoRemoveFromGroup)
{
pGroup->pEnemyGroup->ubNumElites--;
pGroup->ubGroupSize--;
}
return true;
}
break;
+1 -1
View File
@@ -76,7 +76,7 @@ BOOLEAN CheckPendingNonPlayerTeam(UINT8 usTeam);
// Flugente: turncoats
UINT16 NumTurncoatsOfClassInSector( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass );
BOOLEAN TurncoatsInSector( INT16 sSectorX, INT16 sSectorY );
bool RemoveOneTurncoat( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass );
bool RemoveOneTurncoat( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass, BOOLEAN alsoRemoveFromGroup );
bool AddOneTurncoat( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass );
void CorrectTurncoatCount( INT16 sSectorX, INT16 sSectorY );
+53
View File
@@ -107,6 +107,59 @@ void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pub
}
}
void ActivateTurncoatsForAutoResolve( INT16 sSectorX, INT16 sSectorY )
{
if (!gSkillTraitValues.fCOTurncoatsActivateInAutoResolve)
return;
if (!gGameExternalOptions.gfAllowReinforcements)
return;
if ( ( GetTownIdForSector( sSectorX, sSectorY ) == OMERTA )&& ( !zDiffSetting[gGameOptions.ubDifficultyLevel].bAllowReinforcementsOmerta ) ) //Madd: skip Omerta //Lal: but not on insane ;-)
return;
UINT16 ubAdminTurncoats = NumTurncoatsOfClassInSector(sSectorX, sSectorY, SOLDIER_CLASS_ADMINISTRATOR);
UINT16 ubTroopTurncoats = NumTurncoatsOfClassInSector(sSectorX, sSectorY, SOLDIER_CLASS_ARMY);
UINT16 ubEliteTurncoats = NumTurncoatsOfClassInSector(sSectorX, sSectorY, SOLDIER_CLASS_ELITE);
for (int i = 0; i < ubAdminTurncoats; ++i) RemoveOneTurncoat(sSectorX, sSectorY, SOLDIER_CLASS_ADMINISTRATOR, TRUE);
for (int i = 0; i < ubTroopTurncoats; ++i) RemoveOneTurncoat(sSectorX, sSectorY, SOLDIER_CLASS_ARMY, TRUE);
for (int i = 0; i < ubEliteTurncoats; ++i) RemoveOneTurncoat(sSectorX, sSectorY, SOLDIER_CLASS_ELITE, TRUE);
StrategicAddMilitiaToSector(sSectorX, sSectorY, GREEN_MILITIA, ubAdminTurncoats);
StrategicAddMilitiaToSector(sSectorX, sSectorY, REGULAR_MILITIA, ubTroopTurncoats);
StrategicAddMilitiaToSector(sSectorX, sSectorY, ELITE_MILITIA, ubEliteTurncoats);
UINT16 pusMoveDir[4][3]; //first column in this matrix is number of sector, except for 4th row
UINT8 ubDirNumber;
GenerateDirectionInfos( sSectorX, sSectorY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
for (UINT8 i = 0; i < ubDirNumber; ++i)
{
GROUP* pGroup = gpGroupList;
while ( pGroup )
{
if ( pGroup->usGroupTeam == ENEMY_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == SECTORX(pusMoveDir[i][0]) && pGroup->ubSectorY == SECTORY(pusMoveDir[i][0]) )
{
ubAdminTurncoats = pGroup->pEnemyGroup->ubNumAdmins_Turncoat;
ubTroopTurncoats = pGroup->pEnemyGroup->ubNumTroops_Turncoat;
ubEliteTurncoats = pGroup->pEnemyGroup->ubNumElites_Turncoat;
for (int j = 0; j < ubAdminTurncoats; ++j) RemoveOneTurncoat(SECTORX(pusMoveDir[i][0]), SECTORY(pusMoveDir[i][0]), SOLDIER_CLASS_ADMINISTRATOR, TRUE);
for (int j = 0; j < ubTroopTurncoats; ++j) RemoveOneTurncoat(SECTORX(pusMoveDir[i][0]), SECTORY(pusMoveDir[i][0]), SOLDIER_CLASS_ARMY, TRUE);
for (int j = 0; j < ubEliteTurncoats; ++j) RemoveOneTurncoat(SECTORX(pusMoveDir[i][0]), SECTORY(pusMoveDir[i][0]), SOLDIER_CLASS_ELITE, TRUE);
// since we're going directly to autoresolve, add miliita directly to sector after removing from a reinforcement group
StrategicAddMilitiaToSector(sSectorX, sSectorY, GREEN_MILITIA, ubAdminTurncoats);
StrategicAddMilitiaToSector(sSectorX, sSectorY, REGULAR_MILITIA, ubTroopTurncoats);
StrategicAddMilitiaToSector(sSectorX, sSectorY, ELITE_MILITIA, ubEliteTurncoats);
}
pGroup = pGroup->next;
}
}
}
UINT8 NumEnemiesInFiveSectors( INT16 sMapX, INT16 sMapY )
{
UINT8 ubNumAdmins, ubNumTroops, ubNumElites, ubNumRobots, ubNumTanks, ubNumJeeps;
+1
View File
@@ -3,6 +3,7 @@
//For Autoresolve (mostly)
void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites, UINT8 *pubNumRobots, UINT8 *pubNumTanks, UINT8 *pubNumJeeps );
void ActivateTurncoatsForAutoResolve( INT16 sSectorX, INT16 sSectorY );
BOOLEAN IsGroupInARightSectorToReinforce( GROUP *pGroup, INT16 sSectorX, INT16 sSectorY );
UINT8 GetAdjacentSectors( UINT8 pSectors[4], INT16 sSectorX, INT16 sSectorY );
UINT8 CountAllMilitiaInFiveSectors(INT16 sMapX, INT16 sMapY);
+1 -1
View File
@@ -7281,7 +7281,7 @@ void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
// Flugente: turncoats
if ( pTeamSoldier->usSoldierFlagMask2 & SOLDIER_TURNCOAT )
RemoveOneTurncoat( sMapX, sMapY, pTeamSoldier->ubSoldierClass );
RemoveOneTurncoat( sMapX, sMapY, pTeamSoldier->ubSoldierClass, FALSE );
// Flugente: campaign stats
gCurrentIncident.AddStat( pTeamSoldier, CAMPAIGNHISTORY_TYPE_PRISONER );
+2 -2
View File
@@ -114,7 +114,7 @@ extern UINT8 gubInterruptProvoker;
extern UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndReady, BOOLEAN fHipStance );
extern bool RemoveOneTurncoat( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass );
extern bool RemoveOneTurncoat( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass, BOOLEAN alsoRemoveFromGroup );
extern void PlaySplashSound(INT32 sGridNo);
// Animation code explanations!
@@ -4212,7 +4212,7 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse )
// Flugente: turncoats
if ( pSoldier->usSoldierFlagMask2 & SOLDIER_TURNCOAT )
RemoveOneTurncoat( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->ubSoldierClass );
RemoveOneTurncoat( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->ubSoldierClass, FALSE );
// Flugente: additional dialogue
if ( pSoldier->ubProfile != NO_PROFILE )
+3 -3
View File
@@ -10286,7 +10286,7 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
{
this->usSoldierFlagMask2 &= ~SOLDIER_TURNCOAT;
RemoveOneTurncoat( this->sSectorX, this->sSectorY, this->ubSoldierClass );
RemoveOneTurncoat( this->sSectorX, this->sSectorY, this->ubSoldierClass, FALSE );
}
}
@@ -21804,7 +21804,7 @@ BOOLEAN SOLDIERTYPE::OrderTurnCoatToSwitchSides( UINT16 usID )
{
// remove turncoat property
pSoldier->usSoldierFlagMask2 &= ~SOLDIER_TURNCOAT;
RemoveOneTurncoat( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->ubSoldierClass );
RemoveOneTurncoat( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->ubSoldierClass, TRUE );
MakeCivHostile( pSoldier );
@@ -21834,7 +21834,7 @@ void SOLDIERTYPE::OrderAllTurnCoatToSwitchSides()
{
// remove turncoat property
pSoldier->usSoldierFlagMask2 &= ~SOLDIER_TURNCOAT;
RemoveOneTurncoat( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->ubSoldierClass );
RemoveOneTurncoat( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->ubSoldierClass, TRUE );
MakeCivHostile( pSoldier );
}