mirror of
https://github.com/UberGames/EF2GameSource.git
synced 2024-11-10 06:31:42 +00:00
282 lines
5.7 KiB
C++
282 lines
5.7 KiB
C++
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// $Logfile:: /EF2/Code/DLLs/game/mover.cpp $
|
||
|
// $Revision:: 11 $
|
||
|
// $Author:: Singlis $
|
||
|
// $Date:: 9/26/03 2:36p $
|
||
|
//
|
||
|
// Copyright (C) 1997 by Ritual Entertainment, Inc.
|
||
|
// All rights reserved.
|
||
|
//
|
||
|
// This source is may not be distributed and/or modified without
|
||
|
// expressly written permission by Ritual Entertainment, Inc.
|
||
|
//
|
||
|
//
|
||
|
// DESCRIPTION:
|
||
|
// Base class for any object that needs to move to specific locations over a
|
||
|
// period of time. This class is kept separate from most entities to keep
|
||
|
// class size down for objects that don't need such behavior.
|
||
|
//
|
||
|
|
||
|
#include "_pch_cpp.h"
|
||
|
#include "entity.h"
|
||
|
#include "trigger.h"
|
||
|
#include "mover.h"
|
||
|
|
||
|
CLASS_DECLARATION( Listener, Mover, "mover" )
|
||
|
{
|
||
|
{ &EV_MoveDone, &Mover::MoveDone },
|
||
|
|
||
|
{ NULL, NULL }
|
||
|
};
|
||
|
|
||
|
|
||
|
Mover::Mover()
|
||
|
{
|
||
|
// Should always use other constructor
|
||
|
|
||
|
assert( 0 );
|
||
|
}
|
||
|
|
||
|
Mover::Mover( Entity *ent )
|
||
|
{
|
||
|
self = ent;
|
||
|
|
||
|
self->edict->s.pos.trType = TR_LERP;
|
||
|
endevent = NULL;
|
||
|
finaldest = ent->origin;
|
||
|
}
|
||
|
|
||
|
Mover::~Mover()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void Mover::MoveDone( Event *ev )
|
||
|
{
|
||
|
Event * event;
|
||
|
Vector move;
|
||
|
Vector amove;
|
||
|
|
||
|
// zero out the movement
|
||
|
if ( moveflags & MOVE_ANGLES )
|
||
|
{
|
||
|
self->avelocity = vec_zero;
|
||
|
amove = angledest - self->localangles;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
amove = vec_zero;
|
||
|
}
|
||
|
|
||
|
if ( moveflags & MOVE_ORIGIN )
|
||
|
{
|
||
|
self->velocity = vec_zero;
|
||
|
move = finaldest - self->GetLocalOrigin();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
move = vec_zero;
|
||
|
}
|
||
|
|
||
|
if ( !G_PushMove( self, move, amove ) )
|
||
|
{
|
||
|
// Delay finish till we can move into the final position
|
||
|
PostEvent( EV_MoveDone, FRAMETIME );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// After moving, set origin to exact final destination
|
||
|
//
|
||
|
if ( moveflags & MOVE_ORIGIN )
|
||
|
{
|
||
|
self->setOrigin( finaldest );
|
||
|
}
|
||
|
|
||
|
if ( moveflags & MOVE_ANGLES )
|
||
|
{
|
||
|
self->localangles = angledest;
|
||
|
|
||
|
if ( ( self->localangles.x >= 360.0f ) || ( self->localangles.x < 0.0f ) )
|
||
|
{
|
||
|
self->localangles.x -= (float)( ( (int)self->localangles.x / 360 ) * 360 );
|
||
|
}
|
||
|
if ( ( self->localangles.y >= 360.0f ) || ( self->localangles.y < 0.0f ) )
|
||
|
{
|
||
|
self->localangles.y -= (float)( ( (int)self->localangles.y / 360 ) * 360 );
|
||
|
}
|
||
|
if ( ( self->localangles.z >= 360.0f ) || ( self->localangles.z < 0.0f ) )
|
||
|
{
|
||
|
self->localangles.z -= (float)( ( (int)self->localangles.z / 360 ) * 360 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
event = endevent;
|
||
|
endevent = NULL;
|
||
|
self->ProcessEvent( event );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============
|
||
|
MoveTo
|
||
|
|
||
|
calculate self.velocity and self.nextthink to reach dest from
|
||
|
self.origin traveling at speed
|
||
|
===============
|
||
|
*/
|
||
|
void Mover::MoveTo( const Vector &tdest, const Vector &angdest, float tspeed, Event &event )
|
||
|
{
|
||
|
Vector vdestdelta;
|
||
|
Vector angdestdelta;
|
||
|
float len;
|
||
|
float traveltime;
|
||
|
|
||
|
assert( tspeed >= 0.0f );
|
||
|
|
||
|
if ( !tspeed )
|
||
|
{
|
||
|
error( "MoveTo", "No speed is defined!" );
|
||
|
}
|
||
|
|
||
|
if ( tspeed < 0.0f )
|
||
|
{
|
||
|
error( "MoveTo", "Speed is negative!" );
|
||
|
}
|
||
|
|
||
|
// Cancel previous moves
|
||
|
CancelEventsOfType( EV_MoveDone );
|
||
|
|
||
|
moveflags = 0;
|
||
|
|
||
|
if ( endevent )
|
||
|
{
|
||
|
delete endevent;
|
||
|
}
|
||
|
endevent = new Event( event );
|
||
|
|
||
|
finaldest = tdest;
|
||
|
angledest = angdest;
|
||
|
|
||
|
if ( finaldest != self->GetLocalOrigin() )
|
||
|
{
|
||
|
moveflags |= MOVE_ORIGIN;
|
||
|
}
|
||
|
if ( angledest != self->localangles )
|
||
|
{
|
||
|
moveflags |= MOVE_ANGLES;
|
||
|
}
|
||
|
|
||
|
if ( !moveflags )
|
||
|
{
|
||
|
// stop the object from moving
|
||
|
self->velocity = vec_zero;
|
||
|
self->avelocity = vec_zero;
|
||
|
|
||
|
// post the event so we don't wait forever
|
||
|
PostEvent( EV_MoveDone, FRAMETIME );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// set destdelta to the vector needed to move
|
||
|
vdestdelta = tdest - self->GetLocalOrigin();
|
||
|
angdestdelta = angdest - self->localangles;
|
||
|
|
||
|
if ( tdest == self->GetLocalOrigin() )
|
||
|
{
|
||
|
// calculate length of vector based on angles
|
||
|
len = angdestdelta.length();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// calculate length of vector based on distance
|
||
|
len = vdestdelta.length();
|
||
|
}
|
||
|
|
||
|
// divide by speed to get time to reach dest
|
||
|
traveltime = len / tspeed;
|
||
|
|
||
|
// Quantize to FRAMETIME
|
||
|
// E3 HACK
|
||
|
// traveltime *= ( 1 / FRAMETIME );
|
||
|
// traveltime = ( float )( (int)traveltime ) * FRAMETIME;
|
||
|
if ( traveltime < FRAMETIME )
|
||
|
{
|
||
|
traveltime = FRAMETIME;
|
||
|
vdestdelta = vec_zero;
|
||
|
angdestdelta = vec_zero;
|
||
|
}
|
||
|
|
||
|
// scale the destdelta vector by the time spent traveling to get velocity
|
||
|
if ( moveflags & MOVE_ORIGIN )
|
||
|
{
|
||
|
self->velocity = vdestdelta * ( 1.0f / traveltime );
|
||
|
}
|
||
|
|
||
|
if ( moveflags & MOVE_ANGLES )
|
||
|
{
|
||
|
self->avelocity = angdestdelta * ( 1.0f / traveltime );
|
||
|
}
|
||
|
|
||
|
PostEvent( EV_MoveDone, traveltime );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=============
|
||
|
LinearInterpolate
|
||
|
===============
|
||
|
*/
|
||
|
void Mover::LinearInterpolate( const Vector &tdest, const Vector &angdest, float time, Event &event )
|
||
|
{
|
||
|
Vector vdestdelta;
|
||
|
Vector angdestdelta;
|
||
|
float t;
|
||
|
|
||
|
if ( endevent )
|
||
|
{
|
||
|
delete endevent;
|
||
|
}
|
||
|
endevent = new Event( event );
|
||
|
finaldest = tdest;
|
||
|
angledest = angdest;
|
||
|
|
||
|
// Cancel previous moves
|
||
|
CancelEventsOfType( EV_MoveDone );
|
||
|
|
||
|
// Quantize to FRAMETIME
|
||
|
//E3 HACK
|
||
|
// time *= ( 1 / FRAMETIME );
|
||
|
// time = ( float )( (int)time ) * FRAMETIME;
|
||
|
if ( time < FRAMETIME )
|
||
|
{
|
||
|
time = FRAMETIME;
|
||
|
}
|
||
|
|
||
|
moveflags = 0;
|
||
|
t = 1.0f / time;
|
||
|
// scale the destdelta vector by the time spent traveling to get velocity
|
||
|
if ( finaldest != self->GetLocalOrigin() )
|
||
|
{
|
||
|
vdestdelta = tdest - self->GetLocalOrigin();
|
||
|
self->velocity = vdestdelta * t;
|
||
|
moveflags |= MOVE_ORIGIN;
|
||
|
}
|
||
|
|
||
|
if ( angledest != self->localangles )
|
||
|
{
|
||
|
angdestdelta = angdest - self->localangles;
|
||
|
self->avelocity = angdestdelta * t;
|
||
|
moveflags |= MOVE_ANGLES;
|
||
|
}
|
||
|
|
||
|
PostEvent( EV_MoveDone, time );
|
||
|
}
|
||
|
|
||
|
void Mover::SetEndEvent( const int endEvent )
|
||
|
{
|
||
|
if ( endevent )
|
||
|
{
|
||
|
delete endevent;
|
||
|
}
|
||
|
endevent = new Event( endEvent );
|
||
|
}
|