The-Simpsons-Hit-and-Run/game/code/mission/mission.cpp

2002 lines
58 KiB
C++

//=============================================================================
// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
//
// File: mission.cpp
//
// Description: Implement Mission
//
// History: 15/04/2002 + Created -- NAME
//
//=============================================================================
//========================================
// System Includes
//========================================
// Foundation Tech
#include <raddebug.hpp>
#include <radtime.hpp>
//========================================
// Project Includes
//========================================
#include <mission/gameplaymanager.h>
#include <mission/mission.h>
#include <mission/missionstage.h>
#include <mission/conditions/missioncondition.h>
#include <mission/objectives/missionobjective.h>
#include <mission/objectives/dialogueobjective.h>
#include <mission/bonusobjective.h>
#include <presentation/gui/guisystem.h>
#include <presentation/gui/guimanager.h>
#include <presentation/gui/ingame/guimanageringame.h>
#include <presentation/gui/ingame/guiscreenhud.h>
#include <worldsim/character/charactermanager.h>
#include <worldsim/character/character.h>
#include <worldsim/avatarmanager.h>
#include <worldsim/redbrick/vehicle.h>
#include <worldsim/vehiclecentral.h>
#include <worldsim/worldphysicsmanager.h>
#include <worldsim/harass/chasemanager.h>
#include <worldsim/parkedcars/parkedcarmanager.h>
#include <events/eventmanager.h>
#include <meta/zoneeventlocator.h>
#include <meta/carstartlocator.h>
#include <render/rendermanager/rendermanager.h>
#include <render/rendermanager/worldrenderlayer.h>
#include <camera/supercammanager.h>
#include <camera/supercamcentral.h>
#include <memory/srrmemory.h>
#include <debug/profiler.h>
#include <contexts/context.h>
#include <gameflow/gameflow.h>
#include <mission/charactersheet/charactersheetmanager.h>
#include <mission/boss.h>
#include <mission/ufo/tractorbeam.h>
#include <mission/statepropcollectible.h>
#include <mission/animatedicon.h>
#include <roads/roadmanager.h>
#include <roads/road.h>
#include <roads/roadsegment.h>
#include <roads/intersection.h>
#include <interiors/interiormanager.h>
#include <stateprop/statepropdata.hpp>
#include <atc/atcmanager.h>
#include <ai/actionbuttonhandler.h>
//******************************************************************************
//
// Global Data, Local Data, Local Classes
//
//******************************************************************************
const float MS_PER_SEC = 1000.0f;
const float SEC_IN_MSEC = 0.001f;
const int FINAL_DELAY = 3000; //How long to delay changing stages when this one is marked "final"
const int COMPLETE_DELAY = 0; //How long to delay changing stages when this one shows COMPLETE
const int MAX_NUM_STATEPROP_COLLECTIBLES = 10;
//******************************************************************************
//
// Public Member Functions
//
//******************************************************************************
//==============================================================================
// Mission::Mission
//==============================================================================
// Description: Constructor.
//
// Parameters: None.
//
// Return: N/A.
//
//==============================================================================
Mission::Mission() :
mIsStreetRace1Or2( false ),
mNumMissionStages( 0 ),
mCurrentStage( -1 ),
#ifdef RAD_GAMECUBE
mHeap( GMA_GC_VMM ),
#else
mHeap( GMA_LEVEL_MISSION ),
#endif
mbComplete( false ),
mbIsLastStage( false ),
mMissionTimer( 0 ),
mState( STATE_WAITING ),
mLastStageState( MissionStage::STAGE_IDLE ),
//mNumVehicles( 0 ),
mVehicleRestart( NULL ),
mPlayerRestart( NULL ),
mDynaloadLoc( NULL ),
mStreetRacePropsLoad(NULL),
mStreetRacePropsUnload(NULL),
mResetToStage( 0 ),
mSundayDrive( false ),
mBonusMisison( false ),
mNumBonusObjectives( 0 ),
mIsForcedCar( false ),
mbAutoRepairCar(false),
mbSwappedCars(false),
mbTriggerPattyAndSelmaScreen(false),
mFinalDelay( -1 ),
mCompleteDelay( -1 ),
mChangingStages( false ),
mNoTimeUpdate(false ),
mJumpBackStage( false ),
mJumpBackBy( 1 ),
mNumStatePropCollectibles( 0 ),
mStatePropCollectibles( NULL ),
mDoorStars( NULL ),
mInitPedGroupId( 0 ),
mShowHUD( true ),
mNumValidFailureHints( -1 )
{
strcpy( mcName, "" );
mbCarryOverOutOfCarCondition = false;
unsigned int i;
for ( i = 0; i < MAX_BONUS_OBJECTIVES; ++i )
{
mBonusObjectives[ i ] = NULL;
}
mElapsedTimems = 0;
for (int j =0; j<MAX_STAGES;j++)
{
mMissionStages[j]=NULL;
}
}
//==============================================================================
// Mission::~Mission
//==============================================================================
// Description: Destructor.
//
// Parameters: None.
//
// Return: N/A.
//
//==============================================================================
Mission::~Mission()
{
/*
for( i = 0; i < mNumVehicles; i++ )
{
mVehicles[ i ]->Release();
mVehicles[ i ] = NULL;
}
*/
if ( mDynaloadLoc )
{
mDynaloadLoc->Release();
}
unsigned int k;
for ( k = 0; k < mNumBonusObjectives; ++k )
{
delete mBonusObjectives[ k ];
mBonusObjectives[ k ] = NULL;
}
mNumBonusObjectives = 0;
if ( mStreetRacePropsLoad )
{
mStreetRacePropsLoad->ReleaseVerified();
}
if ( mStreetRacePropsUnload )
{
mStreetRacePropsUnload->ReleaseVerified();
}
// Release all statepropcollectibles and remove them from the world
for ( int i = 0 ; i < mNumStatePropCollectibles ; i++ )
{
StatePropCollectible* collectible = mStatePropCollectibles[i];
if ( collectible )
{
collectible->RemoveFromDSG();
collectible->Release();
}
}
delete [] mStatePropCollectibles;
mStatePropCollectibles = NULL;
mNumStatePropCollectibles = 0;
if ( mDoorStars )
{
delete mDoorStars;
}
}
//=============================================================================
// Mission::AddPlayerVehicle
//=============================================================================
// Description: Comment
//
// Parameters: ( Vehicle* vehicle )
//
// Return: void
//
//=============================================================================
/*
void Mission::AddVehicle( Vehicle* vehicle )
{
rAssert( vehicle != NULL );
int i;
for ( i = 0; i < mNumVehicles; ++i )
{
if ( mVehicles[ i ] == vehicle )
{
//We've already got this one!
return;
}
}
rAssert( mNumVehicles < MAX_VEHICLES );
mVehicles[ mNumVehicles ] = vehicle;
vehicle->AddRef();
mNumVehicles++;
}
*/
//=============================================================================
// Mission::GetVehicleByName
//=============================================================================
// Description: Comment
//
// Parameters: ( char* name )
//
// Return: Vehicle
//
//=============================================================================
/*
Vehicle* Mission::GetVehicleByName( char* name )
{
Vehicle* vehicle = NULL;
for( int i = 0; i < mNumVehicles; i++ )
{
if( strcmp( mVehicles[ i ]->GetName(), name ) == 0 )
{
vehicle = mVehicles[ i ];
break;
}
}
// TODOGREG - is this what we want to do here?
// if mission doesn't have one of these, do we really want to return one from vehicle central??????????
if ( !vehicle )
{
vehicle = GetVehicleCentral()->GetVehicleByName( name );
}
return vehicle;
}
*/
//=============================================================================
// Mission::Initialize
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: void
//
//=============================================================================
void Mission::Initialize( GameMemoryAllocator heap)
{
mHeap = heap;
unsigned int i;
for ( i = 0; i < mNumBonusObjectives; ++i )
{
mBonusObjectives[ i ]->Initialize();
}
mbComplete = false;
mbIsLastStage = false;
mJumpBackStage = false;
mJumpBackBy = 1;
SetToStage( -1 );
mState = STATE_WAITING;
//if missions are forced cars turn off phone booths
if(mIsForcedCar == true)
{
GetGameplayManager()->DisablePhoneBooths();
}
if(mbAutoRepairCar == true)
{
//GetGameplayManager()->GetCurrentVehicle()->ResetDamageState();
if (GetGameplayManager()->GetCurrentVehicle() != NULL)
{
if (GetGameplayManager()->GetCurrentVehicle()->IsVehicleDestroyed() == true)
{
GetEventManager()->TriggerEvent(EVENT_REPAIR_CAR);
}
}
}
else
{
if (IsSundayDrive() == true ||IsWagerMission()== true )
{
}
else
{
mbAutoRepairCar = true;
}
}
//Purchase rewards only in sunday drive.
ActionButton::PurchaseReward::SetEnabled( mSundayDrive );
GetEventManager()->AddListener(this, EVENT_ENTER_INTERIOR_TRANSITION_START);
GetEventManager()->AddListener(this, EVENT_ENTER_INTERIOR_END);
GetEventManager()->AddListener(this, EVENT_EXIT_INTERIOR_START);
GetEventManager()->AddListener(this, EVENT_EXIT_INTERIOR_END);
//chuck: Adding this to handle the patty and selma done talking event. since this class will now trigger screen.
GetEventManager()->AddListener(this, EVENT_GUI_TRIGGER_PATTY_AND_SELMA_SCREEN);
//Try to setup the doorstars if this is sunday drive
rAssert( mDoorStars == NULL );
if ( mSundayDrive )
{
int level = GetGameplayManager()->GetCurrentLevelIndex() + 1;
if ( level == 5 )
{
level = 2;
}
else if ( level == 6 )
{
level = 3;
}
else if ( level == 7 )
{
level = 4;
}
char name[ 64 ];
sprintf( name, "l%d_doorstars", level );
mDoorStars = new AnimatedIcon();
mDoorStars->Init( name, rmt::Vector( 0.0f, 0.0f, 0.0f ), true, false );
}
if( strncmp( mcName, "sr1", 3 ) == 0 ||
strncmp( mcName, "sr2", 3 ) == 0 )
{
mIsStreetRace1Or2 = true;
}
else
{
mIsStreetRace1Or2 = false;
}
}
//=============================================================================
// Mission::Finalize
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: void
//
//=============================================================================
void Mission::Finalize()
{
SetToStage( -1 );
//chuck adding draw synch I hope to fix the level 5 m1 crash when user aborts missions.
p3d::pddi->DrawSync();
//Stop harrass cars from spawning
GameplayManager* gameplayManager = GetGameplayManager();
if ( gameplayManager != NULL )
{
ChaseManager* chaseManager = gameplayManager->GetChaseManager(0);
if ( chaseManager != NULL )
{
chaseManager->ClearAllObjects();
chaseManager->SetMaxObjects(0);
}
gameplayManager->EmptyMissionVehicleSlots();
}
int i;
for ( i = 0; i < mNumMissionStages; i++ )
{
delete mMissionStages[ i ];
mMissionStages[ i ] = NULL;
}
// Remove all collectibles from the vehicles
GetVehicleCentral()->DetachAllCollectibles();
// Release all statepropcollectibles and remove them from the world
for ( int i = 0 ; i < mNumStatePropCollectibles ; i++ )
{
StatePropCollectible* collectible = mStatePropCollectibles[i];
if ( collectible )
{
collectible->RemoveFromDSG();
collectible->Release();
p3d::inventory->Remove( collectible );
collectible = NULL;
}
}
mNumStatePropCollectibles = 0;
/*
for ( j = 0; j < mNumVehicles; ++j )
{
//bool succeeded = GetVehicleCentral()->RemoveVehicleFromActiveList( mVehicles[ j ] );
// rAssert( succeeded );
mVehicles[ j ]->Release();
mVehicles[ j ] = NULL;
}
mNumVehicles = 0;
*/
mNumMissionStages = 0;
mbComplete = false;
mbIsLastStage = false;
unsigned int k;
for ( k = 0; k < mNumBonusObjectives; ++k )
{
mBonusObjectives[ k ]->Finalize();
delete mBonusObjectives[ k ];
}
mNumBonusObjectives = 0;
//This is a safety catch
GetEventManager()->RemoveAll( this );
//
// TODO: Dump all the mission vehicles (player & AI)
//
//Dump the car if this is a forced car mission
if ( mIsForcedCar )
{
//re-enable phone booths
GetGameplayManager()->EnablePhoneBooths();
Character* player = GetAvatarManager()->GetAvatarForPlayer( 0 )->GetCharacter();
Vehicle* forcedCar = GetGameplayManager()->GetVehicleInSlot(GameplayManager::eOtherCar);
Vehicle* currCar = GetAvatarManager()->GetAvatarForPlayer(0)->GetVehicle();
if(currCar && currCar->mVehicleID == VehicleEnum::HUSKA)
{
currCar = GetVehicleCentral()->mHuskPool.FindOriginalVehicleGivenHusk(currCar);
}
if ( forcedCar != NULL && currCar == forcedCar && (mbSwappedCars == false) )
{
//locking forced car since we are done with it.
forcedCar->TransitToAI();
//The character is in the forced car
GetAvatarManager()->PutCharacterOnGround( player, forcedCar );
//Move the character somewhere reasonable
rmt::Vector pos;
player->GetPosition( &pos );
float rotation = player->GetFacingDir();
const Road* road;
RoadSegment* roadSeg;
int segIndex;
float in;
float lateral;
if ( RoadManager::GetInstance()->FindRoad( pos, &road, &roadSeg, segIndex, in, lateral, true ) )
{
//We're on a road set our position to the side of the road.
roadSeg->GetPosition( 0.5f, 0.5f, &pos );
}
else
{
//Am I in an intersection?
Intersection* intersection = RoadManager::GetInstance()->FindIntersection( pos );
if ( intersection != NULL )
{
//Take the first road going out of the intersection and
//put the player on the corner.
const Road* road = intersection->GetRoadOut( 0 );
if(!road)
{
road = intersection->GetRoadIn( 0 );
}
if(road)
{
roadSeg = road->GetRoadSegment( 0 );
roadSeg->GetPosition( 0.5f, 0.5f, &pos );
}
}
else
{
// we're not on a road or on an intersection. get the "closeset" road
float distance;
RoadSegment* segment;
GetIntersectManager()->FindClosestRoad(
pos,
50.0f, //yay the magic numbers i just made this one up
segment,
distance
);
rAssert( segment != NULL );
segment->GetPosition( &pos );
}
}
rmt::Vector CharacterPositionVsCar;
rmt::Vector CharacterPositionVsCharacterStartPosition;
player->GetPosition(CharacterPositionVsCar);
player->GetPosition(CharacterPositionVsCharacterStartPosition);
//subtract the character position from the forced car start locator
CharacterPositionVsCar.Sub(GetGameplayManager()->mPlayerAndCarInfo.mForceLocation);
//subtract the character's position from the original start position.
CharacterPositionVsCharacterStartPosition.Sub(GetGameplayManager()->mPlayerAndCarInfo.mPlayerPosition);
float vaule1,vaule2;
//distance between character and the forced cars respawn locator
vaule1 = rmt::Sqrt(CharacterPositionVsCar.MagnitudeSqr());
//distance between character and the spot where they talked to NPC to start mission.
vaule2 = rmt::Sqrt(CharacterPositionVsCharacterStartPosition.MagnitudeSqr());
//if the character is less than 2 meter from the forced carstart location then place them at the spot that
//they were in when starting the talk to objective that started this mission
if (vaule1 < 2.0f && vaule2 < 20.0f)
{
pos = GetGameplayManager()->mPlayerAndCarInfo.mPlayerPosition;
}
player->RelocateAndReset( pos, rotation, true );
//GetGameplayManager()->PutPlayerInCar( true ); //Hackish way to put the player in the car in the next / prev stage / mission
//GetGameplayManager()->mShouldLoadDefaultVehicle = true;
GetEventManager()->TriggerEvent( EVENT_CHARACTER_POS_RESET );
}
GetGameplayManager()->ClearVehicleSlot(GameplayManager::eOtherCar);
}
//unload streetrace props if there are any for this mission
InitStreetRacePropUnload();
mbSwappedCars = false;
if ( mDoorStars )
{
delete mDoorStars;
mDoorStars = NULL;
}
}
//=============================================================================
// Mission::SetToStage
//=============================================================================
// Description: Comment
//
// Parameters: (unsigned int index)
//
// Return: void
//
//=============================================================================
void Mission::SetToStage( int index, bool resetting )
{
if( index == mCurrentStage )
{
return;
}
MissionStage* stage = GetCurrentStage();
if( stage != NULL )
{
stage->Finalize();
}
stage = GetStage( index );
//Test if this is a "locked" stage and see if you can do it.
if ( stage && stage->GetMissionLocked() )
{
if ( UnlockStage( stage ) )
{
//Now we always play the dialogue.
// //Go to the next stage
// rAssert( index < MAX_STAGES );
// ++index;
}
}
mCurrentStage = index;
stage = GetCurrentStage();
if( stage != NULL )
{
unsigned int time;
MissionStage::StageTimeType type;
stage->GetStageTime( type, time );
switch( type )
{
case MissionStage::STAGETIME_NOT_TIMED:
{
mMissionTimer = -1;
break;
}
case MissionStage::STAGETIME_ADD:
{
mMissionTimer += static_cast<int>( time * MS_PER_SEC );
break;
}
case MissionStage::STAGETIME_SET:
{
mMissionTimer = static_cast<int>( time * MS_PER_SEC );
break;
}
default:
{
rAssert( false );
break;
}
}
// new
// greg
// jan 10, 2003
// loop through up to and including this stage and
// re-initialize the vehicle stuff
if(resetting)
{
ResetPlayer();
int i;
for(i = 0; i < index; i++)
{
GetStage(i)->VehicleInfoInitialize();
GetStage(i)->VehicleFinalize();
}
}
stage->Initialize();
// Is this the start of the mission?
//
if( index == 0 )
{
mState = STATE_INPROGRESS;
}
}
}
//=============================================================================
// Mission::NextStage
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: void
//
//=============================================================================
void Mission::NextStage()
{
SetToStage( mCurrentStage + 1 );
}
//=============================================================================
// Mission::PrevStage
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: void
//
//=============================================================================
void Mission::PrevStage()
{
rAssert( mCurrentStage != -1 );
if ( mCurrentStage == 0 )
{ //We're on the first stage.
GetCurrentStage()->Finalize();
ResetStage();
}
else
{
SetToStage( mCurrentStage - 1 );
}
}
//=============================================================================
// Mission::ResetStage
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: void
//
//=============================================================================
void Mission::ResetStage()
{
GetCurrentStage()->Reset();
}
//=============================================================================
// Mission::HandleEvent
//=============================================================================
// Description: Comment
//
// Parameters: ( EventEnum id, void* pEventData )
//
// Return: void
//
//=============================================================================
void Mission::HandleEvent( EventEnum id, void* pEventData )
{
if((id == EVENT_ENTER_INTERIOR_TRANSITION_START) || (id == EVENT_EXIT_INTERIOR_START))
{
mNoTimeUpdate = true;
}
else if ((id == EVENT_ENTER_INTERIOR_END) || (id == EVENT_EXIT_INTERIOR_END))
{
mNoTimeUpdate = false;
}
else if ( id == EVENT_GUI_MISSION_START )
{
//Dirty dirty
GetCurrentStage()->Start();
GetGameFlow()->GetContext( CONTEXT_GAMEPLAY )->Resume();
if ( GetCurrentStage()->StartBonusObjective() )
{
StartBonusObjectives();
}
}
else if ( id == EVENT_GUI_TRIGGER_PATTY_AND_SELMA_SCREEN)
{
mbTriggerPattyAndSelmaScreen = true;
}
else
{
MissionStage* pStage = GetCurrentStage();
if( pStage != NULL )
{
pStage->HandleEvent( id, pEventData );
}
}
}
//=============================================================================
// Mission::Update
//=============================================================================
// Description: Comment
//
// Parameters: ( unsigned int elapsedTime )
//
// Return: void
//
//=============================================================================
void Mission::Update( unsigned int elapsedTime )
{
if ( mChangingStages )
{
DoStageChange();
}
MissionStage* stage = GetCurrentStage();
// MS9: take this out! There should always be a stage
if( stage == NULL )
return;
rAssert( stage != NULL );
BEGIN_PROFILE( "Mission Update" );
MissionStage::MissionStageState state = stage->GetProgress();
ContextEnum currentContext = GetGameFlow()->GetCurrentContext();
if( currentContext == CONTEXT_PAUSE )
{
state = MissionStage::STAGE_INPROGRESS;
}
switch( state )
{
case MissionStage::STAGE_INPROGRESS:
{
if (GetCurrentStage() != NULL)
{
if( mMissionTimer >=1 && !mNoTimeUpdate && GetCurrentStage()->mbDisablePlayerControlForCountDown != true)
{
if(GetCurrentStage()->QueryUseElapsedTime() ==true) //make timer count up if stage is using elasped time.
{
mMissionTimer += elapsedTime;
}
else
{
mMissionTimer -= elapsedTime;
}
mElapsedTimems += elapsedTime;
//Chuck:only trigger red flashing timer if we aren't using elasped time.
if( ( mMissionTimer <= 10000 )
&& ( mMissionTimer + elapsedTime > 10000 )
&& ( stage->GetFinalStage()
&& !(GetCurrentStage()->QueryUseElapsedTime())
) )
{
GetEventManager()->TriggerEvent( EVENT_TIME_RUNNING_OUT );
}
}
GetCurrentStage()->Update( elapsedTime );
unsigned int i;
for ( i = 0; i < mNumBonusObjectives; ++i )
{
mBonusObjectives[ i ]->Update( elapsedTime );
}
break;
}
}
case MissionStage::STAGE_COMPLETE:
{
if( state == mLastStageState && mFinalDelay == -1 && mCompleteDelay == -1 )
{
break;
}
mbComplete = mCurrentStage == mNumMissionStages-1;
if ( mFinalDelay == -1 && stage->GetFinalStage() && mbComplete )
{
//Setup the delay and skip outta here.
MissionStage* thisStage = this->GetCurrentStage();
MissionObjective* objective = thisStage->GetObjective();
if( objective->IsPattyAndSelmaDialog() )
{
mFinalDelay = 0;
}
else
{
mFinalDelay = FINAL_DELAY;
//
// Tell the GUI system that the mission succeeded
//
if(!IsSundayDrive())
{
GetGuiSystem()->HandleMessage( GUI_MSG_INGAME_MISSION_COMPLETE );
}
}
//TODO: Send off the bonus mission info too.
GetEventManager()->TriggerEvent( EVENT_MISSION_SUCCESS );
if( stage->GetObjective()->GetObjectiveType() == MissionObjective::OBJ_LOSETAIL )
{
GetEventManager()->TriggerEvent( EVENT_TAIL_LOST_DIALOG );
}
else
{
GetEventManager()->TriggerEvent( EVENT_MISSION_SUCCESS_DIALOG );
}
break;
}
else if ( stage->GetFinalStage() && mbComplete )
{
if ( static_cast<int>(elapsedTime) >= mFinalDelay )
{
//All done, carry on.
mFinalDelay = -1;
}
else
{
//Decrement the time and get outta here. WE pause to show the mission complete stuff.
mFinalDelay -= elapsedTime;
break;
}
}
// trigger stage complete event
//
unsigned int showStageComplete = stage->IsShowStageComplete() ? 1 : 0;
if ( showStageComplete && mCompleteDelay == -1 )
{
//We need to delay the mission stage change to prevent weirdness.
mCompleteDelay = COMPLETE_DELAY;
GetEventManager()->TriggerEvent( EVENT_STAGE_COMPLETE,
reinterpret_cast<void*>( showStageComplete ) );
if( stage->GetObjective()->GetObjectiveType() == MissionObjective::OBJ_LOSETAIL )
{
GetEventManager()->TriggerEvent( EVENT_TAIL_LOST_DIALOG );
}
break;
}
else if ( showStageComplete )
{
if ( mCompleteDelay > static_cast<int>(elapsedTime) )
{
mCompleteDelay -= elapsedTime;
break;
}
else
{
//We're good.
mCompleteDelay = -1;
}
}
if ( stage->GetFinalStage() || mbComplete )
{
mState = STATE_SUCCESS;
if ( stage->GetFinalStage() )
{
//To Do::MESA Insert Call to CharacterSheetManager to update
//character sheet with complete and bonus object stuff
if (mBonusObjectives[0] != NULL)
{
int seconds = (mElapsedTimems /1000);
GetCharacterSheetManager()->SetMissionComplete(GetGameplayManager()->GetCurrentLevelIndex(),mcName,mBonusObjectives[0]->GetSuccessful(),seconds );
}
else
{
int seconds = (mElapsedTimems/1000);
GetCharacterSheetManager()->SetMissionComplete(GetGameplayManager()->GetCurrentLevelIndex(),mcName,false,seconds);
}
if ( mbTriggerPattyAndSelmaScreen == true)
{
GetGuiSystem()->HandleMessage( GUI_MSG_GOTO_SCREEN,
CGuiWindow::GUI_SCREEN_ID_MISSION_SUCCESS,
CLEAR_WINDOW_HISTORY );
GetEventManager()->TriggerEvent( EVENT_GUI_ENTERING_MISSION_SUCCESS_SCREEN );
GetGameFlow()->SetContext( CONTEXT_PAUSE );
InitStreetRacePropUnload();
mbTriggerPattyAndSelmaScreen = false;
}
}
//This is silly.... Dirty too. At least it's not the GUI doing it.
//Really this just updates the state of all the missions. GAH.
GetGameplayManager()->ContinueGameplay();
if ( mCurrentStage != -1 )
{
//GetCurrentStage()->Reset();
GetCurrentStage()->Start();
if ( GetCurrentStage()->StartBonusObjective() )
{
StartBonusObjectives();
}
}
}
else
{
SetupStageChange();
}
break;
}
case MissionStage::STAGE_FAILED:
{
unsigned int i;
unsigned int numConditions;
bool isChaseCondition = false;
if( state == mLastStageState )
{
break;
}
mState = STATE_FAILED;
//if we fail a forced car relock the forced car
if ( IsForcedCar() == true)
{
if (GetGameplayManager()-> mVehicleSlots[GameplayManager::eOtherCar].mp_vehicle != NULL)
{
GetGameplayManager()-> mVehicleSlots[GameplayManager::eOtherCar].mp_vehicle->ActivateTriggers(false);
}
}
// Tell the GUI system that mission failed
//
GetGuiSystem()->HandleMessage( GUI_MSG_INGAME_MISSION_FAILED );
// get the failure condition
//
MissionCondition* failedCondition = stage->GetFailureCondition();
rTuneAssertMsg( failedCondition != NULL,
"WTF?? How could there be no failure condition?" );
//
// Determine whether any of the conditions involve chases
//
numConditions = stage->GetNumConditions();
for( i = 0; i < numConditions; i++ )
{
if( stage->GetCondition( i )->IsChaseCondition() )
{
isChaseCondition = true;
break;
}
}
GetEventManager()->TriggerEvent( EVENT_MISSION_FAILURE, reinterpret_cast<void*>( failedCondition ) );
mbComplete = true;
//
// We need to re-enable world rendering if we failed because of
// entering an interior
//
bool entering = GetInteriorManager()->IsEntering();
if( entering )
{
GetRenderManager()->mpLayer( RenderEnums::LevelSlot )->Thaw();
}
if(IsBonusMission())
{
GetCharacterManager()->ResetBonusCharacters();
}
break;
}
case MissionStage::STAGE_BACKUP:
{
//This is a bad thing.
rAssert( false );
/* PrevStage();
GetCurrentStage()->Start();
*/
break;
}
default:
{
// whatever
break;
}
}
mLastStageState = state;
if ( mDoorStars )
{
mDoorStars->Update( elapsedTime );
}
DoUpdate( elapsedTime );
END_PROFILE( "Mission Update" );
}
//=============================================================================
// Mission::IsComplete
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: bool
//
//=============================================================================
bool Mission::IsComplete()
{
return( mbComplete );
}
//=============================================================================
// Mission::SetRestartDyanload
//=============================================================================
// Description: Comment
//
// Parameters: ( const char* loadString )
//
// Return: void
//
//=============================================================================
void Mission::SetRestartDynaload( const char* loadString, const char* interior)
{
HeapMgr()->PushHeap (GMA_LEVEL_MISSION);
MEMTRACK_PUSH_GROUP( "Mission - Dynaload" );
if ( mDynaloadLoc )
{
mDynaloadLoc->Release();
}
if( strcmp( loadString, "" ) != 0 )
{
mDynaloadLoc = new ZoneEventLocator;
mDynaloadLoc->AddRef();
mDynaloadLoc->SetZoneSize( strlen(loadString) + 1 );
mDynaloadLoc->SetZone( loadString );
mDynaloadLoc->SetPlayerEntered();
if(interior)
{
mDynaloadLoc->SetName(interior);
}
}
else
{
mDynaloadLoc = NULL;
}
MEMTRACK_POP_GROUP( "Mission - Dynaload" );
HeapMgr()->PopHeap (GMA_LEVEL_MISSION);
}
//=============================================================================
// Mission::AddBonusObjective
//=============================================================================
// Description: Comment
//
// Parameters: ( BonusObjective* bo )
//
// Return: void
//
//=============================================================================
void Mission::AddBonusObjective( BonusObjective* bo )
{
rAssert( mNumBonusObjectives < MAX_BONUS_OBJECTIVES );
mBonusObjectives[ mNumBonusObjectives ] = bo;
++mNumBonusObjectives;
}
//=============================================================================
// Mission::StartBonusObjectives
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: void
//
//=============================================================================
void Mission::StartBonusObjectives()
{
unsigned int i;
for ( i = 0; i < mNumBonusObjectives; ++i )
{
mBonusObjectives[ i ]->Start();
}
}
//=============================================================================
// Mission::SetForcedCar
//=============================================================================
// Description: Comment
//
// Parameters: ( bool isForced )
//
// Return: void
//
//=============================================================================
void Mission::SetForcedCar( bool isForced )
{
mIsForcedCar = isForced;
}
//=============================================================================
// Mission::SetMissionTime
//=============================================================================
// Description: Comment
//
// Parameters: ( int timeMilliseconds )
//
// Return: void
//
//=============================================================================
void Mission::SetMissionTime( int timeMilliseconds )
{
mMissionTimer = timeMilliseconds;
}
//=============================================================================
// Mission::CreateStatePropCollectible
//=============================================================================
// Description: Creates a new statepropcollectible and places it at the given locator
//
// Parameters: name of the CStateProp data chunk in the inventory, name of the locator
//
// Return: void
//
//=============================================================================
void Mission::CreateStatePropCollectible( const char* statepropname, const char* locatorname, int collisionattributes )
{
// No space in the array, bail
if ( mNumStatePropCollectibles >= MAX_NUM_STATEPROP_COLLECTIBLES )
return;
HeapMgr()->PushHeap (GMA_LEVEL_MISSION);
Locator* locator = p3d::find< Locator >( locatorname );
if ( locator )
{
CStatePropData* propdata = p3d::find< CStatePropData >(statepropname);
if ( propdata )
{
// Get the locator's position
rmt::Vector locatorposition;
locator->GetPosition( &locatorposition );
// Fill out a translation matrix
rmt::Matrix transform;
transform.Identity();
transform.FillTranslate( locatorposition );
StatePropCollectible* collectible = new StatePropCollectible();
CollisionAttributes* collAttr = GetATCManager()->CreateCollisionAttributes( PROP_MOVEABLE, collisionattributes, 2.242f );
collAttr->AddRef();
collectible->LoadSetup( propdata, 0, transform, collAttr, false, NULL );
collAttr->Release();
collectible->SetName( statepropname );
p3d::inventory->Store( collectible );
// Add it to the internal list of prop collectibles
// Allocate a new list if necessary
if ( mNumStatePropCollectibles == 0 )
{
mStatePropCollectibles = new StatePropCollectible*[ MAX_NUM_STATEPROP_COLLECTIBLES ];
}
mStatePropCollectibles[ mNumStatePropCollectibles ] = collectible;
collectible->AddRef();
mNumStatePropCollectibles++;
}
else
{
rReleaseAssertMsg("can't find stateprop %s\n",statepropname);
}
}
else
{
rReleaseAssertMsg("can't find locator %s\n",locatorname);
}
HeapMgr()->PopHeap (GMA_LEVEL_MISSION);
}
//=============================================================================
// Mission::AttachStatePropCollectible
//=============================================================================
// Description: Creates and attaches a new statepropcollectible on a vehicle
//
// Parameters: name of the CStateProp data chunk in the inventory, name of the vehicle
//
// Return: void
//
//=============================================================================
void Mission::AttachStatePropCollectible( const char* statepropname, const char* vehicleName, int collisionattributes )
{
// No space in the array, bail
if ( mNumStatePropCollectibles >= MAX_NUM_STATEPROP_COLLECTIBLES )
return;
CStatePropData* statePropData = p3d::find< CStatePropData > (statepropname);
if ( statePropData )
{
Vehicle* vehicle = GetVehicleCentral()->GetVehicleByName( vehicleName );
StatePropCollectible* stateprop = new StatePropCollectible();
rmt::Matrix transform;
transform.Identity();
// Create some collision attributes. Unfort I may just have to leave these hardcoded.
// Settings seem to make very little difference anyway.
CollisionAttributes* collAttr = GetATCManager()->CreateCollisionAttributes( PROP_MOVEABLE, collisionattributes, 2.242f );
collAttr->AddRef();
stateprop->LoadSetup( statePropData, 0, transform, collAttr, false );
collAttr->Release();
// Add it to scenegraph
stateprop->AddToDSG();
vehicle->AttachCollectible( stateprop );
// Add it to the internal list of prop collectibles
// Allocate a new list if necessary
if ( mNumStatePropCollectibles == 0 )
{
mStatePropCollectibles = new StatePropCollectible*[ MAX_NUM_STATEPROP_COLLECTIBLES ];
}
stateprop->SetName( statepropname );
p3d::inventory->Store( stateprop );
mStatePropCollectibles[ mNumStatePropCollectibles ] = stateprop;
stateprop->AddRef();
mNumStatePropCollectibles++;
}
}
//=============================================================================
// Mission::Reset
//=============================================================================
// Description: Comment
//
// Parameters: ( bool JumpStage )
//
// Return: void
//
//=============================================================================
void Mission::Reset( bool jumpStage )
{
mbComplete = false;
mState = STATE_INPROGRESS;
mbIsLastStage = false;
mElapsedTimems = 0;
mbCarryOverOutOfCarCondition = false;
//Reset ChaseManager Spawn Rate incase of Retries
GameplayManager* gameplayManager = GetGameplayManager();
if ( gameplayManager != NULL )
{
ChaseManager* chaseManager = gameplayManager->GetChaseManager(0);
if ( chaseManager != NULL )
{
chaseManager->SetMaxObjects(0);
}
gameplayManager->MakeSureHusksAreReverted(); // do this rather than let GameplayManager catch event below, because that's too late I think
}
SetToStage( -1 );
if ( jumpStage )
{
SetToStage( mResetToStage, jumpStage );
// repair car on mission reset or retry
GetEventManager()->TriggerEvent(EVENT_REPAIR_CAR);
}
else
{
SetToStage( 0 );
}
//Reset the bonus objectives.
unsigned int i;
for ( i = 0; i < mNumBonusObjectives; ++i )
{
mBonusObjectives[ i ]->Reset();
}
GetEventManager()->TriggerEvent( EVENT_MISSION_RESET, (void*)( jumpStage ) );
GetCharacterSheetManager()->IncrementMissionAttempt(GetGameplayManager()->GetCurrentLevelIndex(),this->mcName);
InitStreetRacePropLoad();
//make sure our current car doesn't have locked doors
//since forced cars have locked doors.
if(IsForcedCar())
{
if(GetGameplayManager()->mVehicleSlots[GameplayManager::eOtherCar].mp_vehicle != NULL)
{
GetGameplayManager()->mVehicleSlots[GameplayManager::eOtherCar].mp_vehicle->ActivateTriggers(true);
}
}
}
//=============================================================================
// Mission::ResetPlayer
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: void
//
//=============================================================================
void Mission::ResetPlayer()
{
//This is where we get the reset data and apply it. Sounds good eh?
Character* player = GetCharacterManager()->GetCharacter( 0 ); //This is the player...
Vehicle* car = GetGameplayManager()->GetCurrentVehicle(); //Current car
if( mVehicleRestart != NULL )
{
GetGameplayManager()->PlaceVehicleAtLocator( car, mVehicleRestart );
}
//if ( mPlayerRestart == NULL || IsForcedCar() || IsRaceMission() )
if ( mPlayerRestart == NULL || IsRaceMission() )
{
rmt::Vector pos;
mVehicleRestart->GetLocation( &pos );
player->RelocateAndReset( pos, 0, true );
if (GetGameplayManager()->GetCurrentVehicle()->mVehicleDestroyed != true)
{
GetAvatarManager()->PutCharacterInCar( player, car );
}
}
else
{
//TODO: Make a put player on ground type thingie. I shouldn't have to know about this.
GetGameplayManager()->PlaceCharacterAtLocator( player, mPlayerRestart );
GetAvatarManager()->PutCharacterOnGround( player, car );
}
GetEventManager()->TriggerEvent( EVENT_CHARACTER_POS_RESET );
//Let's cut the camera.
GetSuperCamManager()->GetSCC( 0 )->NoTransition();
GetSuperCamManager()->GetSCC( 0 )->DoCameraCut();
}
//=============================================================================
// Mission::InitDynaLoad
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: void
//
//=============================================================================
void Mission::InitDynaLoad()
{
rTuneAssertMsg( mDynaloadLoc, "DYNALOAD information is required in all missions!" );
GetEventManager()->TriggerEvent( EVENT_FIRST_DYNAMIC_ZONE_START, mDynaloadLoc );
// set the pedgroup sheeyatsu...
if( 0 <= mInitPedGroupId && mInitPedGroupId < PedestrianManager::MAX_MODEL_GROUPS )
{
PedestrianManager::GetInstance()->SwitchModelGroup( mInitPedGroupId );
PedestrianManager::SetDefaultModelGroup( mInitPedGroupId );
}
}
void Mission::SetInitPedGroup( int initGroupId )
{
rTuneAssert( 0 <= mInitPedGroupId && mInitPedGroupId < PedestrianManager::MAX_MODEL_GROUPS );
mInitPedGroupId = initGroupId;
}
//=============================================================================
// Mission::DialogueCharactersTeleported
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: bool
//
//=============================================================================
bool Mission::DialogueCharactersTeleported()
{
if ( !GetCurrentStage() ||
!(GetCurrentStage()->GetObjective()) )
{
//DAMN THOSE COSMIC RAYS!
return false; //No cut.
}
if ( GetCurrentStage()->GetObjective()->GetObjectiveType() == MissionObjective::OBJ_DIALOGUE )
{
return static_cast<DialogueObjective*>(GetCurrentStage()->GetObjective())->CharactersReset();
}
return false;
}
//=============================================================================
// Mission::GetCurrentStage
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: inline
//
//=============================================================================
MissionStage* Mission::GetCurrentStage()
{
if(( mCurrentStage >= 0 ) && (mCurrentStage < (int)mNumMissionStages ))
{
return( mMissionStages[ mCurrentStage ] );
}
else
{
return( NULL );
}
}
//=============================================================================
// Mission::GetMissionTimeLeftInSeconds
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: unsigned
//
//=============================================================================
int Mission::GetMissionTimeLeftInSeconds()
{
return( static_cast<int>( mMissionTimer * SEC_IN_MSEC ));
}
//=============================================================================
// Mission::GetMissionTimeLeftInMilliSeconds
//=============================================================================
// Description: Comment
//
// Parameters: ()
//
// Return: unsigned
//
//=============================================================================
int Mission::GetMissionTimeLeftInMilliSeconds()
{
return( mMissionTimer );
}
//******************************************************************************
//
// Private Member Functions
//
//******************************************************************************
//=============================================================================
// Mission::DoUpdate
//=============================================================================
// Description: Comment
//
// Parameters: ( int elapsedTime )
//
// Return: void
//
//=============================================================================
void Mission::DoUpdate( int elapsedTime )
{
}
//=============================================================================
// Mission::SetBonusMission
//=============================================================================
// Description: sets a flag if this is a bonus mission
//
// Parameters: NONE
//
// Return: void
//
//=============================================================================
void Mission::SetBonusMission()
{
mBonusMisison = true;
}
//=============================================================================
// Mission::IsBonusMission
//=============================================================================
// Description: Comment
//
// Parameters: ( int elapsedTime )
//
// Return: void
//
//=============================================================================
bool Mission::IsBonusMission()
{
if( IsRaceMission() )
{
return false;
}
return mBonusMisison;
}
//=============================================================================
// Mission::IsBonusMission
//=============================================================================
// Description: determines if this mission is a special road race
//
// Parameters: ( int elapsedTime )
//
// Return: void
//
//=============================================================================
bool Mission::IsRaceMission()
{
if( ( mcName[ 0 ] == 's' ) && ( mcName[ 1 ] == 'r' ) )
{
return true;
}
return false;
}
//=============================================================================
// Mission::IsWagerMission
//=============================================================================
// Description: determines if this mission is a wager mission or not
//
// Parameters: NONE
//
// Return: bool - is it or isn't it?
//
//=============================================================================
bool Mission::IsWagerMission()
{
if( ( mcName[ 0 ] == 'g' ) && ( mcName[ 1 ] == 'r' ) )
{
return true;
}
return false;
}
//=============================================================================
// Mission::UnlockStage
//=============================================================================
// Description: Comment
//
// Parameters: ( MissionStage* stage )
//
// Return: bool
//
//=============================================================================
bool Mission::UnlockStage( MissionStage* stage )
{
unsigned int i;
for ( i = 0; i < MAX_LOCK_REQUIREMENTS; ++i )
{
const MissionStage::LockRequirement& requirement = stage->GetLockRequirement( i );
if ( requirement.mType == MissionStage::LockRequirement::NONE )
{
continue;
}
//Test this against what the character has.
if ( requirement.mType == MissionStage::LockRequirement::CAR )
{
if ( strcmp( GetGameplayManager()->GetCurrentVehicle()->mName, requirement.mName ) != 0 )
{
//Failed the car test.
return false;
}
}
else if ( requirement.mType == MissionStage::LockRequirement::SKIN /*Should test for skins.*/ )
{
Character* character = GetAvatarManager()->GetAvatarForPlayer(0)->GetCharacter();
if ( strcmp( GetCharacterManager()->GetModelName( character ), requirement.mName ) != 0 )
{
//failed the skin test
return false;
}
}
}
return true;
}
//=============================================================================
// Mission::LoadStreetRaceProps
//=============================================================================
// Description: Load the p3d file that contains the instanced streetrace props
//
// Parameters: ( const char* loadString )
//
// Return: void
//
//=============================================================================
void Mission::LoadStreetRaceProps( const char* loadString )
{
HeapMgr()->PushHeap (GMA_LEVEL_MISSION);
MEMTRACK_PUSH_GROUP( "Mission - StreetRaceProps" );
//clear any junk
if ( mStreetRacePropsLoad != NULL)
{
mStreetRacePropsLoad->ReleaseVerified();
}
if( strcmp( loadString, "" ) != 0 )
{
mStreetRacePropsLoad = new ZoneEventLocator;
mStreetRacePropsLoad->AddRef();
mStreetRacePropsLoad->SetZoneSize( strlen(loadString) + 1 );
mStreetRacePropsLoad->SetZone( loadString );
mStreetRacePropsLoad->SetPlayerEntered();
}
else
{
mStreetRacePropsLoad = NULL;
}
MEMTRACK_POP_GROUP( "Mission - StreetRaceProps" );
HeapMgr()->PopHeap (GMA_LEVEL_MISSION);
}
//=============================================================================
// Mission::LoadStreetRaceProps
//=============================================================================
// Description: Unload the p3d file that contains the instanced streetrace props
//
// Parameters: ( const char* loadString )
//
// Return: void
//
//=============================================================================
void Mission::UnloadStreetRaceProps( const char* loadString )
{
HeapMgr()->PushHeap (GMA_LEVEL_MISSION);
MEMTRACK_PUSH_GROUP( "Mission - StreetRacePropsUnload" );
//clear any junk
if ( mStreetRacePropsUnload != NULL)
{
mStreetRacePropsUnload->ReleaseVerified();
}
if( strcmp( loadString, "" ) != 0 )
{
mStreetRacePropsUnload = new ZoneEventLocator;
mStreetRacePropsUnload->AddRef();
mStreetRacePropsUnload->SetZoneSize( strlen(loadString) + 1 );
mStreetRacePropsUnload->SetZone( loadString );
mStreetRacePropsUnload->SetPlayerEntered();
}
else
{
mStreetRacePropsUnload = NULL;
}
MEMTRACK_POP_GROUP( "Mission - StreetRacePropsUnload" );
HeapMgr()->PopHeap (GMA_LEVEL_MISSION);
}
void Mission::SetupStageChange()
{
mChangingStages = true;
GetCurrentStage()->DoTransition();
}
void Mission::DoStageChange()
{
// if( !GetInteriorManager()->IsEntering() && !GetInteriorManager()->IsExiting() )
{
GetGuiSystem()->HandleMessage( GUI_MSG_RESUME_INGAME );
}
MissionStage* currStage = GetCurrentStage();
if ( currStage->GetMissionLocked() && !UnlockStage( currStage ) )
{
//Display the new message and stop the next stage from displaying its message
rAssert( currStage->GetStartMessageIndex() >= 0 );
GetGuiSystem()->HandleMessage( GUI_MSG_INGAME_DISPLAY_PROMPT, currStage->GetStartMessageIndex() );
GetEventManager()->TriggerEvent( EVENT_STAGE_TRANSITION_FAILED );
GetStage( mCurrentStage + 1 )->ShowStartMessageIndex( false );
NextStage();
}
else if ( mJumpBackStage )
{
rTuneAssertMsg( (mCurrentStage - mJumpBackBy) >= 0, "Jumping back too far!" );
SetToStage( mCurrentStage - mJumpBackBy );
mJumpBackStage = false;
}
else
{
NextStage();
}
GetCurrentStage()->Start();
if ( GetCurrentStage()->StartBonusObjective() )
{
StartBonusObjectives();
}
mChangingStages = false;
}
void Mission::SetSwappedCarsFlag(bool flag)
{
mbSwappedCars = flag;
}
bool Mission::GetSwappedCarsFlag()
{
return mbSwappedCars;
}
void Mission::InitStreetRacePropLoad()
{
//Chuck: Trigger the loading of the Street Race Specify Props
if (mStreetRacePropsLoad != NULL)
{
GetEventManager()->TriggerEvent( (EventEnum)(EVENT_LOCATOR+LocatorEvent::DYNAMIC_ZONE), mStreetRacePropsLoad );
// about to do a street race so disable peds and parked cars
if( IsRaceMission() )
{
PedestrianManager::GetInstance()->DumpAllPedModels();
}
else
{
PedestrianManager::GetInstance()->RemoveAllPeds();
}
PedestrianManager::GetInstance()->AllowAddingPeds(false);
GetPCM().DisableParkedCars();
}
}
void Mission::InitStreetRacePropUnload()
{
if (mStreetRacePropsUnload != NULL)
{
//Chuck: Trigger the unloading of the Street Race Specify Props
GetEventManager()->TriggerEvent( (EventEnum)(EVENT_LOCATOR+LocatorEvent::DYNAMIC_ZONE), mStreetRacePropsUnload );
// street race done so reenable peds and parked cars
PedestrianManager::GetInstance()->AllowAddingPeds(true);
GetPCM().EnableParkedCars();
}
}
//=============================================================================
// Mission::ShowHUD
//=============================================================================
// Description: Comment
//
// Parameters:
//
// Return: inline
//
//=============================================================================
void Mission::ShowHUD( bool isShowHUD )
{
mShowHUD = isShowHUD;
CGuiScreenHud* currentHud = GetCurrentHud();
if( currentHud != NULL )
{
currentHud->SetVisible( isShowHUD );
}
}
bool Mission::CanMDKCar(Vehicle* pVehicle,MissionStage* pStage)
{
//search for the input stage.
int counter =0;
int i = 0;
int index =0;
for (i = 0;i<MAX_STAGES;i++)
{
if (mMissionStages[i] != NULL)
{
if (mMissionStages[i] == pStage)
{
index = i+1;
break;
}
}
}
for (index; index <MAX_STAGES;index++)
{
if (mMissionStages[index] != NULL )
{
for (int j =0; j< MissionStage::MAX_VEHICLES;j++)
{
if ( mMissionStages[index]->GetVehicle(j) == pVehicle)
{
counter++;
}
}//end of vehicle search loop
}
}//end of out missionstage loop
if ( counter > 0)
{
return false;
}
else
{
return true;
}
}