diff --git a/Strategic/Player Command.cpp b/Strategic/Player Command.cpp index 57378482b..efa91292c 100644 --- a/Strategic/Player Command.cpp +++ b/Strategic/Player Command.cpp @@ -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; diff --git a/Strategic/Queen Command.cpp b/Strategic/Queen Command.cpp index c725d71d3..b964eed51 100644 --- a/Strategic/Queen Command.cpp +++ b/Strategic/Queen Command.cpp @@ -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 } -void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier ) +int CalculateMaximumPrisonerAmount() { - UINT32 i; - BOOLEAN fMadeCorpse; - INT32 iNumEnemiesInSector; +#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 ) +{ +#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 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 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 } diff --git a/Strategic/Quests.cpp b/Strategic/Quests.cpp index 3efbaf952..55b7bb23a 100644 --- a/Strategic/Quests.cpp +++ b/Strategic/Quests.cpp @@ -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 +} diff --git a/Strategic/Quests.h b/Strategic/Quests.h index f3a6b017d..71dfca2fd 100644 --- a/Strategic/Quests.h +++ b/Strategic/Quests.h @@ -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 - - - - - - diff --git a/Strategic/Strategic Movement.cpp b/Strategic/Strategic Movement.cpp index 9ed5170b1..5b884b569 100644 --- a/Strategic/Strategic Movement.cpp +++ b/Strategic/Strategic Movement.cpp @@ -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; } -} \ No newline at end of file +} diff --git a/Strategic/strategicmap.cpp b/Strategic/strategicmap.cpp index 3fe5133a7..e1dd54c47 100644 --- a/Strategic/strategicmap.cpp +++ b/Strategic/strategicmap.cpp @@ -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); -} \ No newline at end of file +} diff --git a/Strategic/strategicmap.h b/Strategic/strategicmap.h index 2bbffc8f3..e43191c5b 100644 --- a/Strategic/strategicmap.h +++ b/Strategic/strategicmap.h @@ -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 \ No newline at end of file +#endif diff --git a/Tactical/Civ Quotes.cpp b/Tactical/Civ Quotes.cpp index 07753c648..4bcf45e3f 100644 --- a/Tactical/Civ Quotes.cpp +++ b/Tactical/Civ Quotes.cpp @@ -197,42 +197,12 @@ BOOLEAN GetCivQuoteText(UINT16 ubCivQuoteID, UINT16 ubEntryID, STR16 zQuote ) void SurrenderMessageBoxCallBack( UINT8 ubExitValue ) { - SOLDIERTYPE *pTeamSoldier; - INT32 cnt = 0; - if ( ubExitValue == MSG_BOX_RETURN_YES ) { - // CJC Dec 1 2002: fix multiple captures - BeginCaptureSquence(); - - // Do capture.... - cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; - - for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pTeamSoldier++) - { - // Are we active and in sector..... - if ( pTeamSoldier->bActive && pTeamSoldier->bInSector ) - { - if ( pTeamSoldier->stats.bLife != 0 ) - { - EnemyCapturesPlayerSoldier( pTeamSoldier ); - - RemoveSoldierFromTacticalSector( pTeamSoldier, TRUE ); - } - } - } - - EndCaptureSequence( ); - - gfSurrendered = TRUE; - SetCustomizableTimerCallbackAndDelay( 3000, CaptureTimerCallback, FALSE ); - - ActionDone( gCivQuoteData.pCiv ); - } - else - { - ActionDone( gCivQuoteData.pCiv ); + AttemptToCapturePlayerSoldiers(); } + gTacticalStatus.fEnemyFlags |= ENEMY_OFFERED_SURRENDER; + ActionDone( gCivQuoteData.pCiv ); } void ShutDownQuoteBox( BOOLEAN fForce ) @@ -2383,4 +2353,4 @@ BOOLEAN PlayVoiceTaunt(SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTYPE *pTa } return TRUE; -} \ No newline at end of file +} diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp index 7d37ee0ab..36e5881de 100644 --- a/Tactical/Overhead.cpp +++ b/Tactical/Overhead.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include "wcheck.h" #include "stdlib.h" #include "debug.h" @@ -7594,35 +7596,11 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) HandleGlobalLoyaltyEvent(GLOBAL_LOYALTY_BATTLE_LOST, gWorldSectorX, gWorldSectorY, gbWorldSectorZ); } - // SANDRO - end quest if cleared the sector after interrogation (sector N7 by Meduna) - if ( gWorldSectorX == gModSettings.ubMeanwhileInterrogatePOWSectorX && gWorldSectorY == gModSettings.ubMeanwhileInterrogatePOWSectorY && - gbWorldSectorZ == 0) - { - if (gubQuest[QUEST_INTERROGATION] == QUESTINPROGRESS) - { - // Quest failed - InternalEndQuest(QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY, FALSE); - } - else if (gubQuest[QUEST_INTERROGATION] == QUESTCANNOTSTART) - { - //shadooow: re-enable quest if player loses control of the N7 prison and quest was disabled previously - gubQuest[QUEST_INTERROGATION] = QUESTNOTSTARTED; - } - } - //shadooow: re-enable quest if player loses control of the Alma prison and quest was disabled previously - if (gWorldSectorX == gModSettings.ubInitialPOWSectorX && gWorldSectorY == gModSettings.ubInitialPOWSectorY && - gbWorldSectorZ == 0 && 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 (gWorldSectorX == gModSettings.ubTixaPrisonSectorX && gWorldSectorY == gModSettings.ubTixaPrisonSectorY && - gbWorldSectorZ == 0 && gubQuest[QUEST_HELD_IN_TIXA] == QUESTCANNOTSTART) - { - gubQuest[QUEST_HELD_IN_TIXA] = QUESTNOTSTARTED; - } - #endif + HandlePOWQuestState(Q_FAIL, QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY, gbWorldSectorZ); + HandlePOWQuestState(Q_FAIL, QUEST_HELD_IN_ALMA, gWorldSectorX, gWorldSectorY, gbWorldSectorZ); + HandlePOWQuestState(Q_FAIL, QUEST_HELD_IN_TIXA, gWorldSectorX, gWorldSectorY, gbWorldSectorZ); + #endif // Play death music #ifdef NEWMUSIC @@ -7818,51 +7796,12 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) if (!is_networked) ShouldBeginAutoBandage( ); } - // SANDRO - end quest if cleared the sector after interrogation (sector N7 by Meduna) - if ( gWorldSectorX == gModSettings.ubMeanwhileInterrogatePOWSectorX && gWorldSectorY == gModSettings.ubMeanwhileInterrogatePOWSectorY && - gbWorldSectorZ == 0) - { - if (gubQuest[QUEST_INTERROGATION] == QUESTINPROGRESS) - { - // Complete quest - EndQuest( QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY ); - } - else if(gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED) - { - //shadooow: disable quest if player takes control of the N7 prison - gubQuest[QUEST_INTERROGATION] = QUESTCANNOTSTART; - } - } - //shadooow: disable quest if player takes control of the Alma prison - if (gWorldSectorX == gModSettings.ubInitialPOWSectorX && gWorldSectorY == gModSettings.ubInitialPOWSectorY && - gbWorldSectorZ == 0) - { - if (gubQuest[QUEST_HELD_IN_ALMA] == QUESTINPROGRESS) - { - // Complete quest - EndQuest(QUEST_HELD_IN_ALMA, gWorldSectorX, gWorldSectorY); - } - else if (gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED) - { - gubQuest[QUEST_HELD_IN_ALMA] = QUESTCANNOTSTART; - } - } - #ifndef JA2UB - //shadooow: disable quest if player takes control of the Tixa prison - if (gWorldSectorX == gModSettings.ubTixaPrisonSectorX && gWorldSectorY == gModSettings.ubTixaPrisonSectorY && - gbWorldSectorZ == 0 && gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED) - { - if (gubQuest[QUEST_HELD_IN_TIXA] == QUESTINPROGRESS) - { - // Complete quest - EndQuest(QUEST_HELD_IN_TIXA, gWorldSectorX, gWorldSectorY); - } - else if (gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED) - { - gubQuest[QUEST_HELD_IN_TIXA] = QUESTCANNOTSTART; - } - } - #endif + + #ifndef JA2UB + HandlePOWQuestState(Q_SUCCESS, QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY, gbWorldSectorZ); + HandlePOWQuestState(Q_SUCCESS, QUEST_HELD_IN_ALMA, gWorldSectorX, gWorldSectorY, gbWorldSectorZ); + HandlePOWQuestState(Q_SUCCESS, QUEST_HELD_IN_TIXA, gWorldSectorX, gWorldSectorY, gbWorldSectorZ); + #endif // Say battle end quote.... if (fAnEnemyRetreated) @@ -8587,16 +8526,14 @@ BOOLEAN CheckForLosingEndOfBattle( ) { //if( GetWorldDay() > STARTDAY_ALLOW_PLAYER_CAPTURE_FOR_RESCUE && !( gStrategicStatus.uiFlags & STRATEGIC_PLAYER_CAPTURED_FOR_RESCUE )) { - #ifdef JA2UB - if (gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED || (gubQuest[QUEST_HELD_IN_ALMA] != QUESTINPROGRESS && gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED)) - #else - if ( gubQuest[ QUEST_HELD_IN_ALMA ] == QUESTNOTSTARTED || gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED || (gubQuest[QUEST_HELD_IN_ALMA] != QUESTINPROGRESS && gubQuest[QUEST_HELD_IN_TIXA] != QUESTINPROGRESS && gubQuest[ QUEST_INTERROGATION ] == QUESTNOTSTARTED ) ) - #endif + #ifndef JA2UB + if ( gubQuest[ QUEST_HELD_IN_ALMA ] == QUESTNOTSTARTED || gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED || gubQuest[ QUEST_INTERROGATION ] == QUESTNOTSTARTED ) { fDoCapture = TRUE; // CJC Dec 1 2002: fix capture sequences BeginCaptureSquence(); } + #endif } } } @@ -8632,8 +8569,6 @@ BOOLEAN CheckForLosingEndOfBattle( ) if ( pTeamSoldier->stats.bLife != 0 && fDoCapture ) { EnemyCapturesPlayerSoldier( pTeamSoldier ); - - RemoveSoldierFromTacticalSector( pTeamSoldier, TRUE ); } } @@ -9677,7 +9612,7 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( ) pSoldier = NULL; - if (gTacticalStatus.ubCurrentTeam == gbPlayerNum) + if (gTacticalStatus.ubCurrentTeam == gbPlayerNum && gusSelectedSoldier < TOTAL_SOLDIERS) { pSoldier = MercPtrs[ gusSelectedSoldier ]; } @@ -9698,7 +9633,7 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( ) // If we still haven't figured out who last acted, it could be that the team number changed during the attack. Unfortunately this // can happen during a switch from real-time. For now we will assume the last actor was a PC, but a real "Who started this?" pointer // would work quite well. If only I could close all the holes that the UI opens so that one routine could handle everything. - if (!pSoldier) + if (!pSoldier && gusSelectedSoldier < TOTAL_SOLDIERS) { if (is_networked) { @@ -10298,7 +10233,10 @@ void DoneFadeOutDueToDeath( ) void EndBattleWithUnconsciousGuysCallback( UINT8 bExitValue ) { // Enter mapscreen..... - if(!is_client)CheckAndHandleUnloadingOfCurrentWorld(); + if (!is_client) + { + CheckAndHandleUnloadingOfCurrentWorld(); + } else { ScreenMsg( FONT_LTGREEN, MSG_CHAT, MPClientMessage[40] ); @@ -10442,6 +10380,12 @@ void DoPOWPathChecks( ) pSoldier->aiData.bNeutral = FALSE; AddCharacterToAnySquad( pSoldier ); pSoldier->DoMercBattleSound( BATTLE_SOUND_COOL1 ); + + // Decrement amount of prisoners + if (gStrategicStatus.ubNumCapturedForRescue > 0) + { + gStrategicStatus.ubNumCapturedForRescue--; + } } } } @@ -11092,6 +11036,107 @@ void HandleTurncoatAttempt( SOLDIERTYPE* pSoldier ) } } +void EscapeTimerCallback() +{ + const bool chanceToEscape = Chance(75); + bool escaped = false; + // Look for an escape direction for remaining mercs + std::array possibleEscapeDirections{ NORTH, EAST, SOUTH, WEST }; + std::random_device rd; + std::mt19937 g(rd()); + std::shuffle(possibleEscapeDirections.begin(), possibleEscapeDirections.end(), g); + + for (const auto direction : possibleEscapeDirections) + { + if (IsEscapeDirectionValid(direction) && chanceToEscape && gbWorldSectorZ == 0) // There is no escaping underground! For now.. + { + escaped = true; + ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_ESCAPE]); + + JumpIntoEscapedSector(direction); + break; + } + } + + if (!escaped) + { + ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_NO_ESCAPE]); + } +} + +void AttemptToCapturePlayerSoldiers() +{ +#ifdef JA2UB + ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_REFUSE_TAKE_PRISONERS]); +#else + // in order for this to work, there must be no militia present, the enemy must not already have offered asked you to surrender, and certain quests may not be active + if (!(gTacticalStatus.fEnemyFlags & ENEMY_OFFERED_SURRENDER) && gTacticalStatus.Team[MILITIA_TEAM].bMenInSector == 0) + { + gTacticalStatus.fEnemyFlags |= ENEMY_OFFERED_SURRENDER; + + if (gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED || gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED || gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED) + { + BeginCaptureSquence(); + const UINT8 currentPOWs = gStrategicStatus.ubNumCapturedForRescue; + // Do capture + UINT32 i = gTacticalStatus.Team[gbPlayerNum].bFirstID; + UINT32 const lastID = gTacticalStatus.Team[gbPlayerNum].bLastID; + for (SOLDIERTYPE* pSoldier = MercPtrs[i]; i <= lastID; ++i, ++pSoldier) + { + // Are we active and in sector + if (pSoldier->bActive && pSoldier->bInSector && pSoldier->bAssignment != ASSIGNMENT_POW) + { + if (pSoldier->stats.bLife != 0) + { + EnemyCapturesPlayerSoldier(pSoldier); + } + } + } + EndCaptureSequence(); + + if (currentPOWs < gStrategicStatus.ubNumCapturedForRescue) + { + gfSurrendered = TRUE; + } + else + { + ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_REFUSE_TAKE_PRISONERS]); + } + } + } + else + { + ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_REFUSE_TAKE_PRISONERS]); + } + + if (gfSurrendered == TRUE) + { + // If we have any remaining active mercs in sector after capture, give them a chance to escape from the clutches of Deidranna's soldiers! + bool activeMercs = false; + + UINT32 i = gTacticalStatus.Team[gbPlayerNum].bFirstID; + UINT32 lastId = gTacticalStatus.Team[gbPlayerNum].bLastID; + for (SOLDIERTYPE* pSoldier = MercPtrs[i]; i <= lastId; ++i, ++pSoldier) + { + // Are we active and in sector + const bool inSector = (pSoldier->sSectorX == gWorldSectorX && pSoldier->sSectorY == gWorldSectorY && pSoldier->bSectorZ == gbWorldSectorZ); + if (pSoldier->bActive && inSector && pSoldier->stats.bLife >= OKLIFE && pSoldier->bAssignment != ASSIGNMENT_POW) + { + activeMercs = true; + break; + } + } + + if (activeMercs) + { + SetCustomizableTimerCallbackAndDelay(500, EscapeTimerCallback, FALSE); + } + SetCustomizableTimerCallbackAndDelay(500, CaptureTimerCallback, FALSE); + CheckForEndOfBattle(FALSE); + } +#endif +} + void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue ) { SOLDIERTYPE *pSoldier = NULL; @@ -11256,49 +11301,7 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue ) return; } - // in order for this to work, there must be no militia present, the enemy must not already have offered asked you to surrender, and certain quests may not be active - if ( !( gTacticalStatus.fEnemyFlags & ENEMY_OFFERED_SURRENDER ) && gTacticalStatus.Team[ MILITIA_TEAM ].bMenInSector == 0 ) - { - #ifdef JA2UB - if (gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED || (gubQuest[QUEST_HELD_IN_ALMA] != QUESTINPROGRESS && gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED)) - #else - if (gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED || gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED || (gubQuest[QUEST_HELD_IN_ALMA] != QUESTINPROGRESS && gubQuest[QUEST_HELD_IN_TIXA] != QUESTINPROGRESS && gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED)) - #endif - { - gTacticalStatus.fEnemyFlags |= ENEMY_OFFERED_SURRENDER; - - // CJC Dec 1 2002: fix multiple captures - BeginCaptureSquence(); - - // Do capture.... - uiCnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; - for ( pSoldier = MercPtrs[ uiCnt ]; uiCnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ++uiCnt, ++pSoldier) - { - // Are we active and in sector..... - if ( pSoldier->bActive && pSoldier->bInSector ) - { - if ( pSoldier->stats.bLife != 0 ) - { - EnemyCapturesPlayerSoldier( pSoldier ); - - RemoveSoldierFromTacticalSector( pSoldier, TRUE ); - } - } - } - - EndCaptureSequence( ); - - gfSurrendered = TRUE; - SetCustomizableTimerCallbackAndDelay( 3000, CaptureTimerCallback, FALSE ); - - success = TRUE; - } - } - - if ( !success ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[ STR_PRISONER_REFUSE_TAKE_PRISONERS ] ); - } + SetCustomizableTimerCallbackAndDelay(500, AttemptToCapturePlayerSoldiers, FALSE); } // we distract the enemy by essentially talking them to death else if ( ubExitValue == 3 ) diff --git a/Tactical/Overhead.h b/Tactical/Overhead.h index 47d936539..53a0acde2 100644 --- a/Tactical/Overhead.h +++ b/Tactical/Overhead.h @@ -433,6 +433,6 @@ void VIPFleesToMeduna(); BOOLEAN IsCivFactionMemberAliveInSector( UINT8 usCivilianGroup ); BOOLEAN IsFreeSlotAvailable( int aTeam ); - +void AttemptToCapturePlayerSoldiers(); #endif diff --git a/Tactical/Turn Based Input.cpp b/Tactical/Turn Based Input.cpp index 38fd00762..e8d6efc92 100644 --- a/Tactical/Turn Based Input.cpp +++ b/Tactical/Turn Based Input.cpp @@ -255,7 +255,6 @@ void CreatePlayerControlledMonster(); void ChangeCurrentSquad( INT32 iSquad ); void HandleSelectMercSlot( UINT8 ubPanelSlot, INT8 bCode ); void EscapeUILock( ); -void TestCapture( ); #ifdef JA2BETAVERSION void ToggleMapEdgepoints(); @@ -4476,9 +4475,8 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) { if ( CHEATER_CHEAT_LEVEL( ) ) { - TestCapture( ); - - //EnterCombatMode( gbPlayerNum ); + // Test Capturing Mercs as POW + AttemptToCapturePlayerSoldiers(); } } else if ( fCtrl && fShift ) @@ -6536,42 +6534,6 @@ void HandleStealthChangeFromUIKeys( ) } } - - -void TestCapture( ) -{ - INT32 cnt; - SOLDIERTYPE *pSoldier; - UINT32 uiNumChosen = 0; - - //StartQuest( QUEST_HELD_IN_ALMA, gWorldSectorX, gWorldSectorY ); - //EndQuest( QUEST_HELD_IN_ALMA, gWorldSectorX, gWorldSectorY ); - - BeginCaptureSquence( ); - - gStrategicStatus.uiFlags &= (~STRATEGIC_PLAYER_CAPTURED_FOR_RESCUE ); - - // loop through soldiers and pick 3 lucky ones.... - for ( cnt = gTacticalStatus.Team[gbPlayerNum].bFirstID, pSoldier=MercPtrs[cnt]; cnt <= gTacticalStatus.Team[gbPlayerNum].bLastID; cnt++, pSoldier++ ) - { - if ( pSoldier->stats.bLife >= OKLIFE && pSoldier->bActive && pSoldier->bInSector ) - { - if ( uiNumChosen < 3 ) - { - EnemyCapturesPlayerSoldier( pSoldier ); - - // Remove them from tectical.... - pSoldier->RemoveSoldierFromGridNo( ); - - uiNumChosen++; - } - } - } - - EndCaptureSequence( ); -} - - void PopupAssignmentMenuInTactical( SOLDIERTYPE *pSoldier ) { // do something diff --git a/TacticalAI/DecideAction.cpp b/TacticalAI/DecideAction.cpp index 3415fc4d8..e426c3732 100644 --- a/TacticalAI/DecideAction.cpp +++ b/TacticalAI/DecideAction.cpp @@ -5161,19 +5161,14 @@ INT16 ubMinAPCost; } // offer surrender? -#ifdef JA2UB -#else +#ifndef JA2UB if ( pSoldier->bTeam == ENEMY_TEAM && pSoldier->bVisible == TRUE && !(gTacticalStatus.fEnemyFlags & ENEMY_OFFERED_SURRENDER) && pSoldier->stats.bLife >= pSoldier->stats.bLifeMax / 2 && !ARMED_VEHICLE( pSoldier ) && !ENEMYROBOT( pSoldier ) ) { if ( gTacticalStatus.Team[ MILITIA_TEAM ].bMenInSector == 0 && gTacticalStatus.Team[ CREATURE_TEAM ].bMenInSector == 0 && NumPCsInSector() < 4 && gTacticalStatus.Team[ ENEMY_TEAM ].bMenInSector >= NumPCsInSector() * 3 ) { - //if( GetWorldDay() > STARTDAY_ALLOW_PLAYER_CAPTURE_FOR_RESCUE && !( gStrategicStatus.uiFlags & STRATEGIC_PLAYER_CAPTURED_FOR_RESCUE ) ) + if (gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED || gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED || gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED) { - if (gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED || gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED || (gubQuest[QUEST_HELD_IN_ALMA] != QUESTINPROGRESS && gubQuest[QUEST_HELD_IN_TIXA] != QUESTINPROGRESS && gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED)) - { - gTacticalStatus.fEnemyFlags |= ENEMY_OFFERED_SURRENDER; - return( AI_ACTION_OFFER_SURRENDER ); - } + return( AI_ACTION_OFFER_SURRENDER ); } } } @@ -9586,15 +9581,13 @@ INT8 ArmedVehicleDecideActionBlack( SOLDIERTYPE *pSoldier ) } // offer surrender? -#ifdef JA2UB -#else +#ifndef JA2UB if ( pSoldier->bTeam == ENEMY_TEAM && pSoldier->bVisible == TRUE && !(gTacticalStatus.fEnemyFlags & ENEMY_OFFERED_SURRENDER) && pSoldier->stats.bLife >= pSoldier->stats.bLifeMax / 2 && !ARMED_VEHICLE( pSoldier ) && !ENEMYROBOT( pSoldier ) ) { if ( gTacticalStatus.Team[MILITIA_TEAM].bMenInSector == 0 && gTacticalStatus.Team[CREATURE_TEAM].bMenInSector == 0 && NumPCsInSector( ) < 4 && gTacticalStatus.Team[ENEMY_TEAM].bMenInSector >= NumPCsInSector( ) * 3 ) { - if ( gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED || (gubQuest[QUEST_HELD_IN_ALMA] == QUESTDONE && gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED) ) + if (gubQuest[QUEST_HELD_IN_ALMA] == QUESTNOTSTARTED || gubQuest[QUEST_HELD_IN_TIXA] == QUESTNOTSTARTED || gubQuest[QUEST_INTERROGATION] == QUESTNOTSTARTED) { - gTacticalStatus.fEnemyFlags |= ENEMY_OFFERED_SURRENDER; return(AI_ACTION_OFFER_SURRENDER); } } @@ -10413,4 +10406,4 @@ void LogKnowledgeInfo(SOLDIERTYPE *pSoldier) //swprintf( pStrInfo, L"%s[%d] %s %s\n", pStrInfo, oppID, MercPtrs[oppID]->GetName(), SeenStr(pSoldier->aiData.bOppList[oppID]) ); } } -} \ No newline at end of file +} diff --git a/Utils/Text.h b/Utils/Text.h index 2ed7ca035..25dabaeb1 100644 --- a/Utils/Text.h +++ b/Utils/Text.h @@ -886,6 +886,8 @@ enum STR_PRISONER_DETECTION_VIP, STR_PRISONER_REFUSE_SURRENDER_LEADER, STR_PRISONER_TURN_VOLUNTEER, + STR_PRISONER_ESCAPE, + STR_PRISONER_NO_ESCAPE, TEXT_NUM_PRISONER_STR }; diff --git a/Utils/_ChineseText.cpp b/Utils/_ChineseText.cpp index 11abdae26..8acb8ddcf 100644 --- a/Utils/_ChineseText.cpp +++ b/Utils/_ChineseText.cpp @@ -9194,6 +9194,8 @@ STR16 szPrisonerTextStr[]= L"一个高阶军官%s被发现!", //L"A high-ranking army officer in %s has been revealed!", L"敌方领袖拒绝考虑投降!", //L"The enemy leader refuses to even consider surrender!", L"%d名囚犯自愿加入我军。", //L"%d prisoners volunteered to join our forces.", + L"Some of your mercs managed to escape the enemy capture!", + L"No possible escape is seen, it's a fight to the death!" }; STR16 szMTATextStr[]= diff --git a/Utils/_DutchText.cpp b/Utils/_DutchText.cpp index 93688f68d..5d4f830f3 100644 --- a/Utils/_DutchText.cpp +++ b/Utils/_DutchText.cpp @@ -9205,6 +9205,8 @@ STR16 szPrisonerTextStr[]= L"A high-ranking army officer in %s has been revealed!", // TODO.Translate L"The enemy leader refuses to even consider surrender!", L"%d prisoners volunteered to join our forces.", + L"Some of your mercs managed to escape the enemy capture!", + L"No possible escape is seen, it's a fight to the death!" }; STR16 szMTATextStr[]= // TODO.Translate diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp index 4ea9f73e6..99343e753 100644 --- a/Utils/_EnglishText.cpp +++ b/Utils/_EnglishText.cpp @@ -9194,6 +9194,8 @@ STR16 szPrisonerTextStr[]= L"A high-ranking army officer in %s has been revealed!", L"The enemy leader refuses to even consider surrender!", L"%d prisoners volunteered to join our forces.", + L"Some of your mercs managed to escape the enemy capture!", + L"No possible escape is seen, it's a fight to the death!" }; STR16 szMTATextStr[]= diff --git a/Utils/_FrenchText.cpp b/Utils/_FrenchText.cpp index 6f22f3a8d..bf1a48c74 100644 --- a/Utils/_FrenchText.cpp +++ b/Utils/_FrenchText.cpp @@ -9187,6 +9187,8 @@ STR16 szPrisonerTextStr[]= L"A high-ranking army officer in %s has been revealed!", // TODO.Translate L"The enemy leader refuses to even consider surrender!", L"%d prisoners volunteered to join our forces.", + L"Some of your mercs managed to escape the enemy capture!", + L"No possible escape is seen, it's a fight to the death!" }; STR16 szMTATextStr[]= diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp index b7d4b8df8..5e3bef9bc 100644 --- a/Utils/_GermanText.cpp +++ b/Utils/_GermanText.cpp @@ -9047,6 +9047,8 @@ STR16 szPrisonerTextStr[]= L"Ein ranghoher Offizier in %s wurde enttarnt!", L"Der feindliche Anführer denkt nicht mal an Kapitulation!", L"%d Gefangene sind uns als Freiwillige beigetreten.", + L"Some of your mercs managed to escape the enemy capture!", + L"No possible escape is seen, it's a fight to the death!" }; STR16 szMTATextStr[]= diff --git a/Utils/_ItalianText.cpp b/Utils/_ItalianText.cpp index dbe3f784d..6edfa7bb2 100644 --- a/Utils/_ItalianText.cpp +++ b/Utils/_ItalianText.cpp @@ -9195,6 +9195,8 @@ STR16 szPrisonerTextStr[]= L"A high-ranking army officer in %s has been revealed!", // TODO.Translate L"The enemy leader refuses to even consider surrender!", L"%d prisoners volunteered to join our forces.", + L"Some of your mercs managed to escape the enemy capture!", + L"No possible escape is seen, it's a fight to the death!" }; STR16 szMTATextStr[]= // TODO.Translate diff --git a/Utils/_PolishText.cpp b/Utils/_PolishText.cpp index 8fec10a92..cfbeb4659 100644 --- a/Utils/_PolishText.cpp +++ b/Utils/_PolishText.cpp @@ -9209,6 +9209,8 @@ STR16 szPrisonerTextStr[]= L"A high-ranking army officer in %s has been revealed!", // TODO.Translate L"The enemy leader refuses to even consider surrender!", L"%d prisoners volunteered to join our forces.", + L"Some of your mercs managed to escape the enemy capture!", + L"No possible escape is seen, it's a fight to the death!" }; STR16 szMTATextStr[]= // TODO.Translate diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index e620eb527..6afd1ec3c 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -9189,6 +9189,8 @@ STR16 szPrisonerTextStr[]= L"В %s был раскрыт высокопоставленный офицер!", L"Вражеский командир отказывается даже подумать о сдаче!", L"%d заключенных добровольно присоединились к нашим силам.", + L"Some of your mercs managed to escape the enemy capture!", + L"No possible escape is seen, it's a fight to the death!" }; STR16 szMTATextStr[]=