openmohaa/code/cgame_hook/script/earthquake.cpp

233 lines
3.9 KiB
C++
Raw Normal View History

2016-03-27 11:49:47 +02:00
/*
* Earthquake.cpp
*
* DESCRIPTION : Client-side realistic earthquake and network optimizer
*/
#include "earthquake.h"
#include "archive.h"
Event EV_Earthquake_Think
(
"eq_think",
EV_CODEONLY,
NULL,
NULL,
"Internal event",
EV_NORMAL
);
Container< Earthquake * > earthquakes;
Earthquake::Earthquake()
{
_duration = 1.0f;
_magnitude = 0.7f;
_no_rampup = false;
_no_rampdown = false;
_location = Vector( 0, 0, 0 );
_radius = 1000.0f;
active = false;
earthquakes.AddObject( this );
}
Earthquake::Earthquake( float duration, float magnitude, qboolean no_rampup, qboolean no_rampdown, Vector location, float radius )
{
SetDuration( duration );
SetMagnitude( magnitude );
SetNoRampup( no_rampup );
SetNoRampdown( no_rampdown );
SetLocation( location );
SetRadius( radius );
active = false;
earthquakes.AddObject( this );
}
Earthquake::~Earthquake()
{
Disable();
earthquakes.RemoveObject( this );
}
void Earthquake::Archive( Archiver &arc )
{
SimpleEntity::Archive( arc );
arc.ArchiveFloat( &_duration );
arc.ArchiveFloat( &_magnitude );
arc.ArchiveBoolean( &_no_rampup );
arc.ArchiveBoolean( &_no_rampdown );
arc.ArchiveVector( &_location );
arc.ArchiveFloat( &_radius );
arc.ArchiveFloat( &_currentMagnitude );
arc.ArchiveFloat( &_currentTime );
arc.ArchiveBoolean( &active );
if( arc.Loading() ) {
_startTime = cg->time - _currentTime;
}
}
float Earthquake::getMagnitude()
{
return _currentMagnitude;
}
Vector Earthquake::getLocation()
{
return _location;
}
float Earthquake::getRadius()
{
return _radius;
}
qboolean Earthquake::hasLocation()
{
return _location != Vector( 0, 0, 0 );
}
void Earthquake::SetDuration( float duration )
{
_duration = duration * 1000.0f;
}
void Earthquake::SetMagnitude( float magnitude )
{
_magnitude = magnitude;
}
void Earthquake::SetNoRampup( qboolean no_rampup )
{
_no_rampup = no_rampup;
}
void Earthquake::SetNoRampdown( qboolean no_rampdown )
{
_no_rampdown = no_rampdown;
}
void Earthquake::SetLocation( Vector origin )
{
_location = origin;
}
void Earthquake::SetRadius( float radius )
{
_radius = radius;
}
void Earthquake::Enable( void )
{
if ( _duration > 0.0f )
{
_startTime = ( float )cg->time;
_currentMagnitude = _magnitude;
_currentTime = 0.0f;
active = true;
ProcessScriptEvent( EV_Earthquake_Think );
}
}
void Earthquake::Disable( void )
{
active = false;
_startTime = 0.0f;
_currentMagnitude = 0.0f;
_currentTime = 0.0f;
CancelEventsOfType( EV_Earthquake_Think );
}
qboolean Earthquake::isActive( void )
{
return active;
}
void Earthquake::Think( Event *ev )
{
float timeDelta;
if( !active )
{
CancelEventsOfType( EV_Earthquake_Think );
return;
}
// Disable the earthquake if the time reached the maximum duration
if( _currentTime >= _duration )
{
delete this;
return;
}
_currentTime += cg->frametime;
timeDelta = cgi.Milliseconds() - _startTime;
// we are in the first half of the earthquake
if ( timeDelta < ( _duration * 0.5f ) )
{
if ( !_no_rampup )
{
float rampUpTime;
rampUpTime = _startTime + ( _duration * 0.33f );
if ( cg->time < rampUpTime )
{
float scale;
scale = ( timeDelta ) / ( _duration * 0.33f );
_currentMagnitude = _magnitude * scale;
} else {
_currentMagnitude = _magnitude;
}
}
}
// we are in the second half of the earthquake
else
{
if ( !_no_rampdown )
{
float rampDownTime;
rampDownTime = _startTime + ( _duration * 0.66f );
if ( cg->time > rampDownTime )
{
float scale;
scale = 1.0f - ( ( cg->time - rampDownTime ) / ( _duration * 0.33f ) );
_currentMagnitude = _magnitude * scale;
} else {
_currentMagnitude = _magnitude;
}
}
}
CancelEventsOfType( EV_Earthquake_Think );
PostEvent( EV_Earthquake_Think, level.frametime );
}
CLASS_DECLARATION( SimpleEntity, Earthquake, NULL )
{
{ &EV_Earthquake_Think, &Earthquake::Think },
{ NULL, NULL },
};