Hard reset

This commit is contained in:
Ley0k 2016-03-27 11:49:47 +02:00
commit 09bed43f97
1594 changed files with 892326 additions and 0 deletions

View file

@ -0,0 +1,156 @@
/*
* CAnimate.cpp
*
* DESCRIPTION : Client animate. Enable entities animations
*/
#include "canimate.h"
#include "clientgamecommand.h"
Event EV_Animate_Anim
(
"anim",
EV_DEFAULT,
"s",
"animName",
"Exec anim commands on client.",
EV_NORMAL
);
Animate::Animate()
{
}
Animate::~Animate()
{
}
void Animate::Archive( Archiver &arc )
{
Entity::Archive( arc );
}
void Animate::Think()
{
int num_playing = 0;
if( !tiki ) {
return Entity::Think();
}
for( int i = 0; i < GetNumFrames(); i++ )
{
float max_time = cgi.Anim_Time( tiki, frame[ i ].index );
if( frame[ i ].time < max_time )
{
frame[ i ].time += cg->frametime;
num_playing++;
}
else
{
frame[ i ].time = max_time;
}
}
// Optimize performances
if( !num_playing && this->classinfo() == Animate::classinfostatic() ) {
turnThinkOff();
}
Entity::Think();
}
void Animate::PlayAnim( const char *name, int index )
{
int num = cgi.Anim_NumForName( tiki, name );
if( num != -1 ) {
PlayAnim( num, index );
}
}
void Animate::PlayAnim( int num, int index )
{
float frametime;
if( index >= MAX_FRAMEINFOS ) {
return;
}
if( index >= numframes )
{
numframes++;
frame = ( frameInfo_t * )realloc( frame, sizeof( frameInfo_t ) * numframes );
}
frame[ index ].index = num;
frame[ index ].time = 0.0f;
frame[ index ].weight = 1.0f;
frametime = cgi.Anim_Frametime( tiki, num );
if( cgi.Anim_HasCommands( tiki, num ) )
{
float time = -frametime;
// Exec anim commands
// They will be executed in the context of the commandManager
for( int i = 0; i < cgi.Anim_NumFrames( tiki, num ); i++ )
{
tiki_cmd_t cmds;
Event *ev;
time += frametime;
if( !cgi.Frame_Commands( tiki, num, i, &cmds ) ) {
continue;
}
for( int k = 0; k < cmds.num_cmds; k++ )
{
cgi.Printf( "args = '%s'\n", cmds.cmds[ k ].args[ 0 ] );
ev = new Event( cmds.cmds[ k ].args[ 0 ] );
for( int c = 1; c < cmds.cmds[ k ].num_args; c++ )
{
const char *argument = cmds.cmds[ k ].args[ c ];
ev->AddString( cmds.cmds[ k ].args[ c ] );
}
commandManager->PostEvent( ev, frametime, 0 );
}
}
}
}
void Animate::SetTime( int index, float time )
{
if( index >= numframes ) {
return;
}
frame[ index ].time = time;
turnThinkOn();
}
//=== SCRIPT ===\\
void Animate::ForwardExec( Event *ev )
{
str name = ev->GetString( 1 );
PlayAnim( name, 0 );
SetTime( 0, 0.0f );
}
CLASS_DECLARATION( Entity, Animate, NULL )
{
{ &EV_Animate_Anim, &Animate::ForwardExec },
{ NULL, NULL },
};

View file

@ -0,0 +1,25 @@
#ifndef __CANIMATE_H__
#define __CANIMATE_H__
#include "centity.h"
class Animate : public Entity
{
public:
CLASS_PROTOTYPE( Animate );
virtual void Archive( Archiver &arc );
Animate();
~Animate();
virtual void Think();
void PlayAnim( const char *name, int index );
void PlayAnim( int num, int index );
void SetTime( int index, float time );
void ForwardExec( Event *ev );
};
#endif /* __CANIMATE_H__ */

View file

@ -0,0 +1,449 @@
/*
* Entity.cpp
*
* DESCRIPTION : Client-side entity
*/
#include "centity.h"
#include "archive.h"
Container< SafePtr< Entity > > s_entities;
Event EV_Entity_Attach
(
"attach",
EV_DEFAULT,
"esIV",
"parent tagname use_angles offset",
"attach this entity to the parent's legs tag called tagname",
EV_NORMAL
);
Event EV_Entity_Detach
(
"detach",
EV_DEFAULT,
NULL,
NULL,
"detach this entity from its parent.",
EV_NORMAL
);
Event EV_Entity_GetModel
(
"model",
EV_DEFAULT,
NULL,
NULL,
"Gets the model.",
EV_RETURN
);
Event EV_Entity_Getter_GetModel
(
"model",
EV_DEFAULT,
NULL,
NULL,
"Gets the model.",
EV_GETTER
);
Event EV_Entity_GetScale
(
"scale",
EV_DEFAULT,
NULL,
NULL,
"Gets the scale.",
EV_GETTER
);
Event EV_Entity_SetModel
(
"model",
EV_DEFAULT,
"s",
"modelName",
"Sets the model to modelName.",
EV_NORMAL
);
Event EV_Entity_SetScale
(
"scale",
EV_DEFAULT,
"f",
"scale",
"Sets the scale.",
EV_SETTER
);
Event EV_Entity_Setter_SetModel
(
"model",
EV_DEFAULT,
"s",
"modelName",
"Sets the model to modelName.",
EV_SETTER
);
Event EV_Entity_SetSize
(
"setsize",
EV_DEFAULT,
"vv",
"mins maxs",
"Set the bounding box of the entity to mins and maxs.",
EV_NORMAL
);
Event EV_Touch
(
"doTouch",
EV_CODEONLY,
"e",
"touchingEntity",
"sent to entity when touched.",
EV_NORMAL
);
Entity * CL_GetCEntity( int ent_num )
{
// Iterate through simple client entities
for( int i = 0; i < s_entities.NumObjects(); i++ )
{
Entity * ent = ( Entity * )s_entities[ i ];
if( !checkInheritance( &Entity::ClassInfo, ent->classinfo() ) ) {
continue;
}
int entnum = ent->GetNumber();
if( entnum != -1 && entnum == ent_num ) {
return ent;
}
}
return NULL;
}
centity_t *CL_GetEntity( int ent_num )
{
entityState_t *ce = NULL;
int i;
for( i = 0; i < cg->activeSnapshots[ 0 ].numEntities; i++ )
{
if( cg->activeSnapshots[ 0 ].entities[ i ].number == ent_num ) {
ce = &cg->activeSnapshots[ 0 ].entities[ i ];
}
}
return ( centity_t * )ce;
}
void CL_ProcessCEntities()
{
// Iterate through client entities
for( int i = s_entities.NumObjects(); i > 0; i-- )
{
Entity *ent = s_entities.ObjectAt( i );
if( !checkInheritance( &Entity::ClassInfo, ent->classinfo() ) ) {
continue;
}
if( ent->CanThink() ) {
ent->Think();
}
}
}
Entity::Entity()
{
cent = &cg_entities[ 0 ];
centity = &cg_entities[ 0 ];
model = "";
modelhandle = 0;
scale = 1.f;
renderFx = 0;
tiki = NULL;
frame = new frameInfo_t[ 1 ];
numframes = 1;
entnum = -1;
frame[ 0 ].index = 0;
frame[ 0 ].time = 0.f;
frame[ 0 ].weight = 1.0f;
//turnThinkOn();
absmin = absmax = mins = maxs = vec_zero;
s_entities.AddObject( this );
}
Entity::~Entity()
{
if( frame ) {
delete[] frame;
}
numframes = 0;
s_entities.RemoveObject( this );
}
bool Entity::IsTouching( Entity *ent )
{
return ent->absmin[ 0 ] <= absmax[ 0 ]
&& ent->absmin[ 1 ] <= absmax[ 1 ]
&& ent->absmin[ 2 ] <= absmax[ 2 ]
&& absmin[ 0 ] <= ent->absmax[ 0 ]
&& absmin[ 1 ] <= ent->absmax[ 1 ]
&& absmin[ 2 ] <= ent->absmax[ 2 ];
}
float Entity::getScale()
{
return scale;
}
qboolean Entity::inRadius( Vector org, float rad )
{
if( Vector::Distance( origin, org ) <= rad ) {
return true;
} else {
return false;
}
}
void Entity::setModel( const char *name )
{
model = name;
modelhandle = cgi.R_RegisterModel( name );
tiki = cgi.R_Model_GetHandle( modelhandle );
}
void Entity::setOrigin( Vector origin )
{
this->origin = origin;
absmin = origin + mins;
absmax = origin + maxs;
}
void Entity::setScale( float s )
{
scale = s;
}
void Entity::Think()
{
}
void Entity::Archive( Archiver &arc )
{
SimpleEntity::Archive( arc );
arc.ArchiveBoolean( &fShader );
if( fShader )
{
arc.ArchiveString( &shader );
if( arc.Loading() ) {
customshader = cgi.R_RegisterShader( shader );
}
}
arc.ArchiveBoolean( &canThink );
arc.ArchiveFloat( &scale );
arc.ArchiveInteger( &entnum );
arc.ArchiveInteger( &renderFx );
arc.ArchiveString( &model );
}
frameInfo_t *Entity::GetFrameInfo( int index )
{
if( index >= numframes ) {
return NULL;
} else {
return &frame[ index ];
}
}
int Entity::GetNumFrames()
{
return numframes;
}
void Entity::GetTag( const char *tagname, orientation_t *orient )
{
refEntity_t ref;
if( tiki == NULL ) {
return;
}
int num = cgi.Tag_NumForName( tiki, tagname );
if( num == -1 ) {
return;
}
memset( &ref, 0, sizeof( refEntity_t ) );
VectorCopy( origin, ref.origin );
MatrixToEulerAngles( ref.axis, angles );
ref.reType = RT_MODEL;
ref.scale = scale;
ref.hModel = modelhandle;
ref.hOldModel = modelhandle;
ref.tiki = tiki;
ref.entityNumber = 0;
ref.actionWeight = 1.0f;
for( int i = 0; i < GetNumFrames(); i++ )
{
frameInfo_t *frame = GetFrameInfo( i );
ref.frameInfo[ i ].index = frame->index;
ref.frameInfo[ i ].time = frame->time;
ref.frameInfo[ i ].weight = frame->weight;
}
//cgi.TIKI_Orientation( orient, &ref, num );
*orient = re.TIKI_Orientation( &ref, num );
}
void Entity::AssignNumber( int ent_num )
{
if( entnum == -1 ) {
entnum = ent_num;
}
}
int Entity::GetNumber()
{
return entnum;
}
qboolean Entity::CanThink()
{
return canThink;
}
void Entity::turnThinkOn()
{
canThink = true;
}
void Entity::turnThinkOff()
{
canThink = false;
}
void Entity::SetShader( const char *name )
{
if( name == NULL )
{
fShader = false;
shader = "";
return;
}
fShader = true;
customshader = cgi.R_RegisterShader( name );
shader = name;
}
//=== SCRIPT ===\\
void Entity::EventAttach( Event *ev )
{
Entity *parent = ev->GetEntity( 1 );
str tagname = ev->GetString( 2 );
int use_angles;
Vector offset;
if( ev->NumArgs() > 2 ) {
use_angles = ev->GetInteger( 3 );
} else {
use_angles = 1;
}
if( ev->NumArgs() > 3 ) {
offset = ev->GetVector( 4 );
} else {
offset = vec_zero;
}
attached = parent;
attached_tagname = tagname;
attached_use_angles = use_angles;
attached_offset = offset;
}
void Entity::EventDetach( Event *ev )
{
attached = NULL;
}
void Entity::EventGetModel( Event *ev )
{
ev->AddString( model );
}
void Entity::EventGetScale( Event *ev )
{
ev->AddFloat( getScale() );
}
void Entity::EventSetScale( Event *ev )
{
setScale( ev->GetFloat( 1 ) );
}
void Entity::EventSetModel( Event *ev )
{
str name = ev->GetString( 1 );
setModel( name );
}
void Entity::EventSetSize( Event *ev )
{
mins = ev->GetVector( 1 );
maxs = ev->GetVector( 2 );
setOrigin( origin );
}
CLASS_DECLARATION( SimpleEntity, Entity, NULL )
{
{ &EV_Entity_Attach, &Entity::EventAttach },
{ &EV_Entity_Detach, &Entity::EventDetach },
{ &EV_Entity_GetModel, &Entity::EventGetModel },
{ &EV_Entity_GetScale, &Entity::EventGetScale },
{ &EV_Entity_Getter_GetModel, &Entity::EventGetModel },
{ &EV_Entity_SetModel, &Entity::EventSetModel },
{ &EV_Entity_SetScale, &Entity::EventSetScale },
{ &EV_Entity_Setter_SetModel, &Entity::EventSetModel },
{ &EV_Entity_SetSize, &Entity::EventSetSize },
{ NULL, NULL }
};

View file

@ -0,0 +1,85 @@
#ifndef __CENTITY_H__
#define __CENTITY_H__
#include "simpleentity.h"
#define MT_PHYSICS (1<<0) // This entity has physics
extern Event EV_Touch;
class Entity : public SimpleEntity {
public:
int entnum;
centity_t *centity;
qboolean fShader;
qhandle_t customshader;
str shader;
str model;
qhandle_t modelhandle;
dtiki_t *tiki;
int renderFx;
float scale;
int moveType;
SafePtr< Entity > attached;
str attached_tagname;
int attached_use_angles;
Vector attached_offset;
Vector absmin, absmax;
Vector mins, maxs;
private:
qboolean canThink;
protected:
frameInfo_t *frame;
int numframes;
public:
CLASS_PROTOTYPE( Entity );
virtual void Archive( Archiver &arc );
Entity();
virtual ~Entity();
frameInfo_t *GetFrameInfo( int index );
int GetNumFrames();
void GetTag( const char *tagname, orientation_t *orient );
virtual void Think();
bool IsTouching( Entity *ent );
float getScale();
qboolean inRadius( Vector org, float rad );
void setModel( const char *name );
virtual void setOrigin( Vector origin );
void setScale( float scale );
void AssignNumber( int ent_num );
qboolean CanThink( void );
int GetNumber( void );
void SetShader( const char *name );
void turnThinkOn( void );
void turnThinkOff( void );
void EventAttach( Event *ev );
void EventDetach( Event *ev );
void EventGetModel( Event *ev );
void EventGetScale( Event *ev );
void EventSetModel( Event *ev );
void EventSetScale( Event *ev );
void EventSetSize( Event *ev );
};
Entity * CL_GetCEntity( int ent_num );
centity_t * CL_GetEntity( int ent_num );
void CL_ProcessCEntities();
extern Container< SafePtr< Entity > > s_entities;
#endif /* __CENTITY_H__ */

View file

@ -0,0 +1,353 @@
/*
* ClientGameCommandManager.cpp
*
* DESCRIPTION : Client Game Command Manager
*/
#include "clientgamecommand.h"
#include "cgame/cl_sound.h"
#include "archive.h"
uintptr_t *sndDriver = ( uintptr_t * )0x7F5D74;
typedef void( __cdecl *AIL_CLOSE_STREAM )( void *stream );
typedef void* ( __cdecl *AIL_OPEN_STREAM )( uintptr_t soundDriver, const char *pFilename, int channel );
typedef void ( __cdecl *AIL_SET_STREAM_LOOP_COUNT )( void *stream, int count );
typedef void( __cdecl *AIL_SET_STREAM_PLAYBACK_RATE )( void *stream, int rate );
typedef void( __cdecl *AIL_SET_STREAM_POSITION )( void *stream, int position );
typedef void( __cdecl *AIL_SET_STREAM_VOLUME )( void *stream, int volume );
typedef void ( __cdecl *AIL_START_STREAM )( void *stream );
typedef int( __cdecl *AIL_STREAM_PLAYBACK_RATE )( void *stream );
typedef int( __cdecl *AIL_STREAM_POSITION )( void *stream );
typedef int ( __cdecl *AIL_STREAM_STATUS )( void *stream );
typedef char * ( __cdecl *GETFILEPATH )( const char *game_path, const char *path, const char *filename );
AIL_CLOSE_STREAM AIL_close_stream = ( AIL_CLOSE_STREAM )0x00486C80;
AIL_OPEN_STREAM AIL_open_stream = ( AIL_OPEN_STREAM )0x00486C20;
AIL_SET_STREAM_LOOP_COUNT AIL_set_stream_loop_count = ( AIL_SET_STREAM_LOOP_COUNT )0x00487030;
AIL_SET_STREAM_PLAYBACK_RATE AIL_set_stream_playback_rate = ( AIL_SET_STREAM_PLAYBACK_RATE )0x00486E70;
AIL_SET_STREAM_POSITION AIL_set_stream_position = ( AIL_SET_STREAM_POSITION )0x00487100;
AIL_SET_STREAM_VOLUME AIL_set_stream_volume = ( AIL_SET_STREAM_VOLUME )0x00486EE0;
AIL_START_STREAM AIL_start_stream = ( AIL_START_STREAM )0x00486DA0;
AIL_STREAM_PLAYBACK_RATE AIL_stream_playback_rate = ( AIL_STREAM_PLAYBACK_RATE )0x00487230;
AIL_STREAM_POSITION AIL_stream_position = ( AIL_STREAM_POSITION )0x004873E0;
AIL_STREAM_STATUS AIL_stream_status = ( AIL_STREAM_STATUS )0x004871E0;
GETFILEPATH GetFilePath = ( GETFILEPATH )0x00450840;
char *gameDir = ( char * )0x00EC4EE0;
Container< LocalSound * > localSounds;
ClientGameCommandManager *commandManager = ( ClientGameCommandManager * )0x30117B90;
ClientSpecialEffectsManager *sfxManager = ( ClientSpecialEffectsManager * )0x3026AB78;
Event EV_LocalSound_Think
(
"localsound_think",
EV_CODEONLY,
NULL,
NULL,
"Internal event",
EV_NORMAL
);
LocalSound::LocalSound( str n, qboolean l )
{
path = GetFilePath( fs_basepath->string, gameDir, n );
stream = AIL_open_stream( *sndDriver, path, 0 );
name = n;
stopping = false;
loop = l;
if( loop ) {
AIL_set_stream_loop_count( stream, 0 );
} else {
AIL_set_stream_loop_count( stream, 1 );
}
volume = 0.0f;
rate = 1.0f;
localSounds.AddObject( this );
}
LocalSound::LocalSound()
{
stream = NULL;
stopping = false;
loop = false;
volume = 0.0f;
rate = 1.0f;
localSounds.AddObject( this );
}
LocalSound::~LocalSound()
{
CancelEventsOfType( &EV_LocalSound_Think );
if( stream ) {
AIL_close_stream( stream );
}
localSounds.RemoveObject( this );
}
void LocalSound::Archive( Archiver &arc )
{
Listener::Archive( arc );
arc.ArchiveString( &name );
arc.ArchiveBoolean( &stopping );
arc.ArchiveBoolean( &loop );
if( arc.Saving() ) {
position = AIL_stream_position( stream );
}
arc.ArchiveInteger( &position );
arc.ArchiveFloat( &volume );
arc.ArchiveFloat( &start_volume );
arc.ArchiveFloat( &target_volume );
arc.ArchiveFloat( &rate );
arc.ArchiveObject( &timer );
if( arc.Loading() )
{
path = GetFilePath( fs_basepath->string, gameDir, name );
stream = AIL_open_stream( *sndDriver, path, 0 );
if( stream )
{
AIL_start_stream( stream );
if( loop ) {
AIL_set_stream_loop_count( stream, 0 );
}
else {
AIL_set_stream_loop_count( stream, 1 );
}
AIL_set_stream_position( stream, position );
Event *ev = new Event( &EV_LocalSound_Think );
ProcessEvent( ev );
}
}
}
str LocalSound::GetName()
{
return name;
}
void LocalSound::Play( float time, float v )
{
stopping = false;
start_volume = volume;
if( time <= 0.0f ) {
volume = v;
} else {
volume = 0.0f;
AIL_set_stream_volume( stream, 0 );
}
target_volume = v;
timer.SetTime( time );
timer.Enable();
start_rate = 1.0f;
target_rate = 1.0f;
rate = 1.0f;
if( stream )
{
AIL_start_stream( stream );
baserate = AIL_stream_playback_rate( stream );
Event *ev = new Event( &EV_LocalSound_Think );
ProcessEvent( ev );
}
}
void LocalSound::Stop( float time )
{
if( time <= 0.0f )
{
delete this;
return;
}
start_volume = volume;
timer.SetTime( time );
timer.Enable();
stopping = true;
}
void LocalSound::SetRate( float r, float time )
{
target_rate = r;
start_rate = rate;
timer_rate.SetTime( time );
timer_rate.Enable();
if( time <= 0.0f )
{
rate = r;
if( stream )
{
int ra = ( int )( ( float )baserate * rate );
AIL_set_stream_playback_rate( stream, ra );
}
}
}
void LocalSound::Think( Event *ev )
{
if( stopping ) {
volume = timer.LerpValue( start_volume, 0.0f );
}
AIL_set_stream_volume( stream, ( int )( volume * s_volume->value * *sound_global_volume * 100.0f ) );
if( !timer_rate.Done() ) {
rate = timer_rate.LerpValue( start_rate, target_rate );
}
int r = ( int )( ( float )baserate * rate );
AIL_set_stream_playback_rate( stream, r );
if( ( stopping && timer.Done() ) || AIL_stream_status( stream ) != STREAM_PLAYING )
{
CancelEventsOfType( &EV_LocalSound_Think );
delete this;
return;
}
if( !stopping ) {
volume = timer.LerpValue( start_volume, target_volume );
}
CancelEventsOfType( &EV_LocalSound_Think );
PostEvent( EV_LocalSound_Think, level.frametime, 0 );
}
CLASS_DECLARATION( Listener, LocalSound, NULL )
{
{ &EV_LocalSound_Think, &LocalSound::Think },
{ NULL, NULL }
};
void ClientGameCommandManager::CleanUp()
{
Container< LocalSound * > local = localSounds;
for( int i = 0; i < local.NumObjects(); i++ )
{
LocalSound *localSound = local[ i ];
delete localSound;
}
localSounds.FreeObjectList();
}
void ClientGameCommandManager::ArchiveFunction( Archiver &arc )
{
int num = localSounds.NumObjects();
arc.ArchiveInteger( &num );
if( arc.Saving() )
{
for( int i = 0; i < num; i++ ) {
arc.ArchiveObject( localSounds[ i ] );
}
}
else
{
for( int i = 0; i < num; i++ ) {
arc.ReadObject();
}
}
}
void ClientGameCommandManager::Initialize()
{
}
void ClientGameCommandManager::PlaySound( str sound_name, float *origin, int channel, float volume, float min_distance, float pitch, int argstype )
{
JMPTO( 0x30015E0C );
}
void ClientGameCommandManager::PlayLocalSound( str sound_name, qboolean loop, float volume, float time )
{
// Don't play the same sound again
StopLocalSound( sound_name );
LocalSound *localSound = new LocalSound( sound_name, loop );
localSound->Play( time, volume );
}
void ClientGameCommandManager::SetLocalSoundRate( str sound_name, float rate, float time )
{
LocalSound *localSound = GetLocalSound( sound_name );
if( !localSound ) {
return;
}
localSound->SetRate( rate, time );
}
void ClientGameCommandManager::StopLocalSound( str sound_name, float time )
{
LocalSound *localSound = GetLocalSound( sound_name );
if( localSound ) {
localSound->Stop( time );
}
}
LocalSound *ClientGameCommandManager::GetLocalSound( str sound_name )
{
for( int i = 1; i <= localSounds.NumObjects(); i++ )
{
LocalSound *localSound = localSounds.ObjectAt( i );
if( localSound->GetName() == sound_name ) {
return localSound;
}
}
return NULL;
}
void ClientSpecialEffectsManager::MakeEffect_Normal( int iEffect, Vector position, Vector normal )
{
JMPTO( 0x3003524D );
}

View file

@ -0,0 +1,72 @@
#ifndef __CLIENTGAMECOMMAND_H__
#define __CLIENTGAMECOMMAND_H__
#include "listener.h"
#include "scripttimer.h"
class LocalSound : public Listener {
private:
void *stream;
str name;
str path;
qboolean loop;
qboolean stopping;
int position;
int baserate;
float rate, start_rate, target_rate;
float volume, start_volume, target_volume;
ScriptTimer timer;
ScriptTimer timer_rate;
public:
CLASS_PROTOTYPE( LocalSound );
virtual void Archive( Archiver &arc );
LocalSound( str name, qboolean loop );
LocalSound();
~LocalSound();
str GetName();
void Play( float time, float volume );
void Stop( float time );
void SetRate( float rate, float time );
void Think( Event *ev );
};
#define STREAM_PLAYING 4
#define STREAM_PAUSED 16
class ClientGameCommandManager : public Listener
{
public:
static void ArchiveFunction( Archiver &arc );
static void CleanUp( void );
static void Initialize( void );
void PlaySound( str sound_name, float *origin, int channel, float volume, float min_distance, float pitch, int argstype );
void PlayLocalSound( str sound_name, qboolean loop, float volume, float time = 0.0f );
void SetLocalSoundRate( str sound_name, float rate, float time = 0.0f );
void StopLocalSound( str sound_name, float time = 0.0f );
LocalSound *GetLocalSound( str sound_name );
};
class ClientSpecialEffectsManager : public Listener
{
public:
void MakeEffect_Normal( int iEffect, Vector position, Vector normal );
};
extern ClientGameCommandManager *commandManager;
extern ClientSpecialEffectsManager *sfxManager;
#endif

View file

@ -0,0 +1,296 @@
/*
* ClientServerCommandManager.cpp
*
* DESCRIPTION : Client Server Command Manager. Processes server commands as event (if one).
*/
#include "clientservercommand.h"
#include "earthquake.h"
#include "cgame/cl_sound.h"
ClientServerCommandManager svcommandManager;
Event EV_ServerCommand_Earthquake
(
"eq",
EV_SERVERCMD,
"ffbbVF",
"duration magnitude no_rampup no_rampdown location radius",
"Earthquake",
EV_NORMAL
);
Event EV_ServerCommand_FadeSound
(
"fadesound2",
EV_SERVERCMD,
"ff",
"time min_vol",
"Fade the sound",
EV_NORMAL
);
Event EV_ServerCommand_RestoreSound
(
"restoresound",
EV_SERVERCMD,
"ff",
"time max_vol",
"Restore the sound",
EV_NORMAL
);
Event EV_ServerCommand_SetClientFlag
(
"cf",
EV_SERVERCMD,
"s",
"name",
"Client call back flag.",
EV_NORMAL
);
Event EV_ServerCommand_SetShader
(
"setshader",
EV_SERVERCMD,
"isb",
"ent_num shader fReset",
"Set entity shader",
EV_NORMAL
);
Event EV_ServerCommand_VisionSetBlur
(
"vsb",
EV_SERVERCMD,
"ff",
"blur_level transition_time",
"Specific server command for the naked blur vision",
EV_NORMAL
);
Event EV_ServerCommand_VisionSetNaked
(
"vsn",
EV_SERVERCMD,
"sff",
"vision transition_time phase",
"Specific server command for the naked vision",
EV_NORMAL
);
void ClientServerCommandManager::Archive( Archiver &arc )
{
}
void ClientServerCommandManager::ExecuteCommand( char *arguments[], int num_arguments )
{
const char *command = arguments[ 0 ];
const char *formatspec;
int k;
char **args = arguments + 1;
Event *ev = new Event( command, EV_NORMAL );
if( ev->eventnum == 0 )
{
delete ev;
return;
}
formatspec = ev->GetFormat();
for( int i = 0, k = 0; k < num_arguments - 1; k++ )
{
const char *argument = args[ i ];
str vec;
if( formatspec[ k ] == '\0' ) {
break;
}
if( argument == NULL || *argument == '\0' ) {
continue;
}
switch( formatspec[ k ] )
{
case 'b':
case 'B':
ev->AddInteger( atoi( argument ) );
i++;
break;
case 's':
case 'S':
ev->AddString( argument );
i++;
break;
case 'i':
case 'I':
ev->AddInteger( atoi( argument ) );
i++;
break;
case 'f':
case 'F':
ev->AddFloat( ( float )atof( argument ) );
i++;
break;
case 'v':
case 'V':
vec = args[ i ];
vec += str( " " ) + args[ i + 1 ];
vec += str( " " ) + args[ i + 2 ];
ev->AddVector( Vector( vec.c_str() ) );
i += 3;
break;
default:
ev->AddString( argument );
i++;
}
}
try
{
ProcessEvent( ev );
}
catch( ScriptException exc )
{
cgi.Printf( exc.string );
}
}
////==== EVENTS ====////
void ClientServerCommandManager::EventEarthquake( Event *ev )
{
float duration = ev->GetFloat( 1 );
float magnitude = ev->GetFloat( 2 );
qboolean no_rampup = ev->GetBoolean( 3 );
qboolean no_rampdown = ev->GetBoolean( 4 );
Vector org;
float radius;
if( ev->NumArgs() > 4 )
{
org = ev->GetVector( 5 );
if( ev->NumArgs() > 5 ) {
radius = ev->GetFloat( 6 );
}
}
Earthquake * earthquake = new Earthquake;
earthquake->SetDuration( duration );
earthquake->SetMagnitude( magnitude );
earthquake->SetNoRampup( no_rampup );
earthquake->SetNoRampdown( no_rampdown );
if( ev->NumArgs() > 4 )
{
earthquake->SetLocation( org );
if( ev->NumArgs() > 5 ) {
earthquake->SetRadius( radius );
}
}
earthquake->Enable();
}
void ClientServerCommandManager::EventFadeSound( Event *ev )
{
float time = ev->GetFloat( 1 );
float min_vol = ev->GetFloat( 2 );
CL_FadeSound2( time, min_vol );
}
void ClientServerCommandManager::EventRestoreSound( Event *ev )
{
float time = ev->GetFloat( 1 );
float max_vol = ev->GetFloat( 2 );
CL_RestoreSound( time, max_vol );
}
void ClientServerCommandManager::EventSetClientFlag( Event *ev )
{
/*str name = ev->GetString( 1 );
ClientScript *clientScript;
clientScript = new ClientScript;
clientScript->ExecuteCallback( name );
if( clientScript->ScriptFailed() ) {
delete clientScript;
}*/
}
void ClientServerCommandManager::EventSetShader( Event *ev )
{
int ent_num = ev->GetInteger( 1 );
str shadername = ev->GetString( 2 );
qboolean fReset = ev->GetBoolean( 3 );
R_SetShader( ent_num, shadername, fReset );
}
void ClientServerCommandManager::EventVisionSetBlur( Event *ev )
{
float blur_level = ev->GetFloat( 1 );
float transition_time;
if( ev->NumArgs() > 1 ) {
transition_time = ev->GetFloat( 2 );
} else {
transition_time = 0.0f;
}
R_ProcessBlur( blur_level, transition_time );
}
void ClientServerCommandManager::EventVisionSetNaked( Event *ev )
{
str vision_name = ev->GetString( 1 );
float transition_time;
float phase;
if( ev->NumArgs() > 1 ) {
transition_time = ev->GetFloat( 2 );
} else {
transition_time = 0.0f;
}
if( ev->NumArgs() > 2 ) {
phase = ev->GetFloat( 3 );
}
else {
phase = 0.0f;
}
R_ProcessVision( vision_name, transition_time, phase );
}
CLASS_DECLARATION( Listener, ClientServerCommandManager, NULL )
{
{ &EV_ServerCommand_Earthquake, &ClientServerCommandManager::EventEarthquake },
{ &EV_ServerCommand_FadeSound, &ClientServerCommandManager::EventFadeSound },
{ &EV_ServerCommand_RestoreSound, &ClientServerCommandManager::EventRestoreSound },
{ &EV_ServerCommand_SetClientFlag, &ClientServerCommandManager::EventSetClientFlag },
{ &EV_ServerCommand_SetShader, &ClientServerCommandManager::EventSetShader },
{ &EV_ServerCommand_VisionSetBlur, &ClientServerCommandManager::EventVisionSetBlur },
{ &EV_ServerCommand_VisionSetNaked, &ClientServerCommandManager::EventVisionSetNaked },
{ NULL, NULL }
};

View file

@ -0,0 +1,26 @@
#ifndef __CLIENTSERVERCOMMAND_H__
#define __CLIENTSERVERCOMMAND_H__
#include "listener.h"
class ClientServerCommandManager : public Listener {
public:
CLASS_PROTOTYPE( ClientServerCommandManager );
virtual void Archive( Archiver &arc );
void ExecuteCommand( char *arguments[], int num_arguments );
// Events
void EventEarthquake( Event *ev );
void EventFadeSound( Event *ev );
void EventRestoreSound( Event *ev );
void EventSetClientFlag( Event *ev );
void EventSetShader( Event *ev );
void EventVisionSetBlur( Event *ev );
void EventVisionSetNaked( Event *ev );
};
extern ClientServerCommandManager svcommandManager;
#endif // __CLIENTSERVERCOMMAND_H__

View file

@ -0,0 +1,688 @@
/*
* CPlayer.cpp
*
* DESCRIPTION : Client-side player
*/
#include "cplayer.h"
#include "earthquake.h"
#include "cgame/cg_viewmodelanim.h"
#include "archive.h"
CPlayer player;
Event EV_ReplicationInfo_GetVariable
(
"getvar",
EV_DEFAULT,
"s",
"name",
"Gets a replicated variable",
EV_RETURN
);
Event EV_Player_GetReplicationInfo
(
"replicationinfo",
EV_DEFAULT,
NULL,
NULL,
"Gets the player's replication info",
EV_GETTER
);
Event EV_Player_GetMovement
(
"getmovement",
EV_DEFAULT,
NULL,
NULL,
"Gets the player's movement state",
EV_RETURN
);
Event EV_Player_GetSpeed
(
"movespeedscale",
EV_DEFAULT,
NULL,
NULL,
"Gets the player's speed scale",
EV_GETTER
);
Event EV_Player_SetSpeed
(
"movespeedscale",
EV_DEFAULT,
"f",
"speed",
"Sets the player's speed scale until the next snapshot",
EV_SETTER
);
Event EV_Player_ViewModelAnim
(
"viewmodelanim",
EV_DEFAULT,
"si",
"anim force_restart",
"Sets the player's view model animation",
EV_NORMAL
);
void ReplicationInfo::ReplicateVariable( ScriptVariable& var )
{
replicatedvars.SetVariable( var.GetKey(), var );
}
void ReplicationInfo::EventGetVariable( Event *ev )
{
ScriptVariable *pVar = replicatedvars.GetVariable( ev->GetString( 1 ) );
if( pVar )
{
ev->AddValue( *pVar );
}
else
{
ev->AddNil();
}
}
CLASS_DECLARATION( Listener, ReplicationInfo, NULL )
{
{ &EV_ReplicationInfo_GetVariable, &ReplicationInfo::EventGetVariable },
{ NULL, NULL }
};
CPlayer::CPlayer()
{
for( int i = 0; i < MAX_DELTAANGLES; i++ )
{
_targetActive[ i ][ 0 ] = false;
_targetActive[ i ][ 1 ] = false;
_targetActive[ i ][ 2 ] = false;
VectorSet( _currentTarget[ i ], 0, 0, 0 );
VectorSet( deltaAngles[ i ], 0, 0, 0 );
VectorSet( deltaAnglesOld[ i ], 0, 0, 0 );
}
VectorSet( eyesDelta, 0, 0, 0 );
VectorSet( eyesDeltaOld, 0, 0, 0 );
debugCamera = false;
debugCameraEnd = false;
debugPoint = Vector( 0, 0, 0 );
mins = Vector( -16, -16, 0 );
maxs = Vector( 16, 16, 96 );
m_fMoveSpeedScale = 1.0f;
m_fExposure = 0.0f;
m_fExposurePrevious = 0.0f;
m_ExposureTimer.setType( TIMER_GLIDE );
renderFx = RF_INVISIBLE;
turnThinkOn();
}
void CPlayer::Archive( Archiver &arc )
{
str s;
if( this != &player )
{
player.Archive( arc );
delete this;
return;
}
Animate::Archive( arc );
for( int i = 0; i < MAX_DELTAANGLES; i++ )
{
arc.ArchiveVector( &_targetDeltaAngles[ i ] );
arc.ArchiveVector( &_targetDeltaStart[ i ] );
arc.ArchiveVector( &_targetDeltaTime[ i ] );
for( int x = 0; x < 3; x++ )
{
arc.ArchiveBoolean( &_targetActive[ i ][ x ] );
arc.ArchiveBoolean( &_godown[ i ][ x ] );
arc.ArchiveBoolean( &_glidingDown[ i ][ x ] );
arc.ArchiveBoolean( &_glideUse[ i ][ x ] );
}
arc.ArchiveVector( &_currentTarget[ i ] );
arc.ArchiveVector( &_currentDeltaTime[ i ] );
arc.ArchiveVector( &_glideRatio[ i ] );
}
arc.ArchiveBoolean( &debugCamera );
arc.ArchiveBoolean( &debugCameraEnd );
arc.ArchiveVector( &debugPoint );
arc.ArchiveVector( &debugAngles );
arc.ArchiveVector( &debugPlayerAngles );
int num_prefixes = 19;
if( !arc.Loading() )
{
for( int i = 19; i < 255; i++ )
{
if( itemName[i] != NULL && itemPrefix[i] != NULL ) {
num_prefixes++;
}
}
}
arc.ArchiveInteger( &num_prefixes );
if( arc.Saving() )
{
for( int i = 19; i < 255; i++ )
{
if( itemName[ i ] != NULL && itemPrefix[ i ] != NULL )
{
s = itemName[ i ];
arc.ArchiveString( &s );
s = itemPrefix[ i ];
arc.ArchiveString( &s );
}
}
}
else
{
for( int i = 19; i < num_prefixes; i++ )
{
arc.ArchiveString( &s );
itemName[ i ] = ( char * )malloc( s.length() + 1 );
strcpy( ( char * )itemName[ i ], s.c_str() );
arc.ArchiveString( &s );
itemPrefix[ i ] = ( char * )malloc( s.length() + 1 );
strcpy( ( char * )itemPrefix[ i ], s.c_str() );
}
}
arc.ArchiveVector( ( Vector * )&viewAngles );
arc.ArchiveVector( &avel );
arc.ArchiveVector( &oldAngles );
}
void CPlayer::Think()
{
Vector a;
Entity *ent;
cent = &cg_entities[ 0 ];
if( cg->playerFPSModel != NULL )
{
model = cg->playerFPSModel->name;
modelhandle = cg->playerFPSModelHandle;
tiki = cg->playerFPSModel;
}
else
{
model = "";
modelhandle = 0;
tiki = NULL;
}
MatrixToEulerAngles( cg->refdef.viewAxis, a );
setOrigin( cg->refdef.viewOrg );
ShakeCamera();
SmoothProcessDeltaAngles();
a[ 0 ] = abs( a[ 0 ] );
a[ 1 ] = abs( a[ 1 ] );
a[ 2 ] = abs( a[ 2 ] );
avel = a - oldAngles;
oldAngles = a;
Container< SafePtr< Entity > > entities = s_entities;
for( int i = entities.NumObjects(); i > 0; i-- )
{
ent = entities.ObjectAt( i );
if( ent && IsTouching( ent ) )
{
Event *event = new Event( EV_Touch );
event->AddEntity( this );
ent->ProcessEvent( event );
}
}
/*if( m_ExposureTrigger != NULL && !IsTouching( m_ExposureTrigger ) )
{
TriggerExposure *trigger = ( TriggerExposure * )m_ExposureTrigger.Pointer();
m_fExposureStart = m_fExposure;
m_fExposureTarget = 0.0f;
m_ExposureTimer.SetTime( trigger->m_fExposureTime );
m_ExposureTimer.Enable();
m_ExposureTrigger = NULL;
}*/
m_fExposure = m_ExposureTimer.LerpValue( m_fExposureStart, m_fExposureTarget );
Animate::Think();
}
void CPlayer::ShakeCamera()
{
// Shake the current player's camera
float earthquakeMagnitude = 0.0f;
Earthquake *eq;
float magnitude;
for( int i = earthquakes.NumObjects(); i > 0; i-- )
{
eq = earthquakes.ObjectAt( i );
if( !eq->isActive() ) {
continue;
}
magnitude = eq->getMagnitude();
if( eq->hasLocation() )
{
Vector location = eq->getLocation();
float radius = eq->getRadius();
if( inRadius( location, radius ) )
{
Vector org = origin;
Vector dir = org - location;
float dist = dir.length();
magnitude = magnitude - ( magnitude * ( dist / radius ) );
}
else
{
magnitude = 0.0f;
}
}
earthquakeMagnitude += magnitude;
}
if( earthquakeMagnitude <= 0.0f )
{
VectorSet( deltaAngles[ ANGLES_EQ ], 0, 0, 0 );
return;
}
magnitude = earthquakeMagnitude / 2.0f;
if( !_targetActive[ ANGLES_EQ ][ PITCH ] )
{
float angle;
if( !_godown[ ANGLES_EQ ][ PITCH ] )
{
angle = 1.85f * magnitude;
_godown[ ANGLES_EQ ][ PITCH ] = true;
}
else
{
angle = -1.85f * magnitude;
_godown[ ANGLES_EQ ][ PITCH ] = false;
}
SmoothSetDeltaAngle( ANGLES_EQ, PITCH, 0.105f, angle );
}
if( !_targetActive[ ANGLES_EQ ][ YAW ] )
{
float angle;
if( !_godown[ ANGLES_EQ ][ YAW ] )
{
angle = 1.75f * magnitude;
_godown[ ANGLES_EQ ][ YAW ] = true;
}
else
{
angle = -1.75f * magnitude;
_godown[ ANGLES_EQ ][ YAW ] = false;
}
SmoothSetDeltaAngle( ANGLES_EQ, YAW, 0.060f, angle );
}
if( !_targetActive[ ANGLES_EQ ][ ROLL ] )
{
float angle;
if( !_godown[ ANGLES_EQ ][ ROLL ] )
{
angle = 1.35f * magnitude;
_godown[ ANGLES_EQ ][ ROLL ] = true;
}
else
{
angle = -1.35f * magnitude;
_godown[ ANGLES_EQ ][ ROLL ] = false;
}
SmoothSetDeltaAngle( ANGLES_EQ, ROLL, 0.082f, angle );
}
}
void CPlayer::SmoothSetDeltaAngles( int port, float time, vec3_t newDeltaAngles, qboolean bMoveVM )
{
SmoothSetDeltaAngle( port, 0, time, newDeltaAngles[ 0 ] );
SmoothSetDeltaAngle( port, 1, time, newDeltaAngles[ 1 ] );
SmoothSetDeltaAngle( port, 2, time, newDeltaAngles[ 2 ] );
}
void CPlayer::SmoothSetDeltaAngle( int port, int index, float time, float angle )
{
if( index > 2 ) {
return;
}
float realtime = time * 1000.0f + 0.5f;
_currentDeltaTime[ port ][ index ] = 0.0f;
deltaAngles[ port ][ index ] = _currentTarget[ port ][ index ];
_glideRatio[ port ][ index ] = 0.0f;
_glidingDown[ port ][ index ] = false;
_glideTime[ port ][ index ] = 0.0f;
_glideUse[ port ][ index ] = ( ( realtime / 2 ) > cg->frametime ) ? true : false;
_targetDeltaAngles[ port ][ index ] = angle;
_targetDeltaStart[ port ][ index ] = _currentTarget[ port ][ index ];
_targetDeltaTime[ port ][ index ] = realtime;
_targetActive[ port ][ index ] = true;
}
void CPlayer::SmoothProcessDeltaAngle( int port, int index )
{
if( index > 2 || port >= MAX_DELTAANGLES ) {
return;
}
// Process each angle
if( !_targetActive[ port ][ index ] ) {
return;
}
_glideTime[ port ][ index ] += cg->frametime;
// Glide the angle by time
if( _glideUse[ port ][ index ] )
{
if( _glidingDown[ port ][ index ] )
{
//_glideRatio[ port ][ index ] -= 2.0f/( _targetDeltaTime[ port ][ index ]/2 ) * cg->frametime;
_glideRatio[ port ][ index ] = 2.0f - 2.0f * _glideTime[ port ][ index ] / ( _targetDeltaTime[ port ][ index ] / 2.0f );
if( _glideRatio[ port ][ index ] < 0.0f )
{
_glideRatio[ port ][ index ] = 0.0f;
_glidingDown[ port ][ index ] = false;
_glideTime[ port ][ index ] = 0.0f;
}
}
else
{
//_glideRatio[ port ][ index ] += 2.0f/( _targetDeltaTime[ port ][ index ]/2 ) * cg->frametime;
_glideRatio[ port ][ index ] = 2.0f * _glideTime[ port ][ index ] / ( _targetDeltaTime[ port ][ index ] / 2.0f );
if( _glideRatio[ port ][ index ] > 2.0f )
{
_glideRatio[ port ][ index ] = 2.0f;
_glidingDown[ port ][ index ] = true;
_glideTime[ port ][ index ] = 0.0f;
}
}
_currentDeltaTime[ port ][ index ] += cg->frametime * _glideRatio[ port ][ index ];
} else {
_currentDeltaTime[ port ][ index ] += cg->frametime;
}
float ratio = _currentDeltaTime[ port ][ index ] / _targetDeltaTime[ port ][ index ];
if( ratio >= 1.0f )
{
deltaAngles[ port ][ index ] = _targetDeltaAngles[ port ][ index ];
_currentTarget[ port ][ index ] = _targetDeltaAngles[ port ][ index ];
_targetActive[ port ][ index ] = false;
return;
}
deltaAngles[ port ][ index ] = _targetDeltaStart[ port ][ index ] + ( _targetDeltaAngles[ port ][ index ] - _targetDeltaStart[ port ][ index ] ) * ratio;
_currentTarget[ port ][ index ] = deltaAngles[ port ][ index ];
}
void CPlayer::SmoothProcessDeltaAngles()
{
for( int i = 0; i < MAX_DELTAANGLES; i++ )
{
SmoothProcessDeltaAngle( i, 0 );
SmoothProcessDeltaAngle( i, 1 );
SmoothProcessDeltaAngle( i, 2 );
}
}
void CPlayer::DebugCamera()
{
if( !cg_debugview->integer )
{
//debugCamera = false;
if( !debugCameraEnd )
{
// Restore the player's view angles
VectorCopy( debugPlayerAngles, viewAngles );
debugCameraEnd = true;
}
return;
}
// Initialize debug point
if( !debugCamera )
{
debugCamera = true;
debugAngles = cg->refdefViewAngles;
debugPoint = cg->refdef.viewOrg;
debugPoint.z += cg->predictedPlayerState.viewheight;
}
if( debugCameraEnd )
{
// Save the player's view angles
debugPlayerAngles = viewAngles;
// Restore the debug camera's view angles
VectorCopy( debugAngles, viewAngles );
debugCameraEnd = false;
}
// Save the camera's view angles
debugAngles = viewAngles;
cg->predictedPlayerState.camera_flags |= 8;
kbutton_t *forward = ( kbutton_t * )0x12F6FE0;
kbutton_t *backward = ( kbutton_t * )0x12F70C0;
kbutton_t *moveleft = ( kbutton_t * )0x12F7040;
kbutton_t *moveright = ( kbutton_t * )0x12F70A0;
kbutton_t *movedown = ( kbutton_t * )0x012F6FC0;
kbutton_t *moveup = ( kbutton_t* )0x012F6FA0;
Vector newAngles = cg->refdefViewAngles;
//newAngles[ 0 ] = 0.f;
if( forward->active )
{
Vector fwdvec;
AngleVectors( newAngles, fwdvec, NULL, NULL );
debugPoint = debugPoint + fwdvec * ( ( float )cg->frametime * 2 );
}
if( backward->active )
{
Vector backvec;
AngleVectors( newAngles, backvec, NULL, NULL );
debugPoint = debugPoint - backvec * ( ( float )cg->frametime * 2 );
}
if( moveleft->active )
{
Vector leftvec;
AngleVectors( newAngles, NULL, leftvec, NULL );
debugPoint = debugPoint + leftvec * ( ( float )cg->frametime * 2 );
}
if( moveright->active )
{
Vector rightvec;
AngleVectors( newAngles, NULL, rightvec, NULL );
debugPoint = debugPoint - rightvec * ( ( float )cg->frametime * 2 );
}
if( moveup->active )
{
Vector upvec;
newAngles.x = 0.f;
AngleVectors( newAngles, NULL, NULL, upvec );
debugPoint = debugPoint + upvec * ( ( float )cg->frametime );
}
if( movedown->active )
{
Vector downvec;
newAngles.x = 0.f;
AngleVectors( newAngles, NULL, NULL, downvec );
debugPoint = debugPoint - downvec * ( ( float )cg->frametime );
}
cg->refdef.viewOrg[ 0 ] = debugPoint[ 0 ];
cg->refdef.viewOrg[ 1 ] = debugPoint[ 1 ];
cg->refdef.viewOrg[ 2 ] = debugPoint[ 2 ];
VectorCopy( cg->refdef.viewOrg, cg->currentViewPos );
VectorCopy( cg->refdef.viewOrg, cg->playerHeadPos );
VectorCopy( cg->refdef.viewOrg, cg->cameraOrigin );
VectorCopy( cg->refdef.viewOrg, cg->soundOrg );
VectorCopy( cg->refdef.viewOrg, cg->predictedPlayerState.camera_origin );
//VectorCopy( cg->refdef.viewOrg, cg->predictedPlayerState.origin );
//cg->predictedPlayerState.origin[ 0 ] -= cg->predictedPlayerState.viewHeight;
}
// Script
void CPlayer::EventGetMovement( Event *ev )
{
kbutton_t *forward = ( kbutton_t * )0x12F6FE0;
kbutton_t *movedown = ( kbutton_t* )0x012F6FC0;
kbutton_t *moveup = ( kbutton_t* )0x012F6FA0;
if( forward->active && !moveup->active && !movedown->active )
{
ev->AddString( "forward" );
}
else if( movedown->active )
{
ev->AddString( "crouch" );
}
else if( moveup->active )
{
ev->AddString( "jump" );
}
else
{
ev->AddString( "idle" );
}
}
void CPlayer::EventGetReplicationInfo( Event *ev )
{
ev->AddListener( &replication );
}
void CPlayer::EventGetSpeed( Event *ev )
{
ev->AddFloat( m_fMoveSpeedScale );
}
void CPlayer::EventSetSpeed( Event *ev )
{
m_fMoveSpeedScale = ev->GetFloat( 1 );
}
void CPlayer::EventViewModelAnim( Event *ev )
{
if( cg->snap != NULL )
{
cg->snap->ps.iViewModelAnim = VMA_CUSTOMANIMATION;
}
cgi.anim->lastVMAnim = VMA_CUSTOMANIMATION;
cgi.anim->lastVMAnimChanged = ( cg->snap->ps.iViewModelAnimChanged + 1 ) & 3;
CG_ViewModelAnim( ( char * )ev->GetString( 1 ).c_str(), false );
}
CLASS_DECLARATION( CAnimate, CPlayer, NULL )
{
{ &EV_Player_GetMovement, &CPlayer::EventGetMovement },
{ &EV_Player_GetReplicationInfo, &CPlayer::EventGetReplicationInfo },
{ &EV_Player_GetSpeed, &CPlayer::EventGetSpeed },
{ &EV_Player_SetSpeed, &CPlayer::EventSetSpeed },
{ &EV_Player_ViewModelAnim, &CPlayer::EventViewModelAnim },
{ NULL, NULL }
};

View file

@ -0,0 +1,97 @@
#ifndef __CPLAYER_H__
#define __CPLAYER_H__
#include "canimate.h"
#include "scripttimer.h"
#include "scriptvariable.h"
// EQ prefix = earthquake
#define ANGLES_EQ 0
#define MAX_DELTAANGLES 4
class ReplicationInfo : public Listener
{
private:
ScriptVariableList replicatedvars;
public:
CLASS_PROTOTYPE( ReplicationInfo );
void ReplicateVariable( ScriptVariable& variable );
void EventGetVariable( Event *ev );
};
class CPlayer : public Animate
{
private:
Vector _targetDeltaAngles[ MAX_DELTAANGLES ];
Vector _targetDeltaStart[ MAX_DELTAANGLES ];
Vector _targetDeltaTime[ MAX_DELTAANGLES ];
qboolean _targetActive[ MAX_DELTAANGLES ][ 3 ];
qboolean _godown[ MAX_DELTAANGLES ][ 3 ];
Vector _currentTarget[ MAX_DELTAANGLES ];
Vector _currentDeltaTime[ MAX_DELTAANGLES ];
Vector _glideRatio[ MAX_DELTAANGLES ];
Vector _glideTime[ MAX_DELTAANGLES ];
qboolean _glidingDown[ MAX_DELTAANGLES ][ 3 ];
qboolean _glideUse[ MAX_DELTAANGLES ][ 3 ];
qboolean debugCamera;
qboolean debugCameraEnd;
Vector debugPoint;
Vector debugAngles;
Vector debugPlayerAngles;
public:
float deltaAnglesOld[MAX_DELTAANGLES][3];
float deltaAngles[MAX_DELTAANGLES][3];
Vector eyesDelta;
Vector eyesDeltaOld;
Vector vAngles;
Vector oldAngles;
Vector avel;
ReplicationInfo replication;
float m_fMoveSpeedScale;
SafePtr< Entity > m_ExposureTrigger;
float m_fExposure;
float m_fExposurePrevious;
float m_fExposureStart;
float m_fExposureTarget;
ScriptTimer m_ExposureTimer;
playerState_t *ps;
private:
void SmoothProcessDeltaAngles( void );
void SmoothProcessDeltaAngle( int port, int index );
public:
CLASS_PROTOTYPE( CPlayer );
virtual void Archive( Archiver &arc );
CPlayer();
virtual void Think( void );
void DebugCamera( void );
void ShakeCamera( void );
void SmoothSetDeltaAngles( int port, float time, vec3_t newDeltaAngles, qboolean bMoveVM = false );
void SmoothSetDeltaAngle( int port, int index, float time, float angle );
void EventGetMovement( Event *ev );
void EventGetReplicationInfo( Event *ev );
void EventGetSpeed( Event *ev );
void EventSetSpeed( Event *ev );
void EventViewModelAnim( Event *ev );
};
extern CPlayer player;
#endif

View file

@ -0,0 +1,232 @@
/*
* 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 },
};

View file

@ -0,0 +1,53 @@
#ifndef __EARTHQUAKE_H__
#define __EARTHQUAKE_H__
#include "simpleentity.h"
class Earthquake : public SimpleEntity
{
private:
float _duration;
float _magnitude;
qboolean _no_rampup;
qboolean _no_rampdown;
Vector _location;
float _radius;
float _currentMagnitude;
float _currentTime;
float _startTime;
qboolean active;
public:
CLASS_PROTOTYPE( Earthquake );
virtual void Archive( Archiver &arc );
Earthquake();
Earthquake( float duration, float magnitude, qboolean no_rampup, qboolean no_rampdown, Vector location = Vector( 0, 0, 0 ), float radius = 1.0f );
virtual ~Earthquake();
void Enable( void );
void Disable( void );
qboolean isActive( void );
float getMagnitude( void );
Vector getLocation( void );
float getRadius( void );
qboolean hasLocation( void );
void SetDuration( float duration );
void SetMagnitude( float magnitude );
void SetNoRampup( qboolean no_rampup );
void SetNoRampdown( qboolean no_rampdown );
void SetLocation( Vector origin );
void SetRadius( float radius );
void Think( Event *ev );
};
extern Container< Earthquake * > earthquakes;
#endif

View file

@ -0,0 +1,64 @@
/*
* Level.cpp
*
* DESCRIPTION : Global level info
*/
#include "level.h"
Event EV_Level_testf
(
"testf",
EV_DEFAULT,
"i",
"test_int",
"test",
EV_SETTER
);
Level level;
Level::Level()
{
prespawned = false;
spawned = false;
}
Level::~Level()
{
}
void Level::setTime( int levelTime )
{
svsTime = levelTime;
inttime = levelTime - svsStartTime;
svsFloatTime = levelTime / 1000.0f;
time = inttime / 1000.0f;
}
void Level::setFrametime( int frametime )
{
intframetime = frametime;
this->frametime = frametime / 1000.0f;
}
void Level::Archive( Archiver &arc )
{
Listener::Archive( arc );
}
void Level::TestEvent( Event *ev )
{
int integer = ev->GetInteger( 1 );
cgi.Printf( "this = %p\n", this );
cgi.Printf( "SCRIPT: integer = %d\n", integer );
}
CLASS_DECLARATION( Listener, Level, NULL )
{
{ &EV_Level_testf, &Level::TestEvent },
{ NULL, NULL }
};

View file

@ -0,0 +1,58 @@
#ifndef __LEVEL_H__
#define __LEVEL_H__
#include "listener.h"
class SimpleArchivedEntity;
class Level : public Listener
{
public:
bool m_LoopDrop;
bool m_LoopProtection;
str m_mapscript;
str current_map;
// Level time
int framenum;
int inttime;
int intframetime;
float time;
float frametime;
int spawnflags;
// Server time
int svsTime;
float svsFloatTime;
int svsStartTime;
int svsEndTime;
bool m_bScriptSpawn;
bool m_bRejectSpawn;
Container< SimpleArchivedEntity * > m_SimpleArchivedEntities;
qboolean prespawned;
qboolean spawned;
public:
CLASS_PROTOTYPE( Level );
void setTime( int _svsTime_ );
void setFrametime( int frameTime );
virtual void Archive( Archiver &arc );
Level();
~Level();
void TestEvent( Event *ev );
};
extern Level level;
#endif // __LEVEL_H__

View file

@ -0,0 +1,319 @@
/*
* ScriptSlave.cpp
*
* DESCRIPTION : Client-side script slave
*/
#include "scriptslave.h"
Event EV_ScriptSlave_GetSpeed
(
"speed",
EV_DEFAULT,
NULL,
NULL,
"Gets the speed.",
EV_GETTER
);
Event EV_ScriptSlave_GetTime
(
"time",
EV_DEFAULT,
NULL,
NULL,
"Gets the travel time.",
EV_GETTER
);
Event EV_ScriptSlave_MoveTo
(
"moveto",
EV_DEFAULT,
"s",
"vector_or_entity",
"Move to the specified vector or entity.",
EV_NORMAL
);
Event EV_ScriptSlave_Move
(
"move",
EV_DEFAULT,
NULL,
NULL,
"Move the script slave.",
EV_NORMAL
);
Event EV_ScriptSlave_SetSpeed
(
"speed",
EV_DEFAULT,
"f",
"speed",
"Sets the speed.",
EV_SETTER
);
Event EV_ScriptSlave_SetTime
(
"time",
EV_DEFAULT,
"f",
"travel_time",
"Sets the travel time.",
EV_SETTER
);
Event EV_ScriptSlave_StopMove
(
"stopmove",
EV_DEFAULT,
NULL,
NULL,
"Make the script slave stop moving.",
EV_NORMAL
);
Event EV_ScriptSlave_WaitMove
(
"waitmove",
EV_DEFAULT,
NULL,
NULL,
"Move the script slave and wait until finished.",
EV_NORMAL
);
void ScriptSlave::Archive( Archiver &arc )
{
}
ScriptSlave::ScriptSlave()
{
moveflags = 0;
slavetype = MOVE_UNSET;
target.origin = NULL;
movespeed = 200.0f;
movetime = 1.0f;
moving = false;
currentTime = 0.f;
turnThinkOn();
}
ScriptSlave::~ScriptSlave()
{
ClearMove();
}
void ScriptSlave::Think()
{
if( moving )
{
float length;
Vector targetOrigin;
// Calculate the length
if( slavetype == MOVE_ENTITY )
{
Entity *ent = ( Entity* )target.entity->Pointer();
if( ent ) {
targetOrigin = ent->origin;
} else {
targetOrigin = vec_zero;
}
}
else
{
targetOrigin = target.origin;
}
if( movespeed > 0.0f && !movetimedone )
{
length = Vector::Distance( origin, targetOrigin );
movetime = ( length / movespeed ) * 1000.0f;
movetimedone = true;
}
float ratio = currentTime / movetime;
currentTime += cg->frametime;
if( ratio >= 1.0f )
{
ratio = 1.0f;
ClearMove();
}
setOrigin( startOrigin + ( targetOrigin - startOrigin ) * ratio );
}
Animate::Think();
}
void ScriptSlave::ClearMove()
{
if( slavetype == MOVE_ENTITY )
{
if( target.entity ) {
delete target.entity;
}
}
else if( slavetype == MOVE_ORIGIN )
{
if( target.origin ) {
delete ( Vector * ) target.origin;
}
}
moving = false;
currentTime = 0.f;
slavetype = MOVE_UNSET;
}
float ScriptSlave::GetSpeed()
{
return movespeed;
}
float ScriptSlave::GetTime()
{
return movetime;
}
void ScriptSlave::MoveTo( Entity *entity )
{
ClearMove();
setSlaveType( MOVE_ENTITY );
target.entity = new SafePtr < Entity > ;
target.entity->InitSafePtr( entity );
}
void ScriptSlave::MoveTo( Vector origin )
{
ClearMove();
setSlaveType( MOVE_ORIGIN );
target.origin = ( float * ) new Vector( origin );
}
void ScriptSlave::Move()
{
if( slavetype == MOVE_UNSET ) {
ScriptError( "No target set for the ScriptSlave !\n" );
}
moving = true;
movetimedone = false;
startOrigin = origin;
}
void ScriptSlave::SetSpeed( float speed )
{
if( speed >= 0.f )
{
movespeed = speed;
movetime = 0.0f;
}
}
void ScriptSlave::SetTime( float time )
{
if( time >= 0.f )
{
movespeed = 0.0f;
movetime = time * 1000.0f;
}
}
void ScriptSlave::StopMove()
{
ClearMove();
}
s_movetype ScriptSlave::getSlaveType()
{
return slavetype;
}
void ScriptSlave::setSlaveType( s_movetype type )
{
slavetype = type;
}
//=== SCRIPT ===\\
void ScriptSlave::EventGetSpeed( Event *ev )
{
ev->AddFloat( GetSpeed() );
}
void ScriptSlave::EventGetTime( Event *ev )
{
ev->AddFloat( GetTime() );
}
void ScriptSlave::EventMove( Event *ev )
{
Move();
}
void ScriptSlave::EventMoveTo( Event *ev )
{
if( ev->IsStringAt( 1 ) || ev->IsVectorAt( 1 ) )
{
Vector pos = ev->GetVector( 1 );
MoveTo( pos );
}
else if( ev->IsEntityAt( 1 ) )
{
Entity *ent = ev->GetEntity( 1 );
MoveTo( ent );
}
}
void ScriptSlave::EventSetSpeed( Event *ev )
{
SetSpeed( ev->GetFloat( 1 ) );
}
void ScriptSlave::EventSetTime( Event *ev )
{
SetTime( ev->GetFloat( 1 ) );
}
void ScriptSlave::EventStopMove( Event *ev )
{
StopMove();
}
void ScriptSlave::EventWaitMove( Event *ev )
{
Move();
}
CLASS_DECLARATION( CAnimate, ScriptSlave, "client_script_object" )
{
{ &EV_ScriptSlave_GetSpeed, &ScriptSlave::EventGetSpeed },
{ &EV_ScriptSlave_GetTime, &ScriptSlave::EventGetTime },
{ &EV_ScriptSlave_Move, &ScriptSlave::EventMove },
{ &EV_ScriptSlave_MoveTo, &ScriptSlave::EventMoveTo },
{ &EV_ScriptSlave_SetSpeed, &ScriptSlave::EventSetSpeed },
{ &EV_ScriptSlave_SetTime, &ScriptSlave::EventSetTime },
{ &EV_ScriptSlave_StopMove, &ScriptSlave::EventStopMove },
{ &EV_ScriptSlave_WaitMove, &ScriptSlave::EventWaitMove },
{ NULL, NULL }
};

View file

@ -0,0 +1,71 @@
#ifndef __SCRIPTSLAVE_H__
#define __SCRIPTSLAVE_H__
#include "canimate.h"
#define MF_GLIDE (1<<0) // The script slave will glide when moving
#define MF_TIMEDMOVE (1<<1) // The script slave will move within the specified time
typedef enum
{
MOVE_UNSET,
MOVE_ENTITY,
MOVE_ORIGIN
} s_movetype;
class ScriptSlave : public Animate
{
private:
int moveflags;
s_movetype slavetype;
float movespeed;
float movetime;
qboolean movetimedone;
float currentTime;
qboolean moving;
union {
SafePtr<Entity> *entity;
float *origin;
} target;
Vector startOrigin;
public:
CLASS_PROTOTYPE( ScriptSlave );
virtual void Archive( Archiver &arc );
ScriptSlave();
~ScriptSlave();
virtual void Think();
void ClearMove();
float GetSpeed();
float GetTime();
void MoveTo( Entity *entity );
void MoveTo( Vector origin );
void Move();
void SetSpeed( float speed );
void SetTime( float time );
void StopMove();
s_movetype getSlaveType();
void setSlaveType( s_movetype type );
void EventGetSpeed( Event *ev );
void EventGetTime( Event *ev );
void EventMove( Event *ev );
void EventMoveTo( Event *ev );
void EventSetSpeed( Event *ev );
void EventSetTime( Event *ev );
void EventStopMove( Event *ev );
void EventWaitMove( Event *ev );
};
#endif /* __SCRIPTSLAVE_H__ */

View file

@ -0,0 +1,147 @@
#ifndef __VISION_H__
#define __VISION_H__
#include "class.h"
class ScriptTimer;
class VisionClass : public Class
{
private:
str name;
str defaultval;
protected:
str string;
ScriptTimer *m_timer;
float value;
float value_start;
float value_target;
public:
qboolean fProcessed;
protected:
void VisionInit( const char *name, const char *value, ScriptTimer *globalTimer );
public:
CLASS_PROTOTYPE( VisionClass );
virtual void Archive( Archiver &arc );
static VisionClass *Get( str name );
static void GlobalArchive( Archiver &arc );
VisionClass();
VisionClass( const char *name, const char *value, ScriptTimer *globalTimer );
virtual void Think();
str GetName();
ScriptTimer *GetTimer();
virtual str GetType();
str defaultValue();
float floatValue();
str stringValue();
virtual qboolean isBasic();
virtual qboolean isEnabled();
virtual qboolean isNewEnabled();
void setFloatValue( float value );
virtual void setValue( str value );
};
class VisionActivator : public VisionClass
{
private:
str vistype;
public:
CLASS_PROTOTYPE( VisionActivator );
virtual void Archive( Archiver &arc );
VisionActivator( const char *name, const char *value, const char *type = "vision", ScriptTimer *globalTimer = NULL );
VisionActivator();
virtual str GetType();
virtual qboolean isBasic();
virtual qboolean isEnabled();
virtual qboolean isNewEnabled();
virtual void setValue( str value );
};
class VisionVariable : public VisionClass
{
private:
VisionActivator *activator;
Vector vector;
// target values
Vector vector_start;
Vector vector_target;
public:
CLASS_PROTOTYPE( VisionVariable );
virtual void Archive( Archiver &arc );
VisionVariable( const char *name, const char *value, VisionActivator *activator );
VisionVariable();
virtual void Think();
VisionActivator *GetActivator();
ScriptTimer *GetTimer();
virtual str GetType();
virtual qboolean isBasic();
virtual qboolean isEnabled();
virtual qboolean isNewEnabled();
Vector vectorValue();
virtual void setValue( str value );
};
extern VisionActivator r_anaglyphTweakEnable;
extern VisionActivator r_distortionEnable;
extern VisionActivator r_filmEnable;
extern VisionActivator r_glow;
extern VisionVariable r_glowRadius0;
extern VisionVariable r_glowRadius1;
extern VisionVariable r_glowBloomCutoff;
extern VisionVariable r_glowBloomDesaturation;
extern VisionVariable r_glowBloomIntensity0;
extern VisionVariable r_glowBloomIntensity1;
extern VisionVariable r_glowBloomStreakX;
extern VisionVariable r_glowBloomStreakY;
extern VisionVariable r_filmContrast;
extern VisionVariable r_filmBleach;
extern VisionVariable r_filmBrightness;
extern VisionVariable r_filmHue;
extern VisionVariable r_filmMidStart;
extern VisionVariable r_filmMidEnd;
extern VisionVariable r_filmDarkTint;
extern VisionVariable r_filmMidTint;
extern VisionVariable r_filmLightTint;
extern VisionVariable r_filmSaturation;
extern VisionVariable r_anaglyphAngleMult;
extern VisionVariable r_anaglyphOffsetMult;
extern VisionVariable r_distortionRadius;
extern VisionVariable r_distortionScale;
#endif