23 Sep 2009

This commit is contained in:
g-cont 2009-09-23 00:00:00 +04:00 committed by Alibek Omarov
parent 9898ac5e0c
commit 2fc0894ba1
29 changed files with 731 additions and 391 deletions

View File

@ -137,7 +137,11 @@ void HUD_UpdateEntityVars( edict_t *ent, skyportal_t *sky, const entity_state_t
ent->v.oldangles = ent->v.angles; // just a delta between frames
ent->v.animtime = state->animtime;
if( state->aiment != 0 )
if( state->groundent != -1 )
ent->v.groundentity = GetEntityByIndex( state->groundent );
else ent->v.groundentity = NULL;
if( state->aiment != -1 )
ent->v.aiment = GetEntityByIndex( state->aiment );
else ent->v.aiment = NULL;
@ -153,7 +157,7 @@ void HUD_UpdateEntityVars( edict_t *ent, skyportal_t *sky, const entity_state_t
ent->v.renderamt = LerpPoint( prev->renderamt, state->renderamt, m_fLerp );
ent->v.scale = LerpPoint( prev->scale, state->scale, m_fLerp );
if(!( ent->v.flags & EF_ANIMATE )) // auto-animation uses v.frame for hold ending frame
if(!( ent->v.effects & EF_ANIMATE )) // auto-animation uses v.frame for hold ending frame
{
float frame = state->frame;
float prevframe = prev->frame;

View File

@ -47,6 +47,7 @@ cvar_t *scr_ofsx;
cvar_t *scr_ofsy;
cvar_t *scr_ofsz;
cvar_t *cl_vsmoothing;
cvar_t *cl_stairsmooth;
cvar_t *cl_forwardspeed;
cvar_t *r_mirrors;
cvar_t *r_portals;
@ -139,7 +140,8 @@ void V_Init( void )
scr_ofsy = g_engfuncs.pfnRegisterVariable( "scr_ofsy", "0", 0, "screen offset by Y" );
scr_ofsz = g_engfuncs.pfnRegisterVariable( "scr_ofsz", "0", 0, "screen offset by Z" );
cl_vsmoothing = g_engfuncs.pfnRegisterVariable( "cl_vsmoothing", "0", 0, "enables lepring in multiplayer" );
cl_vsmoothing = g_engfuncs.pfnRegisterVariable( "cl_vsmoothing", "0.05", 0, "enables lepring in multiplayer" );
cl_stairsmooth = g_engfuncs.pfnRegisterVariable( "cl_vstairsmooth", "100", FCVAR_ARCHIVE, "how fast your view moves upward/downward when running up/down stairs" );
cl_forwardspeed = g_engfuncs.pfnRegisterVariable( "cl_forwardspeed", "200", 0, "client forward speed limit" );
v_iyaw_cycle = g_engfuncs.pfnRegisterVariable( "v_iyaw_cycle", "2", 0, "viewing inverse yaw cycle" );
@ -504,12 +506,7 @@ void V_GetChasePos( ref_params_t *pparams, edict_t *ent, float *cl_angles, Vecto
else angles = cl_angles;
// refresh the position
if( !pparams->smoothing || pparams->demoplayback )
{
// use interpolated values
origin = pparams->simorg + pparams->viewheight;
}
origin = ent->v.origin;
origin[2] += 28; // DEFAULT_VIEWHEIGHT - some offset
V_GetChaseOrigin( angles, origin, cl_chasedist->value, origin );
}
@ -857,19 +854,19 @@ void V_CalcScrOffset( ref_params_t *pparams )
}
//==========================
// V_InterpolateOrigin
// V_InterpolatePos
//==========================
void V_InterpolateOrigin( ref_params_t *pparams )
void V_InterpolatePos( ref_params_t *pparams )
{
edict_t *view;
// view is the weapon model (only visible from inside body )
view = GetViewModel();
if( cl_vsmoothing->value && ( pparams->maxclients > 1 ))
if( cl_vsmoothing->value && ( pparams->smoothing && ( pparams->maxclients > 1 )))
{
int i, foundidx;
float t;
int i, foundidx;
float t;
if( cl_vsmoothing->value < 0.0 ) CVAR_SET_FLOAT( "cl_vsmoothing", 0 );
t = pparams->time - cl_vsmoothing->value;
@ -887,10 +884,10 @@ void V_InterpolateOrigin( ref_params_t *pparams )
double dt;
Vector neworg;
dt = ViewInterp.OriginTime[ (foundidx + 1) & ORIGIN_MASK ] - ViewInterp.OriginTime[foundidx & ORIGIN_MASK];
dt = ViewInterp.OriginTime[(foundidx + 1) & ORIGIN_MASK] - ViewInterp.OriginTime[foundidx & ORIGIN_MASK];
if ( dt > 0.0 )
{
frac = ( t - ViewInterp.OriginTime[ foundidx & ORIGIN_MASK] ) / dt;
frac = ( t - ViewInterp.OriginTime[foundidx & ORIGIN_MASK] ) / dt;
frac = min( 1.0, frac );
delta = ViewInterp.Origins[(foundidx + 1) & ORIGIN_MASK] - ViewInterp.Origins[foundidx & ORIGIN_MASK];
neworg.MA( frac, ViewInterp.Origins[foundidx & ORIGIN_MASK], delta );
@ -909,6 +906,15 @@ void V_InterpolateOrigin( ref_params_t *pparams )
}
}
float V_CalcStairSmoothValue( float oldz, float newz, float smoothtime, float stepheight )
{
if( oldz < newz )
return bound( newz - stepheight, oldz + smoothtime * cl_stairsmooth->value, newz );
else if( oldz > newz )
return bound( newz, oldz - smoothtime * cl_stairsmooth->value, newz + stepheight );
return 0.0;
}
//==========================
// V_CalcFirstPersonRefdef
//==========================
@ -928,16 +934,11 @@ void V_CalcFirstPersonRefdef( ref_params_t *pparams )
bob = V_CalcBob( pparams );
// refresh the position
if( !pparams->smoothing || pparams->demoplayback )
{
// use interpolated values
pparams->vieworg = pparams->simorg + pparams->viewheight;
}
// in-game use predicted values
pparams->viewangles = pparams->cl_viewangles;
pparams->vieworg = pparams->simorg;
pparams->vieworg[2] += ( bob );
pparams->vieworg += pparams->viewheight;
pparams->viewangles = pparams->cl_viewangles;
V_CalcShake();
V_ApplyShake( pparams->vieworg, pparams->viewangles, 1.0 );
@ -956,57 +957,65 @@ void V_CalcFirstPersonRefdef( ref_params_t *pparams )
V_CalcGunAngle( pparams );
// use predicted origin as view origin.
view->v.origin = pparams->vieworg;
view->v.origin = pparams->simorg;
view->v.origin[2] += ( waterOffset );
view->v.origin += pparams->viewheight;
// Let the viewmodel shake at about 10% of the amplitude
V_ApplyShake( view->v.origin, view->v.angles, 0.9 );
for( i = 0; i < 3; i++ )
{
view->v.origin[i] += bob * 0.2 * pparams->forward[i];
view->v.origin[i] += bob * 0.4 * pparams->right[i];
}
view->v.origin[2] += (bob * 0.01f);
for( i = 0; i < 3; i++ ) view->v.origin[i] += bob * 0.4 * pparams->forward[i];
view->v.origin[2] += bob;
view->v.angles[YAW] -= bob * 0.5;
view->v.angles[ROLL] -= bob * 1;
view->v.angles[PITCH] -= bob * 0.3;
view->v.origin[2] -= 1;
view->v.oldangles = view->v.angles;
view->v.oldorigin = view->v.origin;
// fudge position around to keep amount of weapon visible
// roughly equal with different FOV
if( pparams->viewsize == 110 ) view->v.origin[2] += 1;
else if( pparams->viewsize == 100 ) view->v.origin[2] += 2;
else if( pparams->viewsize == 90 ) view->v.origin[2] += 1;
else if( pparams->viewsize == 80 ) view->v.origin[2] += 0.5;
if( g_bMirrorPass || g_bPortalPass || g_bScreenPass )
pparams->punchangle = -pparams->punchangle; // make inverse for mirror
pparams->viewangles += pparams->punchangle;
pparams->viewangles += ev_punchangle;
V_DropPunchAngle( pparams->frametime, ev_punchangle );
static float oldz = 0;
static float stairoldtime = 0;
static float old_client_z = 0;
static float old_weapon_z = 0;
if( !pparams->smoothing && pparams->onground && pparams->simorg[2] - oldz > 0 )
// calculate how much time has passed since the last V_CalcRefdef
float smoothtime = bound( 0.0, pparams->time - stairoldtime, 0.1 );
stairoldtime = pparams->time;
// smooth stair stepping, but only if onground and enabled
if( !pparams->smoothing || !pparams->onground || cl_stairsmooth->value <= 0 )
{
float steptime;
steptime = pparams->time - lasttime;
if( steptime < 0 ) steptime = 0;
oldz += steptime * 150;
if( oldz > pparams->vieworg[2])
oldz = pparams->vieworg[2];
if( pparams->vieworg[2] - oldz > pparams->movevars->stepheight )
oldz = pparams->vieworg[2] - pparams->movevars->stepheight;
pparams->vieworg[2] += oldz - pparams->vieworg[2];
view->v.origin[2] += oldz - pparams->vieworg[2];
old_client_z = pparams->vieworg[2];
old_weapon_z = pparams->vieworg[2];
}
else
{
float result;
float stepheight = pparams->movevars->stepheight;
result = V_CalcStairSmoothValue( old_client_z, pparams->vieworg[2], smoothtime, stepheight );
if( result ) pparams->vieworg[2] = old_client_z = result;
result = V_CalcStairSmoothValue( old_weapon_z, view->v.origin[2], smoothtime, stepheight );
if( result ) view->v.origin[2] = old_weapon_z = result;
}
else oldz = pparams->vieworg[2];
static Vector lastorg;
Vector delta;
delta = pparams->vieworg - lastorg;
delta = pparams->simorg - lastorg;
if( delta.Length() != 0.0 )
{
@ -1014,9 +1023,9 @@ void V_CalcFirstPersonRefdef( ref_params_t *pparams )
ViewInterp.OriginTime[ViewInterp.CurrentOrigin & ORIGIN_MASK] = pparams->time;
ViewInterp.CurrentOrigin++;
lastorg = pparams->vieworg;
lastorg = pparams->simorg;
}
V_InterpolateOrigin( pparams ); // smooth moving in multiplayer
V_InterpolatePos( pparams ); // smooth predicting moving in multiplayer
lasttime = pparams->time;
v_origin = pparams->vieworg;

View File

@ -18,7 +18,9 @@ typedef int string_t;
typedef int shader_t;
typedef struct cvar_s cvar_t;
typedef struct edict_s edict_t;
typedef struct pmove_s pmove_t;
typedef struct movevars_s movevars_t;
typedef struct usercmd_s usercmd_t;
typedef struct cl_priv_s cl_priv_t;
typedef struct sv_priv_s sv_priv_t;
typedef float vec_t;

View File

@ -128,6 +128,14 @@ typedef enum
at_logged // server print to console ( only in multiplayer games ). (NOT IMPLEMENTED)
} ALERT_TYPE;
// filter client messages
typedef enum
{
print_console, // dev. console messages
print_center, // at center of the screen
print_chat, // level high
} PRINT_TYPE;
// edict movetype
typedef enum
{

38
common/pm_defs.h Normal file
View File

@ -0,0 +1,38 @@
//=======================================================================
// Copyright XashXT Group 2009 ©
// pm_defs.h - shared player movement code
//=======================================================================
#ifndef PM_DEFS_H
#define PM_DEFS_H
#define MAX_TOUCH_ENTS 32
typedef struct pmove_s
{
// state (in / out)
edict_t ps; // client state
// command (in)
usercmd_t cmd;
bool snapinitial; // if is has been changed outside pmove
movevars_t *movevars; // sv.movevars
// results (out)
int numtouch;
edict_t *touchents[MAX_TOUCH_ENTS];
vec3_t viewangles; // clamped
float viewheight;
vec3_t mins, maxs; // bounding box size
edict_t *groundentity;
int watertype;
int waterlevel;
// engine toolbox
trace_t (*trace)( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end );
int (*pointcontents)( vec3_t point );
};
#endif//PM_DEFS_H

View File

@ -57,9 +57,6 @@ typedef struct enginefuncs_s
// interface validator
int api_size; // must matched with sizeof( enginefuncs_t )
void* (*pfnMemAlloc)( size_t cb, const char *filename, const int fileline );
void (*pfnMemCopy)( void *dest, const void *src, size_t cb, const char *filename, const int fileline );
void (*pfnMemFree)( void *mem, const char *filename, const int fileline );
int (*pfnPrecacheModel)( const char* s );
int (*pfnPrecacheSound)( const char* s );
void (*pfnSetModel)( edict_t *e, const char *m );
@ -67,6 +64,8 @@ typedef struct enginefuncs_s
int (*pfnModelFrames)( int modelIndex );
void (*pfnSetSize)( edict_t *e, const float *rgflMin, const float *rgflMax );
void (*pfnChangeLevel)( const char* s1, const char* s2 );
edict_t* (*pfnFindClientInPHS)( edict_t *pEdict ); // was pfnGetSpawnParms
edict_t* (*pfnEntitiesInPHS)( edict_t *pplayer ); // was pfnSaveSpawnParms
float (*pfnVecToYaw)( const float *rgflVector );
void (*pfnVecToAngles)( const float *rgflVectorIn, float *rgflVectorOut );
void (*pfnMoveToOrigin)( edict_t *ent, const float *pflGoal, float dist, int iMoveType );
@ -76,27 +75,26 @@ typedef struct enginefuncs_s
int (*pfnGetEntityIllum)( edict_t* pEnt );
edict_t* (*pfnFindEntityInSphere)( edict_t *pStartEdict, const float *org, float rad );
edict_t* (*pfnFindClientInPVS)( edict_t *pEdict );
edict_t* (*pfnFindClientInPHS)( edict_t *pEdict );
edict_t* (*pfnEntitiesInPVS)( edict_t *pplayer );
edict_t* (*pfnEntitiesInPHS)( edict_t *pplayer );
void (*pfnMakeVectors)( const float *rgflVector );
void (*pfnAngleVectors)( const float *rgflVector, float *forward, float *right, float *up );
edict_t* (*pfnCreateEntity)( void );
void (*pfnRemoveEntity)( edict_t* e );
edict_t* (*pfnCreateNamedEntity)( string_t className );
void (*pfnMakeStatic)( edict_t *ent );
void (*pfnLinkEdict)( edict_t *e );
void (*pfnLinkEdict)( edict_t *e ); // was pfnEntIsOnFloor
int (*pfnDropToFloor)( edict_t* e );
int (*pfnWalkMove)( edict_t *ent, float yaw, float dist, int iMode );
void (*pfnSetOrigin)( edict_t *e, const float *rgflOrigin );
void (*pfnSetAngles)( edict_t *e, const float *rgflAngles );
void (*pfnEmitSound)( edict_t *ent, int chan, const char *sample, float vol, float attn, int flags, int pitch );
void (*pfnEmitAmbientSound)( edict_t *ent, float *pos, const char *samp, float vol, float attn, int flags, int pitch );
void (*pfnTraceLine)( const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr );
void (*pfnTraceToss)( edict_t* pent, edict_t* pentToIgnore, TraceResult *ptr );
int (*pfnTraceMonsterHull)( edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr );
void (*pfnTraceHull)( const float *v1, const float *mins, const float *maxs, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr );
void (*pfnTraceModel)( const float *v1, const float *v2, edict_t *pent, TraceResult *ptr );
const char *(*pfnTraceTexture)( edict_t *pTextureEntity, const float *v1, const float *v2 );
void (*pfnTraceSphere)( const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr );
void (*pfnGetAimVector)( edict_t* ent, float speed, float *rgflReturn );
void (*pfnServerCommand)( const char* str );
void (*pfnServerExecute)( void );
@ -113,7 +111,6 @@ typedef struct enginefuncs_s
void (*pfnWriteLong)( int iValue );
void (*pfnWriteAngle)( float flValue );
void (*pfnWriteCoord)( float flValue );
void (*pfnWriteFloat)( float flValue );
void (*pfnWriteString)( const char *sz );
void (*pfnWriteEntity)( int iValue );
cvar_t* (*pfnCVarRegister)( const char *name, const char *value, int flags, const char *desc );
@ -122,10 +119,13 @@ typedef struct enginefuncs_s
void (*pfnCVarSetFloat)( const char *szVarName, float flValue );
void (*pfnCVarSetString)( const char *szVarName, const char *szValue );
void (*pfnAlertMessage)( ALERT_TYPE level, char *szFmt, ... );
void (*pfnWriteFloat)( float flValue ); // was pfnEngineFprintf
void* (*pfnPvAllocEntPrivateData)( edict_t *pEdict, long cb );
void* (*pfnPvEntPrivateData)( edict_t *pEdict );
void (*pfnFreeEntPrivateData)( edict_t *pEdict );
const char *(*pfnGetString)( string_t iString ); // was pfnSzFromIndex
string_t (*pfnAllocString)( const char *szValue );
const char *(*pfnGetString)( string_t iString );
entvars_t *(*pfnGetVarsOfEnt)( edict_t *pEdict );
edict_t* (*pfnPEntityOfEntOffset)( int iEntOffset );
int (*pfnEntOffsetOfPEntity)( const edict_t *pEdict );
int (*pfnIndexOfEdict)( const edict_t *pEdict );
@ -137,50 +137,60 @@ typedef struct enginefuncs_s
void (*pfnGetBonePosition)( const edict_t* pEdict, int iBone, float *rgflOrigin, float *rgflAngles );
dword (*pfnFunctionFromName)( const char *pName );
const char *(*pfnNameForFunction)( dword function );
void (*pfnClientPrintf)( edict_t* pEdict, PRINT_TYPE ptype, const char *szMsg );
void (*pfnServerPrint)( const char *szMsg );
void (*pfnAreaPortal)( edict_t *pEdict, BOOL enable );
void (*pfnClassifyEdict)( edict_t *pEdict, int ed_type );
const char *(*pfnCmd_Args)( void );
const char *(*pfnCmd_Argv)( int argc );
int (*pfnCmd_Argc)( void );
void (*pfnGetAttachment)( const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles );
void (*pfnCRC_Init)( word *pulCRC );
void (*pfnCRC_ProcessBuffer)( word *pulCRC, void *p, int len );
void (*pfnCRC_ProcessByte)( word *pulCRC, byte ch );
word (*pfnCRC_Final)( word pulCRC );
long (*pfnRandomLong)( long lLow, long lHigh );
float (*pfnRandomFloat)( float flLow, float flHigh );
void (*pfnSetView)( const edict_t *pClient, const edict_t *pViewent );
float (*pfnTime)( void ); // host.realtime, not sv.time
void (*pfnCrosshairAngle)( const edict_t *pClient, float pitch, float yaw );
byte* (*pfnLoadFile)( const char *filename, int *pLength );
void *(*pfnFOpen)( const char* path, const char* mode );
int (*pfnFClose)( void *file );
long (*pfnFWrite)( void *file, const void* data, size_t datasize);
long (*pfnFRead)( void *file, void* buffer, size_t buffersize );
int (*pfnFGets)( void *file, byte *string, size_t bufsize );
int (*pfnFSeek)( void *file, long offset, int whence );
long (*pfnFTell)( void *file );
int (*pfnFileExists)( const char *filename );
void (*pfnFreeFile)( void *buffer );
void (*pfnEndGame)( const char *engine_command ); // was pfnEndSection
int (*pfnCompareFileTime)( const char *filename1, const char *filename2, int *iCompare );
void (*pfnGetGameDir)( char *szGetGameDir );
void (*pfnStaticDecal)( const float *origin, int decalIndex, int entityIndex, int modelIndex );
int (*pfnPrecacheGeneric)( const char* s );
int (*pfnIsDedicatedServer)( void ); // is this a dedicated server?
int (*pfnIsMapValid)( char *filename );
void (*pfnInfo_RemoveKey)( char *s, char *key );
void (*pfnClassifyEdict)( edict_t *pEdict, int ed_type ); // was pfnCvar_RegisterVariable
void (*pfnAreaPortal)( edict_t *pEdict, BOOL enable ); // was pfnFadeClientVolume
void (*pfnSetClientMaxspeed)( const edict_t *pEdict, float fNewMaxspeed );
edict_t *(*pfnCreateFakeClient)( const char *netname ); // returns NULL if fake client can't be created
void (*pfnThinkFakeClient)( edict_t *client, usercmd_t *cmd ); // was pfnRunPlayerMove, like it
int (*pfnFileExists)( const char *filename ); // was pfnNumberOfEntities - see gpGlobals->numEntities
char* (*pfnGetInfoKeyBuffer)( edict_t *e ); // passing in NULL gets the serverinfo
char* (*pfnInfoKeyValue)( char *infobuffer, char *key );
void (*pfnSetKeyValue)( char *infobuffer, char *key, char *value );
char* (*pfnGetInfoKeyBuffer)( edict_t *e ); // passing in NULL gets the serverinfo
void (*pfnSetClientKeyValue)( int clientIndex, char *infobuffer, char *key, char *value );
int (*pfnIsMapValid)( char *filename );
void (*pfnStaticDecal)( const float *origin, int decalIndex, int entityIndex, int modelIndex );
int (*pfnPrecacheGeneric)( const char* s );
void (*pfnSetSkybox)( const char *name ); // was pfnGetPlayerUserId
void (*pfnPlayMusic)( const char *trackname, int flags ); // was pfnBuildSoundMsg
int (*pfnIsDedicatedServer)( void ); // is this a dedicated server?
void* (*pfnMemAlloc)(size_t cb, const char *file, const int line);// was pfnCVarGetPointer
void (*pfnMemFree)(void *mem, const char *file, const int line); // was pfnGetPlayerWONId
void (*pfnInfo_RemoveKey)( char *s, char *key );
void *(*pfnFOpen)( const char* path, const char* mode ); // was pfnGetPhysicsKeyValue
int (*pfnFClose)( void *file ); // was pfnSetPhysicsKeyValue
long (*pfnFTell)( void *file ); // was pfnGetPhysicsInfoString
word (*pfnPrecacheEvent)( int type, const char *psz );
void (*pfnPlaybackEvent)( int flags, const edict_t *pInvoker, word eventindex, float delay, event_args_t *args );
long (*pfnFWrite)(void *file, const void* data, size_t datasize);// was pfnSetFatPVS
long (*pfnFRead)( void *file, void* buffer, size_t buffersize ); // was pfnSetFatPAS
int (*pfnFGets)( void *file, byte *string, size_t bufsize ); // was pfnCheckVisibility
int (*pfnFSeek)( void *file, long offset, int whence ); // was pfnDeltaSetField
void (*pfnDropClient)( int clientIndex ); // was pfnDeltaUnsetField
void (*pfnHostError)( const char *szFmt, ... ); // was pfnDeltaAddEncoder
void (*pfnGetPlayerPing)( const edict_t *pClient, int *ping ); // was pfnGetCurrentPlayer
BOOL (*pfnCanSkipPlayer)( const edict_t *player );
void (*pfnSetSkybox)( const char *name );
void (*pfnPlayMusic)( const char *trackname, int flags ); // background track
void (*pfnDropClient)( int clientIndex ); // used for kick cheaters from server
void (*pfnHostError)( const char *szFmt, ... ); // invoke host error
// after this point enginefuncs_t completely unmatched with Half-Life interface
} enginefuncs_t;
// passed to pfnKeyValue
@ -239,7 +249,7 @@ typedef struct saverestore_s
char szLandmarkName[64]; // probably not used
vec3_t vecLandmarkOffset; // for landmark transitions
char szCurrentMap[64]; // ENG To check global entities
float time; // ENG
float time; // ENG current sv.time
} SAVERESTOREDATA;
typedef enum _fieldtypes
@ -330,11 +340,18 @@ typedef struct
void (*pfnEndFrame)( void );
void (*pfnBuildLevelList)( void );
int (*pfnShouldCollide)( edict_t *pentTouched, edict_t *pentOther );
int (*pfnClassifyEdict)( edict_t *pentToClassify );
void (*pfnUpdateEntityState)( struct entity_state_s *to, edict_t *from, int baseline );
void (*pfnOnFreeEntPrivateData)( edict_t *pEnt );
// returns string describing current .dll. E.g., TeamFotrress 2, Half-Life
const char *(*pfnGetGameDescription)( void );
// Spectator funcs
void (*pfnSpectatorConnect)( edict_t *pEntity );
void (*pfnSpectatorDisconnect)( edict_t *pEntity );
void (*pfnSpectatorThink)( edict_t *pEntity );
} DLL_FUNCTIONS;
typedef int (*SERVERAPI)( DLL_FUNCTIONS *pFunctionTable, enginefuncs_t* engfuncs, globalvars_t *pGlobals );

View File

@ -15,6 +15,6 @@ typedef struct usercmd_s
int sidemove;
int upmove;
int buttons;
} usercmd_t;
};
#endif//USER_CMD_H

View File

@ -5,6 +5,7 @@
#include "common.h"
#include "client.h"
#include "pm_defs.h"
#include "matrix_lib.h"
#include "const.h"

View File

@ -57,11 +57,7 @@ void V_SetupRefDef( void )
VectorCopy( clent->v.punchangle, cl.refdef.punchangle );
cl.refdef.movevars = &clgame.movevars;
if( clent->v.flags & FL_ONGROUND )
cl.refdef.onground = clent->v.groundentity;
else cl.refdef.onground = NULL;
cl.refdef.onground = clent->v.groundentity;
cl.refdef.areabits = cl.frame.areabits;
cl.refdef.health = clent->v.health;
cl.refdef.movetype = clent->v.movetype;
@ -76,10 +72,11 @@ void V_SetupRefDef( void )
cl.refdef.smoothing = cl_predict->integer;
cl.refdef.waterlevel = clent->v.waterlevel;
cl.refdef.flags = cl.render_flags;
cl.refdef.viewsize = 120; // fixme if you can
cl.refdef.nextView = 0;
// calculate the origin
if( cl.refdef.smoothing && !cl.refdef.demoplayback )
if( cl_predict->integer && !cl.refdef.demoplayback )
{
// use predicted values
int i, delta;

View File

@ -122,6 +122,7 @@ int Host_MaxClients( void );
void Host_AbortCurrentFrame( void );
void Host_WriteDefaultConfig( void );
void Host_WriteConfig( void );
int Host_Milliseconds( void );
void Host_Print( const char *txt );
void Host_Error( const char *error, ... );
@ -160,6 +161,7 @@ PRVM INTERACTIONS
void pfnMemCopy( void *dest, const void *src, size_t cb, const char *filename, const int fileline );
cvar_t *pfnCVarRegister( const char *szName, const char *szValue, int flags, const char *szDesc );
byte* pfnLoadFile( const char *filename, int *pLength );
void pfnFreeFile( void *buffer );
int pfnFileExists( const char *filename );
long pfnRandomLong( long lLow, long lHigh );
float pfnRandomFloat( float flLow, float flHigh );
@ -172,6 +174,7 @@ int pfnFSeek( void *file, long offset, int whence );
int pfnFClose( void *file );
long pfnFTell( void *file );
void pfnGetGameDir( char *szGetGameDir );
float pfnTime( void );
#define prog vm->prog // global callback to vprogs.dll
#define PRVM_EDICT_NUM( num ) _PRVM_EDICT_NUM( num, __FILE__, __LINE__ )

View File

@ -21,6 +21,11 @@ byte* pfnLoadFile( const char *filename, int *pLength )
return FS_LoadFile( filename, pLength );
}
void pfnFreeFile( void *buffer )
{
if( buffer ) Mem_Free( buffer );
}
/*
=============
pfnFileExists
@ -54,6 +59,17 @@ float pfnRandomFloat( float flLow, float flHigh )
return Com_RandomFloat( flLow, flHigh );
}
/*
=============
pfnTime
=============
*/
float pfnTime( void )
{
return (Host_Milliseconds() * 0.001f);
}
/*
=============
pfnCVarRegister

View File

@ -70,9 +70,9 @@ static net_field_t ent_fields[] =
{ ES_FIELD(flags), NET_LONG, false }, // misc edict flags
{ ES_FIELD(movetype), NET_BYTE, false },
{ ES_FIELD(gravity), NET_SHORT, false }, // gravity multiplier
{ ES_FIELD(aiment), NET_WORD, false }, // entity index
{ ES_FIELD(aiment), NET_SHORT, false }, // entity index
{ ES_FIELD(owner), NET_WORD, false }, // entity owner index
{ ES_FIELD(groundent), NET_WORD, false }, // ground entity index, if FL_ONGROUND is set
{ ES_FIELD(groundent), NET_SHORT, false }, // ground entity index, if FL_ONGROUND is set
{ ES_FIELD(solid), NET_LONG, false }, // encoded mins/maxs
{ ES_FIELD(mins[0]), NET_FLOAT, false },
{ ES_FIELD(mins[1]), NET_FLOAT, false },
@ -82,10 +82,10 @@ static net_field_t ent_fields[] =
{ ES_FIELD(maxs[2]), NET_FLOAT, false },
{ ES_FIELD(effects), NET_LONG, false }, // effect flags
{ ES_FIELD(renderfx), NET_LONG, false }, // renderfx flags
{ ES_FIELD(renderamt), NET_COLOR, false }, // alpha amount
{ ES_FIELD(rendercolor[0]), NET_COLOR, false }, // stateflags_t #2 (4 bytes)
{ ES_FIELD(rendercolor[1]), NET_COLOR, false },
{ ES_FIELD(rendercolor[2]), NET_COLOR, false },
{ ES_FIELD(renderamt), NET_FLOAT, false }, // alpha amount
{ ES_FIELD(rendercolor[0]), NET_FLOAT, false }, // stateflags_t #2 (4 bytes)
{ ES_FIELD(rendercolor[1]), NET_FLOAT, false },
{ ES_FIELD(rendercolor[2]), NET_FLOAT, false },
{ ES_FIELD(oldorigin[0]), NET_FLOAT, true },
{ ES_FIELD(oldorigin[1]), NET_FLOAT, true },
{ ES_FIELD(oldorigin[2]), NET_FLOAT, true },

View File

@ -1,88 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: engine - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP9E49.tmp" with contents
[
user32.lib msvcrtd.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"..\temp\engine\!debug/engine.pdb" /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"..\temp\engine\!debug/engine.dll" /implib:"..\temp\engine\!debug/engine.lib" /pdbtype:sept
"\Xash3D\src_main\temp\engine\!debug\cinematic.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_cmds.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_demo.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_effects.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_frame.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_game.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_input.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_main.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_parse.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_phys.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_scrn.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_view.obj"
"\Xash3D\src_main\temp\engine\!debug\com_library.obj"
"\Xash3D\src_main\temp\engine\!debug\con_keys.obj"
"\Xash3D\src_main\temp\engine\!debug\con_main.obj"
"\Xash3D\src_main\temp\engine\!debug\con_utils.obj"
"\Xash3D\src_main\temp\engine\!debug\engfuncs.obj"
"\Xash3D\src_main\temp\engine\!debug\engine.obj"
"\Xash3D\src_main\temp\engine\!debug\host.obj"
"\Xash3D\src_main\temp\engine\!debug\infostring.obj"
"\Xash3D\src_main\temp\engine\!debug\input.obj"
"\Xash3D\src_main\temp\engine\!debug\net_chan.obj"
"\Xash3D\src_main\temp\engine\!debug\net_huff.obj"
"\Xash3D\src_main\temp\engine\!debug\net_msg.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_client.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_cmds.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_frame.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_game.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_init.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_main.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_move.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_phys.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_save.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_world.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_advanced.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_audio.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_controls.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_credits.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_defaults.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_demos.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_gameoptions.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_gotosite.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_ingame.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_loadgame.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_main.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_menu.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_mods.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_multiplayer.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_network.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_options.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_performance.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_playersetup.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_qmenu.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_quit.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_savegame.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_singleplayer.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_video.obj"
]
Creating command line "link.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP9E49.tmp"
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP9E4A.bat" with contents
[
@echo off
copy \Xash3D\src_main\temp\engine\!debug\engine.dll "D:\Xash3D\bin\engine.dll"
]
Creating command line "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP9E4A.bat"
Linking...
<h3>Output Window</h3>
Performing Custom Build Step on \Xash3D\src_main\temp\engine\!debug\engine.dll
‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
<h3>Results</h3>
engine.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -6,6 +6,7 @@
#include "common.h"
#include "const.h"
#include "server.h"
#include "pm_defs.h"
#define MAX_FORWARD 6

View File

@ -1457,29 +1457,6 @@ void pfnSetOrigin( edict_t *e, const float *rgflOrigin )
SV_LinkEdict( e );
}
/*
=================
pfnSetAngles
=================
*/
void pfnSetAngles( edict_t *e, const float *rgflAngles )
{
if( e == EDICT_NUM( 0 )) return;
if( e->free )
{
MsgDev( D_ERROR, "SV_SetAngles: can't modify free entity\n" );
return;
}
if( VectorCompare( rgflAngles, e->v.angles ))
return; // already there ?
VectorCopy( rgflAngles, e->v.angles );
Matrix3x3_FromAngles( e->v.angles, e->v.m_pmatrix );
Matrix3x3_Transpose( e->v.m_pmatrix, e->v.m_pmatrix );
}
/*
=================
SV_StartSound
@ -1642,11 +1619,38 @@ static void pfnTraceHull( const float *v1, const float *mins, const float *maxs,
SV_CopyTraceResult( ptr, trace );
}
/*
=============
pfnTraceMonsterHull
FIXME: implement
=============
*/
static int pfnTraceMonsterHull( edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr )
{
// FIXME: implement
return 0;
}
/*
=============
pfnTraceModel
FIXME: implement
=============
*/
static void pfnTraceModel( const float *v1, const float *v2, edict_t *pent, TraceResult *ptr )
{
// FIXME: implement
}
/*
=============
pfnTraceSphere
FIXME: implement
=============
*/
static const char *pfnTraceTexture( edict_t *pTextureEntity, const float *v1, const float *v2 )
{
trace_t trace;
@ -1659,6 +1663,17 @@ static const char *pfnTraceTexture( edict_t *pTextureEntity, const float *v1, co
return trace.pTexName;
}
/*
=============
pfnTraceSphere
FIXME: implement
=============
*/
static void pfnTraceSphere( const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr )
{
}
/*
=============
pfnGetAimVector
@ -2104,7 +2119,20 @@ void *pfnPvAllocEntPrivateData( edict_t *pEdict, long cb )
return pEdict->pvPrivateData;
}
/*
/*
=============
pfnPvEntPrivateData
=============
*/
void *pfnPvEntPrivateData( edict_t *pEdict )
{
if( pEdict )
return pEdict->pvPrivateData;
return NULL;
}
/*
=============
pfnFreeEntPrivateData
@ -2139,6 +2167,19 @@ const char *SV_GetString( string_t iString )
return StringTable_GetString( svgame.hStringTable, iString );
}
/*
=============
pfnGetVarsOfEnt
=============
*/
entvars_t *pfnGetVarsOfEnt( edict_t *pEdict )
{
if( pEdict )
return &pEdict->v;
return NULL;
}
/*
=============
pfnPEntityOfEntOffset
@ -2320,6 +2361,17 @@ const char *pfnNameForFunction( dword function )
return NULL;
}
/*
=============
pfnClientPrintf
=============
*/
void pfnClientPrintf( edict_t* pEdict, PRINT_TYPE ptype, const char *szMsg )
{
// FIXME: implement
}
/*
=============
pfnServerPrint
@ -2375,6 +2427,34 @@ void pfnClassifyEdict( edict_t *pEdict, int class )
MsgDev( D_NOTE, "%s: <%s>\n", STRING( pEdict->v.classname ), ed_name[class] );
}
/*
=============
pfnSetClientMaxspeed
=============
*/
void pfnSetClientMaxspeed( const edict_t *pEdict, float fNewMaxspeed )
{
// FIXME: implement
}
/*
=============
pfnCreateFakeClient
=============
*/
edict_t *pfnCreateFakeClient( const char *netname )
{
// FIXME: implement SV_FakeClientConnect properly
return NULL;
}
void pfnThinkFakeClient( edict_t *client, usercmd_t *cmd )
{
// FIXME: implement
}
/*
=============
pfnCmd_Args
@ -2445,6 +2525,17 @@ void pfnCRC_ProcessBuffer( word *pulCRC, void *p, int len )
while( len-- ) CRC_ProcessByte( pulCRC, *start++ );
}
/*
=============
pfnCRC_ProcessByte
=============
*/
void pfnCRC_ProcessByte( word *pulCRC, byte ch )
{
CRC_ProcessByte( pulCRC, ch );
}
/*
=============
pfnCRC_Final
@ -2757,6 +2848,17 @@ void pfnSetView( const edict_t *pClient, const edict_t *pViewent )
MSG_Send( MSG_ONE_R, NULL, client->edict );
}
/*
=============
pfnEndGame
=============
*/
void pfnEndGame( const char *engine_command )
{
// FIXME: implement
}
/*
=============
pfnSetSkybox
@ -2799,14 +2901,22 @@ void pfnDropClient( int clientIndex )
}
SV_DropClient( svs.clients + clientIndex );
}
/*
=============
pfnGetPlayerPing
=============
*/
void pfnGetPlayerPing( const edict_t *pClient, int *ping )
{
// FIXME: implement
}
// engine callbacks
static enginefuncs_t gEngfuncs =
{
sizeof( enginefuncs_t ),
pfnMemAlloc,
pfnMemCopy,
pfnMemFree,
pfnPrecacheModel,
pfnPrecacheSound,
pfnSetModel,
@ -2814,6 +2924,8 @@ static enginefuncs_t gEngfuncs =
pfnModelFrames,
pfnSetSize,
pfnChangeLevel,
pfnFindClientInPHS,
pfnEntitiesInPHS,
pfnVecToYaw,
pfnVecToAngles,
pfnMoveToOrigin,
@ -2823,28 +2935,27 @@ static enginefuncs_t gEngfuncs =
pfnGetEntityIllum,
pfnFindEntityInSphere,
pfnFindClientInPVS,
pfnFindClientInPHS,
pfnEntitiesInPVS,
pfnEntitiesInPHS,
pfnMakeVectors,
AngleVectors,
pfnCreateEntity,
pfnRemoveEntity,
pfnCreateNamedEntity,
pfnCreateNamedEntity,
pfnMakeStatic,
pfnLinkEntity,
pfnDropToFloor,
pfnWalkMove,
pfnSetOrigin,
pfnSetAngles,
SV_StartSound,
pfnEmitAmbientSound,
pfnTraceLine,
pfnTraceToss,
pfnTraceMonsterHull,
pfnTraceHull,
pfnTraceModel,
pfnTraceTexture,
pfnGetAimVector,
pfnTraceSphere,
pfnGetAimVector,
pfnServerCommand,
pfnServerExecute,
pfnClientCommand,
@ -2860,7 +2971,6 @@ static enginefuncs_t gEngfuncs =
pfnWriteLong,
pfnWriteAngle,
pfnWriteCoord,
pfnWriteFloat,
pfnWriteString,
pfnWriteEntity,
pfnCVarRegister,
@ -2869,10 +2979,13 @@ static enginefuncs_t gEngfuncs =
pfnCVarSetFloat,
pfnCVarSetString,
pfnAlertMessage,
pfnWriteFloat,
pfnPvAllocEntPrivateData,
pfnPvEntPrivateData,
pfnFreeEntPrivateData,
SV_AllocString,
SV_GetString,
SV_AllocString,
pfnGetVarsOfEnt,
pfnPEntityOfEntOffset,
pfnEntOffsetOfPEntity,
pfnIndexOfEdict,
@ -2884,47 +2997,58 @@ static enginefuncs_t gEngfuncs =
pfnGetBonePosition,
pfnFunctionFromName,
pfnNameForFunction,
pfnClientPrintf,
pfnServerPrint,
pfnAreaPortal,
pfnClassifyEdict,
pfnCmd_Args,
pfnCmd_Args,
pfnCmd_Argv,
pfnCmd_Argc,
pfnCmd_Argc,
pfnGetAttachment,
pfnCRC_Init,
pfnCRC_ProcessBuffer,
pfnCRC_Final,
pfnCRC_ProcessByte,
pfnCRC_Final,
pfnRandomLong,
pfnRandomFloat,
pfnSetView,
pfnTime,
pfnCrosshairAngle,
pfnLoadFile,
pfnFreeFile,
pfnEndGame,
pfnCompareFileTime,
pfnGetGameDir,
pfnClassifyEdict,
pfnAreaPortal,
pfnSetClientMaxspeed,
pfnCreateFakeClient,
pfnThinkFakeClient,
pfnFileExists,
pfnGetInfoKeyBuffer,
pfnInfoKeyValue,
pfnSetKeyValue,
pfnSetClientKeyValue,
pfnIsMapValid,
pfnStaticDecal,
pfnPrecacheGeneric,
pfnSetSkybox,
pfnPlayMusic,
pfnIsDedicatedServer,
pfnMemAlloc,
pfnMemFree,
pfnInfo_RemoveKey,
pfnFOpen,
pfnFClose,
pfnFTell,
pfnPrecacheEvent,
pfnPlaybackEvent,
pfnFWrite,
pfnFRead,
pfnFGets,
pfnFSeek,
pfnFTell,
pfnFileExists,
pfnCompareFileTime,
pfnGetGameDir,
pfnStaticDecal,
pfnPrecacheGeneric,
pfnIsDedicatedServer,
pfnIsMapValid,
pfnInfo_RemoveKey,
pfnInfoKeyValue,
pfnSetKeyValue,
pfnGetInfoKeyBuffer,
pfnSetClientKeyValue,
pfnPrecacheEvent,
pfnPlaybackEvent,
pfnDropClient,
Host_Error,
pfnGetPlayerPing,
pfnCanSkipPlayer,
pfnSetSkybox,
pfnPlayMusic,
pfnDropClient,
Host_Error
};
/*

View File

@ -1428,7 +1428,11 @@ static void R_ShaderpassRenderMode( ref_stage_t *pass )
pass->alphaGen.type = ALPHAGEN_ENTITY;
break;
case mod_alias:
break;
case mod_studio:
pass->glState = (GLSTATE_SRCBLEND_SRC_ALPHA|GLSTATE_DSTBLEND_ONE);
pass->rgbGen.type = RGBGEN_IDENTITY_LIGHTING; // models ignore color in 'add' mode
pass->alphaGen.type = ALPHAGEN_ENTITY;
break;
case mod_sprite:
pass->glState = (GLSTATE_SRCBLEND_SRC_ALPHA|GLSTATE_DSTBLEND_ONE);

View File

@ -264,8 +264,17 @@ typedef struct studiovars_s
mouth_t mouth; // UNDONE: for synchronizing mouth movements.
float blending[MAXSTUDIOBLENDS];
float controller[MAXSTUDIOCONTROLLERS];
vec3_t gaitorigin; // player stuff
vec3_t gaitorigin; // client oldorigin used to calc velocity
float gaitframe; // client->frame + yaw
float gaityaw; // local value
// EF_ANIMATE stuff
int m_fSequenceLoops; // sequence is looped
int m_fSequenceFinished; // sequence is finished
float m_flFrameRate; // looped sequence framerate
float m_flGroundSpeed; // looped sequence ground speed (movement)
float m_flLastEventCheck; // last time when event is checked
// cached bones, valid only for current frame
char bonenames[MAXSTUDIOBONES][32];// used for attached entities
matrix4x4 rotationmatrix;
@ -314,14 +323,8 @@ typedef struct ref_entity_s
int colormap; // q1 and hl1 model colormap (can applied for sprites)
int flags; // q1 effect flags, EF_ROTATE, EF_DIMLIGHT etc
// EF_ANIMATE stuff
int m_fSequenceLoops;
int m_fSequenceFinished;
// client gait sequence (local stuff)
int gaitsequence; // client->sequence + yaw
float gaitframe; // client->frame + yaw
float gaityaw; // local value
// most recent data
vec3_t axis[3];

View File

@ -2126,30 +2126,6 @@ bool R_AddGenericEntity( edict_t *pRefEntity, ref_entity_t *refent )
{
switch( refent->model->type )
{
case mod_studio:
if( pRefEntity->v.frame == -1 )
{
pRefEntity->v.frame = refent->frame = 0;
refent->sequence = pRefEntity->v.sequence;
R_StudioResetSequenceInfo( refent );
}
else
{
R_StudioFrameAdvance( refent, 0 );
if( refent->m_fSequenceFinished )
{
if( refent->m_fSequenceLoops )
pRefEntity->v.frame = -1;
// hold at last frame
}
else
{
// copy current frame back to let user grab it on a client-side
pRefEntity->v.frame = refent->frame;
}
}
break;
case mod_sprite:
if(((msprite_t *)refent->model->extradata)->numframes > 1 )
{
@ -2160,6 +2136,7 @@ bool R_AddGenericEntity( edict_t *pRefEntity, ref_entity_t *refent )
refent->frame = fmod( refent->frame, numframes );
}
break;
case mod_studio:
case mod_alias:
case mod_brush:
case mod_world:

View File

@ -504,7 +504,7 @@ bool R_DrawSpriteModel( const meshbuffer_t *mb )
lerp = bound( 0, lerp, 1 );
ilerp = 1.0f - lerp;
if( ilerp != 0 )
if( ilerp != 0 && oldframe->shader > 0 && oldframe->shader < MAX_SHADERS ) // FIXME
{
e->renderamt = renderamt * ilerp; // merge prevframe alpha
rb->shaderkey = r_shaders[oldframe->shader].sortkey;

View File

@ -119,7 +119,32 @@ void R_StudioAllocExtradata( edict_t *in, ref_entity_t *e )
studio->latched.blending[i] = studio->blending[i];
}
if(!( e->flags & EF_ANIMATE ))
if( e->flags & EF_ANIMATE )
{
if( in->v.frame == -1 )
{
in->v.frame = e->frame = 0;
e->sequence = in->v.sequence;
R_StudioResetSequenceInfo( e );
}
else
{
R_StudioFrameAdvance( e, 0 );
if( studio->m_fSequenceFinished )
{
if( studio->m_fSequenceLoops )
in->v.frame = -1;
// hold at last frame
}
else
{
// copy current frame back to let user grab it on a client-side
in->v.frame = e->frame;
}
}
}
else
{
e->sequence = in->v.sequence;
e->prev.animtime = e->animtime; // must be update each frame!
@ -508,8 +533,39 @@ int R_StudioGetSequenceFlags( dstudiohdr_t *hdr, ref_entity_t *ent )
return pseqdesc->flags;
}
void R_StuioGetSequenceInfo( dstudiohdr_t *hdr, ref_entity_t *ent, float *pflFrameRate, float *pflGroundSpeed )
{
dstudioseqdesc_t *pseqdesc;
if( !hdr || ent->sequence >= hdr->numseq )
{
*pflFrameRate = 0.0;
*pflGroundSpeed = 0.0;
return;
}
pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + ent->sequence;
if( pseqdesc->numframes > 1 )
{
*pflFrameRate = 256 * pseqdesc->fps / (pseqdesc->numframes - 1);
*pflGroundSpeed = com.sqrt( DotProduct( pseqdesc->linearmovement, pseqdesc->linearmovement ));
*pflGroundSpeed = *pflGroundSpeed * pseqdesc->fps / (pseqdesc->numframes - 1);
}
else
{
*pflFrameRate = 256.0;
*pflGroundSpeed = 0.0;
}
}
float R_StudioFrameAdvance( ref_entity_t *ent, float flInterval )
{
studiovars_t *pstudio = (studiovars_t *)ent->extradata;
if( !ent->extradata )
return 0.0;
if( flInterval == 0.0 )
{
flInterval = ( RI.refdef.time - ent->animtime );
@ -521,17 +577,15 @@ float R_StudioFrameAdvance( ref_entity_t *ent, float flInterval )
}
if( !ent->animtime ) flInterval = 0.0;
// stop auto-animation on pause
if( !r_paused->integer )
ent->frame += flInterval * ent->framerate;
//ent->animtime = RI.refdef.time;
ent->frame += flInterval * pstudio->m_flFrameRate * ent->framerate;
ent->animtime = RI.refdef.time;
if( ent->frame < 0.0 || ent->frame >= 256.0 )
{
if( ent->m_fSequenceLoops )
if( pstudio->m_fSequenceLoops )
ent->frame -= (int)(ent->frame / 256.0) * 256.0;
else ent->frame = (ent->frame < 0.0) ? 0 : 255;
ent->m_fSequenceFinished = true;
pstudio->m_fSequenceFinished = true;
}
return flInterval;
}
@ -539,19 +593,20 @@ float R_StudioFrameAdvance( ref_entity_t *ent, float flInterval )
void R_StudioResetSequenceInfo( ref_entity_t *ent )
{
dstudiohdr_t *hdr;
studiovars_t *pstudio = (studiovars_t *)ent->extradata;
if( !ent || !ent->model || !ent->model->extradata )
if( !ent || !ent->extradata || !ent->model || !ent->model->extradata )
return;
hdr = ((mstudiomodel_t *)ent->model->extradata)->phdr;
if( !hdr ) return;
ent->m_fSequenceLoops = ((R_StudioGetSequenceFlags( hdr, ent ) & STUDIO_LOOPING) != 0 );
// calc anim time
if( !ent->animtime ) ent->animtime = RI.refdef.time;
R_StuioGetSequenceInfo( hdr, ent, &pstudio->m_flFrameRate, &pstudio->m_flGroundSpeed );
pstudio->m_fSequenceLoops = ((R_StudioGetSequenceFlags( hdr, ent ) & STUDIO_LOOPING) != 0 );
ent->prev.animtime = ent->animtime;
ent->animtime = RI.refdef.time + R_StudioSequenceDuration( hdr, ent );
ent->m_fSequenceFinished = FALSE;
ent->animtime = RI.refdef.time;
pstudio->m_fSequenceFinished = false;
pstudio->m_flLastEventCheck = RI.refdef.time;
}
int R_StudioGetEvent( ref_entity_t *e, dstudioevent_t *pcurrent, float flStart, float flEnd, int index )
@ -566,11 +621,17 @@ int R_StudioGetEvent( ref_entity_t *e, dstudioevent_t *pcurrent, float flStart,
if( pseqdesc->numevents == 0 || index > pseqdesc->numevents )
return 0;
if( pseqdesc->numframes == 1 )
if( pseqdesc->numframes > 1 )
{
flStart *= (pseqdesc->numframes - 1) / 256.0;
flEnd *= (pseqdesc->numframes - 1) / 256.0;
}
else
{
flStart = 0;
flEnd = 1.0;
}
for( ; index < pseqdesc->numevents; index++ )
{
// don't send server-side events to the client effects
@ -1213,7 +1274,7 @@ float R_StudioSetupBones( ref_entity_t *e )
pseqdesc = (dstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + e->gaitsequence;
panim = R_StudioGetAnim( RI.currentmodel, pseqdesc );
R_StudioCalcRotations( pos2, q2, pseqdesc, panim, e->gaitframe );
R_StudioCalcRotations( pos2, q2, pseqdesc, panim, pstudio->gaitframe );
for( i = 0; i < m_pStudioHeader->numbones; i++ )
{
@ -1957,7 +2018,7 @@ void R_StudioEstimateGait( ref_entity_t *e, edict_t *pplayer )
if( est_velocity[1] == 0 && est_velocity[0] == 0 )
{
float flYawDiff = e->angles[YAW] - e->gaityaw;
float flYawDiff = e->angles[YAW] - pstudio->gaityaw;
flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360;
if( flYawDiff > 180 ) flYawDiff -= 360;
@ -1966,15 +2027,15 @@ void R_StudioEstimateGait( ref_entity_t *e, edict_t *pplayer )
if( dt < 0.25 ) flYawDiff *= dt * 4;
else flYawDiff *= dt;
e->gaityaw += flYawDiff;
e->gaityaw = e->gaityaw - (int)(e->gaityaw / 360) * 360;
pstudio->gaityaw += flYawDiff;
pstudio->gaityaw = pstudio->gaityaw - (int)(pstudio->gaityaw / 360) * 360;
m_flGaitMovement = 0;
}
else
{
e->gaityaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI);
if( e->gaityaw > 180 ) e->gaityaw = 180;
if( e->gaityaw < -180 ) e->gaityaw = -180;
pstudio->gaityaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI);
if( pstudio->gaityaw > 180 ) pstudio->gaityaw = 180;
if( pstudio->gaityaw < -180 ) pstudio->gaityaw = -180;
}
}
@ -2010,20 +2071,20 @@ void R_StudioProcessGait( ref_entity_t *e, edict_t *pplayer, studiovars_t *pstud
// MsgDev( D_INFO, "%f %f\n", e->angles[YAW], m_pPlayerInfo->gaityaw );
// calc side to side turning
flYaw = e->angles[YAW] - e->gaityaw;
flYaw = e->angles[YAW] - pstudio->gaityaw;
flYaw = flYaw - (int)(flYaw / 360) * 360;
if( flYaw < -180 ) flYaw = flYaw + 360;
if( flYaw > 180 ) flYaw = flYaw - 360;
if( flYaw > 120 )
{
e->gaityaw = e->gaityaw - 180;
pstudio->gaityaw = pstudio->gaityaw - 180;
m_flGaitMovement = -m_flGaitMovement;
flYaw = flYaw - 180;
}
else if( flYaw < -120 )
{
e->gaityaw = e->gaityaw + 180;
pstudio->gaityaw = pstudio->gaityaw + 180;
m_flGaitMovement = -m_flGaitMovement;
flYaw = flYaw + 180;
}
@ -2038,7 +2099,7 @@ void R_StudioProcessGait( ref_entity_t *e, edict_t *pplayer, studiovars_t *pstud
pstudio->prev.controller[2] = pstudio->controller[2];
pstudio->prev.controller[3] = pstudio->controller[3];
e->angles[YAW] = e->gaityaw;
e->angles[YAW] = pstudio->gaityaw;
if( e->angles[YAW] < -0 ) e->angles[YAW] += 360;
if( pplayer->v.gaitsequence >= m_pStudioHeader->numseq )
@ -2049,16 +2110,16 @@ void R_StudioProcessGait( ref_entity_t *e, edict_t *pplayer, studiovars_t *pstud
// calc gait frame
if( pseqdesc->linearmovement[0] > 0 )
{
e->gaitframe += (m_flGaitMovement / pseqdesc->linearmovement[0]) * pseqdesc->numframes;
pstudio->gaitframe += (m_flGaitMovement / pseqdesc->linearmovement[0]) * pseqdesc->numframes;
}
else
{
e->gaitframe += pseqdesc->fps * dt;
pstudio->gaitframe += pseqdesc->fps * dt;
}
// do modulo
e->gaitframe = e->gaitframe - (int)(e->gaitframe / pseqdesc->numframes) * pseqdesc->numframes;
if( e->gaitframe < 0 ) e->gaitframe += pseqdesc->numframes;
pstudio->gaitframe = pstudio->gaitframe - (int)(pstudio->gaitframe / pseqdesc->numframes) * pseqdesc->numframes;
if( pstudio->gaitframe < 0 ) pstudio->gaitframe += pseqdesc->numframes;
}
static bool R_StudioSetupModel( ref_entity_t *e, ref_model_t *mod )
@ -2127,14 +2188,20 @@ static bool R_StudioSetupModel( ref_entity_t *e, ref_model_t *mod )
if( m_pEntity && e->m_nCachedFrameCount != r_framecount2 )
{
float flStart = curframe + e->framerate;
float flEnd = flStart + 0.4f; // FIXME: calc real end, based on framerate
float flInterval = 0.1f;
float flStart = e->frame + (pstudio->m_flLastEventCheck - e->animtime) * pstudio->m_flFrameRate * e->framerate;
float flEnd = e->frame + flInterval * pstudio->m_flFrameRate * e->framerate;
int index = 0;
dstudioevent_t event;
Mem_Set( &event, 0, sizeof( event ));
R_StudioCalcAttachments( e, m_pEntity );
pstudio->m_flLastEventCheck = e->animtime + flInterval;
pstudio->m_fSequenceFinished = false;
if( flEnd >= 256.0f || flEnd <= 0.0f )
pstudio->m_fSequenceFinished = true;
while(( index = R_StudioGetEvent( e, &event, flStart, flEnd, index )) != 0 )
ri.StudioEvent( &event, m_pEntity );
}

View File

@ -1,62 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: render - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP9E62.tmp" with contents
[
/nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../public" /I "../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"..\temp\render\!debug/" /Fo"..\temp\render\!debug/" /Fd"..\temp\render\!debug/" /FD /c
"D:\Xash3D\src_main\render\r_studio.c"
]
Creating command line "cl.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP9E62.tmp"
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP9E63.tmp" with contents
[
msvcrtd.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"..\temp\render\!debug/render.pdb" /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"..\temp\render\!debug/render.dll" /implib:"..\temp\render\!debug/render.lib" /pdbtype:sept
"\Xash3D\src_main\temp\render\!debug\cin.obj"
"\Xash3D\src_main\temp\render\!debug\r_aliasq.obj"
"\Xash3D\src_main\temp\render\!debug\r_backend.obj"
"\Xash3D\src_main\temp\render\!debug\r_bloom.obj"
"\Xash3D\src_main\temp\render\!debug\r_cin.obj"
"\Xash3D\src_main\temp\render\!debug\r_cull.obj"
"\Xash3D\src_main\temp\render\!debug\r_draw.obj"
"\Xash3D\src_main\temp\render\!debug\r_image.obj"
"\Xash3D\src_main\temp\render\!debug\r_light.obj"
"\Xash3D\src_main\temp\render\!debug\r_main.obj"
"\Xash3D\src_main\temp\render\!debug\r_math.obj"
"\Xash3D\src_main\temp\render\!debug\r_mesh.obj"
"\Xash3D\src_main\temp\render\!debug\r_model.obj"
"\Xash3D\src_main\temp\render\!debug\r_opengl.obj"
"\Xash3D\src_main\temp\render\!debug\r_poly.obj"
"\Xash3D\src_main\temp\render\!debug\r_program.obj"
"\Xash3D\src_main\temp\render\!debug\r_register.obj"
"\Xash3D\src_main\temp\render\!debug\r_shader.obj"
"\Xash3D\src_main\temp\render\!debug\r_shadow.obj"
"\Xash3D\src_main\temp\render\!debug\r_sky.obj"
"\Xash3D\src_main\temp\render\!debug\r_sprite.obj"
"\Xash3D\src_main\temp\render\!debug\r_studio.obj"
"\Xash3D\src_main\temp\render\!debug\r_surf.obj"
]
Creating command line "link.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP9E63.tmp"
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP9E64.bat" with contents
[
@echo off
copy \Xash3D\src_main\temp\render\!debug\render.dll "D:\Xash3D\bin\render.dll"
]
Creating command line "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP9E64.bat"
Compiling...
r_studio.c
Linking...
<h3>Output Window</h3>
Performing Custom Build Step on \Xash3D\src_main\temp\render\!debug\render.dll
‘ª®¯¨à®¢ ­® ä ©«®¢: 1.
<h3>Results</h3>
render.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -629,19 +629,19 @@ void CNukeExplode :: Precache( void )
void CNukeExplode :: ExplodeThink( void )
{
pev->renderamt -= 1.5;
pev->scale += .2;
pev->renderamt = UTIL_Approach( 0, pev->renderamt, 200 * gpGlobals->frametime );
pev->scale = UTIL_Approach( 30, pev->scale, 30 * gpGlobals->frametime );
if(pev->scale >= 8 && pev->scale < 8.2 ) // create second explode sprite
if( pev->scale >= 8 && pev->scale < 8.2 ) // create second explode sprite
SFX_Explode( m_usExplodeSprite2, pev->oldorigin, 100, TE_EXPLFLAG_NOPARTICLES|TE_EXPLFLAG_NOSOUND );
entvars_t *pevOwner;
if ( pev->owner ) pevOwner = VARS( pev->owner );
if( pev->owner ) pevOwner = VARS( pev->owner );
else pevOwner = NULL;
pev->owner = NULL; //can't traceline attack owner if this is set
pev->owner = NULL; // can't traceline attack owner if this is set
::RadiusDamage( pev->origin, pev, pevOwner, pev->renderamt/2, pev->scale * 30, CLASS_NONE, DMG_BLAST | DMG_NUCLEAR );
if (pev->scale > 25 )UTIL_Remove( this );
::RadiusDamage( pev->origin, pev, pevOwner, pev->renderamt/2, pev->scale * 30, CLASS_NONE, DMG_BLAST|DMG_NUCLEAR );
if( pev->scale > 25 ) UTIL_Remove( this );
SetNextThink( 0.01 );
}

View File

@ -902,6 +902,51 @@ void EndFrame( void )
{
}
/*
================
SpectatorConnect
A spectator has joined the game
================
*/
void SpectatorConnect( edict_t *pEntity )
{
entvars_t *pev = &pEntity->v;
CBaseSpectator *pPlayer = (CBaseSpectator *)GET_PRIVATE( pEntity );
if( pPlayer ) pPlayer->SpectatorConnect( );
}
/*
================
SpectatorConnect
A spectator has left the game
================
*/
void SpectatorDisconnect( edict_t *pEntity )
{
entvars_t *pev = &pEntity->v;
CBaseSpectator *pPlayer = (CBaseSpectator *)GET_PRIVATE( pEntity );
if( pPlayer ) pPlayer->SpectatorDisconnect( );
}
/*
================
SpectatorConnect
A spectator has sent a usercmd
================
*/
void SpectatorThink( edict_t *pEntity )
{
entvars_t *pev = &pEntity->v;
CBaseSpectator *pPlayer = (CBaseSpectator *)GET_PRIVATE( pEntity );
if( pPlayer ) pPlayer->SpectatorThink( );
}
int ServerClassifyEdict( edict_t *pentToClassify )
{
if( !pentToClassify ) return ED_SPAWNED;
@ -998,6 +1043,10 @@ void UpdateEntityState( entity_state_t *to, edict_t *from, int baseline )
to->rendercolor = pNet->pev->rendercolor;
to->oldorigin = pNet->pev->oldorigin;
if( pNet->pev->groundentity )
to->groundent = ENTINDEX( pNet->pev->groundentity );
else to->groundent = -1;
// studio model sequence
if( pNet->pev->sequence != -1 ) to->sequence = pNet->pev->sequence;
@ -1028,7 +1077,7 @@ void UpdateEntityState( entity_state_t *to, edict_t *from, int baseline )
if( pNet->pev->aiment )
to->aiment = ENTINDEX( pNet->pev->aiment );
else to->aiment = 0;
else to->aiment = -1;
to->viewoffset = pNet->pev->view_ofs;
to->viewangles = pNet->pev->viewangles;
@ -1240,21 +1289,18 @@ void LinkUserMessages( void )
/*
================================
AllowLagCompensation
ShouldCollide
The game .dll should return 1 if lag compensation should be allowed ( could also just set
the sv_unlag cvar.
Most games right now should return 0, until client-side weapon prediction code is written
and tested for them ( note you can predict weapons, but not do lag compensation, too,
if you want.
Called when the engine believes two entities are about to collide. Return 0 if you
want the two entities to just pass through each other without colliding or calling the
touch function.
================================
*/
int AllowLagCompensation( void )
int ShouldCollide( edict_t *pentTouched, edict_t *pentOther )
{
return 1;
}
/*
================
InitWorld

View File

@ -68,10 +68,16 @@ static DLL_FUNCTIONS gFunctionTable =
EndFrame, // pfnEndFrame
BuildLevelList, // pfnBuildLevelList
ShouldCollide, // pfnShouldCollide
ServerClassifyEdict, // pfnClassifyEdict
UpdateEntityState, // pfnUpdateEntityState
OnFreeEntPrivateData, // pfnOnFreeEntPrivateData
GetGameDescription, // pfnGetGameDescription - returns string describing current .dll game.
SpectatorConnect, // pfnSpectatorConnect
SpectatorDisconnect, // pfnSpectatorDisconnect
SpectatorThink, // pfnSpectatorThink
};
//=======================================================================
@ -368,6 +374,14 @@ void SaveReadFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseD
restoreHelper.ReadFields( pname, pBaseData, pFields, fieldCount );
}
void OnFreeEntPrivateData( edict_s *pEdict )
{
if( pEdict && pEdict->pvPrivateData )
{
((CBaseEntity*)pEdict->pvPrivateData)->~CBaseEntity();
}
}
void SetObjectCollisionBox( entvars_t *pev )
{
if ( (pev->solid == SOLID_BSP) && (pev->angles.x || pev->angles.y|| pev->angles.z) )

View File

@ -22,7 +22,6 @@ extern enginefuncs_t g_engfuncs;
// The actual engine callbacks
#define MALLOC( x ) (*g_engfuncs.pfnMemAlloc)( x, __FILE__, __LINE__ )
#define CALLOC( x, y ) (*g_engfuncs.pfnMemAlloc)((x) * (y), __FILE__, __LINE__ )
#define MEMCPY( x, y, z ) (*g_engfuncs.pfnMemCopy)( x, y, z, __FILE__, __LINE__ )
#define FREE( x ) (*g_engfuncs.pfnMemFree)( x, __FILE__, __LINE__ )
#define PRECACHE_MODEL (*g_engfuncs.pfnPrecacheModel)
#define PRECACHE_SOUND (*g_engfuncs.pfnPrecacheSound)
@ -128,7 +127,7 @@ inline void *GET_PRIVATE( edict_t *pent )
#define SET_SKYBOX (*g_engfuncs.pfnSetSkybox)
#define LOAD_FILE (*g_engfuncs.pfnLoadFile)
#define FILE_EXISTS (*g_engfuncs.pfnFileExists)
#define FREE_FILE FREE
#define FREE_FILE (*g_engfuncs.pfnFreeFile)
#define COMPARE_FILE_TIME (*g_engfuncs.pfnCompareFileTime)
#define GET_GAME_DIR (*g_engfuncs.pfnGetGameDir)
#define ENGINE_CANSKIP (*g_engfuncs.pfnCanSkipPlayer)

View File

@ -26,7 +26,6 @@ extern DLL_GLOBAL BOOL g_startSuit;
#endif
extern "C" EXPORT int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion );
extern "C" EXPORT int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion );
extern int DispatchSpawn( edict_t *pent );
extern int DispatchCreate( edict_t *pent, const char *szName );
@ -46,6 +45,13 @@ extern void SaveReadFields( SAVERESTOREDATA *pSaveData, const char *pname, void
extern void SaveGlobalState( SAVERESTOREDATA *pSaveData );
extern void RestoreGlobalState( SAVERESTOREDATA *pSaveData );
extern void ResetGlobalState( void );
extern void OnFreeEntPrivateData( edict_s *pEdict );
extern int ShouldCollide( edict_t *pentTouched, edict_t *pentOther );
// spectator funcs
extern void SpectatorConnect( edict_t *pEntity );
extern void SpectatorDisconnect( edict_t *pEntity );
extern void SpectatorThink( edict_t *pEntity );
typedef void (CBaseEntity::*BASEPTR)(void);
typedef void (CBaseEntity::*ENTITYFUNCPTR)(CBaseEntity *pOther );

147
server/global/spectator.cpp Normal file
View File

@ -0,0 +1,147 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
// CBaseSpectator
// YWB: UNDONE
// Spectator functions
//
#include "extdll.h"
#include "utils.h"
#include "cbase.h"
#include "monsters.h"
#include "spectator.h"
/*
===========
SpectatorConnect
called when a spectator connects to a server
============
*/
void CBaseSpectator::SpectatorConnect( void )
{
pev->flags = FL_SPECTATOR;
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NOCLIP;
m_pGoalEnt = NULL;
}
/*
===========
SpectatorDisconnect
called when a spectator disconnects from a server
============
*/
void CBaseSpectator::SpectatorDisconnect( void )
{
}
/*
================
SpectatorImpulseCommand
Called by SpectatorThink if the spectator entered an impulse
================
*/
void CBaseSpectator::SpectatorImpulseCommand( void )
{
static edict_t *pGoal = NULL;
edict_t *pPreviousGoal;
edict_t *pCurrentGoal;
BOOL bFound;
switch( pev->impulse )
{
case 1:
// teleport the spectator to the next spawn point
// note that if the spectator is tracking, this doesn't do
// much
pPreviousGoal = pGoal;
pCurrentGoal = pGoal;
// Start at the current goal, skip the world, and stop if we looped
// back around
bFound = FALSE;
while( 1 )
{
pCurrentGoal = FIND_ENTITY_BY_CLASSNAME( pCurrentGoal, "info_player_deathmatch" );
// Looped around, failure
if( pCurrentGoal == pPreviousGoal )
{
ALERT( at_console, "Could not find a spawn spot.\n" );
break;
}
// found a non-world entity, set success, otherwise, look for the next one.
if( !FNullEnt( pCurrentGoal ))
{
bFound = TRUE;
break;
}
}
if( !bFound ) // Didn't find a good spot.
break;
pGoal = pCurrentGoal;
UTIL_SetOrigin( this, pGoal->v.origin );
pev->angles = pGoal->v.angles;
pev->fixangle = FALSE;
break;
default:
ALERT( at_console, "Unknown spectator impulse\n" );
break;
}
pev->impulse = 0;
}
/*
================
SpectatorThink
Called every frame after physics are run
================
*/
void CBaseSpectator::SpectatorThink( void )
{
if( !( pev->flags & FL_SPECTATOR ))
{
pev->flags = FL_SPECTATOR;
}
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NOCLIP;
if( pev->impulse ) SpectatorImpulseCommand();
}
/*
===========
Spawn
Called when spectator is initialized:
UNDONE: Is this actually being called because spectators are not allocated in normal fashion?
============
*/
void CBaseSpectator::Spawn( void )
{
pev->flags = FL_SPECTATOR;
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NOCLIP;
m_pGoalEnt = NULL;
}

View File

@ -333,6 +333,10 @@ SOURCE=.\game\sound.cpp
# End Source File
# Begin Source File
SOURCE=.\global\spectator.cpp
# End Source File
# Begin Source File
SOURCE=.\monsters\squadmonster.cpp
# End Source File
# Begin Source File

View File

@ -143,7 +143,10 @@ Beta 13.12.09
116. create flashlight for player OK
117. re-organize refdef flags OK
118. revise ref_params_t OK
119. fixup client smooth stair climbing
119. fixup client smooth stair climbing OK
120. fixup fov OK
121. make lerping for sprites OK
122. fix studio lerping between sequences
122. fix studio lerping between sequences OK
123. fixup studio EF_ANIMATE OK
124. fixup studio events on client-side OK
125. sort & implement engfuncs on server.dll