Merge branch 'master' into ExtraMercs

This commit is contained in:
Asdow
2023-07-26 13:17:49 +03:00
754 changed files with 9435 additions and 74371 deletions
+129 -216
View File
@@ -1,11 +1,7 @@
#ifdef PRECOMPILEDHEADERS
#include "Tactical All.h"
#include "PreBattle Interface.h"
#include "creature spreading.h"
#include "Lua Interpreter.h"
#else
#include <stdio.h>
#include <string.h>
#include <random>
#include <array>
#include "wcheck.h"
#include "stdlib.h"
#include "debug.h"
@@ -118,7 +114,6 @@
#include "MilitiaIndividual.h" // added by Flugente
#include "Rebel Command.h"
#include "MilitiaSquads.h"
#endif
#include "connect.h"
#include "Luaglobal.h"
@@ -1185,12 +1180,6 @@ BOOLEAN ExecuteOverhead( )
pSoldier->flags.fSoldierWasMoving = FALSE;
HandlePlacingRoofMarker( pSoldier, pSoldier->sGridNo, TRUE, FALSE );
if ( !gGameSettings.fOptions[ TOPTION_MERC_ALWAYS_LIGHT_UP ] )
{
pSoldier->DeleteSoldierLight( );
pSoldier->SetCheckSoldierLightFlag( );
}
}
}
else
@@ -7603,35 +7592,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
@@ -7827,51 +7792,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)
@@ -8599,16 +8525,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
}
}
}
@@ -8644,8 +8568,6 @@ BOOLEAN CheckForLosingEndOfBattle( )
if ( pTeamSoldier->stats.bLife != 0 && fDoCapture )
{
EnemyCapturesPlayerSoldier( pTeamSoldier );
RemoveSoldierFromTacticalSector( pTeamSoldier, TRUE );
}
}
@@ -9308,11 +9230,6 @@ void HandleSuppressionFire( UINT16 ubTargetedMerc, UINT16 ubCausedAttacker )
{
DebugAI(AI_MSG_INFO, pSoldier, String("CancelAIAction: suppression: change stance/cower"));
CancelAIAction( pSoldier, TRUE );
#if 0
pSoldier->aiData.bAction = AI_ACTION_CHANGE_STANCE;
pSoldier->aiData.usActionData = ubNewStance;
pSoldier->aiData.bActionInProgress = TRUE;
#endif
}
// go for it!
@@ -9654,38 +9571,6 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( )
UINT32 cnt;
UINT16 ubID;
#if 0
// 0verhaul: None of this is necessary anymore with the new attack busy system
if (ubID == NOBODY)
{
pSoldier = NULL;
pTarget = NULL;
}
else
{
pSoldier = MercPtrs[ ubID ];
if ( ubTargetID != NOBODY)
{
pTarget = MercPtrs[ ubTargetID ];
}
else
{
pTarget = NULL;
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String(">>Target ptr is null!" ) );
}
}
if (fCalledByAttacker)
{
if (pSoldier && Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_GUN)
{
if (pSoldier->bBulletsLeft > 0)
{
return( pTarget );
}
}
}
#endif
// if ((gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT))
// {
@@ -9726,7 +9611,7 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( )
pSoldier = NULL;
if (gTacticalStatus.ubCurrentTeam == gbPlayerNum)
if (gTacticalStatus.ubCurrentTeam == gbPlayerNum && gusSelectedSoldier < TOTAL_SOLDIERS)
{
pSoldier = MercPtrs[ gusSelectedSoldier ];
}
@@ -9747,7 +9632,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)
{
@@ -9810,15 +9695,6 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( )
return( NULL );
}
#endif
#if 0
// 0verhaul: This is moved to the end loop where everybody's state is reset for the next action
if (pTarget)
{
// reset # of shotgun pellets hit by
pTarget->bNumPelletsHitBy = 0;
// reset flag for making "ow" sound on being shot
}
#endif
if (pSoldier)
{
@@ -10111,17 +9987,6 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( )
SOLDIERTYPE * ReduceAttackBusyCount( )
{
#if 0
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("ReduceAttackBusyCount") );
if ( ubID == NOBODY )
{
return( InternalReduceAttackBusyCount( ubID, fCalledByAttacker, NOBODY ) );
}
else
{
return( InternalReduceAttackBusyCount( ubID, fCalledByAttacker, MercPtrs[ ubID ]->ubTargetID ) );
}
#endif
// 0verhaul: This is now a simple subroutine.
return InternalReduceAttackBusyCount( );
}
@@ -10138,26 +10003,6 @@ SOLDIERTYPE * FreeUpAttacker( )
return( ReduceAttackBusyCount( ) );
}
#if 0
// 0verhaul: These routines are declared obsolete. Call ReduceAttackBusyCount instead.
SOLDIERTYPE * FreeUpAttackerGivenTarget( UINT8 ubID, UINT8 ubTargetID )
{
// Strange as this may seem, this function returns a pointer to
// the *target* in case the target has changed sides as a result
// of being attacked
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("FreeUpAttackerGivenTarget") );
return( InternalReduceAttackBusyCount( ubID, TRUE, ubTargetID ) );
}
SOLDIERTYPE * ReduceAttackBusyGivenTarget( UINT8 ubID, UINT8 ubTargetID )
{
// Strange as this may seem, this function returns a pointer to
// the *target* in case the target has changed sides as a result
// of being attacked
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("ReduceAttackBusyGivenTarget") );
return( InternalReduceAttackBusyCount( ubID, FALSE, ubTargetID ) );
}
#endif
void StopMercAnimation( BOOLEAN fStop )
@@ -10387,7 +10232,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] );
@@ -10531,6 +10379,12 @@ void DoPOWPathChecks( )
pSoldier->aiData.bNeutral = FALSE;
AddCharacterToAnySquad( pSoldier );
pSoldier->DoMercBattleSound( BATTLE_SOUND_COOL1 );
// Decrement amount of prisoners
if (gStrategicStatus.ubNumCapturedForRescue > 0)
{
gStrategicStatus.ubNumCapturedForRescue--;
}
}
}
}
@@ -11181,6 +11035,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<WorldDirections, 4> 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;
@@ -11345,49 +11300,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 )