30 Nov 2016

This commit is contained in:
g-cont 2016-11-30 00:00:00 +03:00 committed by Alibek Omarov
parent 33c48f4cad
commit 39542ce469
14 changed files with 426 additions and 88 deletions

View File

@ -89,7 +89,7 @@ typedef enum
TF_UNCOMPRESSED = (1<<5), // don't compress texture in video memory
TF_CUBEMAP = (1<<6), // it's cubemap texture
TF_DEPTHMAP = (1<<7), // custom texture filter used
TF_INTENSITY = (1<<8), // monochrome intensity image
// reserved
TF_LUMINANCE = (1<<9), // force image to grayscale
TF_SKYSIDE = (1<<10), // this is a part of skybox
TF_CLAMP = (1<<11), // clamp texcoords to [0..1] range
@ -102,10 +102,9 @@ typedef enum
TF_TEXTURE_1D = (1<<18), // this is GL_TEXTURE_1D
TF_BORDER = (1<<19), // zero clamp for projected textures
TF_TEXTURE_3D = (1<<20), // this is GL_TEXTURE_3D
TF_STATIC = (1<<21), // obsolete (not used)
// reserved
TF_TEXTURE_RECTANGLE= (1<<22), // this is GL_TEXTURE_RECTANGLE
TF_DXT_FORMAT = (1<<23), // internal flag who indicated DXT-compressed texture
// reserved
TF_TEXTURE_2D_ARRAY = (1<<24), // this is 2D texture array (multi-layers)
TF_IMG_UPLOADED = (1<<25), // this is set for first time when called glTexImage, otherwise it will be call glTexSubImage
TF_ARB_FLOAT = (1<<26), // float textures

View File

@ -326,7 +326,9 @@ qboolean CL_ProcessOverviewCmds( usercmd_t *cmd )
{
ref_overview_t *ov = &clgame.overView;
int sign = 1;
float step = 100.0f * (cl.time - cl.oldtime);
float size = world.size[!ov->rotated] / world.size[ov->rotated];
float step = (2.0f / size) * host.realframetime;
float step2 = step * 100.0f * (2.0f / ov->flZoom);
if( !gl_overview->integer || gl_showtextures->integer )
return false;
@ -339,22 +341,22 @@ qboolean CL_ProcessOverviewCmds( usercmd_t *cmd )
if( cmd->buttons & IN_JUMP ) ov->zFar += step;
else if( cmd->buttons & IN_DUCK ) ov->zFar -= step;
if( cmd->buttons & IN_FORWARD ) ov->origin[ov->rotated] -= sign * step;
else if( cmd->buttons & IN_BACK ) ov->origin[ov->rotated] += sign * step;
if( cmd->buttons & IN_FORWARD ) ov->origin[ov->rotated] -= sign * step2;
else if( cmd->buttons & IN_BACK ) ov->origin[ov->rotated] += sign * step2;
if( ov->rotated )
{
if( cmd->buttons & ( IN_RIGHT|IN_MOVERIGHT ))
ov->origin[0] -= sign * step;
ov->origin[0] -= sign * step2;
else if( cmd->buttons & ( IN_LEFT|IN_MOVELEFT ))
ov->origin[0] += sign * step;
ov->origin[0] += sign * step2;
}
else
{
if( cmd->buttons & ( IN_RIGHT|IN_MOVERIGHT ))
ov->origin[1] += sign * step;
ov->origin[1] += sign * step2;
else if( cmd->buttons & ( IN_LEFT|IN_MOVELEFT ))
ov->origin[1] -= sign * step;
ov->origin[1] -= sign * step2;
}
if( cmd->buttons & IN_ATTACK ) ov->flZoom += step;

View File

@ -652,8 +652,6 @@ static void GL_SetTextureFormat( gltexture_t *tex, pixformat_t format, int chann
case PF_DXT3: tex->format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
case PF_DXT5: tex->format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
}
SetBits( tex->flags, TF_DXT_FORMAT );
return;
}
else if( FBitSet( tex->flags, TF_DEPTHMAP ))
@ -693,58 +691,40 @@ static void GL_SetTextureFormat( gltexture_t *tex, pixformat_t format, int chann
}
else if( compressImage )
{
if( tex->flags & TF_INTENSITY )
switch( GL_CalcTextureSamples( channelMask ))
{
tex->format = GL_COMPRESSED_INTENSITY_ARB;
}
else
{
switch( GL_CalcTextureSamples( channelMask ))
{
case 1: tex->format = GL_LUMINANCE8; break;
case 2: tex->format = GL_LUMINANCE8_ALPHA8; break;
case 3: tex->format = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break;
case 4: tex->format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
}
tex->flags &= ~TF_INTENSITY;
case 1: tex->format = GL_LUMINANCE8; break;
case 2: tex->format = GL_LUMINANCE8_ALPHA8; break;
case 3: tex->format = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break;
case 4: tex->format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
}
}
else
{
// NOTE: not all the types will be compressed
if( tex->flags & TF_INTENSITY )
{
tex->format = GL_INTENSITY8;
}
else
{
int bits = glw_state.desktopBitsPixel;
int bits = glw_state.desktopBitsPixel;
switch( GL_CalcTextureSamples( channelMask ) )
switch( GL_CalcTextureSamples( channelMask ) )
{
case 1: tex->format = GL_LUMINANCE8; break;
case 2: tex->format = GL_LUMINANCE8_ALPHA8; break;
case 3:
switch( bits )
{
case 1: tex->format = GL_LUMINANCE8; break;
case 2: tex->format = GL_LUMINANCE8_ALPHA8; break;
case 3:
switch( bits )
{
case 16: tex->format = GL_RGB5; break;
case 32: tex->format = GL_RGB8; break;
default: tex->format = GL_RGB; break;
}
break;
case 4:
default:
switch( bits )
{
case 16: tex->format = GL_RGBA4; break;
case 32: tex->format = GL_RGBA8; break;
default: tex->format = GL_RGBA; break;
}
break;
case 16: tex->format = GL_RGB5; break;
case 32: tex->format = GL_RGB8; break;
default: tex->format = GL_RGB; break;
}
tex->flags &= ~TF_INTENSITY;
break;
case 4:
default:
switch( bits )
{
case 16: tex->format = GL_RGBA4; break;
case 32: tex->format = GL_RGBA8; break;
default: tex->format = GL_RGBA; break;
}
break;
}
}
}

View File

@ -418,6 +418,25 @@ byte *COM_LoadFile( const char *filename, int usehunk, int *pLength )
return COM_LoadFileForMe( filename, pLength );
}
/*
=============
COM_LoadFile
=============
*/
int COM_SaveFile( const char *filename, const void *data, long len )
{
// check for empty filename
if( !filename || !*filename )
return false;
// check for null data
if( !data || len <= 0 )
return false;
return FS_WriteFile( filename, data, len );
}
/*
=============
COM_FreeFile

View File

@ -695,6 +695,7 @@ qboolean SV_Active( void );
cvar_t *pfnCvar_RegisterClientVariable( const char *szName, const char *szValue, int flags );
cvar_t *pfnCvar_RegisterGameUIVariable( const char *szName, const char *szValue, int flags );
char *COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize );
int COM_SaveFile( const char *filename, const void *data, long len );
byte* COM_LoadFileForMe( const char *filename, int *pLength );
cvar_t *pfnCVarGetPointer( const char *szVarName );
int pfnDrawConsoleString( int x, int y, char *string );

View File

@ -67,7 +67,7 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
int ver = -1, mapver = -1, lumpofs = 0, lumplen = 0;
const char *ext = FS_FileExtension( t->filenames[i] );
char *ents = NULL, *pfile;
qboolean paranoia = false;
int version = 0;
qboolean gearbox = false;
if( Q_stricmp( ext, "bsp" )) continue;
@ -108,8 +108,7 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
hdrext = (dextrahdr_t *)((byte *)buf + sizeof( dheader31_t ));
else hdrext = (dextrahdr_t *)((byte *)buf + sizeof( dheader_t ));
if( hdrext->id == IDEXTRAHEADER && hdrext->version == EXTRA_VERSION )
paranoia = true;
if( hdrext->id == IDEXTRAHEADER ) version = hdrext->version;
Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
FS_StripExtension( entfilename );
@ -163,11 +162,17 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
break;
case HLBSP_VERSION:
if( gearbox ) Q_strncpy( buf, "Blue-Shift", sizeof( buf ));
else if( paranoia ) Q_strncpy( buf, "Paranoia 2", sizeof( buf ));
else if( version == 1 ) Q_strncpy( buf, "XashXT old format", sizeof( buf ));
else if( version == 2 ) Q_strncpy( buf, "Paranoia 2: Savior", sizeof( buf ));
else if( version == 3 ) Q_strncpy( buf, "not supported", sizeof( buf ));
else if( version == 4 ) Q_strncpy( buf, "Half-Life extended", sizeof( buf ));
else Q_strncpy( buf, "Half-Life", sizeof( buf ));
break;
case XTBSP_VERSION:
if( paranoia ) Q_strncpy( buf, "Paranoia 2", sizeof( buf ));
if( version == 1 ) Q_strncpy( buf, "XashXT old format", sizeof( buf ));
else if( version == 2 ) Q_strncpy( buf, "Paranoia 2: Savior", sizeof( buf ));
else if( version == 3 ) Q_strncpy( buf, "not supported", sizeof( buf ));
else if( version == 4 ) Q_strncpy( buf, "Xash3D extended", sizeof( buf ));
else Q_strncpy( buf, "Xash3D", sizeof( buf ));
break;
default: Q_strncpy( buf, "??", sizeof( buf )); break;

View File

@ -2400,8 +2400,9 @@ qboolean FS_WriteFile( const char *filename, const void *data, long len )
return false;
}
FS_Write (file, data, len);
FS_Close (file);
FS_Write( file, data, len );
FS_Close( file );
return true;
}

View File

@ -142,6 +142,9 @@ void Mod_TesselatePolygon( msurface_t *surf, model_t *mod, float tessSize );
int Mod_BoxLeafnums( const vec3_t mins, const vec3_t maxs, short *list, int listsize, int *lastleaf );
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis );
qboolean Mod_BoxVisible( const vec3_t mins, const vec3_t maxs, const byte *visbits );
int Mod_CheckLump( const char *filename, const int lump, int *lumpsize );
int Mod_ReadLump( const char *filename, const int lump, void **lumpdata, int *lumpsize );
int Mod_SaveLump( const char *filename, const int lump, void *lumpdata, int lumpsize );
void Mod_BuildSurfacePolygons( msurface_t *surf, mextrasurf_t *info );
void Mod_AmbientLevels( const vec3_t p, byte *pvolumes );
int Mod_SampleSizeForFace( msurface_t *surf );

View File

@ -22,6 +22,7 @@ GNU General Public License for more details.
#include "gl_local.h"
#include "features.h"
#include "client.h"
#include "physint.h" // LUMP_ error codes
#define MAX_SIDE_VERTS 512 // per one polygon
@ -3336,4 +3337,235 @@ model_t *Mod_Handle( int handle )
return NULL;
}
return com_models[handle];
}
/*
==================
Mod_CheckLump
check lump for existing
==================
*/
int Mod_CheckLump( const char *filename, const int lump, int *lumpsize )
{
file_t *f = FS_Open( filename, "rb", true );
byte buffer[sizeof( dheader31_t ) + sizeof( dextrahdr_t )];
size_t prefetch_size = sizeof( buffer );
dextrahdr_t *extrahdr;
dheader_t *header;
if( !f ) return LUMP_LOAD_COULDNT_OPEN;
if( FS_Read( f, buffer, prefetch_size ) != prefetch_size )
{
FS_Close( f );
return LUMP_LOAD_BAD_HEADER;
}
header = (dheader_t *)buffer;
if( header->version != HLBSP_VERSION && header->version != XTBSP_VERSION )
{
FS_Close( f );
return LUMP_LOAD_BAD_VERSION;
}
// BSP31 and BSP30 have different offsets
if( header->version == XTBSP_VERSION )
extrahdr = (dextrahdr_t *)((byte *)buffer + sizeof( dheader31_t ));
else extrahdr = (dextrahdr_t *)((byte *)buffer + sizeof( dheader_t ));
if( extrahdr->id != IDEXTRAHEADER || extrahdr->version != EXTRA_VERSION )
{
FS_Close( f );
return LUMP_LOAD_NO_EXTRADATA;
}
if( lump < 0 || lump >= EXTRA_LUMPS )
{
FS_Close( f );
return LUMP_LOAD_INVALID_NUM;
}
if( extrahdr->lumps[lump].filelen <= 0 )
{
FS_Close( f );
return LUMP_LOAD_NOT_EXIST;
}
if( lumpsize )
*lumpsize = extrahdr->lumps[lump].filelen;
FS_Close( f );
return LUMP_LOAD_OK;
}
/*
==================
Mod_ReadLump
reading random lump by user request
==================
*/
int Mod_ReadLump( const char *filename, const int lump, void **lumpdata, int *lumpsize )
{
file_t *f = FS_Open( filename, "rb", true );
byte buffer[sizeof( dheader31_t ) + sizeof( dextrahdr_t )];
size_t prefetch_size = sizeof( buffer );
dextrahdr_t *extrahdr;
dheader_t *header;
byte *data;
int length;
if( !f ) return LUMP_LOAD_COULDNT_OPEN;
if( FS_Read( f, buffer, prefetch_size ) != prefetch_size )
{
FS_Close( f );
return LUMP_LOAD_BAD_HEADER;
}
header = (dheader_t *)buffer;
if( header->version != HLBSP_VERSION && header->version != XTBSP_VERSION )
{
FS_Close( f );
return LUMP_LOAD_BAD_VERSION;
}
// BSP31 and BSP30 have different offsets
if( header->version == XTBSP_VERSION )
extrahdr = (dextrahdr_t *)((byte *)buffer + sizeof( dheader31_t ));
else extrahdr = (dextrahdr_t *)((byte *)buffer + sizeof( dheader_t ));
if( extrahdr->id != IDEXTRAHEADER || extrahdr->version != EXTRA_VERSION )
{
FS_Close( f );
return LUMP_LOAD_NO_EXTRADATA;
}
if( lump < 0 || lump >= EXTRA_LUMPS )
{
FS_Close( f );
return LUMP_LOAD_INVALID_NUM;
}
if( extrahdr->lumps[lump].filelen <= 0 )
{
FS_Close( f );
return LUMP_LOAD_NOT_EXIST;
}
data = malloc( extrahdr->lumps[lump].filelen + 1 );
length = extrahdr->lumps[lump].filelen;
if( !data )
{
FS_Close( f );
return LUMP_LOAD_MEM_FAILED;
}
FS_Seek( f, extrahdr->lumps[lump].fileofs, SEEK_SET );
if( FS_Read( f, data, length ) != length )
{
Mem_Free( data );
FS_Close( f );
return LUMP_LOAD_CORRUPTED;
}
data[length] = 0; // write term
FS_Close( f );
if( lumpsize )
*lumpsize = length;
*lumpdata = data;
return LUMP_LOAD_OK;
}
/*
==================
Mod_SaveLump
writing lump by user request
only empty lumps is allows
==================
*/
int Mod_SaveLump( const char *filename, const int lump, void *lumpdata, int lumpsize )
{
file_t *f = FS_Open( filename, "e+b", true );
byte buffer[sizeof( dheader31_t ) + sizeof( dextrahdr_t )];
size_t prefetch_size = sizeof( buffer );
dextrahdr_t *extrahdr;
dheader_t *header;
if( !f ) return LUMP_SAVE_COULDNT_OPEN;
if( !lumpdata || lumpsize <= 0 )
return LUMP_SAVE_NO_DATA;
if( FS_Read( f, buffer, prefetch_size ) != prefetch_size )
{
FS_Close( f );
return LUMP_SAVE_BAD_HEADER;
}
header = (dheader_t *)buffer;
if( header->version != HLBSP_VERSION && header->version != XTBSP_VERSION )
{
FS_Close( f );
return LUMP_SAVE_BAD_VERSION;
}
// BSP31 and BSP30 have different offsets
if( header->version == XTBSP_VERSION )
extrahdr = (dextrahdr_t *)((byte *)buffer + sizeof( dheader31_t ));
else extrahdr = (dextrahdr_t *)((byte *)buffer + sizeof( dheader_t ));
if( extrahdr->id != IDEXTRAHEADER || extrahdr->version != EXTRA_VERSION )
{
FS_Close( f );
return LUMP_SAVE_NO_EXTRADATA;
}
if( lump < 0 || lump >= EXTRA_LUMPS )
{
FS_Close( f );
return LUMP_SAVE_INVALID_NUM;
}
if( extrahdr->lumps[lump].filelen != 0 )
{
FS_Close( f );
return LUMP_SAVE_ALREADY_EXIST;
}
FS_Seek( f, 0, SEEK_END );
// will be saved later
extrahdr->lumps[lump].fileofs = FS_Tell( f );
extrahdr->lumps[lump].filelen = lumpsize;
if( FS_Write( f, lumpdata, lumpsize ) != lumpsize )
{
FS_Close( f );
return LUMP_SAVE_CORRUPTED;
}
// update the header
if( header->version == XTBSP_VERSION )
FS_Seek( f, sizeof( dheader31_t ), SEEK_SET );
else FS_Seek( f, sizeof( dheader_t ), SEEK_SET );
if( FS_Write( f, extrahdr, sizeof( dextrahdr_t )) != sizeof( dextrahdr_t ))
{
FS_Close( f );
return LUMP_SAVE_CORRUPTED;
}
FS_Close( f );
return LUMP_SAVE_OK;
}

View File

@ -26,6 +26,28 @@ GNU General Public License for more details.
#define SERVER_LOADING 1
#define SERVER_ACTIVE 2
// LUMP reading errors
#define LUMP_LOAD_OK 0
#define LUMP_LOAD_COULDNT_OPEN 1
#define LUMP_LOAD_BAD_HEADER 2
#define LUMP_LOAD_BAD_VERSION 3
#define LUMP_LOAD_NO_EXTRADATA 4
#define LUMP_LOAD_INVALID_NUM 5
#define LUMP_LOAD_NOT_EXIST 6
#define LUMP_LOAD_MEM_FAILED 7
#define LUMP_LOAD_CORRUPTED 8
// LUMP saving errors
#define LUMP_SAVE_OK 0
#define LUMP_SAVE_COULDNT_OPEN 1
#define LUMP_SAVE_BAD_HEADER 2
#define LUMP_SAVE_BAD_VERSION 3
#define LUMP_SAVE_NO_EXTRADATA 4
#define LUMP_SAVE_INVALID_NUM 5
#define LUMP_SAVE_ALREADY_EXIST 6
#define LUMP_SAVE_NO_DATA 7
#define LUMP_SAVE_CORRUPTED 8
typedef struct areanode_s
{
int axis; // -1 = leaf node
@ -64,6 +86,22 @@ typedef struct server_physics_api_s
// static allocations
void *(*pfnMemAlloc)( size_t cb, const char *filename, const int fileline );
void (*pfnMemFree)( void *mem, const char *filename, const int fileline );
// trace & contents
int (*pfnMaskPointContents)( const float *pos, int groupmask );
trace_t (*pfnTrace)( const float *p0, float *mins, float *maxs, const float *p1, int type, edict_t *e );
trace_t (*pfnTraceNoEnts)( const float *p0, float *mins, float *maxs, const float *p1, int type, edict_t *e );
int (*pfnBoxInPVS)( const float *org, const float *boxmins, const float *boxmaxs );
// message handler (missed function to write raw bytes)
void (*pfnWriteBytes)( byte *bytes, int count );
// BSP lump management
int (*pfnCheckLump)( const char *filename, const int lump, int *lumpsize );
int (*pfnReadLump)( const char *filename, const int lump, void **lumpdata, int *lumpsize );
int (*pfnSaveLump)( const char *filename, const int lump, void *lumpdata, int lumpsize );
int (*pfnSaveFile)( const char *filename, const void *data, long len );
} server_physics_api_t;
// physic callbacks
@ -109,6 +147,8 @@ typedef struct physics_interface_s
const char* (*pfnGetString)( string_t iString );
// helper for restore custom decals that have custom message (e.g. Paranoia)
int (*pfnRestoreDecal)( struct decallist_s *entry, edict_t *pEdict, qboolean adjacent );
// handle custom trigger touching for player
void (*PM_PlayerTouch)( struct playermove_s *ppmove, edict_t *client );
} physics_interface_t;
#endif//PHYSINT_H

View File

@ -555,6 +555,7 @@ edict_t* SV_FindEntityByString( edict_t *pStartEdict, const char *pszField, cons
void SV_PlaybackEventFull( int flags, const edict_t *pInvoker, word eventindex, float delay, float *origin,
float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 );
void SV_PlaybackReliableEvent( sizebuf_t *msg, word eventindex, float delay, event_args_t *args );
qboolean SV_BoxInPVS( const vec3_t org, const vec3_t absmin, const vec3_t absmax );
void SV_BaselineForEntity( edict_t *pEdict );
void SV_WriteEntityPatch( const char *filename );
char *SV_ReadEntityScript( const char *filename, int *flags );
@ -571,6 +572,7 @@ void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float
void SV_CreateStaticEntity( struct sizebuf_s *msg, sv_static_entity_t *ent );
edict_t* pfnPEntityOfEntIndex( int iEntIndex );
int pfnIndexOfEdict( const edict_t *pEdict );
void pfnWriteBytes( const byte *bytes, int count );
void SV_UpdateBaseVelocity( edict_t *ent );
byte *pfnSetFatPVS( const float *org );
byte *pfnSetFatPAS( const float *org );

View File

@ -529,7 +529,7 @@ SV_BoxInPVS
check brush boxes in fat pvs
==============
*/
static qboolean SV_BoxInPVS( const vec3_t org, const vec3_t absmin, const vec3_t absmax )
qboolean SV_BoxInPVS( const vec3_t org, const vec3_t absmin, const vec3_t absmax )
{
byte *vis = Mod_GetPVSForPoint( org );
@ -2115,6 +2115,9 @@ static int pfnTraceMonsterHull( edict_t *pEdict, const float *v1, const float *v
return 1;
}
if( pEdict != pentToSkip )
MsgDev( D_ERROR, "TRACE_MONSTER_HULL: pEdict != pentToSkip\n" );
trace = SV_Move( v1, pEdict->v.mins, pEdict->v.maxs, v2, fNoMonsters, pentToSkip );
if( ptr ) SV_ConvertTrace( ptr, &trace );
@ -2640,6 +2643,18 @@ void pfnWriteCoord( float flValue )
svgame.msg_realsize += 2;
}
/*
=============
pfnWriteBytes
=============
*/
void pfnWriteBytes( const byte *bytes, int count )
{
MSG_WriteBytes( &sv.multicast, bytes, count );
svgame.msg_realsize += count;
}
/*
=============
pfnWriteString

View File

@ -232,21 +232,23 @@ qboolean SV_PlayerRunThink( edict_t *ent, float frametime, double time )
{
float thinktime;
if(!( ent->v.flags & (FL_KILLME|FL_DORMANT )))
if( !FBitSet( ent->v.flags, FL_KILLME|FL_DORMANT ))
{
thinktime = ent->v.nextthink;
if( thinktime <= 0.0f || thinktime > time + frametime )
if( thinktime <= 0.0f || (time + frametime) < thinktime )
return true;
if( thinktime > time )
thinktime = time;
if( thinktime < time )
thinktime = time; // don't let things stay in the past.
// it is possible to start that way
// by a trigger with a local time.
ent->v.nextthink = 0.0f;
svgame.globals->time = thinktime;
svgame.dllFuncs.pfnThink( ent );
}
if( ent->v.flags & FL_KILLME )
if( FBitSet( ent->v.flags, FL_KILLME ))
SV_FreeEdict( ent );
return !ent->free;
@ -1929,6 +1931,26 @@ static void pfnMem_Free( void *mem, const char *filename, const int fileline )
_Mem_Free( mem, filename, fileline );
}
/*
=============
pfnPointContents
=============
*/
static int pfnPointContents( const float *pos, int groupmask )
{
int oldmask, cont;
if( !pos ) return CONTENTS_NONE;
oldmask = svs.groupmask;
svs.groupmask = groupmask;
cont = SV_PointContents( pos );
svs.groupmask = oldmask; // restore old mask
return cont;
}
static server_physics_api_t gPhysicsAPI =
{
SV_LinkEdict,
@ -1951,6 +1973,15 @@ static server_physics_api_t gPhysicsAPI =
GL_TextureData,
pfnMem_Alloc,
pfnMem_Free,
pfnPointContents,
SV_Move,
SV_MoveNoEnts,
SV_BoxInPVS,
pfnWriteBytes,
Mod_CheckLump,
Mod_ReadLump,
Mod_SaveLump,
COM_SaveFile,
};
/*

View File

@ -1095,29 +1095,37 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd, int random_seed )
// copy results back to client
SV_FinishPMove( svgame.pmove, cl );
// link into place and touch triggers
SV_LinkEdict( clent, true );
VectorCopy( clent->v.velocity, oldvel ); // save velocity
// touch other objects
for( i = 0; i < svgame.pmove->numtouch; i++ )
if( svgame.physFuncs.PM_PlayerTouch != NULL )
{
// never touch the objects when "playersonly" is active
if( i == MAX_PHYSENTS || ( sv.hostflags & SVF_PLAYERSONLY ))
break;
pmtrace = &svgame.pmove->touchindex[i];
touch = EDICT_NUM( svgame.pmove->physents[pmtrace->ent].info );
if( touch == clent ) continue;
VectorCopy( pmtrace->deltavelocity, clent->v.velocity );
SV_ConvertPMTrace( &trace, pmtrace, touch );
SV_Impact( touch, clent, &trace );
// run custom impact function
svgame.physFuncs.PM_PlayerTouch( svgame.pmove, clent );
}
else
{
// link into place and touch triggers
SV_LinkEdict( clent, true );
VectorCopy( clent->v.velocity, oldvel ); // save velocity
// restore velocity
VectorCopy( oldvel, clent->v.velocity );
// touch other objects
for( i = 0; i < svgame.pmove->numtouch; i++ )
{
// never touch the objects when "playersonly" is active
if( i == MAX_PHYSENTS || ( sv.hostflags & SVF_PLAYERSONLY ))
break;
pmtrace = &svgame.pmove->touchindex[i];
touch = EDICT_NUM( svgame.pmove->physents[pmtrace->ent].info );
if( touch == clent ) continue;
VectorCopy( pmtrace->deltavelocity, clent->v.velocity );
SV_ConvertPMTrace( &trace, pmtrace, touch );
SV_Impact( touch, clent, &trace );
}
// restore velocity
VectorCopy( oldvel, clent->v.velocity );
}
svgame.pmove->numtouch = 0;
svgame.globals->time = cl->timebase;