mirror of
https://github.com/1dot13/source.git
synced 2026-09-02 14:36:06 +02:00
- New prisoner class: Civilians can be interrogated. Does not work for profile-based charcters.
- Capturing civilians is possible if their faction has <fCanBeCaptured> set to 1. Requires GameDir >= r2215. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7762 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -1248,7 +1248,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
|
||||
}
|
||||
|
||||
// Flugente: handcuffing people
|
||||
if ( gGameExternalOptions.fAllowPrisonerSystem && HasItemFlag( usHandItem, HANDCUFFS ) && pTargetSoldier && pTargetSoldier->CanBeHandcuffed( ) )
|
||||
if ( gGameExternalOptions.fAllowPrisonerSystem && HasItemFlag( usHandItem, HANDCUFFS ) && pTargetSoldier && pTargetSoldier->CanBeCaptured( ) )
|
||||
{
|
||||
// ATE: AI CANNOT GO THROUGH HERE!
|
||||
INT32 usMapPos;
|
||||
|
||||
@@ -82,6 +82,7 @@ typedef struct
|
||||
BOOLEAN Enabled; //add
|
||||
BOOLEAN Loyalty;
|
||||
BOOLEAN AddToBattle;
|
||||
BOOLEAN fCanBeCaptured; // Flugente: if TRUE, members of this faction can be captured
|
||||
CHAR16 szCurGroup[MAX_ENEMY_NAMES_CHARS];
|
||||
|
||||
} CIV_NAMES_VALUES;
|
||||
|
||||
+57
-10
@@ -6789,7 +6789,7 @@ void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
|
||||
for ( pTeamSoldier = Menptr, cnt = 0; cnt < TOTAL_SOLDIERS; ++pTeamSoldier, ++cnt )
|
||||
{
|
||||
// Kill those not already dead.,...
|
||||
if ( pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->bTeam == ENEMY_TEAM )
|
||||
if ( pTeamSoldier->bActive && pTeamSoldier->bInSector )
|
||||
{
|
||||
// Only pows that are not dead yet
|
||||
if ( (pTeamSoldier->usSoldierFlagMask & SOLDIER_POW) && !(pTeamSoldier->flags.uiStatusFlags & SOLDIER_DEAD) )
|
||||
@@ -6802,7 +6802,7 @@ void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
|
||||
++sNumPrisoner[PRISONER_GENERAL];
|
||||
else if ( pTeamSoldier->usSoldierFlagMask & SOLDIER_ENEMY_OFFICER )
|
||||
++sNumPrisoner[PRISONER_OFFICER];
|
||||
else
|
||||
else if ( pTeamSoldier->bTeam == ENEMY_TEAM )
|
||||
{
|
||||
switch ( pTeamSoldier->ubSoldierClass )
|
||||
{
|
||||
@@ -6815,6 +6815,10 @@ void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
|
||||
break;
|
||||
}
|
||||
}
|
||||
else //if ( pTeamSoldier->bTeam == CIV_TEAM )
|
||||
{
|
||||
++sNumPrisoner[PRISONER_CIVILIAN];
|
||||
}
|
||||
|
||||
// Flugente: VIPs
|
||||
if ( pTeamSoldier->usSoldierFlagMask & SOLDIER_VIP )
|
||||
@@ -10427,6 +10431,12 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
// if the merc asking for surrender is experienced in capitulation negotiations, we get a bonus to our strength
|
||||
if ( pSoldier )
|
||||
playersidestrength = (playersidestrength * (100 + pSoldier->GetBackgroundValue(BG_PERC_CAPITULATION))) / 100;
|
||||
|
||||
// Capturing profile-based NPCs would be desirable, but is a good way to break quests. Due to this, we don't allow capturing them.
|
||||
// As it would be odd if the entire enemy team surrenders apart from one guy, we don't allow surrender, no matter the surrender strength, if a hostile profile-based NPC is around.
|
||||
// We also don't allow surrender if the enemy has a tank.
|
||||
// We justify this storywise by these soldiers being very determined leaders who don't allow surrender categorically.
|
||||
BOOLEAN fNoSurrender = FALSE;
|
||||
|
||||
// enemy team
|
||||
firstid = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID;
|
||||
@@ -10436,6 +10446,9 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
if( pSoldier->bActive && ( pSoldier->sSectorX == gWorldSectorX ) && ( pSoldier->sSectorY == gWorldSectorY ) && ( pSoldier->bSectorZ == gbWorldSectorZ) )
|
||||
{
|
||||
enemysidestrength += pSoldier->GetSurrenderStrength();
|
||||
|
||||
if ( pSoldier->ubProfile != NO_PROFILE || pSoldier->ubSoldierClass == SOLDIER_CLASS_TANK )
|
||||
fNoSurrender = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10447,8 +10460,14 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
if( pSoldier->bActive && ( pSoldier->sSectorX == gWorldSectorX ) && ( pSoldier->sSectorY == gWorldSectorY ) && ( pSoldier->bSectorZ == gbWorldSectorZ) )
|
||||
{
|
||||
// if a civilian is not neutral and on the enemy side, add his strength to the team
|
||||
if ( !pSoldier->aiData.bNeutral && pSoldier->bSide == 1 )
|
||||
enemysidestrength += pSoldier->GetSurrenderStrength();
|
||||
if ( !pSoldier->aiData.bNeutral && pSoldier->bSide == 1 && zCivGroupName[pSoldier->ubCivilianGroup].fCanBeCaptured && pSoldier->ubProfile != NO_PROFILE )
|
||||
fNoSurrender = TRUE;
|
||||
|
||||
// a civilian can only be captured if his faction is allowed to. This should prevent the player from exploiting a huge numerical superiority against small enemy groups, like lone assassins.
|
||||
if ( !pSoldier->CanBeCaptured() )
|
||||
continue;
|
||||
|
||||
enemysidestrength += pSoldier->GetSurrenderStrength( );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10464,7 +10483,7 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_SURRENDER_VALUES], playersidestrength, gGameExternalOptions.fSurrenderMultiplier * enemysidestrength );
|
||||
|
||||
// perhaps this can be fleshed out more, for now, let's see if this is acceptable behaviour
|
||||
if ( playersidestrength >= gGameExternalOptions.fSurrenderMultiplier * enemysidestrength )
|
||||
if ( !fNoSurrender && playersidestrength >= gGameExternalOptions.fSurrenderMultiplier * enemysidestrength )
|
||||
{
|
||||
// it is enough to simply set all soldiers to captured
|
||||
firstid = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID;
|
||||
@@ -10473,8 +10492,12 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
{
|
||||
if( pSoldier->bActive && ( pSoldier->sSectorX == gWorldSectorX ) && ( pSoldier->sSectorY == gWorldSectorY ) && ( pSoldier->bSectorZ == gbWorldSectorZ) )
|
||||
{
|
||||
// only if not dying, and if not a NPC (Mike...)
|
||||
if( pSoldier->stats.bLife >= OKLIFE && pSoldier->ubProfile == NO_PROFILE )
|
||||
// can this guy be captured?
|
||||
if ( !pSoldier->CanBeCaptured( ) )
|
||||
continue;
|
||||
|
||||
// only if not dying
|
||||
if( pSoldier->stats.bLife >= OKLIFE )
|
||||
{
|
||||
pSoldier->usSoldierFlagMask |= SOLDIER_POW;
|
||||
|
||||
@@ -10483,10 +10506,34 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
firstid = gTacticalStatus.Team[CIV_TEAM].bFirstID;
|
||||
lastid = gTacticalStatus.Team[CIV_TEAM].bLastID;
|
||||
for ( uiCnt = firstid, pSoldier = MercPtrs[uiCnt]; uiCnt <= lastid; ++uiCnt, ++pSoldier )
|
||||
{
|
||||
if ( pSoldier->bActive && (pSoldier->sSectorX == gWorldSectorX) && (pSoldier->sSectorY == gWorldSectorY) && (pSoldier->bSectorZ == gbWorldSectorZ) )
|
||||
{
|
||||
// can this guy be captured?
|
||||
if ( !pSoldier->CanBeCaptured() )
|
||||
continue;
|
||||
|
||||
// only if not dying
|
||||
if ( pSoldier->stats.bLife >= OKLIFE )
|
||||
{
|
||||
pSoldier->usSoldierFlagMask |= SOLDIER_POW;
|
||||
|
||||
// Remove as target
|
||||
RemoveManAsTarget( pSoldier );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_REFUSE_SURRENDER] );
|
||||
if ( fNoSurrender )
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_REFUSE_SURRENDER_LEADER] );
|
||||
else
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_REFUSE_SURRENDER] );
|
||||
|
||||
// if asking for surrender while undercover and the enemy refuses, he learns who you are, so he uncovers you
|
||||
if ( gusSelectedSoldier != NOBODY && MercPtrs[ gusSelectedSoldier ]->usSoldierFlagMask & (SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER) )
|
||||
@@ -10561,8 +10608,8 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
// Flugente: offer the enemy the chance to surrender
|
||||
void HandleSurrenderOffer( SOLDIERTYPE* pSoldier )
|
||||
{
|
||||
// only against enemies...
|
||||
if ( !pSoldier || pSoldier->bTeam != ENEMY_TEAM )
|
||||
// abort if bad pointer, or not an enemy and not a capturable civilian
|
||||
if ( !pSoldier || !pSoldier->CanBeCaptured( ) )
|
||||
return;
|
||||
|
||||
// remember the target's ID
|
||||
|
||||
@@ -16176,13 +16176,28 @@ BOOLEAN SOLDIERTYPE::FreePrisoner( )
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// can this guy be handcuffed?
|
||||
BOOLEAN SOLDIERTYPE::CanBeHandcuffed( )
|
||||
// can this guy be captured (by handcuffing or asking him to surrender)?
|
||||
BOOLEAN SOLDIERTYPE::CanBeCaptured( )
|
||||
{
|
||||
// if this is an enemy that has not already been captured, and is not a NPC, we can handcuff and thus capture him
|
||||
if ( this->bTeam == ENEMY_TEAM && !(this->usSoldierFlagMask & SOLDIER_POW) && this->ubProfile == NO_PROFILE )
|
||||
return TRUE;
|
||||
// if this guy is not already handcuffed, and is not an NPC
|
||||
if ( !(this->usSoldierFlagMask & SOLDIER_POW) && this->ubProfile == NO_PROFILE )
|
||||
{
|
||||
// tanks cannot be captured
|
||||
if ( this->ubSoldierClass == SOLDIER_CLASS_TANK )
|
||||
return FALSE;
|
||||
|
||||
// enemies can be captured
|
||||
if ( this->bTeam == ENEMY_TEAM )
|
||||
return TRUE;
|
||||
|
||||
// civilians can be captured if their faction can, and if they are hostile
|
||||
if ( this->bTeam == CIV_TEAM && zCivGroupName[this->ubCivilianGroup].fCanBeCaptured )
|
||||
{
|
||||
if ( !this->aiData.bNeutral && this->bSide == 1 )
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -19795,7 +19810,7 @@ void SOLDIERTYPE::EVENT_SoldierHandcuffPerson( INT32 sGridNo, UINT8 ubDirection
|
||||
|
||||
UINT8 ubPerson = WhoIsThere2( sGridNo, this->pathing.bLevel );
|
||||
|
||||
if ( ubPerson != NOBODY && MercPtrs[ubPerson]->CanBeHandcuffed( ) )
|
||||
if ( ubPerson != NOBODY && MercPtrs[ubPerson]->CanBeCaptured( ) )
|
||||
{
|
||||
// we found someone we can handcuff
|
||||
SOLDIERTYPE* pSoldier = MercPtrs[ubPerson];
|
||||
@@ -20390,8 +20405,9 @@ BOOLEAN SOLDIERTYPE::PlayerSoldierStartTalking( UINT8 ubTargetID, BOOLEAN fValid
|
||||
DeductPoints( this, sAPCost, 0, UNTRIGGERED_INTERRUPT );
|
||||
apsDeducted = TRUE;
|
||||
|
||||
// Flugente: if we are talking to an enemy, we have the option to offer them surrendering... but not on y levels >= 16 (no surrendering in the palace, as we have to kill, not capture, the queen)
|
||||
if ( pTSoldier->bTeam == ENEMY_TEAM && (gGameExternalOptions.fEnemyCanSurrender || gGameExternalOptions.fPlayerCanAsktoSurrender) && gWorldSectorY < WORLD_MAP_X - 2 )
|
||||
// Flugente: if we are talking to an enemy, we have the option to offer them surrender...
|
||||
if ( (pTSoldier->bTeam == ENEMY_TEAM || (pTSoldier->bTeam == CIV_TEAM && zCivGroupName[pTSoldier->ubCivilianGroup].fCanBeCaptured) )
|
||||
&& (gGameExternalOptions.fEnemyCanSurrender || gGameExternalOptions.fPlayerCanAsktoSurrender) )
|
||||
{
|
||||
HandleSurrenderOffer( pTSoldier );
|
||||
return(FALSE);
|
||||
|
||||
@@ -407,7 +407,9 @@ enum
|
||||
#define SOLDIER_INTERROGATE_OFFICER 0x00000040 //64 // interrogate officers
|
||||
#define SOLDIER_INTERROGATE_GENERAL 0x00000080 //128 // interrogate generals
|
||||
|
||||
#define SOLDIER_INTERROGATE_ALL 0x000000F8 // all interrogation flags
|
||||
#define SOLDIER_INTERROGATE_CIVILIAN 0x00000100 //256 // interrogate civilian
|
||||
|
||||
#define SOLDIER_INTERROGATE_ALL 0x000001F8 // all interrogation flags
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// -------- added by Flugente: disease property flags --------
|
||||
@@ -1769,7 +1771,7 @@ public:
|
||||
BOOLEAN CanProcessPrisoners();
|
||||
UINT32 GetSurrenderStrength();
|
||||
BOOLEAN FreePrisoner(); // used for an enemy liberating fellow prisoners
|
||||
BOOLEAN CanBeHandcuffed(); // can this guy be handcuffed?
|
||||
BOOLEAN CanBeCaptured(); // can this guy be captured (by handcuffing or asking him to surrender)?
|
||||
|
||||
// Flugente: scuba gear
|
||||
BOOLEAN UsesScubaGear();
|
||||
|
||||
@@ -2253,7 +2253,7 @@ UINT8 HandleHandcuffCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT32 uiCurso
|
||||
{
|
||||
// is there a person here?
|
||||
UINT8 usSoldierIndex = WhoIsThere2( sGridNo, pSoldier->pathing.bLevel );
|
||||
if ( usSoldierIndex != NOBODY && MercPtrs[usSoldierIndex]->CanBeHandcuffed( ) )
|
||||
if ( usSoldierIndex != NOBODY && MercPtrs[usSoldierIndex]->CanBeCaptured( ) )
|
||||
{
|
||||
return( HANDCUFF_GREY_UICURSOR );
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ civGroupNamesStartElementHandle(void *userData, const XML_Char *name, const XML_
|
||||
strcmp(name, "Enabled") == 0 ||
|
||||
strcmp(name, "Loyalty") == 0 ||
|
||||
strcmp(name, "AddToBattle") == 0 ||
|
||||
strcmp(name, "fCanBeCaptured" ) == 0 ||
|
||||
strcmp(name, "szGroup") == 0 ))
|
||||
{
|
||||
pData->curElement = ELEMENT_PROPERTY;
|
||||
@@ -98,6 +99,7 @@ civGroupNamesEndElementHandle(void *userData, const XML_Char *name)
|
||||
|
||||
zCivGroupName[pData->curCivGroupNames.uiIndex].AddToBattle = pData->curCivGroupNames.AddToBattle;
|
||||
zCivGroupName[pData->curCivGroupNames.uiIndex].Loyalty = pData->curCivGroupNames.Loyalty;
|
||||
zCivGroupName[pData->curCivGroupNames.uiIndex].fCanBeCaptured = pData->curCivGroupNames.fCanBeCaptured;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -125,6 +127,11 @@ civGroupNamesEndElementHandle(void *userData, const XML_Char *name)
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curCivGroupNames.AddToBattle = (BOOLEAN) atol(pData->szCharData);
|
||||
}
|
||||
else if ( strcmp( name, "fCanBeCaptured" ) == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curCivGroupNames.fCanBeCaptured = (BOOLEAN)atol( pData->szCharData );
|
||||
}
|
||||
else if(strcmp(name, "szGroup") == 0 )
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
|
||||
Reference in New Issue
Block a user