//============================================================================= // Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. // // File: gotoobjective.cpp // // Description: Implement GoToObjective // // History: 16/04/2002 + Created -- NAME // //============================================================================= //======================================== // System Includes //======================================== // Foundation Tech #include #include //======================================== // Project Includes //======================================== #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //****************************************************************************** // // Global Data, Local Data, Local Classes // //****************************************************************************** //****************************************************************************** // // Public Member Functions // //****************************************************************************** //============================================================================== // GoToObjective::GoToObjective //============================================================================== // Description: Constructor. // // Parameters: None. // // Return: N/A. // //============================================================================== GoToObjective::GoToObjective() : mDestinationLocator( NULL ), mAnimatedIcon( NULL ), mScaleFactor( 1.0f ), mHudMapIconID( -1 ), mCollectEffect( NULL ), mWaitingForEffect( false ), mGotoDialogOn( true ), mActionTrigger( false ), mOldEvent( LocatorEvent::NUM_EVENTS ), mOldData( -1 ) { mArrowPath.mPathRoute.Allocate( RoadManager::GetInstance()->GetNumRoads() ); mEffectName[0] = '\0'; } //============================================================================== // GoToObjective::~GoToObjective //============================================================================== // Description: Destructor. // // Parameters: None. // // Return: N/A. // //============================================================================== GoToObjective::~GoToObjective() { if ( mAnimatedIcon ) { delete mAnimatedIcon; mAnimatedIcon = NULL; UnregisterLocator( mHudMapIconID ); //Alert the walkercam that there is a drawable. WalkerCam* wc = static_cast(GetSuperCamManager()->GetSCC( 0 )->GetSuperCam( SuperCam::WALKER_CAM )); if ( wc ) { wc->SetCollectibleLocation( mAnimatedIcon ); } } if ( mCollectEffect ) { delete mCollectEffect; mCollectEffect = NULL; } } //============================================================================= // GoToObjective::OnInitalize //============================================================================= // Description: Comment // // Parameters: () // // Return: void // //============================================================================= void GoToObjective::OnInitialize() { MEMTRACK_PUSH_GROUP( "Mission - GoToObjective" ); GameMemoryAllocator gma = GetGameplayManager()->GetCurrentMissionHeap(); rAssert( mDestinationLocator == NULL ); mDestinationLocator = p3d::find( mDestinationLocatorName ); rAssert( mDestinationLocator != NULL ); //mDestinationLocator->AddRef(); mDestinationLocator->SetFlag( Locator::ACTIVE, true ); //mDestinationLocator->SetFlag( Locator::DRAWN, true ); EventLocator* eventLocator = dynamic_cast( mDestinationLocator ); if( eventLocator != NULL ) { GetEventManager()->AddListener( this, (EventEnum)(EVENT_LOCATOR + eventLocator->GetEventType())); } if ( mActionTrigger ) { //Swap the settings of the event locator to make it go through the action button //handing system. mOldEvent = eventLocator->GetEventType(); eventLocator->SetEventType( LocatorEvent::GENERIC_BUTTON_HANDLER_EVENT ); ActionButton::GenericEventButtonHandler* pABHandler = dynamic_cast( ActionButton::GenericEventButtonHandler::NewAction( eventLocator, (EventEnum)(EVENT_LOCATOR + mOldEvent), gma ) ); rAssert( pABHandler ); pABHandler->SetEventData( static_cast(eventLocator) ); int id = 0; bool bResult = GetActionButtonManager()->AddAction( pABHandler, id ); rAssert( bResult ); mOldData = eventLocator->GetData(); eventLocator->SetData( id ); } if( strcmp( mDestinationDrawableName, "" ) != 0 ) { rmt::Vector pos; mDestinationLocator->GetLocation( &pos ); mAnimatedIcon = new AnimatedIcon(); mAnimatedIcon->Init( mDestinationDrawableName, pos ); SphereTriggerVolume* sphTrig = dynamic_cast(eventLocator->GetTriggerVolume(0)); //rAssertMsg( sphTrig != NULL, "GOTO objectives should only use sphere triggers." ); if ( sphTrig ) { if ( mScaleFactor != 0.0f ) { sphTrig->SetSphereRadius( mScaleFactor ); } } //Only put up an icon in the HUD if there is a drawable in the world. RegisterLocator( mDestinationLocator, mHudMapIconID, true, HudMapIcon::ICON_MISSION ); //Alert the walkercam that there is a drawable. WalkerCam* wc = static_cast(GetSuperCamManager()->GetSCC( 0 )->GetSuperCam( SuperCam::WALKER_CAM )); if ( wc ) { wc->SetCollectibleLocation( mAnimatedIcon ); } } else { // mDestinationLocator->SetFlag( Locator::DRAWN, true ); } if ( strcmp( mEffectName, "" ) != 0 && strcmp( mEffectName, "none" ) != 0 ) { mCollectEffect = new AnimatedIcon(); mCollectEffect->Init( mEffectName, rmt::Vector( 0.0f, 0.0f, 0.0f ), false, true ); } mWaitingForEffect = false; rmt::Vector targetPosn; mDestinationLocator->GetLocation(&targetPosn); LightPath( targetPosn, mArrowPath ); // if the goto objective is near the entrance of our current interior, // lets assume that we don't need to do it if(GetInteriorManager()->IsInside()) { Locator* entrance = p3d::find(GetInteriorManager()->GetInterior()); if(entrance) { rmt::Vector e, d, dist; entrance->GetLocation(&e); mDestinationLocator->GetLocation(&d); dist.Sub(d,e); if(dist.Magnitude() < 20.0f) { SetFinished( true ); // don't wan't to show stage complete for doing nothing GetGameplayManager()->GetCurrentMission()->GetCurrentStage()->ShowStageComplete(false); } } } MEMTRACK_POP_GROUP("Mission - GoToObjective"); } //============================================================================= // GoToObjective::OnFinalize //============================================================================= // Description: Comment // // Parameters: () // // Return: void // //============================================================================= void GoToObjective::OnFinalize() { // // Disable the controller // GetInputManager()->SetGameState( Input::ACTIVE_GAMEPLAY ); rAssert( mDestinationLocator != NULL ); mDestinationLocator->SetFlag( Locator::ACTIVE, false ); EventLocator* eventLocator = dynamic_cast( mDestinationLocator ); if( eventLocator != NULL ) { GetEventManager()->RemoveListener( this, (EventEnum)(EVENT_LOCATOR + eventLocator->GetEventType())); //This is to make sure that the exit volume triggers to kill characters hanging on //to action button handlers. Semi-hack unsigned int i; for ( i = 0; i < eventLocator->GetNumTriggers(); ++i ) { GetTriggerVolumeTracker()->RemoveTrigger( eventLocator->GetTriggerVolume( i ) ); GetTriggerVolumeTracker()->AddTrigger( eventLocator->GetTriggerVolume( i ) ); } } //Redundant if the old data is -1 if ( mActionTrigger && mOldData != -1 ) { int id = eventLocator->GetData(); GetActionButtonManager()->RemoveActionByIndex( id ); eventLocator->SetData( mOldData ); eventLocator->SetEventType( mOldEvent ); //reset the old data mOldData = -1; } //mDestinationLocator->Release(); mDestinationLocator = NULL; if ( mAnimatedIcon ) { delete mAnimatedIcon; mAnimatedIcon = NULL; UnregisterLocator( mHudMapIconID ); //Alert the walkercam that there is a drawable. WalkerCam* wc = static_cast(GetSuperCamManager()->GetSCC( 0 )->GetSuperCam( SuperCam::WALKER_CAM )); if ( wc ) { wc->SetCollectibleLocation( NULL ); } } if ( mCollectEffect ) { delete mCollectEffect; mCollectEffect = NULL; } UnlightPath( mArrowPath.mPathRoute ); } //============================================================================= // GoToObjective::OnUpdate //============================================================================= // Description: Comment // // Parameters: ( unsigned int elapsedTime ) // // Return: void // //============================================================================= void GoToObjective::OnUpdate( unsigned int elapsedTime ) { if ( mAnimatedIcon ) { mAnimatedIcon->Update( elapsedTime ); } if ( mCollectEffect ) { mCollectEffect->Update( elapsedTime ); } //This is so that we can see the effect finish before we blow it away. if ( mWaitingForEffect ) { if ( !mCollectEffect->IsRendering() ) { //The effect is finished rendering. SetFinished( true ); } } UpdateLightPath(mArrowPath); //Hard-code a test to see if we're already in the volume. This will correct if //We're starting a mission inside it. if ( !GetFinished() && mDestinationLocator && !mActionTrigger ) { unsigned int i; for ( i = 0; i < mDestinationLocator->GetNumTriggers(); ++i ) { if ( reinterpret_cast(mDestinationLocator)->GetTriggerVolume( i )->IsPlayerTracking( 0 ) ) { SetFinished( true ); } } } } //============================================================================= // GoToObjective::HandleEvent //============================================================================= // Description: Comment // // Parameters: ( EventEnum id, void* pEventData ) // // Return: void // //============================================================================= void GoToObjective::HandleEvent( EventEnum id, void* pEventData ) { switch( id ) { case EVENT_LOCATOR + LocatorEvent::CHECK_POINT: { Locator* locator = static_cast( pEventData ); if( locator == mDestinationLocator && !mWaitingForEffect ) { if ( mActionTrigger && mOldData != -1 ) { //This is a hack for if the Effect takes too long, we need //to get rid of the frickin' button in the screen int id = locator->GetData(); GetCharacterManager()->GetCharacter( 0 )->RemoveActionButtonHandler( GetActionButtonManager()->GetActionByIndex( id ) ); } if( mGotoDialogOn ) { GetEventManager()->TriggerEvent( EVENT_DESTINATION_REACHED ); } if ( IsFinished() == false ) { // // Disable the controller // GetInputManager()->SetGameState( Input::ACTIVE_NONE ); if ( mAnimatedIcon ) { //Put the collection effect here and hit start. rmt::Vector pos; locator->GetLocation( &pos ); if ( mCollectEffect ) { mCollectEffect->Reset(); mCollectEffect->Move( pos ); mCollectEffect->ShouldRender( true ); mWaitingForEffect = true; } else if ( strcmp( mEffectName, "none" ) != 0 ) { //Only show the effect if there is a drawable. if ( strcmp( mDestinationDrawableName, "" ) != 0 ) { //USe the default one from the mission manager GetMissionManager()->PutEffectHere( pos ); } } //Also, get rid of the old one. mAnimatedIcon->ShouldRender( false ); } } if ( !mWaitingForEffect ) { SetFinished( true ); } } break; } default: { // this isn't a "real" event listener so it may get events // it doesn't care about break; } } } //============================================================================= // GoToObjective::SetDestinationLocatorName //============================================================================= // Description: Comment // // Parameters: ( char* locatorname, char* p3dname, float scale ) // // Return: void // //============================================================================= void GoToObjective::SetDestinationNames( char* locatorname, char* p3dname, float scale ) { strcpy( mDestinationLocatorName, locatorname ); strcpy( mDestinationDrawableName, p3dname ); mScaleFactor = scale; } //============================================================================= // GoToObjective::SetCollectEffectName //============================================================================= // Description: Comment // // Parameters: ( char* name ) // // Return: void // //============================================================================= void GoToObjective::SetCollectEffectName( char* name ) { rAssert( name ); strcpy( mEffectName, name ); } //****************************************************************************** // // Private Member Functions // //******************************************************************************