New feature: turncoats can be created from enemies and ordered to switch sides

Requires GameDir >= r2535

For more info, see http://thepit.ja-galaxy-forum.com/index.php?t=msg&goto=360191&#msg_360191

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8811 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2020-05-30 00:13:42 +00:00
parent 0f13599775
commit c5022fa1e5
44 changed files with 1587 additions and 140 deletions
+7 -5
View File
@@ -6671,13 +6671,13 @@ void HandleSpyAssignments()
if ( Chance( uncoverrisk ) )
{
// if we are already in hiding, we will be uncovered
if ( pSoldier->usSkillCooldown[SOLDIER_COOLDOWN_INTEL_PENALTY] )
if ( pSoldier->usSkillCooldown[SOLDIER_COOLDOWN_INTEL_PENALTY] > 10 )
vector_uncoveredmercs.push_back( uiCnt );
// we get a penalty, and a chance to be uncovered
pSoldier->usSkillCooldown[SOLDIER_COOLDOWN_INTEL_PENALTY] += 2 + Random( 3 );
pSoldier->usSkillCooldown[SOLDIER_COOLDOWN_INTEL_PENALTY] += 20 + Random( 30 );
ScreenMsg( FONT_MCOLOR_RED, MSG_INTERFACE, szIntelText[1], pSoldier->GetName(), (pSoldier->usSkillCooldown[SOLDIER_COOLDOWN_INTEL_PENALTY] - 1) );
ScreenMsg( FONT_MCOLOR_RED, MSG_INTERFACE, szIntelText[1], pSoldier->GetName(), (pSoldier->usSkillCooldown[SOLDIER_COOLDOWN_INTEL_PENALTY] - 10) / 10 );
continue;
}
@@ -6688,8 +6688,10 @@ void HandleSpyAssignments()
}
// penalty runs out for every soldier, regardless of whether they are on an intel assignment
if ( pSoldier->usSkillCooldown[SOLDIER_COOLDOWN_INTEL_PENALTY] )
pSoldier->usSkillCooldown[SOLDIER_COOLDOWN_INTEL_PENALTY]--;
if ( pSoldier->usSkillCooldown[SOLDIER_COOLDOWN_INTEL_PENALTY] > 10)
pSoldier->usSkillCooldown[SOLDIER_COOLDOWN_INTEL_PENALTY] -= 10;
else
pSoldier->usSkillCooldown[SOLDIER_COOLDOWN_INTEL_PENALTY] = 0;
}
}
+7 -1
View File
@@ -570,7 +570,13 @@ typedef struct SECTORINFO
// Flugente: burial assignment
FLOAT dBurial_UnappliedProgress; // progress done via assignment work. This way no work gets lost
INT8 bPadding[ 12 ];
// Flugente: number of turncoats
UINT8 ubNumAdmins_Turncoat;
UINT8 ubNumTroops_Turncoat;
UINT8 ubNumElites_Turncoat;
UINT8 bPadding_1;
INT8 bPadding[ 8 ];
}SECTORINFO;
+30
View File
@@ -6636,6 +6636,15 @@ UINT32 WhatPlayerKnowsAboutEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
fCount = TRUE;
}
}
// Flugente: turncoats allow vision as well
if ( gSkillTraitValues.fCOTurncoats
&& TurncoatsInSector( sSectorX, sSectorY ) )
{
fDetection = TRUE;
fCount = TRUE;
fDirection = TRUE;
}
// Flugente: we can buy info on enemy groups with intel
GetInfoFromGroupsInSector( sSectorX, sSectorY, ENEMY_TEAM, fDetection, fCount, fDirection );
@@ -8466,6 +8475,27 @@ void DetermineMapIntelData( INT32 asSectorZ )
}
}
}
// Flugente: turncoats
if ( gSkillTraitValues.fCOTurncoats )
{
for ( UINT16 sector = 0; sector < 256; ++sector )
{
CorrectTurncoatCount( SECTORX( sector ), SECTORY( sector ) );
UINT16 numturncoats = NumTurncoatsOfClassInSector( SECTORX( sector ), SECTORY( sector ), SOLDIER_CLASS_ADMINISTRATOR )
+ NumTurncoatsOfClassInSector( SECTORX( sector ), SECTORY( sector ), SOLDIER_CLASS_ARMY )
+ NumTurncoatsOfClassInSector( SECTORX( sector ), SECTORY( sector ), SOLDIER_CLASS_ELITE );
if ( numturncoats )
{
CHAR16 str[128];
swprintf( str, szTurncoatText[9], numturncoats );
AddIntelAndQuestMapDataForSector( SECTORX( sector ), SECTORY( sector ), -1, 23, str, L"" );
}
}
}
}
// add lua data
+97
View File
@@ -580,6 +580,103 @@ UINT32 CreateNewIndividualMilitia( UINT8 aMilitiaRank, UINT8 aOrigin, UINT8 aSec
return newmilitia.id;
}
UINT32 CreateNewIndividualMilitiaFromSoldier( SOLDIERTYPE* pSoldier, UINT8 aOrigin )
{
if ( !gGameExternalOptions.fIndividualMilitia || !pSoldier )
return 0;
MILITIA newmilitia;
newmilitia.id = GetFreeIndividualMilitiaId();
switch ( pSoldier->ubSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR:
case SOLDIER_CLASS_GREEN_MILITIA:
case SOLDIER_CLASS_BANDIT:
newmilitia.militiarank = GREEN_MILITIA;
break;
case SOLDIER_CLASS_ELITE:
case SOLDIER_CLASS_ELITE_MILITIA:
newmilitia.militiarank = ELITE_MILITIA;
break;
case SOLDIER_CLASS_ARMY:
case SOLDIER_CLASS_REG_MILITIA:
newmilitia.militiarank = REGULAR_MILITIA;
break;
default:
return 0;
break;
}
// according to origin, we choose bodytype, skin, hair, fore- and surname
newmilitia.origin = aOrigin;
newmilitia.originsector = SECTOR( pSoldier->sSectorX, pSoldier->sSectorY );
newmilitia.sector = newmilitia.originsector;
newmilitia.bodytype = pSoldier->ubBodyType;
if ( COMPARE_PALETTEREP_ID( pSoldier->SkinPal, "PINKSKIN" ) ) newmilitia.skin = PINKSKIN;
else if ( COMPARE_PALETTEREP_ID( pSoldier->SkinPal, "TANSKIN" ) ) newmilitia.skin = TANSKIN;
else if ( COMPARE_PALETTEREP_ID( pSoldier->SkinPal, "DARKSKIN" ) ) newmilitia.skin = DARKSKIN;
else if ( COMPARE_PALETTEREP_ID( pSoldier->SkinPal, "BLACKSKIN" ) ) newmilitia.skin = BLACKSKIN;
if ( COMPARE_PALETTEREP_ID( pSoldier->HeadPal, "BROWNHEAD" ) ) newmilitia.hair = BROWNHEAD;
if ( COMPARE_PALETTEREP_ID( pSoldier->HeadPal, "BLACKHEAD" ) ) newmilitia.hair = BLACKHEAD;
if ( COMPARE_PALETTEREP_ID( pSoldier->HeadPal, "WHITEHEAD" ) ) newmilitia.hair = WHITEHEAD;
if ( COMPARE_PALETTEREP_ID( pSoldier->HeadPal, "BLONDHEAD" ) ) newmilitia.hair = BLONDEHEAD;
if ( COMPARE_PALETTEREP_ID( pSoldier->HeadPal, "REDHEAD" ) ) newmilitia.hair = REDHEAD;
// age is random
newmilitia.age = 16 + Random( 2 ) * ( 1 + Random( 8 ) )
+ Random( 2 ) * ( 1 + Random( 8 ) )
+ Random( 2 ) * ( 1 + Random( 8 ) )
+ Random( 2 ) * ( 1 + Random( 8 ) )
+ Random( 2 ) * ( 1 + Random( 8 ) )
+ Random( 2 ) * ( 1 + Random( 8 ) );
if ( newmilitia.hair == WHITEHEAD )
newmilitia.age = max( newmilitia.age, 38 + Random( 2 ) * ( 1 + Random( 8 ) ) );
// we have to choose a new name, as we cannot take the soldiers name, as those are set in separate arrays
if ( newmilitia.bodytype == REGFEMALE )
{
newmilitia.forename = Random( gMilitiaOriginData[newmilitia.origin].szFemale_Forename.size() );
newmilitia.surname = Random( gMilitiaOriginData[newmilitia.origin].szFemale_Surname.size() );
}
else
{
newmilitia.forename = Random( gMilitiaOriginData[newmilitia.origin].szMale_Forename.size() );
newmilitia.surname = Random( gMilitiaOriginData[newmilitia.origin].szMale_Surname.size() );
}
newmilitia.flagmask = 0;
newmilitia.healthratio = 100.0f * pSoldier->stats.bLife / pSoldier->stats.bLifeMax;
newmilitia.kills = 0;
newmilitia.assists = 0;
newmilitia.promotionpoints = 0.0f;
// promotion points are based on kills and assists. For proper accounting, award points for current rank
newmilitia.AddKills( 0, 0 );
// make up some history
MILITIA_BATTLEREPORT report;
report.flagmask |= MILITIA_BATTLEREPORT_FLAG_RECRUITED_TURNCOAT;
report.id = GetWorldTotalMin();
newmilitia.history.push_back( report );
gIndividualMilitiaVector.push_back( newmilitia );
return newmilitia.id;
}
// search for a individual militia that is alive and not currently in use in this sector, and return its id
// if none is found, create new and return that one
UINT32 GetIdOfUnusedIndividualMilitia( UINT8 aSoldierClass, UINT8 aSector )
+4
View File
@@ -38,6 +38,8 @@ NUM_TOTAL_STATS
#define MILITIA_BATTLEREPORT_FLAG_KILLEDENEMY 0x00000040 // killed an enemy
#define MILITIA_BATTLEREPORT_FLAG_FIRED 0x00000080 // militia was fired
#define MILITIA_BATTLEREPORT_FLAG_RECRUITED_TURNCOAT 0x00000100 // defected to our side
struct MILITIA_BATTLEREPORT
{
MILITIA_BATTLEREPORT( ) : id( 0 ), flagmask( 0 ) {}
@@ -166,6 +168,8 @@ UINT32 CreateRandomIndividualMilitia( UINT8 aMilitiaRank, UINT8 aOrigin, UINT8 a
UINT32 CreateNewIndividualMilitia( UINT8 aMilitiaRank, UINT8 aOrigin, UINT8 aSector );
UINT32 CreateNewIndividualMilitiaFromSoldier( SOLDIERTYPE* pSoldier, UINT8 aOrigin );
UINT32 GetIdOfUnusedIndividualMilitia( UINT8 aSoldierClass, UINT8 aSector );
BOOLEAN GetIdOfIndividualMilitiaWithClassSector( UINT8 aSoldierClass, UINT8 aSector, UINT32& arId );
+405
View File
@@ -3039,3 +3039,408 @@ void HandleBloodCatDeaths( SECTORINFO *pSector )
}
}
#endif
UINT16 NumTurncoatsOfClassInSector( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass )
{
// 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.
if ( sSectorX < MINIMUM_VALID_X_COORDINATE ||
sSectorX > MAXIMUM_VALID_X_COORDINATE ||
sSectorY < MINIMUM_VALID_Y_COORDINATE ||
sSectorY > MAXIMUM_VALID_Y_COORDINATE )
{
return ( 0 );
}
AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE );
AssertLE( sSectorX, MAXIMUM_VALID_X_COORDINATE );
AssertGE( sSectorY, MINIMUM_VALID_Y_COORDINATE );
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
SECTORINFO* pSector = &SectorInfo[SECTOR( sSectorX, sSectorY )];
UINT16 num = 0;
switch ( aSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR: num += pSector->ubNumAdmins_Turncoat; break;
case SOLDIER_CLASS_ARMY: num += pSector->ubNumTroops_Turncoat; break;
case SOLDIER_CLASS_ELITE: num += pSector->ubNumElites_Turncoat; break;
default: break;
}
GROUP* pGroup = gpGroupList;
while ( pGroup )
{
if ( pGroup->usGroupTeam == ENEMY_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY )
{
switch ( aSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR: num += pGroup->pEnemyGroup->ubNumAdmins_Turncoat; break;
case SOLDIER_CLASS_ARMY: num += pGroup->pEnemyGroup->ubNumTroops_Turncoat; break;
case SOLDIER_CLASS_ELITE: num += pGroup->pEnemyGroup->ubNumElites_Turncoat; break;
default: break;
}
}
pGroup = pGroup->next;
}
return num;
}
BOOLEAN TurncoatsInSector( INT16 sSectorX, INT16 sSectorY )
{
// 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.
if ( sSectorX < MINIMUM_VALID_X_COORDINATE ||
sSectorX > MAXIMUM_VALID_X_COORDINATE ||
sSectorY < MINIMUM_VALID_Y_COORDINATE ||
sSectorY > MAXIMUM_VALID_Y_COORDINATE )
{
return ( 0 );
}
AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE );
AssertLE( sSectorX, MAXIMUM_VALID_X_COORDINATE );
AssertGE( sSectorY, MINIMUM_VALID_Y_COORDINATE );
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
SECTORINFO* pSector = &SectorInfo[SECTOR( sSectorX, sSectorY )];
if ( pSector->ubNumAdmins_Turncoat
|| pSector->ubNumTroops_Turncoat
|| pSector->ubNumElites_Turncoat )
return TRUE;
GROUP* pGroup = gpGroupList;
while ( pGroup )
{
if ( pGroup->usGroupTeam == ENEMY_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY )
{
if ( pGroup->pEnemyGroup->ubNumAdmins_Turncoat
|| pGroup->pEnemyGroup->ubNumTroops_Turncoat
|| pGroup->pEnemyGroup->ubNumElites_Turncoat )
return TRUE;
}
pGroup = pGroup->next;
}
return FALSE;
}
bool RemoveOneTurncoat( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass )
{
// 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.
if ( sSectorX < MINIMUM_VALID_X_COORDINATE ||
sSectorX > MAXIMUM_VALID_X_COORDINATE ||
sSectorY < MINIMUM_VALID_Y_COORDINATE ||
sSectorY > MAXIMUM_VALID_Y_COORDINATE )
{
return false;
}
AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE );
AssertLE( sSectorX, MAXIMUM_VALID_X_COORDINATE );
AssertGE( sSectorY, MINIMUM_VALID_Y_COORDINATE );
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
SECTORINFO* pSector = &SectorInfo[SECTOR( sSectorX, sSectorY )];
// count how many turncoats we have
UINT16 num_static = 0;
UINT16 num_groups = 0;
switch ( aSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR:
num_static = pSector->ubNumAdmins_Turncoat;
break;
case SOLDIER_CLASS_ARMY:
num_static = pSector->ubNumTroops_Turncoat;
break;
case SOLDIER_CLASS_ELITE:
num_static = pSector->ubNumElites_Turncoat;
break;
default:
break;
}
GROUP* pGroup = gpGroupList;
while ( pGroup )
{
if ( pGroup->usGroupTeam == ENEMY_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY )
{
switch ( aSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR:
num_groups += pGroup->pEnemyGroup->ubNumAdmins_Turncoat;
break;
case SOLDIER_CLASS_ARMY:
num_groups += pGroup->pEnemyGroup->ubNumTroops_Turncoat;
break;
case SOLDIER_CLASS_ELITE:
num_groups += pGroup->pEnemyGroup->ubNumElites_Turncoat;
break;
default:
break;
}
}
pGroup = pGroup->next;
}
if ( num_static + num_groups )
{
if ( Chance( 100 * num_static / ( num_static + num_groups ) ) )
{
// add to garrison
switch ( aSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR:
pSector->ubNumAdmins_Turncoat--;
return true;
break;
case SOLDIER_CLASS_ARMY:
pSector->ubNumTroops_Turncoat--;
return true;
break;
case SOLDIER_CLASS_ELITE:
pSector->ubNumElites_Turncoat--;
return true;
break;
default:
break;
}
}
else
{
GROUP* pGroup = gpGroupList;
while ( pGroup )
{
if ( pGroup->usGroupTeam == ENEMY_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY )
{
switch ( aSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR:
if ( pGroup->pEnemyGroup->ubNumAdmins_Turncoat )
{
pGroup->pEnemyGroup->ubNumAdmins_Turncoat--;
return true;
}
break;
case SOLDIER_CLASS_ARMY:
if ( pGroup->pEnemyGroup->ubNumTroops_Turncoat )
{
pGroup->pEnemyGroup->ubNumTroops_Turncoat--;
return true;
}
break;
case SOLDIER_CLASS_ELITE:
if ( pGroup->pEnemyGroup->ubNumElites_Turncoat )
{
pGroup->pEnemyGroup->ubNumElites_Turncoat--;
return true;
}
break;
default:
break;
}
}
pGroup = pGroup->next;
}
}
}
return false;
}
bool AddOneTurncoat( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass )
{
// 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.
if ( sSectorX < MINIMUM_VALID_X_COORDINATE ||
sSectorX > MAXIMUM_VALID_X_COORDINATE ||
sSectorY < MINIMUM_VALID_Y_COORDINATE ||
sSectorY > MAXIMUM_VALID_Y_COORDINATE )
{
return false;
}
AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE );
AssertLE( sSectorX, MAXIMUM_VALID_X_COORDINATE );
AssertGE( sSectorY, MINIMUM_VALID_Y_COORDINATE );
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
SECTORINFO* pSector = &SectorInfo[SECTOR( sSectorX, sSectorY )];
// count how many 'slots' we have for more turncoats, then add one at a random position
UINT16 freeslots_static = 0;
UINT16 freeslots_groups = 0;
switch ( aSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR:
if ( pSector->ubNumAdmins_Turncoat < pSector->ubNumAdmins )
freeslots_static = pSector->ubNumAdmins - pSector->ubNumAdmins_Turncoat;
break;
case SOLDIER_CLASS_ARMY:
if ( pSector->ubNumTroops_Turncoat < pSector->ubNumTroops )
freeslots_static = pSector->ubNumTroops - pSector->ubNumTroops_Turncoat;
break;
case SOLDIER_CLASS_ELITE:
if ( pSector->ubNumElites_Turncoat < pSector->ubNumElites )
freeslots_static = pSector->ubNumElites - pSector->ubNumElites_Turncoat;
break;
default:
break;
}
GROUP* pGroup = gpGroupList;
while ( pGroup )
{
if ( pGroup->usGroupTeam == ENEMY_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY )
{
switch ( aSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR:
if ( pGroup->pEnemyGroup->ubNumAdmins_Turncoat < pGroup->pEnemyGroup->ubNumAdmins )
freeslots_groups += pGroup->pEnemyGroup->ubNumAdmins - pGroup->pEnemyGroup->ubNumAdmins_Turncoat;
break;
case SOLDIER_CLASS_ARMY:
if ( pGroup->pEnemyGroup->ubNumTroops_Turncoat < pGroup->pEnemyGroup->ubNumTroops )
freeslots_groups += pGroup->pEnemyGroup->ubNumTroops - pGroup->pEnemyGroup->ubNumTroops_Turncoat;
break;
case SOLDIER_CLASS_ELITE:
if ( pGroup->pEnemyGroup->ubNumElites_Turncoat < pGroup->pEnemyGroup->ubNumElites )
freeslots_groups += pGroup->pEnemyGroup->ubNumElites - pGroup->pEnemyGroup->ubNumElites_Turncoat;
break;
default:
break;
}
}
pGroup = pGroup->next;
}
if ( freeslots_static + freeslots_groups )
{
if ( Chance( 100 * freeslots_static / ( freeslots_static + freeslots_groups ) ) )
{
// add to garrison
switch ( aSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR:
pSector->ubNumAdmins_Turncoat++;
return true;
break;
case SOLDIER_CLASS_ARMY:
pSector->ubNumTroops_Turncoat++;
return true;
break;
case SOLDIER_CLASS_ELITE:
pSector->ubNumElites_Turncoat++;
return true;
break;
default:
break;
}
}
else
{
GROUP* pGroup = gpGroupList;
while ( pGroup )
{
if ( pGroup->usGroupTeam == ENEMY_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY )
{
switch ( aSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR:
if ( pGroup->pEnemyGroup->ubNumAdmins_Turncoat < pGroup->pEnemyGroup->ubNumAdmins )
{
pGroup->pEnemyGroup->ubNumAdmins_Turncoat++;
return true;
}
break;
case SOLDIER_CLASS_ARMY:
if ( pGroup->pEnemyGroup->ubNumTroops_Turncoat < pGroup->pEnemyGroup->ubNumTroops )
{
pGroup->pEnemyGroup->ubNumTroops_Turncoat++;
return true;
}
break;
case SOLDIER_CLASS_ELITE:
if ( pGroup->pEnemyGroup->ubNumElites_Turncoat < pGroup->pEnemyGroup->ubNumElites )
{
pGroup->pEnemyGroup->ubNumElites_Turncoat++;
return true;
}
break;
default:
break;
}
}
pGroup = pGroup->next;
}
}
}
return false;
}
void CorrectTurncoatCount( INT16 sSectorX, INT16 sSectorY )
{
// 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.
if ( sSectorX < MINIMUM_VALID_X_COORDINATE ||
sSectorX > MAXIMUM_VALID_X_COORDINATE ||
sSectorY < MINIMUM_VALID_Y_COORDINATE ||
sSectorY > MAXIMUM_VALID_Y_COORDINATE )
{
return;
}
AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE );
AssertLE( sSectorX, MAXIMUM_VALID_X_COORDINATE );
AssertGE( sSectorY, MINIMUM_VALID_Y_COORDINATE );
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
SECTORINFO* pSector = &SectorInfo[SECTOR( sSectorX, sSectorY )];
if ( pSector->ubNumAdmins_Turncoat > pSector->ubNumAdmins )
{
pSector->ubNumTroops_Turncoat += pSector->ubNumAdmins_Turncoat - pSector->ubNumAdmins;
pSector->ubNumAdmins_Turncoat = pSector->ubNumAdmins;
}
if ( pSector->ubNumTroops_Turncoat > pSector->ubNumTroops )
{
pSector->ubNumElites_Turncoat += pSector->ubNumTroops_Turncoat - pSector->ubNumTroops;
pSector->ubNumTroops_Turncoat = pSector->ubNumTroops;
}
if ( pSector->ubNumElites_Turncoat > pSector->ubNumElites )
{
pSector->ubNumElites_Turncoat = pSector->ubNumElites;
}
GROUP* pGroup = gpGroupList;
while ( pGroup )
{
if ( pGroup->usGroupTeam == ENEMY_TEAM && !pGroup->fVehicle && pGroup->ubSectorX == sSectorX && pGroup->ubSectorY == sSectorY )
{
if ( pGroup->pEnemyGroup->ubNumAdmins_Turncoat > pGroup->pEnemyGroup->ubNumAdmins )
{
pGroup->pEnemyGroup->ubNumTroops_Turncoat += pGroup->pEnemyGroup->ubNumAdmins_Turncoat - pGroup->pEnemyGroup->ubNumAdmins;
pGroup->pEnemyGroup->ubNumAdmins_Turncoat = pGroup->pEnemyGroup->ubNumAdmins;
}
if ( pGroup->pEnemyGroup->ubNumTroops_Turncoat > pGroup->pEnemyGroup->ubNumTroops )
{
pGroup->pEnemyGroup->ubNumElites_Turncoat += pGroup->pEnemyGroup->ubNumTroops_Turncoat - pGroup->pEnemyGroup->ubNumTroops;
pGroup->pEnemyGroup->ubNumTroops_Turncoat = pGroup->pEnemyGroup->ubNumTroops;
}
if ( pGroup->pEnemyGroup->ubNumElites_Turncoat > pGroup->pEnemyGroup->ubNumElites )
{
pGroup->pEnemyGroup->ubNumElites_Turncoat = pGroup->pEnemyGroup->ubNumElites;
}
}
pGroup = pGroup->next;
}
}
+7
View File
@@ -73,6 +73,13 @@ extern INT32 gsGridNoForMapEdgePointInfo;
// This currently does not exist for MILITIA_TEAM, making such a check relatively useless
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 AddOneTurncoat( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass );
void CorrectTurncoatCount( INT16 sSectorX, INT16 sSectorY );
extern UINT32 guiTurnCnt, guiReinforceTurn, guiMilitiaReinforceTurn;//dnl ch68 080913
#endif
+35
View File
@@ -5815,6 +5815,13 @@ void InvestigateSector( UINT8 ubSectorID )
ubNumToSend--;
ubAdmins[i]++;
ubTotal++;
// Flugente: turncoats might move as well
if ( pSector->ubNumAdmins_Turncoat > pSector->ubNumAdmins )
{
SectorInfo[ubSectorID].ubNumAdmins_Turncoat += pSector->ubNumAdmins_Turncoat - pSector->ubNumAdmins;
pSector->ubNumAdmins_Turncoat = pSector->ubNumAdmins;
}
}
else if( pSector->ubNumTroops )
{
@@ -5822,6 +5829,13 @@ void InvestigateSector( UINT8 ubSectorID )
ubNumToSend--;
ubTroops[i]++;
ubTotal++;
// Flugente: turncoats might move as well
if ( pSector->ubNumTroops_Turncoat > pSector->ubNumTroops )
{
SectorInfo[ubSectorID].ubNumTroops_Turncoat += pSector->ubNumTroops_Turncoat - pSector->ubNumTroops;
pSector->ubNumTroops_Turncoat = pSector->ubNumTroops;
}
}
else if( pSector->ubNumElites )
{
@@ -5829,6 +5843,13 @@ void InvestigateSector( UINT8 ubSectorID )
ubNumToSend--;
ubElites[i]++;
ubTotal++;
// Flugente: turncoats might move as well
if ( pSector->ubNumElites_Turncoat > pSector->ubNumElites )
{
SectorInfo[ubSectorID].ubNumElites_Turncoat += pSector->ubNumElites_Turncoat - pSector->ubNumElites;
pSector->ubNumElites_Turncoat = pSector->ubNumElites;
}
}
else
{
@@ -6571,6 +6592,13 @@ void UpgradeAdminsToTroops()
--ubAdminsToCheck;
}
// Flugente: make sure turncoat numbers are plausible
if ( pSector->ubNumAdmins_Turncoat > pSector->ubNumAdmins )
{
pSector->ubNumTroops_Turncoat += pSector->ubNumAdmins_Turncoat - pSector->ubNumAdmins;
pSector->ubNumAdmins_Turncoat = pSector->ubNumAdmins;
}
}
}
}
@@ -6628,6 +6656,13 @@ void UpgradeAdminsToTroops()
ubAdminsToCheck--;
}
// Flugente: make sure turncoat numbers are plausible
if ( pGroup->pEnemyGroup->ubNumAdmins_Turncoat > pGroup->pEnemyGroup->ubNumAdmins )
{
pGroup->pEnemyGroup->ubNumTroops_Turncoat += pGroup->pEnemyGroup->ubNumAdmins_Turncoat - pGroup->pEnemyGroup->ubNumAdmins;
pGroup->pEnemyGroup->ubNumAdmins_Turncoat = pGroup->pEnemyGroup->ubNumAdmins;
}
}
}
}
+8 -1
View File
@@ -75,7 +75,14 @@ typedef struct ENEMYGROUP
UINT8 ubTanksInBattle;
UINT8 ubNumJeeps;
UINT8 ubJeepsInBattle;
INT8 bPadding[16];
// Flugente: number of turncoats
UINT8 ubNumAdmins_Turncoat;
UINT8 ubNumTroops_Turncoat;
UINT8 ubNumElites_Turncoat;
UINT8 bPadding_1;
INT8 bPadding[12];
}ENEMYGROUP;
//NOTE: ALL FLAGS ARE CLEARED WHENEVER A GROUP ARRIVES IN A SECTOR, OR ITS WAYPOINTS ARE
+3
View File
@@ -431,12 +431,15 @@ INT8 SoldierClassToMilitiaRank(UINT8 ubSoldierClass)
switch( ubSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR:
case SOLDIER_CLASS_GREEN_MILITIA:
bRank = GREEN_MILITIA;
break;
case SOLDIER_CLASS_ARMY:
case SOLDIER_CLASS_REG_MILITIA:
bRank = REGULAR_MILITIA;
break;
case SOLDIER_CLASS_ELITE:
case SOLDIER_CLASS_ELITE_MILITIA:
bRank = ELITE_MILITIA;
break;