// sv_phys.c
#include "quakedef.h"
+#include "prvm_cmds.h"
/*
void SV_Physics_Toss (prvm_edict_t *ent);
-int SV_GetPitchSign(prvm_edict_t *ent)
+int SV_GetPitchSign(prvm_prog_t *prog, prvm_edict_t *ent)
{
dp_model_t *model;
if (
int SV_GenericHitSuperContentsMask(const prvm_edict_t *passedict)
{
+ prvm_prog_t *prog = SVVM_prog;
if (passedict)
{
int dphitcontentsmask = (int)PRVM_serveredictfloat(passedict, dphitcontentsmask);
*/
trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask)
{
+ prvm_prog_t *prog = SVVM_prog;
int i, bodysupercontents;
int passedictprog;
float pitchsign = 1;
// 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
- numtouchedicts = World_EntitiesInBox(&sv.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
+ numtouchedicts = SV_EntitiesInBox(clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
if (numtouchedicts > MAX_EDICTS)
{
// this never happens
if ((int) PRVM_serveredictfloat(touch, solid) == SOLID_BSP || type == MOVE_HITMODEL)
{
model = SV_GetModelFromEdict(touch);
- pitchsign = SV_GetPitchSign(touch);
+ pitchsign = SV_GetPitchSign(prog, touch);
}
if (model)
Matrix4x4_CreateFromQuakeEntity(&matrix, PRVM_serveredictvector(touch, origin)[0], PRVM_serveredictvector(touch, origin)[1], PRVM_serveredictvector(touch, origin)[2], pitchsign * PRVM_serveredictvector(touch, angles)[0], PRVM_serveredictvector(touch, angles)[1], PRVM_serveredictvector(touch, angles)[2], 1);
else
Matrix4x4_CreateTranslate(&matrix, PRVM_serveredictvector(touch, origin)[0], PRVM_serveredictvector(touch, origin)[1], PRVM_serveredictvector(touch, origin)[2]);
Matrix4x4_Invert_Simple(&imatrix, &matrix);
- VM_GenerateFrameGroupBlend(touch->priv.server->framegroupblend, touch);
+ VM_GenerateFrameGroupBlend(prog, touch->priv.server->framegroupblend, touch);
VM_FrameBlendFromFrameGroupBlend(touch->priv.server->frameblend, touch->priv.server->framegroupblend, model);
- VM_UpdateEdictSkeleton(touch, model, touch->priv.server->frameblend);
+ VM_UpdateEdictSkeleton(prog, touch, model, touch->priv.server->frameblend);
if (type == MOVE_MISSILE && (int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER)
Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, PRVM_serveredictvector(touch, mins), PRVM_serveredictvector(touch, maxs), bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipstart, hitsupercontentsmask);
else
trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask)
#endif
{
+ prvm_prog_t *prog = SVVM_prog;
int i, bodysupercontents;
int passedictprog;
float pitchsign = 1;
// 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
- numtouchedicts = World_EntitiesInBox(&sv.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
+ numtouchedicts = SV_EntitiesInBox(clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
if (numtouchedicts > MAX_EDICTS)
{
// this never happens
if ((int) PRVM_serveredictfloat(touch, solid) == SOLID_BSP || type == MOVE_HITMODEL)
{
model = SV_GetModelFromEdict(touch);
- pitchsign = SV_GetPitchSign(touch);
+ pitchsign = SV_GetPitchSign(prog, touch);
}
if (model)
Matrix4x4_CreateFromQuakeEntity(&matrix, PRVM_serveredictvector(touch, origin)[0], PRVM_serveredictvector(touch, origin)[1], PRVM_serveredictvector(touch, origin)[2], pitchsign * PRVM_serveredictvector(touch, angles)[0], PRVM_serveredictvector(touch, angles)[1], PRVM_serveredictvector(touch, angles)[2], 1);
else
Matrix4x4_CreateTranslate(&matrix, PRVM_serveredictvector(touch, origin)[0], PRVM_serveredictvector(touch, origin)[1], PRVM_serveredictvector(touch, origin)[2]);
Matrix4x4_Invert_Simple(&imatrix, &matrix);
- VM_GenerateFrameGroupBlend(touch->priv.server->framegroupblend, touch);
+ VM_GenerateFrameGroupBlend(prog, touch->priv.server->framegroupblend, touch);
VM_FrameBlendFromFrameGroupBlend(touch->priv.server->frameblend, touch->priv.server->framegroupblend, model);
- VM_UpdateEdictSkeleton(touch, model, touch->priv.server->frameblend);
+ VM_UpdateEdictSkeleton(prog, touch, model, touch->priv.server->frameblend);
if (type == MOVE_MISSILE && (int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER)
Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, PRVM_serveredictvector(touch, mins), PRVM_serveredictvector(touch, maxs), bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask);
else
#endif
#endif
{
+ prvm_prog_t *prog = SVVM_prog;
vec3_t hullmins, hullmaxs;
int i, bodysupercontents;
int passedictprog;
// 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
- numtouchedicts = World_EntitiesInBox(&sv.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
+ numtouchedicts = SV_EntitiesInBox(clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
if (numtouchedicts > MAX_EDICTS)
{
// this never happens
if ((int) PRVM_serveredictfloat(touch, solid) == SOLID_BSP || type == MOVE_HITMODEL)
{
model = SV_GetModelFromEdict(touch);
- pitchsign = SV_GetPitchSign(touch);
+ pitchsign = SV_GetPitchSign(prog, touch);
}
if (model)
Matrix4x4_CreateFromQuakeEntity(&matrix, PRVM_serveredictvector(touch, origin)[0], PRVM_serveredictvector(touch, origin)[1], PRVM_serveredictvector(touch, origin)[2], pitchsign * PRVM_serveredictvector(touch, angles)[0], PRVM_serveredictvector(touch, angles)[1], PRVM_serveredictvector(touch, angles)[2], 1);
else
Matrix4x4_CreateTranslate(&matrix, PRVM_serveredictvector(touch, origin)[0], PRVM_serveredictvector(touch, origin)[1], PRVM_serveredictvector(touch, origin)[2]);
Matrix4x4_Invert_Simple(&imatrix, &matrix);
- VM_GenerateFrameGroupBlend(touch->priv.server->framegroupblend, touch);
+ VM_GenerateFrameGroupBlend(prog, touch->priv.server->framegroupblend, touch);
VM_FrameBlendFromFrameGroupBlend(touch->priv.server->frameblend, touch->priv.server->framegroupblend, model);
- VM_UpdateEdictSkeleton(touch, model, touch->priv.server->frameblend);
+ VM_UpdateEdictSkeleton(prog, touch, model, touch->priv.server->frameblend);
if (type == MOVE_MISSILE && (int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER)
Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, PRVM_serveredictvector(touch, mins), PRVM_serveredictvector(touch, maxs), bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask);
else
int SV_PointSuperContents(const vec3_t point)
{
+ prvm_prog_t *prog = SVVM_prog;
int supercontents = 0;
int i;
prvm_edict_t *touch;
return supercontents;
// get list of entities at this point
- numtouchedicts = World_EntitiesInBox(&sv.world, point, point, MAX_EDICTS, touchedicts);
+ numtouchedicts = SV_EntitiesInBox(point, point, MAX_EDICTS, touchedicts);
if (numtouchedicts > MAX_EDICTS)
{
// this never happens
===============================================================================
*/
+int SV_EntitiesInBox(const vec3_t mins, const vec3_t maxs, int maxedicts, prvm_edict_t **resultedicts)
+{
+ prvm_prog_t *prog = SVVM_prog;
+ vec3_t paddedmins, paddedmaxs;
+ if (maxedicts < 1 || resultedicts == NULL)
+ return 0;
+ VectorSet(paddedmins, mins[0] - 10, mins[1] - 10, mins[2] - 1);
+ VectorSet(paddedmaxs, maxs[0] + 10, maxs[1] + 10, maxs[2] + 1);
+ if (sv_areadebug.integer)
+ {
+ int numresultedicts = 0;
+ int edictindex;
+ prvm_edict_t *ed;
+ for (edictindex = 1;edictindex < prog->num_edicts;edictindex++)
+ {
+ ed = PRVM_EDICT_NUM(edictindex);
+ if (!ed->priv.required->free && BoxesOverlap(PRVM_serveredictvector(ed, absmin), PRVM_serveredictvector(ed, absmax), paddedmins, paddedmaxs))
+ {
+ resultedicts[numresultedicts++] = ed;
+ if (numresultedicts == maxedicts)
+ break;
+ }
+ }
+ return numresultedicts;
+ }
+ else
+ return World_EntitiesInBox(&sv.world, paddedmins, paddedmaxs, maxedicts, resultedicts);
+}
+
void SV_LinkEdict_TouchAreaGrid_Call(prvm_edict_t *touch, prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(touch);
PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(ent);
PRVM_serverglobalfloat(time) = sv.time;
PRVM_serverglobalfloat(trace_dphitcontents) = 0;
PRVM_serverglobalfloat(trace_dphitq3surfaceflags) = 0;
PRVM_serverglobalstring(trace_dphittexturename) = 0;
- PRVM_ExecuteProgram (PRVM_serveredictfunction(touch, touch), "QC function self.touch is missing");
+ prog->ExecuteProgram(prog, PRVM_serveredictfunction(touch, touch), "QC function self.touch is missing");
}
void SV_LinkEdict_TouchAreaGrid(prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
int i, numtouchedicts, old_self, old_other;
prvm_edict_t *touch;
static prvm_edict_t *touchedicts[MAX_EDICTS];
// 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);
+ numtouchedicts = SV_EntitiesInBox(ent->priv.server->areamins, ent->priv.server->areamaxs, MAX_EDICTS, touchedicts);
if (numtouchedicts > MAX_EDICTS)
{
// this never happens
*/
void SV_LinkEdict (prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
dp_model_t *model;
vec3_t mins, maxs;
int modelindex;
}
model = SV_GetModelByIndex(modelindex);
- VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
+ VM_GenerateFrameGroupBlend(prog, ent->priv.server->framegroupblend, ent);
VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
- VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
+ VM_UpdateEdictSkeleton(prog, ent, model, ent->priv.server->frameblend);
// set the abs box
*/
static int SV_TestEntityPosition (prvm_edict_t *ent, vec3_t offset)
{
+ prvm_prog_t *prog = SVVM_prog;
int contents;
vec3_t org;
trace_t trace;
return false;
}
-/*
-================
-SV_CheckAllEnts
-================
-*/
-void SV_CheckAllEnts (void)
-{
- int e;
- prvm_edict_t *check;
-
- // see if any solid entities are inside the final position
- check = PRVM_NEXT_EDICT(prog->edicts);
- for (e = 1;e < prog->num_edicts;e++, check = PRVM_NEXT_EDICT(check))
- {
- if (check->priv.server->free)
- continue;
- if (PRVM_serveredictfloat(check, movetype) == MOVETYPE_PUSH
- || PRVM_serveredictfloat(check, movetype) == MOVETYPE_NONE
- || PRVM_serveredictfloat(check, movetype) == MOVETYPE_FOLLOW
- || PRVM_serveredictfloat(check, movetype) == MOVETYPE_NOCLIP
- || PRVM_serveredictfloat(check, movetype) == MOVETYPE_FLY_WORLDONLY)
- continue;
-
- if (SV_TestEntityPosition (check, vec3_origin))
- Con_Print("entity in invalid position\n");
- }
-}
-
// DRESK - Support for Entity Contents Transition Event
/*
================
returns true if entity had a valid contentstransition function call
================
*/
-int SV_CheckContentsTransition(prvm_edict_t *ent, const int nContents)
+static int SV_CheckContentsTransition(prvm_edict_t *ent, const int nContents)
{
+ prvm_prog_t *prog = SVVM_prog;
int bValidFunctionCall;
// Default Valid Function Call to False
// Assign Valid Function
bValidFunctionCall = true;
// Prepare Parameters (Original Contents, New Contents)
- // Original Contents
- PRVM_G_FLOAT(OFS_PARM0) = PRVM_serveredictfloat(ent, watertype);
- // New Contents
- PRVM_G_FLOAT(OFS_PARM1) = nContents;
- // Assign Self
- PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
+ // Original Contents
+ PRVM_G_FLOAT(OFS_PARM0) = PRVM_serveredictfloat(ent, watertype);
+ // New Contents
+ PRVM_G_FLOAT(OFS_PARM1) = nContents;
+ // Assign Self
+ PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
+ // Set Time
+ PRVM_serverglobalfloat(time) = sv.time;
// Execute VM Function
- PRVM_ExecuteProgram(PRVM_serveredictfunction(ent, contentstransition), "contentstransition: NULL function");
+ prog->ExecuteProgram(prog, PRVM_serveredictfunction(ent, contentstransition), "contentstransition: NULL function");
}
}
*/
void SV_CheckVelocity (prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
int i;
float wishspeed;
{
if (IS_NAN(PRVM_serveredictvector(ent, velocity)[i]))
{
- Con_Printf("Got a NaN velocity on entity #%i (%s)\n", PRVM_NUM_FOR_EDICT(ent), PRVM_GetString(PRVM_serveredictstring(ent, classname)));
+ Con_Printf("Got a NaN velocity on entity #%i (%s)\n", PRVM_NUM_FOR_EDICT(ent), PRVM_GetString(prog, PRVM_serveredictstring(ent, classname)));
PRVM_serveredictvector(ent, velocity)[i] = 0;
}
if (IS_NAN(PRVM_serveredictvector(ent, origin)[i]))
{
- Con_Printf("Got a NaN origin on entity #%i (%s)\n", PRVM_NUM_FOR_EDICT(ent), PRVM_GetString(PRVM_serveredictstring(ent, classname)));
+ Con_Printf("Got a NaN origin on entity #%i (%s)\n", PRVM_NUM_FOR_EDICT(ent), PRVM_GetString(prog, PRVM_serveredictstring(ent, classname)));
PRVM_serveredictvector(ent, origin)[i] = 0;
}
}
Returns false if the entity removed itself.
=============
*/
-qboolean SV_RunThink (prvm_edict_t *ent)
+static qboolean SV_RunThink (prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
int iterations;
// don't let things stay in the past.
PRVM_serveredictfloat(ent, nextthink) = 0;
PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(prog->edicts);
- PRVM_ExecuteProgram (PRVM_serveredictfunction(ent, think), "QC function self.think is missing");
+ prog->ExecuteProgram(prog, PRVM_serveredictfunction(ent, think), "QC function self.think is missing");
// mods often set nextthink to time to cause a think every frame,
// we don't want to loop in that case, so exit if the new nextthink is
// <= the time the qc was told, also exit if it is past the end of the
Two entities have touched, so run their touch functions
==================
*/
-extern void VM_SetTraceGlobals(const trace_t *trace);
-extern sizebuf_t vm_tempstringsbuf;
-void SV_Impact (prvm_edict_t *e1, trace_t *trace)
+static void SV_Impact (prvm_edict_t *e1, trace_t *trace)
{
+ prvm_prog_t *prog = SVVM_prog;
int restorevm_tempstringsbuf_cursize;
int old_self, old_other;
prvm_edict_t *e2 = (prvm_edict_t *)trace->ent;
old_self = PRVM_serverglobaledict(self);
old_other = PRVM_serverglobaledict(other);
- restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize;
+ restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
- VM_SetTraceGlobals(trace);
+ VM_SetTraceGlobals(prog, trace);
- PRVM_serverglobalfloat(time) = sv.time;
if (!e1->priv.server->free && !e2->priv.server->free && PRVM_serveredictfunction(e1, touch) && PRVM_serveredictfloat(e1, solid) != SOLID_NOT)
{
+ PRVM_serverglobalfloat(time) = sv.time;
PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(e1);
PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(e2);
- PRVM_ExecuteProgram (PRVM_serveredictfunction(e1, touch), "QC function self.touch is missing");
+ prog->ExecuteProgram(prog, PRVM_serveredictfunction(e1, touch), "QC function self.touch is missing");
}
if (!e1->priv.server->free && !e2->priv.server->free && PRVM_serveredictfunction(e2, touch) && PRVM_serveredictfloat(e2, solid) != SOLID_NOT)
{
+ PRVM_serverglobalfloat(time) = sv.time;
PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(e2);
PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(e1);
VectorCopy(PRVM_serveredictvector(e2, origin), PRVM_serverglobalvector(trace_endpos));
PRVM_serverglobalfloat(trace_dphitcontents) = 0;
PRVM_serverglobalfloat(trace_dphitq3surfaceflags) = 0;
PRVM_serverglobalstring(trace_dphittexturename) = 0;
- PRVM_ExecuteProgram (PRVM_serveredictfunction(e2, touch), "QC function self.touch is missing");
+ prog->ExecuteProgram(prog, PRVM_serveredictfunction(e2, touch), "QC function self.touch is missing");
}
PRVM_serverglobaledict(self) = old_self;
PRVM_serverglobaledict(other) = old_other;
- vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
+ prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
}
==================
*/
#define STOP_EPSILON 0.1
-void ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce)
+static void ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce)
{
int i;
float backoff;
#define MAX_CLIP_PLANES 5
static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, float *stepnormal, int hitsupercontentsmask, float stepheight)
{
+ prvm_prog_t *prog = SVVM_prog;
int blocked, bumpcount;
int i, j, numplanes;
float d, time_left, gravity;
*/
static float SV_Gravity (prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
float ent_gravity;
ent_gravity = PRVM_serveredictfloat(ent, gravity);
static qboolean SV_NudgeOutOfSolid_PivotIsKnownGood(prvm_edict_t *ent, vec3_t pivot)
{
+ prvm_prog_t *prog = SVVM_prog;
int bump;
trace_t stucktrace;
vec3_t stuckorigin;
static qboolean SV_NudgeOutOfSolid(prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
int bump;
trace_t stucktrace;
vec3_t stuckorigin;
*/
static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, qboolean failonbmodelstartsolid, qboolean dolink)
{
+ prvm_prog_t *prog = SVVM_prog;
int solid;
int movetype;
int type;
vec3_t mins, maxs;
- vec3_t original, original_velocity;
vec3_t start;
vec3_t end;
VectorCopy(trace->endpos, PRVM_serveredictvector(ent, origin));
- VectorCopy(PRVM_serveredictvector(ent, origin), original);
- VectorCopy(PRVM_serveredictvector(ent, velocity), original_velocity);
+ ent->priv.required->mark = PRVM_EDICT_MARK_WAIT_FOR_SETORIGIN; // -2: setorigin running
SV_LinkEdict(ent);
if((PRVM_serveredictfloat(ent, solid) >= SOLID_TRIGGER && trace->ent && (!((int)PRVM_serveredictfloat(ent, flags) & FL_ONGROUND) || PRVM_serveredictedict(ent, groundentity) != PRVM_EDICT_TO_PROG(trace->ent))))
SV_Impact (ent, trace);
- return VectorCompare(PRVM_serveredictvector(ent, origin), original) && VectorCompare(PRVM_serveredictvector(ent, velocity), original_velocity);
+ if(ent->priv.required->mark == PRVM_EDICT_MARK_SETORIGIN_CAUGHT)
+ {
+ ent->priv.required->mark = 0;
+ return false;
+ }
+ else if(ent->priv.required->mark == PRVM_EDICT_MARK_WAIT_FOR_SETORIGIN)
+ {
+ ent->priv.required->mark = 0;
+ return true;
+ }
+ else
+ {
+ Con_Printf("The edict mark had been overwritten! Please debug this.\n");
+ return true;
+ }
}
============
*/
-void SV_PushMove (prvm_edict_t *pusher, float movetime)
+static void SV_PushMove (prvm_edict_t *pusher, float movetime)
{
+ prvm_prog_t *prog = SVVM_prog;
int i, e, index;
int pusherowner, pusherprog;
int checkcontents;
if (PRVM_serveredictfloat(pusher, movetype) == MOVETYPE_FAKEPUSH) // Tenebrae's MOVETYPE_PUSH variant that doesn't push...
numcheckentities = 0;
else // MOVETYPE_PUSH
- numcheckentities = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, checkentities);
+ numcheckentities = SV_EntitiesInBox(mins, maxs, MAX_EDICTS, checkentities);
for (e = 0;e < numcheckentities;e++)
{
prvm_edict_t *check = checkentities[e];
// if the pusher has a "blocked" function, call it, otherwise just stay in place until the obstacle is gone
if (PRVM_serveredictfunction(pusher, blocked))
{
+ PRVM_serverglobalfloat(time) = sv.time;
PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(pusher);
PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(check);
- PRVM_ExecuteProgram (PRVM_serveredictfunction(pusher, blocked), "QC function self.blocked is missing");
+ prog->ExecuteProgram(prog, PRVM_serveredictfunction(pusher, blocked), "QC function self.blocked is missing");
}
break;
}
================
*/
-void SV_Physics_Pusher (prvm_edict_t *ent)
+static void SV_Physics_Pusher (prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
float thinktime, oldltime, movetime;
oldltime = PRVM_serveredictfloat(ent, ltime);
PRVM_serverglobalfloat(time) = sv.time;
PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(prog->edicts);
- PRVM_ExecuteProgram (PRVM_serveredictfunction(ent, think), "QC function self.think is missing");
+ prog->ExecuteProgram(prog, PRVM_serveredictfunction(ent, think), "QC function self.think is missing");
}
}
}
unstickresult_t;
-unstickresult_t SV_UnstickEntityReturnOffset (prvm_edict_t *ent, vec3_t offset)
+static unstickresult_t SV_UnstickEntityReturnOffset (prvm_edict_t *ent, vec3_t offset)
{
+ prvm_prog_t *prog = SVVM_prog;
int i, maxunstick;
// if not stuck in a bmodel, just return
qboolean SV_UnstickEntity (prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
vec3_t offset;
switch(SV_UnstickEntityReturnOffset(ent, offset))
{
case UNSTICK_GOOD:
return true;
case UNSTICK_UNSTUCK:
- Con_DPrintf("Unstuck entity %i (classname \"%s\") with offset %f %f %f.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(PRVM_serveredictstring(ent, classname)), offset[0], offset[1], offset[2]);
+ Con_DPrintf("Unstuck entity %i (classname \"%s\") with offset %f %f %f.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(prog, PRVM_serveredictstring(ent, classname)), offset[0], offset[1], offset[2]);
return true;
case UNSTICK_STUCK:
if (developer_extra.integer)
- Con_DPrintf("Stuck entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(PRVM_serveredictstring(ent, classname)));
+ Con_DPrintf("Stuck entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(prog, PRVM_serveredictstring(ent, classname)));
return false;
default:
Con_Printf("SV_UnstickEntityReturnOffset returned a value outside its enum.\n");
clipping hull.
=============
*/
-void SV_CheckStuck (prvm_edict_t *ent)
+static void SV_CheckStuck (prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
vec3_t offset;
switch(SV_UnstickEntityReturnOffset(ent, offset))
VectorCopy (PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, oldorigin));
break;
case UNSTICK_UNSTUCK:
- Con_DPrintf("Unstuck player entity %i (classname \"%s\") with offset %f %f %f.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(PRVM_serveredictstring(ent, classname)), offset[0], offset[1], offset[2]);
+ Con_DPrintf("Unstuck player entity %i (classname \"%s\") with offset %f %f %f.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(prog, PRVM_serveredictstring(ent, classname)), offset[0], offset[1], offset[2]);
break;
case UNSTICK_STUCK:
VectorSubtract(PRVM_serveredictvector(ent, oldorigin), PRVM_serveredictvector(ent, origin), offset);
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(PRVM_serveredictstring(ent, classname)));
+ Con_DPrintf("Unstuck player entity %i (classname \"%s\") by restoring oldorigin.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(prog, PRVM_serveredictstring(ent, classname)));
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(PRVM_serveredictstring(ent, classname)));
+ Con_DPrintf("Stuck player entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(prog, PRVM_serveredictstring(ent, classname)));
break;
default:
Con_Printf("SV_UnstickEntityReturnOffset returned a value outside its enum.\n");
SV_CheckWater
=============
*/
-qboolean SV_CheckWater (prvm_edict_t *ent)
+static qboolean SV_CheckWater (prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
int cont;
int nNativeContents;
vec3_t point;
============
*/
-void SV_WallFriction (prvm_edict_t *ent, float *stepnormal)
+static void SV_WallFriction (prvm_edict_t *ent, float *stepnormal)
{
+ prvm_prog_t *prog = SVVM_prog;
float d, i;
vec3_t forward, into, side;
Only used by players
======================
*/
-void SV_WalkMove (prvm_edict_t *ent)
+static void SV_WalkMove (prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
int clip;
int oldonground;
//int originalmove_clip;
Entities that are "stuck" to another entity
=============
*/
-void SV_Physics_Follow (prvm_edict_t *ent)
+static void SV_Physics_Follow (prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
vec3_t vf, vr, vu, angles, v;
prvm_edict_t *e;
=============
*/
-void SV_CheckWaterTransition (prvm_edict_t *ent)
+static void SV_CheckWaterTransition (prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
+ // LordHavoc: bugfixes in this function are keyed to the sv_gameplayfix_bugfixedcheckwatertransition cvar - if this cvar is 0 then all the original bugs should be reenabled for compatibility
int cont;
cont = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_serveredictvector(ent, origin)));
if (!PRVM_serveredictfloat(ent, watertype))
{
// just spawned here
- PRVM_serveredictfloat(ent, watertype) = cont;
- PRVM_serveredictfloat(ent, waterlevel) = 1;
- return;
+ if (!sv_gameplayfix_fixedcheckwatertransition.integer)
+ {
+ PRVM_serveredictfloat(ent, watertype) = cont;
+ PRVM_serveredictfloat(ent, waterlevel) = 1;
+ return;
+ }
}
-
// DRESK - Support for Entity Contents Transition Event
// NOTE: Call here BEFORE updating the watertype below,
// and suppress watersplash sound if a valid function
// call was made to allow for custom "splash" sounds.
- if( !SV_CheckContentsTransition(ent, cont) )
+ else if( !SV_CheckContentsTransition(ent, cont) )
{ // Contents Transition Function Invalid; Potentially Play Water Sound
// check if the entity crossed into or out of water
if (sv_sound_watersplash.string && ((PRVM_serveredictfloat(ent, watertype) == CONTENTS_WATER || PRVM_serveredictfloat(ent, watertype) == CONTENTS_SLIME) != (cont == CONTENTS_WATER || cont == CONTENTS_SLIME)))
- SV_StartSound (ent, 0, sv_sound_watersplash.string, 255, 1, false);
+ SV_StartSound (ent, 0, sv_sound_watersplash.string, 255, 1, false, 1.0f);
}
if (cont <= CONTENTS_WATER)
else
{
PRVM_serveredictfloat(ent, watertype) = CONTENTS_EMPTY;
- PRVM_serveredictfloat(ent, waterlevel) = 0;
+ PRVM_serveredictfloat(ent, waterlevel) = sv_gameplayfix_fixedcheckwatertransition.integer ? 0 : cont;
}
}
void SV_Physics_Toss (prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
trace_t trace;
vec3_t move;
vec_t movetime;
int bump;
prvm_edict_t *groundentity;
+ float d, ent_gravity;
+ float bouncefactor;
+ float bouncestop;
// if onground, return without moving
if ((int)PRVM_serveredictfloat(ent, flags) & FL_ONGROUND)
for (bump = 0;bump < MAX_CLIP_PLANES && movetime > 0;bump++)
{
// move origin
- VectorScale (PRVM_serveredictvector(ent, velocity), movetime, move);
- if(!SV_PushEntity (&trace, ent, move, true, true))
+ VectorScale(PRVM_serveredictvector(ent, velocity), movetime, move);
+ if(!SV_PushEntity(&trace, ent, move, true, true))
return; // teleported
if (ent->priv.server->free)
return;
// try to unstick the entity
if (sv_gameplayfix_unstickentities.integer)
SV_UnstickEntity(ent);
- if(!SV_PushEntity (&trace, ent, move, false, true))
+ if(!SV_PushEntity(&trace, ent, move, false, true))
return; // teleported
if (ent->priv.server->free)
return;
if (trace.fraction == 1)
break;
movetime *= 1 - min(1, trace.fraction);
- if (PRVM_serveredictfloat(ent, movetype) == MOVETYPE_BOUNCEMISSILE)
+ switch((int)PRVM_serveredictfloat(ent, movetype))
{
- float bouncefactor;
+ case MOVETYPE_BOUNCEMISSILE:
bouncefactor = PRVM_serveredictfloat(ent, bouncefactor);
if (!bouncefactor)
bouncefactor = 1.0f;
- ClipVelocity (PRVM_serveredictvector(ent, velocity), trace.plane.normal, PRVM_serveredictvector(ent, velocity), 1 + bouncefactor);
+ ClipVelocity(PRVM_serveredictvector(ent, velocity), trace.plane.normal, PRVM_serveredictvector(ent, velocity), 1 + bouncefactor);
PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) & ~FL_ONGROUND;
- }
- else if (PRVM_serveredictfloat(ent, movetype) == MOVETYPE_BOUNCE)
- {
- float d, ent_gravity;
- float bouncefactor;
- float bouncestop;
-
+ if (!sv_gameplayfix_slidemoveprojectiles.integer)
+ movetime = 0;
+ break;
+ case MOVETYPE_BOUNCE:
bouncefactor = PRVM_serveredictfloat(ent, bouncefactor);
if (!bouncefactor)
bouncefactor = 0.5f;
if (!bouncestop)
bouncestop = 60.0f / 800.0f;
- ClipVelocity (PRVM_serveredictvector(ent, velocity), trace.plane.normal, PRVM_serveredictvector(ent, velocity), 1 + bouncefactor);
+ ClipVelocity(PRVM_serveredictvector(ent, velocity), trace.plane.normal, PRVM_serveredictvector(ent, velocity), 1 + bouncefactor);
ent_gravity = PRVM_serveredictfloat(ent, gravity);
if (!ent_gravity)
ent_gravity = 1.0f;
// LordHavoc: fixed grenades not bouncing when fired down a slope
if (sv_gameplayfix_grenadebouncedownslopes.integer)
+ d = fabs(DotProduct(trace.plane.normal, PRVM_serveredictvector(ent, velocity)));
+ else
+ d = PRVM_serveredictvector(ent, velocity)[2];
+ if (trace.plane.normal[2] > 0.7 && d < sv_gravity.value * bouncestop * ent_gravity)
{
- d = DotProduct(trace.plane.normal, PRVM_serveredictvector(ent, velocity));
- if (trace.plane.normal[2] > 0.7 && fabs(d) < sv_gravity.value * bouncestop * ent_gravity)
- {
- PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
- PRVM_serveredictedict(ent, groundentity) = PRVM_EDICT_TO_PROG(trace.ent);
- VectorClear (PRVM_serveredictvector(ent, velocity));
- VectorClear (PRVM_serveredictvector(ent, avelocity));
- }
- else
- PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) & ~FL_ONGROUND;
+ PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
+ PRVM_serveredictedict(ent, groundentity) = PRVM_EDICT_TO_PROG(trace.ent);
+ VectorClear(PRVM_serveredictvector(ent, velocity));
+ VectorClear(PRVM_serveredictvector(ent, avelocity));
+ movetime = 0;
}
else
{
- if (trace.plane.normal[2] > 0.7 && PRVM_serveredictvector(ent, velocity)[2] < sv_gravity.value * bouncestop * ent_gravity)
- {
- PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
- PRVM_serveredictedict(ent, groundentity) = PRVM_EDICT_TO_PROG(trace.ent);
- VectorClear (PRVM_serveredictvector(ent, velocity));
- VectorClear (PRVM_serveredictvector(ent, avelocity));
- }
- else
- PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) & ~FL_ONGROUND;
+ PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) & ~FL_ONGROUND;
+ if (!sv_gameplayfix_slidemoveprojectiles.integer)
+ movetime = 0;
}
- }
- else
- {
+ break;
+ default:
ClipVelocity (PRVM_serveredictvector(ent, velocity), trace.plane.normal, PRVM_serveredictvector(ent, velocity), 1.0);
if (trace.plane.normal[2] > 0.7)
{
}
else
PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) & ~FL_ONGROUND;
- }
- if (!sv_gameplayfix_slidemoveprojectiles.integer || (PRVM_serveredictfloat(ent, movetype) != MOVETYPE_BOUNCE && PRVM_serveredictfloat(ent, movetype) == MOVETYPE_BOUNCEMISSILE) || ((int)PRVM_serveredictfloat(ent, flags) & FL_ONGROUND))
+ movetime = 0;
break;
+ }
}
// check for in water
will fall if the floor is pulled out from under them.
=============
*/
-void SV_Physics_Step (prvm_edict_t *ent)
+static void SV_Physics_Step (prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
int flags = (int)PRVM_serveredictfloat(ent, flags);
// DRESK
if(PRVM_serveredictfunction(ent, movetypesteplandevent))
{ // Valid Function; Execute
// Prepare Parameters
- // Assign Velocity at Impact
- PRVM_G_VECTOR(OFS_PARM0)[0] = backupVelocity[0];
- PRVM_G_VECTOR(OFS_PARM0)[1] = backupVelocity[1];
- PRVM_G_VECTOR(OFS_PARM0)[2] = backupVelocity[2];
- // Assign Self
- PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
+ // Assign Velocity at Impact
+ PRVM_G_VECTOR(OFS_PARM0)[0] = backupVelocity[0];
+ PRVM_G_VECTOR(OFS_PARM0)[1] = backupVelocity[1];
+ PRVM_G_VECTOR(OFS_PARM0)[2] = backupVelocity[2];
+ // Assign Self
+ PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
+ // Set Time
+ PRVM_serverglobalfloat(time) = sv.time;
// Execute VM Function
- PRVM_ExecuteProgram(PRVM_serveredictfunction(ent, movetypesteplandevent), "movetypesteplandevent: NULL function");
+ prog->ExecuteProgram(prog, PRVM_serveredictfunction(ent, movetypesteplandevent), "movetypesteplandevent: NULL function");
}
else
// Check for Engine Landing Sound
if(sv_sound_land.string)
- SV_StartSound(ent, 0, sv_sound_land.string, 255, 1, false);
+ SV_StartSound(ent, 0, sv_sound_land.string, 255, 1, false, 1.0f);
}
ent->priv.server->waterposition_forceupdate = true;
}
static void SV_Physics_Entity (prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
// don't run think/move on newly spawned projectiles as it messes up
// movement interpolation and rocket trails, and is inconsistent with
// respect to entities spawned in the same frame
void SV_Physics_ClientMove(void)
{
+ prvm_prog_t *prog = SVVM_prog;
prvm_edict_t *ent;
ent = host_client->edict;
PRVM_serverglobalfloat(time) = sv.time;
PRVM_serverglobalfloat(frametime) = 0;
PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
- PRVM_ExecuteProgram (PRVM_serverfunction(PlayerPreThink), "QC function PlayerPreThink is missing");
+ prog->ExecuteProgram(prog, PRVM_serverfunction(PlayerPreThink), "QC function PlayerPreThink is missing");
PRVM_serverglobalfloat(frametime) = sv.frametime;
// make sure the velocity is sane (not a NaN)
PRVM_serverglobalfloat(time) = sv.time;
PRVM_serverglobalfloat(frametime) = 0;
PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
- PRVM_ExecuteProgram (PRVM_serverfunction(PlayerPostThink), "QC function PlayerPostThink is missing");
+ prog->ExecuteProgram(prog, PRVM_serverfunction(PlayerPostThink), "QC function PlayerPostThink is missing");
PRVM_serverglobalfloat(frametime) = sv.frametime;
if(PRVM_serveredictfloat(ent, fixangle))
static void SV_Physics_ClientEntity_PreThink(prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
// don't do physics on disconnected clients, FrikBot relies on this
if (!host_client->spawned)
return;
// call standard client pre-think
PRVM_serverglobalfloat(time) = sv.time;
PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
- PRVM_ExecuteProgram(PRVM_serverfunction(PlayerPreThink), "QC function PlayerPreThink is missing");
+ prog->ExecuteProgram(prog, PRVM_serverfunction(PlayerPreThink), "QC function PlayerPreThink is missing");
// make sure the velocity is still sane (not a NaN)
SV_CheckVelocity(ent);
static void SV_Physics_ClientEntity_PostThink(prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
// don't do physics on disconnected clients, FrikBot relies on this
if (!host_client->spawned)
return;
// call standard player post-think
PRVM_serverglobalfloat(time) = sv.time;
PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
- PRVM_ExecuteProgram(PRVM_serverfunction(PlayerPostThink), "QC function PlayerPostThink is missing");
+ prog->ExecuteProgram(prog, PRVM_serverfunction(PlayerPostThink), "QC function PlayerPostThink is missing");
// make sure the velocity is still sane (not a NaN)
SV_CheckVelocity(ent);
static void SV_Physics_ClientEntity(prvm_edict_t *ent)
{
+ prvm_prog_t *prog = SVVM_prog;
// don't do physics on disconnected clients, FrikBot relies on this
if (!host_client->spawned)
{
*/
void SV_Physics (void)
{
+ prvm_prog_t *prog = SVVM_prog;
int i;
prvm_edict_t *ent;
PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(prog->edicts);
PRVM_serverglobalfloat(time) = sv.time;
PRVM_serverglobalfloat(frametime) = sv.frametime;
- PRVM_ExecuteProgram (PRVM_serverfunction(StartFrame), "QC function StartFrame is missing");
+ prog->ExecuteProgram(prog, PRVM_serverfunction(StartFrame), "QC function StartFrame is missing");
// run physics engine
World_Physics_Frame(&sv.world, sv.frametime, sv_gravity.value);
PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(prog->edicts);
PRVM_serverglobaledict(other) = PRVM_EDICT_TO_PROG(prog->edicts);
PRVM_serverglobalfloat(time) = sv.time;
- PRVM_ExecuteProgram (PRVM_serverfunction(EndFrame), "QC function EndFrame is missing");
+ prog->ExecuteProgram(prog, PRVM_serverfunction(EndFrame), "QC function EndFrame is missing");
}
// decrement prog->num_edicts if the highest number entities died
- for (;PRVM_ED_CanAlloc(PRVM_EDICT_NUM(prog->num_edicts - 1));prog->num_edicts--);
+ for (;PRVM_ED_CanAlloc(prog, PRVM_EDICT_NUM(prog->num_edicts - 1));prog->num_edicts--);
if (!sv_freezenonclients.integer)
sv.time += sv.frametime;