etqw-sdk/source/game/roles/WayPointManager.cpp

575 lines
12 KiB
C++
Raw Normal View History

2008-05-29 00:00:00 +00:00
// Copyright (C) 2007 Id Software, Inc.
//
#include "../precompiled.h"
#pragma hdrstop
#if defined( _DEBUG ) && !defined( ID_REDIRECT_NEWDELETE )
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "WayPointManager.h"
#include "../misc/WorldToScreen.h"
#include "../Player.h"
#include "../script/Script_Helper.h"
#include "../script/Script_ScriptObject.h"
/*
===============================================================================
sdWayPoint
===============================================================================
*/
/*
================
sdWayPoint::sdWayPoint
================
*/
sdWayPoint::sdWayPoint( void ) {
_activeNode.SetOwner( this );
Clear();
}
/*
================
sdWayPoint::Clear
================
*/
void sdWayPoint::Clear( void ) {
_flags = 0;
_activeTime = 0;
_highlightActiveTime = 0;
_fixedBounds.GetMins() = idVec3( -8.f, -8.f, -8.f );
_fixedBounds.GetMaxs() = idVec3( 8.f, 8.f, 8.f );
_text = L"";
_fixedLocation = vec3_origin;
_iconOffset = vec3_origin;
_material = NULL;
_offScreenMaterial = NULL;
_owner = NULL;
_range = 1024.f;
_shouldCheckLineOfSight = true;
_isVisible = true;
_selected = -1;
_flashEndTime = -1;
_activeNode.Remove();
sdWayPointManager::GetInstance().RemoveWayPoint( this );
}
/*
================
sdWayPoint::Init
================
*/
void sdWayPoint::Init( void ) {
}
/*
================
sdWayPoint::Update
================
*/
void sdWayPoint::Update( void ) {
idPlayer* viewPlayer = gameLocal.GetLocalViewPlayer();
_isVisible = true;
}
/*
================
sdWayPoint::GetBounds
================
*/
const idBounds& sdWayPoint::GetBounds( void ) const {
static idBounds emptyBounds = idBounds( vec3_zero );
if ( _flags & WF_FIXEDSIZE ) {
return _fixedBounds;
}
if ( _owner.IsValid() ) {
if ( _flags & WF_RENDERMODEL ) {
return _owner->GetRenderEntity()->bounds;
}
return _owner->GetWayPointBounds();
}
return emptyBounds;
}
/*
================
sdWayPoint::GetPosition
================
*/
const idVec3 sdWayPoint::GetPosition( void ) const {
if ( _flags & WF_FIXEDPOSITION ) {
return _fixedLocation + _iconOffset;
}
// ao: avoid prediction jerkiness
if ( _owner->GetRenderEntity() != NULL ) {
return _owner->GetLastPushedOrigin() + _iconOffset;
}
return _owner->GetWayPointOrigin() + _iconOffset;
}
/*
================
sdWayPoint::GetBracketPosition
================
*/
const idVec3 sdWayPoint::GetBracketPosition( void ) const {
if ( _flags & WF_FIXEDPOSITION ) {
return _fixedLocation;
}
// ao: avoid prediction jerkiness
if ( _owner->GetRenderEntity() != NULL ) {
return _owner->GetLastPushedOrigin();
}
return _owner->GetWayPointOrigin();
}
/*
================
sdWayPoint::GetOrientation
================
*/
const idMat3& sdWayPoint::GetOrientation( void ) const {
if ( _flags & WF_FIXEDPOSITION ) {
return mat3_identity;
}
// ao: avoid prediction jerkiness
const renderEntity_t* rEnt = _owner->GetRenderEntity();
if ( rEnt != NULL ) {
return rEnt->axis;
}
return _owner->GetWayPointAxis();
}
/*
================
sdWayPoint::SetBounds
================
*/
void sdWayPoint::SetBounds( const idBounds& bounds ) {
_fixedBounds = bounds;
_flags |= WF_FIXEDSIZE;
}
/*
================
sdWayPoint::SetOrigin
================
*/
void sdWayPoint::SetOrigin( const idVec3& org ) {
_fixedLocation = org;
_flags |= WF_FIXEDPOSITION;
}
/*
================
sdWayPoint::SetIconOffset
================
*/
void sdWayPoint::SetIconOffset( const idVec3& offset ) {
_iconOffset = offset;
}
/*
================
sdWayPoint::SetOwner
================
*/
void sdWayPoint::SetOwner( idEntity* owner ) {
_owner = owner;
if ( owner == NULL ) {
gameLocal.Warning( "sdWayPoint::SetOwner NULL owner" );
return;
}
idVec3 offset = owner->spawnArgs.GetVector( "waypoint_offset", "0 0 64" );
SetIconOffset( offset );
}
/*
================
sdWayPoint::GetActiveFraction
================
*/
float sdWayPoint::GetActiveFraction( void ) const {
if ( IsActive() ) {
if ( gameLocal.time > _activeTime ) {
return 1.f;
}
return 1.f - ( ( _activeTime - gameLocal.time ) / ( float )ACTIVATE_TIME );
}
int timeSince = gameLocal.time - _activeTime;
if ( timeSince > ACTIVATE_TIME ) {
return 0.f;
}
return 1.f - ( ( timeSince ) / ( float )ACTIVATE_TIME );
}
/*
================
sdWayPoint::MakeActive
================
*/
void sdWayPoint::MakeActive( void ) {
float active = GetActiveFraction();
_activeTime = gameLocal.time + ( ( 1.f - active ) * ACTIVATE_TIME );
_flags |= WF_ACTIVE;
}
/*
================
sdWayPoint::MakeInActive
================
*/
void sdWayPoint::MakeInActive( void ) {
float active = GetActiveFraction();
_activeTime = gameLocal.time - ( ( 1.f - active ) * ACTIVATE_TIME );
_flags &= ~WF_ACTIVE;
}
/*
================
sdWayPoint::GetHighLightActiveFraction
================
*/
float sdWayPoint::GetHighLightActiveFraction( void ) const {
if ( IsHighlightActive() ) {
if ( gameLocal.time > _highlightActiveTime ) {
return 1.f;
}
return 1.f - ( ( _highlightActiveTime - gameLocal.time ) / ( float )ACTIVATE_TIME );
}
int timeSince = gameLocal.time - _highlightActiveTime;
if ( timeSince > ACTIVATE_TIME ) {
return 0.f;
}
return 1.f - ( ( timeSince ) / ( float )ACTIVATE_TIME );
}
/*
================
sdWayPoint::MakeHighlightActive
================
*/
void sdWayPoint::MakeHighlightActive( void ) {
float active = GetHighLightActiveFraction();
_highlightActiveTime = gameLocal.time + ( ( 1.f - active ) * ACTIVATE_TIME );
_flags |= WF_HIGHLIGHTACTIVE;
}
/*
================
sdWayPoint::MakeHighlightInActive
================
*/
void sdWayPoint::MakeHighlightInActive( void ) {
float active = GetHighLightActiveFraction();
_highlightActiveTime = gameLocal.time - ( ( 1.f - active ) * ACTIVATE_TIME );
_flags &= ~WF_HIGHLIGHTACTIVE;
}
/*
================
sdWayPoint::Event_Free
================
*/
void sdWayPoint::Event_Free( void ) {
sdWayPointManager::GetInstance().FreeWayPoint( this );
}
/*
================
sdWayPoint::Event_SetBounds
================
*/
void sdWayPoint::Event_SetBounds( const idVec3& mins, const idVec3& maxs ) {
SetBounds( idBounds( mins, maxs ) );
}
/*
================
sdWayPoint::Event_SetOrigin
================
*/
void sdWayPoint::Event_SetOrigin( const idVec3& org ) {
SetOrigin( org );
}
/*
================
sdWayPoint::Event_SetOwner
================
*/
void sdWayPoint::Event_SetOwner( idEntity* owner ) {
if ( !owner ) {
gameLocal.Error( "sdWayPoint::Event_SetOwner Cannot Take a NULL entity" );
}
SetOwner( owner );
}
/*
================
sdWayPoint::SetRange
================
*/
void sdWayPoint::SetRange( float range ) {
_range = range;
}
/*
================
sdWayPoint::SetMaterial
================
*/
void sdWayPoint::SetMaterial( const idMaterial* material ) {
_material = material;
}
/*
================
sdWayPoint::SetOffScreenMaterial
================
*/
void sdWayPoint::SetOffScreenMaterial( const idMaterial* material ) {
_offScreenMaterial = material;
}
/*
================
sdWayPoint::UseRenderModel
================
*/
void sdWayPoint::UseRenderModel( void ) {
_flags |= WF_RENDERMODEL;
}
/*
================
sdWayPoint::SetBracketed
================
*/
void sdWayPoint::SetBracketed( bool bracketed ) {
if ( bracketed ) {
_flags |= WF_BRACKETED;
} else {
_flags &= ~WF_BRACKETED;
}
}
/*
===============================================================================
sdWayPointManagerLocal
===============================================================================
*/
/*
================
sdWayPointManagerLocal::sdWayPointManagerLocal
================
*/
sdWayPointManagerLocal::sdWayPointManagerLocal( void ) {
_forceShowWayPoints = false;
}
/*
================
sdWayPointManagerLocal::~sdWayPointManagerLocal
================
*/
sdWayPointManagerLocal::~sdWayPointManagerLocal( void ) {
}
/*
================
sdWayPointManagerLocal::AllocWayPoint
================
*/
sdWayPoint* sdWayPointManagerLocal::AllocWayPoint( void ) {
if ( networkSystem->IsDedicated() ) {
return NULL;
}
sdWayPoint* wayPoint = _allocator.Alloc();
AddWayPoint( wayPoint );
wayPoint->Init();
return wayPoint;
}
/*
================
sdWayPointManagerLocal::Think
================
*/
void sdWayPointManagerLocal::Think( void ) {
UpdateActive();
UpdateWayPoints();
}
/*
================
sdWayPointManagerLocal::Think
================
*/
void sdWayPointManagerLocal::UpdateActive( void ) {
if ( ( gameLocal.time - _lastActiveUpdate ) < SEC2MS( 0.25f ) ) {
return;
}
_lastActiveUpdate = gameLocal.time;
idPlayer* viewPlayer = gameLocal.GetLocalViewPlayer();
if ( !viewPlayer ) {
return;
}
renderView_t& view = viewPlayer->renderView;
int worldZoneIndex = gameLocal.GetWorldPlayZoneIndex( view.vieworg );
for ( int i = 0; i < _wayPoints.Num(); i++ ) {
sdWayPoint* wayPoint = _wayPoints[ i ];
bool shouldBeActive = true;
do {
if ( !wayPoint->IsValid() ) {
shouldBeActive = false;
break;
}
if ( !wayPoint->IsAlwaysActive() ) {
if ( ( wayPoint->GetPosition() - view.vieworg ).LengthSqr() > Square( wayPoint->GetRange() ) ) {
shouldBeActive = false;
break;
}
}
if ( gameLocal.GetWorldPlayZoneIndex( wayPoint->GetPosition() ) != worldZoneIndex ) {
shouldBeActive = false;
break;
}
} while ( false );
if ( shouldBeActive ) {
if ( !wayPoint->IsActive() ) {
wayPoint->MakeActive();
wayPoint->GetActiveNode().AddToEnd( _activeWayPoints );
}
} else {
if ( wayPoint->IsActive() ) {
wayPoint->MakeInActive();
}
if ( wayPoint->GetActiveFraction() <= 0.f ) {
wayPoint->GetActiveNode().Remove();
}
}
}
}
/*
================
sdWayPointManagerLocal::UpdateWayPoints
================
*/
void sdWayPointManagerLocal::UpdateWayPoints( void ) {
if ( _wayPoints.Num() == 0 ) {
return;
}
// update 2
int firstUpdateIndex = ( _lastUpdatedWayPointIndex + 1 ) % _wayPoints.Num();
int numUpdated = 0;
sdWayPoint* firstUpdated = NULL;
for ( int i = firstUpdateIndex; numUpdated < 2; i = ( i + 1 ) % _wayPoints.Num(), numUpdated++ ) {
sdWayPoint* wayPoint = _wayPoints[ i ];
if ( firstUpdated == NULL ) {
firstUpdated = wayPoint;
} else if ( numUpdated > 0 && firstUpdated == wayPoint ) {
// got back around to the first one
break;
}
wayPoint->Update();
_lastUpdatedWayPointIndex = i;
if ( _wayPoints.Num() == 0 ) {
break;
}
int newI = i % _wayPoints.Num();
sdWayPoint* newWayPoint = _wayPoints[ newI ];
if ( newWayPoint != wayPoint && newI == i ) {
// hit this index again - it has changed!
i--;
}
}
}
/*
================
sdWayPointManagerLocal::Init
================
*/
void sdWayPointManagerLocal::Init( void ) {
_lastActiveUpdate = 0;
_lastUpdatedWayPointIndex = -1;
while ( _wayPoints.Num() > 0 ) {
FreeWayPoint( _wayPoints[ 0 ] );
}
}
/*
================
sdWayPointManagerLocal::FreeWayPoint
================
*/
void sdWayPointManagerLocal::FreeWayPoint( sdWayPoint* wayPoint ) {
wayPoint->Clear();
_allocator.Free( wayPoint );
}
/*
================
sdWayPointManagerLocal::AddWayPoint
================
*/
void sdWayPointManagerLocal::AddWayPoint( sdWayPoint* way ) {
assert( _wayPoints.FindElement( way ) == NULL );
_wayPoints.Append( way );
}
/*
================
sdWayPointManagerLocal::RemoveWayPoint
================
*/
void sdWayPointManagerLocal::RemoveWayPoint( sdWayPoint* way ) {
_wayPoints.RemoveFast( way );
}