Files
source/Strategic/Quests.cpp
T

1391 lines
38 KiB
C++

#ifdef PRECOMPILEDHEADERS
#include "Strategic All.h"
#include "GameSettings.h"
#else
#include "sgp.h"
#include "message.h"
#include "quests.h"
#include "game clock.h"
#include "StrategicMap.h"
#include "soldier profile.h"
#include "LaptopSave.h"
#include "Handle Items.h"
#include "overhead.h"
#include "Interface Dialogue.h"
#include "Soldier Profile.h"
#include "Isometric Utils.h"
#include "Render Fun.h"
#include "History.h"
#include "Map Screen Helicopter.h"
#include "Overhead.h"
#include "Strategic Mines.h"
#include "Boxing.h"
#include "Campaign Types.h"
#include "Strategic Town Loyalty.h"
#include "Queen Command.h"
#include "Campaign.h"
#include "GameSettings.h"
#include "Arms Dealer Init.h"
#include "GameSettings.h"
#endif
#include "BobbyRMailOrder.h"
#define TESTQUESTS
extern SOLDIERTYPE * gpSrcSoldier;
extern SOLDIERTYPE * gpDestSoldier;
UINT8 gubQuest[MAX_QUESTS];
UINT8 gubFact[ NUM_FACTS ]; // this has to be updated when we figure out how many facts we have
INT16 gsFoodQuestSectorX;
INT16 gsFoodQuestSectorY;
extern void GuaranteeAtLeastXItemsOfIndex( UINT8 ubArmsDealer, UINT16 usItemIndex, UINT8 ubHowMany );
void SetFactTrue( UINT16 usFact )
{
// This function is here just for control flow purposes (debug breakpoints)
// and code is more readable that way
// must intercept when Jake is first trigered to start selling fuel
if ( ( usFact == FACT_ESTONI_REFUELLING_POSSIBLE ) && ( CheckFact( usFact, 0 ) == FALSE ) )
{
// give him some gas...
GuaranteeAtLeastXItemsOfIndex( ARMS_DEALER_JAKE, GAS_CAN, ( UINT8 ) ( 4 + Random( 3 ) ) );
}
gubFact[usFact] = TRUE;
}
void SetFactFalse( UINT16 usFact )
{
gubFact[usFact] = FALSE;
}
BOOLEAN CheckForNewShipment( void )
{
ITEM_POOL * pItemPool;
if ( ( gWorldSectorX == BOBBYR_SHIPPING_DEST_SECTOR_X ) && ( gWorldSectorY == BOBBYR_SHIPPING_DEST_SECTOR_Y ) && ( gbWorldSectorZ == BOBBYR_SHIPPING_DEST_SECTOR_Z ) )
{
if ( GetItemPool( BOBBYR_SHIPPING_DEST_GRIDNO, &pItemPool, 0 ) )
{
return( !( ITEMPOOL_VISIBLE( pItemPool ) ) );
}
}
return( FALSE );
}
BOOLEAN CheckNPCWounded( UINT8 ubProfileID, BOOLEAN fByPlayerOnly )
{
SOLDIERTYPE * pSoldier;
// is the NPC is wounded at all?
pSoldier = FindSoldierByProfileID( ubProfileID, FALSE );
if (pSoldier && pSoldier->bLife < pSoldier->bLifeMax)
{
if (fByPlayerOnly)
{
if (gMercProfiles[ubProfileID].ubMiscFlags & PROFILE_MISC_FLAG_WOUNDEDBYPLAYER)
{
return( TRUE );
}
else
{
return( FALSE );
}
}
else
{
return( TRUE );
}
}
else
{
return( FALSE );
}
}
BOOLEAN CheckNPCInOkayHealth( UINT8 ubProfileID )
{
SOLDIERTYPE * pSoldier;
// is the NPC at better than half health?
pSoldier = FindSoldierByProfileID( ubProfileID, FALSE );
if (pSoldier && pSoldier->bLife > (pSoldier->bLifeMax / 2) && pSoldier->bLife > 30)
{
return( TRUE );
}
else
{
return( FALSE );
}
}
BOOLEAN CheckNPCBleeding( UINT8 ubProfileID )
{
SOLDIERTYPE * pSoldier;
// the NPC is wounded...
pSoldier = FindSoldierByProfileID( ubProfileID, FALSE );
if (pSoldier && pSoldier->bLife > 0 && pSoldier->bBleeding > 0)
{
return( TRUE );
}
else
{
return( FALSE );
}
}
BOOLEAN CheckNPCWithin( UINT8 ubFirstNPC, UINT8 ubSecondNPC, UINT8 ubMaxDistance )
{
SOLDIERTYPE * pFirstNPC, * pSecondNPC;
pFirstNPC = FindSoldierByProfileID( ubFirstNPC, FALSE );
pSecondNPC = FindSoldierByProfileID( ubSecondNPC, FALSE );
if (!pFirstNPC || !pSecondNPC)
{
return( FALSE );
}
return( PythSpacesAway( pFirstNPC->sGridNo, pSecondNPC->sGridNo ) <= ubMaxDistance );
}
BOOLEAN CheckGuyVisible( UINT8 ubNPC, UINT8 ubGuy )
{
// NB ONLY WORKS IF ON DIFFERENT TEAMS
SOLDIERTYPE * pNPC, * pGuy;
pNPC = FindSoldierByProfileID( ubNPC, FALSE );
pGuy = FindSoldierByProfileID( ubGuy, FALSE );
if (!pNPC || !pGuy)
{
return( FALSE );
}
if (pNPC->bOppList[ pGuy->ubID ] == SEEN_CURRENTLY )
{
return( TRUE );
}
else
{
return( FALSE );
}
}
BOOLEAN CheckNPCAt( UINT8 ubNPC, INT16 sGridNo )
{
SOLDIERTYPE * pNPC;
pNPC = FindSoldierByProfileID( ubNPC, FALSE );
if (!pNPC)
{
return( FALSE );
}
return( pNPC->sGridNo == sGridNo );
}
BOOLEAN CheckNPCIsEnemy( UINT8 ubProfileID )
{
SOLDIERTYPE * pNPC;
pNPC = FindSoldierByProfileID( ubProfileID, FALSE );
if (!pNPC)
{
return( FALSE );
}
if (pNPC->bSide == gbPlayerNum || pNPC->bNeutral)
{
if (pNPC->ubCivilianGroup != NON_CIV_GROUP)
{
// although the soldier is NOW the same side, this civ group could be set to "will become hostile"
return( gTacticalStatus.fCivGroupHostile[ pNPC->ubCivilianGroup ] >= CIV_GROUP_WILL_BECOME_HOSTILE );
}
else
{
return( FALSE );
}
}
else
{
return( TRUE );
}
}
BOOLEAN CheckIfMercIsNearNPC( SOLDIERTYPE *pMerc, UINT8 ubProfileId )
{
SOLDIERTYPE * pNPC;
INT16 sGridNo;
// no merc nearby?
if ( pMerc == NULL )
{
return( FALSE );
}
pNPC = FindSoldierByProfileID( ubProfileId, FALSE );
if ( pNPC == NULL )
{
return( FALSE );
}
sGridNo = pNPC->sGridNo;
// is the merc and NPC close enough?
if (PythSpacesAway( sGridNo, pMerc->sGridNo ) <= 9)
{
return( TRUE );
}
return( FALSE );
}
INT8 NumWoundedMercsNearby( UINT8 ubProfileID )
{
INT8 bNumber = 0;
UINT32 uiLoop;
SOLDIERTYPE * pNPC;
SOLDIERTYPE * pSoldier;
INT16 sGridNo;
pNPC = FindSoldierByProfileID( ubProfileID, FALSE );
if (!pNPC)
{
return( FALSE );
}
sGridNo = pNPC->sGridNo;
for ( uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++)
{
pSoldier = MercSlots[ uiLoop ];
if ( pSoldier && pSoldier->bTeam == gbPlayerNum && pSoldier->bLife > 0 && pSoldier->bLife < pSoldier->bLifeMax && pSoldier->bAssignment != ASSIGNMENT_HOSPITAL )
{
if (PythSpacesAway( sGridNo, pSoldier->sGridNo ) <= HOSPITAL_PATIENT_DISTANCE)
{
bNumber++;
}
}
}
return( bNumber );
}
INT8 NumMercsNear( UINT8 ubProfileID, UINT8 ubMaxDist )
{
INT8 bNumber = 0;
UINT32 uiLoop;
SOLDIERTYPE * pNPC;
SOLDIERTYPE * pSoldier;
INT16 sGridNo;
pNPC = FindSoldierByProfileID( ubProfileID, FALSE );
if (!pNPC)
{
return( FALSE );
}
sGridNo = pNPC->sGridNo;
for ( uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++)
{
pSoldier = MercSlots[ uiLoop ];
if ( pSoldier && pSoldier->bTeam == gbPlayerNum && pSoldier->bLife >= OKLIFE )
{
if (PythSpacesAway( sGridNo, pSoldier->sGridNo ) <= ubMaxDist)
{
bNumber++;
}
}
}
return( bNumber );
}
BOOLEAN CheckNPCIsEPC( UINT8 ubProfileID )
{
SOLDIERTYPE * pNPC;
if ( gMercProfiles[ ubProfileID ].bMercStatus == MERC_IS_DEAD )
{
return( FALSE );
}
pNPC = FindSoldierByProfileID( ubProfileID, TRUE );
if (!pNPC)
{
return( FALSE );
}
return( (pNPC->ubWhatKindOfMercAmI == MERC_TYPE__EPC ) );
}
BOOLEAN NPCInRoom( UINT8 ubProfileID, UINT8 ubRoomID )
{
SOLDIERTYPE * pNPC;
pNPC = FindSoldierByProfileID( ubProfileID, FALSE );
if ( !pNPC || (gubWorldRoomInfo[ pNPC->sGridNo ] != ubRoomID) )
{
return( FALSE );
}
return( TRUE );
}
BOOLEAN NPCInRoomRange( UINT8 ubProfileID, UINT8 ubRoomID1, UINT8 ubRoomID2 )
{
SOLDIERTYPE * pNPC;
pNPC = FindSoldierByProfileID( ubProfileID, FALSE );
if ( !pNPC || (gubWorldRoomInfo[ pNPC->sGridNo ] < ubRoomID1) || (gubWorldRoomInfo[ pNPC->sGridNo ] > ubRoomID2) )
{
return( FALSE );
}
return( TRUE );
}
BOOLEAN PCInSameRoom( UINT8 ubProfileID )
{
SOLDIERTYPE * pNPC;
UINT8 ubRoom;
INT8 bLoop;
SOLDIERTYPE * pSoldier;
pNPC = FindSoldierByProfileID( ubProfileID, FALSE );
if ( !pNPC )
{
return( FALSE );
}
ubRoom = gubWorldRoomInfo[ pNPC->sGridNo ];
for ( bLoop = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; bLoop <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; bLoop++ )
{
pSoldier = MercPtrs[ bLoop ];
if ( pSoldier && pSoldier->bActive && pSoldier->bInSector )
{
if ( gubWorldRoomInfo[ pSoldier->sGridNo ] == ubRoom )
{
return( TRUE );
}
}
}
return( FALSE );
}
BOOLEAN CheckTalkerStrong( void )
{
if (gpSrcSoldier && gpSrcSoldier->bTeam == gbPlayerNum)
{
return( gpSrcSoldier->bStrength >= 84 );
}
else if (gpDestSoldier && gpDestSoldier->bTeam == gbPlayerNum)
{
return( gpDestSoldier->bStrength >= 84 );
}
return( FALSE );
}
BOOLEAN CheckTalkerFemale( void )
{
if (gpSrcSoldier && gpSrcSoldier->bTeam == gbPlayerNum && gpSrcSoldier->ubProfile != NO_PROFILE)
{
return( gMercProfiles[ gpSrcSoldier->ubProfile ].bSex == FEMALE );
}
else if (gpDestSoldier && gpDestSoldier->bTeam == gbPlayerNum && gpDestSoldier->ubProfile != NO_PROFILE)
{
return( gMercProfiles[ gpDestSoldier->ubProfile ].bSex == FEMALE );
}
return( FALSE );
}
BOOLEAN CheckTalkerUnpropositionedFemale( void )
{
if (gpSrcSoldier && gpSrcSoldier->bTeam == gbPlayerNum && gpSrcSoldier->ubProfile != NO_PROFILE)
{
if ( !(gMercProfiles[ gpSrcSoldier->ubProfile ].ubMiscFlags2 & PROFILE_MISC_FLAG2_ASKED_BY_HICKS) )
{
return( gMercProfiles[ gpSrcSoldier->ubProfile ].bSex == FEMALE );
}
}
else if (gpDestSoldier && gpDestSoldier->bTeam == gbPlayerNum && gpDestSoldier->ubProfile != NO_PROFILE)
{
if ( !(gMercProfiles[ gpDestSoldier->ubProfile ].ubMiscFlags2 & PROFILE_MISC_FLAG2_ASKED_BY_HICKS) )
{
return( gMercProfiles[ gpDestSoldier->ubProfile ].bSex == FEMALE );
}
}
return( FALSE );
}
INT8 NumMalesPresent( UINT8 ubProfileID )
{
INT8 bNumber = 0;
UINT32 uiLoop;
SOLDIERTYPE * pNPC;
SOLDIERTYPE * pSoldier;
INT16 sGridNo;
pNPC = FindSoldierByProfileID( ubProfileID, FALSE );
if (!pNPC)
{
return( FALSE );
}
sGridNo = pNPC->sGridNo;
for ( uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++)
{
pSoldier = MercSlots[ uiLoop ];
if ( pSoldier && pSoldier->bTeam == gbPlayerNum && pSoldier->bLife >= OKLIFE)
{
if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile].bSex == MALE )
{
if (PythSpacesAway( sGridNo, pSoldier->sGridNo ) <= 8)
{
bNumber++;
}
}
}
}
return( bNumber );
}
BOOLEAN FemalePresent( UINT8 ubProfileID )
{
UINT32 uiLoop;
SOLDIERTYPE * pNPC;
SOLDIERTYPE * pSoldier;
INT16 sGridNo;
pNPC = FindSoldierByProfileID( ubProfileID, FALSE );
if (!pNPC)
{
return( FALSE );
}
sGridNo = pNPC->sGridNo;
for ( uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++)
{
pSoldier = MercSlots[ uiLoop ];
if ( pSoldier && pSoldier->bTeam == gbPlayerNum && pSoldier->bLife >= OKLIFE)
{
if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile].bSex == FEMALE )
{
if (PythSpacesAway( sGridNo, pSoldier->sGridNo ) <= 10)
{
return( TRUE );
}
}
}
}
return( FALSE );
}
BOOLEAN CheckPlayerHasHead( void )
{
INT8 bLoop;
SOLDIERTYPE * pSoldier;
for ( bLoop = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; bLoop <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; bLoop++ )
{
pSoldier = MercPtrs[ bLoop ];
if ( pSoldier->bActive && pSoldier->bLife > 0 )
{
if ( FindObjInObjRange( pSoldier, HEAD_2, HEAD_7 ) != NO_SLOT )
{
return( TRUE );
}
}
}
return( FALSE );
}
BOOLEAN CheckNPCSector( UINT8 ubProfileID, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
{
SOLDIERTYPE * pSoldier;
pSoldier = FindSoldierByProfileID( ubProfileID, TRUE );
if( pSoldier )
{
if (pSoldier->sSectorX == sSectorX &&
pSoldier->sSectorY == sSectorY &&
pSoldier->bSectorZ == bSectorZ )
{
return( TRUE );
}
}
else if (gMercProfiles[ubProfileID].sSectorX == sSectorX &&
gMercProfiles[ubProfileID].sSectorY == sSectorY &&
gMercProfiles[ubProfileID].bSectorZ == bSectorZ )
{
return( TRUE );
}
return( FALSE );
}
BOOLEAN AIMMercWithin( INT16 sGridNo, INT16 sDistance )
{
UINT32 uiLoop;
SOLDIERTYPE * pSoldier;
for ( uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++)
{
pSoldier = MercSlots[ uiLoop ];
if ( pSoldier && (pSoldier->bTeam == gbPlayerNum) && (pSoldier->bLife >= OKLIFE) && ( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC ) )
{
if (PythSpacesAway( sGridNo, pSoldier->sGridNo ) <= sDistance)
{
return( TRUE );
}
}
}
return( FALSE );
}
BOOLEAN CheckNPCCowering( UINT8 ubProfileID )
{
SOLDIERTYPE * pNPC;
pNPC = FindSoldierByProfileID( ubProfileID, FALSE );
if ( !pNPC )
{
return( FALSE );
}
return( ( (pNPC->uiStatusFlags & SOLDIER_COWERING) != 0) );
}
UINT8 CountBartenders( void )
{
UINT8 ubLoop;
UINT8 ubBartenders = 0;
for( ubLoop = HERVE; ubLoop <= CARLO; ubLoop++ )
{
if (gMercProfiles[ ubLoop ].bNPCData != 0 )
{
ubBartenders++;
}
}
return( ubBartenders );
}
BOOLEAN CheckNPCIsUnderFire( UINT8 ubProfileID )
{
SOLDIERTYPE * pNPC;
pNPC = FindSoldierByProfileID( ubProfileID, FALSE );
if ( !pNPC )
{
return( FALSE );
}
return( pNPC->bUnderFire != 0 );
}
BOOLEAN NPCHeardShot( UINT8 ubProfileID )
{
SOLDIERTYPE * pNPC;
pNPC = FindSoldierByProfileID( ubProfileID, FALSE );
if ( !pNPC )
{
return( FALSE );
}
return( pNPC->ubMiscSoldierFlags & SOLDIER_MISC_HEARD_GUNSHOT );
}
BOOLEAN InTownSectorWithTrainingLoyalty( INT16 sSectorX, INT16 sSectorY )
{
UINT8 ubTown;
INT32 iMinLoyaltyToTrain = gGameExternalOptions.iMinLoyaltyToTrain;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Quests");
ubTown = GetTownIdForSector( sSectorX, sSectorY );
if ( ( ubTown != BLANK_SECTOR ) && gTownLoyalty[ ubTown ].fStarted && gfTownUsesLoyalty[ ubTown ])
{
return( gTownLoyalty[ ubTown ].ubRating >= iMinLoyaltyToTrain );
}
else
{
return( FALSE );
}
}
BOOLEAN CheckFact( UINT16 usFact, UINT8 ubProfileID )
{
INT8 bTown = -1;
switch( usFact )
{
case FACT_DIMITRI_DEAD:
gubFact[ usFact ] = (gMercProfiles[ DIMITRI ].bMercStatus == MERC_IS_DEAD );
break;
case FACT_CURRENT_SECTOR_IS_SAFE:
gubFact[FACT_CURRENT_SECTOR_IS_SAFE] = !( ( (gTacticalStatus.fEnemyInSector && NPCHeardShot( ubProfileID ) ) || gTacticalStatus.uiFlags & INCOMBAT ) );
break;
case FACT_BOBBYRAY_SHIPMENT_IN_TRANSIT:
case FACT_NEW_BOBBYRAY_SHIPMENT_WAITING:
if ( gubFact[FACT_PABLO_PUNISHED_BY_PLAYER] == TRUE && gubFact[FACT_PABLO_RETURNED_GOODS] == FALSE && gMercProfiles[ PABLO ].bMercStatus != MERC_IS_DEAD )
{
gubFact[FACT_BOBBYRAY_SHIPMENT_IN_TRANSIT] = FALSE;
gubFact[FACT_NEW_BOBBYRAY_SHIPMENT_WAITING] = FALSE;
}
else
{
if (CheckForNewShipment()) // if new stuff waiting unseen in Drassen
{
gubFact[FACT_BOBBYRAY_SHIPMENT_IN_TRANSIT] = FALSE;
gubFact[FACT_NEW_BOBBYRAY_SHIPMENT_WAITING] = TRUE;
}
else if ( CountNumberOfBobbyPurchasesThatAreInTransit() > 0) // if stuff in transit
{
if ( gubFact[ FACT_PACKAGE_DAMAGED ] == TRUE )
{
gubFact[FACT_BOBBYRAY_SHIPMENT_IN_TRANSIT] = FALSE;
}
else
{
gubFact[FACT_BOBBYRAY_SHIPMENT_IN_TRANSIT] = TRUE;
}
gubFact[FACT_NEW_BOBBYRAY_SHIPMENT_WAITING] = FALSE;
}
else
{
gubFact[FACT_BOBBYRAY_SHIPMENT_IN_TRANSIT] = FALSE;
gubFact[FACT_NEW_BOBBYRAY_SHIPMENT_WAITING] = FALSE;
}
}
break;
case FACT_NPC_WOUNDED:
gubFact[FACT_NPC_WOUNDED] = CheckNPCWounded( ubProfileID, FALSE );
break;
case FACT_NPC_WOUNDED_BY_PLAYER:
gubFact[FACT_NPC_WOUNDED_BY_PLAYER] = CheckNPCWounded( ubProfileID, TRUE );
break;
case FACT_IRA_NOT_PRESENT:
gubFact[FACT_IRA_NOT_PRESENT] = !CheckNPCWithin( ubProfileID, IRA, 10 );
break;
case FACT_IRA_TALKING:
gubFact[FACT_IRA_TALKING] = ( gubSrcSoldierProfile == 59 );
break;
case FACT_IRA_UNHIRED_AND_ALIVE:
if ( gMercProfiles[ IRA ].bMercStatus != MERC_IS_DEAD && CheckNPCSector( IRA, 10, 1, 1) && !(gMercProfiles[IRA].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED) )
{
gubFact[FACT_IRA_UNHIRED_AND_ALIVE] = TRUE;
}
else
{
gubFact[FACT_IRA_UNHIRED_AND_ALIVE] = FALSE;
}
break;
case FACT_NPC_BLEEDING:
gubFact[FACT_NPC_BLEEDING] = CheckNPCBleeding( ubProfileID );
break;
case FACT_NPC_BLEEDING_BUT_OKAY:
if ( CheckNPCBleeding( ubProfileID ) && CheckNPCInOkayHealth( ubProfileID ) )
{
gubFact[FACT_NPC_BLEEDING_BUT_OKAY] = TRUE;
}
else
{
gubFact[FACT_NPC_BLEEDING_BUT_OKAY] = FALSE;
}
break;
case FACT_PLAYER_HAS_HEAD_AND_CARMEN_IN_SAN_MONA:
gubFact[usFact] = (CheckNPCSector( CARMEN, 5, MAP_ROW_C, 0 ) && CheckPlayerHasHead() );
break;
case FACT_PLAYER_HAS_HEAD_AND_CARMEN_IN_CAMBRIA:
gubFact[usFact] = (CheckNPCSector( CARMEN, 9, MAP_ROW_G, 0 ) && CheckPlayerHasHead() );
break;
case FACT_PLAYER_HAS_HEAD_AND_CARMEN_IN_DRASSEN:
gubFact[usFact] = (CheckNPCSector( CARMEN, 13, MAP_ROW_C, 0 ) && CheckPlayerHasHead() );
break;
case FACT_NPC_OWED_MONEY:
gubFact[FACT_NPC_OWED_MONEY] = (gMercProfiles[ubProfileID].iBalance < 0);
break;
case FACT_FATHER_DRUNK:
gubFact[FACT_FATHER_DRUNK] = ( gMercProfiles[ FATHER ].bNPCData >= 5 );
break;
case FACT_MICKY_DRUNK:
gubFact[FACT_MICKY_DRUNK] = ( gMercProfiles[ MICKY ].bNPCData >= 5 );
break;
case FACT_BRENDA_IN_STORE_AND_ALIVE:
// ensure alive
if ( gMercProfiles[ 85 ].bMercStatus == MERC_IS_DEAD)
{
gubFact[FACT_BRENDA_IN_STORE_AND_ALIVE] = FALSE;
}
// ensure in a building and nearby
else if ( !(NPCInRoom( 85, 47 ) ) )
{
gubFact[FACT_BRENDA_IN_STORE_AND_ALIVE] = FALSE;
}
else
{
gubFact[FACT_BRENDA_IN_STORE_AND_ALIVE] = CheckNPCWithin( ubProfileID, 85, 12 );
}
break;
case FACT_BRENDA_DEAD:
gubFact[FACT_BRENDA_DEAD] = (gMercProfiles[ 85 ].bMercStatus == MERC_IS_DEAD);
break;
case FACT_NPC_IS_ENEMY:
gubFact[FACT_NPC_IS_ENEMY] = CheckNPCIsEnemy( ubProfileID ) || gMercProfiles[ ubProfileID ].ubMiscFlags2 & PROFILE_MISC_FLAG2_NEEDS_TO_SAY_HOSTILE_QUOTE;
break;
/*
case FACT_SKYRIDER_CLOSE_TO_CHOPPER:
SetUpHelicopterForPlayer( 13, MAP_ROW_B );
break;
*/
case FACT_SPIKE_AT_DOOR:
gubFact[FACT_SPIKE_AT_DOOR] = CheckNPCAt( 93, 9817 );
break;
case FACT_WOUNDED_MERCS_NEARBY:
gubFact[usFact] = (NumWoundedMercsNearby( ubProfileID ) > 0);
break;
case FACT_ONE_WOUNDED_MERC_NEARBY:
gubFact[usFact] = (NumWoundedMercsNearby( ubProfileID ) == 1);
break;
case FACT_MULTIPLE_WOUNDED_MERCS_NEARBY:
gubFact[usFact] = (NumWoundedMercsNearby( ubProfileID ) > 1);
break;
case FACT_HANS_AT_SPOT:
gubFact[usFact] = CheckNPCAt( 117, 13523 );
break;
case FACT_MULTIPLE_MERCS_CLOSE:
gubFact[usFact] = ( NumMercsNear( ubProfileID, 3 ) > 1 );
break;
case FACT_SOME_MERCS_CLOSE:
gubFact[usFact] = ( NumMercsNear( ubProfileID, 3 ) > 0 );
break;
case FACT_MARIA_ESCORTED:
gubFact[usFact] = CheckNPCIsEPC( MARIA );
break;
case FACT_JOEY_ESCORTED:
gubFact[usFact] = CheckNPCIsEPC( JOEY );
break;
case FACT_ESCORTING_SKYRIDER:
gubFact[usFact] = CheckNPCIsEPC( SKYRIDER );
break;
case FACT_MARIA_ESCORTED_AT_LEATHER_SHOP:
gubFact[usFact] = ( CheckNPCIsEPC( MARIA ) && (NPCInRoom( MARIA, 2 )) );
break;
case FACT_PC_STRONG_AND_LESS_THAN_3_MALES_PRESENT:
gubFact[usFact] = ( CheckTalkerStrong() && (NumMalesPresent( ubProfileID ) < 3) );
break;
case FACT_PC_STRONG_AND_3_PLUS_MALES_PRESENT:
gubFact[usFact] = ( CheckTalkerStrong() && (NumMalesPresent( ubProfileID ) >= 3) );
break;
case FACT_FEMALE_SPEAKING_TO_NPC:
gubFact[usFact] = CheckTalkerFemale();
break;
case FACT_CARMEN_IN_C5:
gubFact[usFact] = CheckNPCSector( 78, 5, MAP_ROW_C, 0 );
break;
case FACT_JOEY_IN_C5:
gubFact[usFact] = CheckNPCSector( 90, 5, MAP_ROW_C, 0 );
break;
case FACT_JOEY_NEAR_MARTHA:
gubFact[usFact] = CheckNPCWithin( 90, 109, 5 ) && ( CheckGuyVisible( MARTHA, JOEY ) || CheckGuyVisible( JOEY, MARTHA ) );
break;
case FACT_JOEY_DEAD:
gubFact[usFact] = gMercProfiles[ JOEY ].bMercStatus == MERC_IS_DEAD;
break;
case FACT_MERC_NEAR_MARTHA:
gubFact[usFact] = ( NumMercsNear( ubProfileID, 5 ) > 0 );
break;
case FACT_REBELS_HATE_PLAYER:
gubFact[usFact] = (gTacticalStatus.fCivGroupHostile[ REBEL_CIV_GROUP ] == CIV_GROUP_HOSTILE);
break;
case FACT_CURRENT_SECTOR_G9:
gubFact[usFact] = ( gWorldSectorX == 9 && gWorldSectorY == MAP_ROW_G && gbWorldSectorZ == 0 );
break;
case FACT_CURRENT_SECTOR_C5:
gubFact[usFact] = ( gWorldSectorX == 5 && gWorldSectorY == MAP_ROW_C && gbWorldSectorZ == 0 );
break;
case FACT_CURRENT_SECTOR_C13:
gubFact[usFact] = ( gWorldSectorX == 13 && gWorldSectorY == MAP_ROW_C && gbWorldSectorZ == 0 );
break;
case FACT_CARMEN_HAS_TEN_THOUSAND:
gubFact[usFact] = ( gMercProfiles[ 78 ].uiMoney >= 10000 );
break;
case FACT_SLAY_IN_SECTOR:
gubFact[usFact] = (gMercProfiles[ SLAY ].sSectorX == gWorldSectorX && gMercProfiles[ SLAY ].sSectorY == gWorldSectorY && gMercProfiles[ SLAY ].bSectorZ == gbWorldSectorZ );
break;
case FACT_SLAY_HIRED_AND_WORKED_FOR_48_HOURS:
gubFact[usFact] = ( ( gMercProfiles[ SLAY ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED ) && ( gMercProfiles[ SLAY ].usTotalDaysServed > 1 ) );
break;
case FACT_SHANK_IN_SQUAD_BUT_NOT_SPEAKING:
gubFact[usFact] = ( ( FindSoldierByProfileID( SHANK, TRUE ) != NULL) && ( gMercProfiles[ SHANK ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED ) && ( gpSrcSoldier == NULL || gpSrcSoldier->ubProfile != SHANK ) );
break;
case FACT_SHANK_NOT_IN_SECTOR:
gubFact[usFact] = ( FindSoldierByProfileID( SHANK, FALSE ) == NULL );
break;
case FACT_QUEEN_DEAD:
gubFact[usFact] = (gMercProfiles[ QUEEN ].bMercStatus == MERC_IS_DEAD);
break;
case FACT_MINE_EMPTY:
gubFact[usFact] = IsHisMineEmpty( ubProfileID );
break;
case FACT_MINE_RUNNING_OUT:
gubFact[usFact] = IsHisMineRunningOut( ubProfileID );
break;
case FACT_MINE_PRODUCING_BUT_LOYALTY_LOW:
gubFact[usFact] = HasHisMineBeenProducingForPlayerForSomeTime( ubProfileID ) && IsHisMineDisloyal( ubProfileID );
break;
case FACT_CREATURES_IN_MINE:
gubFact[usFact] = IsHisMineInfested( ubProfileID );
break;
case FACT_PLAYER_LOST_MINE:
gubFact[usFact] = IsHisMineLostAndRegained( ubProfileID );
break;
case FACT_MINE_AT_FULL_PRODUCTION:
gubFact[usFact] = IsHisMineAtMaxProduction( ubProfileID );
break;
case FACT_DYNAMO_IN_J9:
gubFact[usFact] = CheckNPCSector( DYNAMO, 9, MAP_ROW_J, 0 ) && NumEnemiesInAnySector( 9, 10, 0 );
break;
case FACT_DYNAMO_ALIVE:
gubFact[usFact] = ( gMercProfiles[ DYNAMO ].bMercStatus != MERC_IS_DEAD );
break;
case FACT_DYNAMO_SPEAKING_OR_NEARBY:
gubFact[usFact] = ( gpSrcSoldier != NULL && (gpSrcSoldier->ubProfile == DYNAMO || ( CheckNPCWithin( gpSrcSoldier->ubProfile, DYNAMO, 10 ) && CheckGuyVisible( gpSrcSoldier->ubProfile, DYNAMO ) ) ) );
break;
case FACT_JOHN_EPC:
gubFact[usFact] = CheckNPCIsEPC( JOHN );
break;
case FACT_MARY_EPC:
gubFact[usFact] = CheckNPCIsEPC( MARY );
break;
case FACT_JOHN_AND_MARY_EPCS:
gubFact[usFact] = CheckNPCIsEPC( JOHN ) && CheckNPCIsEPC( MARY );
break;
case FACT_MARY_ALIVE:
gubFact[usFact] = ( gMercProfiles[ MARY ].bMercStatus != MERC_IS_DEAD );
break;
case FACT_MARY_BLEEDING:
gubFact[usFact] = CheckNPCBleeding( MARY );
break;
case FACT_JOHN_ALIVE:
gubFact[usFact] = ( gMercProfiles[ JOHN ].bMercStatus != MERC_IS_DEAD );
break;
case FACT_JOHN_BLEEDING:
gubFact[usFact] = CheckNPCBleeding( JOHN );
break;
case FACT_MARY_DEAD:
gubFact[usFact] = ( gMercProfiles[ MARY ].bMercStatus == MERC_IS_DEAD );
break;
case FACT_ANOTHER_FIGHT_POSSIBLE:
gubFact[usFact] = AnotherFightPossible();
break;
case FACT_RECEIVING_INCOME_FROM_DCAC:
gubFact[usFact] = (
( PredictDailyIncomeFromAMine( MINE_DRASSEN ) > 0 ) &&
( PredictDailyIncomeFromAMine( MINE_ALMA ) > 0 ) &&
( PredictDailyIncomeFromAMine( MINE_CAMBRIA ) > 0 ) &&
( PredictDailyIncomeFromAMine( MINE_CHITZENA ) > 0 ) );
break;
case FACT_PLAYER_BEEN_TO_K4:
{
UNDERGROUND_SECTORINFO * pUnderGroundSector;
pUnderGroundSector = FindUnderGroundSector( 4, MAP_ROW_K, 1 );
gubFact[usFact] = pUnderGroundSector->fVisited;
}
break;
case FACT_WARDEN_DEAD:
gubFact[usFact] = ( gMercProfiles[ WARDEN ].bMercStatus == MERC_IS_DEAD );
break;
case FACT_PLAYER_PAID_FOR_TWO_IN_BROTHEL:
gubFact[usFact] = (gMercProfiles[ MADAME ].bNPCData > 1);
break;
case FACT_LOYALTY_OKAY:
bTown = gMercProfiles[ ubProfileID ].bTown;
if( ( bTown != BLANK_SECTOR ) && gTownLoyalty[ bTown ].fStarted && gfTownUsesLoyalty[ bTown ])
{
gubFact[usFact] = ( (gTownLoyalty[ bTown ].ubRating >= LOYALTY_LOW_THRESHOLD ) && (gTownLoyalty[ bTown ].ubRating < LOYALTY_OK_THRESHOLD ) );
}
else
{
gubFact[usFact] = FALSE;
}
break;
case FACT_LOYALTY_LOW:
bTown = gMercProfiles[ ubProfileID ].bTown;
if( ( bTown != BLANK_SECTOR ) && gTownLoyalty[ bTown ].fStarted && gfTownUsesLoyalty[ bTown ])
{
// if Skyrider, ignore low loyalty until he has monologues, and wait at least a day since the latest monologue to avoid a hot/cold attitude
if ( ( ubProfileID == SKYRIDER ) &&
( ( guiHelicopterSkyriderTalkState == 0 ) || ( ( GetWorldTotalMin() - guiTimeOfLastSkyriderMonologue ) < ( 24 * 60 ) ) ) )
{
gubFact[usFact] = FALSE;
}
else
{
gubFact[usFact] = (gTownLoyalty[ bTown ].ubRating < LOYALTY_LOW_THRESHOLD );
}
}
else
{
gubFact[usFact] = FALSE;
}
break;
case FACT_LOYALTY_HIGH:
bTown = gMercProfiles[ ubProfileID ].bTown;
if( ( bTown != BLANK_SECTOR ) && gTownLoyalty[ bTown ].fStarted && gfTownUsesLoyalty[ bTown ])
{
gubFact[usFact] = (gTownLoyalty[ gMercProfiles[ ubProfileID ].bTown ].ubRating >= LOYALTY_HIGH_THRESHOLD );
}
else
{
gubFact[usFact] = FALSE;
}
break;
case FACT_ELGIN_ALIVE:
gubFact[usFact] = ( gMercProfiles[ DRUGGIST ].bMercStatus != MERC_IS_DEAD );
break;
case FACT_SPEAKER_AIM_OR_AIM_NEARBY:
gubFact[usFact] = gpDestSoldier && AIMMercWithin( gpDestSoldier->sGridNo, 10 );
break;
case FACT_MALE_SPEAKING_FEMALE_PRESENT:
gubFact[usFact] = ( !CheckTalkerFemale() && FemalePresent( ubProfileID ) );
break;
case FACT_PLAYER_OWNS_2_TOWNS_INCLUDING_OMERTA:
gubFact[usFact] = ( ( GetNumberOfWholeTownsUnderControl() == 3 ) && IsTownUnderCompleteControlByPlayer( OMERTA ) );
break;
case FACT_PLAYER_OWNS_3_TOWNS_INCLUDING_OMERTA:
gubFact[usFact] = ( ( GetNumberOfWholeTownsUnderControl() == 5 ) && IsTownUnderCompleteControlByPlayer( OMERTA ) );
break;
case FACT_PLAYER_OWNS_4_TOWNS_INCLUDING_OMERTA:
gubFact[usFact] = ( ( GetNumberOfWholeTownsUnderControl() >= 6 ) && IsTownUnderCompleteControlByPlayer( OMERTA ) );
break;
case FACT_PLAYER_FOUGHT_THREE_TIMES_TODAY:
gubFact[usFact] = !BoxerAvailable();
break;
case FACT_PLAYER_DOING_POORLY:
gubFact[usFact] = ( CurrentPlayerProgressPercentage() < 20 );
break;
case FACT_PLAYER_DOING_WELL:
gubFact[usFact] = ( CurrentPlayerProgressPercentage() > 50 );
break;
case FACT_PLAYER_DOING_VERY_WELL:
gubFact[usFact] = ( CurrentPlayerProgressPercentage() > 80 );
break;
case FACT_FATHER_DRUNK_AND_SCIFI_OPTION_ON:
gubFact[usFact] = ( ( gMercProfiles[ FATHER ].bNPCData >= 5 ) && gGameOptions.ubGameStyle == STYLE_SCIFI );
break;
case FACT_BLOODCAT_QUEST_STARTED_TWO_DAYS_AGO:
gubFact[usFact] = ( (gubQuest[ QUEST_BLOODCATS ] != QUESTNOTSTARTED) && (GetWorldTotalMin() - GetTimeQuestWasStarted( QUEST_BLOODCATS ) > 2 * NUM_SEC_IN_DAY / NUM_SEC_IN_MIN) );
break;
case FACT_NOTHING_REPAIRED_YET:
gubFact[usFact] = RepairmanIsFixingItemsButNoneAreDoneYet( ubProfileID );
break;
case FACT_NPC_COWERING:
gubFact[usFact] = CheckNPCCowering( ubProfileID );
break;
case FACT_TOP_AND_BOTTOM_LEVELS_CLEARED:
gubFact[usFact] = ( gubFact[ FACT_TOP_LEVEL_CLEARED ] && gubFact[ FACT_BOTTOM_LEVEL_CLEARED ] );
break;
case FACT_FIRST_BARTENDER:
gubFact[ usFact ] = ( gMercProfiles[ubProfileID].bNPCData == 1 || (gMercProfiles[ubProfileID].bNPCData == 0 && CountBartenders() == 0) );
break;
case FACT_SECOND_BARTENDER:
gubFact[ usFact ] = ( gMercProfiles[ubProfileID].bNPCData == 2 || (gMercProfiles[ubProfileID].bNPCData == 0 && CountBartenders() == 1) );
break;
case FACT_THIRD_BARTENDER:
gubFact[ usFact ] = ( gMercProfiles[ubProfileID].bNPCData == 3 || (gMercProfiles[ubProfileID].bNPCData == 0 && CountBartenders() == 2) );
break;
case FACT_FOURTH_BARTENDER:
gubFact[ usFact ] = ( gMercProfiles[ubProfileID].bNPCData == 4 || (gMercProfiles[ubProfileID].bNPCData == 0 && CountBartenders() == 3) );
break;
case FACT_NPC_NOT_UNDER_FIRE:
gubFact[usFact] = !CheckNPCIsUnderFire( ubProfileID );
break;
case FACT_KINGPIN_NOT_IN_OFFICE:
gubFact[usFact] = !( gWorldSectorX == 5 && gWorldSectorY == MAP_ROW_D && NPCInRoomRange( KINGPIN, 30, 39 ) );
// 30 to 39
break;
case FACT_DONT_OWE_KINGPIN_MONEY:
gubFact[usFact] = (gubQuest[ QUEST_KINGPIN_MONEY ] != QUESTINPROGRESS);
break;
case FACT_NO_CLUB_FIGHTING_ALLOWED:
gubFact[usFact] = ( gubQuest[ QUEST_KINGPIN_MONEY ] == QUESTINPROGRESS || gfBoxersResting );// plus other conditions
break;
case FACT_MADDOG_IS_SPEAKER:
gubFact[usFact] = ( gubSrcSoldierProfile == MADDOG );
break;
case FACT_PC_HAS_CONRADS_RECRUIT_OPINION:
gubFact[usFact] = ( gpDestSoldier && (CalcDesireToTalk( gpDestSoldier->ubProfile, gubSrcSoldierProfile, APPROACH_RECRUIT ) >= 50) );
break;
case FACT_NPC_HOSTILE_OR_PISSED_OFF:
gubFact[usFact] = CheckNPCIsEnemy( ubProfileID ) || (gMercProfiles[ ubProfileID ].ubMiscFlags3 & PROFILE_MISC_FLAG3_NPC_PISSED_OFF);
break;
case FACT_TONY_IN_BUILDING:
gubFact[usFact] = CheckNPCSector( TONY, 5, MAP_ROW_C, 0 ) && NPCInRoom( TONY, 50 );
break;
case FACT_SHANK_SPEAKING:
gubFact[usFact] = ( gpSrcSoldier && gpSrcSoldier->ubProfile == SHANK );
break;
case FACT_ROCKET_RIFLE_EXISTS:
gubFact[usFact] = ItemTypeExistsAtLocation( 10472, ROCKET_RIFLE, 0, NULL );
break;
case FACT_DOREEN_ALIVE:
gubFact[usFact] = gMercProfiles[ DOREEN ].bMercStatus != MERC_IS_DEAD;
break;
case FACT_WALDO_ALIVE:
gubFact[usFact] = gMercProfiles[ WALDO ].bMercStatus != MERC_IS_DEAD;
break;
case FACT_PERKO_ALIVE:
gubFact[usFact] = gMercProfiles[ PERKO ].bMercStatus != MERC_IS_DEAD;
break;
case FACT_TONY_ALIVE:
gubFact[usFact] = gMercProfiles[ TONY ].bMercStatus != MERC_IS_DEAD;
break;
case FACT_VINCE_ALIVE:
gubFact[usFact] = gMercProfiles[ VINCE ].bMercStatus != MERC_IS_DEAD;
break;
case FACT_JENNY_ALIVE:
gubFact[usFact] = gMercProfiles[ JENNY ].bMercStatus != MERC_IS_DEAD;
break;
case FACT_ARNOLD_ALIVE:
gubFact[usFact] = gMercProfiles[ ARNIE ].bMercStatus != MERC_IS_DEAD;
break;
case FACT_I16_BLOODCATS_KILLED:
gubFact[usFact] = (SectorInfo[ SEC_I16 ].bBloodCats == 0);
break;
case FACT_NPC_BANDAGED_TODAY:
gubFact[usFact] = (gMercProfiles[ ubProfileID ].ubMiscFlags2 & PROFILE_MISC_FLAG2_BANDAGED_TODAY) != 0;
break;
case FACT_PLAYER_IN_SAME_ROOM:
gubFact[usFact] = PCInSameRoom( ubProfileID );
break;
case FACT_PLAYER_SPOKE_TO_DRASSEN_MINER:
gubFact[usFact] = SpokenToHeadMiner( MINE_DRASSEN );
break;
case FACT_PLAYER_IN_CONTROLLED_DRASSEN_MINE:
gubFact[usFact] = ( GetIdOfMineForSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) == MINE_DRASSEN && !(StrategicMap[ gWorldSectorX + MAP_WORLD_X * gWorldSectorY ].fEnemyControlled) );
break;
case FACT_PLAYER_SPOKE_TO_CAMBRIA_MINER:
gubFact[usFact] = SpokenToHeadMiner( MINE_CAMBRIA );
break;
case FACT_PLAYER_IN_CONTROLLED_CAMBRIA_MINE:
gubFact[usFact] = ( GetIdOfMineForSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) == MINE_CAMBRIA && !(StrategicMap[ gWorldSectorX + MAP_WORLD_X * gWorldSectorY ].fEnemyControlled) );
break;
case FACT_PLAYER_SPOKE_TO_CHITZENA_MINER:
gubFact[usFact] = SpokenToHeadMiner( MINE_CHITZENA );
break;
case FACT_PLAYER_IN_CONTROLLED_CHITZENA_MINE:
gubFact[usFact] = ( GetIdOfMineForSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) == MINE_CHITZENA && !(StrategicMap[ gWorldSectorX + MAP_WORLD_X * gWorldSectorY ].fEnemyControlled) );
break;
case FACT_PLAYER_SPOKE_TO_ALMA_MINER:
gubFact[usFact] = SpokenToHeadMiner( MINE_ALMA );
break;
case FACT_PLAYER_IN_CONTROLLED_ALMA_MINE:
gubFact[usFact] = ( GetIdOfMineForSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) == MINE_ALMA && !(StrategicMap[ gWorldSectorX + MAP_WORLD_X * gWorldSectorY ].fEnemyControlled) );
break;
case FACT_PLAYER_SPOKE_TO_GRUMM_MINER:
gubFact[usFact] = SpokenToHeadMiner( MINE_GRUMM );
break;
case FACT_PLAYER_IN_CONTROLLED_GRUMM_MINE:
gubFact[usFact] = ( GetIdOfMineForSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) == MINE_GRUMM && !(StrategicMap[ gWorldSectorX + MAP_WORLD_X * gWorldSectorY ].fEnemyControlled) );
break;
case FACT_ENOUGH_LOYALTY_TO_TRAIN_MILITIA:
gubFact[usFact] = InTownSectorWithTrainingLoyalty( gWorldSectorX, gWorldSectorY );
break;
case FACT_WALKER_AT_BAR:
gubFact[usFact] = (gMercProfiles[ FATHER ].sSectorX == 13 && gMercProfiles[ FATHER ].sSectorY == MAP_ROW_C);
break;
case FACT_JOEY_ALIVE:
gubFact[usFact] = gMercProfiles[ JOEY ].bMercStatus != MERC_IS_DEAD;
break;
case FACT_UNPROPOSITIONED_FEMALE_SPEAKING_TO_NPC:
gubFact[usFact] = CheckTalkerUnpropositionedFemale();
break;
case FACT_84_AND_85_TRUE:
gubFact[usFact] = CheckFact( 84, ubProfileID ) && CheckFact( FACT_HANS_AT_SPOT, ubProfileID );
break;
case FACT_SKYRIDER_IN_B15:
gubFact[ usFact ] = CheckNPCSector( SKYRIDER, 15, MAP_ROW_B, 0 );
break;
case FACT_SKYRIDER_IN_C16:
gubFact[ usFact ] = CheckNPCSector( SKYRIDER, 16, MAP_ROW_C, 0 );
break;
case FACT_SKYRIDER_IN_E14:
gubFact[ usFact ] = CheckNPCSector( SKYRIDER, 14, MAP_ROW_E, 0 );
break;
case FACT_SKYRIDER_IN_D12:
gubFact[ usFact ] = CheckNPCSector( SKYRIDER, 12, MAP_ROW_D, 0 );
break;
case FACT_KINGPIN_IS_ENEMY:
gubFact[usFact] = (gTacticalStatus.fCivGroupHostile[ KINGPIN_CIV_GROUP ] >= CIV_GROUP_WILL_BECOME_HOSTILE);
break;
case FACT_DYNAMO_NOT_SPEAKER:
gubFact[usFact] = !( gpSrcSoldier != NULL && (gpSrcSoldier->ubProfile == DYNAMO ) );
break;
case FACT_PABLO_BRIBED:
gubFact[usFact] = !CheckFact( FACT_PABLOS_BRIBED, ubProfileID );
break;
case FACT_VEHICLE_PRESENT:
gubFact[usFact] = CheckFact( FACT_OK_USE_HUMMER, ubProfileID ) && ( (FindSoldierByProfileID( PROF_HUMMER, TRUE ) != NULL) || (FindSoldierByProfileID( PROF_ICECREAM, TRUE ) != NULL) );
break;
case FACT_PLAYER_KILLED_BOXERS:
gubFact[usFact] = !BoxerExists();
break;
case 245: // Can dimitri be recruited? should be true if already true, OR if Miguel has been recruited already
gubFact[usFact] = ( gubFact[usFact] || FindSoldierByProfileID( MIGUEL, TRUE ) );
/*
case FACT_:
gubFact[usFact] = ;
break;
*/
default:
break;
}
return( gubFact[usFact] );
}
void StartQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY )
{
InternalStartQuest( ubQuest, sSectorX, sSectorY, TRUE );
}
void InternalStartQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY, BOOLEAN fUpdateHistory )
{
if ( gubQuest[ubQuest ] == QUESTNOTSTARTED )
{
gubQuest[ubQuest] = QUESTINPROGRESS;
if ( fUpdateHistory )
{
SetHistoryFact( HISTORY_QUEST_STARTED, ubQuest, GetWorldTotalMin(), sSectorX, sSectorY );
}
}
else
{
gubQuest[ubQuest] = QUESTINPROGRESS;
}
}
void EndQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY )
{
InternalEndQuest( ubQuest, sSectorX, sSectorY, TRUE );
}
void InternalEndQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY, BOOLEAN fUpdateHistory )
{
if ( gubQuest[ubQuest ] == QUESTINPROGRESS )
{
gubQuest[ubQuest] = QUESTDONE;
if ( fUpdateHistory )
{
ResetHistoryFact( ubQuest, sSectorX, sSectorY );
}
}
else
{
gubQuest[ubQuest] = QUESTDONE;
}
if ( ubQuest == QUEST_RESCUE_MARIA )
{
// cheap hack to try to prevent Madame Layla from thinking that you are
// still in the brothel with Maria...
gMercProfiles[ MADAME ].bNPCData = 0;
gMercProfiles[ MADAME ].bNPCData2 = 0;
}
};
void InitQuestEngine()
{
memset(gubQuest, 0, sizeof(gubQuest));
memset(gubFact, 0, sizeof(gubFact));
// semi-hack to make the letter quest start right away
CheckForQuests( 1 );
if ( gGameOptions.ubGameStyle == STYLE_SCIFI )
{
// 3 medical boosters
gubCambriaMedicalObjects = 21;
}
else
{
gubCambriaMedicalObjects = 18;
}
gubBoxingMatchesWon = 0;
gubBoxersRests = 0;
gfBoxersResting = FALSE;
}
void CheckForQuests( UINT32 uiDay )
{
// This function gets called at 8:00 AM time of the day
#ifdef TESTQUESTS
ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"Checking For Quests, Day %d", uiDay );
#endif
// -------------------------------------------------------------------------------
// QUEST 0 : DELIVER LETTER
// -------------------------------------------------------------------------------
// The game always starts with DELIVER LETTER quest, so turn it on if it hasn't
// already started
if (gubQuest[QUEST_DELIVER_LETTER] == QUESTNOTSTARTED)
{
StartQuest( QUEST_DELIVER_LETTER, -1, -1 );
#ifdef TESTQUESTS
ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"Started DELIVER LETTER quest");
#endif
}
// This quest gets turned OFF through conversation with Miguel - when user hands
// Miguel the letter
}
BOOLEAN SaveQuestInfoToSavedGameFile( HWFILE hFile )
{
UINT32 uiNumBytesWritten;
//Save all the states if the Quests
FileWrite( hFile, gubQuest, MAX_QUESTS, &uiNumBytesWritten );
if( uiNumBytesWritten != MAX_QUESTS )
{
return(FALSE);
}
//Save all the states for the facts
FileWrite( hFile, gubFact, NUM_FACTS, &uiNumBytesWritten );
if( uiNumBytesWritten != NUM_FACTS )
{
return(FALSE);
}
return( TRUE );
}
BOOLEAN LoadQuestInfoFromSavedGameFile( HWFILE hFile )
{
UINT32 uiNumBytesRead;
//Save all the states if the Quests
FileRead( hFile, gubQuest, MAX_QUESTS, &uiNumBytesRead );
if( uiNumBytesRead != MAX_QUESTS )
{
return(FALSE);
}
//Save all the states for the facts
FileRead( hFile, gubFact, NUM_FACTS, &uiNumBytesRead );
if( uiNumBytesRead != NUM_FACTS )
{
return(FALSE);
}
return( TRUE );
}