mirror of
https://github.com/1dot13/source.git
synced 2026-08-12 14:10:23 +02:00
Prisoner feature bugfix (#110)
* Allow game to continue after offering to surrender to enemies * Fix issues related to surrender and POW quests - Quests were ended prematurely if one had prisoners in both alma and tixa - Strategic status flags for rescue/escape were not set properly - Only the maximum amount a prison can hold will be taken as POWs, rest of the mercs will either escape or have to fight to the death, to prevent a player having unrescuable POWs - Capturing a mercenary had a lot of functions called that should not have been, IF the merc is not going to be captured after all * Switch all tactical surrender calls to use one unified function * Only mercs that are capable can escape Incapacitated mercs left behind will die. Should probably prioritize incapacitated mercs to be captured by the enemy to prevent needless deaths * Combine pow quest state changes into one function * Add JumpIntoEscapedSector to header file * Allow enemy to demand surrender even if they already have POWs in Tixa and Alma * Remove surrender from UB * Address review feedback
This commit is contained in:
@@ -523,22 +523,10 @@ BOOLEAN SetThisSectorAsEnemyControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BO
|
||||
UpdateRefuelSiteAvailability( );
|
||||
}
|
||||
|
||||
//shadooow: re-enable quest if player loses control of the N7 prison and quest was disabled previously
|
||||
if (sMapX == gModSettings.ubMeanwhileInterrogatePOWSectorX && sMapY == gModSettings.ubMeanwhileInterrogatePOWSectorY && gubQuest[QUEST_INTERROGATION] == QUESTCANNOTSTART)
|
||||
{
|
||||
gubQuest[QUEST_INTERROGATION] = QUESTNOTSTARTED;
|
||||
}
|
||||
//shadooow: re-enable quest if player loses control of the Alma prison and quest was disabled previously
|
||||
if (sMapX == gModSettings.ubInitialPOWSectorX && sMapY == gModSettings.ubInitialPOWSectorY && gubQuest[QUEST_HELD_IN_ALMA] == QUESTCANNOTSTART)
|
||||
{
|
||||
gubQuest[QUEST_HELD_IN_ALMA] = QUESTNOTSTARTED;
|
||||
}
|
||||
#ifndef JA2UB
|
||||
//shadooow: re-enable quest if player loses control of the Tixa prison and quest was disabled previously
|
||||
if (sMapX == gModSettings.ubTixaPrisonSectorX && sMapY == gModSettings.ubTixaPrisonSectorY && gubQuest[QUEST_HELD_IN_TIXA] == QUESTCANNOTSTART)
|
||||
{
|
||||
gubQuest[QUEST_HELD_IN_TIXA] = QUESTNOTSTARTED;
|
||||
}
|
||||
HandlePOWQuestState(Q_RESET, QUEST_INTERROGATION, sMapX, sMapY, bMapZ);
|
||||
HandlePOWQuestState(Q_RESET, QUEST_HELD_IN_ALMA, sMapX, sMapY, bMapZ);
|
||||
HandlePOWQuestState(Q_RESET, QUEST_HELD_IN_TIXA, sMapX, sMapY, bMapZ);
|
||||
#endif
|
||||
// Flugente: reduce workforce
|
||||
SectorInfo[SECTOR( sMapX, sMapY )].usWorkers = SectorInfo[SECTOR( sMapX, sMapY )].usWorkers * gGameExternalOptions.dInitialWorkerRate;
|
||||
|
||||
+67
-66
@@ -41,6 +41,7 @@
|
||||
#include "Morale.h"
|
||||
#include "CampaignStats.h" // added by Flugente
|
||||
#include "ASD.h" // added by Flugente
|
||||
#include "Interface Panels.h"
|
||||
|
||||
#ifdef JA2BETAVERSION
|
||||
extern BOOLEAN gfClearCreatureQuest;
|
||||
@@ -2716,43 +2717,31 @@ void BeginCaptureSquence( )
|
||||
|
||||
void EndCaptureSequence( )
|
||||
{
|
||||
#ifdef JA2UB
|
||||
// no UB
|
||||
#else
|
||||
|
||||
#ifndef JA2UB
|
||||
// Set flag...
|
||||
if( !( gStrategicStatus.uiFlags & STRATEGIC_PLAYER_CAPTURED_FOR_RESCUE ) || !(gStrategicStatus.uiFlags & STRATEGIC_PLAYER_CAPTURED_FOR_ESCAPE) )
|
||||
{
|
||||
// CJC Dec 1 2002: fixing multiple captures:
|
||||
//gStrategicStatus.uiFlags |= STRATEGIC_PLAYER_CAPTURED_FOR_RESCUE;
|
||||
|
||||
if ( gubQuest[ QUEST_HELD_IN_ALMA ] == QUESTNOTSTARTED )
|
||||
{
|
||||
// CJC Dec 1 2002: fixing multiple captures:
|
||||
gStrategicStatus.uiFlags |= STRATEGIC_PLAYER_CAPTURED_FOR_RESCUE;
|
||||
StartQuest( QUEST_HELD_IN_ALMA, gWorldSectorX, gWorldSectorY );
|
||||
}
|
||||
// CJC Dec 1 2002: fixing multiple captures:
|
||||
//else if ( gubQuest[ QUEST_HELD_IN_ALMA ] == QUESTDONE )
|
||||
else if (gubQuest[QUEST_HELD_IN_ALMA] != QUESTINPROGRESS && gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED)
|
||||
else if (gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED)
|
||||
{
|
||||
// CJC Dec 1 2002: fixing multiple captures:
|
||||
gStrategicStatus.uiFlags |= STRATEGIC_PLAYER_CAPTURED_FOR_RESCUE;
|
||||
StartQuest(QUEST_HELD_IN_TIXA, gWorldSectorX, gWorldSectorY);
|
||||
}
|
||||
else if (gubQuest[QUEST_HELD_IN_ALMA] != QUESTINPROGRESS && gubQuest[QUEST_HELD_IN_TIXA] != QUESTINPROGRESS && gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED)
|
||||
else if (gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED)
|
||||
{
|
||||
StartQuest( QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY );
|
||||
// CJC Dec 1 2002: fixing multiple captures:
|
||||
gStrategicStatus.uiFlags |= STRATEGIC_PLAYER_CAPTURED_FOR_ESCAPE;
|
||||
|
||||
// OK! - Schedule Meanwhile now!
|
||||
HandleInterrogationMeanwhileScene();
|
||||
}
|
||||
// CJC Dec 1 2002: fixing multiple captures
|
||||
else
|
||||
{
|
||||
// !?!? set both flags
|
||||
// Set both flags if we can't start any of the three POW quests
|
||||
gStrategicStatus.uiFlags |= STRATEGIC_PLAYER_CAPTURED_FOR_RESCUE;
|
||||
gStrategicStatus.uiFlags |= STRATEGIC_PLAYER_CAPTURED_FOR_ESCAPE;
|
||||
}
|
||||
@@ -2760,16 +2749,22 @@ void EndCaptureSequence( )
|
||||
#endif
|
||||
}
|
||||
|
||||
int CalculateMaximumPrisonerAmount()
|
||||
{
|
||||
#ifndef JA2UB
|
||||
if (gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED) { return std::size(gModSettings.iInitialPOWGridNo); }
|
||||
if (gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED) { return std::size(gModSettings.iTixaPrisonPOWGridNo); }
|
||||
if (gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED) { return std::size(gModSettings.iMeanwhileInterrogatePOWGridNo); }
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
UINT32 i;
|
||||
BOOLEAN fMadeCorpse;
|
||||
INT32 iNumEnemiesInSector;
|
||||
|
||||
#ifndef JA2UB
|
||||
AssertNotNIL(pSoldier);
|
||||
|
||||
// ATE: Check first if ! in player captured sequence already
|
||||
// CJC Dec 1 2002: fixing multiple captures
|
||||
if ( ( gStrategicStatus.uiFlags & STRATEGIC_PLAYER_CAPTURED_FOR_RESCUE ) && (gStrategicStatus.uiFlags & STRATEGIC_PLAYER_CAPTURED_FOR_ESCAPE) )
|
||||
{
|
||||
return;
|
||||
@@ -2780,6 +2775,7 @@ void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
pSoldier->stats.bLife = 0;
|
||||
pSoldier->iHealableInjury = 0; // added by SANDRO
|
||||
BOOLEAN fMadeCorpse;
|
||||
HandleSoldierDeath( pSoldier, &fMadeCorpse );
|
||||
return;
|
||||
}
|
||||
@@ -2800,32 +2796,31 @@ void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier )
|
||||
return;
|
||||
}
|
||||
|
||||
// ATE: Patch fix If in a vehicle, remove from vehicle...
|
||||
TakeSoldierOutOfVehicle( pSoldier );
|
||||
|
||||
HandleMoraleEvent( pSoldier, MORALE_MERC_CAPTURED, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ );
|
||||
|
||||
// Change to POW....
|
||||
//-add him to a POW assignment/group
|
||||
if( ( pSoldier->bAssignment != ASSIGNMENT_POW ) )
|
||||
if (gStrategicStatus.ubNumCapturedForRescue >= CalculateMaximumPrisonerAmount())
|
||||
{
|
||||
SetTimeOfAssignmentChangeForMerc( pSoldier );
|
||||
SetTimeOfAssignmentChangeForMerc(pSoldier);
|
||||
return;
|
||||
}
|
||||
|
||||
ChangeSoldiersAssignment( pSoldier, ASSIGNMENT_POW );
|
||||
RemoveCharacterFromSquads( pSoldier );
|
||||
|
||||
WORLDITEM WorldItem;
|
||||
std::vector<WORLDITEM> pWorldItem;
|
||||
|
||||
#ifdef JA2UB
|
||||
if (gStrategicStatus.ubNumCapturedForRescue < 3 && (gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED || gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED))
|
||||
#else
|
||||
if (gStrategicStatus.ubNumCapturedForRescue < 3 && (gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED || gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED || gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED))
|
||||
#endif
|
||||
{
|
||||
INT32 itemdropoffgridno = -1;
|
||||
// ATE: Patch fix If in a vehicle, remove from vehicle...
|
||||
TakeSoldierOutOfVehicle(pSoldier);
|
||||
|
||||
HandleMoraleEvent(pSoldier, MORALE_MERC_CAPTURED, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ);
|
||||
|
||||
// Change to POW....
|
||||
//-add him to a POW assignment/group
|
||||
if ((pSoldier->bAssignment != ASSIGNMENT_POW))
|
||||
{
|
||||
SetTimeOfAssignmentChangeForMerc(pSoldier);
|
||||
}
|
||||
|
||||
ChangeSoldiersAssignment(pSoldier, ASSIGNMENT_POW);
|
||||
RemoveCharacterFromSquads(pSoldier);
|
||||
|
||||
|
||||
INT32 itemdropoffgridno = -1;
|
||||
// Is this the first one..?
|
||||
if ( gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED )
|
||||
{
|
||||
@@ -2837,7 +2832,6 @@ void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier )
|
||||
pSoldier->usStrategicInsertionData = gModSettings.iInitialPOWGridNo[gStrategicStatus.ubNumCapturedForRescue];
|
||||
itemdropoffgridno = gModSettings.iInitialPOWItemGridNo[gStrategicStatus.ubNumCapturedForRescue];
|
||||
}
|
||||
#ifndef JA2UB
|
||||
else if (gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED)
|
||||
{
|
||||
//-teleport him to Tixa as originally planned
|
||||
@@ -2848,7 +2842,6 @@ void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier )
|
||||
pSoldier->usStrategicInsertionData = gModSettings.iTixaPrisonPOWGridNo[gStrategicStatus.ubNumCapturedForRescue];
|
||||
itemdropoffgridno = gModSettings.iTixaPrisonPOWItemGridNo[gStrategicStatus.ubNumCapturedForRescue];
|
||||
}
|
||||
#endif
|
||||
else //if ( gubQuest[QUEST_HELD_IN_ALMA] == QUESTDONE )
|
||||
{
|
||||
//-teleport him to N7
|
||||
@@ -2860,8 +2853,10 @@ void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier )
|
||||
}
|
||||
|
||||
// OK, drop all items!
|
||||
WORLDITEM WorldItem;
|
||||
std::vector<WORLDITEM> pWorldItem;
|
||||
UINT32 invsize = pSoldier->inv.size();
|
||||
for ( i = 0; i < invsize; ++i )
|
||||
for (UINT32 i = 0; i < invsize; ++i )
|
||||
{
|
||||
if ( pSoldier->inv[i].exists() )
|
||||
{
|
||||
@@ -2883,34 +2878,40 @@ void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier )
|
||||
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
|
||||
|
||||
gStrategicStatus.ubNumCapturedForRescue++;
|
||||
}
|
||||
|
||||
//Bandaging him would prevent him from dying (due to low HP)
|
||||
pSoldier->bBleeding = 0;
|
||||
//Bandaging him would prevent him from dying (due to low HP)
|
||||
pSoldier->bBleeding = 0;
|
||||
|
||||
// wake him up
|
||||
if ( pSoldier->flags.fMercAsleep )
|
||||
{
|
||||
PutMercInAwakeState( pSoldier );
|
||||
pSoldier->flags.fForcedToStayAwake = FALSE;
|
||||
}
|
||||
// wake him up
|
||||
if ( pSoldier->flags.fMercAsleep )
|
||||
{
|
||||
PutMercInAwakeState( pSoldier );
|
||||
pSoldier->flags.fForcedToStayAwake = FALSE;
|
||||
}
|
||||
|
||||
//Set his life to 50% + or - 10 HP.
|
||||
INT8 oldlife = pSoldier->stats.bLife;
|
||||
pSoldier->stats.bLife = max(35, pSoldier->stats.bLifeMax / 2);
|
||||
//Set his life to 50% + or - 10 HP.
|
||||
INT8 oldlife = pSoldier->stats.bLife;
|
||||
pSoldier->stats.bLife = max(35, pSoldier->stats.bLifeMax / 2);
|
||||
|
||||
if ( pSoldier->stats.bLife >= 45 )
|
||||
{
|
||||
pSoldier->stats.bLife += (INT8)(10 - Random( 21 ) );
|
||||
}
|
||||
if ( pSoldier->stats.bLife >= 45 )
|
||||
{
|
||||
pSoldier->stats.bLife += (INT8)(10 - Random( 21 ) );
|
||||
}
|
||||
|
||||
// SANDRO - make the lost life insta-healable
|
||||
pSoldier->iHealableInjury = ((pSoldier->stats.bLifeMax - pSoldier->stats.bLife) * 100);
|
||||
// SANDRO - make the lost life insta-healable
|
||||
pSoldier->iHealableInjury = ((pSoldier->stats.bLifeMax - pSoldier->stats.bLife) * 100);
|
||||
|
||||
// make him quite exhausted when found
|
||||
pSoldier->bBreath = pSoldier->bBreathMax = 50;
|
||||
pSoldier->sBreathRed = 0;
|
||||
pSoldier->flags.fMercCollapsedFlag = FALSE;
|
||||
// make him quite exhausted when found
|
||||
pSoldier->bBreath = pSoldier->bBreathMax = 50;
|
||||
pSoldier->sBreathRed = 0;
|
||||
pSoldier->flags.fMercCollapsedFlag = FALSE;
|
||||
|
||||
|
||||
RemoveSoldierFromTacticalSector(pSoldier, TRUE);
|
||||
RemovePlayerFromTeamSlotGivenMercID(pSoldier->ubID);
|
||||
SelectNextAvailSoldier(pSoldier);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
+80
-5
@@ -1731,9 +1731,84 @@ void GiveQuestRewardPoint( INT16 sQuestSectorX, INT16 sQuestsSectorY, INT8 bExpR
|
||||
}
|
||||
}
|
||||
|
||||
void HandlePOWQuestState(PowQuestState state, Quests quest, INT16 mapX, INT16 mapY, INT8 mapZ)
|
||||
{
|
||||
#ifndef JA2UB
|
||||
bool correctSector = false;
|
||||
switch (quest)
|
||||
{
|
||||
case QUEST_HELD_IN_ALMA:
|
||||
correctSector = (mapX == gModSettings.ubInitialPOWSectorX && mapY == gModSettings.ubInitialPOWSectorY && mapZ == 0);
|
||||
break;
|
||||
case QUEST_INTERROGATION:
|
||||
correctSector = (mapX == gModSettings.ubMeanwhileInterrogatePOWSectorX && mapY == gModSettings.ubMeanwhileInterrogatePOWSectorY && mapZ == 0);
|
||||
break;
|
||||
case QUEST_HELD_IN_TIXA:
|
||||
correctSector = (mapX == gModSettings.ubTixaPrisonSectorX && mapY == gModSettings.ubTixaPrisonSectorY && mapZ == 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (correctSector)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case Q_FAIL:
|
||||
// End quest if player loses prison
|
||||
if (gubQuest[quest] == QUESTINPROGRESS)
|
||||
{
|
||||
// Quest failed
|
||||
InternalEndQuest(quest, mapX, mapY, FALSE);
|
||||
}
|
||||
else if (gubQuest[quest] == QUESTCANNOTSTART)
|
||||
{
|
||||
// Re-enable quest if player loses control of the prison and quest was disabled previously
|
||||
gubQuest[quest] = QUESTNOTSTARTED;
|
||||
}
|
||||
break;
|
||||
case Q_SUCCESS:
|
||||
// End quest if player takes control of the prison
|
||||
if (gubQuest[quest] == QUESTINPROGRESS)
|
||||
{
|
||||
// Complete quest
|
||||
EndQuest(quest, mapX, mapY);
|
||||
}
|
||||
else if (gubQuest[quest] == QUESTNOTSTARTED)
|
||||
{
|
||||
// Disable quest if player takes control of the prison
|
||||
gubQuest[quest] = QUESTCANNOTSTART;
|
||||
}
|
||||
break;
|
||||
case Q_RESET:
|
||||
// Re-enable quest if player loses control of the prison and quest was disabled previously
|
||||
if (gubQuest[quest] == QUESTCANNOTSTART)
|
||||
{
|
||||
gubQuest[quest] = QUESTNOTSTARTED;
|
||||
}
|
||||
break;
|
||||
case Q_END:
|
||||
if (gubQuest[quest] == QUESTINPROGRESS)
|
||||
{
|
||||
EndQuest(quest, mapX, mapY);
|
||||
HandleNPCDoAction(0, NPC_ACTION_GRANT_EXPERIENCE_3, 0);
|
||||
}
|
||||
break;
|
||||
case Q_LEFT_SECTOR:
|
||||
// End interrogation quest if we left the sector, but haven't killed all enemies
|
||||
if (gubQuest[quest] == QUESTINPROGRESS)
|
||||
{
|
||||
// Finish quest, although not give points here...
|
||||
InternalEndQuest(quest, mapX, mapY, FALSE);
|
||||
// ... give them manually, but halved
|
||||
GiveQuestRewardPoint(mapX, mapY, 4, NO_PROFILE);
|
||||
// Also let us know we finished the quest
|
||||
ResetHistoryFact(quest, mapX, mapY);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
+9
-6
@@ -756,10 +756,13 @@ extern BOOLEAN CheckForNewShipment( void );
|
||||
extern BOOLEAN CheckTalkerFemale( void );
|
||||
extern BOOLEAN CheckTalkerUnpropositionedFemale( void );
|
||||
|
||||
enum PowQuestState
|
||||
{
|
||||
Q_FAIL,
|
||||
Q_SUCCESS,
|
||||
Q_RESET,
|
||||
Q_END,
|
||||
Q_LEFT_SECTOR
|
||||
};
|
||||
void HandlePOWQuestState(PowQuestState state, Quests quest, INT16 mapX, INT16 mapY, INT8 mapZ);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4453,7 +4453,7 @@ void CheckMembersOfMvtGroupAndComplainAboutBleeding( SOLDIERTYPE *pSoldier )
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure there are members in the group..if so, then run through and make each bleeder compain
|
||||
// make sure there are members in the group..if so, then run through and make each bleeder complain
|
||||
pPlayer = pGroup->pPlayerList;
|
||||
|
||||
// is there a player list?
|
||||
@@ -6274,4 +6274,4 @@ void GetInfoFromGroupsInSector( INT16 sSectorX, INT16 sSectorY, UINT8 ubTeam, BO
|
||||
}
|
||||
pGroup = pGroup->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+110
-41
@@ -2215,7 +2215,7 @@ BOOLEAN SetCurrentWorldSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
|
||||
// GridNo = NOWHERE, which causes this assertion to fail
|
||||
//CHRISL: There's also an issue with vehicles. Soldiers in any vehicle are considered to be in sGridNo = NOWHERE
|
||||
// This will result in an assertion error, so let's skip the assertion if the merc is assigned to a vehicle
|
||||
if ( !(MercPtrs[i]->flags.uiStatusFlags & SOLDIER_DEAD) && MercPtrs[i]->bAssignment != VEHICLE && !SPY_LOCATION( MercPtrs[i]->bAssignment ) )
|
||||
if (!(MercPtrs[i]->flags.uiStatusFlags & SOLDIER_DEAD) && MercPtrs[i]->bAssignment != VEHICLE && !SPY_LOCATION(MercPtrs[i]->bAssignment) && MercPtrs[i]->bAssignment != ASSIGNMENT_POW)
|
||||
{
|
||||
//Assert( !MercPtrs[i]->bActive || !MercPtrs[i]->bInSector || MercPtrs[i]->sGridNo != NOWHERE || MercPtrs[i]->bVehicleID == iHelicopterVehicleId );
|
||||
Assert( !MercPtrs[i]->bActive || !MercPtrs[i]->bInSector || !TileIsOutOfBounds( MercPtrs[i]->sGridNo ) || MercPtrs[i]->bVehicleID == iHelicopterVehicleId );
|
||||
@@ -2265,7 +2265,7 @@ BOOLEAN SetCurrentWorldSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
|
||||
// GridNo = NOWHERE, which causes this assertion to fail
|
||||
//CHRISL: There's also an issue with vehicles. Soldiers in any vehicle are considered to be in sGridNo = NOWHERE
|
||||
// This will result in an assertion error, so let's skip the assertion if the merc is assigned to a vehicle
|
||||
if ( !(MercPtrs[i]->flags.uiStatusFlags & SOLDIER_DEAD) && MercPtrs[i]->bAssignment != VEHICLE )
|
||||
if (!(MercPtrs[i]->flags.uiStatusFlags & SOLDIER_DEAD) && MercPtrs[i]->bAssignment != VEHICLE && MercPtrs[i]->bAssignment != ASSIGNMENT_POW)
|
||||
{
|
||||
//Assert( !MercPtrs[i]->bActive || !MercPtrs[i]->bInSector || MercPtrs[i]->sGridNo != NOWHERE || MercPtrs[i]->bVehicleID == iHelicopterVehicleId );
|
||||
Assert( !MercPtrs[i]->bActive || !MercPtrs[i]->bInSector || !TileIsOutOfBounds( MercPtrs[i]->sGridNo ) || MercPtrs[i]->bVehicleID == iHelicopterVehicleId );
|
||||
@@ -3290,23 +3290,9 @@ void UpdateMercsInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
|
||||
}
|
||||
|
||||
// ATE: Call actions based on what POW we are on...
|
||||
if ( gubQuest[QUEST_HELD_IN_ALMA] == QUESTINPROGRESS )
|
||||
{
|
||||
// Complete quest
|
||||
EndQuest( QUEST_HELD_IN_ALMA, sSectorX, sSectorY );
|
||||
|
||||
// Do action
|
||||
HandleNPCDoAction( 0, NPC_ACTION_GRANT_EXPERIENCE_3, 0 );
|
||||
}
|
||||
#ifndef JA2UB
|
||||
else if (gubQuest[QUEST_HELD_IN_TIXA] == QUESTINPROGRESS)
|
||||
{
|
||||
// Complete quest
|
||||
EndQuest(QUEST_HELD_IN_TIXA, sSectorX, sSectorY);
|
||||
|
||||
// Do action
|
||||
HandleNPCDoAction(0, NPC_ACTION_GRANT_EXPERIENCE_3, 0);
|
||||
}
|
||||
HandlePOWQuestState(Q_END, QUEST_HELD_IN_ALMA, sSectorX, sSectorY, bSectorZ);
|
||||
HandlePOWQuestState(Q_END, QUEST_HELD_IN_TIXA, sSectorX, sSectorY, bSectorZ);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -4301,6 +4287,68 @@ void JumpIntoAdjacentSector( UINT8 ubTacticalDirection, UINT8 ubJumpCode, INT32
|
||||
}
|
||||
}
|
||||
|
||||
void JumpIntoEscapedSector(UINT8 ubTacticalDirection)
|
||||
{
|
||||
// Remove any incapacitated mercs from current squads and assign them to new squad
|
||||
UINT32 i = gTacticalStatus.Team[gbPlayerNum].bFirstID;
|
||||
UINT32 const lastID = gTacticalStatus.Team[gbPlayerNum].bLastID;
|
||||
INT8 currentSquad = -1;
|
||||
|
||||
for (SOLDIERTYPE* pSoldier = MercPtrs[i]; i <= lastID; ++i, ++pSoldier)
|
||||
{
|
||||
// Are we not active in sector
|
||||
if (!pSoldier->bActive || !pSoldier->bInSector || pSoldier->stats.bLife >= OKLIFE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (currentSquad == -1)
|
||||
{
|
||||
currentSquad = AddCharacterToUniqueSquad(pSoldier);
|
||||
continue;
|
||||
}
|
||||
if (!AddCharacterToSquad(pSoldier, currentSquad))
|
||||
{
|
||||
currentSquad = AddCharacterToUniqueSquad(pSoldier);
|
||||
}
|
||||
}
|
||||
|
||||
// Retreat squads that are capable of it
|
||||
for (size_t i = 0; i < NUMBER_OF_SQUADS; i++)
|
||||
{
|
||||
for (size_t j = 0; j < NUMBER_OF_SOLDIERS_PER_SQUAD; j++)
|
||||
{
|
||||
SOLDIERTYPE* pSoldier = Squad[i][j];
|
||||
if (pSoldier && OK_CONTROLLABLE_MERC(pSoldier))
|
||||
{
|
||||
GROUP* pGroup = GetGroup(pSoldier->ubGroupID);
|
||||
switch (ubTacticalDirection)
|
||||
{
|
||||
case NORTH:
|
||||
pGroup->ubPrevX = pGroup->ubSectorX;
|
||||
pGroup->ubPrevY = pGroup->ubSectorY - 1;
|
||||
break;
|
||||
case EAST:
|
||||
pGroup->ubPrevX = pGroup->ubSectorX + 1;
|
||||
pGroup->ubPrevY = pGroup->ubSectorY;
|
||||
break;
|
||||
case SOUTH:
|
||||
pGroup->ubPrevX = pGroup->ubSectorX;
|
||||
pGroup->ubPrevY = pGroup->ubSectorY + 1;
|
||||
break;
|
||||
case WEST:
|
||||
pGroup->ubPrevX = pGroup->ubSectorX - 1;
|
||||
pGroup->ubPrevY = pGroup->ubSectorY;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
RetreatGroupToPreviousSector(pGroup);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandleSoldierLeavingSectorByThemSelf( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
@@ -4361,17 +4409,7 @@ void AllMercsWalkedToExitGrid( )
|
||||
(gubAdjacentJumpCode == JUMP_ALL_LOAD_NEW || gubAdjacentJumpCode == JUMP_SINGLE_LOAD_NEW) )
|
||||
{
|
||||
HandleLoyaltyImplicationsOfMercRetreat( RETREAT_TACTICAL_TRAVERSAL, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
||||
|
||||
// End inetrrogation quest if we left the sector, but haven't killed all enemies
|
||||
if ( gWorldSectorX == 7 && gWorldSectorY == 14 && gbWorldSectorZ == 0 && gubQuest[QUEST_INTERROGATION] == QUESTINPROGRESS )
|
||||
{
|
||||
// Finish quest, although not give points here...
|
||||
InternalEndQuest( QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY, FALSE );
|
||||
// ... give them manually, but halved
|
||||
GiveQuestRewardPoint( gWorldSectorX, gWorldSectorY, 4, NO_PROFILE );
|
||||
// Also get us know, we finished the quest
|
||||
ResetHistoryFact( QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY );
|
||||
}
|
||||
HandlePOWQuestState(Q_END, QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY, gbWorldSectorZ);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -4539,17 +4577,7 @@ void AllMercsHaveWalkedOffSector( )
|
||||
(gubAdjacentJumpCode == JUMP_ALL_LOAD_NEW || gubAdjacentJumpCode == JUMP_SINGLE_LOAD_NEW) )
|
||||
{
|
||||
HandleLoyaltyImplicationsOfMercRetreat( RETREAT_TACTICAL_TRAVERSAL, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
||||
|
||||
// End inetrrogation quest if we left the sector, but haven't killed all enemies
|
||||
if ( gWorldSectorX == 7 && gWorldSectorY == 14 && gbWorldSectorZ == 0 && gubQuest[QUEST_INTERROGATION] == QUESTINPROGRESS )
|
||||
{
|
||||
// Finish quest, although not give points here...
|
||||
InternalEndQuest( QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY, FALSE );
|
||||
// ... give them manually, but halved
|
||||
GiveQuestRewardPoint( gWorldSectorX, gWorldSectorY, 4, NO_PROFILE );
|
||||
// Also get us know, we finished the quest
|
||||
ResetHistoryFact( QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY );
|
||||
}
|
||||
HandlePOWQuestState(Q_END, QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY, gbWorldSectorZ);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
@@ -6921,6 +6949,47 @@ BOOLEAN EscapeDirectionIsValid( INT8 * pbDirection )
|
||||
}
|
||||
return(*pbDirection != -1);
|
||||
}
|
||||
|
||||
bool IsEscapeDirectionValid(WorldDirections pbDirection)
|
||||
{
|
||||
bool isValid = false;
|
||||
UINT8 const ubSectorID = SECTOR(gWorldSectorX, gWorldSectorY);
|
||||
|
||||
switch (pbDirection)
|
||||
{
|
||||
case NORTH:
|
||||
if (!(gWorldSectorY - 1 < MINIMUM_VALID_Y_COORDINATE || gMapInformation.sNorthGridNo == NOWHERE ||
|
||||
SectorInfo[ubSectorID].ubTraversability[NORTH_STRATEGIC_MOVE] == GROUNDBARRIER || SectorInfo[ubSectorID].ubTraversability[NORTH_STRATEGIC_MOVE] == EDGEOFWORLD))
|
||||
{
|
||||
isValid = true;
|
||||
}
|
||||
break;
|
||||
case EAST:
|
||||
if (!(gWorldSectorX + 1 > MAXIMUM_VALID_X_COORDINATE || gMapInformation.sEastGridNo == NOWHERE ||
|
||||
SectorInfo[ubSectorID].ubTraversability[EAST_STRATEGIC_MOVE] == GROUNDBARRIER || SectorInfo[ubSectorID].ubTraversability[EAST_STRATEGIC_MOVE] == EDGEOFWORLD))
|
||||
{
|
||||
isValid = true;
|
||||
}
|
||||
break;
|
||||
case SOUTH:
|
||||
if (!(gWorldSectorY + 1 > MAXIMUM_VALID_Y_COORDINATE || gMapInformation.sSouthGridNo == NOWHERE ||
|
||||
SectorInfo[ubSectorID].ubTraversability[SOUTH_STRATEGIC_MOVE] == GROUNDBARRIER || SectorInfo[ubSectorID].ubTraversability[SOUTH_STRATEGIC_MOVE] == EDGEOFWORLD))
|
||||
{
|
||||
isValid = true;
|
||||
}
|
||||
break;
|
||||
case WEST:
|
||||
if (!(gWorldSectorX - 1 < MINIMUM_VALID_X_COORDINATE || gMapInformation.sWestGridNo == NOWHERE ||
|
||||
SectorInfo[ubSectorID].ubTraversability[WEST_STRATEGIC_MOVE] == GROUNDBARRIER || SectorInfo[ubSectorID].ubTraversability[WEST_STRATEGIC_MOVE] == EDGEOFWORLD))
|
||||
{
|
||||
isValid = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
#ifdef JA2UB
|
||||
|
||||
|
||||
@@ -7968,4 +8037,4 @@ UINT8 tryToRecoverSquadsAndMovementGroups(SOLDIERTYPE* pCharacter) {
|
||||
}
|
||||
CheckSquadMovementGroups();
|
||||
return GetSoldierGroupId(pCharacter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ void GetMapFileName(INT16 sMapX,INT16 sMapY, INT8 bSectorZ, STR8 bString, BOOLEA
|
||||
|
||||
// Called from within tactical.....
|
||||
void JumpIntoAdjacentSector( UINT8 ubDirection, UINT8 ubJumpCode, INT32 sAdditionalData );//dnl ch56 151009
|
||||
|
||||
void JumpIntoEscapedSector(UINT8 ubTacticalDirection);
|
||||
|
||||
|
||||
BOOLEAN CanGoToTacticalInSector( INT16 sX, INT16 sY, UINT8 ubZ );
|
||||
@@ -207,6 +207,7 @@ BOOLEAN HandlePotentialBringUpAutoresolveToFinishBattle( int pSectorX, int pSect
|
||||
BOOLEAN MapExists( UINT8 * szFilename );
|
||||
|
||||
BOOLEAN EscapeDirectionIsValid( INT8 * pbDirection );
|
||||
bool IsEscapeDirectionValid(WorldDirections pbDirection);
|
||||
//Used for determining the type of error message that comes up when you can't traverse to
|
||||
//an adjacent sector. THESE VALUES DO NOT NEED TO BE SAVED!
|
||||
extern BOOLEAN gfInvalidTraversal;
|
||||
@@ -235,4 +236,4 @@ BOOLEAN CanRequestMilitiaReinforcements( INT16 sMapX, INT16 sMapY, INT16 sSrcMap
|
||||
// Bob: check and try to fix issues with squad and group assignment
|
||||
UINT8 tryToRecoverSquadsAndMovementGroups(SOLDIERTYPE* pCharacter);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user