Compare commits

...

5 Commits

Author SHA1 Message Date
fgsfds 2e4c399f3b fix whitespace 2021-01-14 21:48:05 +03:00
fgsfds ababdaefb3 sync repo with CU#3:
add nodegraph_graphset_remove

backport clipgroups from xonotic-darkplaces

treat clipgroups as bit flags

add timestamps to developer_loading messages
2021-01-14 21:45:06 +03:00
fgsfds 7fa67fed66 fix #3 2020-05-30 21:07:42 +03:00
fgsfds 81cfc9ebac sync repo with CU#2:
* more fun viewbob fixes

* noclip and fly now work similarly to Half-Life

* backported some fixes from xonotic/darkplaces

* added saveshot command

* various limit adjustments
2020-05-28 19:08:31 +03:00
fgsfds ae8a4c06f2 Fix memalloc error in nodegraph.c 2020-02-29 04:49:35 +03:00
29 changed files with 317 additions and 73 deletions

View File

@ -227,6 +227,7 @@ trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
// list of entities to test for collisions
int numtouchedicts;
static prvm_edict_t *touchedicts[MAX_EDICTS];
int clipgroup;
if (hitnetworkentity)
*hitnetworkentity = 0;
@ -280,6 +281,8 @@ trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
// precalculate passedict's owner edict pointer for comparisons
traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_clientedictedict(passedict, owner)) : NULL;
clipgroup = passedict ? (int)PRVM_clientedictfloat(passedict, clipgroup) : 0;
// collide against network entities
if (hitnetworkbrushmodels)
{
@ -379,6 +382,9 @@ skipnetworkplayers:
// don't clip owner against owned entities
if (passedictprog == PRVM_clientedictedict(touch, owner))
continue;
// don't clip against any entities in the same clipgroup (DP_RM_CLIPGROUP)
if ((clipgroup & (int)PRVM_clientedictfloat(touch, clipgroup)) != 0)
continue;
// don't clip points against points (they can't collide)
if (VectorCompare(PRVM_clientedictvector(touch, mins), PRVM_clientedictvector(touch, maxs)) && (type != MOVE_MISSILE || !((int)PRVM_clientedictfloat(touch, flags) & FL_MONSTER)))
continue;
@ -440,6 +446,9 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
// list of entities to test for collisions
int numtouchedicts;
static prvm_edict_t *touchedicts[MAX_EDICTS];
int clipgroup;
if (VectorCompare(start, end))
return CL_TracePoint(start, type, passedict, hitsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities);
@ -496,6 +505,8 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
// precalculate passedict's owner edict pointer for comparisons
traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_clientedictedict(passedict, owner)) : NULL;
clipgroup = passedict ? (int)PRVM_clientedictfloat(passedict, clipgroup) : 0;
// collide against network entities
if (hitnetworkbrushmodels)
{
@ -595,6 +606,9 @@ skipnetworkplayers:
// don't clip owner against owned entities
if (passedictprog == PRVM_clientedictedict(touch, owner))
continue;
// don't clip against any entities in the same clipgroup (DP_RM_CLIPGROUP)
if ((clipgroup & (int)PRVM_clientedictfloat(touch, clipgroup)) != 0)
continue;
// don't clip points against points (they can't collide)
if (VectorCompare(PRVM_clientedictvector(touch, mins), PRVM_clientedictvector(touch, maxs)) && (type != MOVE_MISSILE || !((int)PRVM_clientedictfloat(touch, flags) & FL_MONSTER)))
continue;
@ -660,6 +674,7 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
// list of entities to test for collisions
int numtouchedicts;
static prvm_edict_t *touchedicts[MAX_EDICTS];
int clipgroup;
if (VectorCompare(mins, maxs))
{
vec3_t shiftstart, shiftend;
@ -739,6 +754,8 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
// precalculate passedict's owner edict pointer for comparisons
traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_clientedictedict(passedict, owner)) : NULL;
clipgroup = passedict ? (int)PRVM_clientedictfloat(passedict, clipgroup) : 0;
// collide against network entities
if (hitnetworkbrushmodels)
{
@ -838,6 +855,9 @@ skipnetworkplayers:
// don't clip owner against owned entities
if (passedictprog == PRVM_clientedictedict(touch, owner))
continue;
// don't clip against any entities in the same clipgroup (DP_RM_CLIPGROUP)
if ((clipgroup & (int)PRVM_clientedictfloat(touch, clipgroup)) != 0)
continue;
// don't clip points against points (they can't collide)
if (pointtrace && VectorCompare(PRVM_clientedictvector(touch, mins), PRVM_clientedictvector(touch, maxs)) && (type != MOVE_MISSILE || !((int)PRVM_clientedictfloat(touch, flags) & FL_MONSTER)))
continue;

View File

@ -1304,6 +1304,7 @@ static void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s)
vec3_t wishdir;
vec3_t yawangles;
trace_t trace;
qboolean moving;
// jump if on ground with jump button pressed but only if it has been
// released at least once since the last jump
@ -1370,6 +1371,7 @@ static void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s)
VectorMA(s->velocity, accelspeed, wishdir, s->velocity);
}
gravity = cl.movevars_gravity * cl.movevars_entgravity * s->cmd.frametime;
moving = s->velocity[0] || s->velocity[1];
if(!(cl.moveflags & MOVEFLAG_NOGRAVITYONGROUND))
{
if(cl.moveflags & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
@ -1379,9 +1381,10 @@ static void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s)
}
if (cls.protocol == PROTOCOL_QUAKEWORLD)
s->velocity[2] = 0;
moving = s->velocity[0] || s->velocity[1];
if (VectorLength2(s->velocity))
CL_ClientMovement_Move(s);
if(!(cl.moveflags & MOVEFLAG_NOGRAVITYONGROUND) || !s->onground)
if(!(cl.moveflags & MOVEFLAG_NOGRAVITYONGROUND) || !s->onground || (s->onground && moving))
{
if(cl.moveflags & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
s->velocity[2] -= gravity * 0.5f;
@ -1440,8 +1443,9 @@ static void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s)
s->velocity[2] -= gravity * 0.5f;
else
s->velocity[2] -= gravity;
moving = s->velocity[0] || s->velocity[1];
CL_ClientMovement_Move(s);
if(!(cl.moveflags & MOVEFLAG_NOGRAVITYONGROUND) || !s->onground)
if(!(cl.moveflags & MOVEFLAG_NOGRAVITYONGROUND) || !s->onground || (s->onground && moving))
{
if(cl.moveflags & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
s->velocity[2] -= gravity * 0.5f;

View File

@ -2377,7 +2377,7 @@ void CL_NewBeam (int ent, vec3_t start, vec3_t end, dp_model_t *m, int lightning
VectorCopy (end, b->end);
}
else
Con_Print("beam list overflow!\n");
Con_DPrint("beam list overflow!\n");
}
static void CL_ParseBeam (dp_model_t *m, int lightning)

View File

@ -130,6 +130,7 @@ int scr_con_margin_bottom;
extern int con_vislines;
static void SCR_ScreenShot_f (void);
static void SCR_SaveShot_f (void);
static void R_Envmap_f (void);
// backend
@ -1417,6 +1418,7 @@ void CL_Screen_Init(void)
Cmd_AddCommand ("sizeup",SCR_SizeUp_f, "increase view size (increases viewsize cvar)");
Cmd_AddCommand ("sizedown",SCR_SizeDown_f, "decrease view size (decreases viewsize cvar)");
Cmd_AddCommand ("screenshot",SCR_ScreenShot_f, "takes a screenshot of the next rendered frame");
Cmd_AddCommand ("saveshot",SCR_SaveShot_f, "takes a screenshot without HUD to be used as a savefile thumbnail");
Cmd_AddCommand ("envmap", R_Envmap_f, "render a cubemap (skybox) of the current scene");
Cmd_AddCommand ("infobar", SCR_InfoBar_f, "display a text in the infobar (usage: infobar expiretime string)");
@ -1427,6 +1429,72 @@ void CL_Screen_Init(void)
scr_initialized = true;
}
/*
==================
SCR_SaveShot_f
==================
*/
void SCR_SaveShot_f (void)
{
int w, h;
char filename[MAX_QPATH] = { 0 };
unsigned char *buffer1;
if (Cmd_Argc() != 4)
{
Con_Print("saveshot <path> <w> <h>: takes a screenshot without HUD to be used as a savefile thumbnail\n");
return;
}
w = atoi(Cmd_Argv(1));
if (w < 1)
{
Con_Print("<w> has to be a positive integer\n");
return;
}
h = atoi(Cmd_Argv(2));
if (h < 1)
{
Con_Print("<h> has to be a positive integer\n");
return;
}
strlcpy(filename, Cmd_Argv(3), sizeof(filename));
buffer1 = (unsigned char *)Mem_Alloc(tempmempool, w * h * 4);
r_refdef.envmap = true;
R_UpdateVariables();
r_refdef.view.width = w;
r_refdef.view.height = h;
r_refdef.view.depth = 1;
r_refdef.view.useperspective = true;
r_refdef.view.isoverlay = false;
r_refdef.view.quality = 1;
r_refdef.view.clear = true;
r_refdef.view.frustum_x = 1;
r_refdef.view.frustum_y = 1;
r_refdef.view.ortho_x = 90;
r_refdef.view.ortho_y = 90;
R_Mesh_Start();
R_RenderView();
R_Mesh_Finish();
GL_ReadPixelsBGRA(0, vid.height - h, w, h, buffer1);
if (PNG_SaveImage_preflipped(filename, w, h, true, buffer1))
Con_Printf("wrote %s\n", filename);
else
Con_Printf("could not create %s\n", filename);
Mem_Free(buffer1);
r_refdef.envmap = false;
}
/*
==================
SCR_ScreenShot_f

2
cmd.c
View File

@ -688,7 +688,7 @@ static void Cmd_Exec(const char *filename)
"sv_gameplayfix_fixedcheckwatertransition 1\n"
"sv_gameplayfix_q1bsptracelinereportstexture 1\n"
"sv_gameplayfix_swiminbmodels 1\n"
"sv_gameplayfix_downtracesupportsongroundflag 1\n"
"sv_gameplayfix_downtracesupportsongroundflag 0\n"
"sv_gameplayfix_stepmultipletimes 1\n"
"sv_gameplayfix_nogravityonground 1\n"
"sys_ticrate 0.01388889\n"

View File

@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#if !defined(WIN32) || defined(__MINGW32__)
# include <unistd.h>
# include <sys/time.h>
#endif
#include <time.h>
@ -1455,6 +1456,57 @@ void Con_Printf(const char *fmt, ...)
Con_MaskPrint(CON_MASK_PRINT, msg);
}
/*
================
Con_Timestamp
================
*/
const char *Con_Timestamp(void)
{
time_t cur_time;
struct timeval tv;
#if _MSC_VER >= 1400
struct tm crt_tm;
#else
struct tm *crt_tm;
#endif
char timestring [16];
static char timestamp [24];
// Build the time stamp (ex: "21:49:08.093");
gettimeofday (&tv, NULL);
cur_time = tv.tv_sec;
#if _MSC_VER >= 1400
localtime_s (&crt_tm, &cur_time);
strftime (timestring, sizeof (timestring), "%H:%M:%S", &crt_tm);
#else
crt_tm = localtime (&cur_time);
strftime (timestring, sizeof (timestring), "%H:%M:%S", crt_tm);
#endif
dpsnprintf (timestamp, sizeof (timestamp), "%s.%03d", timestring, (int)tv.tv_usec / 1000);
return timestamp;
}
/*
================
Con_TimePrintf
================
*/
void Con_TimePrintf(const char *fmt, ...)
{
va_list argptr;
char msg[MAX_INPUTLINE];
va_start(argptr,fmt);
dpvsnprintf(msg,sizeof(msg),fmt,argptr);
va_end(argptr);
Con_Printf("[%s] %s", Con_Timestamp(), msg);
}
/*
================
Con_DPrint

View File

@ -51,6 +51,9 @@ void Con_Print(const char *txt);
/// Prints to all appropriate console targets.
void Con_Printf(const char *fmt, ...) DP_FUNC_PRINTF(1);
/// Same as Con_Printf, but prepends message with timestamp
void Con_TimePrintf(const char *fmt, ...) DP_FUNC_PRINTF(1);
/// A Con_Print that only shows up if the "developer" cvar is set.
void Con_DPrint(const char *msg);
@ -61,7 +64,9 @@ void Con_DrawNotify (void);
/// Clear all notify lines.
void Con_ClearNotify (void);
void Con_ToggleConsole_f (void);
const char *Con_Timestamp(void);
int Nicks_CompleteChatLine(char *buffer, size_t size, unsigned int pos);

View File

@ -451,7 +451,7 @@ reload:
if ((!strncmp(pic->name, "gfx/", 4) || (gamemode == GAME_BLOODOMNICIDE && !strncmp(pic->name, "locale/", 6))) && (lmpdata = FS_LoadFile(lmpname, tempmempool, false, &lmpsize)))
{
if (developer_loading.integer)
Con_Printf("loading lump \"%s\"\n", pic->name);
Con_TimePrintf("loading lump \"%s\"\n", pic->name);
if (lmpsize >= 9)
{
@ -469,7 +469,7 @@ reload:
else if ((lmpdata = W_GetLumpName (pic->name + 4)))
{
if (developer_loading.integer)
Con_Printf("loading gfx.wad lump \"%s\"\n", pic->name + 4);
Con_TimePrintf("loading gfx.wad lump \"%s\"\n", pic->name + 4);
if (!strcmp(pic->name, "gfx/conchars"))
{

View File

@ -3421,7 +3421,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
// FIXME handle miplevel
if (developer_loading.integer)
Con_Printf("loading skin \"%s\"\n", name);
Con_TimePrintf("loading skin \"%s\"\n", name);
// we've got some pixels to store, so really allocate this new texture now
if (!skinframe)
@ -3633,7 +3633,7 @@ skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, co
return NULL;
if (developer_loading.integer)
Con_Printf("loading 32bit skin \"%s\"\n", name);
Con_TimePrintf("loading 32bit skin \"%s\"\n", name);
if (r_loadnormalmap && r_shadow_bumpscale_basetexture.value > 0)
{
@ -3703,7 +3703,7 @@ skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, i
return NULL;
if (developer_loading.integer)
Con_Printf("loading quake skin \"%s\"\n", name);
Con_TimePrintf("loading quake skin \"%s\"\n", name);
// we actually don't upload anything until the first use, because mdl skins frequently go unused, and are almost never used in both modes (colormapped and non-colormapped)
skinframe->qpixels = (unsigned char *)Mem_Alloc(r_main_mempool, width*height); // FIXME LEAK
@ -3827,7 +3827,7 @@ skinframe_t *R_SkinFrame_LoadInternal8bit(const char *name, int textureflags, co
return NULL;
if (developer_loading.integer)
Con_Printf("loading embedded 8bit image \"%s\"\n", name);
Con_TimePrintf("loading embedded 8bit image \"%s\"\n", name);
skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_PALETTE, textureflags, -1, palette);
if (textureflags & TEXF_ALPHA)
@ -3968,7 +3968,7 @@ static rtexture_t *R_LoadCubemap(const char *basename)
if (cubemappixels)
{
if (developer_loading.integer)
Con_Printf("loading cubemap \"%s\"\n", basename);
Con_TimePrintf("loading cubemap \"%s\"\n", basename);
cubemaptexture = R_LoadTextureCubeMap(r_main_texturepool, basename, cubemapsize, cubemappixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, (gl_texturecompression_lightcubemaps.integer && gl_texturecompression.integer ? TEXF_COMPRESS : 0) | forcefilter | TEXF_CLAMP, -1, NULL);
Mem_Free(cubemappixels);
@ -3978,7 +3978,7 @@ static rtexture_t *R_LoadCubemap(const char *basename)
Con_DPrintf("failed to load cubemap \"%s\"\n", basename);
if (developer_loading.integer)
{
Con_Printf("(tried tried images ");
Con_TimePrintf("(tried tried images ");
for (j = 0;j < 3;j++)
for (i = 0;i < 6;i++)
Con_Printf("%s\"%s%s.tga\"", j + i > 0 ? ", " : "", basename, suffix[j][i].suffix);
@ -8154,7 +8154,7 @@ static void R_LoadQWSkin(r_qwskincache_t *cache, const char *skinname)
strlcpy(cache->name, skinname, sizeof(cache->name));
dpsnprintf(name, sizeof(name), "skins/%s.pcx", cache->name);
if (developer_loading.integer)
Con_Printf("loading %s\n", name);
Con_TimePrintf("loading %s\n", name);
skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, false);
if (!skinframe || !skinframe->base)
{

View File

@ -579,6 +579,9 @@ void Host_Savegame_to(prvm_prog_t *prog, const char *name)
isserver = prog == SVVM_prog;
Con_Printf("Saving game to %s...\n", name);
if (developer_loading.integer)
Con_TimePrintf("save game start\n");
f = FS_OpenRealFile(name, "wb", false);
if (!f)
{
@ -704,6 +707,9 @@ void Host_Savegame_to(prvm_prog_t *prog, const char *name)
FS_Close (f);
Con_Print("done.\n");
if (developer_loading.integer)
Con_TimePrintf("save game end\n");
}
/*
@ -797,6 +803,8 @@ static void Host_Loadgame_f (void)
FS_DefaultExtension (filename, ".sav", sizeof (filename));
Con_Printf("Loading game from %s...\n", filename);
if (developer_loading.integer)
Con_TimePrintf("load game start\n");
// stop playing demos
if (cls.demoplayback)
@ -1107,6 +1115,9 @@ static void Host_Loadgame_f (void)
if(developer_entityparsing.integer)
Con_Printf("Host_Loadgame_f: finished\n");
if (developer_loading.integer)
Con_TimePrintf("load game end\n");
// make sure we're connected to loopback
if (sv.active && cls.state == ca_disconnected)
{

View File

@ -974,7 +974,7 @@ unsigned char *loadimagepixelsbgra (const char *filename, qboolean complain, qbo
}
}
if (developer_loading.integer)
Con_DPrintf("loaded image %s (%dx%d)\n", name, image_width, image_height);
Con_TimePrintf("loaded image %s (%dx%d)\n", name, image_width, image_height);
if(miplevel)
*miplevel = mymiplevel;
//if (developer_memorydebug.integer)

View File

@ -2026,7 +2026,7 @@ static void Mod_Q1BSP_LoadLighting(sizebuf_t *sb)
if (i == 1)
{
if (developer_loading.integer)
Con_Printf("loaded %s\n", litfilename);
Con_TimePrintf("loaded %s\n", litfilename);
loadmodel->brushq1.lightdata = (unsigned char *)Mem_Alloc(loadmodel->mempool, filesize - 8);
memcpy(loadmodel->brushq1.lightdata, data + 8, filesize - 8);
Mem_Free(data);
@ -2039,7 +2039,7 @@ static void Mod_Q1BSP_LoadLighting(sizebuf_t *sb)
if (i == 1)
{
if (developer_loading.integer)
Con_Printf("loaded %s\n", dlitfilename);
Con_TimePrintf("loaded %s\n", dlitfilename);
loadmodel->brushq1.nmaplightdata = (unsigned char *)Mem_Alloc(loadmodel->mempool, filesize - 8);
memcpy(loadmodel->brushq1.nmaplightdata, data + 8, filesize - 8);
loadmodel->brushq3.deluxemapping_modelspace = false;
@ -4971,20 +4971,22 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump)
{
// prefer internal LMs for compatibility (a BSP contains no info on whether external LMs exist)
if (developer_loading.integer)
Con_Printf("Using internal lightmaps\n");
Con_TimePrintf("Using internal lightmaps\n");
input_pointer = (q3dlightmap_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*input_pointer))
Host_Error("Mod_Q3BSP_LoadLightmaps: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*input_pointer);
for(i = 0; i < count; ++i)
inpixels[i] = input_pointer[i].rgb;
if (developer_loading.integer)
Con_TimePrintf("loaded internal lightmaps\n");
}
else
{
// no internal lightmaps
// try external lightmaps
if (developer_loading.integer)
Con_Printf("Using external lightmaps\n");
Con_TimePrintf("Using external lightmaps\n");
FS_StripExtension(loadmodel->name, mapname, sizeof(mapname));
inpixels[0] = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s/lm_%04d", mapname, 0), false, false, false, NULL);
if(!inpixels[0])
@ -5017,6 +5019,9 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump)
break;
}
}
if (developer_loading.integer)
Con_TimePrintf("loaded external lightmaps\n");
}
loadmodel->brushq3.lightmapsize = size;

View File

@ -193,7 +193,7 @@ void Mod_UnloadModel (dp_model_t *mod)
dp_model_t *parentmodel;
if (developer_loading.integer)
Con_Printf("unloading model %s\n", mod->name);
Con_TimePrintf("unloading model %s\n", mod->name);
strlcpy(name, mod->name, sizeof(name));
parentmodel = mod->brush.parentmodel;
@ -393,7 +393,7 @@ dp_model_t *Mod_LoadModel(dp_model_t *mod, qboolean crash, qboolean checkdisk)
Mod_UnloadModel(mod);
if (developer_loading.integer)
Con_Printf("loading model %s\n", mod->name);
Con_TimePrintf("loading model %s\n", mod->name);
mod->used = true;
mod->crc = (unsigned int)-1;
@ -447,7 +447,7 @@ dp_model_t *Mod_LoadModel(dp_model_t *mod, qboolean crash, qboolean checkdisk)
}
if (developer_loading.integer)
Con_Printf("loading model %s\n", mod->name);
Con_TimePrintf("loading model %s\n", mod->name);
SCR_PushLoadingScreen(true, mod->name, 1);
@ -2469,7 +2469,7 @@ qboolean Mod_LoadTextureFromQ3Shader(texture_t *texture, const char *name, qbool
if (shader)
{
if (developer_loading.integer)
Con_Printf("%s: loaded shader for %s\n", loadmodel->name, name);
Con_TimePrintf("%s: loaded shader for %s\n", loadmodel->name, name);
// allow disabling of picmip or compression by defaulttexflags
texture->textureflags = (shader->textureflags & texflagsmask) | texflagsor;
@ -2836,7 +2836,7 @@ tag_torso,
if (words == 3)
{
if (developer_loading.integer)
Con_Printf("Mod_LoadSkinFiles: parsed mesh \"%s\" shader replacement \"%s\"\n", word[1], word[2]);
Con_TimePrintf("Mod_LoadSkinFiles: parsed mesh \"%s\" shader replacement \"%s\"\n", word[1], word[2]);
skinfileitem = (skinfileitem_t *)Mem_Alloc(loadmodel->mempool, sizeof(skinfileitem_t));
skinfileitem->next = skinfile->items;
skinfile->items = skinfileitem;
@ -2855,7 +2855,7 @@ tag_torso,
{
// mesh shader name, like "U_RArm,models/players/Legoman/BikerA1.tga"
if (developer_loading.integer)
Con_Printf("Mod_LoadSkinFiles: parsed mesh \"%s\" shader replacement \"%s\"\n", word[0], word[2]);
Con_TimePrintf("Mod_LoadSkinFiles: parsed mesh \"%s\" shader replacement \"%s\"\n", word[0], word[2]);
skinfileitem = (skinfileitem_t *)Mem_Alloc(loadmodel->mempool, sizeof(skinfileitem_t));
skinfileitem->next = skinfile->items;
skinfile->items = skinfileitem;

View File

@ -2,7 +2,7 @@
#include "nodegraph.h"
// ============================================================================
#define NODEGRAPH_NODES_COUNT_LIMIT 1024
#define NODEGRAPH_NODES_COUNT_LIMIT 4096
#define NODEGRAPH_QUERY_ENTRIES_LIMIT NODEGRAPH_NODES_COUNT_LIMIT
#define NODEGRAPH_QUERIES_COUNT_LIMIT 128
@ -129,7 +129,7 @@ static qboolean nodegraph_graph_rebuild_floyd_warshall_matrices(void)
{
short graphid, i, j, k;
float *floyd_matrix_measures = (float *)Mem_Alloc(tempmempool, NODEGRAPH_NODES_COUNT_LIMIT * NODEGRAPH_NODES_COUNT_LIMIT);
float *floyd_matrix_measures = (float *)Mem_Alloc(tempmempool, NODEGRAPH_NODES_COUNT_LIMIT * NODEGRAPH_NODES_COUNT_LIMIT * sizeof(float));
if (!floyd_matrix_measures)
{
@ -208,6 +208,18 @@ qboolean nodegraph_graphset_clear(void)
return true;
}
// ============================================================================
qboolean nodegraph_graphset_remove(void)
{
char vabuf[1024];
if (remove(va(vabuf, sizeof(vabuf), "%s/%s.qng", fs_gamedir, sv.worldnamenoextension)) != 0)
{
Con_Printf("Could not remove %s.qng\n", sv.worldnamenoextension);
return false;
}
return true;
}
// ============================================================================
qboolean nodegraph_graphset_load(void)
{
@ -225,7 +237,10 @@ qboolean nodegraph_graphset_load(void)
size_t offset, length;
Con_Printf("Loaded %s.qng\n", sv.worldnamenoextension);
if (developer_loading.integer)
Con_TimePrintf("loading %s.qng\n", sv.worldnamenoextension);
else
Con_Printf("loaded %s.qng\n", sv.worldnamenoextension);
nodegraph_graphset_clear();
@ -293,6 +308,9 @@ qboolean nodegraph_graphset_load(void)
Mem_Free(graphset_data);
if (developer_loading.integer)
Con_TimePrintf("done loading %s.qng\n", sv.worldnamenoextension);
return true;
}
@ -314,6 +332,9 @@ qboolean nodegraph_graphset_save(void)
size_t offset, length;
if (developer_loading.integer)
Con_TimePrintf("saving %s.qng\n", sv.worldnamenoextension);
nodegraph_graph_rebuild_floyd_warshall_matrices();
graphset_data_size = sizeof(short) * NODEGRAPH_GRAPHSET_SIZE_LIMIT + sizeof(g_nodegraph_set) + sizeof(g_nodegraph_floyd_warshall_matrices);
@ -399,7 +420,10 @@ qboolean nodegraph_graphset_save(void)
if (nodegraph_graphset_has_been_saved)
{
Con_Printf("Saved %s.qng\n", sv.worldnamenoextension);
if (developer_loading.integer)
Con_TimePrintf("done saving %s.qng\n", sv.worldnamenoextension);
else
Con_Printf("saved %s.qng\n", sv.worldnamenoextension);
}
return nodegraph_graphset_has_been_saved;

View File

@ -11,6 +11,7 @@
// ============================================================================
qboolean nodegraph_graphset_clear(void);
qboolean nodegraph_graphset_remove(void);
qboolean nodegraph_graphset_load(void);
qboolean nodegraph_graphset_save(void);

View File

@ -8,6 +8,7 @@ PRVM_DECLARE_clientfieldfloat(alpha)
PRVM_DECLARE_clientfieldfloat(bouncefactor)
PRVM_DECLARE_clientfieldfloat(bouncestop)
PRVM_DECLARE_clientfieldfloat(colormap)
PRVM_DECLARE_clientfieldfloat(clipgroup)
PRVM_DECLARE_clientfieldfloat(dphitcontentsmask)
PRVM_DECLARE_clientfieldfloat(drawmask)
PRVM_DECLARE_clientfieldfloat(effects)
@ -256,6 +257,7 @@ PRVM_DECLARE_field(classname)
PRVM_DECLARE_field(clientcamera)
PRVM_DECLARE_field(clientcolors)
PRVM_DECLARE_field(clientstatus)
PRVM_DECLARE_field(clipgroup)
PRVM_DECLARE_field(color)
PRVM_DECLARE_field(colormap)
PRVM_DECLARE_field(colormod)
@ -694,6 +696,7 @@ PRVM_DECLARE_serverfieldfloat(button16)
PRVM_DECLARE_serverfieldfloat(buttonchat)
PRVM_DECLARE_serverfieldfloat(buttonuse)
PRVM_DECLARE_serverfieldfloat(clientcolors)
PRVM_DECLARE_serverfieldfloat(clipgroup)
PRVM_DECLARE_serverfieldfloat(colormap)
PRVM_DECLARE_serverfieldfloat(currentammo)
PRVM_DECLARE_serverfieldfloat(cursor_active)

View File

@ -187,7 +187,7 @@ extern char engineversion[128];
#define MAX_ENITIES_INITIAL 256 ///< initial size of cl.entities
#define MAX_STATICENTITIES 1024 ///< limit on size of cl.static_entities
#define MAX_EFFECTS 256 ///< limit on size of cl.effects
#define MAX_BEAMS 256 ///< limit on size of cl.beams
#define MAX_BEAMS 4096 ///< limit on size of cl.beams
#define MAX_TEMPENTITIES 4096 ///< max number of temporary models visible per frame (certain sprite effects, certain types of CSQC entities also use this)
#define SERVERLIST_TOTALSIZE 2048 ///< max servers in the server list
#define SERVERLIST_ANDMASKCOUNT 16 ///< max items in server list AND mask

View File

@ -88,7 +88,7 @@ static void R_UnloadSkyBox(void)
skyboxskinframe[i] = NULL;
}
if (c && developer_loading.integer)
Con_Printf("unloading skybox\n");
Con_TimePrintf("unloading skybox\n");
}
static int R_LoadSkyBox(void)
@ -137,7 +137,7 @@ static int R_LoadSkyBox(void)
return false;
if (developer_loading.integer)
Con_Printf("loading skybox \"%s\"\n", name);
Con_TimePrintf("loading skybox \"%s\"\n", name);
return true;
}

View File

@ -375,6 +375,7 @@ typedef struct client_s
#define FL_PARTIALGROUND 1024 ///< not all corners are valid
#define FL_WATERJUMP 2048 ///< player jumping out of water
#define FL_JUMPRELEASED 4096 ///< for jump debouncing
#define FL_IGNOREINPUT 8192 ///< ignores client input while set
#define SPAWNFLAG_NOT_EASY 256
#define SPAWNFLAG_NOT_MEDIUM 512

View File

@ -1043,7 +1043,7 @@ void S_FreeSfx (sfx_t *sfx, qboolean force)
return;
if (developer_loading.integer)
Con_Printf ("unloading sound %s\n", sfx->name);
Con_TimePrintf ("unloading sound %s\n", sfx->name);
// Remove it from the list of known sfx
if (sfx == known_sfx)

View File

@ -323,7 +323,7 @@ qboolean S_LoadSound (sfx_t *sfx, qboolean complain)
sfx->volume_peak = 0.0;
if (developer_loading.integer)
Con_Printf("loading sound %s\n", sfx->name);
Con_TimePrintf("loading sound %s\n", sfx->name);
SCR_PushLoadingScreen(true, sfx->name, 1);

View File

@ -625,7 +625,7 @@ qboolean OGG_LoadVorbisFile(const char *filename, sfx_t *sfx)
return false;
if (developer_loading.integer >= 2)
Con_Printf("Loading Ogg Vorbis file \"%s\"\n", filename);
Con_TimePrintf("Loading Ogg Vorbis file \"%s\"\n", filename);
// Open it with the VorbisFile API
ov_decode.buffer = data;

View File

@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
static unsigned int sdlaudiotime = 0;
static int audio_device = 0;
// Note: SDL calls SDL_LockAudio() right before this function, so no need to lock the audio data here
@ -67,10 +68,20 @@ static void Buffer_Callback (void *userdata, Uint8 *stream, int len)
PartialLength2 = FrameCount * factor - PartialLength1;
memcpy(&stream[PartialLength1], &snd_renderbuffer->ring[0], PartialLength2);
// As of SDL 2.0 buffer needs to be fully initialized, so fill leftover part with silence
// FIXME this is another place that assumes 8bit is always unsigned and others always signed
memset(&stream[PartialLength1 + PartialLength2], snd_renderbuffer->format.width == 1 ? 0x80 : 0, len - (PartialLength1 + PartialLength2));
}
else
{
memcpy(stream, &snd_renderbuffer->ring[StartOffset * factor], FrameCount * factor);
// As of SDL 2.0 buffer needs to be fully initialized, so fill leftover part with silence
// FIXME this is another place that assumes 8bit is always unsigned and others always signed
memset(&stream[FrameCount * factor], snd_renderbuffer->format.width == 1 ? 0x80 : 0, len - (FrameCount * factor));
}
snd_renderbuffer->startframe += FrameCount;
if (FrameCount < RequestedFrames && developer_insane.integer && vid_activewindow)
@ -91,7 +102,7 @@ Create "snd_renderbuffer" with the proper sound format if the call is successful
May return a suggested format if the requested format isn't available
====================
*/
qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested)
qboolean SndSys_Init (const snd_format_t* fmt, snd_format_t* suggested)
{
unsigned int buffersize;
SDL_AudioSpec wantspec;
@ -107,14 +118,15 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested)
return false;
}
buffersize = (unsigned int)ceil((double)requested->speed / 25.0); // 2048 bytes on 24kHz to 48kHz
buffersize = (unsigned int)ceil((double)fmt->speed / 25.0); // 2048 bytes on 24kHz to 48kHz
// Init the SDL Audio subsystem
memset(&wantspec, 0, sizeof(wantspec));
wantspec.callback = Buffer_Callback;
wantspec.userdata = NULL;
wantspec.freq = requested->speed;
wantspec.format = ((requested->width == 1) ? AUDIO_U8 : AUDIO_S16SYS);
wantspec.channels = requested->channels;
wantspec.freq = fmt->speed;
wantspec.format = fmt->width == 1 ? AUDIO_U8 : AUDIO_S16SYS;
wantspec.channels = fmt->channels;
wantspec.samples = CeilPowerOf2(buffersize); // needs to be a power of 2 on some platforms.
Con_Printf("Wanted audio Specification:\n"
@ -124,7 +136,7 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested)
"\tSamples : %i\n",
wantspec.channels, wantspec.format, wantspec.freq, wantspec.samples);
if( SDL_OpenAudio( &wantspec, &obtainspec ) )
if ((audio_device = SDL_OpenAudioDevice(NULL, 0, &wantspec, &obtainspec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE)) == 0)
{
Con_Printf( "Failed to open the audio device! (%s)\n", SDL_GetError() );
return false;
@ -137,33 +149,18 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested)
"\tSamples : %i\n",
obtainspec.channels, obtainspec.format, obtainspec.freq, obtainspec.samples);
// If we haven't obtained what we wanted
if (wantspec.freq != obtainspec.freq ||
wantspec.format != obtainspec.format ||
wantspec.channels != obtainspec.channels)
{
SDL_CloseAudio();
// Pass the obtained format as a suggested format
if (suggested != NULL)
{
suggested->speed = obtainspec.freq;
// FIXME: check the format more carefully. There are plenty of unsupported cases
suggested->width = ((obtainspec.format == AUDIO_U8) ? 1 : 2);
suggested->channels = obtainspec.channels;
}
return false;
}
memmove(suggested, fmt, sizeof(snd_format_t));
suggested->speed = obtainspec.freq;
suggested->channels = obtainspec.channels;
snd_threaded = true;
snd_renderbuffer = Snd_CreateRingBuffer(requested, 0, NULL);
snd_renderbuffer = Snd_CreateRingBuffer(suggested, 0, NULL);
if (snd_channellayout.integer == SND_CHANNELLAYOUT_AUTO)
Cvar_SetValueQuick (&snd_channellayout, SND_CHANNELLAYOUT_STANDARD);
sdlaudiotime = 0;
SDL_PauseAudio( false );
SDL_PauseAudioDevice(audio_device, 0);
return true;
}
@ -178,8 +175,10 @@ Stop the sound card, delete "snd_renderbuffer" and free its other resources
*/
void SndSys_Shutdown(void)
{
SDL_CloseAudio();
if (audio_device > 0) {
SDL_CloseAudioDevice(audio_device);
audio_device = 0;
}
if (snd_renderbuffer != NULL)
{
Mem_Free(snd_renderbuffer->ring);
@ -224,7 +223,7 @@ Get the exclusive lock on "snd_renderbuffer"
*/
qboolean SndSys_LockRenderBuffer (void)
{
SDL_LockAudio();
SDL_LockAudioDevice(audio_device);
return true;
}
@ -238,7 +237,7 @@ Release the exclusive lock on "snd_renderbuffer"
*/
void SndSys_UnlockRenderBuffer (void)
{
SDL_UnlockAudio();
SDL_UnlockAudioDevice(audio_device);
}
/*

View File

@ -291,7 +291,7 @@ qboolean S_LoadWavFile (const char *filename, sfx_t *sfx)
}
if (developer_loading.integer >= 2)
Con_Printf ("Loading WAV file \"%s\"\n", filename);
Con_TimePrintf ("Loading WAV file \"%s\"\n", filename);
info = GetWavinfo (sfx->name, data, (int)filesize);
if (info.channels < 1 || info.channels > 2) // Stereo sounds are allowed (intended for music)

View File

@ -3257,6 +3257,9 @@ void SV_SpawnServer (const char *server)
Con_DPrintf("SpawnServer: %s\n", server);
if (developer_loading.integer)
Con_TimePrintf("SpawnServer start\n");
dpsnprintf (modelname, sizeof(modelname), "maps/%s.bsp", server);
if (!FS_FileExists(modelname))
@ -3545,6 +3548,10 @@ void SV_SpawnServer (const char *server)
Cvar_SetQuick(&sv_worldmessage, sv.worldmessage);
Con_DPrint("Server spawned.\n");
if (developer_loading.integer)
Con_TimePrintf("SpawnServer end\n");
NetConn_Heartbeat (2);
if(cls.state == ca_dedicated)

View File

@ -126,7 +126,7 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
// list of entities to test for collisions
int numtouchedicts;
static prvm_edict_t *touchedicts[MAX_EDICTS];
int clipgroup;
//return SV_TraceBox(start, vec3_origin, vec3_origin, end, type, passedict, hitsupercontentsmask);
VectorCopy(start, clipstart);
@ -176,6 +176,9 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
// precalculate passedict's owner edict pointer for comparisons
traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_serveredictedict(passedict, owner)) : 0;
clipgroup = passedict ? (int)PRVM_serveredictfloat(passedict, clipgroup) : 0;
// clip to entities
// because this uses World_EntitiestoBox, we know all entity boxes overlap
// the clip region, so we can skip culling checks in the loop below
@ -206,6 +209,9 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
// don't clip owner against owned entities
if (passedictprog == PRVM_serveredictedict(touch, owner))
continue;
// don't clip against any entities in the same clipgroup (DP_RM_CLIPGROUP)
if ((clipgroup & (int)PRVM_serveredictfloat(touch, clipgroup)) != 0)
continue;
// don't clip points against points (they can't collide)
if (VectorCompare(PRVM_serveredictvector(touch, mins), PRVM_serveredictvector(touch, maxs)) && (type != MOVE_MISSILE || !((int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER)))
continue;
@ -272,6 +278,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
// list of entities to test for collisions
int numtouchedicts;
static prvm_edict_t *touchedicts[MAX_EDICTS];
int clipgroup;
if (VectorCompare(start, end))
return SV_TracePoint(start, type, passedict, hitsupercontentsmask);
@ -325,6 +332,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
// precalculate passedict's owner edict pointer for comparisons
traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_serveredictedict(passedict, owner)) : 0;
clipgroup = passedict ? (int)PRVM_serveredictfloat(passedict, clipgroup) : 0;
// clip to entities
// because this uses World_EntitiestoBox, we know all entity boxes overlap
// the clip region, so we can skip culling checks in the loop below
@ -355,6 +363,9 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
// don't clip owner against owned entities
if (passedictprog == PRVM_serveredictedict(touch, owner))
continue;
// don't clip against any entities in the same clipgroup (DP_RM_CLIPGROUP)
if ((clipgroup & (int)PRVM_serveredictfloat(touch, clipgroup)) != 0)
continue;
// don't clip points against points (they can't collide)
if (VectorCompare(PRVM_serveredictvector(touch, mins), PRVM_serveredictvector(touch, maxs)) && (type != MOVE_MISSILE || !((int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER)))
continue;
@ -429,6 +440,7 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
// list of entities to test for collisions
int numtouchedicts;
static prvm_edict_t *touchedicts[MAX_EDICTS];
int clipgroup;
if (VectorCompare(mins, maxs))
{
vec3_t shiftstart, shiftend;
@ -503,6 +515,8 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
// precalculate passedict's owner edict pointer for comparisons
traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_serveredictedict(passedict, owner)) : 0;
clipgroup = passedict ? (int)PRVM_serveredictfloat(passedict, clipgroup) : 0;
// clip to entities
// because this uses World_EntitiestoBox, we know all entity boxes overlap
// the clip region, so we can skip culling checks in the loop below
@ -533,6 +547,9 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
// don't clip owner against owned entities
if (passedictprog == PRVM_serveredictedict(touch, owner))
continue;
// don't clip against any entities in the same clipgroup (DP_RM_CLIPGROUP)
if ((clipgroup & (int)PRVM_serveredictfloat(touch, clipgroup)) != 0)
continue;
// don't clip points against points (they can't collide)
if (pointtrace && VectorCompare(PRVM_serveredictvector(touch, mins), PRVM_serveredictvector(touch, maxs)) && (type != MOVE_MISSILE || !((int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER)))
continue;
@ -1188,6 +1205,7 @@ static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, flo
vec3_t end;
#endif
trace_t trace;
qboolean moving;
if (time <= 0)
return 0;
gravity = 0;
@ -1197,7 +1215,7 @@ static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, flo
if(applygravity)
{
gravity = SV_Gravity(ent);
moving = PRVM_serveredictvector(ent, velocity)[0] || PRVM_serveredictvector(ent, velocity)[1];
if(!sv_gameplayfix_nogravityonground.integer || !((int)PRVM_serveredictfloat(ent, flags) & FL_ONGROUND))
{
if (sv_gameplayfix_gravityunaffectedbyticrate.integer)
@ -1401,9 +1419,10 @@ static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, flo
if (sv_gameplayfix_easierwaterjump.integer && ((int)PRVM_serveredictfloat(ent, flags) & FL_WATERJUMP) && !(blocked & 8))
VectorCopy(primal_velocity, PRVM_serveredictvector(ent, velocity));
moving = PRVM_serveredictvector(ent, velocity)[0] || PRVM_serveredictvector(ent, velocity)[1];
if(applygravity)
{
if(!sv_gameplayfix_nogravityonground.integer || !((int)PRVM_serveredictfloat(ent, flags) & FL_ONGROUND))
if(!sv_gameplayfix_nogravityonground.integer || !((int)PRVM_serveredictfloat(ent, flags) & FL_ONGROUND) || (((int)PRVM_serveredictfloat(ent, flags) & FL_ONGROUND) && moving))
{
if (sv_gameplayfix_gravityunaffectedbyticrate.integer)
PRVM_serveredictvector(ent, velocity)[2] -= gravity * 0.5f;

View File

@ -313,8 +313,16 @@ static void SV_AirMove (void)
float fmove, smove, temp;
// LordHavoc: correct quake movement speed bug when looking up/down
wishvel[0] = wishvel[2] = 0;
wishvel[1] = PRVM_serveredictvector(host_client->edict, angles)[1];
if (PRVM_serveredictfloat(host_client->edict, movetype) == MOVETYPE_NOCLIP || PRVM_serveredictfloat(host_client->edict, movetype) == MOVETYPE_FLY)
{
VectorCopy(PRVM_serveredictvector(host_client->edict, v_angle), wishvel);
wishvel[2] = 0;
}
else
{
wishvel[0] = wishvel[2] = 0;
wishvel[1] = PRVM_serveredictvector(host_client->edict, angles)[1];
}
AngleVectors (wishvel, forward, right, up);
fmove = cmd.forwardmove;
@ -339,7 +347,7 @@ static void SV_AirMove (void)
wishspeed = sv_maxspeed.value;
}
if (PRVM_serveredictfloat(host_client->edict, movetype) == MOVETYPE_NOCLIP)
if (PRVM_serveredictfloat(host_client->edict, movetype) == MOVETYPE_NOCLIP || PRVM_serveredictfloat(host_client->edict, movetype) == MOVETYPE_FLY)
{
// noclip
VectorCopy (wishvel, PRVM_serveredictvector(host_client->edict, velocity));
@ -398,6 +406,14 @@ void SV_ClientThink (void)
cmd = host_client->cmd;
// clear movement vector if IGNOREINPUT is set
if ( (int)PRVM_serveredictfloat(host_client->edict, flags) & FL_IGNOREINPUT )
{
cmd.forwardmove = 0.0f;
cmd.sidemove = 0.0f;
cmd.upmove = 0.0f;
}
// angles
// show 1/3 the pitch angle and all the roll angle
VectorAdd (PRVM_serveredictvector(host_client->edict, v_angle), PRVM_serveredictvector(host_client->edict, punchangle), v_angle);

View File

@ -228,6 +228,7 @@ const char *vm_sv_extensions =
"ZQ_PAUSE "
"EXT_WRATH "
"EXT_NODEGRAPH "
"DP_RM_CLIPGROUP "
//"EXT_CSQC " // not ready yet
;
@ -3619,6 +3620,14 @@ static void VM_nodegraph_graph_query_nodes_in_radius_walk_reachable(prvm_prog_t
PRVM_G_FLOAT(OFS_RETURN) = (float)nodegraph_graph_query_nodes_in_radius_walk_reachable(graphid, position, radius, mins, maxs, stepheight, dropheight);
}
// #725 float() nodegraph_graphset_remove (EXT_NODEGRAPH)
static void VM_nodegraph_graphset_remove(prvm_prog_t *prog)
{
VM_SAFEPARMCOUNT(0, VM_nodegraph_graphset_load);
PRVM_G_FLOAT(OFS_RETURN) = (float)nodegraph_graphset_remove();
}
prvm_builtin_t vm_sv_builtins[] = {
NULL, // #0 NULL function (not callable) (QUAKE)
VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
@ -4350,7 +4359,7 @@ VM_nodegraph_moveprobe_fly, // #721 float(vector nodefrom, vector nodeto
VM_nodegraph_moveprobe_walk, // #722 (vector nodefrom, vector nodeto, vector mins, vector maxs, float stepheight, float dropheight) nodegraph_moveprobe_walk (EXT_NODEGRAPH)
VM_nodegraph_graph_query_nodes_in_radius_fly_reachable, // #723 float(float graphid, vector position, float radius, vector mins, vector maxs, float type) nodegraph_graph_query_nodes_in_radius_fly_reachable (EXT_NODEGRAPH)
VM_nodegraph_graph_query_nodes_in_radius_walk_reachable, // #724 float(float graphid, vector position, float radius, vector mins, vector maxs, float stepheight, float dropheight) nodegraph_graph_query_nodes_in_radius_walk_reachable (EXT_NODEGRAPH)
NULL, // #725
VM_nodegraph_graphset_remove, // #725 float() nodegraph_graphset_remove (EXT_NODEGRAPH)
NULL, // #726
NULL, // #727
NULL, // #728

2
view.c
View File

@ -489,7 +489,7 @@ void V_CalcRefdefUsing (const matrix4x4_t *entrendermatrix, const vec3_t clviewa
realonground = clonground;
// if nogravityonground is enabled, use a "delayed" onground flag
if (sv_gameplayfix_nogravityonground.integer && !clonground && (cl.time - cl.bobongroundtime < 0.2))
if ((cl.moveflags & MOVEFLAG_NOGRAVITYONGROUND) && !clonground && (cl.time - cl.bobongroundtime < 0.2))
clonground = true;
// react to clonground state changes (for gun bob)