From 2f311cc6db562c4a78e216f914fdbeab4227aa69 Mon Sep 17 00:00:00 2001 From: havoc Date: Sun, 4 Oct 2009 02:10:35 +0000 Subject: [PATCH] duplicated PRVM_ExecuteProgram to become MVM_ExecuteProgram, CLVM_ExecuteProgram, SVVM_ExecuteProgram - all identical but this greatly improves profiling reports split calls to SV_LinkEdict into SV_LinkEdict and SV_LinkEdict_TouchAreaGrid because the SV_LinkEdict profile report looked nasty but it was only SV_LinkEdict_TouchAreaGrid to blame git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9297 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_collision.c | 8 +- csprogs.c | 1 + host_cmd.c | 2 +- menu.c | 1 + progsvm.h | 7 +- prvm_exec.c | 416 ++++++++++++++++++++++++++++++++++++++++++++++++- server.h | 5 +- sv_main.c | 3 +- sv_move.c | 26 +++- sv_phys.c | 88 ++++++----- svvm_cmds.c | 12 +- view.c | 15 ++ world.c | 2 +- 13 files changed, 522 insertions(+), 64 deletions(-) diff --git a/cl_collision.c b/cl_collision.c index 7f6d9c64..9ef311b1 100644 --- a/cl_collision.c +++ b/cl_collision.c @@ -728,13 +728,11 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co VectorAdd(start, mins, shiftstart); VectorAdd(end, mins, shiftend); if (VectorCompare(start, end)) - return CL_TracePoint(shiftstart, type, passedict, hitsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities); + trace = CL_TracePoint(shiftstart, type, passedict, hitsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities); else - { trace = CL_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities); - VectorSubtract(trace.endpos, mins, trace.endpos); - return trace; - } + VectorSubtract(trace.endpos, mins, trace.endpos); + return trace; } if (hitnetworkentity) diff --git a/csprogs.c b/csprogs.c index 003eab4c..5ed99d11 100644 --- a/csprogs.c +++ b/csprogs.c @@ -883,6 +883,7 @@ void CL_VM_Init (void) prog->init_cmd = VM_CL_Cmd_Init; prog->reset_cmd = VM_CL_Cmd_Reset; prog->error_cmd = CL_VM_Error; + prog->ExecuteProgram = CLVM_ExecuteProgram; PRVM_LoadProgs(csprogsfn, cl_numrequiredfunc, cl_required_func, 0, NULL, 0, NULL); diff --git a/host_cmd.c b/host_cmd.c index 21ddd7aa..5c1f0969 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -877,7 +877,7 @@ void Host_Loadgame_f (void) // link it into the bsp tree if (!ent->priv.server->free) - SV_LinkEdict (ent, false); + SV_LinkEdict(ent); } end = t; diff --git a/menu.c b/menu.c index ed17203c..06d164d0 100644 --- a/menu.c +++ b/menu.c @@ -5185,6 +5185,7 @@ void MP_Init (void) prog->init_cmd = VM_M_Cmd_Init; prog->reset_cmd = VM_M_Cmd_Reset; prog->error_cmd = MP_Error; + prog->ExecuteProgram = MVM_ExecuteProgram; // allocate the mempools prog->progs_mempool = Mem_AllocPool(M_PROG_FILENAME, 0, NULL); diff --git a/progsvm.h b/progsvm.h index 93b45059..1d9fd7bd 100644 --- a/progsvm.h +++ b/progsvm.h @@ -471,6 +471,8 @@ typedef struct prvm_prog_s void (*reset_cmd)(void); // [INIT] used by PRVM_ResetProg void (*error_cmd)(const char *format, ...) DP_FUNC_PRINTF(1); // [INIT] + + void (*ExecuteProgram)(func_t fnum, const char *errormessage); // pointer to one of the *VM_ExecuteProgram functions } prvm_prog_t; extern prvm_prog_t * prog; @@ -511,7 +513,10 @@ void VM_Cmd_Reset(void); void PRVM_Init (void); -void PRVM_ExecuteProgram (func_t fnum, const char *errormessage); +void MVM_ExecuteProgram (func_t fnum, const char *errormessage); +void CLVM_ExecuteProgram (func_t fnum, const char *errormessage); +void SVVM_ExecuteProgram (func_t fnum, const char *errormessage); +#define PRVM_ExecuteProgram prog->ExecuteProgram #define PRVM_Alloc(buffersize) _PRVM_Alloc(buffersize, __FILE__, __LINE__) #define PRVM_Free(buffer) _PRVM_Free(buffer, __FILE__, __LINE__) diff --git a/prvm_exec.c b/prvm_exec.c index c2864168..a4f529c2 100644 --- a/prvm_exec.c +++ b/prvm_exec.c @@ -643,7 +643,415 @@ void PRVM_Init_Exec(void) /* ==================== -PRVM_ExecuteProgram +MVM_ExecuteProgram +==================== +*/ +// LordHavoc: optimized +#define OPA ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->a]) +#define OPB ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->b]) +#define OPC ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->c]) +extern cvar_t prvm_traceqc; +extern cvar_t prvm_statementprofiling; +extern sizebuf_t vm_tempstringsbuf; +extern qboolean prvm_runawaycheck; +extern qboolean prvm_boundscheck; +void MVM_ExecuteProgram (func_t fnum, const char *errormessage) +{ + dstatement_t *st, *startst; + mfunction_t *f, *newf; + prvm_edict_t *ed; + prvm_eval_t *ptr; + int jumpcount, cachedpr_trace, exitdepth; + int restorevm_tempstringsbuf_cursize; + double calltime; + + calltime = Sys_DoubleTime(); + + if (!fnum || fnum >= (unsigned int)prog->progs->numfunctions) + { + if (prog->globaloffsets.self >= 0 && PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict) + PRVM_ED_Print(PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict), NULL); + PRVM_ERROR ("MVM_ExecuteProgram: %s", errormessage); + } + + f = &prog->functions[fnum]; + + // after executing this function, delete all tempstrings it created + restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize; + + prog->trace = prvm_traceqc.integer; + + // we know we're done when pr_depth drops to this + exitdepth = prog->depth; + +// make a stack frame + st = &prog->statements[PRVM_EnterFunction (f)]; + // save the starting statement pointer for profiling + // (when the function exits or jumps, the (st - startst) integer value is + // added to the function's profile counter) + startst = st; + // instead of counting instructions, we count jumps + jumpcount = 0; + // add one to the callcount of this function because otherwise engine-called functions aren't counted + prog->xfunction->callcount++; + +chooseexecprogram: + cachedpr_trace = prog->trace; + if (prvm_runawaycheck) + { +#define PRVMRUNAWAYCHECK 1 + if (prvm_statementprofiling.integer) + { +#define PRVMSTATEMENTPROFILING 1 + if (prvm_boundscheck) + { +#define PRVMBOUNDSCHECK 1 + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } +#undef PRVMBOUNDSCHECK + } + else + { + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } + } +#undef PRVMSTATEMENTPROFILING + } + else + { + if (prvm_boundscheck) + { +#define PRVMBOUNDSCHECK 1 + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } +#undef PRVMBOUNDSCHECK + } + else + { + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } + } + } +#undef PRVMRUNAWAYCHECK + } + else + { + if (prvm_statementprofiling.integer) + { +#define PRVMSTATEMENTPROFILING 1 + if (prvm_boundscheck) + { +#define PRVMBOUNDSCHECK 1 + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } +#undef PRVMBOUNDSCHECK + } + else + { + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } + } +#undef PRVMSTATEMENTPROFILING + } + else + { + if (prvm_boundscheck) + { +#define PRVMBOUNDSCHECK 1 + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } +#undef PRVMBOUNDSCHECK + } + else + { + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } + } + } + } + +cleanup: + if (developer.integer >= 200 && vm_tempstringsbuf.cursize > restorevm_tempstringsbuf_cursize) + Con_Printf("MVM_ExecuteProgram: %s used %i bytes of tempstrings\n", PRVM_GetString(prog->functions[fnum].s_name), vm_tempstringsbuf.cursize - restorevm_tempstringsbuf_cursize); + // delete tempstrings created by this function + vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; + + f->totaltime += (Sys_DoubleTime() - calltime); + + SV_FlushBroadcastMessages(); +} + +/* +==================== +CLVM_ExecuteProgram +==================== +*/ +// LordHavoc: optimized +#define OPA ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->a]) +#define OPB ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->b]) +#define OPC ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->c]) +extern cvar_t prvm_traceqc; +extern cvar_t prvm_statementprofiling; +extern sizebuf_t vm_tempstringsbuf; +extern qboolean prvm_runawaycheck; +extern qboolean prvm_boundscheck; +void CLVM_ExecuteProgram (func_t fnum, const char *errormessage) +{ + dstatement_t *st, *startst; + mfunction_t *f, *newf; + prvm_edict_t *ed; + prvm_eval_t *ptr; + int jumpcount, cachedpr_trace, exitdepth; + int restorevm_tempstringsbuf_cursize; + double calltime; + + calltime = Sys_DoubleTime(); + + if (!fnum || fnum >= (unsigned int)prog->progs->numfunctions) + { + if (prog->globaloffsets.self >= 0 && PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict) + PRVM_ED_Print(PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict), NULL); + PRVM_ERROR ("CLVM_ExecuteProgram: %s", errormessage); + } + + f = &prog->functions[fnum]; + + // after executing this function, delete all tempstrings it created + restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize; + + prog->trace = prvm_traceqc.integer; + + // we know we're done when pr_depth drops to this + exitdepth = prog->depth; + +// make a stack frame + st = &prog->statements[PRVM_EnterFunction (f)]; + // save the starting statement pointer for profiling + // (when the function exits or jumps, the (st - startst) integer value is + // added to the function's profile counter) + startst = st; + // instead of counting instructions, we count jumps + jumpcount = 0; + // add one to the callcount of this function because otherwise engine-called functions aren't counted + prog->xfunction->callcount++; + +chooseexecprogram: + cachedpr_trace = prog->trace; + if (prvm_runawaycheck) + { +#define PRVMRUNAWAYCHECK 1 + if (prvm_statementprofiling.integer) + { +#define PRVMSTATEMENTPROFILING 1 + if (prvm_boundscheck) + { +#define PRVMBOUNDSCHECK 1 + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } +#undef PRVMBOUNDSCHECK + } + else + { + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } + } +#undef PRVMSTATEMENTPROFILING + } + else + { + if (prvm_boundscheck) + { +#define PRVMBOUNDSCHECK 1 + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } +#undef PRVMBOUNDSCHECK + } + else + { + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } + } + } +#undef PRVMRUNAWAYCHECK + } + else + { + if (prvm_statementprofiling.integer) + { +#define PRVMSTATEMENTPROFILING 1 + if (prvm_boundscheck) + { +#define PRVMBOUNDSCHECK 1 + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } +#undef PRVMBOUNDSCHECK + } + else + { + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } + } +#undef PRVMSTATEMENTPROFILING + } + else + { + if (prvm_boundscheck) + { +#define PRVMBOUNDSCHECK 1 + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } +#undef PRVMBOUNDSCHECK + } + else + { + if (prog->trace) + { +#define PRVMTRACE 1 +#include "prvm_execprogram.h" +#undef PRVMTRACE + } + else + { +#include "prvm_execprogram.h" + } + } + } + } + +cleanup: + if (developer.integer >= 200 && vm_tempstringsbuf.cursize > restorevm_tempstringsbuf_cursize) + Con_Printf("CLVM_ExecuteProgram: %s used %i bytes of tempstrings\n", PRVM_GetString(prog->functions[fnum].s_name), vm_tempstringsbuf.cursize - restorevm_tempstringsbuf_cursize); + // delete tempstrings created by this function + vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; + + f->totaltime += (Sys_DoubleTime() - calltime); + + SV_FlushBroadcastMessages(); +} + +/* +==================== +SVVM_ExecuteProgram ==================== */ // LordHavoc: optimized @@ -655,7 +1063,7 @@ extern cvar_t prvm_statementprofiling; extern sizebuf_t vm_tempstringsbuf; extern qboolean prvm_runawaycheck; extern qboolean prvm_boundscheck; -void PRVM_ExecuteProgram (func_t fnum, const char *errormessage) +void SVVM_ExecuteProgram (func_t fnum, const char *errormessage) { dstatement_t *st, *startst; mfunction_t *f, *newf; @@ -671,7 +1079,7 @@ void PRVM_ExecuteProgram (func_t fnum, const char *errormessage) { if (prog->globaloffsets.self >= 0 && PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict) PRVM_ED_Print(PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict), NULL); - PRVM_ERROR ("PRVM_ExecuteProgram: %s", errormessage); + PRVM_ERROR ("SVVM_ExecuteProgram: %s", errormessage); } f = &prog->functions[fnum]; @@ -836,7 +1244,7 @@ chooseexecprogram: cleanup: if (developer.integer >= 200 && vm_tempstringsbuf.cursize > restorevm_tempstringsbuf_cursize) - Con_Printf("PRVM_ExecuteProgram: %s used %i bytes of tempstrings\n", PRVM_GetString(prog->functions[fnum].s_name), vm_tempstringsbuf.cursize - restorevm_tempstringsbuf_cursize); + Con_Printf("SVVM_ExecuteProgram: %s used %i bytes of tempstrings\n", PRVM_GetString(prog->functions[fnum].s_name), vm_tempstringsbuf.cursize - restorevm_tempstringsbuf_cursize); // delete tempstrings created by this function vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize; diff --git a/server.h b/server.h index ed44332e..d6cac81b 100644 --- a/server.h +++ b/server.h @@ -507,9 +507,10 @@ qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean /*! Needs to be called any time an entity changes origin, mins, maxs, or solid * sets ent->v.absmin and ent->v.absmax - * if touchtriggers, calls prog functions for the intersected triggers + * call TouchAreaGrid as well to fire triggers that overlap the box */ -void SV_LinkEdict (prvm_edict_t *ent, qboolean touch_triggers); +void SV_LinkEdict(prvm_edict_t *ent); +void SV_LinkEdict_TouchAreaGrid(prvm_edict_t *ent); /*! move an entity that is stuck by small amounts in various directions to try to nudge it back into the collision hull * returns true if it found a better place diff --git a/sv_main.c b/sv_main.c index a7d61496..1de8afc0 100644 --- a/sv_main.c +++ b/sv_main.c @@ -3080,7 +3080,7 @@ static void SV_VM_CB_EndIncreaseEdicts(void) // link every entity except world for (i = 1, ent = prog->edicts;i < prog->max_edicts;i++, ent++) if (!ent->priv.server->free) - SV_LinkEdict(ent, false); + SV_LinkEdict(ent); } static void SV_VM_CB_InitEdict(prvm_edict_t *e) @@ -3240,6 +3240,7 @@ static void SV_VM_Setup(void) prog->init_cmd = VM_SV_Cmd_Init; prog->reset_cmd = VM_SV_Cmd_Reset; prog->error_cmd = Host_Error; + prog->ExecuteProgram = SVVM_ExecuteProgram; // TODO: add a requiredfuncs list (ask LH if this is necessary at all) PRVM_LoadProgs( sv_progs.string, 0, NULL, REQFIELDS, reqfields, 0, NULL ); diff --git a/sv_move.c b/sv_move.c index fa551875..507f51c3 100644 --- a/sv_move.c +++ b/sv_move.c @@ -148,7 +148,10 @@ qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean VectorCopy (traceendpos, ent->fields.server->origin); if (relink) - SV_LinkEdict (ent, true); + { + SV_LinkEdict(ent); + SV_LinkEdict_TouchAreaGrid(ent); + } return true; } @@ -180,7 +183,10 @@ qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean { VectorAdd (ent->fields.server->origin, move, ent->fields.server->origin); if (relink) - SV_LinkEdict (ent, true); + { + SV_LinkEdict(ent); + SV_LinkEdict_TouchAreaGrid(ent); + } ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND; return true; } @@ -197,7 +203,10 @@ qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean { // entity had floor mostly pulled out from underneath it // and is trying to correct if (relink) - SV_LinkEdict (ent, true); + { + SV_LinkEdict(ent); + SV_LinkEdict_TouchAreaGrid(ent); + } return true; } VectorCopy (oldorg, ent->fields.server->origin); @@ -211,7 +220,10 @@ qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean // the move is ok if (relink) - SV_LinkEdict (ent, true); + { + SV_LinkEdict(ent); + SV_LinkEdict_TouchAreaGrid(ent); + } return true; } @@ -249,10 +261,12 @@ qboolean SV_StepDirection (prvm_edict_t *ent, float yaw, float dist) { // not turned far enough, so don't take the step VectorCopy (oldorigin, ent->fields.server->origin); } - SV_LinkEdict (ent, true); + SV_LinkEdict(ent); + SV_LinkEdict_TouchAreaGrid(ent); return true; } - SV_LinkEdict (ent, true); + SV_LinkEdict(ent); + SV_LinkEdict_TouchAreaGrid(ent); return false; } diff --git a/sv_phys.c b/sv_phys.c index d7b38c5b..91fbbcca 100644 --- a/sv_phys.c +++ b/sv_phys.c @@ -105,6 +105,8 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int int numtouchedicts; prvm_edict_t *touchedicts[MAX_EDICTS]; + //return SV_TraceBox(start, vec3_origin, vec3_origin, end, type, passedict, hitsupercontentsmask); + VectorCopy(start, clipstart); VectorClear(clipmins2); VectorClear(clipmaxs2); @@ -216,7 +218,7 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int else Matrix4x4_CreateTranslate(&matrix, touch->fields.server->origin[0], touch->fields.server->origin[1], touch->fields.server->origin[2]); Matrix4x4_Invert_Simple(&imatrix, &matrix); - if ((int)touch->fields.server->flags & FL_MONSTER) + if (type == MOVE_MISSILE && (int)touch->fields.server->flags & FL_MONSTER) Collision_ClipToGenericEntity(&trace, model, (int) touch->fields.server->frame, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipstart, hitsupercontentsmask); else Collision_ClipPointToGenericEntity(&trace, model, (int) touch->fields.server->frame, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, hitsupercontentsmask); @@ -274,6 +276,8 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ VectorCopy(pEnd, end); #endif + //return SV_TraceBox(start, vec3_origin, vec3_origin, end, type, passedict, hitsupercontentsmask); + if (VectorCompare(start, end)) return SV_TracePoint(start, type, passedict, hitsupercontentsmask); @@ -469,13 +473,11 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co VectorAdd(start, mins, shiftstart); VectorAdd(end, mins, shiftend); if (VectorCompare(start, end)) - return SV_TracePoint(shiftstart, type, passedict, hitsupercontentsmask); + trace = SV_TracePoint(shiftstart, type, passedict, hitsupercontentsmask); else - { trace = SV_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask); - VectorSubtract(trace.endpos, mins, trace.endpos); - return trace; - } + VectorSubtract(trace.endpos, mins, trace.endpos); + return trace; } VectorCopy(start, clipstart); @@ -603,7 +605,7 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co else Matrix4x4_CreateTranslate(&matrix, touch->fields.server->origin[0], touch->fields.server->origin[1], touch->fields.server->origin[2]); Matrix4x4_Invert_Simple(&imatrix, &matrix); - if ((int)touch->fields.server->flags & FL_MONSTER) + if (type == MOVE_MISSILE && (int)touch->fields.server->flags & FL_MONSTER) Collision_ClipToGenericEntity(&trace, model, (int) touch->fields.server->frame, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask); else Collision_ClipToGenericEntity(&trace, model, (int) touch->fields.server->frame, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask); @@ -709,6 +711,15 @@ void SV_LinkEdict_TouchAreaGrid(prvm_edict_t *ent) int i, numtouchedicts, old_self, old_other; prvm_edict_t *touch, *touchedicts[MAX_EDICTS]; + if (ent == prog->edicts) + return; // don't add the world + + if (ent->priv.server->free) + return; + + if (ent->fields.server->solid == SOLID_NOT) + return; + // build a list of edicts to touch, because the link loop can be corrupted // by IncreaseEdicts called during touch functions numtouchedicts = World_EntitiesInBox(&sv.world, ent->priv.server->areamins, ent->priv.server->areamaxs, MAX_EDICTS, touchedicts); @@ -760,7 +771,7 @@ SV_LinkEdict =============== */ -void SV_LinkEdict (prvm_edict_t *ent, qboolean touch_triggers) +void SV_LinkEdict (prvm_edict_t *ent) { dp_model_t *model; vec3_t mins, maxs; @@ -845,10 +856,6 @@ void SV_LinkEdict (prvm_edict_t *ent, qboolean touch_triggers) VectorCopy(maxs, ent->fields.server->absmax); World_LinkEdict(&sv.world, ent, mins, maxs); - - // if touch_triggers, call touch on all entities overlapping this box - if (touch_triggers && ent->fields.server->solid != SOLID_NOT) - SV_LinkEdict_TouchAreaGrid(ent); } /* @@ -1442,7 +1449,6 @@ static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, q { int type; vec3_t end; - qboolean impact; VectorAdd (ent->fields.server->origin, push, end); @@ -1458,6 +1464,7 @@ static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, q return true; VectorCopy (trace->endpos, ent->fields.server->origin); + SV_LinkEdict(ent); #if 0 if(!trace->startsolid) @@ -1467,15 +1474,11 @@ static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, q } #endif - impact = (ent->fields.server->solid >= SOLID_TRIGGER && trace->ent && (!((int)ent->fields.server->flags & FL_ONGROUND) || ent->fields.server->groundentity != PRVM_EDICT_TO_PROG(trace->ent))); + if (dolink) + SV_LinkEdict_TouchAreaGrid(ent); - if(impact) - { - SV_LinkEdict (ent, dolink); + if((ent->fields.server->solid >= SOLID_TRIGGER && trace->ent && (!((int)ent->fields.server->flags & FL_ONGROUND) || ent->fields.server->groundentity != PRVM_EDICT_TO_PROG(trace->ent)))) return SV_Impact (ent, trace); - } - else if(dolink) - SV_LinkEdict (ent, true); return true; } @@ -1526,7 +1529,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime) pusher->fields.server->angles[1] -= 360.0 * floor(pusher->fields.server->angles[1] * (1.0 / 360.0)); pusher->fields.server->angles[2] -= 360.0 * floor(pusher->fields.server->angles[2] * (1.0 / 360.0)); pusher->fields.server->ltime += movetime; - SV_LinkEdict (pusher, false); + SV_LinkEdict(pusher); return; default: Con_Printf("SV_PushMove: entity #%i, unrecognized solid type %f\n", PRVM_NUM_FOR_EDICT(pusher), pusher->fields.server->solid); @@ -1608,7 +1611,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime) VectorMA (pusher->fields.server->origin, movetime, pusher->fields.server->velocity, pusher->fields.server->origin); VectorMA (pusher->fields.server->angles, movetime, pusher->fields.server->avelocity, pusher->fields.server->angles); pusher->fields.server->ltime += movetime; - SV_LinkEdict (pusher, false); + SV_LinkEdict(pusher); pushermodel = NULL; if (pusher->fields.server->modelindex >= 1 && pusher->fields.server->modelindex < MAX_MODELS) @@ -1747,7 +1750,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime) VectorCopy (pushorig, pusher->fields.server->origin); VectorCopy (pushang, pusher->fields.server->angles); pusher->fields.server->ltime = pushltime; - SV_LinkEdict (pusher, false); + SV_LinkEdict(pusher); // move back any entities we already moved for (i = 0;i < num_moved;i++) @@ -1755,7 +1758,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime) prvm_edict_t *ed = PRVM_EDICT_NUM(moved_edicts[i]); VectorCopy (ed->priv.server->moved_from, ed->fields.server->origin); VectorCopy (ed->priv.server->moved_fromangles, ed->fields.server->angles); - SV_LinkEdict (ed, false); + SV_LinkEdict(ed); } // if the pusher has a "blocked" function, call it, otherwise just stay in place until the obstacle is gone @@ -1858,7 +1861,8 @@ unstickresult_t SV_UnstickEntityReturnOffset (prvm_edict_t *ent, vec3_t offset) if (!SV_TestEntityPosition(ent, unstickoffsets + i)) { VectorCopy(unstickoffsets + i, offset); - SV_LinkEdict (ent, true); + SV_LinkEdict(ent); + //SV_LinkEdict_TouchAreaGrid(ent); return UNSTICK_UNSTUCK; } } @@ -1872,13 +1876,15 @@ unstickresult_t SV_UnstickEntityReturnOffset (prvm_edict_t *ent, vec3_t offset) offset[2] = -i; if (!SV_TestEntityPosition(ent, offset)) { - SV_LinkEdict (ent, true); + SV_LinkEdict(ent); + //SV_LinkEdict_TouchAreaGrid(ent); return UNSTICK_UNSTUCK; } offset[2] = i; if (!SV_TestEntityPosition(ent, offset)) { - SV_LinkEdict (ent, true); + SV_LinkEdict(ent); + //SV_LinkEdict_TouchAreaGrid(ent); return UNSTICK_UNSTUCK; } } @@ -1931,7 +1937,8 @@ void SV_CheckStuck (prvm_edict_t *ent) if (!SV_TestEntityPosition(ent, offset)) { Con_DPrintf("Unstuck player entity %i (classname \"%s\") by restoring oldorigin.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname)); - SV_LinkEdict (ent, true); + SV_LinkEdict(ent); + //SV_LinkEdict_TouchAreaGrid(ent); } else Con_DPrintf("Stuck player entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname)); @@ -2117,7 +2124,8 @@ void SV_WalkMove (prvm_edict_t *ent) ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND; SV_CheckVelocity(ent); - SV_LinkEdict (ent, true); + SV_LinkEdict(ent); + SV_LinkEdict_TouchAreaGrid(ent); if(clip & 8) // teleport return; @@ -2179,7 +2187,8 @@ void SV_WalkMove (prvm_edict_t *ent) } SV_CheckVelocity(ent); - SV_LinkEdict (ent, true); + SV_LinkEdict(ent); + SV_LinkEdict_TouchAreaGrid(ent); // check for stuckness, possibly due to the limited precision of floats // in the clipping hulls @@ -2246,7 +2255,8 @@ void SV_WalkMove (prvm_edict_t *ent) } SV_CheckVelocity(ent); - SV_LinkEdict (ent, true); + SV_LinkEdict(ent); + SV_LinkEdict_TouchAreaGrid(ent); } //============================================================================ @@ -2292,7 +2302,8 @@ void SV_Physics_Follow (prvm_edict_t *ent) ent->fields.server->origin[2] = v[0] * vu[0] + v[1] * vu[1] + v[2] * vu[2] + e->fields.server->origin[2]; } VectorAdd (e->fields.server->angles, ent->fields.server->v_angle, ent->fields.server->angles); - SV_LinkEdict (ent, true); + SV_LinkEdict(ent); + //SV_LinkEdict_TouchAreaGrid(ent); } /* @@ -2530,7 +2541,8 @@ void SV_Physics_Step (prvm_edict_t *ent) ent->fields.server->flags -= FL_ONGROUND; SV_CheckVelocity(ent); SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent)); - SV_LinkEdict(ent, true); + SV_LinkEdict(ent); + SV_LinkEdict_TouchAreaGrid(ent); ent->priv.server->waterposition_forceupdate = true; } } @@ -2541,7 +2553,8 @@ void SV_Physics_Step (prvm_edict_t *ent) SV_CheckVelocity(ent); SV_FlyMove(ent, sv.frametime, true, NULL, SV_GenericHitSuperContentsMask(ent)); - SV_LinkEdict(ent, true); + SV_LinkEdict(ent); + SV_LinkEdict_TouchAreaGrid(ent); // just hit ground if (hitsound && (int)ent->fields.server->flags & FL_ONGROUND) @@ -2617,7 +2630,7 @@ static void SV_Physics_Entity (prvm_edict_t *ent) VectorMA(ent->fields.server->origin, sv.frametime, ent->fields.server->velocity, ent->fields.server->origin); VectorMA(ent->fields.server->angles, sv.frametime, ent->fields.server->avelocity, ent->fields.server->angles); } - SV_LinkEdict(ent, false); + SV_LinkEdict(ent); break; case MOVETYPE_STEP: SV_Physics_Step (ent); @@ -2774,7 +2787,8 @@ void SV_Physics_ClientEntity(prvm_edict_t *ent) SV_CheckVelocity (ent); - SV_LinkEdict (ent, true); + SV_LinkEdict(ent); + SV_LinkEdict_TouchAreaGrid(ent); SV_CheckVelocity (ent); @@ -2821,7 +2835,7 @@ void SV_Physics (void) if (prog->globals.server->force_retouch > 0) for (i = 1, ent = PRVM_EDICT_NUM(i);i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent)) if (!ent->priv.server->free) - SV_LinkEdict (ent, true); // force retouch even for stationary + SV_LinkEdict_TouchAreaGrid(ent); // force retouch even for stationary // run physics on the client entities for (i = 1, ent = PRVM_EDICT_NUM(i), host_client = svs.clients;i <= svs.maxclients;i++, ent = PRVM_NEXT_EDICT(ent), host_client++) diff --git a/svvm_cmds.c b/svvm_cmds.c index 1efe5a51..d91ce4bb 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -211,7 +211,7 @@ static void VM_SV_setorigin (void) } org = PRVM_G_VECTOR(OFS_PARM1); VectorCopy (org, e->fields.server->origin); - SV_LinkEdict (e, false); + SV_LinkEdict(e); } // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black] @@ -228,7 +228,7 @@ static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rot VectorCopy (max, e->fields.server->maxs); VectorSubtract (max, min, e->fields.server->size); - SV_LinkEdict (e, false); + SV_LinkEdict(e); } /* @@ -1089,7 +1089,7 @@ static void VM_SV_droptofloor (void) { Con_DPrintf("droptofloor at %f %f %f - COULD NOT FIX BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]); SV_UnstickEntity(ent); - SV_LinkEdict (ent, false); + SV_LinkEdict(ent); ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND; ent->fields.server->groundentity = 0; PRVM_G_FLOAT(OFS_RETURN) = 1; @@ -1099,7 +1099,7 @@ static void VM_SV_droptofloor (void) Con_DPrintf("droptofloor at %f %f %f - FIXED BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]); VectorCopy (trace.endpos, ent->fields.server->origin); SV_UnstickEntity(ent); - SV_LinkEdict (ent, false); + SV_LinkEdict(ent); ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND; ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent); PRVM_G_FLOAT(OFS_RETURN) = 1; @@ -1113,7 +1113,7 @@ static void VM_SV_droptofloor (void) { if (trace.fraction < 1) VectorCopy (trace.endpos, ent->fields.server->origin); - SV_LinkEdict (ent, false); + SV_LinkEdict(ent); ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND; ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent); PRVM_G_FLOAT(OFS_RETURN) = 1; @@ -1682,7 +1682,7 @@ static void VM_SV_copyentity (void) return; } memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4); - SV_LinkEdict(out, false); + SV_LinkEdict(out); } diff --git a/view.c b/view.c index d94c2bd4..8b55d0c3 100644 --- a/view.c +++ b/view.c @@ -357,10 +357,12 @@ void V_CalcRefdef (void) { entity_t *ent; float vieworg[3], gunorg[3], viewangles[3], smoothtime; +#if 0 // begin of chase camera bounding box size for proper collisions by Alexander Zubov vec3_t camboxmins = {-3, -3, -3}; vec3_t camboxmaxs = {3, 3, 3}; // end of chase camera bounding box size for proper collisions by Alexander Zubov +#endif trace_t trace; VectorClear(gunorg); viewmodelmatrix = identitymatrix; @@ -439,13 +441,22 @@ void V_CalcRefdef (void) chase_dest[1] = vieworg[1] - forward[1] * camback + up[1] * camup; chase_dest[2] = vieworg[2] - forward[2] * camback + up[2] * camup; #if 0 +#if 1 + //trace = CL_TraceLine(vieworg, eyeboxmins, eyeboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); + trace = CL_TraceLine(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); +#else //trace = CL_TraceBox(vieworg, eyeboxmins, eyeboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); +#endif VectorCopy(trace.endpos, vieworg); vieworg[2] -= 8; #else // trace from first person view location to our chosen third person view location +#if 1 + trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); +#else trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); +#endif VectorCopy(trace.endpos, bestvieworg); offset[2] = 0; for (offset[0] = -16;offset[0] <= 16;offset[0] += 8) @@ -456,7 +467,11 @@ void V_CalcRefdef (void) chase_dest[0] = vieworg[0] - forward[0] * camback + up[0] * camup + offset[0]; chase_dest[1] = vieworg[1] - forward[1] * camback + up[1] * camup + offset[1]; chase_dest[2] = vieworg[2] - forward[2] * camback + up[2] * camup + offset[2]; +#if 1 + trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); +#else trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false); +#endif if (bestvieworg[2] > trace.endpos[2]) bestvieworg[2] = trace.endpos[2]; } diff --git a/world.c b/world.c index d1352d39..20abb84a 100644 --- a/world.c +++ b/world.c @@ -235,7 +235,7 @@ void World_LinkEdict_AreaGrid(world_t *world, prvm_edict_t *ent) if (entitynumber <= 0 || entitynumber >= prog->max_edicts || PRVM_EDICT_NUM(entitynumber) != ent) { - Con_Printf ("SV_LinkEdict_AreaGrid: invalid edict %p (edicts is %p, edict compared to prog->edicts is %i)\n", (void *)ent, (void *)prog->edicts, entitynumber); + Con_Printf ("World_LinkEdict_AreaGrid: invalid edict %p (edicts is %p, edict compared to prog->edicts is %i)\n", (void *)ent, (void *)prog->edicts, entitynumber); return; } -- 2.39.2