18 Oct 2010
This commit is contained in:
parent
dca58964c0
commit
a2a61486e2
|
@ -271,6 +271,12 @@ int CHud :: Redraw( float flTime )
|
|||
// clock was reset, reset delta
|
||||
if( m_flTimeDelta < 0 ) m_flTimeDelta = 0;
|
||||
|
||||
if( v_dark )
|
||||
{
|
||||
SetScreenFade( Vector( 0, 0, 0 ), 255, 4, 4, FFADE_IN );
|
||||
v_dark = FALSE;
|
||||
}
|
||||
|
||||
// draw screen fade before hud
|
||||
DrawScreenFade();
|
||||
|
||||
|
|
|
@ -639,6 +639,9 @@ public:
|
|||
Vector m_vecFadeColor;
|
||||
float m_flFadeAlpha;
|
||||
BOOL m_bModulate;
|
||||
|
||||
// v_dark issues
|
||||
BOOL v_dark;
|
||||
|
||||
// error sprite
|
||||
int m_HUD_error;
|
||||
|
|
|
@ -146,12 +146,9 @@ int CHud :: MsgFunc_ResetHUD(const char *pszName, int iSize, void *pbuf )
|
|||
m_flStartDist = 0;
|
||||
m_flEndDist = 0;
|
||||
|
||||
if( CVAR_GET_FLOAT( "v_dark" ))
|
||||
{
|
||||
SetScreenFade( Vector( 0, 0, 0 ), 255, 4, 4, FFADE_IN );
|
||||
CVAR_SET_FLOAT( "v_dark", 0.0f );
|
||||
}
|
||||
|
||||
v_dark = CVAR_GET_FLOAT( "v_dark" );
|
||||
CVAR_SET_FLOAT( "v_dark", 0.0f );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2010 ©
|
||||
// custom.h - create custom user recources
|
||||
//=======================================================================
|
||||
#ifndef CUSTOM_H
|
||||
#define CUSTOM_H
|
||||
|
||||
#include "const.h"
|
||||
|
||||
/////////////////
|
||||
// Customization
|
||||
// passed to pfnPlayerCustomization
|
||||
// For automatic downloading.
|
||||
|
||||
typedef enum
|
||||
{
|
||||
t_sound = 0,
|
||||
t_skin,
|
||||
t_model,
|
||||
t_decal,
|
||||
t_generic,
|
||||
t_eventscript,
|
||||
t_world, // fake type for world, is really t_model
|
||||
} resourcetype_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int size;
|
||||
} _resourceinfo_t;
|
||||
|
||||
typedef struct resourceinfo_s
|
||||
{
|
||||
_resourceinfo_t info[8];
|
||||
} resourceinfo_t;
|
||||
|
||||
#define RES_FATALIFMISSING (1<<0) // Disconnect if we can't get this file.
|
||||
#define RES_WASMISSING (1<<1) // Do we have the file locally, did we get it ok?
|
||||
#define RES_CUSTOM (1<<2) // Is this resource one that corresponds to another player's customization
|
||||
// or is it a server startup resource.
|
||||
#define RES_REQUESTED (1<<3) // Already requested a download of this one
|
||||
#define RES_PRECACHED (1<<4) // Already precached
|
||||
|
||||
typedef struct resource_s
|
||||
{
|
||||
char szFileName[64]; // file name to download/precache.
|
||||
resourcetype_t type; // t_sound, t_skin, t_model, t_decal.
|
||||
int nIndex; // for t_decals
|
||||
int nDownloadSize; // size in bytes if this must be downloaded.
|
||||
byte ucFlags;
|
||||
|
||||
// for handling client to client resource propagation
|
||||
byte rgucMD5_hash[16]; // to determine if we already have it.
|
||||
byte playernum; // which player index this resource is associated with,
|
||||
// if it's a custom resource.
|
||||
|
||||
byte rguc_reserved[32]; // for future expansion
|
||||
struct resource_s *pNext; // Next in chain.
|
||||
struct resource_s *pPrev;
|
||||
} resource_t;
|
||||
|
||||
typedef struct custom_s
|
||||
{
|
||||
BOOL bInUse; // is this customization in use;
|
||||
resource_t resource; // the resource_t for this customization
|
||||
BOOL bTranslated; // has the raw data been translated into a useable format?
|
||||
// (e.g., raw decal .wad make into texture_t *)
|
||||
int nUserData1; // sustomization specific data
|
||||
int nUserData2; // customization specific data
|
||||
void *pInfo; // buffer that holds the data structure that references
|
||||
// the data (e.g., the cachewad_t)
|
||||
void *pBuffer; // buffer that holds the data for the customization
|
||||
// (the raw .wad data)
|
||||
struct customization_s *pNext; // next in chain
|
||||
} customization_t;
|
||||
|
||||
#endif // CUSTOM_H
|
|
@ -6,6 +6,7 @@
|
|||
#define EIFACE_H
|
||||
|
||||
#include "cvardef.h"
|
||||
#include "custom.h"
|
||||
|
||||
#define INTERFACE_VERSION 140 // GetEntityAPI, GetEntityAPI2
|
||||
#define NEW_DLL_FUNCTIONS_VERSION 2 // GetNewDLLFunctions (Xash3D uses version 2)
|
||||
|
@ -17,9 +18,9 @@ typedef enum
|
|||
{
|
||||
at_notice,
|
||||
at_console, // format: [msg]
|
||||
at_aiconsole, // same as at_console, but only shown if developer level is 2!
|
||||
at_warning, // format: Warning: [msg]
|
||||
at_error, // format: Error: [msg]
|
||||
at_aiconsole, // same as at_console, but only shown if developer level is 5!
|
||||
at_logged // server print to console ( only in multiplayer games ). (NOT IMPLEMENTED)
|
||||
} ALERT_TYPE;
|
||||
|
||||
|
@ -34,9 +35,10 @@ typedef enum
|
|||
// for integrity checking of content on clients
|
||||
typedef enum
|
||||
{
|
||||
force_exactfile, // file on client must exactly match server's file
|
||||
force_model_samebounds, // for model files only, the geometry must fit in the same bbox
|
||||
force_model_specifybounds, // for model files only, the geometry must fit in the specified bbox
|
||||
force_exactfile, // file on client must exactly match server's file
|
||||
force_model_samebounds, // for model files only, the geometry must fit in the same bbox
|
||||
force_model_specifybounds, // for model files only, the geometry must fit in the specified bbox
|
||||
force_model_specifybounds_if_avail, // for model files only, the geometry must fit in the specified bbox (if the file is available)
|
||||
} FORCE_TYPE;
|
||||
|
||||
typedef struct
|
||||
|
@ -63,16 +65,16 @@ 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 );
|
||||
edict_t* (*pfnEntitiesInPHS)( edict_t *pplayer );
|
||||
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 );
|
||||
void (*pfnChangeYaw)( edict_t* ent );
|
||||
void (*pfnChangePitch)( edict_t* ent );
|
||||
edict_t* (*pfnFindEntityByString)( edict_t *pStartEdict, const char *pszField, const char *pszValue);
|
||||
edict_t* (*pfnFindEntityByString)( edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue );
|
||||
int (*pfnGetEntityIllum)( edict_t* pEnt );
|
||||
edict_t* (*pfnFindEntityInSphere)( edict_t *pStartEdict, const float *org, float rad );
|
||||
edict_t* (*pfnFindEntityInSphere)( edict_t *pEdictStartSearchAfter, const float *org, float rad );
|
||||
edict_t* (*pfnFindClientInPVS)( edict_t *pEdict );
|
||||
edict_t* (*pfnEntitiesInPVS)( edict_t *pplayer );
|
||||
void (*pfnMakeVectors)( const float *rgflVector );
|
||||
|
@ -81,7 +83,7 @@ typedef struct enginefuncs_s
|
|||
void (*pfnRemoveEntity)( edict_t* e );
|
||||
edict_t* (*pfnCreateNamedEntity)( string_t className );
|
||||
void (*pfnMakeStatic)( edict_t *ent );
|
||||
void (*pfnLinkEdict)( edict_t *e, int touch_triggers ); // a part of CustomPhysics implementation
|
||||
int (*pfnEntIsOnFloor)( edict_t *e );
|
||||
int (*pfnDropToFloor)( edict_t* e );
|
||||
int (*pfnWalkMove)( edict_t *ent, float yaw, float dist, int iMode );
|
||||
void (*pfnSetOrigin)( edict_t *e, const float *rgflOrigin );
|
||||
|
@ -93,7 +95,7 @@ typedef struct enginefuncs_s
|
|||
void (*pfnTraceHull)( const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr );
|
||||
void (*pfnTraceModel)( const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr );
|
||||
const char *(*pfnTraceTexture)( edict_t *pTextureEntity, const float *v1, const float *v2 );
|
||||
int (*pfnBoxVisible)( const float *mins, const float *maxs, const byte *pset );
|
||||
int (*pfnBoxVisible)( const float *mins, const float *maxs, const byte *pset ); // was pfnTraceSphere
|
||||
void (*pfnGetAimVector)( edict_t* ent, float speed, float *rgflReturn );
|
||||
void (*pfnServerCommand)( const char* str );
|
||||
void (*pfnServerExecute)( void );
|
||||
|
|
|
@ -285,6 +285,14 @@ usercmd_t CL_CreateCmd( void )
|
|||
|
||||
clgame.dllFuncs.pfnCreateMove( &cmd, cl.time - cl.oldtime, ( cls.state == ca_active && !cl.refdef.paused ));
|
||||
|
||||
if( re )
|
||||
{
|
||||
vec3_t color;
|
||||
|
||||
re->LightForPoint( cl.frame.clientdata.origin, color );
|
||||
cmd.lightlevel = VectorAvg( color ) * 255;
|
||||
}
|
||||
|
||||
// random seed for predictable random values
|
||||
cl.random_seed = Com_RandomLong( 0, 0x7fffffff ); // full range
|
||||
|
||||
|
|
|
@ -28,13 +28,13 @@ const char *svc_strings[256] =
|
|||
"svc_setangle",
|
||||
"svc_serverdata",
|
||||
"svc_restore",
|
||||
"svc_frame",
|
||||
"svc_updateuserinfo",
|
||||
"svc_usermessage",
|
||||
"svc_clientdata",
|
||||
"svc_download",
|
||||
"svc_updatepings",
|
||||
"svc_particle",
|
||||
"svc_ambientsound",
|
||||
"svc_frame",
|
||||
"svc_spawnstatic",
|
||||
"svc_crosshairangle",
|
||||
"svc_spawnbaseline",
|
||||
|
@ -44,7 +44,7 @@ const char *svc_strings[256] =
|
|||
"svc_centerprint",
|
||||
"svc_event",
|
||||
"svc_event_reliable",
|
||||
"svc_updateuserinfo",
|
||||
"svc_ambientsound",
|
||||
"svc_intermission",
|
||||
"svc_soundfade",
|
||||
"svc_cdtrack",
|
||||
|
@ -452,6 +452,46 @@ void CL_ParseParticles( sizebuf_t *msg )
|
|||
clgame.dllFuncs.pfnParticleEffect( org, dir, color, count );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseStaticEntity
|
||||
|
||||
==================
|
||||
*/
|
||||
void CL_ParseStaticEntity( sizebuf_t *msg )
|
||||
{
|
||||
entity_state_t ent;
|
||||
int i;
|
||||
|
||||
Mem_Set( &ent, 0, sizeof( ent ));
|
||||
|
||||
ent.modelindex = BF_ReadShort( msg );
|
||||
ent.sequence = BF_ReadByte( msg );
|
||||
ent.frame = BF_ReadByte( msg );
|
||||
ent.colormap = BF_ReadWord( msg );
|
||||
ent.skin = BF_ReadByte( msg );
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
ent.origin[i] = BF_ReadBitCoord( msg );
|
||||
ent.angles[i] = BF_ReadBitAngle( msg, 16 );
|
||||
}
|
||||
|
||||
ent.rendermode = BF_ReadByte( msg );
|
||||
|
||||
if( ent.rendermode != kRenderNormal )
|
||||
{
|
||||
ent.renderamt = BF_ReadByte( msg );
|
||||
ent.rendercolor.r = BF_ReadByte( msg );
|
||||
ent.rendercolor.g = BF_ReadByte( msg );
|
||||
ent.rendercolor.b = BF_ReadByte( msg );
|
||||
ent.renderfx = BF_ReadByte( msg );
|
||||
}
|
||||
|
||||
// FIXME: allocate client entity, add new static...
|
||||
MsgDev( D_ERROR, "Static entities are not implemented\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseStaticDecal
|
||||
|
@ -1081,12 +1121,12 @@ void CL_ParseServerMessage( sizebuf_t *msg )
|
|||
case svc_particle:
|
||||
CL_ParseParticles( msg );
|
||||
break;
|
||||
case svc_spawnstatic:
|
||||
CL_ParseStaticEntity( msg );
|
||||
break;
|
||||
case svc_ambientsound:
|
||||
CL_ParseSoundPacket( msg, true );
|
||||
break;
|
||||
case svc_spawnstatic:
|
||||
Host_Error( "svc_spawnstatic: not implemented\n" );
|
||||
break;
|
||||
case svc_crosshairangle:
|
||||
CL_ParseCrosshairAngle( msg );
|
||||
break;
|
||||
|
|
|
@ -187,6 +187,13 @@ int CM_LightEntity( edict_t *pEdict )
|
|||
return 255;
|
||||
}
|
||||
|
||||
if( pEdict->v.flags & FL_CLIENT )
|
||||
{
|
||||
// client has more precision light level
|
||||
// that come from client
|
||||
return pEdict->v.light_level;
|
||||
}
|
||||
|
||||
VectorCopy( pEdict->v.origin, start );
|
||||
VectorCopy( pEdict->v.origin, end );
|
||||
|
||||
|
|
|
@ -697,7 +697,7 @@ void Delta_ParseTable( script_t *delta_script, delta_info_t *dt, const char *enc
|
|||
if( !com.stricmp( encodeDll, "none" ))
|
||||
dt->customEncode = CUSTOM_NONE;
|
||||
else if( !com.stricmp( encodeDll, "gamedll" ))
|
||||
dt->customEncode = CUSTOM_SEREVR_ENCODE;
|
||||
dt->customEncode = CUSTOM_SERVER_ENCODE;
|
||||
else if( !com.stricmp( encodeDll, "clientdll" ))
|
||||
dt->customEncode = CUSTOM_CLIENT_ENCODE;
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
enum
|
||||
{
|
||||
CUSTOM_NONE = 0,
|
||||
CUSTOM_SEREVR_ENCODE, // keyword "gamedll"
|
||||
CUSTOM_SERVER_ENCODE, // keyword "gamedll"
|
||||
CUSTOM_CLIENT_ENCODE, // keyword "client"
|
||||
};
|
||||
|
||||
|
|
|
@ -21,14 +21,14 @@
|
|||
#define svc_setangle 10 // [angle angle] set the view angle to this absolute value
|
||||
#define svc_serverdata 11 // [long] protocol ...
|
||||
#define svc_restore 12 // restore saved game on the client
|
||||
#define svc_frame 13 // begin a new server frame
|
||||
#define svc_updateuserinfo 13 // [byte] playernum, [string] userinfo
|
||||
#define svc_usermessage 14 // [string][byte] REG_USER_MSG stuff
|
||||
#define svc_clientdata 15 // [...]
|
||||
#define svc_download 16 // [short] size [size bytes]
|
||||
#define svc_updatepings 17 // [bit][idx][ping][packet_loss]
|
||||
#define svc_particle 18 // [float*3][char*3][byte][byte]
|
||||
#define svc_ambientsound 19 // <see code>
|
||||
#define svc_spawnstatic 20 // NOT IMPLEMENTED
|
||||
#define svc_frame 19 // <OBSOLETE>
|
||||
#define svc_spawnstatic 20 // creates a static client entity
|
||||
#define svc_crosshairangle 21 // [short][short][short]
|
||||
#define svc_spawnbaseline 22 // <see code>
|
||||
#define svc_temp_entity 23 // <variable sized>
|
||||
|
@ -37,7 +37,7 @@
|
|||
#define svc_centerprint 26 // [string] to put in center of the screen
|
||||
#define svc_event 27 // playback event queue
|
||||
#define svc_event_reliable 28 // playback event directly from message, not queue
|
||||
#define svc_updateuserinfo 29 // [byte] playernum, [string] userinfo
|
||||
#define svc_ambientsound 29 // <see code>
|
||||
#define svc_intermission 30 // empty message (event)
|
||||
#define svc_soundfade 31 // [float*4] sound fade parms
|
||||
#define svc_cdtrack 32 // [byte] track [byte] looptrack
|
||||
|
|
|
@ -219,7 +219,7 @@ void Host_CheckChanges( void )
|
|||
if(( host_video->modified || host_audio->modified ) && CL_Active( ))
|
||||
{
|
||||
host.soundList = (soundlist_t *)Z_Malloc( sizeof( soundlist_t ) * 128 );
|
||||
host.numsounds = S_GetCurrentStaticSounds( host.soundList, 128, CHAN_AUTO );
|
||||
host.numsounds = S_GetCurrentStaticSounds( host.soundList, 128, CHAN_STATIC );
|
||||
Msg( "Total stored %i sounds\n", host.numsounds );
|
||||
}
|
||||
|
||||
|
|
|
@ -153,6 +153,8 @@ typedef struct sv_client_s
|
|||
float latency;
|
||||
float ping;
|
||||
|
||||
int listeners; // 32 bits == MAX_CLIENTS (voice listeners)
|
||||
|
||||
float addangle; // add angles to client position
|
||||
|
||||
edict_t *edict; // EDICT_NUM(clientnum+1)
|
||||
|
@ -381,9 +383,10 @@ bool SV_TestPlayerPosition( edict_t *ent ); // for PlayerInSolid checks
|
|||
//
|
||||
// sv_move.c
|
||||
//
|
||||
bool SV_WalkMove( edict_t *ent, const vec3_t move, int iMode );
|
||||
bool SV_MoveStep( edict_t *ent, vec3_t move, bool relink );
|
||||
bool SV_MoveTest( edict_t *ent, vec3_t move, bool relink );
|
||||
void SV_MoveToOrigin( edict_t *ed, const vec3_t goal, float dist, int iMode );
|
||||
bool SV_CheckBottom( edict_t *ent, float flStepSize, int iMode );
|
||||
bool SV_CheckBottom( edict_t *ent, int iMode );
|
||||
float SV_VecToYaw( const vec3_t src );
|
||||
|
||||
//
|
||||
|
@ -432,6 +435,7 @@ void SV_BuildClientFrame( sv_client_t *client );
|
|||
void SV_ClearFrames( client_frame_t **frames );
|
||||
void SV_InactivateClients( void );
|
||||
void SV_SendMessagesToAll( void );
|
||||
void SV_SkipUpdates( void );
|
||||
|
||||
//
|
||||
// sv_game.c
|
||||
|
|
|
@ -814,6 +814,7 @@ void SV_PutClientInServer( edict_t *ent )
|
|||
{
|
||||
if( ent->v.flags & FL_SPECTATOR )
|
||||
{
|
||||
svgame.globals->time = sv.time;
|
||||
svgame.dllFuncs.pfnSpectatorConnect( ent );
|
||||
}
|
||||
else
|
||||
|
@ -823,6 +824,7 @@ void SV_PutClientInServer( edict_t *ent )
|
|||
else ent->v.netname = MAKE_STRING( "player" );
|
||||
|
||||
// fisrt entering
|
||||
svgame.globals->time = sv.time;
|
||||
svgame.dllFuncs.pfnClientPutInServer( ent );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -723,6 +723,9 @@ void SV_SendMessagesToAll( void )
|
|||
int i;
|
||||
sv_client_t *cl;
|
||||
|
||||
if( sv.state == ss_dead )
|
||||
return;
|
||||
|
||||
for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ )
|
||||
{
|
||||
if( cl->state >= cs_connected )
|
||||
|
@ -731,6 +734,29 @@ void SV_SendMessagesToAll( void )
|
|||
SV_SendClientMessages();
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
SV_SkipUpdates
|
||||
|
||||
used before changing level
|
||||
=======================
|
||||
*/
|
||||
void SV_SkipUpdates( void )
|
||||
{
|
||||
int i;
|
||||
sv_client_t *cl;
|
||||
|
||||
if( sv.state == ss_dead )
|
||||
return;
|
||||
|
||||
for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ )
|
||||
{
|
||||
if( cl->state != cs_spawned || cl->fakeclient )
|
||||
continue;
|
||||
cl->skip_message = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
SV_InactivateClients
|
||||
|
|
|
@ -560,6 +560,18 @@ void SV_FreeEdict( edict_t *pEdict )
|
|||
// unlink from world
|
||||
SV_UnlinkEdict( pEdict );
|
||||
|
||||
// never remove global entities from map
|
||||
if( pEdict->v.globalname && sv.state == ss_active )
|
||||
{
|
||||
pEdict->v.solid = SOLID_NOT;
|
||||
pEdict->v.flags &= ~FL_KILLME;
|
||||
pEdict->v.effects = EF_NODRAW;
|
||||
pEdict->v.movetype = MOVETYPE_NONE;
|
||||
pEdict->v.modelindex = 0;
|
||||
pEdict->v.nextthink = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if( pEdict->pvPrivateData )
|
||||
{
|
||||
if( svgame.dllFuncs2.pfnOnFreeEntPrivateData )
|
||||
|
@ -912,6 +924,8 @@ void pfnChangeLevel( const char* s1, const char* s2 )
|
|||
|
||||
svs.changelevel_next_time = host.realtime + 1.0f; // rest 1 secs if failed
|
||||
|
||||
SV_SkipUpdates ();
|
||||
|
||||
if( !s2 ) Cbuf_AddText( va( "changelevel %s\n", s1 )); // Quake changlevel
|
||||
else Cbuf_AddText( va( "changelevel %s %s\n", s1, s2 )); // Half-Life changelevel
|
||||
}
|
||||
|
@ -1341,32 +1355,60 @@ disable entity updates to client
|
|||
*/
|
||||
static void pfnMakeStatic( edict_t *ent )
|
||||
{
|
||||
int index, i;
|
||||
|
||||
if( !SV_IsValidEdict( ent ))
|
||||
{
|
||||
MsgDev( D_WARN, "SV_MakeStatic: invalid entity %s\n", SV_ClassName( ent ));
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: write svc_spawnstatic to the client
|
||||
ent->v.flags |= FL_KILLME;
|
||||
index = SV_ModelIndex( STRING( ent->v.model ));
|
||||
|
||||
BF_WriteByte( &sv.signon, svc_spawnstatic );
|
||||
BF_WriteShort(&sv.signon, index );
|
||||
BF_WriteByte( &sv.signon, ent->v.sequence );
|
||||
BF_WriteByte( &sv.signon, ent->v.frame );
|
||||
BF_WriteWord( &sv.signon, ent->v.colormap );
|
||||
BF_WriteByte( &sv.signon, ent->v.skin );
|
||||
|
||||
for(i = 0; i < 3; i++ )
|
||||
{
|
||||
BF_WriteBitCoord( &sv.signon, ent->v.origin[i] );
|
||||
BF_WriteBitAngle( &sv.signon, ent->v.angles[i], 16 );
|
||||
}
|
||||
|
||||
BF_WriteByte( &sv.signon, ent->v.rendermode );
|
||||
|
||||
if( ent->v.rendermode != kRenderNormal )
|
||||
{
|
||||
BF_WriteByte( &sv.signon, ent->v.renderamt );
|
||||
BF_WriteByte( &sv.signon, ent->v.rendercolor[0] );
|
||||
BF_WriteByte( &sv.signon, ent->v.rendercolor[1] );
|
||||
BF_WriteByte( &sv.signon, ent->v.rendercolor[2] );
|
||||
BF_WriteByte( &sv.signon, ent->v.renderfx );
|
||||
}
|
||||
|
||||
// remove at end of the frame
|
||||
ent->v.flags |= FL_KILLME;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
pfnLinkEntity
|
||||
pfnEntIsOnFloor
|
||||
|
||||
Xash3D extension
|
||||
legacy builtin
|
||||
=============
|
||||
*/
|
||||
static void pfnLinkEntity( edict_t *e, int touch_triggers )
|
||||
static int pfnEntIsOnFloor( edict_t *e )
|
||||
{
|
||||
if( !SV_IsValidEdict( e ))
|
||||
{
|
||||
MsgDev( D_WARN, "SV_LinkEntity: invalid entity %s\n", SV_ClassName( e ));
|
||||
return;
|
||||
MsgDev( D_WARN, "SV_CheckBottom: invalid entity %s\n", SV_ClassName( e ));
|
||||
return 0;
|
||||
}
|
||||
SV_LinkEdict( e, touch_triggers );
|
||||
|
||||
return SV_CheckBottom( e, MOVE_NORMAL );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1429,7 +1471,19 @@ int pfnWalkMove( edict_t *ent, float yaw, float dist, int iMode )
|
|||
yaw = yaw * M_PI * 2 / 360;
|
||||
VectorSet( move, com.cos( yaw ) * dist, com.sin( yaw ) * dist, 0.0f );
|
||||
|
||||
return SV_WalkMove( ent, move, iMode );
|
||||
switch( iMode )
|
||||
{
|
||||
case WALKMOVE_NORMAL:
|
||||
return SV_MoveStep( ent, move, true );
|
||||
case WALKMOVE_WORLDONLY:
|
||||
return SV_MoveTest( ent, move, true );
|
||||
case WALKMOVE_CHECKONLY:
|
||||
return SV_MoveStep( ent, move, false);
|
||||
default:
|
||||
MsgDev( D_ERROR, "SV_WalkMove: invalid walk mode %i.\n", iMode );
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1623,7 +1677,7 @@ void pfnEmitAmbientSound( edict_t *ent, float *pos, const char *sample, float vo
|
|||
BF_WriteByte( &sv.multicast, svc_ambientsound );
|
||||
BF_WriteWord( &sv.multicast, flags );
|
||||
BF_WriteWord( &sv.multicast, sound_idx );
|
||||
BF_WriteByte( &sv.multicast, CHAN_AUTO );
|
||||
BF_WriteByte( &sv.multicast, CHAN_STATIC );
|
||||
|
||||
if( flags & SND_VOLUME ) BF_WriteByte( &sv.multicast, vol * 255 );
|
||||
if( flags & SND_ATTENUATION ) BF_WriteByte( &sv.multicast, attn * 64 );
|
||||
|
@ -1651,6 +1705,7 @@ static void pfnTraceLine( const float *v1, const float *v2, int fNoMonsters, edi
|
|||
svgame.globals->trace_flags = 0;
|
||||
|
||||
*ptr = SV_Move( v1, vec3_origin, vec3_origin, v2, fNoMonsters, pentToSkip );
|
||||
SV_CopyTraceToGlobal( ptr );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1670,6 +1725,7 @@ static void pfnTraceToss( edict_t* pent, edict_t* pentToIgnore, TraceResult *ptr
|
|||
}
|
||||
|
||||
*ptr = SV_MoveToss( pent, pentToIgnore );
|
||||
SV_CopyTraceToGlobal( ptr );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1687,6 +1743,7 @@ static void pfnTraceHull( const float *v1, const float *v2, int fNoMonsters, int
|
|||
svgame.globals->trace_flags = 0;
|
||||
|
||||
*ptr = SV_MoveHull( v1, hullNumber, v2, fNoMonsters, pentToSkip );
|
||||
SV_CopyTraceToGlobal( ptr );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1698,7 +1755,6 @@ pfnTraceMonsterHull
|
|||
static int pfnTraceMonsterHull( edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr )
|
||||
{
|
||||
trace_t result;
|
||||
float *mins, *maxs;
|
||||
|
||||
if( !SV_IsValidEdict( pEdict ))
|
||||
{
|
||||
|
@ -1710,15 +1766,16 @@ static int pfnTraceMonsterHull( edict_t *pEdict, const float *v1, const float *v
|
|||
fNoMonsters |= FMOVE_SIMPLEBOX;
|
||||
svgame.globals->trace_flags = 0;
|
||||
|
||||
mins = pEdict->v.mins;
|
||||
maxs = pEdict->v.maxs;
|
||||
result = SV_Move( v1, pEdict->v.mins, pEdict->v.maxs, v2, fNoMonsters, pentToSkip );
|
||||
if( ptr )
|
||||
{
|
||||
SV_CopyTraceToGlobal( ptr );
|
||||
*ptr = result;
|
||||
}
|
||||
|
||||
if( VectorIsNAN( v1 ) || VectorIsNAN( v2 ))
|
||||
Host_Error( "TraceMonsterHull: NAN errors detected '%f %f %f', '%f %f %f'\n", v1[0], v1[1], v1[2], v2[0], v2[1], v2[2] );
|
||||
result = SV_Move( v1, mins, maxs, v2, fNoMonsters, pentToSkip );
|
||||
if( ptr ) Mem_Copy( ptr, &result, sizeof( *ptr ));
|
||||
|
||||
return ptr->fAllSolid;
|
||||
if( result.fAllSolid || result.flFraction != 1.0f )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1744,6 +1801,7 @@ static void pfnTraceModel( const float *v1, const float *v2, int hullNumber, edi
|
|||
maxs = sv.worldmodel->hulls[hullNumber].clip_maxs;
|
||||
|
||||
*ptr = SV_TraceHull( pent, hullNumber, v1, mins, maxs, v2 );
|
||||
SV_CopyTraceToGlobal( ptr );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2294,23 +2352,26 @@ static void pfnAlertMessage( ALERT_TYPE level, char *szFmt, ... )
|
|||
com.vsnprintf( buffer, 2048, szFmt, args );
|
||||
va_end( args );
|
||||
|
||||
if( host.developer < level )
|
||||
return;
|
||||
|
||||
switch( level )
|
||||
if( level == at_notice )
|
||||
{
|
||||
case at_notice:
|
||||
case at_console:
|
||||
case at_aiconsole:
|
||||
com.print( buffer );
|
||||
break;
|
||||
case at_warning:
|
||||
com.print( va( "^3Warning:^7 %s", buffer ));
|
||||
break;
|
||||
case at_error:
|
||||
com.print( va( "^1Error:^7 %s", buffer ));
|
||||
break;
|
||||
com.print( buffer ); // notice printing always
|
||||
}
|
||||
else if( level == at_console && host.developer >= D_INFO )
|
||||
{
|
||||
com.print( buffer );
|
||||
}
|
||||
else if( level == at_aiconsole && host.developer >= D_AICONSOLE )
|
||||
{
|
||||
com.print( buffer );
|
||||
}
|
||||
else if( level == at_warning && host.developer >= D_WARN )
|
||||
{
|
||||
com.print( va( "^3Warning:^7 %s", buffer ));
|
||||
}
|
||||
else if( level == at_error && host.developer >= D_ERROR )
|
||||
{
|
||||
com.print( va( "^1Error:^7 %s", buffer ));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3636,7 +3697,7 @@ static enginefuncs_t gEngfuncs =
|
|||
pfnRemoveEntity,
|
||||
pfnCreateNamedEntity,
|
||||
pfnMakeStatic,
|
||||
pfnLinkEntity,
|
||||
pfnEntIsOnFloor,
|
||||
pfnDropToFloor,
|
||||
pfnWalkMove,
|
||||
pfnSetOrigin,
|
||||
|
|
|
@ -172,11 +172,11 @@ void SV_DeactivateServer( void )
|
|||
|
||||
if( !svs.initialized ) return;
|
||||
|
||||
SV_FreeEdicts ();
|
||||
|
||||
if( sv.state == ss_dead ) return;
|
||||
sv.state = ss_dead;
|
||||
|
||||
SV_FreeEdicts ();
|
||||
|
||||
if( svgame.globals->pStringBase )
|
||||
Mem_EmptyPool( svgame.stringspool );
|
||||
else StringTable_Clear( svgame.hStringTable );
|
||||
|
|
|
@ -22,7 +22,7 @@ is not a staircase.
|
|||
|
||||
=============
|
||||
*/
|
||||
bool SV_CheckBottom( edict_t *ent, float flStepSize, int iMode )
|
||||
bool SV_CheckBottom( edict_t *ent, int iMode )
|
||||
{
|
||||
vec3_t mins, maxs, start, stop;
|
||||
float mid, bottom;
|
||||
|
@ -50,12 +50,12 @@ bool SV_CheckBottom( edict_t *ent, float flStepSize, int iMode )
|
|||
return true; // we got out easy
|
||||
realcheck:
|
||||
// check it for real...
|
||||
start[2] = mins[2] + flStepSize;
|
||||
start[2] = mins[2] + svgame.movevars.stepsize;
|
||||
|
||||
// the midpoint must be within 16 of the bottom
|
||||
start[0] = stop[0] = (mins[0] + maxs[0]) * 0.5f;
|
||||
start[1] = stop[1] = (mins[1] + maxs[1]) * 0.5f;
|
||||
stop[2] = start[2] - 2 * flStepSize;
|
||||
stop[2] = start[2] - 2 * svgame.movevars.stepsize;
|
||||
|
||||
if( iMode == WALKMOVE_WORLDONLY )
|
||||
trace = SV_Move( start, vec3_origin, vec3_origin, stop, MOVE_WORLDONLY, ent );
|
||||
|
@ -79,7 +79,7 @@ realcheck:
|
|||
|
||||
if( trace.flFraction != 1.0f && trace.vecEndPos[2] > bottom )
|
||||
bottom = trace.vecEndPos[2];
|
||||
if( trace.flFraction == 1.0f || mid - trace.vecEndPos[2] > flStepSize )
|
||||
if( trace.flFraction == 1.0f || mid - trace.vecEndPos[2] > svgame.movevars.stepsize )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -110,199 +110,350 @@ float SV_VecToYaw( const vec3_t src )
|
|||
}
|
||||
|
||||
//============================================================================
|
||||
/*
|
||||
======================
|
||||
SV_WalkMove
|
||||
|
||||
======================
|
||||
*/
|
||||
bool SV_WalkMove( edict_t *ent, const vec3_t move, int iMode )
|
||||
bool SV_MoveStep( edict_t *ent, vec3_t move, bool relink )
|
||||
{
|
||||
int i;
|
||||
trace_t trace;
|
||||
vec3_t oldorg, neworg, end;
|
||||
edict_t *groundent = NULL;
|
||||
float flStepSize;
|
||||
bool relink;
|
||||
edict_t *enemy;
|
||||
float dz;
|
||||
|
||||
if( iMode == WALKMOVE_NORMAL )
|
||||
relink = true;
|
||||
else relink = false;
|
||||
|
||||
// try the move
|
||||
VectorCopy( ent->v.origin, oldorg );
|
||||
VectorAdd( oldorg, move, neworg );
|
||||
|
||||
// flying pawns don't step up
|
||||
VectorAdd( ent->v.origin, move, neworg );
|
||||
|
||||
// well, try it. Flying and swimming monsters are easiest.
|
||||
if( ent->v.flags & ( FL_SWIM|FL_FLY ))
|
||||
{
|
||||
if( iMode == WALKMOVE_WORLDONLY )
|
||||
trace = SV_Move( oldorg, ent->v.mins, ent->v.maxs, neworg, MOVE_WORLDONLY, ent );
|
||||
else trace = SV_Move( oldorg, ent->v.mins, ent->v.maxs, neworg, MOVE_NORMAL, ent );
|
||||
// try one move with vertical motion, then one without
|
||||
for( i = 0; i < 2; i++ )
|
||||
{
|
||||
VectorAdd( ent->v.origin, move, neworg );
|
||||
|
||||
enemy = ent->v.enemy;
|
||||
if( i == 0 && enemy != NULL )
|
||||
{
|
||||
dz = ent->v.origin[2] - enemy->v.origin[2];
|
||||
|
||||
if( dz > 40 ) neworg[2] -= 8;
|
||||
else if( dz < 30 ) neworg[2] += 8;
|
||||
}
|
||||
|
||||
trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, neworg, MOVE_NORMAL, ent );
|
||||
|
||||
if( trace.flFraction == 1.0f )
|
||||
{
|
||||
svs.groupmask = ent->v.groupinfo;
|
||||
|
||||
// that move takes us out of the water.
|
||||
// apparently though, it's okay to travel into solids, lava, sky, etc :)
|
||||
if(( ent->v.flags & FL_SWIM ) && SV_PointContents( trace.vecEndPos ) == CONTENTS_EMPTY )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
VectorCopy( trace.vecEndPos, ent->v.origin );
|
||||
|
||||
if( relink != 0 )
|
||||
{
|
||||
SV_LinkEdict( ent, true );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( enemy == NULL )
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
dz = svgame.movevars.stepsize;
|
||||
neworg[2] += dz;
|
||||
VectorCopy( neworg, end );
|
||||
end[2] -= dz * 2.0f;
|
||||
|
||||
trace = SV_Move( neworg, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent );
|
||||
if( trace.fAllSolid != 0 )
|
||||
return 0;
|
||||
|
||||
if( trace.fStartSolid != 0 )
|
||||
{
|
||||
neworg[2] -= dz;
|
||||
trace = SV_Move( neworg, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent );
|
||||
|
||||
if( trace.fAllSolid != 0 || trace.fStartSolid != 0 )
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( trace.flFraction == 1.0f )
|
||||
{
|
||||
if( ent->v.flags & FL_SWIM && SV_PointContents( trace.vecEndPos ) == CONTENTS_EMPTY )
|
||||
return false; // swim monster left water
|
||||
|
||||
if( ent->v.flags & FL_PARTIALGROUND )
|
||||
{
|
||||
VectorAdd( ent->v.origin, move, ent->v.origin );
|
||||
if( relink != 0 )
|
||||
{
|
||||
SV_LinkEdict( ent, true );
|
||||
}
|
||||
ent->v.flags &= ~FL_ONGROUND;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy( trace.vecEndPos, ent->v.origin );
|
||||
|
||||
if( !VectorCompare( ent->v.origin, oldorg ))
|
||||
SV_LinkEdict( ent, relink );
|
||||
return true;
|
||||
if( SV_CheckBottom( ent, MOVE_NORMAL ) == 0 )
|
||||
{
|
||||
if( ent->v.flags & FL_PARTIALGROUND )
|
||||
{
|
||||
if( relink != 0 )
|
||||
{
|
||||
SV_LinkEdict( ent, true );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
VectorCopy( oldorg, ent->v.origin );
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ent->v.flags & FL_PARTIALGROUND )
|
||||
ent->v.flags &= ~FL_PARTIALGROUND;
|
||||
|
||||
ent->v.groundentity = trace.pHit;
|
||||
|
||||
if( relink != 0 )
|
||||
{
|
||||
SV_LinkEdict( ent, true );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// push down from a step height above the wished position
|
||||
flStepSize = svgame.movevars.stepsize;
|
||||
neworg[2] += flStepSize;
|
||||
bool SV_MoveTest( edict_t *ent, vec3_t move, bool relink )
|
||||
{
|
||||
float temp;
|
||||
vec3_t oldorg, neworg, end;
|
||||
trace_t trace;
|
||||
|
||||
VectorCopy( ent->v.origin, oldorg );
|
||||
VectorAdd( ent->v.origin, move, neworg );
|
||||
|
||||
temp = svgame.movevars.stepsize;
|
||||
|
||||
neworg[2] += temp;
|
||||
VectorCopy( neworg, end );
|
||||
end[2] -= flStepSize * 2;
|
||||
end[2] -= temp * 2.0f;
|
||||
|
||||
if( iMode == WALKMOVE_WORLDONLY )
|
||||
trace = SV_Move( neworg, ent->v.mins, ent->v.maxs, end, MOVE_WORLDONLY, ent );
|
||||
else trace = SV_Move( neworg, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent );
|
||||
|
||||
if( trace.fAllSolid )
|
||||
return false;
|
||||
trace = SV_Move( neworg, ent->v.mins, ent->v.maxs, end, MOVE_WORLDONLY, ent );
|
||||
|
||||
if( trace.fStartSolid )
|
||||
if( trace.fAllSolid != 0 )
|
||||
return 0;
|
||||
|
||||
if( trace.fStartSolid != 0 )
|
||||
{
|
||||
neworg[2] -= flStepSize;
|
||||
neworg[2] -= temp;
|
||||
trace = SV_Move( neworg, ent->v.mins, ent->v.maxs, end, MOVE_WORLDONLY, ent );
|
||||
|
||||
if( iMode == WALKMOVE_WORLDONLY )
|
||||
trace = SV_Move( neworg, ent->v.mins, ent->v.maxs, end, MOVE_WORLDONLY, ent );
|
||||
else trace = SV_Move( neworg, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent );
|
||||
|
||||
if( trace.fAllSolid || trace.fStartSolid )
|
||||
return false;
|
||||
if( trace.fAllSolid != 0 || trace.fStartSolid != 0 )
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( trace.flFraction == 1.0f )
|
||||
{
|
||||
// if monster had the ground pulled out, go ahead and fall
|
||||
if( ent->v.flags & FL_PARTIALGROUND )
|
||||
{
|
||||
VectorAdd( ent->v.origin, move, ent->v.origin );
|
||||
|
||||
if( !VectorCompare( ent->v.origin, oldorg ))
|
||||
SV_LinkEdict( ent, relink );
|
||||
|
||||
ent->v.flags &= ~FL_ONGROUND;
|
||||
return true;
|
||||
}
|
||||
return false; // walked off an edge
|
||||
}
|
||||
|
||||
// check point traces down for dangling corners
|
||||
VectorCopy( trace.vecEndPos, ent->v.origin );
|
||||
groundent = trace.pHit;
|
||||
|
||||
// check our pos
|
||||
if( iMode == WALKMOVE_WORLDONLY )
|
||||
trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_WORLDONLY, ent );
|
||||
else trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_NORMAL, ent );
|
||||
|
||||
if( trace.fStartSolid )
|
||||
{
|
||||
VectorCopy( oldorg, ent->v.origin );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !SV_CheckBottom( ent, flStepSize, iMode ))
|
||||
{
|
||||
if( ent->v.flags & FL_PARTIALGROUND )
|
||||
{
|
||||
// actor had floor mostly pulled out from underneath it
|
||||
// and is trying to correct
|
||||
if( !VectorCompare( ent->v.origin, oldorg ))
|
||||
SV_LinkEdict( ent, relink );
|
||||
return true;
|
||||
}
|
||||
|
||||
ent->v.flags |= FL_PARTIALGROUND;
|
||||
VectorCopy( oldorg, ent->v.origin );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( ent->v.flags & FL_PARTIALGROUND )
|
||||
ent->v.flags &= ~FL_PARTIALGROUND;
|
||||
|
||||
ent->v.groundentity = groundent;
|
||||
|
||||
// the move is ok
|
||||
if( !VectorCompare( ent->v.origin, oldorg ))
|
||||
SV_LinkEdict( ent, relink );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
SV_StepDirection
|
||||
|
||||
Turns to the movement direction, and walks the current distance if
|
||||
facing it.
|
||||
======================
|
||||
*/
|
||||
bool SV_StepDirection( edict_t *ent, float yaw, float dist, int iMode )
|
||||
{
|
||||
vec3_t move, oldorigin;
|
||||
float delta;
|
||||
|
||||
yaw = yaw * M_PI * 2 / 360;
|
||||
VectorSet( move, com.cos( yaw ) * dist, com.sin( yaw ) * dist, 0.0f );
|
||||
VectorCopy( ent->v.origin, oldorigin );
|
||||
|
||||
if( SV_WalkMove( ent, move, WALKMOVE_NORMAL ))
|
||||
{
|
||||
if( iMode != MOVE_STRAFE )
|
||||
{
|
||||
delta = ent->v.angles[YAW] - ent->v.ideal_yaw;
|
||||
if( delta > 45 && delta < 315 )
|
||||
{
|
||||
// not turned far enough, so don't take the step
|
||||
VectorCopy( oldorigin, ent->v.origin );
|
||||
if( relink != 0 )
|
||||
{
|
||||
SV_LinkEdict( ent, true );
|
||||
}
|
||||
ent->v.flags &= ~FL_ONGROUND;
|
||||
return 1;
|
||||
}
|
||||
SV_LinkEdict( ent, false );
|
||||
return true;
|
||||
}
|
||||
|
||||
SV_LinkEdict( ent, false );
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
SV_MoveToOrigin
|
||||
|
||||
Turns to the movement direction, and walks the current distance if
|
||||
facing it.
|
||||
======================
|
||||
*/
|
||||
void SV_MoveToOrigin( edict_t *ed, const vec3_t goal, float dist, int iMode )
|
||||
{
|
||||
float yaw, distToGoal;
|
||||
vec3_t vecDist;
|
||||
|
||||
if( iMode == MOVE_STRAFE )
|
||||
{
|
||||
vec3_t delta;
|
||||
|
||||
VectorSubtract( goal, ed->v.origin, delta );
|
||||
VectorNormalizeFast( delta );
|
||||
yaw = SV_VecToYaw( delta );
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
yaw = ed->v.ideal_yaw;
|
||||
VectorCopy( trace.vecEndPos, ent->v.origin );
|
||||
|
||||
if( SV_CheckBottom( ent, MOVE_WORLDONLY ) == 0 )
|
||||
{
|
||||
if( ent->v.flags & FL_PARTIALGROUND )
|
||||
{
|
||||
if( relink != 0 )
|
||||
{
|
||||
SV_LinkEdict( ent, true );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
VectorCopy( oldorg, ent->v.origin );
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ent->v.flags & FL_PARTIALGROUND )
|
||||
ent->v.flags &= ~FL_PARTIALGROUND;
|
||||
|
||||
ent->v.groundentity = trace.pHit;
|
||||
|
||||
if( relink != 0 )
|
||||
{
|
||||
SV_LinkEdict( ent, true );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SV_StepDirection( edict_t *ent, float yaw, float dist )
|
||||
{
|
||||
int ret;
|
||||
vec3_t move;
|
||||
|
||||
yaw = yaw * M_PI * 2 / 360;
|
||||
VectorSet( move, com.cos( yaw ) * dist, com.sin( yaw ) * dist, 0.0f );
|
||||
|
||||
ret = SV_MoveStep( ent, move, 0 );
|
||||
SV_LinkEdict( ent, true );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool SV_FlyDirection( edict_t *ent, vec3_t move )
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = SV_MoveStep( ent, move, 0 );
|
||||
SV_LinkEdict( ent, true );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SV_NewChaseDir( edict_t *actor, vec3_t destination, float dist )
|
||||
{
|
||||
float deltax, deltay;
|
||||
float tempdir, olddir, turnaround;
|
||||
vec3_t d;
|
||||
|
||||
// so, we're shaving down some of the precision. Ohkay.
|
||||
olddir = anglemod(((int)( actor->v.ideal_yaw / 45.0f )) * 45.0f );
|
||||
turnaround = anglemod( olddir - 180 );
|
||||
|
||||
deltax = destination[0] - actor->v.origin[0];
|
||||
deltay = destination[1] - actor->v.origin[1];
|
||||
|
||||
if( deltax > 10 )
|
||||
d[1] = 0.0f;
|
||||
else if( deltax < -10 )
|
||||
d[1] = 180.0f;
|
||||
else d[1] = -1;
|
||||
|
||||
if( deltay < -10 )
|
||||
d[2] = 270.0f;
|
||||
else if( deltay > 10 )
|
||||
d[2] = 90.0f;
|
||||
else d[2] = -1;
|
||||
|
||||
// try direct route
|
||||
if( d[1] != -1 && d[2] != -1 )
|
||||
{
|
||||
if( d[1] == 0.0f )
|
||||
tempdir = ( d[2] == 90.0f ) ? 45.0f : 315.0f;
|
||||
else tempdir = ( d[2] == 90.0f ) ? 135.0f : 215.0f;
|
||||
|
||||
if( tempdir != turnaround && SV_StepDirection( actor, tempdir, dist ))
|
||||
return;
|
||||
}
|
||||
|
||||
// try other directions
|
||||
if( Com_RandomLong( 0, 1 ) != 0 || fabs( deltay ) > fabs( deltax ))
|
||||
{
|
||||
tempdir = d[1];
|
||||
d[1] = d[2];
|
||||
d[2] = tempdir;
|
||||
}
|
||||
|
||||
VectorSubtract( ed->v.origin, goal, vecDist );
|
||||
distToGoal = com.sqrt( vecDist[0] * vecDist[0] + vecDist[1] * vecDist[1] );
|
||||
if( dist > distToGoal ) dist = distToGoal;
|
||||
if( d[1] != -1 && d[1] != turnaround && SV_StepDirection( actor, d[1], dist ))
|
||||
return;
|
||||
|
||||
SV_StepDirection( ed, yaw, dist, iMode );
|
||||
if( d[2] != -1 && d[2] != turnaround && SV_StepDirection( actor, d[2], dist ))
|
||||
return;
|
||||
|
||||
// there is no direct path to the player, so pick another direction
|
||||
if( olddir != -1 && SV_StepDirection( actor, olddir, dist ))
|
||||
return;
|
||||
|
||||
// fine, just run somewhere.
|
||||
if( Com_RandomLong( 0, 1 ) != 1 )
|
||||
{
|
||||
for( tempdir = 0; tempdir <= 315; tempdir += 45 )
|
||||
{
|
||||
if( tempdir != turnaround && SV_StepDirection( actor, tempdir, dist ))
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( tempdir = 315; tempdir >= 0; tempdir -= 45 )
|
||||
{
|
||||
if( tempdir != turnaround && SV_StepDirection( actor, tempdir, dist ))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// we tried. Run backwards. THAT ought to work...
|
||||
if( turnaround != -1 && SV_StepDirection( actor, turnaround, dist ))
|
||||
return;
|
||||
|
||||
// well, we're stuck somehow.
|
||||
actor->v.ideal_yaw = olddir;
|
||||
|
||||
// if a bridge was pulled out from underneath a monster, it may not have
|
||||
// a valid standing position at all.
|
||||
|
||||
if( !SV_CheckBottom( actor, MOVE_NORMAL ))
|
||||
{
|
||||
actor->v.flags |= FL_PARTIALGROUND;
|
||||
}
|
||||
}
|
||||
|
||||
void SV_MoveToOrigin( edict_t *ent, const vec3_t pflGoal, float dist, int iMoveType )
|
||||
{
|
||||
vec3_t vecDist;
|
||||
|
||||
VectorCopy( pflGoal, vecDist );
|
||||
|
||||
if( ent->v.flags & ( FL_FLY|FL_SWIM|FL_ONGROUND ))
|
||||
{
|
||||
if( iMoveType == MOVE_NORMAL )
|
||||
{
|
||||
if( SV_StepDirection( ent, ent->v.ideal_yaw, dist ) == 0 )
|
||||
{
|
||||
SV_NewChaseDir( ent, vecDist, dist );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vecDist[0] -= ent->v.origin[0];
|
||||
vecDist[1] -= ent->v.origin[1];
|
||||
|
||||
if( ent->v.flags & ( FL_FLY|FL_SWIM ))
|
||||
vecDist[2] -= ent->v.origin[2];
|
||||
else vecDist[2] = 0.0f;
|
||||
|
||||
VectorNormalize( vecDist );
|
||||
VectorScale( vecDist, dist, vecDist );
|
||||
SV_FlyDirection( ent, vecDist );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -176,6 +176,7 @@ void SV_Impact( edict_t *e1, trace_t *trace )
|
|||
return;
|
||||
}
|
||||
|
||||
svgame.globals->time = sv.time;
|
||||
SV_CopyTraceToGlobal( trace );
|
||||
|
||||
if( !e1->free && !e2->free && e1->v.solid != SOLID_NOT )
|
||||
|
@ -562,7 +563,7 @@ trace_t SV_PushEntity( edict_t *ent, const vec3_t lpush, const vec3_t apush, int
|
|||
type = MOVE_NOMONSTERS; // only clip against bmodels
|
||||
else type = MOVE_NORMAL;
|
||||
|
||||
trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, end, type|FMOVE_SIMPLEBOX, ent );
|
||||
trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, end, type, ent );
|
||||
if( !trace.fAllSolid && !trace.fStartSolid )
|
||||
{
|
||||
VectorCopy( trace.vecEndPos, ent->v.origin );
|
||||
|
@ -928,12 +929,14 @@ void SV_Physics_Pusher( edict_t *ent )
|
|||
if( thinktime > oldtime && thinktime <= ent->v.ltime )
|
||||
{
|
||||
ent->v.nextthink = 0.0f;
|
||||
svgame.globals->time = sv.time;
|
||||
svgame.dllFuncs.pfnThink( ent );
|
||||
if( ent->free ) return;
|
||||
}
|
||||
else if( ent->v.flags & FL_ALWAYSTHINK || ( sv.state == ss_loading && !sv.loadgame ))
|
||||
{
|
||||
ent->v.nextthink = 0.0f;
|
||||
svgame.globals->time = sv.time;
|
||||
svgame.dllFuncs.pfnThink( ent );
|
||||
if( ent->free ) return;
|
||||
}
|
||||
|
|
|
@ -367,6 +367,8 @@ void SV_TouchLinks( edict_t *ent, areanode_t *node )
|
|||
if( SV_HullPointContents( hull, hull->firstclipnode, test ) == CONTENTS_EMPTY )
|
||||
continue;
|
||||
}
|
||||
|
||||
svgame.globals->time = sv.time;
|
||||
svgame.dllFuncs.pfnTouch( touch, ent );
|
||||
}
|
||||
|
||||
|
@ -933,6 +935,83 @@ trace_t SV_TraceHull( edict_t *ent, int hullNum, const vec3_t start, vec3_t mins
|
|||
return trace;
|
||||
}
|
||||
|
||||
/* DESCRIPTION: SurfaceAtPoint
|
||||
// LOCATION:
|
||||
// PATH: TraceTexture, recursive
|
||||
//
|
||||
// A weird one. First, it seems to recursively call itself to dig deep into
|
||||
// the node tree, treating its own failure as a sign that it's dug deep
|
||||
// enough. Then, it loops through some odd texture stuff, looking for
|
||||
// a match. A match of what? Don't know yet.
|
||||
*/
|
||||
msurface_t *SV_RecursiveSurfCheck( model_t *model, mnode_t *node, vec3_t v1, vec3_t v2 )
|
||||
{
|
||||
double var_4, var_8, var_c;
|
||||
int var_10, var_10_2;
|
||||
mplane_t * var_14_plane;
|
||||
vec3_t var_20;
|
||||
msurface_t * var_24_surface;
|
||||
int var_28, var_2c;
|
||||
int var_30, var_34;
|
||||
int var_38;
|
||||
mtexinfo_t * var_3C_texinfo;
|
||||
|
||||
|
||||
if(node->contents < 0) { return(NULL); }
|
||||
|
||||
var_14_plane = node->plane;
|
||||
|
||||
var_4 = ((v1[0] * var_14_plane->normal[0]) + (v1[1] * var_14_plane->normal[1]) + (v1[2] * var_14_plane->normal[2])) - var_14_plane->dist;
|
||||
var_8 = ((v2[0] * var_14_plane->normal[0]) + (v2[1] * var_14_plane->normal[1]) + (v2[2] * var_14_plane->normal[2])) - var_14_plane->dist;
|
||||
|
||||
if(var_4 < 0) { var_10 = 1; }
|
||||
else { var_10 = 0; }
|
||||
|
||||
if(var_8 < 0) { var_10_2 = 1; }
|
||||
else { var_10_2 = 0; }
|
||||
|
||||
if(var_10 == var_10_2) {
|
||||
|
||||
return(SV_RecursiveSurfCheck(model, node->children[var_10], v1, v2));
|
||||
}
|
||||
|
||||
var_c = var_4 / (var_4 - var_8);
|
||||
|
||||
var_20[0] = ((v2[0] - v1[0]) * var_c) + v1[0];
|
||||
var_20[1] = ((v2[1] - v1[1]) * var_c) + v1[1];
|
||||
var_20[2] = ((v2[2] - v1[2]) * var_c) + v1[2];
|
||||
|
||||
//Now THIS is weird.
|
||||
var_24_surface = SV_RecursiveSurfCheck(model, node->children[var_10], v1, var_20);
|
||||
if(var_24_surface != NULL || var_10 == var_10_2) { return(var_24_surface); } //Second check not possible as in asm... I think.
|
||||
|
||||
|
||||
var_24_surface = node->firstface;
|
||||
|
||||
for(var_38 = 0; var_38 < node->numfaces; var_38++, var_24_surface++) {
|
||||
|
||||
var_3C_texinfo = var_24_surface->texinfo;
|
||||
|
||||
var_28 = (var_20[0] * var_3C_texinfo->vecs[0][0]) + (var_20[1] * var_3C_texinfo->vecs[0][1]) + (var_20[2] * var_3C_texinfo->vecs[0][2]) + var_3C_texinfo->vecs[0][3];
|
||||
var_2c = (var_20[0] * var_3C_texinfo->vecs[1][0]) + (var_20[1] * var_3C_texinfo->vecs[1][1]) + (var_20[2] * var_3C_texinfo->vecs[1][2]) + var_3C_texinfo->vecs[1][3];
|
||||
|
||||
if(var_28 >= var_24_surface->texturemins[0] && var_2c >= var_24_surface->texturemins[1]) {
|
||||
|
||||
var_30 = var_28 - var_24_surface->texturemins[0];
|
||||
var_34 = var_2c - var_24_surface->texturemins[1];
|
||||
|
||||
if(var_30 <= var_24_surface->extents[0] && var_34 <= var_24_surface->extents[1]) {
|
||||
|
||||
return(var_24_surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(var_10 == 1) { var_10 = 0; }
|
||||
else { var_10 = 1; }
|
||||
return(SV_RecursiveSurfCheck( model, node->children[var_10], var_20, v2 ));
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
SV_ClipToLinks
|
||||
|
|
Reference in New Issue