#include "quakedef.h"
#include "cl_collision.h"
-/*
-// not yet used
-typedef struct physentity_s
-{
- // this may be a entity_t, or a prvm_edict_t, or whatever
- void *realentity;
-
- // can be NULL if it is a bbox object
- model_t *bmodel;
-
- // node this entity crosses
- // for avoiding unnecessary collisions
- physnode_t *node;
-
- // matrix for converting from model to world coordinates
- double modeltoworldmatrix[3][4];
-
- // matrix for converting from world to model coordinates
- double worldtomodelmatrix[3][4];
-
- // if this is a bmodel, this is used for culling it quickly
- // if this is not a bmodel, this is used for actual collisions
- double mins[3], maxs[3];
-}
-physentity_t;
-*/
-
-trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitbmodels, int *hitent, int hitsupercontentsmask, qboolean hitplayers)
-{
- int n;
- entity_render_t *ent;
- vec3_t tracemins, tracemaxs;
- trace_t cliptrace, trace;
- vec3_t origin;
- vec3_t starttransformed, endtransformed;
- vec3_t entmins, entmaxs;
- vec_t *playermins, *playermaxs;
-
- memset (&cliptrace, 0 , sizeof(trace_t));
- cliptrace.fraction = 1;
- cliptrace.realfraction = 1;
-
- if (cl.worldmodel && cl.worldmodel->TraceBox)
- cl.worldmodel->TraceBox(cl.worldmodel, 0, &cliptrace, start, mins, maxs, end, hitsupercontentsmask);
-
- if (hitent)
- *hitent = 0;
-
- if (hitbmodels && cl.num_brushmodel_entities)
- {
- tracemins[0] = min(start[0], end[0]) + mins[0];
- tracemaxs[0] = max(start[0], end[0]) + maxs[0];
- tracemins[1] = min(start[1], end[1]) + mins[1];
- tracemaxs[1] = max(start[1], end[1]) + maxs[1];
- tracemins[2] = min(start[2], end[2]) + mins[2];
- tracemaxs[2] = max(start[2], end[2]) + maxs[2];
-
- // look for embedded bmodels
- for (n = 0;n < cl.num_brushmodel_entities;n++)
- {
- ent = &cl.entities[cl.brushmodel_entities[n]].render;
- if (!BoxesOverlap(tracemins, tracemaxs, ent->mins, ent->maxs))
- continue;
-
- Matrix4x4_Transform(&ent->inversematrix, start, starttransformed);
- Matrix4x4_Transform(&ent->inversematrix, end, endtransformed);
-
- memset (&trace, 0 , sizeof(trace_t));
- trace.fraction = 1;
- trace.realfraction = 1;
-
- if (ent->model && ent->model->TraceBox)
- ent->model->TraceBox(ent->model, 0, &trace, starttransformed, mins, maxs, endtransformed, hitsupercontentsmask);
-
- // LordHavoc: take the 'best' answers from the new trace and combine with existing data
- if (trace.allsolid)
- cliptrace.allsolid = true;
- if (trace.startsolid)
- {
- cliptrace.startsolid = true;
- if (cliptrace.realfraction == 1)
- if (hitent)
- *hitent = cl.brushmodel_entities[n];
- }
- // don't set this except on the world, because it can easily confuse
- // monsters underwater if there's a bmodel involved in the trace
- // (inopen && inwater is how they check water visibility)
- //if (trace.inopen)
- // cliptrace.inopen = true;
- if (trace.inwater)
- cliptrace.inwater = true;
- if (trace.realfraction < cliptrace.realfraction)
- {
- cliptrace.fraction = trace.fraction;
- cliptrace.realfraction = trace.realfraction;
- cliptrace.plane = trace.plane;
- if (hitent)
- *hitent = cl.brushmodel_entities[n];
- Matrix4x4_Transform3x3(&ent->matrix, trace.plane.normal, cliptrace.plane.normal);
- cliptrace.hitsupercontents = trace.hitsupercontents;
- cliptrace.hitq3surfaceflags = trace.hitq3surfaceflags;
- cliptrace.hittexture = trace.hittexture;
- }
- cliptrace.startsupercontents |= trace.startsupercontents;
- }
- }
- if (hitplayers)
- {
- tracemins[0] = min(start[0], end[0]) + mins[0];
- tracemaxs[0] = max(start[0], end[0]) + maxs[0];
- tracemins[1] = min(start[1], end[1]) + mins[1];
- tracemaxs[1] = max(start[1], end[1]) + maxs[1];
- tracemins[2] = min(start[2], end[2]) + mins[2];
- tracemaxs[2] = max(start[2], end[2]) + maxs[2];
-
- for (n = 1;n < cl.maxclients+1;n++)
- {
- if (n != cl.playerentity)
- {
- ent = &cl.entities[n].render;
- // FIXME: crouch
- playermins = cl.playerstandmins;
- playermaxs = cl.playerstandmaxs;
- Matrix4x4_OriginFromMatrix(&ent->matrix, origin);
- VectorAdd(origin, playermins, entmins);
- VectorAdd(origin, playermaxs, entmaxs);
- if (!BoxesOverlap(tracemins, tracemaxs, entmins, entmaxs))
- continue;
-
- memset (&trace, 0 , sizeof(trace_t));
- trace.fraction = 1;
- trace.realfraction = 1;
-
- Matrix4x4_Transform(&ent->inversematrix, start, starttransformed);
- Matrix4x4_Transform(&ent->inversematrix, end, endtransformed);
- Collision_ClipTrace_Box(&trace, playermins, playermaxs, starttransformed, mins, maxs, endtransformed, hitsupercontentsmask, SUPERCONTENTS_BODY, 0, NULL);
-
- // LordHavoc: take the 'best' answers from the new trace and combine with existing data
- if (trace.allsolid)
- cliptrace.allsolid = true;
- if (trace.startsolid)
- {
- cliptrace.startsolid = true;
- if (cliptrace.realfraction == 1)
- if (hitent)
- *hitent = n;
- }
- // don't set this except on the world, because it can easily confuse
- // monsters underwater if there's a bmodel involved in the trace
- // (inopen && inwater is how they check water visibility)
- //if (trace.inopen)
- // cliptrace.inopen = true;
- if (trace.inwater)
- cliptrace.inwater = true;
- if (trace.realfraction < cliptrace.realfraction)
- {
- cliptrace.fraction = trace.fraction;
- cliptrace.realfraction = trace.realfraction;
- cliptrace.plane = trace.plane;
- if (hitent)
- *hitent = n;
- Matrix4x4_Transform3x3(&ent->matrix, trace.plane.normal, cliptrace.plane.normal);
- cliptrace.hitsupercontents = trace.hitsupercontents;
- cliptrace.hitq3surfaceflags = trace.hitq3surfaceflags;
- cliptrace.hittexture = trace.hittexture;
- }
- cliptrace.startsupercontents |= trace.startsupercontents;
- }
- }
- }
- cliptrace.fraction = bound(0, cliptrace.fraction, 1);
- cliptrace.realfraction = bound(0, cliptrace.realfraction, 1);
- VectorLerp(start, cliptrace.fraction, end, cliptrace.endpos);
- return cliptrace;
-}
-
float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int *hitent, entity_render_t *ignoreent)
{
float maxfrac, maxrealfrac;
cl.worldmodel->brush.FindNonSolidLocation(cl.worldmodel, in, out, radius);
}
-int CL_PointSuperContents(const vec3_t p)
+model_t *CL_GetModelByIndex(int modelindex)
{
- return CL_TraceBox(p, vec3_origin, vec3_origin, p, true, NULL, 0, false).startsupercontents;
+ if(!modelindex)
+ return NULL;
+ if (modelindex < 0)
+ {
+ modelindex = -(modelindex+1);
+ if (modelindex < MAX_MODELS)
+ return cl.csqc_model_precache[modelindex];
+ }
+ else
+ {
+ if(modelindex < MAX_MODELS)
+ return cl.model_precache[modelindex];
+ }
+ return NULL;
+}
+
+model_t *CL_GetModelFromEdict(prvm_edict_t *ed)
+{
+ if (!ed || ed->priv.server->free)
+ return NULL;
+ return CL_GetModelByIndex((int)ed->fields.client->modelindex);
+}
+
+void CL_LinkEdict(prvm_edict_t *ent)
+{
+ if (ent == prog->edicts)
+ return; // don't add the world
+
+ if (ent->priv.server->free)
+ return;
+
+ VectorAdd(ent->fields.client->origin, ent->fields.client->mins, ent->fields.client->absmin);
+ VectorAdd(ent->fields.client->origin, ent->fields.client->maxs, ent->fields.client->absmax);
+
+ World_LinkEdict(&cl.world, ent, ent->fields.client->absmin, ent->fields.client->absmax);
}
+int CL_GenericHitSuperContentsMask(const prvm_edict_t *passedict)
+{
+ prvm_eval_t *val;
+ if (passedict)
+ {
+ val = PRVM_EDICTFIELDVALUE(passedict, prog->fieldoffsets.dphitcontentsmask);
+ if (val && val->_float)
+ return (int)val->_float;
+ else if (passedict->fields.client->solid == SOLID_SLIDEBOX)
+ {
+ if ((int)passedict->fields.client->flags & FL_MONSTER)
+ return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_MONSTERCLIP;
+ else
+ return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP;
+ }
+ else if (passedict->fields.client->solid == SOLID_CORPSE)
+ return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY;
+ else
+ return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE;
+ }
+ else
+ return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE;
+}
+
+/*
+==================
+CL_Move
+==================
+*/
+extern cvar_t sv_debugmove;
+trace_t CL_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities)
+{
+ vec3_t hullmins, hullmaxs;
+ int i;
+ int passedictprog;
+ qboolean pointtrace;
+ prvm_edict_t *traceowner, *touch;
+ trace_t trace;
+ // bounding box of entire move area
+ vec3_t clipboxmins, clipboxmaxs;
+ // size of the moving object
+ vec3_t clipmins, clipmaxs;
+ // size when clipping against monsters
+ vec3_t clipmins2, clipmaxs2;
+ // start and end origin of move
+ vec3_t clipstart, clipend;
+ // trace results
+ trace_t cliptrace;
+ // matrices to transform into/out of other entity's space
+ matrix4x4_t matrix, imatrix;
+ // model of other entity
+ model_t *model;
+ // list of entities to test for collisions
+ int numtouchedicts;
+ prvm_edict_t *touchedicts[MAX_EDICTS];
+
+ if (hitnetworkentity)
+ *hitnetworkentity = 0;
+
+ VectorCopy(start, clipstart);
+ VectorCopy(end, clipend);
+ VectorCopy(mins, clipmins);
+ VectorCopy(maxs, clipmaxs);
+ VectorCopy(mins, clipmins2);
+ VectorCopy(maxs, clipmaxs2);
+#if COLLISIONPARANOID >= 3
+ Con_Printf("move(%f %f %f,%f %f %f)", clipstart[0], clipstart[1], clipstart[2], clipend[0], clipend[1], clipend[2]);
+#endif
+
+ // clip to world
+ Collision_ClipToWorld(&cliptrace, cl.worldmodel, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask);
+ cliptrace.bmodelstartsolid = cliptrace.startsolid;
+ if (cliptrace.startsolid || cliptrace.fraction < 1)
+ cliptrace.ent = prog ? prog->edicts : NULL;
+ if (type == MOVE_WORLDONLY)
+ return cliptrace;
+
+ if (type == MOVE_MISSILE)
+ {
+ // LordHavoc: modified this, was = -15, now -= 15
+ for (i = 0;i < 3;i++)
+ {
+ clipmins2[i] -= 15;
+ clipmaxs2[i] += 15;
+ }
+ }
+
+ // get adjusted box for bmodel collisions if the world is q1bsp or hlbsp
+ if (cl.worldmodel && cl.worldmodel->brush.RoundUpToHullSize)
+ cl.worldmodel->brush.RoundUpToHullSize(cl.worldmodel, clipmins, clipmaxs, hullmins, hullmaxs);
+ else
+ {
+ VectorCopy(clipmins, hullmins);
+ VectorCopy(clipmaxs, hullmaxs);
+ }
+
+ // create the bounding box of the entire move
+ for (i = 0;i < 3;i++)
+ {
+ clipboxmins[i] = min(clipstart[i], cliptrace.endpos[i]) + min(hullmins[i], clipmins2[i]) - 1;
+ clipboxmaxs[i] = max(clipstart[i], cliptrace.endpos[i]) + max(hullmaxs[i], clipmaxs2[i]) + 1;
+ }
+
+ // debug override to test against everything
+ if (sv_debugmove.integer)
+ {
+ clipboxmins[0] = clipboxmins[1] = clipboxmins[2] = -999999999;
+ clipboxmaxs[0] = clipboxmaxs[1] = clipboxmaxs[2] = 999999999;
+ }
+
+ // if the passedict is world, make it NULL (to avoid two checks each time)
+ // this checks prog because this function is often called without a CSQC
+ // VM context
+ if (prog == NULL || passedict == prog->edicts)
+ passedict = NULL;
+ // precalculate prog value for passedict for comparisons
+ passedictprog = prog != NULL ? PRVM_EDICT_TO_PROG(passedict) : 0;
+ // figure out whether this is a point trace for comparisons
+ pointtrace = VectorCompare(clipmins, clipmaxs);
+ // precalculate passedict's owner edict pointer for comparisons
+ traceowner = passedict ? PRVM_PROG_TO_EDICT(passedict->fields.client->owner) : 0;
+
+ // collide against network entities
+ if (hitnetworkbrushmodels)
+ {
+ for (i = 0;i < cl.num_brushmodel_entities;i++)
+ {
+ entity_render_t *ent = &cl.entities[cl.brushmodel_entities[i]].render;
+ if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs))
+ continue;
+ Collision_ClipToGenericEntity(&trace, ent->model, ent->frame, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, mins, maxs, end, hitsupercontentsmask);
+ if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
+ *hitnetworkentity = cl.brushmodel_entities[i];
+ Collision_CombineTraces(&cliptrace, &trace, NULL, true);
+ }
+ }
+
+ // collide against player entities
+ if (hitnetworkplayers)
+ {
+ vec3_t origin, entmins, entmaxs;
+ matrix4x4_t entmatrix, entinversematrix;
+ for (i = 1;i < cl.maxclients+1;i++)
+ {
+ entity_render_t *ent = &cl.entities[i].render;
+ // don't hit ourselves
+ if (i == cl.playerentity)
+ continue;
+ Matrix4x4_OriginFromMatrix(&ent->matrix, origin);
+ VectorAdd(origin, cl.playerstandmins, entmins);
+ VectorAdd(origin, cl.playerstandmaxs, entmaxs);
+ if (!BoxesOverlap(clipboxmins, clipboxmaxs, entmins, entmaxs))
+ continue;
+ Matrix4x4_CreateTranslate(&entmatrix, origin[0], origin[1], origin[2]);
+ Matrix4x4_CreateTranslate(&entinversematrix, -origin[0], -origin[1], -origin[2]);
+ Collision_ClipToGenericEntity(&trace, NULL, 0, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, mins, maxs, end, hitsupercontentsmask);
+ if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
+ *hitnetworkentity = i;
+ Collision_CombineTraces(&cliptrace, &trace, NULL, false);
+ }
+ }
+
+ // 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
+ // note: if prog is NULL then there won't be any linked entities
+ numtouchedicts = 0;
+ if (hitcsqcentities && prog != NULL)
+ {
+ numtouchedicts = World_EntitiesInBox(&cl.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
+ if (numtouchedicts > MAX_EDICTS)
+ {
+ // this never happens
+ Con_Printf("CL_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
+ numtouchedicts = MAX_EDICTS;
+ }
+ }
+ for (i = 0;i < numtouchedicts;i++)
+ {
+ touch = touchedicts[i];
+
+ if (touch->fields.client->solid < SOLID_BBOX)
+ continue;
+ if (type == MOVE_NOMONSTERS && touch->fields.client->solid != SOLID_BSP)
+ continue;
+
+ if (passedict)
+ {
+ // don't clip against self
+ if (passedict == touch)
+ continue;
+ // don't clip owned entities against owner
+ if (traceowner == touch)
+ continue;
+ // don't clip owner against owned entities
+ if (passedictprog == touch->fields.client->owner)
+ continue;
+ // don't clip points against points (they can't collide)
+ if (pointtrace && VectorCompare(touch->fields.client->mins, touch->fields.client->maxs) && (type != MOVE_MISSILE || !((int)touch->fields.client->flags & FL_MONSTER)))
+ continue;
+ }
+
+ // might interact, so do an exact clip
+ model = NULL;
+ if ((int) touch->fields.client->solid == SOLID_BSP || type == MOVE_HITMODEL)
+ {
+ unsigned int modelindex = (unsigned int)touch->fields.client->modelindex;
+ // if the modelindex is 0, it shouldn't be SOLID_BSP!
+ if (modelindex > 0 && modelindex < MAX_MODELS)
+ model = CL_GetModelByIndex((int)touch->fields.client->modelindex);
+ Matrix4x4_CreateFromQuakeEntity(&matrix, touch->fields.client->origin[0], touch->fields.client->origin[1], touch->fields.client->origin[2], touch->fields.client->angles[0], touch->fields.client->angles[1], touch->fields.client->angles[2], 1);
+ }
+ else
+ Matrix4x4_CreateTranslate(&matrix, touch->fields.client->origin[0], touch->fields.client->origin[1], touch->fields.client->origin[2]);
+ Matrix4x4_Invert_Simple(&imatrix, &matrix);
+ if ((int)touch->fields.client->flags & FL_MONSTER)
+ Collision_ClipToGenericEntity(&trace, model, touch->fields.client->frame, touch->fields.client->mins, touch->fields.client->maxs, SUPERCONTENTS_BODY, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask);
+ else
+ Collision_ClipToGenericEntity(&trace, model, touch->fields.client->frame, touch->fields.client->mins, touch->fields.client->maxs, SUPERCONTENTS_BODY, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask);
+ if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
+ *hitnetworkentity = 0;
+ Collision_CombineTraces(&cliptrace, &trace, (void *)touch, touch->fields.client->solid == SOLID_BSP);
+ }
+
+ return cliptrace;
+}
#ifndef CL_COLLISION_H
#define CL_COLLISION_H
-trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitbmodels, int *hitent, int hitsupercontentsmask, qboolean hitplayers);
float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int *hitent, entity_render_t *ignoreent);
void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius);
-int CL_PointSuperContents(const vec3_t p);
+
+model_t *CL_GetModelByIndex(int modelindex);
+model_t *CL_GetModelFromEdict(prvm_edict_t *ed);
+
+void CL_LinkEdict(prvm_edict_t *ent);
+int CL_GenericHitSuperContentsMask(const prvm_edict_t *edict);
+trace_t CL_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities);
+#define CL_PointSuperContents(point) (CL_Move((point), vec3_origin, vec3_origin, (point), sv_gameplayfix_swiminbmodels.integer ? MOVE_NOMONSTERS : MOVE_WORLDONLY, NULL, 0, true, false, NULL, true).startsupercontents)
#endif
for (i = 0;i < NUMOFFSETS;i++)
{
VectorAdd(offsets[i], s->origin, neworigin);
- if (!CL_TraceBox(neworigin, cl.playercrouchmins, cl.playercrouchmaxs, neworigin, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true).startsolid)
+ if (!CL_Move(neworigin, cl.playercrouchmins, cl.playercrouchmaxs, neworigin, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, false).startsolid)
{
VectorCopy(neworigin, s->origin);
return true;
// low ceiling first
if (s->crouched)
{
- trace = CL_TraceBox(s->origin, cl.playerstandmins, cl.playerstandmaxs, s->origin, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true);
+ trace = CL_Move(s->origin, cl.playerstandmins, cl.playerstandmaxs, s->origin, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, false);
if (!trace.startsolid)
s->crouched = false;
}
// set onground
VectorSet(origin1, s->origin[0], s->origin[1], s->origin[2] + 1);
VectorSet(origin2, s->origin[0], s->origin[1], s->origin[2] - 2);
- trace = CL_TraceBox(origin1, s->mins, s->maxs, origin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true);
+ trace = CL_Move(origin1, s->mins, s->maxs, origin2, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, false);
s->onground = trace.fraction < 1 && trace.plane.normal[2] > 0.7 && s->velocity[2] < cl_gravity.value * s->q.frametime;
// set watertype/waterlevel
VectorSet(origin1, s->origin[0], s->origin[1], s->origin[2] + s->mins[2] + 1);
s->waterlevel = WATERLEVEL_NONE;
- s->watertype = CL_TraceBox(origin1, vec3_origin, vec3_origin, origin1, true, NULL, 0, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK;
+ s->watertype = CL_Move(origin1, vec3_origin, vec3_origin, origin1, MOVE_NOMONSTERS, NULL, 0, true, false, NULL, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK;
if (s->watertype)
{
s->waterlevel = WATERLEVEL_WETFEET;
origin1[2] = s->origin[2] + (s->mins[2] + s->maxs[2]) * 0.5f;
- if (CL_TraceBox(origin1, vec3_origin, vec3_origin, origin1, true, NULL, 0, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK)
+ if (CL_Move(origin1, vec3_origin, vec3_origin, origin1, MOVE_NOMONSTERS, NULL, 0, true, false, NULL, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK)
{
s->waterlevel = WATERLEVEL_SWIMMING;
origin1[2] = s->origin[2] + 22;
- if (CL_TraceBox(origin1, vec3_origin, vec3_origin, origin1, true, NULL, 0, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK)
+ if (CL_Move(origin1, vec3_origin, vec3_origin, origin1, MOVE_NOMONSTERS, NULL, 0, true, false, NULL, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK)
s->waterlevel = WATERLEVEL_SUBMERGED;
}
}
for (bump = 0, t = s->q.frametime;bump < 8 && VectorLength2(s->velocity) > 0;bump++)
{
VectorMA(s->origin, t, s->velocity, neworigin);
- trace = CL_TraceBox(s->origin, s->mins, s->maxs, neworigin, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true);
+ trace = CL_Move(s->origin, s->mins, s->maxs, neworigin, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, false);
if (trace.fraction < 1 && trace.plane.normal[2] == 0)
{
// may be a step or wall, try stepping up
// first move forward at a higher level
VectorSet(currentorigin2, s->origin[0], s->origin[1], s->origin[2] + s->movevars_stepheight);
VectorSet(neworigin2, neworigin[0], neworigin[1], s->origin[2] + s->movevars_stepheight);
- trace2 = CL_TraceBox(currentorigin2, s->mins, s->maxs, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true);
+ trace2 = CL_Move(currentorigin2, s->mins, s->maxs, neworigin2, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, false);
if (!trace2.startsolid)
{
// then move down from there
VectorCopy(trace2.endpos, currentorigin2);
VectorSet(neworigin2, trace2.endpos[0], trace2.endpos[1], s->origin[2]);
- trace3 = CL_TraceBox(currentorigin2, s->mins, s->maxs, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true);
+ trace3 = CL_Move(currentorigin2, s->mins, s->maxs, neworigin2, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, false);
//Con_Printf("%f %f %f %f : %f %f %f %f : %f %f %f %f\n", trace.fraction, trace.endpos[0], trace.endpos[1], trace.endpos[2], trace2.fraction, trace2.endpos[0], trace2.endpos[1], trace2.endpos[2], trace3.fraction, trace3.endpos[0], trace3.endpos[1], trace3.endpos[2]);
// accept the new trace if it made some progress
if (fabs(trace3.endpos[0] - trace.endpos[0]) >= 0.03125 || fabs(trace3.endpos[1] - trace.endpos[1]) >= 0.03125)
AngleVectors(yawangles, forward, NULL, NULL);
VectorMA(s->origin, 24, forward, spot);
spot[2] += 8;
- if (CL_TraceBox(spot, vec3_origin, vec3_origin, spot, true, NULL, 0, false).startsolid)
+ if (CL_Move(spot, vec3_origin, vec3_origin, spot, MOVE_NOMONSTERS, NULL, 0, true, false, NULL, false).startsolid)
{
spot[2] += 24;
- if (!CL_TraceBox(spot, vec3_origin, vec3_origin, spot, true, NULL, 0, false).startsolid)
+ if (!CL_Move(spot, vec3_origin, vec3_origin, spot, MOVE_NOMONSTERS, NULL, 0, true, false, NULL, false).startsolid)
{
VectorScale(forward, 50, s->velocity);
s->velocity[2] = 310;
VectorSet(neworigin2, s->origin[0] + s->velocity[0]*(16/f), s->origin[1] + s->velocity[1]*(16/f), s->origin[2] + s->mins[2]);
VectorSet(neworigin3, neworigin2[0], neworigin2[1], neworigin2[2] - 34);
if (cls.protocol == PROTOCOL_QUAKEWORLD)
- trace = CL_TraceBox(neworigin2, s->mins, s->maxs, neworigin3, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true);
+ trace = CL_Move(neworigin2, s->mins, s->maxs, neworigin3, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, false);
else
- trace = CL_TraceBox(neworigin2, vec3_origin, vec3_origin, neworigin3, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true);
+ trace = CL_Move(neworigin2, vec3_origin, vec3_origin, neworigin3, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, false);
if (trace.fraction == 1 && !trace.startsolid)
friction *= s->movevars_edgefriction;
}
trace_t trace;
matrix4x4_t tempmatrix;
Matrix4x4_Transform(&e->render.matrix, muzzleflashorigin, v2);
- trace = CL_TraceBox(origin, vec3_origin, vec3_origin, v2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, false);
+ trace = CL_Move(origin, vec3_origin, vec3_origin, v2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, true, false, NULL, false);
Matrix4x4_Normalize(&tempmatrix, &e->render.matrix);
Matrix4x4_SetOrigin(&tempmatrix, trace.endpos[0], trace.endpos[1], trace.endpos[2]);
Matrix4x4_Scale(&tempmatrix, 150, 1);
{
VectorRandom(org2);
VectorMA(org, maxdist, org2, org2);
- trace = CL_TraceBox(org, vec3_origin, vec3_origin, org2, true, &hitent, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, false);
+ trace = CL_Move(org, vec3_origin, vec3_origin, org2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, true, false, &hitent, false);
// take the closest trace result that doesn't end up hitting a NOMARKS
// surface (sky for example)
if (bestfrac > trace.fraction && !(trace.hitq3surfaceflags & Q3SURFACEFLAG_NOMARKS))
v[0] = org[0] + lhrandom(-48, 48);
v[1] = org[1] + lhrandom(-48, 48);
v[2] = org[2] + lhrandom(-48, 48);
- trace = CL_TraceBox(org, vec3_origin, vec3_origin, v, true, NULL, SUPERCONTENTS_SOLID, false);
+ trace = CL_Move(org, vec3_origin, vec3_origin, v, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false);
if (trace.fraction >= 0.1)
break;
}
VectorCopy(p->org, org);
if (p->bounce)
{
- trace = CL_TraceBox(oldorg, vec3_origin, vec3_origin, p->org, true, &hitent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | (p->type == particletype + pt_rain ? SUPERCONTENTS_LIQUIDSMASK : 0), false);
+ trace = CL_Move(oldorg, vec3_origin, vec3_origin, p->org, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | (p->type == particletype + pt_rain ? SUPERCONTENTS_LIQUIDSMASK : 0), true, false, &hitent, false);
// if the trace started in or hit something of SUPERCONTENTS_NODROP
// or if the trace hit something flagged as NOIMPACT
// then remove the particle
//4 feature darkplaces csqc: add builtins to clientside qc for gl calls
sfx_t *S_FindName(const char *name);
-void PF_registercvar (void);
int Sbar_GetPlayer (int index);
void Sbar_SortFrags (void);
void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius);
void CSQC_RelinkAllEntities (int drawmask);
void CSQC_RelinkCSQCEntities (void);
char *Key_GetBind (int key);
-model_t *CSQC_GetModelByIndex(int modelindex);
-model_t *CSQC_GetModelFromEntity(prvm_edict_t *ed);
-void CL_LinkEdict(prvm_edict_t *ed);
// #1 void(vector ang) makevectors
-void VM_CL_makevectors (void)
+static void VM_CL_makevectors (void)
{
VM_SAFEPARMCOUNT(1, VM_CL_makevectors);
AngleVectors (PRVM_G_VECTOR(OFS_PARM0), prog->globals.client->v_forward, prog->globals.client->v_right, prog->globals.client->v_up);
}
// #2 void(entity e, vector o) setorigin
-void VM_CL_setorigin (void)
+static void VM_CL_setorigin (void)
{
prvm_edict_t *e;
float *org;
+ VM_SAFEPARMCOUNT(2, VM_CL_setorigin);
e = PRVM_G_EDICT(OFS_PARM0);
if (e == prog->edicts)
}
// #3 void(entity e, string m) setmodel
-void VM_CL_setmodel (void)
+static void VM_CL_setmodel (void)
{
prvm_edict_t *e;
const char *m;
}
// #4 void(entity e, vector min, vector max) setsize
-void VM_CL_setsize (void)
+static void VM_CL_setsize (void)
{
prvm_edict_t *e;
float *min, *max;
CL_LinkEdict(e);
}
-// #8 void(entity e, float chan, string samp) sound
-void VM_CL_sound (void)
+// #8 void(entity e, float chan, string samp, float volume, float atten) sound
+static void VM_CL_sound (void)
{
const char *sample;
int channel;
}
// #14 entity() spawn
-void VM_CL_spawn (void)
+static void VM_CL_spawn (void)
{
prvm_edict_t *ed;
ed = PRVM_ED_Alloc();
VM_RETURN_EDICT(ed);
}
-// #16 float(vector v1, vector v2, float tryents) traceline
-void VM_CL_traceline (void)
+// #16 float(vector v1, vector v2, float movetype, entity ignore) traceline
+static void VM_CL_traceline (void)
{
float *v1, *v2;
trace_t trace;
- int ent;
+ int move;
+ prvm_edict_t *ent;
+
+ VM_SAFEPARMCOUNTRANGE(4, 8, VM_CL_traceline); // allow more parameters for future expansion
+
+ prog->xfunction->builtinsprofile += 30;
v1 = PRVM_G_VECTOR(OFS_PARM0);
v2 = PRVM_G_VECTOR(OFS_PARM1);
+ move = (int)PRVM_G_FLOAT(OFS_PARM2);
+ ent = PRVM_G_EDICT(OFS_PARM3);
+
+ if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
+ PRVM_ERROR("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
+
+ trace = CL_Move(v1, vec3_origin, vec3_origin, v2, move, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
+
+ VM_SetTraceGlobals(&trace);
+}
+
+/*
+=================
+VM_CL_tracebox
+
+Used for use tracing and shot targeting
+Traces are blocked by bbox and exact bsp entityes, and also slide box entities
+if the tryents flag is set.
+
+tracebox (vector1, vector mins, vector maxs, vector2, tryents)
+=================
+*/
+// LordHavoc: added this for my own use, VERY useful, similar to traceline
+static void VM_CL_tracebox (void)
+{
+ float *v1, *v2, *m1, *m2;
+ trace_t trace;
+ int move;
+ prvm_edict_t *ent;
+
+ VM_SAFEPARMCOUNTRANGE(6, 8, VM_CL_tracebox); // allow more parameters for future expansion
+
+ prog->xfunction->builtinsprofile += 30;
+
+ v1 = PRVM_G_VECTOR(OFS_PARM0);
+ m1 = PRVM_G_VECTOR(OFS_PARM1);
+ m2 = PRVM_G_VECTOR(OFS_PARM2);
+ v2 = PRVM_G_VECTOR(OFS_PARM3);
+ move = (int)PRVM_G_FLOAT(OFS_PARM4);
+ ent = PRVM_G_EDICT(OFS_PARM5);
+
+ if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
+ PRVM_ERROR("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
- trace = CL_TraceBox(v1, vec3_origin, vec3_origin, v2, 1, &ent, 1, false);
-
- prog->globals.client->trace_allsolid = trace.allsolid;
- prog->globals.client->trace_startsolid = trace.startsolid;
- prog->globals.client->trace_fraction = trace.fraction;
- prog->globals.client->trace_inwater = trace.inwater;
- prog->globals.client->trace_inopen = trace.inopen;
- VectorCopy (trace.endpos, prog->globals.client->trace_endpos);
- VectorCopy (trace.plane.normal, prog->globals.client->trace_plane_normal);
- prog->globals.client->trace_plane_dist = trace.plane.dist;
- if (ent)
- prog->globals.client->trace_ent = ent;
+ trace = CL_Move(v1, m1, m2, v2, move, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
+
+ VM_SetTraceGlobals(&trace);
+}
+
+extern cvar_t cl_gravity;
+trace_t CL_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
+{
+ int i;
+ float gravity;
+ vec3_t move, end;
+ vec3_t original_origin;
+ vec3_t original_velocity;
+ vec3_t original_angles;
+ vec3_t original_avelocity;
+ prvm_eval_t *val;
+ trace_t trace;
+
+ VectorCopy(tossent->fields.client->origin , original_origin );
+ VectorCopy(tossent->fields.client->velocity , original_velocity );
+ VectorCopy(tossent->fields.client->angles , original_angles );
+ VectorCopy(tossent->fields.client->avelocity, original_avelocity);
+
+ val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
+ if (val != NULL && val->_float != 0)
+ gravity = val->_float;
else
- prog->globals.client->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
+ gravity = 1.0;
+ gravity *= cl_gravity.value * 0.05;
+
+ for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
+ {
+ tossent->fields.client->velocity[2] -= gravity;
+ VectorMA (tossent->fields.client->angles, 0.05, tossent->fields.client->avelocity, tossent->fields.client->angles);
+ VectorScale (tossent->fields.client->velocity, 0.05, move);
+ VectorAdd (tossent->fields.client->origin, move, end);
+ trace = CL_Move (tossent->fields.client->origin, tossent->fields.client->mins, tossent->fields.client->maxs, end, MOVE_NORMAL, tossent, CL_GenericHitSuperContentsMask(tossent), true, true, NULL, true);
+ VectorCopy (trace.endpos, tossent->fields.client->origin);
+
+ if (trace.fraction < 1)
+ break;
+ }
+
+ VectorCopy(original_origin , tossent->fields.client->origin );
+ VectorCopy(original_velocity , tossent->fields.client->velocity );
+ VectorCopy(original_angles , tossent->fields.client->angles );
+ VectorCopy(original_avelocity, tossent->fields.client->avelocity);
+
+ return trace;
}
-// #19 void(string s) precache_sound
-void VM_CL_precache_sound (void)
+static void VM_CL_tracetoss (void)
{
- VM_SAFEPARMCOUNT(1, VM_CL_precache_sound);
- S_PrecacheSound(PRVM_G_STRING(OFS_PARM0), true, false);
+ trace_t trace;
+ prvm_edict_t *ent;
+ prvm_edict_t *ignore;
+
+ prog->xfunction->builtinsprofile += 600;
+
+ VM_SAFEPARMCOUNT(2, VM_CL_tracetoss);
+
+ ent = PRVM_G_EDICT(OFS_PARM0);
+ if (ent == prog->edicts)
+ {
+ VM_Warning("tracetoss: can not use world entity\n");
+ return;
+ }
+ ignore = PRVM_G_EDICT(OFS_PARM1);
+
+ trace = CL_Trace_Toss (ent, ignore);
+
+ VM_SetTraceGlobals(&trace);
}
+
// #20 void(string s) precache_model
-void VM_CL_precache_model (void)
+static void VM_CL_precache_model (void)
{
const char *name;
int i;
}
// #22 entity(vector org, float rad) findradius
-void VM_CL_findradius (void)
+static void VM_CL_findradius (void)
{
prvm_edict_t *ent, *chain;
vec_t radius, radius2;
int i, numtouchedicts;
prvm_edict_t *touchedicts[MAX_EDICTS];
+ VM_SAFEPARMCOUNT(2, VM_CL_findradius);
+
chain = (prvm_edict_t *)prog->edicts;
VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
}
// #34 float() droptofloor
-void VM_CL_droptofloor (void)
+static void VM_CL_droptofloor (void)
{
prvm_edict_t *ent;
+ prvm_eval_t *val;
vec3_t end;
trace_t trace;
- int i;
+
+ VM_SAFEPARMCOUNTRANGE(0, 2, VM_CL_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
// assume failure if it returns early
PRVM_G_FLOAT(OFS_RETURN) = 0;
VectorCopy (ent->fields.client->origin, end);
end[2] -= 256;
- trace = CL_TraceBox(ent->fields.client->origin, ent->fields.client->mins, ent->fields.client->maxs, end, 1, &i, 1, false);
+ trace = CL_Move(ent->fields.client->origin, ent->fields.client->mins, ent->fields.client->maxs, end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
if (trace.fraction != 1)
{
VectorCopy (trace.endpos, ent->fields.client->origin);
ent->fields.client->flags = (int)ent->fields.client->flags | FL_ONGROUND;
-// ent->fields.client->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
+ if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.groundentity)))
+ val->edict = PRVM_EDICT_TO_PROG(trace.ent);
PRVM_G_FLOAT(OFS_RETURN) = 1;
// if support is destroyed, keep suspended (gross hack for floating items in various maps)
// ent->priv.server->suspendedinairflag = true;
}
// #35 void(float style, string value) lightstyle
-void VM_CL_lightstyle (void)
+static void VM_CL_lightstyle (void)
{
int i;
const char *c;
}
// #40 float(entity e) checkbottom
-void VM_CL_checkbottom (void)
+static void VM_CL_checkbottom (void)
{
static int cs_yes, cs_no;
prvm_edict_t *ent;
vec3_t mins, maxs, start, stop;
trace_t trace;
- int x, y, hit;
+ int x, y;
float mid, bottom;
VM_SAFEPARMCOUNT(1, VM_CL_checkbottom);
start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
stop[2] = start[2] - 2*sv_stepheight.value;
- trace = CL_TraceBox (start, vec3_origin, vec3_origin, stop, 1, &hit, 1, true);
+ trace = CL_Move (start, vec3_origin, vec3_origin, stop, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
if (trace.fraction == 1.0)
return;
start[0] = stop[0] = x ? maxs[0] : mins[0];
start[1] = stop[1] = y ? maxs[1] : mins[1];
- trace = CL_TraceBox (start, vec3_origin, vec3_origin, stop, 1, &hit, 1, true);
+ trace = CL_Move (start, vec3_origin, vec3_origin, stop, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
bottom = trace.endpos[2];
}
// #41 float(vector v) pointcontents
-void VM_CL_pointcontents (void)
+static void VM_CL_pointcontents (void)
{
VM_SAFEPARMCOUNT(1, VM_CL_pointcontents);
PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, CL_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
}
// #48 void(vector o, vector d, float color, float count) particle
-void VM_CL_particle (void)
+static void VM_CL_particle (void)
{
float *org, *dir;
int count;
CL_ParticleEffect(EFFECT_SVC_PARTICLE, count, org, org, dir, dir, NULL, color);
}
-// #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS)
-void VM_CL_tracetoss (void)
-{
-/* trace_t trace;
- prvm_edict_t *ent;
- prvm_edict_t *ignore;
-
- ent = PRVM_G_EDICT(OFS_PARM0);
- if (ent == prog->edicts)
- {
- VM_Warning("tracetoss: can not use world entity\n");
- return;
- }
- ignore = PRVM_G_EDICT(OFS_PARM1);
-
-//FIXME
- trace = SV_Trace_Toss (ent, ignore);
-
- prog->globals.server->trace_allsolid = trace.allsolid;
- prog->globals.server->trace_startsolid = trace.startsolid;
- prog->globals.server->trace_fraction = trace.fraction;
- prog->globals.server->trace_inwater = trace.inwater;
- prog->globals.server->trace_inopen = trace.inopen;
- VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
- VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
- prog->globals.server->trace_plane_dist = trace.plane.dist;
- if (trace.ent)
- prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
- else
- prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
-*/
-}
-
// #74 void(vector pos, string samp, float vol, float atten) ambientsound
-void VM_CL_ambientsound (void)
+static void VM_CL_ambientsound (void)
{
float *f;
sfx_t *s;
S_StaticSound (s, f, PRVM_G_FLOAT(OFS_PARM2), PRVM_G_FLOAT(OFS_PARM3)*64);
}
-// #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
-void VM_CL_tracebox (void)
-{
- float *v1, *v2, *m1, *m2;
- trace_t trace;
- int ent;
-
- v1 = PRVM_G_VECTOR(OFS_PARM0);
- m1 = PRVM_G_VECTOR(OFS_PARM1);
- m2 = PRVM_G_VECTOR(OFS_PARM2);
- v2 = PRVM_G_VECTOR(OFS_PARM3);
-
- trace = CL_TraceBox(v1, m1, m2, v2, 1, &ent, 1, false);
-
- prog->globals.client->trace_allsolid = trace.allsolid;
- prog->globals.client->trace_startsolid = trace.startsolid;
- prog->globals.client->trace_fraction = trace.fraction;
- prog->globals.client->trace_inwater = trace.inwater;
- prog->globals.client->trace_inopen = trace.inopen;
- VectorCopy (trace.endpos, prog->globals.client->trace_endpos);
- VectorCopy (trace.plane.normal, prog->globals.client->trace_plane_normal);
- prog->globals.client->trace_plane_dist = trace.plane.dist;
- if (ent)
- prog->globals.client->trace_ent = ent;
- else
- prog->globals.client->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
-}
-
// #92 vector(vector org) getlight (DP_QC_GETLIGHT)
-void VM_CL_getlight (void)
+static void VM_CL_getlight (void)
{
vec3_t ambientcolor, diffusecolor, diffusenormal;
vec_t *p;
void CL_RelinkLightFlashes(void);
//#300 void() clearscene (EXT_CSQC)
-void VM_R_ClearScene (void)
+static void VM_CL_R_ClearScene (void)
{
- VM_SAFEPARMCOUNT(0, VM_R_ClearScene);
+ VM_SAFEPARMCOUNT(0, VM_CL_R_ClearScene);
// clear renderable entity and light lists
r_refdef.numentities = 0;
r_refdef.numlights = 0;
//#301 void(float mask) addentities (EXT_CSQC)
extern void CSQC_Predraw (prvm_edict_t *ed);//csprogs.c
extern void CSQC_Think (prvm_edict_t *ed);//csprogs.c
-void VM_R_AddEntities (void)
+static void VM_CL_R_AddEntities (void)
{
int i, drawmask;
prvm_edict_t *ed;
- VM_SAFEPARMCOUNT(1, VM_R_AddEntities);
+ VM_SAFEPARMCOUNT(1, VM_CL_R_AddEntities);
drawmask = (int)PRVM_G_FLOAT(OFS_PARM0);
CSQC_RelinkAllEntities(drawmask);
CL_RelinkLightFlashes();
}
//#302 void(entity ent) addentity (EXT_CSQC)
-void VM_R_AddEntity (void)
+static void VM_CL_R_AddEntity (void)
{
- VM_SAFEPARMCOUNT(1, VM_R_AddEntity);
+ VM_SAFEPARMCOUNT(1, VM_CL_R_AddEntity);
CSQC_AddRenderEdict(PRVM_G_EDICT(OFS_PARM0));
}
//#303 float(float property, ...) setproperty (EXT_CSQC)
-void VM_R_SetView (void)
+static void VM_CL_R_SetView (void)
{
int c;
float *f;
float k;
- if(prog->argc < 2)
- VM_SAFEPARMCOUNT(2, VM_R_SetView);
+ VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_R_SetView);
c = (int)PRVM_G_FLOAT(OFS_PARM0);
f = PRVM_G_VECTOR(OFS_PARM1);
break;
default: PRVM_G_FLOAT(OFS_RETURN) = 0;
- VM_Warning("VM_R_SetView : unknown parm %i\n", c);
+ VM_Warning("VM_CL_R_SetView : unknown parm %i\n", c);
return;
}
PRVM_G_FLOAT(OFS_RETURN) = 1;
extern void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit);
//#304 void() renderscene (EXT_CSQC)
-void VM_R_RenderScene (void) //#134
+static void VM_CL_R_RenderScene (void)
{
int i;
- VM_SAFEPARMCOUNT(0, VM_R_RenderScene);
+ VM_SAFEPARMCOUNT(0, VM_CL_R_RenderScene);
// we need to update any RENDER_VIEWMODEL entities at this point because
// csqc supplies its own view matrix
for (i = 1;i < cl.num_entities;i++)
}
//#305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
-void VM_R_AddDynamicLight (void)
+static void VM_CL_R_AddDynamicLight (void)
{
float *pos, *col;
matrix4x4_t matrix;
- VM_SAFEPARMCOUNT(3, VM_R_AddDynamicLight);
+ VM_SAFEPARMCOUNTRANGE(3, 8, VM_CL_R_AddDynamicLight); // allow more than 3 because we may extend this in the future
// if we've run out of dlights, just return
if (r_refdef.numlights >= MAX_DLIGHTS)
//============================================================================
//#310 vector (vector v) cs_unproject (EXT_CSQC)
-void VM_CL_unproject (void)
+static void VM_CL_unproject (void)
{
float *f;
vec3_t temp;
}
//#311 vector (vector v) cs_project (EXT_CSQC)
-void VM_CL_project (void)
+static void VM_CL_project (void)
{
float *f;
vec3_t v;
}
//#330 float(float stnum) getstatf (EXT_CSQC)
-void VM_CL_getstatf (void)
+static void VM_CL_getstatf (void)
{
int i;
union
}
//#331 float(float stnum) getstati (EXT_CSQC)
-void VM_CL_getstati (void)
+static void VM_CL_getstati (void)
{
int i, index;
VM_SAFEPARMCOUNT(1, VM_CL_getstati);
}
//#332 string(float firststnum) getstats (EXT_CSQC)
-void VM_CL_getstats (void)
+static void VM_CL_getstats (void)
{
int i;
char t[17];
}
//#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
-void VM_CL_setmodelindex (void)
+static void VM_CL_setmodelindex (void)
{
int i;
prvm_edict_t *t;
if (!i)
return;
- model = CSQC_GetModelByIndex(i);
+ model = CL_GetModelByIndex(i);
if (!model)
{
VM_Warning("VM_CL_setmodelindex: null model\n");
}
//#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
-void VM_CL_modelnameforindex (void)
+static void VM_CL_modelnameforindex (void)
{
model_t *model;
VM_SAFEPARMCOUNT(1, VM_CL_modelnameforindex);
PRVM_G_INT(OFS_RETURN) = OFS_NULL;
- model = CSQC_GetModelByIndex((int)PRVM_G_FLOAT(OFS_PARM0));
+ model = CL_GetModelByIndex((int)PRVM_G_FLOAT(OFS_PARM0));
PRVM_G_INT(OFS_RETURN) = model ? PRVM_SetEngineString(model->name) : 0;
}
//#335 float(string effectname) particleeffectnum (EXT_CSQC)
-void VM_CL_particleeffectnum (void)
+static void VM_CL_particleeffectnum (void)
{
int i;
VM_SAFEPARMCOUNT(1, VM_CL_particleeffectnum);
}
// #336 void(entity ent, float effectnum, vector start, vector end[, float color]) trailparticles (EXT_CSQC)
-void VM_CL_trailparticles (void)
+static void VM_CL_trailparticles (void)
{
int i;
float *start, *end;
prvm_edict_t *t;
- VM_SAFEPARMCOUNT(4, VM_CL_trailparticles);
+ VM_SAFEPARMCOUNTRANGE(4, 5, VM_CL_trailparticles);
t = PRVM_G_EDICT(OFS_PARM0);
i = (int)PRVM_G_FLOAT(OFS_PARM1);
start = PRVM_G_VECTOR(OFS_PARM2);
end = PRVM_G_VECTOR(OFS_PARM3);
- CL_ParticleEffect(i, VectorDistance(start, end), start, end, t->fields.client->velocity, t->fields.client->velocity, NULL, (int)PRVM_G_FLOAT(OFS_PARM4));
+ CL_ParticleEffect(i, VectorDistance(start, end), start, end, t->fields.client->velocity, t->fields.client->velocity, NULL, prog->argc >= 5 ? (int)PRVM_G_FLOAT(OFS_PARM4) : 0);
}
-//#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
-void VM_CL_pointparticles (void)
+//#337 void(float effectnum, vector origin, vector dir, float count[, float color]) pointparticles (EXT_CSQC)
+static void VM_CL_pointparticles (void)
{
int i, n;
float *f, *v;
- VM_SAFEPARMCOUNT(4, VM_CL_pointparticles);
+ VM_SAFEPARMCOUNTRANGE(4, 5, VM_CL_pointparticles);
i = (int)PRVM_G_FLOAT(OFS_PARM0);
f = PRVM_G_VECTOR(OFS_PARM1);
v = PRVM_G_VECTOR(OFS_PARM2);
n = (int)PRVM_G_FLOAT(OFS_PARM3);
- CL_ParticleEffect(i, n, f, f, v, v, NULL, 0);
-}
-
-//#338 void(string s) cprint (EXT_CSQC)
-void VM_CL_centerprint (void)
-{
- char s[VM_STRINGTEMP_LENGTH];
- if(prog->argc < 1)
- VM_SAFEPARMCOUNT(1, VM_CL_centerprint);
- VM_VarString(0, s, sizeof(s));
- SCR_CenterPrint(s);
+ CL_ParticleEffect(i, n, f, f, v, v, NULL, prog->argc >= 5 ? (int)PRVM_G_FLOAT(OFS_PARM4) : 0);
}
//#342 string(float keynum) getkeybind (EXT_CSQC)
-void VM_CL_getkeybind (void)
+static void VM_CL_getkeybind (void)
{
VM_SAFEPARMCOUNT(1, VM_CL_getkeybind);
PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Key_GetBind((int)PRVM_G_FLOAT(OFS_PARM0)));
}
//#343 void(float usecursor) setcursormode (EXT_CSQC)
-void VM_CL_setcursormode (void)
+static void VM_CL_setcursormode (void)
{
VM_SAFEPARMCOUNT(1, VM_CL_setcursormode);
cl.csqc_wantsmousemove = PRVM_G_FLOAT(OFS_PARM0);
}
//#345 float(float framenum) getinputstate (EXT_CSQC)
-void VM_CL_getinputstate (void)
+static void VM_CL_getinputstate (void)
{
int i, frame;
VM_SAFEPARMCOUNT(1, VM_CL_getinputstate);
}
//#346 void(float sens) setsensitivityscaler (EXT_CSQC)
-void VM_CL_setsensitivityscale (void)
+static void VM_CL_setsensitivityscale (void)
{
VM_SAFEPARMCOUNT(1, VM_CL_setsensitivityscale);
cl.sensitivityscale = PRVM_G_FLOAT(OFS_PARM0);
}
//#347 void() runstandardplayerphysics (EXT_CSQC)
-void VM_CL_runplayerphysics (void)
+static void VM_CL_runplayerphysics (void)
{
}
//#348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
-void VM_CL_getplayerkey (void)
+static void VM_CL_getplayerkey (void)
{
int i;
char t[128];
}
//#349 float() isdemo (EXT_CSQC)
-void VM_CL_isdemo (void)
+static void VM_CL_isdemo (void)
{
+ VM_SAFEPARMCOUNT(0, VM_CL_isdemo);
PRVM_G_FLOAT(OFS_RETURN) = cls.demoplayback;
}
//#351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
-void VM_CL_setlistener (void)
+static void VM_CL_setlistener (void)
{
VM_SAFEPARMCOUNT(4, VM_CL_setlistener);
Matrix4x4_FromVectors(&csqc_listenermatrix, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), PRVM_G_VECTOR(OFS_PARM3), PRVM_G_VECTOR(OFS_PARM0));
}
//#352 void(string cmdname) registercommand (EXT_CSQC)
-void VM_CL_registercmd (void)
+static void VM_CL_registercmd (void)
{
char *t;
VM_SAFEPARMCOUNT(1, VM_CL_registercmd);
}
-//#354 float() playernum (EXT_CSQC)
-void VM_CL_playernum (void)
-{
- int i, k;
-
- VM_SAFEPARMCOUNT(0, VM_CL_playernum);
-
- for(i=k=0 ; i<cl.maxclients ; i++)
- if(cl.scores[i].name[0])
- k++;
- PRVM_G_FLOAT(OFS_RETURN) = k;
-}
-
-//#355 float() cl_onground (EXT_CSQC)
-void VM_CL_onground (void)
-{
- PRVM_G_FLOAT(OFS_RETURN) = cl.onground;
-}
-
//#360 float() readbyte (EXT_CSQC)
-void VM_CL_ReadByte (void)
+static void VM_CL_ReadByte (void)
{
+ VM_SAFEPARMCOUNT(0, VM_CL_ReadByte);
PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadByte();
}
//#361 float() readchar (EXT_CSQC)
-void VM_CL_ReadChar (void)
+static void VM_CL_ReadChar (void)
{
+ VM_SAFEPARMCOUNT(0, VM_CL_ReadChar);
PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadChar();
}
//#362 float() readshort (EXT_CSQC)
-void VM_CL_ReadShort (void)
+static void VM_CL_ReadShort (void)
{
+ VM_SAFEPARMCOUNT(0, VM_CL_ReadShort);
PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadShort();
}
//#363 float() readlong (EXT_CSQC)
-void VM_CL_ReadLong (void)
+static void VM_CL_ReadLong (void)
{
+ VM_SAFEPARMCOUNT(0, VM_CL_ReadLong);
PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadLong();
}
//#364 float() readcoord (EXT_CSQC)
-void VM_CL_ReadCoord (void)
+static void VM_CL_ReadCoord (void)
{
+ VM_SAFEPARMCOUNT(0, VM_CL_ReadCoord);
PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadCoord(cls.protocol);
}
//#365 float() readangle (EXT_CSQC)
-void VM_CL_ReadAngle (void)
+static void VM_CL_ReadAngle (void)
{
+ VM_SAFEPARMCOUNT(0, VM_CL_ReadAngle);
PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadAngle(cls.protocol);
}
//#366 string() readstring (EXT_CSQC)
-void VM_CL_ReadString (void)
+static void VM_CL_ReadString (void)
{
+ VM_SAFEPARMCOUNT(0, VM_CL_ReadString);
PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(MSG_ReadString());
}
//#367 float() readfloat (EXT_CSQC)
-void VM_CL_ReadFloat (void)
+static void VM_CL_ReadFloat (void)
{
+ VM_SAFEPARMCOUNT(0, VM_CL_ReadFloat);
PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadFloat();
}
+//////////////////////////////////////////////////////////
+
+static void VM_CL_makestatic (void)
+{
+ prvm_edict_t *ent;
+
+ VM_SAFEPARMCOUNT(1, VM_CL_makestatic);
+
+ ent = PRVM_G_EDICT(OFS_PARM0);
+ if (ent == prog->edicts)
+ {
+ VM_Warning("makestatic: can not modify world entity\n");
+ return;
+ }
+ if (ent->priv.server->free)
+ {
+ VM_Warning("makestatic: can not modify free entity\n");
+ return;
+ }
+
+ if (cl.num_static_entities < cl.max_static_entities)
+ {
+ int renderflags;
+ prvm_eval_t *val;
+ entity_t *staticent = &cl.static_entities[cl.num_static_entities++];
+
+ // copy it to the current state
+ staticent->render.model = CL_GetModelByIndex((int)ent->fields.client->modelindex);
+ staticent->render.frame = staticent->render.frame1 = staticent->render.frame2 = (int)ent->fields.client->frame;
+ staticent->render.framelerp = 0;
+ // make torchs play out of sync
+ staticent->render.frame1time = staticent->render.frame2time = lhrandom(-10, -1);
+ staticent->render.colormap = (int)ent->fields.client->colormap; // no special coloring
+ staticent->render.skinnum = (int)ent->fields.client->skin;
+ staticent->render.effects = (int)ent->fields.client->effects;
+ staticent->render.alpha = 1;
+ if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.alpha)) && val->_float) staticent->render.alpha = val->_float;
+ staticent->render.scale = 1;
+ if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)) && val->_float) staticent->render.scale = val->_float;
+ if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.colormod)) && VectorLength2(val->vector)) VectorCopy(val->vector, staticent->render.colormod);
+
+ renderflags = 0;
+ if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.renderflags)) && val->_float) renderflags = (int)val->_float;
+ if (renderflags & RF_USEAXIS)
+ {
+ vec3_t left;
+ VectorNegate(prog->globals.client->v_right, left);
+ Matrix4x4_FromVectors(&staticent->render.matrix, prog->globals.client->v_forward, left, prog->globals.client->v_up, ent->fields.client->origin);
+ Matrix4x4_Scale(&staticent->render.matrix, staticent->render.scale, 1);
+ }
+ else
+ Matrix4x4_CreateFromQuakeEntity(&staticent->render.matrix, ent->fields.client->origin[0], ent->fields.client->origin[1], ent->fields.client->origin[2], ent->fields.client->angles[0], ent->fields.client->angles[1], ent->fields.client->angles[2], staticent->render.scale);
+ CL_UpdateRenderEntity(&staticent->render);
+
+ // transparent stuff can't be lit during the opaque stage
+ if (staticent->render.effects & (EF_ADDITIVE | EF_NODEPTHTEST) || staticent->render.alpha < 1)
+ staticent->render.flags |= RENDER_TRANSPARENT;
+ // double sided rendering mode causes backfaces to be visible
+ // (mostly useful on transparent stuff)
+ if (staticent->render.effects & EF_DOUBLESIDED)
+ staticent->render.flags |= RENDER_NOCULLFACE;
+ // either fullbright or lit
+ if (!(staticent->render.effects & EF_FULLBRIGHT) && !r_fullbright.integer)
+ staticent->render.flags |= RENDER_LIGHT;
+ // turn off shadows from transparent objects
+ if (!(staticent->render.effects & EF_NOSHADOW)
+ && !(staticent->render.flags & RENDER_TRANSPARENT))
+ staticent->render.flags |= RENDER_SHADOW;
+ }
+ else
+ Con_Printf("Too many static entities");
+
+// throw the entity away now
+ PRVM_ED_Free (ent);
+}
+
+//=================================================================//
+
+/*
+=================
+VM_CL_copyentity
+
+copies data from one entity to another
+
+copyentity(src, dst)
+=================
+*/
+static void VM_CL_copyentity (void)
+{
+ prvm_edict_t *in, *out;
+ VM_SAFEPARMCOUNT(2, VM_CL_copyentity);
+ in = PRVM_G_EDICT(OFS_PARM0);
+ if (in == prog->edicts)
+ {
+ VM_Warning("copyentity: can not read world entity\n");
+ return;
+ }
+ if (in->priv.server->free)
+ {
+ VM_Warning("copyentity: can not read free entity\n");
+ return;
+ }
+ out = PRVM_G_EDICT(OFS_PARM1);
+ if (out == prog->edicts)
+ {
+ VM_Warning("copyentity: can not modify world entity\n");
+ return;
+ }
+ if (out->priv.server->free)
+ {
+ VM_Warning("copyentity: can not modify free entity\n");
+ return;
+ }
+ memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
+ CL_LinkEdict(out);
+}
+
//=================================================================//
// #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
-void VM_CL_effect (void)
+static void VM_CL_effect (void)
{
VM_SAFEPARMCOUNT(5, VM_CL_effect);
CL_Effect(PRVM_G_VECTOR(OFS_PARM0), (int)PRVM_G_FLOAT(OFS_PARM1), (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), PRVM_G_FLOAT(OFS_PARM4));
}
// #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
-void VM_CL_te_blood (void)
+static void VM_CL_te_blood (void)
{
float *pos;
vec3_t pos2;
}
// #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
-void VM_CL_te_bloodshower (void)
+static void VM_CL_te_bloodshower (void)
{
vec_t speed;
vec3_t vel1, vel2;
}
// #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
-void VM_CL_te_explosionrgb (void)
+static void VM_CL_te_explosionrgb (void)
{
float *pos;
vec3_t pos2;
}
// #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE)
-void VM_CL_te_particlecube (void)
+static void VM_CL_te_particlecube (void)
{
VM_SAFEPARMCOUNT(7, VM_CL_te_particlecube);
CL_ParticleCube(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), PRVM_G_FLOAT(OFS_PARM5), PRVM_G_FLOAT(OFS_PARM6));
}
// #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
-void VM_CL_te_particlerain (void)
+static void VM_CL_te_particlerain (void)
{
VM_SAFEPARMCOUNT(5, VM_CL_te_particlerain);
CL_ParticleRain(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), 0);
}
// #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
-void VM_CL_te_particlesnow (void)
+static void VM_CL_te_particlesnow (void)
{
VM_SAFEPARMCOUNT(5, VM_CL_te_particlesnow);
CL_ParticleRain(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), 1);
}
// #411 void(vector org, vector vel, float howmany) te_spark
-void VM_CL_te_spark (void)
+static void VM_CL_te_spark (void)
{
float *pos;
vec3_t pos2;
}
// #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
-void VM_CL_te_gunshotquad (void)
+static void VM_CL_te_gunshotquad (void)
{
float *pos;
vec3_t pos2;
}
// #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
-void VM_CL_te_spikequad (void)
+static void VM_CL_te_spikequad (void)
{
float *pos;
vec3_t pos2;
}
// #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
-void VM_CL_te_superspikequad (void)
+static void VM_CL_te_superspikequad (void)
{
float *pos;
vec3_t pos2;
}
// #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
-void VM_CL_te_explosionquad (void)
+static void VM_CL_te_explosionquad (void)
{
float *pos;
vec3_t pos2;
}
// #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
-void VM_CL_te_smallflash (void)
+static void VM_CL_te_smallflash (void)
{
float *pos;
vec3_t pos2;
}
// #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
-void VM_CL_te_customflash (void)
+static void VM_CL_te_customflash (void)
{
float *pos;
vec3_t pos2;
}
// #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
-void VM_CL_te_gunshot (void)
+static void VM_CL_te_gunshot (void)
{
float *pos;
vec3_t pos2;
}
// #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
-void VM_CL_te_spike (void)
+static void VM_CL_te_spike (void)
{
float *pos;
vec3_t pos2;
}
// #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
-void VM_CL_te_superspike (void)
+static void VM_CL_te_superspike (void)
{
float *pos;
vec3_t pos2;
}
// #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
-void VM_CL_te_explosion (void)
+static void VM_CL_te_explosion (void)
{
float *pos;
vec3_t pos2;
}
// #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
-void VM_CL_te_tarexplosion (void)
+static void VM_CL_te_tarexplosion (void)
{
float *pos;
vec3_t pos2;
}
// #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
-void VM_CL_te_wizspike (void)
+static void VM_CL_te_wizspike (void)
{
float *pos;
vec3_t pos2;
}
// #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
-void VM_CL_te_knightspike (void)
+static void VM_CL_te_knightspike (void)
{
float *pos;
vec3_t pos2;
}
// #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
-void VM_CL_te_lavasplash (void)
+static void VM_CL_te_lavasplash (void)
{
VM_SAFEPARMCOUNT(1, VM_CL_te_lavasplash);
CL_ParticleEffect(EFFECT_TE_LAVASPLASH, 1, PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM0), vec3_origin, vec3_origin, NULL, 0);
}
// #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
-void VM_CL_te_teleport (void)
+static void VM_CL_te_teleport (void)
{
VM_SAFEPARMCOUNT(1, VM_CL_te_teleport);
CL_ParticleEffect(EFFECT_TE_TELEPORT, 1, PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM0), vec3_origin, vec3_origin, NULL, 0);
}
// #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
-void VM_CL_te_explosion2 (void)
+static void VM_CL_te_explosion2 (void)
{
float *pos;
vec3_t pos2, color;
// #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
-void VM_CL_te_lightning1 (void)
+static void VM_CL_te_lightning1 (void)
{
VM_SAFEPARMCOUNT(3, VM_CL_te_lightning1);
CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt, true);
}
// #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
-void VM_CL_te_lightning2 (void)
+static void VM_CL_te_lightning2 (void)
{
VM_SAFEPARMCOUNT(3, VM_CL_te_lightning2);
CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt2, true);
}
// #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
-void VM_CL_te_lightning3 (void)
+static void VM_CL_te_lightning3 (void)
{
VM_SAFEPARMCOUNT(3, VM_CL_te_lightning3);
CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt3, false);
}
// #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
-void VM_CL_te_beam (void)
+static void VM_CL_te_beam (void)
{
VM_SAFEPARMCOUNT(3, VM_CL_te_beam);
CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_beam, false);
}
// #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
-void VM_CL_te_plasmaburn (void)
+static void VM_CL_te_plasmaburn (void)
{
float *pos;
vec3_t pos2;
CL_ParticleEffect(EFFECT_TE_PLASMABURN, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
}
+// #457 void(vector org, vector velocity, float howmany) te_flamejet (DP_TE_FLAMEJET)
+static void VM_CL_te_flamejet (void)
+{
+ float *pos;
+ vec3_t pos2;
+ VM_SAFEPARMCOUNT(3, VM_CL_te_flamejet);
+ if (PRVM_G_FLOAT(OFS_PARM2) < 1)
+ return;
+ pos = PRVM_G_VECTOR(OFS_PARM0);
+ CL_FindNonSolidLocation(pos, pos2, 4);
+ CL_ParticleEffect(EFFECT_TE_FLAMEJET, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM1), NULL, 0);
+}
+
//====================================================================
//DP_QC_GETSURFACE
}
// #434 float(entity e, float s) getsurfacenumpoints
-void VM_CL_getsurfacenumpoints(void)
+static void VM_CL_getsurfacenumpoints(void)
{
- model_t *model = CSQC_GetModelFromEntity(PRVM_G_EDICT(OFS_PARM0));
+ model_t *model;
msurface_t *surface;
+ VM_SAFEPARMCOUNT(2, VM_CL_getsurfacenumpoints);
// return 0 if no such surface
- if (!model || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+ if (!(model = CL_GetModelFromEdict(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
{
PRVM_G_FLOAT(OFS_RETURN) = 0;
return;
}
// #435 vector(entity e, float s, float n) getsurfacepoint
-void VM_CL_getsurfacepoint(void)
+static void VM_CL_getsurfacepoint(void)
{
prvm_edict_t *ed;
model_t *model;
msurface_t *surface;
int pointnum;
+ VM_SAFEPARMCOUNT(3, VM_CL_getsurfacenumpoints);
VectorClear(PRVM_G_VECTOR(OFS_RETURN));
ed = PRVM_G_EDICT(OFS_PARM0);
- if (!(model = CSQC_GetModelFromEntity(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+ if (!(model = CL_GetModelFromEdict(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
return;
// note: this (incorrectly) assumes it is a simple polygon
pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
}
// #436 vector(entity e, float s) getsurfacenormal
-void VM_CL_getsurfacenormal(void)
+static void VM_CL_getsurfacenormal(void)
{
model_t *model;
msurface_t *surface;
vec3_t normal;
+ VM_SAFEPARMCOUNT(2, VM_CL_getsurfacenormal);
VectorClear(PRVM_G_VECTOR(OFS_RETURN));
- if (!(model = CSQC_GetModelFromEntity(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+ if (!(model = CL_GetModelFromEdict(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
return;
// FIXME: implement rotation/scaling
// note: this (incorrectly) assumes it is a simple polygon
}
// #437 string(entity e, float s) getsurfacetexture
-void VM_CL_getsurfacetexture(void)
+static void VM_CL_getsurfacetexture(void)
{
model_t *model;
msurface_t *surface;
+ VM_SAFEPARMCOUNT(2, VM_CL_getsurfacetexture);
PRVM_G_INT(OFS_RETURN) = OFS_NULL;
- if (!(model = CSQC_GetModelFromEntity(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+ if (!(model = CL_GetModelFromEdict(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
return;
PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
}
// #438 float(entity e, vector p) getsurfacenearpoint
-void VM_CL_getsurfacenearpoint(void)
+static void VM_CL_getsurfacenearpoint(void)
{
int surfacenum, best;
vec3_t clipped, p;
model_t *model = NULL;
msurface_t *surface;
vec_t *point;
+ VM_SAFEPARMCOUNT(2, VM_CL_getsurfacenearpoint);
PRVM_G_FLOAT(OFS_RETURN) = -1;
ed = PRVM_G_EDICT(OFS_PARM0);
- if(!(model = CSQC_GetModelFromEntity(ed)) || !model->num_surfaces)
+ if(!(model = CL_GetModelFromEdict(ed)) || !model->num_surfaces)
return;
// FIXME: implement rotation/scaling
}
// #439 vector(entity e, float s, vector p) getsurfaceclippedpoint
-void VM_CL_getsurfaceclippedpoint(void)
+static void VM_CL_getsurfaceclippedpoint(void)
{
prvm_edict_t *ed;
model_t *model;
msurface_t *surface;
vec3_t p, out;
+ VM_SAFEPARMCOUNT(3, VM_CL_getsurfaceclippedpoint);
VectorClear(PRVM_G_VECTOR(OFS_RETURN));
ed = PRVM_G_EDICT(OFS_PARM0);
- if (!(model = CSQC_GetModelFromEntity(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
+ if (!(model = CL_GetModelFromEdict(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
return;
// FIXME: implement rotation/scaling
VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.client->origin, p);
}
// #443 void(entity e, entity tagentity, string tagname) setattachment
-void VM_CL_setattachment (void)
+static void VM_CL_setattachment (void)
{
- prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
- prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
- const char *tagname = PRVM_G_STRING(OFS_PARM2);
+ prvm_edict_t *e;
+ prvm_edict_t *tagentity;
+ const char *tagname;
prvm_eval_t *v;
int modelindex;
model_t *model;
+ VM_SAFEPARMCOUNT(3, VM_CL_setattachment);
+
+ e = PRVM_G_EDICT(OFS_PARM0);
+ tagentity = PRVM_G_EDICT(OFS_PARM1);
+ tagname = PRVM_G_STRING(OFS_PARM2);
if (e == prog->edicts)
{
if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
{
modelindex = (int)tagentity->fields.client->modelindex;
- model = CSQC_GetModelByIndex(modelindex);
+ model = CL_GetModelByIndex(modelindex);
if (model)
{
v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.client->skin, tagname);
int CL_GetTagIndex (prvm_edict_t *e, const char *tagname)
{
- model_t *model = CSQC_GetModelFromEntity(e);
+ model_t *model = CL_GetModelFromEdict(e);
if (model)
return Mod_Alias_GetTagIndexForName(model, (int)e->fields.client->skin, tagname);
else
if (ent->priv.server->free)
return 2;
- model = CSQC_GetModelFromEntity(ent);
+ model = CL_GetModelFromEdict(ent);
if(!model)
return 3;
attachent = PRVM_EDICT_NUM(val->edict); // to this it entity our entity is attached
val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index);
- model = CSQC_GetModelFromEntity(attachent);
+ model = CL_GetModelFromEdict(attachent);
if (model && val->_float >= 1 && model->animscenes && attachent->fields.client->frame >= 0 && attachent->fields.client->frame < model->numframes)
Mod_Alias_GetTagMatrix(model, model->animscenes[(int)attachent->fields.client->frame].firstframe, (int)val->_float - 1, &attachmatrix);
}
// #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
-void VM_CL_gettagindex (void)
+static void VM_CL_gettagindex (void)
{
- prvm_edict_t *ent = PRVM_G_EDICT(OFS_PARM0);
- const char *tag_name = PRVM_G_STRING(OFS_PARM1);
+ prvm_edict_t *ent;
+ const char *tag_name;
int modelindex, tag_index;
+ VM_SAFEPARMCOUNT(2, VM_CL_gettagindex);
+
+ ent = PRVM_G_EDICT(OFS_PARM0);
+ tag_name = PRVM_G_STRING(OFS_PARM1);
if (ent == prog->edicts)
{
VM_Warning("gettagindex: can't affect world entity\n");
}
// #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
-void VM_CL_gettaginfo (void)
+static void VM_CL_gettaginfo (void)
{
- prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
- int tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
+ prvm_edict_t *e;
+ int tagindex;
matrix4x4_t tag_matrix;
int returncode;
+ VM_SAFEPARMCOUNT(2, VM_CL_gettaginfo);
+
+ e = PRVM_G_EDICT(OFS_PARM0);
+ tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
returncode = CL_GetTagMatrix(&tag_matrix, e, tagindex);
Matrix4x4_ToVectors(&tag_matrix, prog->globals.client->v_forward, prog->globals.client->v_right, prog->globals.client->v_up, PRVM_G_VECTOR(OFS_RETURN));
}
}
-//=================================================
-//[515]: here goes test/unfinished/etc.
+//============================================================================
+
+//====================
+//QC POLYGON functions
+//====================
-//[515]: check if it is what it should be
-void VM_WasFreed (void)
+typedef struct
{
- prvm_edict_t *e;
- VM_SAFEPARMCOUNT(1, VM_WasFreed);
+ rtexture_t *tex;
+ float data[36]; //[515]: enough for polygons
+ unsigned char flags; //[515]: + VM_POLYGON_2D and VM_POLYGON_FL4V flags
+}vm_polygon_t;
- e = PRVM_G_EDICT(OFS_PARM0);
- if (!e->priv.required->free || (e->priv.required->free && (e->priv.required->freetime < 2 || (prog->globals.client->time - e->priv.required->freetime) > 0.5 )))
- PRVM_G_FLOAT(OFS_RETURN) = false;
+//static float vm_polygon_linewidth = 1;
+static mempool_t *vm_polygons_pool = NULL;
+static unsigned char vm_current_vertices = 0;
+static qboolean vm_polygons_initialized = false;
+static vm_polygon_t *vm_polygons = NULL;
+static unsigned long vm_polygons_num = 0, vm_drawpolygons_num = 0; //[515]: ok long on 64bit ?
+static qboolean vm_polygonbegin = false; //[515]: for "no-crap-on-the-screen" check
+#define VM_DEFPOLYNUM 64 //[515]: enough for default ?
+
+#define VM_POLYGON_FL3V 16 //more than 2 vertices (used only for lines)
+#define VM_POLYGON_FLLINES 32
+#define VM_POLYGON_FL2D 64
+#define VM_POLYGON_FL4V 128 //4 vertices
+
+static void VM_InitPolygons (void)
+{
+ vm_polygons_pool = Mem_AllocPool("VMPOLY", 0, NULL);
+ vm_polygons = (vm_polygon_t *)Mem_Alloc(vm_polygons_pool, VM_DEFPOLYNUM*sizeof(vm_polygon_t));
+ memset(vm_polygons, 0, VM_DEFPOLYNUM*sizeof(vm_polygon_t));
+ vm_polygons_num = VM_DEFPOLYNUM;
+ vm_drawpolygons_num = 0;
+ vm_polygonbegin = false;
+ vm_polygons_initialized = true;
+}
+
+static void VM_DrawPolygonCallback (const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
+{
+ int surfacelistindex;
+ // LordHavoc: FIXME: this is stupid code
+ for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
+ {
+ const vm_polygon_t *p = &vm_polygons[surfacelist[surfacelistindex]];
+ int flags = p->flags & 0x0f;
+
+ if(flags == DRAWFLAG_ADDITIVE)
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ else if(flags == DRAWFLAG_MODULATE)
+ GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
+ else if(flags == DRAWFLAG_2XMODULATE)
+ GL_BlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
+ else
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ R_Mesh_TexBind(0, R_GetTexture(p->tex));
+
+ CHECKGLERROR
+ //[515]: is speed is max ?
+ if(p->flags & VM_POLYGON_FLLINES) //[515]: lines
+ {
+ qglLineWidth(p->data[13]);CHECKGLERROR
+ qglBegin(GL_LINE_LOOP);
+ qglTexCoord1f (p->data[12]);
+ qglColor4f (p->data[20], p->data[21], p->data[22], p->data[23]);
+ qglVertex3f (p->data[0] , p->data[1], p->data[2]);
+
+ qglTexCoord1f (p->data[14]);
+ qglColor4f (p->data[24], p->data[25], p->data[26], p->data[27]);
+ qglVertex3f (p->data[3] , p->data[4], p->data[5]);
+
+ if(p->flags & VM_POLYGON_FL3V)
+ {
+ qglTexCoord1f (p->data[16]);
+ qglColor4f (p->data[28], p->data[29], p->data[30], p->data[31]);
+ qglVertex3f (p->data[6] , p->data[7], p->data[8]);
+
+ if(p->flags & VM_POLYGON_FL4V)
+ {
+ qglTexCoord1f (p->data[18]);
+ qglColor4f (p->data[32], p->data[33], p->data[34], p->data[35]);
+ qglVertex3f (p->data[9] , p->data[10], p->data[11]);
+ }
+ }
+ qglEnd();
+ CHECKGLERROR
+ }
+ else
+ {
+ qglBegin(GL_POLYGON);
+ qglTexCoord2f (p->data[12], p->data[13]);
+ qglColor4f (p->data[20], p->data[21], p->data[22], p->data[23]);
+ qglVertex3f (p->data[0] , p->data[1], p->data[2]);
+
+ qglTexCoord2f (p->data[14], p->data[15]);
+ qglColor4f (p->data[24], p->data[25], p->data[26], p->data[27]);
+ qglVertex3f (p->data[3] , p->data[4], p->data[5]);
+
+ qglTexCoord2f (p->data[16], p->data[17]);
+ qglColor4f (p->data[28], p->data[29], p->data[30], p->data[31]);
+ qglVertex3f (p->data[6] , p->data[7], p->data[8]);
+
+ if(p->flags & VM_POLYGON_FL4V)
+ {
+ qglTexCoord2f (p->data[18], p->data[19]);
+ qglColor4f (p->data[32], p->data[33], p->data[34], p->data[35]);
+ qglVertex3f (p->data[9] , p->data[10], p->data[11]);
+ }
+ qglEnd();
+ CHECKGLERROR
+ }
+ }
+}
+
+static void VM_CL_AddPolygonTo2DScene (vm_polygon_t *p)
+{
+ drawqueuemesh_t mesh;
+ static int picelements[6] = {0, 1, 2, 0, 2, 3};
+
+ mesh.texture = p->tex;
+ mesh.data_element3i = picelements;
+ mesh.data_vertex3f = p->data;
+ mesh.data_texcoord2f = p->data + 12;
+ mesh.data_color4f = p->data + 20;
+ if(p->flags & VM_POLYGON_FL4V)
+ {
+ mesh.num_vertices = 4;
+ mesh.num_triangles = 2;
+ }
else
- PRVM_G_FLOAT(OFS_RETURN) = true;
+ {
+ mesh.num_vertices = 3;
+ mesh.num_triangles = 1;
+ }
+ if(p->flags & VM_POLYGON_FLLINES) //[515]: lines
+ DrawQ_LineLoop (&mesh, (p->flags&0x0f));
+ else
+ DrawQ_Mesh (&mesh, (p->flags&0x0f));
}
-void VM_CL_select_cube (void)
+void VM_CL_AddPolygonsToMeshQueue (void)
{
- int i;
- float *mins2, *maxs2;
- prvm_edict_t *ent, *chain;
- vec3_t mins1, maxs1;
+ int i;
+ if(!vm_drawpolygons_num)
+ return;
+ R_Mesh_Matrix(&identitymatrix);
+ GL_CullFace(GL_NONE);
+ for(i = 0;i < (int)vm_drawpolygons_num;i++)
+ VM_DrawPolygonCallback(NULL, NULL, 1, &i);
+ vm_drawpolygons_num = 0;
+}
- VM_SAFEPARMCOUNT(2, VM_CL_select_cube);
+//void(string texturename, float flag[, float 2d[, float lines]]) R_BeginPolygon
+static void VM_CL_R_PolygonBegin (void)
+{
+ vm_polygon_t *p;
+ const char *picname;
+ VM_SAFEPARMCOUNTRANGE(2, 4, VM_CL_R_PolygonBegin);
- if (prog->fieldoffsets.chain < 0)
- PRVM_ERROR("VM_findchain: %s doesnt have a chain field !\n", PRVM_NAME);
+ if(!vm_polygons_initialized)
+ VM_InitPolygons();
+ if(vm_polygonbegin)
+ {
+ VM_Warning("VM_CL_R_PolygonBegin: called twice without VM_CL_R_PolygonEnd after first\n");
+ return;
+ }
+ if(vm_drawpolygons_num >= vm_polygons_num)
+ {
+ p = (vm_polygon_t *)Mem_Alloc(vm_polygons_pool, 2 * vm_polygons_num * sizeof(vm_polygon_t));
+ memset(p, 0, 2 * vm_polygons_num * sizeof(vm_polygon_t));
+ memcpy(p, vm_polygons, vm_polygons_num * sizeof(vm_polygon_t));
+ Mem_Free(vm_polygons);
+ vm_polygons = p;
+ vm_polygons_num *= 2;
+ }
+ p = &vm_polygons[vm_drawpolygons_num];
+ picname = PRVM_G_STRING(OFS_PARM0);
+ if(picname[0])
+ p->tex = Draw_CachePic(picname, true)->tex;
+ else
+ p->tex = r_texture_white;
+ p->flags = (unsigned char)PRVM_G_FLOAT(OFS_PARM1);
+ vm_current_vertices = 0;
+ vm_polygonbegin = true;
+ if(prog->argc >= 3)
+ {
+ if(PRVM_G_FLOAT(OFS_PARM2))
+ p->flags |= VM_POLYGON_FL2D;
+ if(prog->argc >= 4 && PRVM_G_FLOAT(OFS_PARM3))
+ {
+ p->data[13] = PRVM_G_FLOAT(OFS_PARM3); //[515]: linewidth
+ p->flags |= VM_POLYGON_FLLINES;
+ }
+ }
+}
- chain = prog->edicts;
+//void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
+static void VM_CL_R_PolygonVertex (void)
+{
+ float *coords, *tx, *rgb, alpha;
+ vm_polygon_t *p;
+ VM_SAFEPARMCOUNT(4, VM_CL_R_PolygonVertex);
- mins2 = PRVM_G_VECTOR(OFS_PARM0);
- maxs2 = PRVM_G_VECTOR(OFS_PARM1);
+ if(!vm_polygonbegin)
+ {
+ VM_Warning("VM_CL_R_PolygonVertex: VM_CL_R_PolygonBegin wasn't called\n");
+ return;
+ }
+ coords = PRVM_G_VECTOR(OFS_PARM0);
+ tx = PRVM_G_VECTOR(OFS_PARM1);
+ rgb = PRVM_G_VECTOR(OFS_PARM2);
+ alpha = PRVM_G_FLOAT(OFS_PARM3);
- ent = PRVM_NEXT_EDICT(prog->edicts);
- for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
+ p = &vm_polygons[vm_drawpolygons_num];
+ if(vm_current_vertices > 4)
{
- if (ent->priv.required->free)
- continue;
- VectorCopy(ent->fields.client->origin, mins1);
- VectorAdd(mins1, ent->fields.client->maxs, maxs1);
- VectorAdd(mins1, ent->fields.client->mins, mins1);
- if (mins1[0] > maxs2[0] || mins1[1] > maxs2[1] || mins1[2] > maxs2[2])
- continue;
- if (maxs1[0] < mins2[0] || maxs1[1] < mins2[1] || maxs1[2] < mins2[2])
- continue;
- PRVM_EDICTFIELDVALUE(ent,prog->fieldoffsets.chain)->edict = PRVM_NUM_FOR_EDICT(chain);
- chain = ent;
+ VM_Warning("VM_CL_R_PolygonVertex: may have 4 vertices max\n");
+ return;
}
- VM_RETURN_EDICT(chain);
+ p->data[vm_current_vertices*3] = coords[0];
+ p->data[1+vm_current_vertices*3] = coords[1];
+ p->data[2+vm_current_vertices*3] = coords[2];
+
+ p->data[12+vm_current_vertices*2] = tx[0];
+ if(!(p->flags & VM_POLYGON_FLLINES))
+ p->data[13+vm_current_vertices*2] = tx[1];
+
+ p->data[20+vm_current_vertices*4] = rgb[0];
+ p->data[21+vm_current_vertices*4] = rgb[1];
+ p->data[22+vm_current_vertices*4] = rgb[2];
+ p->data[23+vm_current_vertices*4] = alpha;
+
+ vm_current_vertices++;
+ if(vm_current_vertices == 4)
+ p->flags |= VM_POLYGON_FL4V;
+ else
+ if(vm_current_vertices == 3)
+ p->flags |= VM_POLYGON_FL3V;
}
-void VM_CL_select_super (void)
+//void() R_EndPolygon
+static void VM_CL_R_PolygonEnd (void)
{
-/* int i;
- float *v[8];
- prvm_edict_t *ent, *chain;
- vec3_t mins1, maxs1;
+ VM_SAFEPARMCOUNT(0, VM_CL_R_PolygonEnd);
+ if(!vm_polygonbegin)
+ {
+ VM_Warning("VM_CL_R_PolygonEnd: VM_CL_R_PolygonBegin wasn't called\n");
+ return;
+ }
+ vm_polygonbegin = false;
+ if(vm_current_vertices > 2 || (vm_current_vertices >= 2 && vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FLLINES))
+ {
+ if(vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FL2D) //[515]: don't use qcpolygons memory if 2D
+ VM_CL_AddPolygonTo2DScene(&vm_polygons[vm_drawpolygons_num]);
+ else
+ vm_drawpolygons_num++;
+ }
+ else
+ VM_Warning("VM_CL_R_PolygonEnd: %i vertices isn't a good choice\n", vm_current_vertices);
+}
- VM_SAFEPARMCOUNT(8, VM_findchain);
- for(i=0;i<8;i++)
- v[i] = PRVM_G_VECTOR(OFS_PARM0+i*3);
+void Debug_PolygonBegin(const char *picname, int flags, qboolean draw2d, float linewidth)
+{
+ vm_polygon_t *p;
- if (prog->fieldoffsets.chain < 0)
- PRVM_ERROR("VM_findchain: %s doesnt have a chain field !\n", PRVM_NAME);
+ if(!vm_polygons_initialized)
+ VM_InitPolygons();
+ if(vm_polygonbegin)
+ {
+ Con_Printf("Debug_PolygonBegin: called twice without Debug_PolygonEnd after first\n");
+ return;
+ }
+ // limit polygons to a vaguely sane amount, beyond this each one just
+ // replaces the last one
+ vm_drawpolygons_num = min(vm_drawpolygons_num, (1<<20)-1);
+ if(vm_drawpolygons_num >= vm_polygons_num)
+ {
+ p = (vm_polygon_t *)Mem_Alloc(vm_polygons_pool, 2 * vm_polygons_num * sizeof(vm_polygon_t));
+ memset(p, 0, 2 * vm_polygons_num * sizeof(vm_polygon_t));
+ memcpy(p, vm_polygons, vm_polygons_num * sizeof(vm_polygon_t));
+ Mem_Free(vm_polygons);
+ vm_polygons = p;
+ vm_polygons_num *= 2;
+ }
+ p = &vm_polygons[vm_drawpolygons_num];
+ if(picname && picname[0])
+ p->tex = Draw_CachePic(picname, true)->tex;
+ else
+ p->tex = r_texture_white;
+ p->flags = flags;
+ vm_current_vertices = 0;
+ vm_polygonbegin = true;
+ if(draw2d)
+ p->flags |= VM_POLYGON_FL2D;
+ if(linewidth)
+ {
+ p->data[13] = linewidth; //[515]: linewidth
+ p->flags |= VM_POLYGON_FLLINES;
+ }
+}
- chain = prog->edicts;
+void Debug_PolygonVertex(float x, float y, float z, float s, float t, float r, float g, float b, float a)
+{
+ vm_polygon_t *p;
- mins2 = PRVM_G_VECTOR(OFS_PARM0);
- maxs2 = PRVM_G_VECTOR(OFS_PARM1);
+ if(!vm_polygonbegin)
+ {
+ Con_Printf("Debug_PolygonVertex: Debug_PolygonBegin wasn't called\n");
+ return;
+ }
- ent = PRVM_NEXT_EDICT(prog->edicts);
- for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
+ p = &vm_polygons[vm_drawpolygons_num];
+ if(vm_current_vertices > 4)
{
- if (ent->priv.required->free)
- continue;
- VectorCopy(ent->fields.client->origin, mins1);
- VectorAdd(mins1, ent->fields.client->maxs, maxs1);
- VectorAdd(mins1, ent->fields.client->mins, mins1);
- if (mins1[0] > maxs2[0] || mins1[1] > maxs2[1] || mins1[2] > maxs2[2])
- continue;
- if (maxs1[0] < mins2[0] || maxs1[1] < mins2[1] || maxs1[2] < mins2[2])
- continue;
- PRVM_EDICTFIELDVALUE(ent,prog->fieldoffsets.chain)->edict = PRVM_NUM_FOR_EDICT(chain);
- chain = ent;
+ Con_Printf("Debug_PolygonVertex: may have 4 vertices max\n");
+ return;
}
- VM_RETURN_EDICT(chain);*/
+ p->data[vm_current_vertices*3] = x;
+ p->data[1+vm_current_vertices*3] = y;
+ p->data[2+vm_current_vertices*3] = z;
+
+ p->data[12+vm_current_vertices*2] = s;
+ if(!(p->flags & VM_POLYGON_FLLINES))
+ p->data[13+vm_current_vertices*2] = t;
+
+ p->data[20+vm_current_vertices*4] = r;
+ p->data[21+vm_current_vertices*4] = g;
+ p->data[22+vm_current_vertices*4] = b;
+ p->data[23+vm_current_vertices*4] = a;
+
+ vm_current_vertices++;
+ if(vm_current_vertices == 4)
+ p->flags |= VM_POLYGON_FL4V;
+ else
+ if(vm_current_vertices == 3)
+ p->flags |= VM_POLYGON_FL3V;
}
-static int Is_Text_Color (char c, char t)
+void Debug_PolygonEnd(void)
{
- int a = 0;
- char c2 = c - (c & 128);
- char t2 = t - (t & 128);
+ if(!vm_polygonbegin)
+ {
+ Con_Printf("Debug_PolygonEnd: Debug_PolygonBegin wasn't called\n");
+ return;
+ }
+ vm_polygonbegin = false;
+ if(vm_current_vertices > 2 || (vm_current_vertices >= 2 && vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FLLINES))
+ {
+ if(vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FL2D) //[515]: don't use qcpolygons memory if 2D
+ VM_CL_AddPolygonTo2DScene(&vm_polygons[vm_drawpolygons_num]);
+ else
+ vm_drawpolygons_num++;
+ }
+ else
+ Con_Printf("Debug_PolygonEnd: %i vertices isn't a good choice\n", vm_current_vertices);
+}
- if(c != STRING_COLOR_TAG && c2 != STRING_COLOR_TAG) return 0;
- if(t >= '0' && t <= '9') a = 1;
- if(t2 >= '0' && t2 <= '9') a = 1;
-/* if(t >= 'A' && t <= 'Z') a = 2;
- if(t2 >= 'A' && t2 <= 'Z') a = 2;
+/*
+=============
+CL_CheckBottom
- if(a == 1 && scr_colortext.integer > 0)
- return 1;
- if(a == 2 && scr_multifonts.integer > 0)
- return 2;
+Returns false if any part of the bottom of the entity is off an edge that
+is not a staircase.
+
+=============
*/
- return a;
+qboolean CL_CheckBottom (prvm_edict_t *ent)
+{
+ vec3_t mins, maxs, start, stop;
+ trace_t trace;
+ int x, y;
+ float mid, bottom;
+
+ VectorAdd (ent->fields.client->origin, ent->fields.client->mins, mins);
+ VectorAdd (ent->fields.client->origin, ent->fields.client->maxs, maxs);
+
+// if all of the points under the corners are solid world, don't bother
+// with the tougher checks
+// the corners must be within 16 of the midpoint
+ start[2] = mins[2] - 1;
+ for (x=0 ; x<=1 ; x++)
+ for (y=0 ; y<=1 ; y++)
+ {
+ start[0] = x ? maxs[0] : mins[0];
+ start[1] = y ? maxs[1] : mins[1];
+ if (!(CL_PointSuperContents(start) & (SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY)))
+ goto realcheck;
+ }
+
+ return true; // we got out easy
+
+realcheck:
+//
+// check it for real...
+//
+ start[2] = mins[2];
+
+// the midpoint must be within 16 of the bottom
+ start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
+ start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
+ stop[2] = start[2] - 2*sv_stepheight.value;
+ trace = CL_Move (start, vec3_origin, vec3_origin, stop, MOVE_NOMONSTERS, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
+
+ if (trace.fraction == 1.0)
+ return false;
+ mid = bottom = trace.endpos[2];
+
+// the corners must be within 16 of the midpoint
+ for (x=0 ; x<=1 ; x++)
+ for (y=0 ; y<=1 ; y++)
+ {
+ start[0] = stop[0] = x ? maxs[0] : mins[0];
+ start[1] = stop[1] = y ? maxs[1] : mins[1];
+
+ trace = CL_Move (start, vec3_origin, vec3_origin, stop, MOVE_NOMONSTERS, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
+
+ if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
+ bottom = trace.endpos[2];
+ if (trace.fraction == 1.0 || mid - trace.endpos[2] > sv_stepheight.value)
+ return false;
+ }
+
+ return true;
}
-void VM_uncolorstring (void) //#170
+/*
+=============
+CL_movestep
+
+Called by monster program code.
+The move will be adjusted for slopes and stairs, but if the move isn't
+possible, no move is done and false is returned
+=============
+*/
+qboolean CL_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean noenemy, qboolean settrace)
{
- const char *in;
- char out[VM_STRINGTEMP_LENGTH];
- int k = 0, i = 0;
+ float dz;
+ vec3_t oldorg, neworg, end, traceendpos;
+ trace_t trace;
+ int i;
+ prvm_edict_t *enemy;
+ prvm_eval_t *val;
- VM_SAFEPARMCOUNT(1, VM_uncolorstring);
- in = PRVM_G_STRING(OFS_PARM0);
- VM_CheckEmptyString (in);
+// try the move
+ VectorCopy (ent->fields.client->origin, oldorg);
+ VectorAdd (ent->fields.client->origin, move, neworg);
- while (in[k])
+// flying monsters don't step up
+ if ( (int)ent->fields.client->flags & (FL_SWIM | FL_FLY) )
{
- if(in[k+1])
- if(Is_Text_Color(in[k], in[k+1]) == 1/* || (in[k] == '&' && in[k+1] == 'r')*/)
+ // try one move with vertical motion, then one without
+ for (i=0 ; i<2 ; i++)
{
- k += 2;
- continue;
+ VectorAdd (ent->fields.client->origin, move, neworg);
+ enemy = PRVM_PROG_TO_EDICT(ent->fields.client->enemy);
+ if (i == 0 && enemy != prog->edicts)
+ {
+ dz = ent->fields.client->origin[2] - PRVM_PROG_TO_EDICT(ent->fields.client->enemy)->fields.client->origin[2];
+ if (dz > 40)
+ neworg[2] -= 8;
+ if (dz < 30)
+ neworg[2] += 8;
+ }
+ trace = CL_Move (ent->fields.client->origin, ent->fields.client->mins, ent->fields.client->maxs, neworg, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
+ if (settrace)
+ VM_SetTraceGlobals(&trace);
+
+ if (trace.fraction == 1)
+ {
+ VectorCopy(trace.endpos, traceendpos);
+ if (((int)ent->fields.client->flags & FL_SWIM) && !(CL_PointSuperContents(traceendpos) & SUPERCONTENTS_LIQUIDSMASK))
+ return false; // swim monster left water
+
+ VectorCopy (traceendpos, ent->fields.client->origin);
+ if (relink)
+ CL_LinkEdict(ent);
+ return true;
+ }
+
+ if (enemy == prog->edicts)
+ break;
+ }
+
+ return false;
+ }
+
+// push down from a step height above the wished position
+ neworg[2] += sv_stepheight.value;
+ VectorCopy (neworg, end);
+ end[2] -= sv_stepheight.value*2;
+
+ trace = CL_Move (neworg, ent->fields.client->mins, ent->fields.client->maxs, end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
+ if (settrace)
+ VM_SetTraceGlobals(&trace);
+
+ if (trace.startsolid)
+ {
+ neworg[2] -= sv_stepheight.value;
+ trace = CL_Move (neworg, ent->fields.client->mins, ent->fields.client->maxs, end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
+ if (settrace)
+ VM_SetTraceGlobals(&trace);
+ if (trace.startsolid)
+ return false;
+ }
+ if (trace.fraction == 1)
+ {
+ // if monster had the ground pulled out, go ahead and fall
+ if ( (int)ent->fields.client->flags & FL_PARTIALGROUND )
+ {
+ VectorAdd (ent->fields.client->origin, move, ent->fields.client->origin);
+ if (relink)
+ CL_LinkEdict(ent);
+ ent->fields.client->flags = (int)ent->fields.client->flags & ~FL_ONGROUND;
+ return true;
+ }
+
+ return false; // walked off an edge
+ }
+
+// check point traces down for dangling corners
+ VectorCopy (trace.endpos, ent->fields.client->origin);
+
+ if (!CL_CheckBottom (ent))
+ {
+ if ( (int)ent->fields.client->flags & FL_PARTIALGROUND )
+ { // entity had floor mostly pulled out from underneath it
+ // and is trying to correct
+ if (relink)
+ CL_LinkEdict(ent);
+ return true;
}
- out[i] = in[k];
- ++k;
- ++i;
+ VectorCopy (oldorg, ent->fields.client->origin);
+ return false;
}
- PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(out);
+
+ if ( (int)ent->fields.client->flags & FL_PARTIALGROUND )
+ ent->fields.client->flags = (int)ent->fields.client->flags & ~FL_PARTIALGROUND;
+
+ if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.groundentity)))
+ val->edict = PRVM_EDICT_TO_PROG(trace.ent);
+
+// the move is ok
+ if (relink)
+ CL_LinkEdict(ent);
+ return true;
}
-void VM_CL_selecttraceline (void)
+/*
+===============
+VM_CL_walkmove
+
+float(float yaw, float dist[, settrace]) walkmove
+===============
+*/
+static void VM_CL_walkmove (void)
{
- float *v1, *v2;
- int ent, ignore, csqcents;
+ prvm_edict_t *ent;
+ float yaw, dist;
+ vec3_t move;
+ mfunction_t *oldf;
+ int oldself;
+ qboolean settrace;
- v1 = PRVM_G_VECTOR(OFS_PARM0);
- v2 = PRVM_G_VECTOR(OFS_PARM1);
- ignore = (int)PRVM_G_FLOAT(OFS_PARM2);
- csqcents = (int)PRVM_G_FLOAT(OFS_PARM3);
- ent = 0;
+ VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_walkmove);
- if (csqcents)
+ // assume failure if it returns early
+ PRVM_G_FLOAT(OFS_RETURN) = 0;
+
+ ent = PRVM_PROG_TO_EDICT(prog->globals.client->self);
+ if (ent == prog->edicts)
{
- VM_Warning("VM_CL_selecttraceline: csqcents flag not supported anymore, and this function is deprecated\n");
+ VM_Warning("walkmove: can not modify world entity\n");
return;
}
- prog->globals.client->trace_fraction = CL_SelectTraceLine(v1, v2, prog->globals.client->trace_endpos, prog->globals.client->trace_plane_normal, &ent, &cl.entities[ignore].render);
- PRVM_G_FLOAT(OFS_RETURN) = ent;
-}
+ if (ent->priv.server->free)
+ {
+ VM_Warning("walkmove: can not modify free entity\n");
+ return;
+ }
+ yaw = PRVM_G_FLOAT(OFS_PARM0);
+ dist = PRVM_G_FLOAT(OFS_PARM1);
+ settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
-void VM_charindex (void)
-{
- const char *s;
- s = PRVM_G_STRING(OFS_PARM0);
- if((unsigned)PRVM_G_FLOAT(OFS_PARM1) > strlen(s))
+ if ( !( (int)ent->fields.client->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
return;
- PRVM_G_FLOAT(OFS_RETURN) = (unsigned char)s[(int)PRVM_G_FLOAT(OFS_PARM1)];
-}
-//#223 string(float c, ...) chr2str (FTE_STRINGS)
-void VM_chr2str (void)
-{
- char t[128];
- int i;
- for(i = 0;i < prog->argc && i < (int)sizeof(t) - 1;i++)
- t[i] = (unsigned char)PRVM_G_FLOAT(OFS_PARM0+i*3);
- t[i] = 0;
- PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
+ yaw = yaw*M_PI*2 / 360;
+
+ move[0] = cos(yaw)*dist;
+ move[1] = sin(yaw)*dist;
+ move[2] = 0;
+
+// save program state, because CL_movestep may call other progs
+ oldf = prog->xfunction;
+ oldself = prog->globals.client->self;
+
+ PRVM_G_FLOAT(OFS_RETURN) = CL_movestep(ent, move, true, false, settrace);
+
+
+// restore program state
+ prog->xfunction = oldf;
+ prog->globals.client->self = oldself;
}
-//#228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
-void VM_strncmp (void)
+/*
+===============
+VM_CL_serverkey
+
+string(string key) serverkey
+===============
+*/
+void VM_CL_serverkey(void)
{
- const char *s1, *s2;
- VM_SAFEPARMCOUNT(1, VM_strncmp);
- s1 = PRVM_G_STRING(OFS_PARM0);
- s2 = PRVM_G_STRING(OFS_PARM1);
- PRVM_G_FLOAT(OFS_RETURN) = strncmp(s1, s2, (size_t)PRVM_G_FLOAT(OFS_PARM2));
+ char string[VM_STRINGTEMP_LENGTH];
+ VM_SAFEPARMCOUNT(1, VM_CL_serverkey);
+ InfoString_GetValue(cl.qw_serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
+ PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
}
-//============================================================================
//============================================================================
prvm_builtin_t vm_cl_builtins[] = {
-0, // to be consistent with the old vm
-VM_CL_makevectors, // #1 void(vector ang) makevectors
-VM_CL_setorigin, // #2 void(entity e, vector o) setorigin
-VM_CL_setmodel, // #3 void(entity e, string m) setmodel
-VM_CL_setsize, // #4 void(entity e, vector min, vector max) setsize
-0,
-VM_break, // #6 void() break
-VM_random, // #7 float() random
-VM_CL_sound, // #8 void(entity e, float chan, string samp) sound
-VM_normalize, // #9 vector(vector v) normalize
-VM_error, // #10 void(string e) error
-VM_objerror, // #11 void(string e) objerror
-VM_vlen, // #12 float(vector v) vlen
-VM_vectoyaw, // #13 float(vector v) vectoyaw
-VM_CL_spawn, // #14 entity() spawn
-VM_remove, // #15 void(entity e) remove
-VM_CL_traceline, // #16 float(vector v1, vector v2, float tryents) traceline
-0,
-VM_find, // #18 entity(entity start, .string fld, string match) find
-VM_CL_precache_sound, // #19 void(string s) precache_sound
-VM_CL_precache_model, // #20 void(string s) precache_model
-0,
-VM_CL_findradius, // #22 entity(vector org, float rad) findradius
-0,
-0,
-VM_dprint, // #25 void(string s) dprint
-VM_ftos, // #26 void(string s) ftos
-VM_vtos, // #27 void(string s) vtos
-VM_coredump, // #28 void() coredump
-VM_traceon, // #29 void() traceon
-VM_traceoff, // #30 void() traceoff
-VM_eprint, // #31 void(entity e) eprint
-0,
-NULL, // #33
-VM_CL_droptofloor, // #34 float() droptofloor
-VM_CL_lightstyle, // #35 void(float style, string value) lightstyle
-VM_rint, // #36 float(float v) rint
-VM_floor, // #37 float(float v) floor
-VM_ceil, // #38 float(float v) ceil
-NULL, // #39
-VM_CL_checkbottom, // #40 float(entity e) checkbottom
-VM_CL_pointcontents, // #41 float(vector v) pointcontents
-NULL, // #42
-VM_fabs, // #43 float(float f) fabs
-0,
-VM_cvar, // #45 float(string s) cvar
-VM_localcmd, // #46 void(string s) localcmd
-VM_nextent, // #47 entity(entity e) nextent
-VM_CL_particle, // #48 void(vector o, vector d, float color, float count) particle
-VM_changeyaw, // #49 void(entity ent) ChangeYaw
-NULL, // #50
-VM_vectoangles, // #51 vector(vector v) vectoangles
-0, // #52 void(float to, float f) WriteByte
-0, // #53 void(float to, float f) WriteChar
-0, // #54 void(float to, float f) WriteShort
-0, // #55 void(float to, float f) WriteLong
-0, // #56 void(float to, float f) WriteCoord
-0, // #57 void(float to, float f) WriteAngle
-0, // #58 void(float to, string s) WriteString
-0,
-VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW)
-VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW)
-VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW)
-VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH)
-VM_CL_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS)
-VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS)
-NULL, // #66
-0, // #67
-0, // #68
-0, // #69
-0, // #70
-NULL, // #71
-VM_cvar_set, // #72 void(string var, string val) cvar_set
-0, // #73
-VM_CL_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound
-VM_CL_precache_model, // #75 string(string s) precache_model2
-VM_CL_precache_sound, // #76 string(string s) precache_sound2
-0, // #77
-VM_chr, // #78
-NULL, // #79
-NULL, // #80
-VM_stof, // #81 float(string s) stof (FRIK_FILE)
-NULL, // #82
-NULL, // #83
-NULL, // #84
-NULL, // #85
-NULL, // #86
-NULL, // #87
-NULL, // #88
-NULL, // #89
-VM_CL_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
-VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
-VM_CL_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
-PF_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
-VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
-VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
-VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
-VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
-VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
-VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
-NULL, // #100
-NULL, // #101
-NULL, // #102
-NULL, // #103
-NULL, // #104
-NULL, // #105
-NULL, // #106
-NULL, // #107
-NULL, // #108
-NULL, // #109
-VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
-VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
-VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
-VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
-VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
-VM_strcat, // #115 string(string s1, string s2) strcat (FRIK_FILE)
-VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
-VM_stov, // #117 vector(string) stov (FRIK_FILE)
-VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
-VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
-
-e10, e10, e10, e10, e10, e10, e10, e10, // #120-199
-e10, //#200-209
-0, //#210
-0, //#211
-0, //#212
-0, //#213
-0, //#214
-0, //#215
-0, //#216
-0, //#217
-VM_bitshift, //#218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
-0, //#219
-0, //#220
-0, //#221
-VM_charindex, //#222 float(string str, float ofs) str2chr (FTE_STRINGS)
-VM_chr2str, //#223 string(float c, ...) chr2str (FTE_STRINGS)
-0, //#224
-0, //#225
-0, //#226
-0, //#227
-VM_strncmp, //#228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
-0,
-e10, e10, e10, e10, e10, e10, e10, // #230-299
-
-//======CSQC start=======//
-//3d world (buffer/buffering) operations
-VM_R_ClearScene, //#300 void() clearscene (EXT_CSQC)
-VM_R_AddEntities, //#301 void(float mask) addentities (EXT_CSQC)
-VM_R_AddEntity, //#302 void(entity ent) addentity (EXT_CSQC)
-VM_R_SetView, //#303 float(float property, ...) setproperty (EXT_CSQC)
-VM_R_RenderScene, //#304 void() renderscene (EXT_CSQC)
-VM_R_AddDynamicLight, //#305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
-VM_R_PolygonBegin, //#306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
-VM_R_PolygonVertex, //#307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
-VM_R_PolygonEnd, //#308 void() R_EndPolygon
-0, //#309
-
-//maths stuff that uses the current view settings
-VM_CL_unproject, //#310 vector (vector v) cs_unproject (EXT_CSQC)
-VM_CL_project, //#311 vector (vector v) cs_project (EXT_CSQC)
-0, //#312
-0, //#313
-0, //#314
-
-//2d (immediate) operations
-VM_drawline, //#315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
-VM_iscachedpic, //#316 float(string name) iscachedpic (EXT_CSQC)
-VM_precache_pic, //#317 string(string name, float trywad) precache_pic (EXT_CSQC)
-VM_getimagesize, //#318 vector(string picname) draw_getimagesize (EXT_CSQC)
-VM_freepic, //#319 void(string name) freepic (EXT_CSQC)
-VM_drawcharacter, //#320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
-VM_drawstring, //#321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
-VM_drawpic, //#322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
-VM_drawfill, //#323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
-VM_drawsetcliparea, //#324 void(float x, float y, float width, float height) drawsetcliparea
-VM_drawresetcliparea, //#325 void(void) drawresetcliparea
-0, //#326
-0, //#327
-0, //#328
-0, //#329
-
-VM_CL_getstatf, //#330 float(float stnum) getstatf (EXT_CSQC)
-VM_CL_getstati, //#331 float(float stnum) getstati (EXT_CSQC)
-VM_CL_getstats, //#332 string(float firststnum) getstats (EXT_CSQC)
-VM_CL_setmodelindex, //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
-VM_CL_modelnameforindex, //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
-VM_CL_particleeffectnum, //#335 float(string effectname) particleeffectnum (EXT_CSQC)
-VM_CL_trailparticles, //#336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
-VM_CL_pointparticles, //#337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
-VM_CL_centerprint, //#338 void(string s) cprint (EXT_CSQC)
-VM_print, //#339 void(string s) print (EXT_CSQC)
-VM_keynumtostring, //#340 string(float keynum) keynumtostring (EXT_CSQC)
-VM_stringtokeynum, //#341 float(string keyname) stringtokeynum (EXT_CSQC)
-VM_CL_getkeybind, //#342 string(float keynum) getkeybind (EXT_CSQC)
-VM_CL_setcursormode, //#343 void(float usecursor) setcursormode (EXT_CSQC)
-VM_getmousepos, //#344 vector() getmousepos (EXT_CSQC)
-VM_CL_getinputstate, //#345 float(float framenum) getinputstate (EXT_CSQC)
-VM_CL_setsensitivityscale, //#346 void(float sens) setsensitivityscaler (EXT_CSQC)
-VM_CL_runplayerphysics, //#347 void() runstandardplayerphysics (EXT_CSQC)
-VM_CL_getplayerkey, //#348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
-VM_CL_isdemo, //#349 float() isdemo (EXT_CSQC)
-VM_isserver, //#350 float() isserver (EXT_CSQC)
-VM_CL_setlistener, //#351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
-VM_CL_registercmd, //#352 void(string cmdname) registercommand (EXT_CSQC)
-VM_WasFreed, //#353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
-VM_CL_playernum, //#354 float() playernum
-VM_CL_onground, //#355 float() cl_onground (EXT_CSQC)
-VM_charindex, //#356 float(string s, float num) charindex
-VM_CL_selecttraceline, //#357 float(vector start, vector end, float ignore, float csqcents) selecttraceline
-0, //#358
-0, //#359
-VM_CL_ReadByte, //#360 float() readbyte (EXT_CSQC)
-VM_CL_ReadChar, //#361 float() readchar (EXT_CSQC)
-VM_CL_ReadShort, //#362 float() readshort (EXT_CSQC)
-VM_CL_ReadLong, //#363 float() readlong (EXT_CSQC)
-VM_CL_ReadCoord, //#364 float() readcoord (EXT_CSQC)
-VM_CL_ReadAngle, //#365 float() readangle (EXT_CSQC)
-VM_CL_ReadString, //#366 string() readstring (EXT_CSQC)
-VM_CL_ReadFloat, //#367 float() readfloat (EXT_CSQC)
-0, //#368
-0, //#369
-0, //#370
-0, //#371
-0, //#372
-0, //#373
-0, //#374
-0, //#375
-0, //#376
-0, //#377
-0, //#378
-0, //#379
-0, //#380
-0, //#381
-0, //#382
-0, //#383
-0, //#384
-0, //#385
-0, //#386
-0, //#387
-0, //#388
-0, //#389
-0, //#390
-0, //#391
-0, //#392
-0, //#393
-0, //#394
-0, //#395
-0, //#396
-0, //#397
-0, //#398
-0, //#399
-//=========CSQC end========//
-
-VM_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
-0,
+NULL, // #0 NULL function (not callable) (QUAKE)
+VM_CL_makevectors, // #1 void(vector ang) makevectors (QUAKE)
+VM_CL_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
+VM_CL_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
+VM_CL_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
+NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
+VM_break, // #6 void() break (QUAKE)
+VM_random, // #7 float() random (QUAKE)
+VM_CL_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
+VM_normalize, // #9 vector(vector v) normalize (QUAKE)
+VM_error, // #10 void(string e) error (QUAKE)
+VM_objerror, // #11 void(string e) objerror (QUAKE)
+VM_vlen, // #12 float(vector v) vlen (QUAKE)
+VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
+VM_CL_spawn, // #14 entity() spawn (QUAKE)
+VM_remove, // #15 void(entity e) remove (QUAKE)
+VM_CL_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
+NULL, // #17 entity() checkclient (QUAKE)
+VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
+VM_precache_sound, // #19 void(string s) precache_sound (QUAKE)
+VM_CL_precache_model, // #20 void(string s) precache_model (QUAKE)
+NULL, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
+VM_CL_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
+NULL, // #23 void(string s, ...) bprint (QUAKE)
+NULL, // #24 void(entity client, string s, ...) sprint (QUAKE)
+VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
+VM_ftos, // #26 string(float f) ftos (QUAKE)
+VM_vtos, // #27 string(vector v) vtos (QUAKE)
+VM_coredump, // #28 void() coredump (QUAKE)
+VM_traceon, // #29 void() traceon (QUAKE)
+VM_traceoff, // #30 void() traceoff (QUAKE)
+VM_eprint, // #31 void(entity e) eprint (QUAKE)
+VM_CL_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
+NULL, // #33 (QUAKE)
+VM_CL_droptofloor, // #34 float() droptofloor (QUAKE)
+VM_CL_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
+VM_rint, // #36 float(float v) rint (QUAKE)
+VM_floor, // #37 float(float v) floor (QUAKE)
+VM_ceil, // #38 float(float v) ceil (QUAKE)
+NULL, // #39 (QUAKE)
+VM_CL_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
+VM_CL_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
+NULL, // #42 (QUAKE)
+VM_fabs, // #43 float(float f) fabs (QUAKE)
+NULL, // #44 vector(entity e, float speed) aim (QUAKE)
+VM_cvar, // #45 float(string s) cvar (QUAKE)
+VM_localcmd, // #46 void(string s) localcmd (QUAKE)
+VM_nextent, // #47 entity(entity e) nextent (QUAKE)
+VM_CL_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
+VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
+NULL, // #50 (QUAKE)
+VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
+NULL, // #52 void(float to, float f) WriteByte (QUAKE)
+NULL, // #53 void(float to, float f) WriteChar (QUAKE)
+NULL, // #54 void(float to, float f) WriteShort (QUAKE)
+NULL, // #55 void(float to, float f) WriteLong (QUAKE)
+NULL, // #56 void(float to, float f) WriteCoord (QUAKE)
+NULL, // #57 void(float to, float f) WriteAngle (QUAKE)
+NULL, // #58 void(float to, string s) WriteString (QUAKE)
+NULL, // #59 (QUAKE)
+VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW)
+VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW)
+VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW)
+VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH)
+VM_CL_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS)
+VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS)
+NULL, // #66 (QUAKE)
+NULL, // #67 void(float step) movetogoal (QUAKE)
+VM_precache_file, // #68 string(string s) precache_file (QUAKE)
+VM_CL_makestatic, // #69 void(entity e) makestatic (QUAKE)
+NULL, // #70 void(string s) changelevel (QUAKE)
+NULL, // #71 (QUAKE)
+VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
+NULL, // #73 void(entity client, strings) centerprint (QUAKE)
+VM_CL_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
+VM_CL_precache_model, // #75 string(string s) precache_model2 (QUAKE)
+VM_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
+VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
+NULL, // #78 void(entity e) setspawnparms (QUAKE)
+NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
+NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
+VM_stof, // #81 float(string s) stof (FRIK_FILE)
+NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
+NULL, // #83 (QUAKE)
+NULL, // #84 (QUAKE)
+NULL, // #85 (QUAKE)
+NULL, // #86 (QUAKE)
+NULL, // #87 (QUAKE)
+NULL, // #88 (QUAKE)
+NULL, // #89 (QUAKE)
+VM_CL_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
+VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
+VM_CL_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
+VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
+VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
+VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
+VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
+VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
+VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
+VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
+// FrikaC and Telejano range #100-#199
+NULL, // #100
+NULL, // #101
+NULL, // #102
+NULL, // #103
+NULL, // #104
+NULL, // #105
+NULL, // #106
+NULL, // #107
+NULL, // #108
+NULL, // #109
+VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
+VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
+VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
+VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
+VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
+VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
+VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
+VM_stov, // #117 vector(string) stov (FRIK_FILE)
+VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
+VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
+NULL, // #120
+NULL, // #121
+NULL, // #122
+NULL, // #123
+NULL, // #124
+NULL, // #125
+NULL, // #126
+NULL, // #127
+NULL, // #128
+NULL, // #129
+NULL, // #130
+NULL, // #131
+NULL, // #132
+NULL, // #133
+NULL, // #134
+NULL, // #135
+NULL, // #136
+NULL, // #137
+NULL, // #138
+NULL, // #139
+NULL, // #140
+NULL, // #141
+NULL, // #142
+NULL, // #143
+NULL, // #144
+NULL, // #145
+NULL, // #146
+NULL, // #147
+NULL, // #148
+NULL, // #149
+NULL, // #150
+NULL, // #151
+NULL, // #152
+NULL, // #153
+NULL, // #154
+NULL, // #155
+NULL, // #156
+NULL, // #157
+NULL, // #158
+NULL, // #159
+NULL, // #160
+NULL, // #161
+NULL, // #162
+NULL, // #163
+NULL, // #164
+NULL, // #165
+NULL, // #166
+NULL, // #167
+NULL, // #168
+NULL, // #169
+NULL, // #170
+NULL, // #171
+NULL, // #172
+NULL, // #173
+NULL, // #174
+NULL, // #175
+NULL, // #176
+NULL, // #177
+NULL, // #178
+NULL, // #179
+NULL, // #180
+NULL, // #181
+NULL, // #182
+NULL, // #183
+NULL, // #184
+NULL, // #185
+NULL, // #186
+NULL, // #187
+NULL, // #188
+NULL, // #189
+NULL, // #190
+NULL, // #191
+NULL, // #192
+NULL, // #193
+NULL, // #194
+NULL, // #195
+NULL, // #196
+NULL, // #197
+NULL, // #198
+NULL, // #199
+// FTEQW range #200-#299
+NULL, // #200
+NULL, // #201
+NULL, // #202
+NULL, // #203
+NULL, // #204
+NULL, // #205
+NULL, // #206
+NULL, // #207
+NULL, // #208
+NULL, // #209
+NULL, // #210
+NULL, // #211
+NULL, // #212
+NULL, // #213
+NULL, // #214
+NULL, // #215
+NULL, // #216
+NULL, // #217
+VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
+NULL, // #219
+NULL, // #220
+NULL, // #221
+VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
+VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
+NULL, // #224
+NULL, // #225
+NULL, // #226
+NULL, // #227
+VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
+NULL, // #229
+NULL, // #230
+NULL, // #231
+NULL, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
+NULL, // #233
+NULL, // #234
+NULL, // #235
+NULL, // #236
+NULL, // #237
+NULL, // #238
+NULL, // #239
+NULL, // #240
+NULL, // #241
+NULL, // #242
+NULL, // #243
+NULL, // #244
+NULL, // #245
+NULL, // #246
+NULL, // #247
+NULL, // #248
+NULL, // #249
+NULL, // #250
+NULL, // #251
+NULL, // #252
+NULL, // #253
+NULL, // #254
+NULL, // #255
+NULL, // #256
+NULL, // #257
+NULL, // #258
+NULL, // #259
+NULL, // #260
+NULL, // #261
+NULL, // #262
+NULL, // #263
+NULL, // #264
+NULL, // #265
+NULL, // #266
+NULL, // #267
+NULL, // #268
+NULL, // #269
+NULL, // #270
+NULL, // #271
+NULL, // #272
+NULL, // #273
+NULL, // #274
+NULL, // #275
+NULL, // #276
+NULL, // #277
+NULL, // #278
+NULL, // #279
+NULL, // #280
+NULL, // #281
+NULL, // #282
+NULL, // #283
+NULL, // #284
+NULL, // #285
+NULL, // #286
+NULL, // #287
+NULL, // #288
+NULL, // #289
+NULL, // #290
+NULL, // #291
+NULL, // #292
+NULL, // #293
+NULL, // #294
+NULL, // #295
+NULL, // #296
+NULL, // #297
+NULL, // #298
+NULL, // #299
+// CSQC range #300-#399
+VM_CL_R_ClearScene, // #300 void() clearscene (EXT_CSQC)
+VM_CL_R_AddEntities, // #301 void(float mask) addentities (EXT_CSQC)
+VM_CL_R_AddEntity, // #302 void(entity ent) addentity (EXT_CSQC)
+VM_CL_R_SetView, // #303 float(float property, ...) setproperty (EXT_CSQC)
+VM_CL_R_RenderScene, // #304 void() renderscene (EXT_CSQC)
+VM_CL_R_AddDynamicLight, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
+VM_CL_R_PolygonBegin, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
+VM_CL_R_PolygonVertex, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
+VM_CL_R_PolygonEnd, // #308 void() R_EndPolygon
+NULL, // #309
+VM_CL_unproject, // #310 vector (vector v) cs_unproject (EXT_CSQC)
+VM_CL_project, // #311 vector (vector v) cs_project (EXT_CSQC)
+NULL, // #312
+NULL, // #313
+NULL, // #314
+VM_drawline, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
+VM_iscachedpic, // #316 float(string name) iscachedpic (EXT_CSQC)
+VM_precache_pic, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
+VM_getimagesize, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
+VM_freepic, // #319 void(string name) freepic (EXT_CSQC)
+VM_drawcharacter, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
+VM_drawstring, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
+VM_drawpic, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
+VM_drawfill, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
+VM_drawsetcliparea, // #324 void(float x, float y, float width, float height) drawsetcliparea
+VM_drawresetcliparea, // #325 void(void) drawresetcliparea
+NULL, // #326
+NULL, // #327
+NULL, // #328
+NULL, // #329
+VM_CL_getstatf, // #330 float(float stnum) getstatf (EXT_CSQC)
+VM_CL_getstati, // #331 float(float stnum) getstati (EXT_CSQC)
+VM_CL_getstats, // #332 string(float firststnum) getstats (EXT_CSQC)
+VM_CL_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
+VM_CL_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
+VM_CL_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
+VM_CL_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
+VM_CL_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
+VM_centerprint, // #338 void(string s, ...) centerprint (EXT_CSQC)
+VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
+VM_keynumtostring, // #340 string(float keynum) keynumtostring (EXT_CSQC)
+VM_stringtokeynum, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
+VM_CL_getkeybind, // #342 string(float keynum) getkeybind (EXT_CSQC)
+VM_CL_setcursormode, // #343 void(float usecursor) setcursormode (EXT_CSQC)
+VM_getmousepos, // #344 vector() getmousepos (EXT_CSQC)
+VM_CL_getinputstate, // #345 float(float framenum) getinputstate (EXT_CSQC)
+VM_CL_setsensitivityscale, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
+VM_CL_runplayerphysics, // #347 void() runstandardplayerphysics (EXT_CSQC)
+VM_CL_getplayerkey, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
+VM_CL_isdemo, // #349 float() isdemo (EXT_CSQC)
+VM_isserver, // #350 float() isserver (EXT_CSQC)
+VM_CL_setlistener, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
+VM_CL_registercmd, // #352 void(string cmdname) registercommand (EXT_CSQC)
+VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
+VM_CL_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
+NULL, // #355
+NULL, // #356
+NULL, // #357
+NULL, // #358
+NULL, // #359
+VM_CL_ReadByte, // #360 float() readbyte (EXT_CSQC)
+VM_CL_ReadChar, // #361 float() readchar (EXT_CSQC)
+VM_CL_ReadShort, // #362 float() readshort (EXT_CSQC)
+VM_CL_ReadLong, // #363 float() readlong (EXT_CSQC)
+VM_CL_ReadCoord, // #364 float() readcoord (EXT_CSQC)
+VM_CL_ReadAngle, // #365 float() readangle (EXT_CSQC)
+VM_CL_ReadString, // #366 string() readstring (EXT_CSQC)
+VM_CL_ReadFloat, // #367 float() readfloat (EXT_CSQC)
+NULL, // #368
+NULL, // #369
+NULL, // #370
+NULL, // #371
+NULL, // #372
+NULL, // #373
+NULL, // #374
+NULL, // #375
+NULL, // #376
+NULL, // #377
+NULL, // #378
+NULL, // #379
+NULL, // #380
+NULL, // #381
+NULL, // #382
+NULL, // #383
+NULL, // #384
+NULL, // #385
+NULL, // #386
+NULL, // #387
+NULL, // #388
+NULL, // #389
+NULL, // #390
+NULL, // #391
+NULL, // #392
+NULL, // #393
+NULL, // #394
+NULL, // #395
+NULL, // #396
+NULL, // #397
+NULL, // #398
+NULL, // #399
+// LordHavoc's range #400-#499
+VM_CL_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
+NULL, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
VM_CL_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
VM_CL_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
VM_CL_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
VM_CL_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
-0, // #440
-VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
-VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
-VM_CL_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
-VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
-VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
-VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
-VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
-VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
-VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
-VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
-VM_CL_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
-VM_CL_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
-0, // #453
-0, // #454
-0, // #455
-NULL, // #456
-NULL, // #457
-NULL, // #458
-NULL, // #459
-VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
-VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
-VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
-VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
-VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
-VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
-VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
-VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
-VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
-VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
-NULL, // #470
-VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
-VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
-VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
-VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
-VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
-VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
-VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_QC_STRINGCOLORFUNCTIONS)
-VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
-NULL, // #479
-e10, e10 // #480-499 (LordHavoc)
+NULL, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
+VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
+VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
+VM_CL_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
+VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
+VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
+VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
+VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
+VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
+VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
+VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
+VM_CL_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
+VM_CL_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
+NULL, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
+NULL, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
+NULL, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
+NULL, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
+VM_CL_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
+NULL, // #458
+VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
+VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
+VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
+VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
+VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
+VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
+VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
+VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
+VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
+VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
+VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
+NULL, // #470 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
+VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
+VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
+VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
+VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
+VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
+VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
+VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_QC_STRINGCOLORFUNCTIONS)
+VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
+NULL, // #479
+NULL, // #480
+NULL, // #481
+NULL, // #482
+NULL, // #483
+NULL, // #484
+NULL, // #485
+NULL, // #486
+NULL, // #487
+NULL, // #488
+NULL, // #489
+NULL, // #490
+NULL, // #491
+NULL, // #492
+NULL, // #493
+NULL, // #494
+NULL, // #495
+NULL, // #496
+NULL, // #497
+NULL, // #498
+NULL, // #499
};
const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);
void VM_CL_Cmd_Init(void)
{
+ // TODO: replace vm_polygons stuff with a more general debugging polygon system, and make vm_polygons functions use that system
+ if(vm_polygons_initialized)
+ {
+ Mem_FreePool(&vm_polygons_pool);
+ vm_polygons_initialized = false;
+ }
}
void VM_CL_Cmd_Reset(void)
{
+ if(vm_polygons_initialized)
+ {
+ Mem_FreePool(&vm_polygons_pool);
+ vm_polygons_initialized = false;
+ }
}
#include "progsvm.h"
#include "clprogdefs.h"
#include "csprogs.h"
+#include "cl_collision.h"
//============================================================================
// Client prog handling
Host_Error(va("CL_VM_Error: %s", errorstring));
}
-model_t *CSQC_GetModelByIndex(int modelindex)
-{
- if(!modelindex)
- return NULL;
- if (modelindex < 0)
- {
- modelindex = -(modelindex+1);
- if (modelindex < MAX_MODELS)
- return cl.csqc_model_precache[modelindex];
- }
- else
- {
- if(modelindex < MAX_MODELS)
- return cl.model_precache[modelindex];
- }
- return NULL;
-}
-
-model_t *CSQC_GetModelFromEntity(prvm_edict_t *ed)
-{
- if (!ed || ed->priv.server->free)
- return NULL;
- return CSQC_GetModelByIndex((int)ed->fields.client->modelindex);
-}
-
//[515]: set globals before calling R_UpdateView, WEIRD CRAP
static void CSQC_SetGlobals (void)
{
model_t *model;
matrix4x4_t tagmatrix, matrix2;
- model = CSQC_GetModelFromEntity(ed);
+ model = CL_GetModelFromEdict(ed);
if (!model)
return false;
e->render.skinnum = (int)ed->fields.client->skin;
e->render.effects |= e->render.model->flags2 & (EF_FULLBRIGHT | EF_ADDITIVE);
scale = 1;
- // FIXME: renderflags should be in the cl_entvars_t
-#if 1
renderflags = 0;
if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.renderflags)) && val->_float) renderflags = (int)val->_float;
-#else
- renderflags = (int)ed->fields.client->renderflags;
-#endif
-
if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.alpha)) && val->_float) e->render.alpha = val->_float;
if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.scale)) && val->_float) e->render.scale = scale = val->_float;
if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.colormod)) && VectorLength2(val->vector)) VectorCopy(val->vector, e->render.colormod);
vec3_t left;
VectorNegate(prog->globals.client->v_right, left);
Matrix4x4_FromVectors(&matrix2, prog->globals.client->v_forward, left, prog->globals.client->v_up, ed->fields.client->origin);
+ Matrix4x4_Scale(&matrix2, scale, 1);
}
else
{
CSQC_END
}
-void CL_LinkEdict(prvm_edict_t *ent)
-{
- if (ent == prog->edicts)
- return; // don't add the world
-
- if (ent->priv.server->free)
- return;
-
- VectorAdd(ent->fields.client->origin, ent->fields.client->mins, ent->fields.client->absmin);
- VectorAdd(ent->fields.client->origin, ent->fields.client->maxs, ent->fields.client->absmax);
-
- World_LinkEdict(&cl.world, ent, ent->fields.client->absmin, ent->fields.client->absmax);
-}
-
void CL_VM_CB_BeginIncreaseEdicts(void)
{
int i;
VID_CheckExtensions();
// LordHavoc: report supported extensions
- Con_DPrintf("\nengine extensions: %s\n", vm_sv_extensions );
+ Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions );
// clear to black (loading plaque will be seen over this)
CHECKGLERROR
}
extern void R_DrawLightningBeams (void);
-extern void VM_AddPolygonsToMeshQueue (void);
+extern void VM_CL_AddPolygonsToMeshQueue (void);
extern void R_DrawPortals (void);
void R_RenderScene(void)
{
{
qglUseProgramObjectARB(0);CHECKGLERROR
}
- VM_AddPolygonsToMeshQueue();
+ VM_CL_AddPolygonsToMeshQueue();
if (r_drawportals.integer)
{
"DP_QC_STRINGCOLORFUNCTIONS "
"DP_QC_UNLIMITEDTEMPSTRINGS";
-/*
-=========
-VM_M_precache_file
-
-string precache_file(string)
-=========
-*/
-void VM_M_precache_file (void)
-{ // precache_file is only used to copy files with qcc, it does nothing
- VM_SAFEPARMCOUNT(1,VM_precache_file);
-
- PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
-}
-
-/*
-=========
-VM_M_preache_error
-
-used instead of the other VM_precache_* functions in the builtin list
-=========
-*/
-
-void VM_M_precache_error (void)
-{
- PRVM_ERROR ("PF_Precache_*: Precache can only be done in spawn functions");
-}
-
-/*
-=========
-VM_M_precache_sound
-
-string precache_sound (string sample)
-=========
-*/
-void VM_M_precache_sound (void)
-{
- const char *s;
-
- VM_SAFEPARMCOUNT(1, VM_precache_sound);
-
- s = PRVM_G_STRING(OFS_PARM0);
- PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
- VM_CheckEmptyString (s);
-
- if(snd_initialized.integer && !S_PrecacheSound (s,true, true))
- {
- VM_Warning("VM_precache_sound: Failed to load %s for %s\n", s, PRVM_NAME);
- return;
- }
-}
-
/*
=========
VM_M_setmousetarget
mfunction_t *func;
const char *s;
- if(prog->argc == 0)
- PRVM_ERROR("VM_M_callfunction: 1 parameter is required !");
+ VM_SAFEPARMCOUNTRANGE(1, 8, VM_M_callfunction);
s = PRVM_G_STRING(OFS_PARM0 + (prog->argc - 1));
PRVM_G_FLOAT(OFS_RETURN) = true;
}
-/*
-=========
-VM_M_writetofile
-
- writetofile(float fhandle, entity ent)
-=========
-*/
-void VM_M_writetofile(void)
-{
- prvm_edict_t * ent;
- qfile_t *file;
-
- VM_SAFEPARMCOUNT(2, VM_M_writetofile);
-
- file = VM_GetFileHandle( (int)PRVM_G_FLOAT(OFS_PARM0) );
- if( !file )
- {
- VM_Warning("VM_M_writetofile: invalid or closed file handle\n");
- return;
- }
-
- ent = PRVM_G_EDICT(OFS_PARM1);
- if(ent->priv.required->free)
- {
- VM_Warning("VM_M_writetofile: %s: entity %i is free !\n", PRVM_NAME, PRVM_NUM_FOR_EDICT(ent));
- return;
- }
-
- PRVM_ED_Write (file, ent);
-}
-
/*
=========
VM_M_getresolution
*/
void VM_M_resetserverlistmasks( void )
{
+ VM_SAFEPARMCOUNT(0, VM_M_resetserverlistmasks);
ServerList_ResetMasks();
}
*/
void VM_M_resortserverlist( void )
{
+ VM_SAFEPARMCOUNT(0, VM_M_resortserverlist);
ServerList_RebuildViewList();
}
MESSAGE WRITING
used only for client and menu
-severs uses VM_SV_...
+server uses VM_SV_...
Write*(* data, float type, float to)
#define MSG_ALL 2 // reliable to all
#define MSG_INIT 3 // write to the init string
-sizebuf_t *VM_WriteDest (void)
+sizebuf_t *VM_M_WriteDest (void)
{
int dest;
int destclient;
if(!sv.active)
- PRVM_ERROR("VM_WriteDest: game is not server (%s)", PRVM_NAME);
+ PRVM_ERROR("VM_M_WriteDest: game is not server (%s)", PRVM_NAME);
dest = (int)PRVM_G_FLOAT(OFS_PARM1);
switch (dest)
void VM_M_WriteByte (void)
{
- MSG_WriteByte (VM_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
+ VM_SAFEPARMCOUNT(1, VM_M_WriteByte);
+ MSG_WriteByte (VM_M_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
}
void VM_M_WriteChar (void)
{
- MSG_WriteChar (VM_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
+ VM_SAFEPARMCOUNT(1, VM_M_WriteChar);
+ MSG_WriteChar (VM_M_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
}
void VM_M_WriteShort (void)
{
- MSG_WriteShort (VM_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
+ VM_SAFEPARMCOUNT(1, VM_M_WriteShort);
+ MSG_WriteShort (VM_M_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
}
void VM_M_WriteLong (void)
{
- MSG_WriteLong (VM_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
+ VM_SAFEPARMCOUNT(1, VM_M_WriteLong);
+ MSG_WriteLong (VM_M_WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM0));
}
void VM_M_WriteAngle (void)
{
- MSG_WriteAngle (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
+ VM_SAFEPARMCOUNT(1, VM_M_WriteAngle);
+ MSG_WriteAngle (VM_M_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
}
void VM_M_WriteCoord (void)
{
- MSG_WriteCoord (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
+ VM_SAFEPARMCOUNT(1, VM_M_WriteCoord);
+ MSG_WriteCoord (VM_M_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
}
void VM_M_WriteString (void)
{
- MSG_WriteString (VM_WriteDest(), PRVM_G_STRING(OFS_PARM0));
+ VM_SAFEPARMCOUNT(1, VM_M_WriteString);
+ MSG_WriteString (VM_M_WriteDest(), PRVM_G_STRING(OFS_PARM0));
}
void VM_M_WriteEntity (void)
{
- MSG_WriteShort (VM_WriteDest(), PRVM_G_EDICTNUM(OFS_PARM0));
+ VM_SAFEPARMCOUNT(1, VM_M_WriteEntity);
+ MSG_WriteShort (VM_M_WriteDest(), PRVM_G_EDICTNUM(OFS_PARM0));
}
//string(void) getextresponse = #624; // returns the next extResponse packet that was sent to this client
}
}
+/*
+=================
+VM_M_copyentity
+
+copies data from one entity to another
+
+copyentity(entity src, entity dst)
+=================
+*/
+static void VM_M_copyentity (void)
+{
+ prvm_edict_t *in, *out;
+ VM_SAFEPARMCOUNT(2,VM_M_copyentity);
+ in = PRVM_G_EDICT(OFS_PARM0);
+ out = PRVM_G_EDICT(OFS_PARM1);
+ memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
+}
+
prvm_builtin_t vm_m_builtins[] = {
- 0, // to be consistent with the old vm
- // common builtings (mostly)
- VM_checkextension,
- VM_error,
- VM_objerror,
- VM_print,
- VM_bprint,
- VM_sprint,
- VM_centerprint,
- VM_normalize,
- VM_vlen,
- VM_vectoyaw, // #10
- VM_vectoangles,
- VM_random,
- VM_localcmd,
- VM_cvar,
- VM_cvar_set,
- VM_dprint,
- VM_ftos,
- VM_fabs,
- VM_vtos,
- VM_etos, // 20
- VM_stof,
- VM_spawn,
- VM_remove,
- VM_find,
- VM_findfloat,
- VM_findchain,
- VM_findchainfloat,
- VM_M_precache_file,
- VM_M_precache_sound,
- VM_coredump, // 30
- VM_traceon,
- VM_traceoff,
- VM_eprint,
- VM_rint,
- VM_floor,
- VM_ceil,
- VM_nextent,
- VM_sin,
- VM_cos,
- VM_sqrt, // 40
- VM_randomvec,
- VM_registercvar,
- VM_min,
- VM_max,
- VM_bound,
- VM_pow,
- VM_copyentity,
- VM_fopen,
- VM_fclose,
- VM_fgets, // 50
- VM_fputs,
- VM_strlen,
- VM_strcat,
- VM_substring,
- VM_stov,
- VM_strzone,
- VM_strunzone,
- VM_tokenize,
- VM_argv,
- VM_isserver, // 60
- VM_clientcount,
- VM_clientstate,
- VM_clcommand,
- VM_changelevel,
- VM_localsound,
- VM_getmousepos,
- VM_gettime,
- VM_loadfromdata,
- VM_loadfromfile,
- VM_modulo, // 70
- VM_cvar_string,
- VM_crash,
- VM_stackdump, // 73
- VM_search_begin,
- VM_search_end,
- VM_search_getsize,
- VM_search_getfilename, // 77
- VM_chr,
- VM_itof,
- VM_ftoe, // 80
- VM_itof, // isString
- VM_altstr_count,
- VM_altstr_prepare,
- VM_altstr_get,
- VM_altstr_set,
- VM_altstr_ins,
- VM_findflags,
- VM_findchainflags,
- VM_cvar_defstring, // 89
- 0, // 90
- e10, // 100
- e100, // 200
- e100, // 300
- e100, // 400
- // msg functions
- VM_M_WriteByte,
- VM_M_WriteChar,
- VM_M_WriteShort,
- VM_M_WriteLong,
- VM_M_WriteAngle,
- VM_M_WriteCoord,
- VM_M_WriteString,
- VM_M_WriteEntity, // 408
- 0,
- 0, // 410
- e10, // 420
- e10, // 430
- e10, // 440
- e10, // 450
- // draw functions
- VM_iscachedpic,
- VM_precache_pic,
- VM_freepic,
- VM_drawcharacter,
- VM_drawstring,
- VM_drawpic,
- VM_drawfill,
- VM_drawsetcliparea,
- VM_drawresetcliparea,
- VM_getimagesize,// 460
- VM_cin_open,
- VM_cin_close,
- VM_cin_setstate,
- VM_cin_getstate,
- VM_cin_restart, // 465
- VM_drawline, // 466
- 0,0,0,0, // 470
- VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
- VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
- VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
- VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
- VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
- VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
- VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_QC_STRINGCOLORFUNCTIONS)
- VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
- 0, // 479
- 0, // 480
- e10, // 490
- e10, // 500
- e100, // 600
- // menu functions
- VM_M_setkeydest,
- VM_M_getkeydest,
- VM_M_setmousetarget,
- VM_M_getmousetarget,
- VM_M_callfunction,
- VM_M_writetofile,
- VM_M_isfunction,
- VM_M_getresolution,
- VM_keynumtostring,
- VM_M_findkeysforcommand,// 610
- VM_M_getserverliststat,
- VM_M_getserverliststring,
- VM_parseentitydata,
- VM_stringtokeynum,
- VM_M_resetserverlistmasks,
- VM_M_setserverlistmaskstring,
- VM_M_setserverlistmasknumber,
- VM_M_resortserverlist,
- VM_M_setserverlistsort,
- VM_M_refreshserverlist,
- VM_M_getserverlistnumber,
- VM_M_getserverlistindexforkey,
- VM_M_addwantedserverlistkey, // 623
- VM_M_getextresponse
+NULL, // #0 NULL function (not callable)
+VM_checkextension, // #1
+VM_error, // #2
+VM_objerror, // #3
+VM_print, // #4
+VM_bprint, // #5
+VM_sprint, // #6
+VM_centerprint, // #7
+VM_normalize, // #8
+VM_vlen, // #9
+VM_vectoyaw, // #10
+VM_vectoangles, // #11
+VM_random, // #12
+VM_localcmd, // #13
+VM_cvar, // #14
+VM_cvar_set, // #15
+VM_dprint, // #16
+VM_ftos, // #17
+VM_fabs, // #18
+VM_vtos, // #19
+VM_etos, // #20
+VM_stof, // #21
+VM_spawn, // #22
+VM_remove, // #23
+VM_find, // #24
+VM_findfloat, // #25
+VM_findchain, // #26
+VM_findchainfloat, // #27
+VM_precache_file, // #28
+VM_precache_sound, // #29
+VM_coredump, // #30
+VM_traceon, // #31
+VM_traceoff, // #32
+VM_eprint, // #33
+VM_rint, // #34
+VM_floor, // #35
+VM_ceil, // #36
+VM_nextent, // #37
+VM_sin, // #38
+VM_cos, // #39
+VM_sqrt, // #40
+VM_randomvec, // #41
+VM_registercvar, // #42
+VM_min, // #43
+VM_max, // #44
+VM_bound, // #45
+VM_pow, // #46
+VM_M_copyentity, // #47
+VM_fopen, // #48
+VM_fclose, // #49
+VM_fgets, // #50
+VM_fputs, // #51
+VM_strlen, // #52
+VM_strcat, // #53
+VM_substring, // #54
+VM_stov, // #55
+VM_strzone, // #56
+VM_strunzone, // #57
+VM_tokenize, // #58
+VM_argv, // #59
+VM_isserver, // #60
+VM_clientcount, // #61
+VM_clientstate, // #62
+VM_clcommand, // #63
+VM_changelevel, // #64
+VM_localsound, // #65
+VM_getmousepos, // #66
+VM_gettime, // #67
+VM_loadfromdata, // #68
+VM_loadfromfile, // #69
+VM_modulo, // #70
+VM_cvar_string, // #71
+VM_crash, // #72
+VM_stackdump, // #73
+VM_search_begin, // #74
+VM_search_end, // #75
+VM_search_getsize, // #76
+VM_search_getfilename, // #77
+VM_chr, // #78
+VM_itof, // #79
+VM_ftoe, // #80
+VM_itof, // #81 isString
+VM_altstr_count, // #82
+VM_altstr_prepare, // #83
+VM_altstr_get, // #84
+VM_altstr_set, // #85
+VM_altstr_ins, // #86
+VM_findflags, // #87
+VM_findchainflags, // #88
+VM_cvar_defstring, // #89
+NULL, // #90
+NULL, // #91
+NULL, // #92
+NULL, // #93
+NULL, // #94
+NULL, // #95
+NULL, // #96
+NULL, // #97
+NULL, // #98
+NULL, // #99
+NULL, // #100
+NULL, // #101
+NULL, // #102
+NULL, // #103
+NULL, // #104
+NULL, // #105
+NULL, // #106
+NULL, // #107
+NULL, // #108
+NULL, // #109
+NULL, // #110
+NULL, // #111
+NULL, // #112
+NULL, // #113
+NULL, // #114
+NULL, // #115
+NULL, // #116
+NULL, // #117
+NULL, // #118
+NULL, // #119
+NULL, // #120
+NULL, // #121
+NULL, // #122
+NULL, // #123
+NULL, // #124
+NULL, // #125
+NULL, // #126
+NULL, // #127
+NULL, // #128
+NULL, // #129
+NULL, // #130
+NULL, // #131
+NULL, // #132
+NULL, // #133
+NULL, // #134
+NULL, // #135
+NULL, // #136
+NULL, // #137
+NULL, // #138
+NULL, // #139
+NULL, // #140
+NULL, // #141
+NULL, // #142
+NULL, // #143
+NULL, // #144
+NULL, // #145
+NULL, // #146
+NULL, // #147
+NULL, // #148
+NULL, // #149
+NULL, // #150
+NULL, // #151
+NULL, // #152
+NULL, // #153
+NULL, // #154
+NULL, // #155
+NULL, // #156
+NULL, // #157
+NULL, // #158
+NULL, // #159
+NULL, // #160
+NULL, // #161
+NULL, // #162
+NULL, // #163
+NULL, // #164
+NULL, // #165
+NULL, // #166
+NULL, // #167
+NULL, // #168
+NULL, // #169
+NULL, // #170
+NULL, // #171
+NULL, // #172
+NULL, // #173
+NULL, // #174
+NULL, // #175
+NULL, // #176
+NULL, // #177
+NULL, // #178
+NULL, // #179
+NULL, // #180
+NULL, // #181
+NULL, // #182
+NULL, // #183
+NULL, // #184
+NULL, // #185
+NULL, // #186
+NULL, // #187
+NULL, // #188
+NULL, // #189
+NULL, // #190
+NULL, // #191
+NULL, // #192
+NULL, // #193
+NULL, // #194
+NULL, // #195
+NULL, // #196
+NULL, // #197
+NULL, // #198
+NULL, // #199
+NULL, // #200
+NULL, // #201
+NULL, // #202
+NULL, // #203
+NULL, // #204
+NULL, // #205
+NULL, // #206
+NULL, // #207
+NULL, // #208
+NULL, // #209
+NULL, // #210
+NULL, // #211
+NULL, // #212
+NULL, // #213
+NULL, // #214
+NULL, // #215
+NULL, // #216
+NULL, // #217
+NULL, // #218
+NULL, // #219
+NULL, // #220
+NULL, // #221
+NULL, // #222
+NULL, // #223
+NULL, // #224
+NULL, // #225
+NULL, // #226
+NULL, // #227
+NULL, // #228
+NULL, // #229
+NULL, // #230
+NULL, // #231
+NULL, // #232
+NULL, // #233
+NULL, // #234
+NULL, // #235
+NULL, // #236
+NULL, // #237
+NULL, // #238
+NULL, // #239
+NULL, // #240
+NULL, // #241
+NULL, // #242
+NULL, // #243
+NULL, // #244
+NULL, // #245
+NULL, // #246
+NULL, // #247
+NULL, // #248
+NULL, // #249
+NULL, // #250
+NULL, // #251
+NULL, // #252
+NULL, // #253
+NULL, // #254
+NULL, // #255
+NULL, // #256
+NULL, // #257
+NULL, // #258
+NULL, // #259
+NULL, // #260
+NULL, // #261
+NULL, // #262
+NULL, // #263
+NULL, // #264
+NULL, // #265
+NULL, // #266
+NULL, // #267
+NULL, // #268
+NULL, // #269
+NULL, // #270
+NULL, // #271
+NULL, // #272
+NULL, // #273
+NULL, // #274
+NULL, // #275
+NULL, // #276
+NULL, // #277
+NULL, // #278
+NULL, // #279
+NULL, // #280
+NULL, // #281
+NULL, // #282
+NULL, // #283
+NULL, // #284
+NULL, // #285
+NULL, // #286
+NULL, // #287
+NULL, // #288
+NULL, // #289
+NULL, // #290
+NULL, // #291
+NULL, // #292
+NULL, // #293
+NULL, // #294
+NULL, // #295
+NULL, // #296
+NULL, // #297
+NULL, // #298
+NULL, // #299
+NULL, // #300
+NULL, // #301
+NULL, // #302
+NULL, // #303
+NULL, // #304
+NULL, // #305
+NULL, // #306
+NULL, // #307
+NULL, // #308
+NULL, // #309
+NULL, // #310
+NULL, // #311
+NULL, // #312
+NULL, // #313
+NULL, // #314
+NULL, // #315
+NULL, // #316
+NULL, // #317
+NULL, // #318
+NULL, // #319
+NULL, // #320
+NULL, // #321
+NULL, // #322
+NULL, // #323
+NULL, // #324
+NULL, // #325
+NULL, // #326
+NULL, // #327
+NULL, // #328
+NULL, // #329
+NULL, // #330
+NULL, // #331
+NULL, // #332
+NULL, // #333
+NULL, // #334
+NULL, // #335
+NULL, // #336
+NULL, // #337
+NULL, // #338
+NULL, // #339
+NULL, // #340
+NULL, // #341
+NULL, // #342
+NULL, // #343
+NULL, // #344
+NULL, // #345
+NULL, // #346
+NULL, // #347
+NULL, // #348
+NULL, // #349
+NULL, // #350
+NULL, // #351
+NULL, // #352
+NULL, // #353
+NULL, // #354
+NULL, // #355
+NULL, // #356
+NULL, // #357
+NULL, // #358
+NULL, // #359
+NULL, // #360
+NULL, // #361
+NULL, // #362
+NULL, // #363
+NULL, // #364
+NULL, // #365
+NULL, // #366
+NULL, // #367
+NULL, // #368
+NULL, // #369
+NULL, // #370
+NULL, // #371
+NULL, // #372
+NULL, // #373
+NULL, // #374
+NULL, // #375
+NULL, // #376
+NULL, // #377
+NULL, // #378
+NULL, // #379
+NULL, // #380
+NULL, // #381
+NULL, // #382
+NULL, // #383
+NULL, // #384
+NULL, // #385
+NULL, // #386
+NULL, // #387
+NULL, // #388
+NULL, // #389
+NULL, // #390
+NULL, // #391
+NULL, // #392
+NULL, // #393
+NULL, // #394
+NULL, // #395
+NULL, // #396
+NULL, // #397
+NULL, // #398
+NULL, // #399
+NULL, // #400
+VM_M_WriteByte, // #401
+VM_M_WriteChar, // #402
+VM_M_WriteShort, // #403
+VM_M_WriteLong, // #404
+VM_M_WriteAngle, // #405
+VM_M_WriteCoord, // #406
+VM_M_WriteString, // #407
+VM_M_WriteEntity, // #408
+NULL, // #409
+NULL, // #410
+NULL, // #411
+NULL, // #412
+NULL, // #413
+NULL, // #414
+NULL, // #415
+NULL, // #416
+NULL, // #417
+NULL, // #418
+NULL, // #419
+NULL, // #420
+NULL, // #421
+NULL, // #422
+NULL, // #423
+NULL, // #424
+NULL, // #425
+NULL, // #426
+NULL, // #427
+NULL, // #428
+NULL, // #429
+NULL, // #430
+NULL, // #431
+NULL, // #432
+NULL, // #433
+NULL, // #434
+NULL, // #435
+NULL, // #436
+NULL, // #437
+NULL, // #438
+NULL, // #439
+NULL, // #440
+NULL, // #441
+NULL, // #442
+NULL, // #443
+NULL, // #444
+NULL, // #445
+NULL, // #446
+NULL, // #447
+NULL, // #448
+NULL, // #449
+NULL, // #450
+VM_iscachedpic, // #451 draw functions...
+VM_precache_pic, // #452
+VM_freepic, // #453
+VM_drawcharacter, // #454
+VM_drawstring, // #455
+VM_drawpic, // #456
+VM_drawfill, // #457
+VM_drawsetcliparea, // #458
+VM_drawresetcliparea, // #459
+VM_getimagesize, // #460
+VM_cin_open, // #461
+VM_cin_close, // #462
+VM_cin_setstate, // #463
+VM_cin_getstate, // #464
+VM_cin_restart, // #465
+VM_drawline, // #466
+NULL, // #467
+NULL, // #468
+NULL, // #469
+NULL, // #470
+VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
+VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
+VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
+VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
+VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
+VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
+VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_QC_STRINGCOLORFUNCTIONS)
+VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
+NULL, // #479
+NULL, // #480
+NULL, // #481
+NULL, // #482
+NULL, // #483
+NULL, // #484
+NULL, // #485
+NULL, // #486
+NULL, // #487
+NULL, // #488
+NULL, // #489
+NULL, // #490
+NULL, // #491
+NULL, // #492
+NULL, // #493
+NULL, // #494
+NULL, // #495
+NULL, // #496
+NULL, // #497
+NULL, // #498
+NULL, // #499
+NULL, // #500
+NULL, // #501
+NULL, // #502
+NULL, // #503
+NULL, // #504
+NULL, // #505
+NULL, // #506
+NULL, // #507
+NULL, // #508
+NULL, // #509
+NULL, // #510
+NULL, // #511
+NULL, // #512
+NULL, // #513
+NULL, // #514
+NULL, // #515
+NULL, // #516
+NULL, // #517
+NULL, // #518
+NULL, // #519
+NULL, // #520
+NULL, // #521
+NULL, // #522
+NULL, // #523
+NULL, // #524
+NULL, // #525
+NULL, // #526
+NULL, // #527
+NULL, // #528
+NULL, // #529
+NULL, // #530
+NULL, // #531
+NULL, // #532
+NULL, // #533
+NULL, // #534
+NULL, // #535
+NULL, // #536
+NULL, // #537
+NULL, // #538
+NULL, // #539
+NULL, // #540
+NULL, // #541
+NULL, // #542
+NULL, // #543
+NULL, // #544
+NULL, // #545
+NULL, // #546
+NULL, // #547
+NULL, // #548
+NULL, // #549
+NULL, // #550
+NULL, // #551
+NULL, // #552
+NULL, // #553
+NULL, // #554
+NULL, // #555
+NULL, // #556
+NULL, // #557
+NULL, // #558
+NULL, // #559
+NULL, // #560
+NULL, // #561
+NULL, // #562
+NULL, // #563
+NULL, // #564
+NULL, // #565
+NULL, // #566
+NULL, // #567
+NULL, // #568
+NULL, // #569
+NULL, // #570
+NULL, // #571
+NULL, // #572
+NULL, // #573
+NULL, // #574
+NULL, // #575
+NULL, // #576
+NULL, // #577
+NULL, // #578
+NULL, // #579
+NULL, // #580
+NULL, // #581
+NULL, // #582
+NULL, // #583
+NULL, // #584
+NULL, // #585
+NULL, // #586
+NULL, // #587
+NULL, // #588
+NULL, // #589
+NULL, // #590
+NULL, // #591
+NULL, // #592
+NULL, // #593
+NULL, // #594
+NULL, // #595
+NULL, // #596
+NULL, // #597
+NULL, // #598
+NULL, // #599
+NULL, // #600
+VM_M_setkeydest, // #601 menu functions...
+VM_M_getkeydest, // #602
+VM_M_setmousetarget, // #603
+VM_M_getmousetarget, // #604
+VM_M_callfunction, // #605
+VM_writetofile, // #606
+VM_M_isfunction, // #607
+VM_M_getresolution, // #608
+VM_keynumtostring, // #609
+VM_M_findkeysforcommand, // #610
+VM_M_getserverliststat, // #611
+VM_M_getserverliststring, // #612
+VM_parseentitydata, // #613
+VM_stringtokeynum, // #614
+VM_M_resetserverlistmasks, // #615
+VM_M_setserverlistmaskstring,// #616
+VM_M_setserverlistmasknumber,// #617
+VM_M_resortserverlist, // #618
+VM_M_setserverlistsort, // #619
+VM_M_refreshserverlist, // #620
+VM_M_getserverlistnumber, // #621
+VM_M_getserverlistindexforkey,// #622
+VM_M_addwantedserverlistkey,// #623
+VM_M_getextresponse // #624
};
const int vm_m_numbuiltins = sizeof(vm_m_builtins) / sizeof(prvm_builtin_t);
int clientnum;
char string[VM_STRINGTEMP_LENGTH];
+ VM_SAFEPARMCOUNTRANGE(1, 8, VM_sprint);
+
//find client for this entity
clientnum = (int)PRVM_G_FLOAT(OFS_PARM0);
if (!sv.active || clientnum < 0 || clientnum >= svs.maxclients || !svs.clients[clientnum].active)
single print to the screen
-centerprint(clientent, value)
+centerprint(value)
=================
*/
void VM_centerprint (void)
{
char string[VM_STRINGTEMP_LENGTH];
+ VM_SAFEPARMCOUNTRANGE(1, 8, VM_centerprint);
VM_VarString(0, string, sizeof(string));
SCR_CenterPrint(string);
}
PRVM_G_FLOAT(OFS_RETURN) = lhrandom(0, 1);
}
-/*
-=================
-PF_sound
-
-Each entity can have eight independant sound sources, like voice,
-weapon, feet, etc.
-
-Channel 0 is an auto-allocate channel, the others override anything
-already running on that entity/channel pair.
-
-An attenuation of 0 will play full volume everywhere in the level.
-Larger attenuations will drop off.
-
-=================
-*/
-/*
-void PF_sound (void)
-{
- char *sample;
- int channel;
- prvm_edict_t *entity;
- int volume;
- float attenuation;
-
- entity = PRVM_G_EDICT(OFS_PARM0);
- channel = PRVM_G_FLOAT(OFS_PARM1);
- sample = PRVM_G_STRING(OFS_PARM2);
- volume = PRVM_G_FLOAT(OFS_PARM3) * 255;
- attenuation = PRVM_G_FLOAT(OFS_PARM4);
-
- if (volume < 0 || volume > 255)
- Host_Error ("SV_StartSound: volume = %i", volume);
-
- if (attenuation < 0 || attenuation > 4)
- Host_Error ("SV_StartSound: attenuation = %f", attenuation);
-
- if (channel < 0 || channel > 7)
- Host_Error ("SV_StartSound: channel = %i", channel);
-
- SV_StartSound (entity, channel, sample, volume, attenuation);
-}
-*/
-
/*
=========
VM_localsound
void VM_localcmd (void)
{
char string[VM_STRINGTEMP_LENGTH];
+ VM_SAFEPARMCOUNTRANGE(1, 8, VM_localcmd);
VM_VarString(0, string, sizeof(string));
Cbuf_AddText(string);
}
void VM_dprint (void)
{
char string[VM_STRINGTEMP_LENGTH];
+ VM_SAFEPARMCOUNTRANGE(1, 8, VM_dprint);
if (developer.integer)
{
VM_VarString(0, string, sizeof(string));
void VM_stof(void)
{
char string[VM_STRINGTEMP_LENGTH];
+ VM_SAFEPARMCOUNTRANGE(1, 8, VM_stof);
VM_VarString(0, string, sizeof(string));
PRVM_G_FLOAT(OFS_RETURN) = atof(string);
}
struct tm *tm;
char fmt[VM_STRINGTEMP_LENGTH];
char result[VM_STRINGTEMP_LENGTH];
- VM_VarString(0, fmt, sizeof(fmt));
+ VM_SAFEPARMCOUNTRANGE(2, 8, VM_strftime);
+ VM_VarString(1, fmt, sizeof(fmt));
t = time(NULL);
if (PRVM_G_FLOAT(OFS_PARM0))
tm = localtime(&t);
void VM_spawn (void)
{
prvm_edict_t *ed;
+ VM_SAFEPARMCOUNT(0, VM_spawn);
prog->xfunction->builtinsprofile += 20;
ed = PRVM_ED_Alloc();
VM_RETURN_EDICT(ed);
VM_RETURN_EDICT(chain);
}
+/*
+=========
+VM_precache_sound
+
+string precache_sound (string sample)
+=========
+*/
+void VM_precache_sound (void)
+{
+ const char *s;
+
+ VM_SAFEPARMCOUNT(1, VM_precache_sound);
+
+ s = PRVM_G_STRING(OFS_PARM0);
+ PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
+ VM_CheckEmptyString(s);
+
+ if(snd_initialized.integer && !S_PrecacheSound(s, true, false))
+ {
+ VM_Warning("VM_precache_sound: Failed to load %s for %s\n", s, PRVM_NAME);
+ return;
+ }
+}
+
+/*
+=================
+VM_precache_file
+
+returns the same string as output
+
+does nothing, only used by qcc to build .pak archives
+=================
+*/
+void VM_precache_file (void)
+{
+ VM_SAFEPARMCOUNT(1,VM_precache_file);
+ // precache_file is only used to copy files with qcc, it does nothing
+ PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
+}
+
/*
=========
VM_coredump
int i;
prvm_edict_t *ent;
+ VM_SAFEPARMCOUNT(1, VM_nextent);
+
i = PRVM_G_EDICTNUM(OFS_PARM0);
while (1)
{
=========
VM_registercvar
-float registercvar (string name, string value, float flags)
+float registercvar (string name, string value[, float flags])
=========
*/
void VM_registercvar (void)
const char *name, *value;
int flags;
- VM_SAFEPARMCOUNT(3,VM_registercvar);
+ VM_SAFEPARMCOUNTRANGE(2, 3, VM_registercvar);
name = PRVM_G_STRING(OFS_PARM0);
value = PRVM_G_STRING(OFS_PARM1);
- flags = (int)PRVM_G_FLOAT(OFS_PARM2);
+ flags = prog->argc >= 3 ? (int)PRVM_G_FLOAT(OFS_PARM2) : 0;
PRVM_G_FLOAT(OFS_RETURN) = 0;
if(flags > CVAR_MAXFLAGSVAL)
PRVM_G_FLOAT(OFS_RETURN) = 1; // success
}
+
/*
=================
VM_min
*/
void VM_min (void)
{
+ VM_SAFEPARMCOUNTRANGE(2, 8, VM_min);
// LordHavoc: 3+ argument enhancement suggested by FrikaC
- if (prog->argc == 2)
- PRVM_G_FLOAT(OFS_RETURN) = min(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
- else if (prog->argc >= 3)
+ if (prog->argc >= 3)
{
int i;
float f = PRVM_G_FLOAT(OFS_PARM0);
for (i = 1;i < prog->argc;i++)
- if (PRVM_G_FLOAT((OFS_PARM0+i*3)) < f)
+ if (f > PRVM_G_FLOAT((OFS_PARM0+i*3)))
f = PRVM_G_FLOAT((OFS_PARM0+i*3));
PRVM_G_FLOAT(OFS_RETURN) = f;
}
else
- PRVM_ERROR("VM_min: %s must supply at least 2 floats", PRVM_NAME);
+ PRVM_G_FLOAT(OFS_RETURN) = min(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
}
/*
*/
void VM_max (void)
{
+ VM_SAFEPARMCOUNTRANGE(2, 8, VM_max);
// LordHavoc: 3+ argument enhancement suggested by FrikaC
- if (prog->argc == 2)
- PRVM_G_FLOAT(OFS_RETURN) = max(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
- else if (prog->argc >= 3)
+ if (prog->argc >= 3)
{
int i;
float f = PRVM_G_FLOAT(OFS_PARM0);
for (i = 1;i < prog->argc;i++)
- if (PRVM_G_FLOAT((OFS_PARM0+i*3)) > f)
+ if (f < PRVM_G_FLOAT((OFS_PARM0+i*3)))
f = PRVM_G_FLOAT((OFS_PARM0+i*3));
PRVM_G_FLOAT(OFS_RETURN) = f;
}
else
- PRVM_ERROR("VM_max: %s must supply at least 2 floats", PRVM_NAME);
+ PRVM_G_FLOAT(OFS_RETURN) = max(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
}
/*
PRVM_G_FLOAT(OFS_RETURN) = pow(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
}
-/*
-=================
-VM_copyentity
-
-copies data from one entity to another
-
-copyentity(entity src, entity dst)
-=================
-*/
-void VM_copyentity (void)
-{
- prvm_edict_t *in, *out;
- VM_SAFEPARMCOUNT(2,VM_copyentity);
- in = PRVM_G_EDICT(OFS_PARM0);
- out = PRVM_G_EDICT(OFS_PARM1);
- memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
-}
-
void VM_Files_Init(void)
{
int i;
}
}
-qfile_t *VM_GetFileHandle( int index )
+static qfile_t *VM_GetFileHandle( int index )
{
if (index < 0 || index >= PRVM_MAX_OPENFILES)
{
Con_Printf("fputs: %s: %s\n", PRVM_NAME, string);
}
+/*
+=========
+VM_writetofile
+
+ writetofile(float fhandle, entity ent)
+=========
+*/
+void VM_writetofile(void)
+{
+ prvm_edict_t * ent;
+ qfile_t *file;
+
+ VM_SAFEPARMCOUNT(2, VM_writetofile);
+
+ file = VM_GetFileHandle( (int)PRVM_G_FLOAT(OFS_PARM0) );
+ if( !file )
+ {
+ VM_Warning("VM_writetofile: invalid or closed file handle\n");
+ return;
+ }
+
+ ent = PRVM_G_EDICT(OFS_PARM1);
+ if(ent->priv.required->free)
+ {
+ VM_Warning("VM_writetofile: %s: entity %i is free !\n", PRVM_NAME, PRVM_NUM_FOR_EDICT(ent));
+ return;
+ }
+
+ PRVM_ED_Write (file, ent);
+}
+
/*
=========
VM_strlen
void VM_strcat(void)
{
char s[VM_STRINGTEMP_LENGTH];
-
- if(prog->argc < 1)
- PRVM_ERROR("VM_strcat wrong parameter count (min. 1 expected ) !");
+ VM_SAFEPARMCOUNTRANGE(1, 8, VM_strcat);
VM_VarString(0, s, sizeof(s));
PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(s);
{
VM_SAFEPARMCOUNT(0,VM_serverstate);
- PRVM_G_FLOAT(OFS_RETURN) = sv.active;
+ PRVM_G_FLOAT(OFS_RETURN) = sv.active && (svs.maxclients > 1 || cls.state == ca_dedicated);
}
/*
CL_RestartVideo( video );
}
+/*
+==============
+VM_makevectors
+
+Writes new values for v_forward, v_up, and v_right based on angles
+void makevectors(vector angle)
+==============
+*/
+void VM_makevectors (void)
+{
+ prvm_eval_t *valforward, *valright, *valup;
+ valforward = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_forward);
+ valright = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_right);
+ valup = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_up);
+ if (!valforward || !valright || !valup)
+ {
+ VM_Warning("makevectors: could not find v_forward, v_right, or v_up global variables\n");
+ return;
+ }
+ VM_SAFEPARMCOUNT(1, VM_makevectors);
+ AngleVectors (PRVM_G_VECTOR(OFS_PARM0), valforward->vector, valright->vector, valup->vector);
+}
+
/*
==============
VM_vectorvectors
Writes new values for v_forward, v_up, and v_right based on the given forward vector
-vectorvectors(vector, vector)
+vectorvectors(vector)
==============
*/
void VM_vectorvectors (void)
{
- VectorNormalize2(PRVM_G_VECTOR(OFS_PARM0), prog->globals.server->v_forward);
- VectorVectors(prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up);
+ prvm_eval_t *valforward, *valright, *valup;
+ valforward = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_forward);
+ valright = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_right);
+ valup = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_up);
+ if (!valforward || !valright || !valup)
+ {
+ VM_Warning("vectorvectors: could not find v_forward, v_right, or v_up global variables\n");
+ return;
+ }
+ VM_SAFEPARMCOUNT(1, VM_vectorvectors);
+ VectorNormalize2(PRVM_G_VECTOR(OFS_PARM0), valforward->vector);
+ VectorVectors(valforward->vector, valright->vector, valup->vector);
}
/*
DrawQ_Line(width, c1[0], c1[1], c2[0], c2[1], rgb[0], rgb[1], rgb[2], alpha, flags);
}
-//====================
-//QC POLYGON functions
-//====================
-
-typedef struct
-{
- rtexture_t *tex;
- float data[36]; //[515]: enough for polygons
- unsigned char flags; //[515]: + VM_POLYGON_2D and VM_POLYGON_FL4V flags
-}vm_polygon_t;
-
-//static float vm_polygon_linewidth = 1;
-static mempool_t *vm_polygons_pool = NULL;
-static unsigned char vm_current_vertices = 0;
-static qboolean vm_polygons_initialized = false;
-static vm_polygon_t *vm_polygons = NULL;
-static unsigned long vm_polygons_num = 0, vm_drawpolygons_num = 0; //[515]: ok long on 64bit ?
-static qboolean vm_polygonbegin = false; //[515]: for "no-crap-on-the-screen" check
-#define VM_DEFPOLYNUM 64 //[515]: enough for default ?
-
-#define VM_POLYGON_FL3V 16 //more than 2 vertices (used only for lines)
-#define VM_POLYGON_FLLINES 32
-#define VM_POLYGON_FL2D 64
-#define VM_POLYGON_FL4V 128 //4 vertices
-
-void VM_InitPolygons (void)
-{
- vm_polygons_pool = Mem_AllocPool("VMPOLY", 0, NULL);
- vm_polygons = (vm_polygon_t *)Mem_Alloc(vm_polygons_pool, VM_DEFPOLYNUM*sizeof(vm_polygon_t));
- memset(vm_polygons, 0, VM_DEFPOLYNUM*sizeof(vm_polygon_t));
- vm_polygons_num = VM_DEFPOLYNUM;
- vm_drawpolygons_num = 0;
- vm_polygonbegin = false;
- vm_polygons_initialized = true;
-}
-
-void VM_DrawPolygonCallback (const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
-{
- int surfacelistindex;
- // LordHavoc: FIXME: this is stupid code
- for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
- {
- const vm_polygon_t *p = &vm_polygons[surfacelist[surfacelistindex]];
- int flags = p->flags & 0x0f;
-
- if(flags == DRAWFLAG_ADDITIVE)
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
- else if(flags == DRAWFLAG_MODULATE)
- GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
- else if(flags == DRAWFLAG_2XMODULATE)
- GL_BlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
- else
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- R_Mesh_TexBind(0, R_GetTexture(p->tex));
-
- CHECKGLERROR
- //[515]: is speed is max ?
- if(p->flags & VM_POLYGON_FLLINES) //[515]: lines
- {
- qglLineWidth(p->data[13]);CHECKGLERROR
- qglBegin(GL_LINE_LOOP);
- qglTexCoord1f (p->data[12]);
- qglColor4f (p->data[20], p->data[21], p->data[22], p->data[23]);
- qglVertex3f (p->data[0] , p->data[1], p->data[2]);
-
- qglTexCoord1f (p->data[14]);
- qglColor4f (p->data[24], p->data[25], p->data[26], p->data[27]);
- qglVertex3f (p->data[3] , p->data[4], p->data[5]);
-
- if(p->flags & VM_POLYGON_FL3V)
- {
- qglTexCoord1f (p->data[16]);
- qglColor4f (p->data[28], p->data[29], p->data[30], p->data[31]);
- qglVertex3f (p->data[6] , p->data[7], p->data[8]);
-
- if(p->flags & VM_POLYGON_FL4V)
- {
- qglTexCoord1f (p->data[18]);
- qglColor4f (p->data[32], p->data[33], p->data[34], p->data[35]);
- qglVertex3f (p->data[9] , p->data[10], p->data[11]);
- }
- }
- qglEnd();
- CHECKGLERROR
- }
- else
- {
- qglBegin(GL_POLYGON);
- qglTexCoord2f (p->data[12], p->data[13]);
- qglColor4f (p->data[20], p->data[21], p->data[22], p->data[23]);
- qglVertex3f (p->data[0] , p->data[1], p->data[2]);
-
- qglTexCoord2f (p->data[14], p->data[15]);
- qglColor4f (p->data[24], p->data[25], p->data[26], p->data[27]);
- qglVertex3f (p->data[3] , p->data[4], p->data[5]);
-
- qglTexCoord2f (p->data[16], p->data[17]);
- qglColor4f (p->data[28], p->data[29], p->data[30], p->data[31]);
- qglVertex3f (p->data[6] , p->data[7], p->data[8]);
-
- if(p->flags & VM_POLYGON_FL4V)
- {
- qglTexCoord2f (p->data[18], p->data[19]);
- qglColor4f (p->data[32], p->data[33], p->data[34], p->data[35]);
- qglVertex3f (p->data[9] , p->data[10], p->data[11]);
- }
- qglEnd();
- CHECKGLERROR
- }
- }
-}
-
-void VM_AddPolygonTo2DScene (vm_polygon_t *p)
-{
- drawqueuemesh_t mesh;
- static int picelements[6] = {0, 1, 2, 0, 2, 3};
-
- mesh.texture = p->tex;
- mesh.data_element3i = picelements;
- mesh.data_vertex3f = p->data;
- mesh.data_texcoord2f = p->data + 12;
- mesh.data_color4f = p->data + 20;
- if(p->flags & VM_POLYGON_FL4V)
- {
- mesh.num_vertices = 4;
- mesh.num_triangles = 2;
- }
- else
- {
- mesh.num_vertices = 3;
- mesh.num_triangles = 1;
- }
- if(p->flags & VM_POLYGON_FLLINES) //[515]: lines
- DrawQ_LineLoop (&mesh, (p->flags&0x0f));
- else
- DrawQ_Mesh (&mesh, (p->flags&0x0f));
-}
-
-//void(string texturename, float flag, float 2d, float lines) R_BeginPolygon
-void VM_R_PolygonBegin (void)
-{
- vm_polygon_t *p;
- const char *picname;
- if(prog->argc < 2)
- VM_SAFEPARMCOUNT(2, VM_R_PolygonBegin);
-
- if(!vm_polygons_initialized)
- VM_InitPolygons();
- if(vm_polygonbegin)
- {
- VM_Warning("VM_R_PolygonBegin: called twice without VM_R_PolygonEnd after first\n");
- return;
- }
- if(vm_drawpolygons_num >= vm_polygons_num)
- {
- p = (vm_polygon_t *)Mem_Alloc(vm_polygons_pool, 2 * vm_polygons_num * sizeof(vm_polygon_t));
- memset(p, 0, 2 * vm_polygons_num * sizeof(vm_polygon_t));
- memcpy(p, vm_polygons, vm_polygons_num * sizeof(vm_polygon_t));
- Mem_Free(vm_polygons);
- vm_polygons = p;
- vm_polygons_num *= 2;
- }
- p = &vm_polygons[vm_drawpolygons_num];
- picname = PRVM_G_STRING(OFS_PARM0);
- if(picname[0])
- p->tex = Draw_CachePic(picname, true)->tex;
- else
- p->tex = r_texture_white;
- p->flags = (unsigned char)PRVM_G_FLOAT(OFS_PARM1);
- vm_current_vertices = 0;
- vm_polygonbegin = true;
- if(prog->argc >= 3)
- {
- if(PRVM_G_FLOAT(OFS_PARM2))
- p->flags |= VM_POLYGON_FL2D;
- if(prog->argc >= 4 && PRVM_G_FLOAT(OFS_PARM3))
- {
- p->data[13] = PRVM_G_FLOAT(OFS_PARM3); //[515]: linewidth
- p->flags |= VM_POLYGON_FLLINES;
- }
- }
-}
-
-//void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
-void VM_R_PolygonVertex (void)
-{
- float *coords, *tx, *rgb, alpha;
- vm_polygon_t *p;
- VM_SAFEPARMCOUNT(4, VM_R_PolygonVertex);
-
- if(!vm_polygonbegin)
- {
- VM_Warning("VM_R_PolygonVertex: VM_R_PolygonBegin wasn't called\n");
- return;
- }
- coords = PRVM_G_VECTOR(OFS_PARM0);
- tx = PRVM_G_VECTOR(OFS_PARM1);
- rgb = PRVM_G_VECTOR(OFS_PARM2);
- alpha = PRVM_G_FLOAT(OFS_PARM3);
-
- p = &vm_polygons[vm_drawpolygons_num];
- if(vm_current_vertices > 4)
- {
- VM_Warning("VM_R_PolygonVertex: may have 4 vertices max\n");
- return;
- }
-
- p->data[vm_current_vertices*3] = coords[0];
- p->data[1+vm_current_vertices*3] = coords[1];
- p->data[2+vm_current_vertices*3] = coords[2];
-
- p->data[12+vm_current_vertices*2] = tx[0];
- if(!(p->flags & VM_POLYGON_FLLINES))
- p->data[13+vm_current_vertices*2] = tx[1];
-
- p->data[20+vm_current_vertices*4] = rgb[0];
- p->data[21+vm_current_vertices*4] = rgb[1];
- p->data[22+vm_current_vertices*4] = rgb[2];
- p->data[23+vm_current_vertices*4] = alpha;
-
- vm_current_vertices++;
- if(vm_current_vertices == 4)
- p->flags |= VM_POLYGON_FL4V;
- else
- if(vm_current_vertices == 3)
- p->flags |= VM_POLYGON_FL3V;
-}
-
-//void() R_EndPolygon
-void VM_R_PolygonEnd (void)
-{
- if(!vm_polygonbegin)
- {
- VM_Warning("VM_R_PolygonEnd: VM_R_PolygonBegin wasn't called\n");
- return;
- }
- vm_polygonbegin = false;
- if(vm_current_vertices > 2 || (vm_current_vertices >= 2 && vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FLLINES))
- {
- if(vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FL2D) //[515]: don't use qcpolygons memory if 2D
- VM_AddPolygonTo2DScene(&vm_polygons[vm_drawpolygons_num]);
- else
- vm_drawpolygons_num++;
- }
- else
- VM_Warning("VM_R_PolygonEnd: %i vertices isn't a good choice\n", vm_current_vertices);
-}
-
-void VM_AddPolygonsToMeshQueue (void)
-{
- int i;
- if(!vm_drawpolygons_num)
- return;
- R_Mesh_Matrix(&identitymatrix);
- GL_CullFace(GL_NONE);
- for(i = 0;i < (int)vm_drawpolygons_num;i++)
- VM_DrawPolygonCallback(NULL, NULL, 1, &i);
- vm_drawpolygons_num = 0;
-}
-
-void Debug_PolygonBegin(const char *picname, int flags, qboolean draw2d, float linewidth)
-{
- vm_polygon_t *p;
-
- if(!vm_polygons_initialized)
- VM_InitPolygons();
- if(vm_polygonbegin)
- {
- Con_Printf("Debug_PolygonBegin: called twice without Debug_PolygonEnd after first\n");
- return;
- }
- // limit polygons to a vaguely sane amount, beyond this each one just
- // replaces the last one
- vm_drawpolygons_num = min(vm_drawpolygons_num, (1<<20)-1);
- if(vm_drawpolygons_num >= vm_polygons_num)
- {
- p = (vm_polygon_t *)Mem_Alloc(vm_polygons_pool, 2 * vm_polygons_num * sizeof(vm_polygon_t));
- memset(p, 0, 2 * vm_polygons_num * sizeof(vm_polygon_t));
- memcpy(p, vm_polygons, vm_polygons_num * sizeof(vm_polygon_t));
- Mem_Free(vm_polygons);
- vm_polygons = p;
- vm_polygons_num *= 2;
- }
- p = &vm_polygons[vm_drawpolygons_num];
- if(picname && picname[0])
- p->tex = Draw_CachePic(picname, true)->tex;
- else
- p->tex = r_texture_white;
- p->flags = flags;
- vm_current_vertices = 0;
- vm_polygonbegin = true;
- if(draw2d)
- p->flags |= VM_POLYGON_FL2D;
- if(linewidth)
- {
- p->data[13] = linewidth; //[515]: linewidth
- p->flags |= VM_POLYGON_FLLINES;
- }
-}
-
-void Debug_PolygonVertex(float x, float y, float z, float s, float t, float r, float g, float b, float a)
-{
- vm_polygon_t *p;
-
- if(!vm_polygonbegin)
- {
- Con_Printf("Debug_PolygonVertex: Debug_PolygonBegin wasn't called\n");
- return;
- }
-
- p = &vm_polygons[vm_drawpolygons_num];
- if(vm_current_vertices > 4)
- {
- Con_Printf("Debug_PolygonVertex: may have 4 vertices max\n");
- return;
- }
-
- p->data[vm_current_vertices*3] = x;
- p->data[1+vm_current_vertices*3] = y;
- p->data[2+vm_current_vertices*3] = z;
-
- p->data[12+vm_current_vertices*2] = s;
- if(!(p->flags & VM_POLYGON_FLLINES))
- p->data[13+vm_current_vertices*2] = t;
-
- p->data[20+vm_current_vertices*4] = r;
- p->data[21+vm_current_vertices*4] = g;
- p->data[22+vm_current_vertices*4] = b;
- p->data[23+vm_current_vertices*4] = a;
-
- vm_current_vertices++;
- if(vm_current_vertices == 4)
- p->flags |= VM_POLYGON_FL4V;
- else
- if(vm_current_vertices == 3)
- p->flags |= VM_POLYGON_FL3V;
-}
-
-void Debug_PolygonEnd(void)
-{
- if(!vm_polygonbegin)
- {
- Con_Printf("Debug_PolygonEnd: Debug_PolygonBegin wasn't called\n");
- return;
- }
- vm_polygonbegin = false;
- if(vm_current_vertices > 2 || (vm_current_vertices >= 2 && vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FLLINES))
- {
- if(vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FL2D) //[515]: don't use qcpolygons memory if 2D
- VM_AddPolygonTo2DScene(&vm_polygons[vm_drawpolygons_num]);
- else
- vm_drawpolygons_num++;
- }
- else
- Con_Printf("Debug_PolygonEnd: %i vertices isn't a good choice\n", vm_current_vertices);
-}
-
char *out;
char outstr[VM_STRINGTEMP_LENGTH];
+ VM_SAFEPARMCOUNT(3, VM_altstr_ins);
+
in = instr = PRVM_G_STRING( OFS_PARM0 );
num = (int)PRVM_G_FLOAT( OFS_PARM1 );
set = setstr = PRVM_G_STRING( OFS_PARM2 );
char *strings[MAX_QCSTR_STRINGS];
}qcstrbuffer_t;
+// FIXME: move stringbuffers to prog_t to allow multiple progs!
static qcstrbuffer_t *qcstringbuffers[MAX_QCSTR_BUFFERS];
static int num_qcstringbuffers;
static int buf_sortpower;
return strncmp(b, a, buf_sortpower);
}
-#ifdef REMOVETHIS
-static void VM_BufStr_Init (void)
-{
- memset(qcstringbuffers, 0, sizeof(qcstringbuffers));
- num_qcstringbuffers = 0;
-}
-
-static void VM_BufStr_ShutDown (void)
-{
- int i;
- for(i=0;i<MAX_QCSTR_BUFFERS && num_qcstringbuffers;i++)
- BufStr_ClearBuffer(i);
-}
-#endif
-
/*
========================
VM_buf_create
prvm_edict_t *ent;
float ideal, current, move, speed;
+ VM_SAFEPARMCOUNT(0, VM_changeyaw);
+
ent = PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict);
if (ent == prog->edicts)
{
prvm_edict_t *ent;
float ideal, current, move, speed;
+ VM_SAFEPARMCOUNT(1, VM_changepitch);
+
ent = PRVM_G_EDICT(OFS_PARM0);
if (ent == prog->edicts)
{
PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.angles)->vector[0] = ANGLEMOD (current + move);
}
+
+static int Is_Text_Color (char c, char t)
+{
+ int a = 0;
+ char c2 = c - (c & 128);
+ char t2 = t - (t & 128);
+
+ if(c != STRING_COLOR_TAG && c2 != STRING_COLOR_TAG) return 0;
+ if(t >= '0' && t <= '9') a = 1;
+ if(t2 >= '0' && t2 <= '9') a = 1;
+/* if(t >= 'A' && t <= 'Z') a = 2;
+ if(t2 >= 'A' && t2 <= 'Z') a = 2;
+
+ if(a == 1 && scr_colortext.integer > 0)
+ return 1;
+ if(a == 2 && scr_multifonts.integer > 0)
+ return 2;
+*/
+ return a;
+}
+
+void VM_uncolorstring (void)
+{
+ const char *in;
+ char out[VM_STRINGTEMP_LENGTH];
+ int k = 0, i = 0;
+
+ VM_SAFEPARMCOUNT(1, VM_uncolorstring);
+ in = PRVM_G_STRING(OFS_PARM0);
+ VM_CheckEmptyString (in);
+
+ while (in[k])
+ {
+ if(in[k+1])
+ if(Is_Text_Color(in[k], in[k+1]) == 1/* || (in[k] == '&' && in[k+1] == 'r')*/)
+ {
+ k += 2;
+ continue;
+ }
+ out[i] = in[k];
+ ++k;
+ ++i;
+ }
+ PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(out);
+}
+
+//#222 string(string s, float index) str2chr (FTE_STRINGS)
+void VM_str2chr (void)
+{
+ const char *s;
+ VM_SAFEPARMCOUNT(2, VM_str2chr);
+ s = PRVM_G_STRING(OFS_PARM0);
+ if((unsigned)PRVM_G_FLOAT(OFS_PARM1) > strlen(s))
+ return;
+ PRVM_G_FLOAT(OFS_RETURN) = (unsigned char)s[(int)PRVM_G_FLOAT(OFS_PARM1)];
+}
+
+//#223 string(float c, ...) chr2str (FTE_STRINGS)
+void VM_chr2str (void)
+{
+ char t[9];
+ int i;
+ VM_SAFEPARMCOUNTRANGE(0, 8, VM_chr2str);
+ for(i = 0;i < prog->argc && i < (int)sizeof(t) - 1;i++)
+ t[i] = (unsigned char)PRVM_G_FLOAT(OFS_PARM0+i*3);
+ t[i] = 0;
+ PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
+}
+
+//#228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
+void VM_strncmp (void)
+{
+ const char *s1, *s2;
+ VM_SAFEPARMCOUNT(1, VM_strncmp);
+ s1 = PRVM_G_STRING(OFS_PARM0);
+ s2 = PRVM_G_STRING(OFS_PARM1);
+ PRVM_G_FLOAT(OFS_RETURN) = strncmp(s1, s2, (size_t)PRVM_G_FLOAT(OFS_PARM2));
+}
+
+void VM_wasfreed (void)
+{
+ VM_SAFEPARMCOUNT(1, VM_wasfreed);
+ PRVM_G_FLOAT(OFS_RETURN) = PRVM_G_EDICT(OFS_PARM0)->priv.required->free;
+}
+
+void VM_SetTraceGlobals(const trace_t *trace)
+{
+ prvm_eval_t *val;
+ if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_allsolid)))
+ val->_float = trace->allsolid;
+ if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_startsolid)))
+ val->_float = trace->startsolid;
+ if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_fraction)))
+ val->_float = trace->fraction;
+ if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_inwater)))
+ val->_float = trace->inwater;
+ if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_inopen)))
+ val->_float = trace->inopen;
+ if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_endpos)))
+ VectorCopy(trace->endpos, val->vector);
+ if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_plane_normal)))
+ VectorCopy(trace->plane.normal, val->vector);
+ if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_plane_dist)))
+ val->_float = trace->plane.dist;
+ if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_ent)))
+ val->edict = PRVM_EDICT_TO_PROG(trace->ent ? trace->ent : prog->edicts);
+ if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dpstartcontents)))
+ val->_float = trace->startsupercontents;
+ if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitcontents)))
+ val->_float = trace->hitsupercontents;
+ if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitq3surfaceflags)))
+ val->_float = trace->hitq3surfaceflags;
+ if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphittexturename)))
+ val->string = trace->hittexture ? PRVM_SetTempString(trace->hittexture->name) : 0;
+}
+
//=============
void VM_Cmd_Init(void)
VM_Files_Init();
VM_Search_Init();
// VM_BufStr_Init();
- if(vm_polygons_initialized)
- {
- Mem_FreePool(&vm_polygons_pool);
- vm_polygons_initialized = false;
- }
}
void VM_Cmd_Reset(void)
VM_Search_Reset();
VM_Files_CloseAll();
// VM_BufStr_ShutDown();
- if(vm_polygons_initialized)
- {
- Mem_FreePool(&vm_polygons_pool);
- vm_polygons_initialized = false;
- }
}
// nice helper macros
#ifndef VM_NOPARMCHECK
-#define VM_SAFEPARMCOUNT(p,f) if(prog->argc != p) PRVM_ERROR(#f " wrong parameter count (" #p " expected ) !")
+#define VM_SAFEPARMCOUNTRANGE(p1,p2,f) if(prog->argc < p1 || prog->argc > p2) PRVM_ERROR(#f " wrong parameter count %i (" #p1 " to " #p2 " expected ) !", prog->argc)
+#define VM_SAFEPARMCOUNT(p,f) if(prog->argc != p) PRVM_ERROR(#f " wrong parameter count %i (" #p " expected ) !", prog->argc)
#else
+#define VM_SAFEPARMCOUNTRANGE(p1,p2,f)
#define VM_SAFEPARMCOUNT(p,f)
#endif
#define VM_RETURN_EDICT(e) (((int *)prog->globals.generic)[OFS_RETURN] = PRVM_EDICT_TO_PROG(e))
-#define e10 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
-#define e100 e10,e10,e10,e10,e10,e10,e10,e10,e10,e10
-#define e1000 e100,e100,e100,e100,e100,e100,e100,e100,e100,e100
-
-#define VM_STRINGTEMP_BUFFERS 16
#define VM_STRINGTEMP_LENGTH MAX_INPUTLINE
// builtins and other general functions
void VM_findflags (void);
void VM_findchainflags (void);
void VM_precache_file (void);
-void VM_precache_error (void);
void VM_precache_sound (void);
void VM_coredump (void);
void VM_max (void);
void VM_bound (void);
void VM_pow (void);
-void VM_copyentity (void);
void VM_asin (void);
void VM_acos (void);
void VM_atan (void);
void VM_fclose(void);
void VM_fgets(void);
void VM_fputs(void);
-// used by M_WriteToFile
-// should be only called from a builtin
-qfile_t *VM_GetFileHandle( int index );
+void VM_writetofile(void); // only used by menu
void VM_strlen(void);
void VM_strcat(void);
void VM_drawresetcliparea(void);
void VM_getimagesize(void);
+void VM_makevectors (void);
void VM_vectorvectors (void);
void VM_keynumtostring (void);
void VM_cin_restart( void );
void VM_drawline (void);
-void VM_R_PolygonBegin (void);
-void VM_R_PolygonVertex (void);
-void VM_R_PolygonEnd (void);
void VM_bitshift (void);
void VM_changeyaw (void);
void VM_changepitch (void);
+void VM_uncolorstring (void);
+void VM_str2chr (void);
+void VM_chr2str (void);
+void VM_strncmp (void);
+void VM_registercvar (void);
+void VM_wasfreed (void);
+
+void VM_SetTraceGlobals(const trace_t *trace);
+
void VM_Cmd_Init(void);
void VM_Cmd_Reset(void);
// clip start origin
if (e->clipping)
{
- trace = CL_TraceBox(e->origin, vec3_origin, vec3_origin, e->vert[j], true, NULL, SUPERCONTENTS_SOLID, false);
+ trace = CL_Move(e->origin, vec3_origin, vec3_origin, e->vert[j], MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false);
VectorCopy(trace.endpos, e->vert[i]);
}
}
VectorMA(e->vert[i], frametime, e->vertvel[i], end);
if (e->clipping)
{
- trace = CL_TraceBox(e->vert[i], vec3_origin, vec3_origin, end, true, NULL, SUPERCONTENTS_SOLID, false);
+ trace = CL_Move(e->vert[i], vec3_origin, vec3_origin, end, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false);
if (trace.fraction < 1)
{
// clip velocity against the wall
R_Mesh_Matrix(&identitymatrix);
viewdist = DotProduct(r_view.origin, r_view.forward);
flag = r_refdef.rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
+ // FIXME: these traces should scan all render entities instead of cl.world
for (lnum = 0, light = r_shadow_worldlightchain;light;light = light->next, lnum++)
{
- if ((light->flags & flag) && light->corona * r_coronas.value > 0 && (r_shadow_debuglight.integer < 0 || r_shadow_debuglight.integer == lnum) && (dist = (DotProduct(light->rtlight.shadoworigin, r_view.forward) - viewdist)) >= 24.0f && CL_TraceBox(light->rtlight.shadoworigin, vec3_origin, vec3_origin, r_view.origin, true, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
+ if ((light->flags & flag) && light->corona * r_coronas.value > 0 && (r_shadow_debuglight.integer < 0 || r_shadow_debuglight.integer == lnum) && (dist = (DotProduct(light->rtlight.shadoworigin, r_view.forward) - viewdist)) >= 24.0f && CL_Move(light->rtlight.shadoworigin, vec3_origin, vec3_origin, r_view.origin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1)
{
cscale = light->rtlight.corona * r_coronas.value * 0.25f;
scale = light->rtlight.radius * light->rtlight.coronasizescale;
for (i = 0;i < r_refdef.numlights;i++)
{
rtlight = &r_refdef.lights[i];
- if ((rtlight->flags & flag) && rtlight->corona * r_coronas.value > 0 && (dist = (DotProduct(rtlight->shadoworigin, r_view.forward) - viewdist)) >= 24.0f && CL_TraceBox(rtlight->shadoworigin, vec3_origin, vec3_origin, r_view.origin, true, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
+ if ((rtlight->flags & flag) && rtlight->corona * r_coronas.value > 0 && (dist = (DotProduct(rtlight->shadoworigin, r_view.forward) - viewdist)) >= 24.0f && CL_Move(rtlight->shadoworigin, vec3_origin, vec3_origin, r_view.origin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1)
{
cscale = rtlight->corona * r_coronas.value * 0.25f;
scale = rtlight->radius * rtlight->coronasizescale;
light = &r_refdef.lights[i];
Matrix4x4_Transform(&light->matrix_worldtolight, p, v);
f = 1 - VectorLength2(v);
- if (f > 0 && CL_TraceBox(p, vec3_origin, vec3_origin, light->shadoworigin, false, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
+ if (f > 0 && CL_Move(p, vec3_origin, vec3_origin, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1)
VectorMA(ambientcolor, f, light->currentcolor, ambientcolor);
}
}
if (rating >= 0.95)
{
rating /= (1 + 0.0625f * sqrt(DotProduct(temp, temp)));
- if (bestrating < rating && CL_TraceBox(light->origin, vec3_origin, vec3_origin, r_view.origin, true, NULL, SUPERCONTENTS_SOLID, false).fraction == 1.0f)
+ if (bestrating < rating && CL_Move(light->origin, vec3_origin, vec3_origin, r_view.origin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1.0f)
{
bestrating = rating;
best = light;
vec3_t dest, endpos;
trace_t trace;
VectorMA(r_view.origin, r_editlights_cursordistance.value, r_view.forward, dest);
- trace = CL_TraceBox(r_view.origin, vec3_origin, vec3_origin, dest, true, NULL, SUPERCONTENTS_SOLID, false);
+ trace = CL_Move(r_view.origin, vec3_origin, vec3_origin, dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false);
if (trace.fraction < 1)
{
dist = trace.fraction * r_editlights_cursordistance.value;
// note this is in server_t rather than server_static_t so that it is
// reset on each map command (such as New Game in singleplayer)
server_connectfloodaddress_t connectfloodaddresses[MAX_CONNECTFLOODADDRESSES];
+
+#define SV_MAX_PARTICLEEFFECTNAME 256
+ qboolean particleeffectnamesloaded;
+ char particleeffectname[SV_MAX_PARTICLEEFFECTNAME][MAX_QPATH];
} server_t;
// if defined this does ping smoothing, otherwise it does not
int SV_ModelIndex(const char *s, int precachemode);
int SV_SoundIndex(const char *s, int precachemode);
+int SV_ParticleEffectIndex(const char *name);
+
void SV_SetIdealPitch (void);
void SV_AddUpdates (void);
qboolean SV_PlayerCheckGround (prvm_edict_t *ent);
qboolean SV_CheckBottom (prvm_edict_t *ent);
-qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink);
+qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean noenemy, qboolean settrace);
// 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
void SV_LinkEdict (prvm_edict_t *ent, qboolean touch_triggers);
-// traces a box move against a single entity
-// mins and maxs are relative
-//
-// if the entire move stays in a single solid brush, trace.allsolid will be set
-//
-// if the starting point is in a solid, it will be allowed to move out to an
-// open area, and trace.startsolid will be set
-//
-// type is one of the MOVE_ values such as MOVE_NOMONSTERS which skips box
-// entities, only colliding with SOLID_BSP entities (doors, lifts)
-//
-// passedict is excluded from clipping checks
-struct trace_s SV_Move_ClipToEntity(prvm_edict_t *ent, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int movetype, int hitsupercontents);
-
+// calculates hitsupercontentsmask for a generic qc entity
+int SV_GenericHitSuperContentsMask(const prvm_edict_t *edict);
// traces a box move against worldmodel and all entities in the specified area
-trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict);
+trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask);
-#define SV_PointSuperContents(point) (SV_Move((point), vec3_origin, vec3_origin, (point), sv_gameplayfix_swiminbmodels.integer ? MOVE_NOMONSTERS : MOVE_WORLDONLY, NULL).startsupercontents)
+#define SV_PointSuperContents(point) (SV_Move((point), vec3_origin, vec3_origin, (point), sv_gameplayfix_swiminbmodels.integer ? MOVE_NOMONSTERS : MOVE_WORLDONLY, NULL, 0).startsupercontents)
void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats);
return 0;
}
+// MUST match effectnameindex_t in client.h
+static const char *standardeffectnames[EFFECT_TOTAL] =
+{
+ "",
+ "TE_GUNSHOT",
+ "TE_GUNSHOTQUAD",
+ "TE_SPIKE",
+ "TE_SPIKEQUAD",
+ "TE_SUPERSPIKE",
+ "TE_SUPERSPIKEQUAD",
+ "TE_WIZSPIKE",
+ "TE_KNIGHTSPIKE",
+ "TE_EXPLOSION",
+ "TE_EXPLOSIONQUAD",
+ "TE_TAREXPLOSION",
+ "TE_TELEPORT",
+ "TE_LAVASPLASH",
+ "TE_SMALLFLASH",
+ "TE_FLAMEJET",
+ "EF_FLAME",
+ "TE_BLOOD",
+ "TE_SPARK",
+ "TE_PLASMABURN",
+ "TE_TEI_G3",
+ "TE_TEI_SMOKE",
+ "TE_TEI_BIGEXPLOSION",
+ "TE_TEI_PLASMAHIT",
+ "EF_STARDUST",
+ "TR_ROCKET",
+ "TR_GRENADE",
+ "TR_BLOOD",
+ "TR_WIZSPIKE",
+ "TR_SLIGHTBLOOD",
+ "TR_KNIGHTSPIKE",
+ "TR_VORESPIKE",
+ "TR_NEHAHRASMOKE",
+ "TR_NEXUIZPLASMA",
+ "TR_GLOWTRAIL",
+ "SVC_PARTICLE"
+};
+
+/*
+================
+SV_ParticleEffectIndex
+
+================
+*/
+int SV_ParticleEffectIndex(const char *name)
+{
+ int i, argc, linenumber, effectnameindex;
+ fs_offset_t filesize;
+ unsigned char *filedata;
+ const char *text, *textstart, *textend;
+ char argv[16][1024];
+ if (!sv.particleeffectnamesloaded)
+ {
+ sv.particleeffectnamesloaded = true;
+ memset(sv.particleeffectname, 0, sizeof(sv.particleeffectname));
+ for (i = 0;i < EFFECT_TOTAL;i++)
+ strlcpy(sv.particleeffectname[i], standardeffectnames[i], sizeof(sv.particleeffectname[i]));
+ filedata = FS_LoadFile("effectinfo.txt", tempmempool, true, &filesize);
+ if (filedata)
+ {
+ textstart = (const char *)filedata;
+ textend = (const char *)filedata + filesize;
+ text = textstart;
+ for (linenumber = 1;;linenumber++)
+ {
+ argc = 0;
+ for (;;)
+ {
+ if (!COM_ParseToken(&text, true) || !strcmp(com_token, "\n"))
+ break;
+ if (argc < 16)
+ {
+ strlcpy(argv[argc], com_token, sizeof(argv[argc]));
+ argc++;
+ }
+ }
+ if (com_token[0] == 0)
+ break; // if the loop exited and it's not a \n, it's EOF
+ if (argc < 1)
+ continue;
+ if (!strcmp(argv[0], "effect"))
+ {
+ if (argc == 2)
+ {
+ for (effectnameindex = 1;effectnameindex < SV_MAX_PARTICLEEFFECTNAME;effectnameindex++)
+ {
+ if (sv.particleeffectname[effectnameindex][0])
+ {
+ if (!strcmp(sv.particleeffectname[effectnameindex], argv[1]))
+ break;
+ }
+ else
+ {
+ strlcpy(sv.particleeffectname[effectnameindex], argv[1], sizeof(sv.particleeffectname[effectnameindex]));
+ break;
+ }
+ }
+ // if we run out of names, abort
+ if (effectnameindex == SV_MAX_PARTICLEEFFECTNAME)
+ {
+ Con_Printf("effectinfo.txt:%i: too many effects!\n", linenumber);
+ break;
+ }
+ }
+ }
+ }
+ Mem_Free(filedata);
+ }
+ }
+ // search for the name
+ for (effectnameindex = 1;effectnameindex < SV_MAX_PARTICLEEFFECTNAME && sv.particleeffectname[effectnameindex][0];effectnameindex++)
+ if (!strcmp(sv.particleeffectname[effectnameindex], name))
+ return effectnameindex;
+ // return 0 if we couldn't find it
+ return 0;
+}
+
/*
================
SV_CreateBaseline
// sv_move.c -- monster movement
#include "quakedef.h"
+#include "prvm_cmds.h"
/*
=============
start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
stop[2] = start[2] - 2*sv_stepheight.value;
- trace = SV_Move (start, vec3_origin, vec3_origin, stop, MOVE_NOMONSTERS, ent);
+ trace = SV_Move (start, vec3_origin, vec3_origin, stop, MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent));
if (trace.fraction == 1.0)
return false;
start[0] = stop[0] = x ? maxs[0] : mins[0];
start[1] = stop[1] = y ? maxs[1] : mins[1];
- trace = SV_Move (start, vec3_origin, vec3_origin, stop, MOVE_NOMONSTERS, ent);
+ trace = SV_Move (start, vec3_origin, vec3_origin, stop, MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent));
if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
bottom = trace.endpos[2];
Called by monster program code.
The move will be adjusted for slopes and stairs, but if the move isn't
-possible, no move is done, false is returned, and
-prog->globals.server->trace_normal is set to the normal of the blocking wall
+possible, no move is done and false is returned
=============
*/
-qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink)
+qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean noenemy, qboolean settrace)
{
float dz;
vec3_t oldorg, neworg, end, traceendpos;
for (i=0 ; i<2 ; i++)
{
VectorAdd (ent->fields.server->origin, move, neworg);
- enemy = PRVM_PROG_TO_EDICT(ent->fields.server->enemy);
- if (i == 0 && enemy != prog->edicts)
+ if (!noenemy)
{
- dz = ent->fields.server->origin[2] - PRVM_PROG_TO_EDICT(ent->fields.server->enemy)->fields.server->origin[2];
- if (dz > 40)
- neworg[2] -= 8;
- if (dz < 30)
- neworg[2] += 8;
+ enemy = PRVM_PROG_TO_EDICT(ent->fields.server->enemy);
+ if (i == 0 && enemy != prog->edicts)
+ {
+ dz = ent->fields.server->origin[2] - PRVM_PROG_TO_EDICT(ent->fields.server->enemy)->fields.server->origin[2];
+ if (dz > 40)
+ neworg[2] -= 8;
+ if (dz < 30)
+ neworg[2] += 8;
+ }
}
- trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, neworg, MOVE_NORMAL, ent);
+ trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, neworg, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
if (trace.fraction == 1)
{
VectorCopy (neworg, end);
end[2] -= sv_stepheight.value*2;
- trace = SV_Move (neworg, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
+ trace = SV_Move (neworg, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
if (trace.startsolid)
{
neworg[2] -= sv_stepheight.value;
- trace = SV_Move (neworg, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
+ trace = SV_Move (neworg, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
if (trace.startsolid)
return false;
}
move[2] = 0;
VectorCopy (ent->fields.server->origin, oldorigin);
- if (SV_movestep (ent, move, false))
+ if (SV_movestep (ent, move, false, false, false))
{
delta = ent->fields.server->angles[YAW] - ent->fields.server->ideal_yaw;
if (delta > 45 && delta < 315)
prvm_edict_t *ent, *goal;
float dist;
+ VM_SAFEPARMCOUNT(1, SV_MoveToGoal);
+
ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
goal = PRVM_PROG_TO_EDICT(ent->fields.server->goalentity);
dist = PRVM_G_FLOAT(OFS_PARM0);
===============================================================================
*/
-/*
-==================
-SV_Move_ClipToEntity
-
-Handles selection or creation of a clipping hull, and offseting (and
-eventually rotation) of the end points
-==================
-*/
-trace_t SV_Move_ClipToEntity(prvm_edict_t *ent, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int movetype, int hitsupercontents)
+int SV_GenericHitSuperContentsMask(const prvm_edict_t *passedict)
{
- trace_t trace;
- model_t *model = NULL;
- matrix4x4_t matrix, imatrix;
- float tempnormal[3], starttransformed[3], endtransformed[3];
-
- memset(&trace, 0, sizeof(trace));
- trace.fraction = trace.realfraction = 1;
- VectorCopy(end, trace.endpos);
-
- if ((int) ent->fields.server->solid == SOLID_BSP || movetype == MOVE_HITMODEL)
+ prvm_eval_t *val;
+ if (passedict)
{
- unsigned int modelindex = (unsigned int)ent->fields.server->modelindex;
- // if the modelindex is 0, it shouldn't be SOLID_BSP!
- if (modelindex == 0)
- {
- Con_Printf("SV_Move_ClipToEntity: edict %i: SOLID_BSP with no model\n", PRVM_NUM_FOR_EDICT(ent));
- return trace;
- }
- if (modelindex >= MAX_MODELS)
- {
- Con_Printf("SV_Move_ClipToEntity: edict %i: SOLID_BSP with invalid modelindex\n", PRVM_NUM_FOR_EDICT(ent));
- return trace;
- }
- model = sv.models[modelindex];
- if (modelindex != 0 && model == NULL)
- {
- Con_Printf("SV_Move_ClipToEntity: edict %i: SOLID_BSP with invalid modelindex\n", PRVM_NUM_FOR_EDICT(ent));
- return trace;
- }
-
- if ((int) ent->fields.server->solid == SOLID_BSP)
+ val = PRVM_EDICTFIELDVALUE(passedict, prog->fieldoffsets.dphitcontentsmask);
+ if (val && val->_float)
+ return (int)val->_float;
+ else if (passedict->fields.server->solid == SOLID_SLIDEBOX)
{
- if (!model->TraceBox)
- {
- Con_Printf("SV_Move_ClipToEntity: edict %i: SOLID_BSP with a non-collidable model\n", PRVM_NUM_FOR_EDICT(ent));
- return trace;
- }
- //if ((int) ent->fields.server->movetype != MOVETYPE_PUSH)
- //{
- // Con_Printf("SV_Move_ClipToEntity: edict %i: SOLID_BSP without MOVETYPE_PUSH\n", PRVM_NUM_FOR_EDICT(ent));
- // return trace;
- //}
+ if ((int)passedict->fields.server->flags & FL_MONSTER)
+ return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_MONSTERCLIP;
+ else
+ return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP;
}
- Matrix4x4_CreateFromQuakeEntity(&matrix, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], 1);
- }
- else
- Matrix4x4_CreateTranslate(&matrix, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
-
- Matrix4x4_Invert_Simple(&imatrix, &matrix);
- Matrix4x4_Transform(&imatrix, start, starttransformed);
- Matrix4x4_Transform(&imatrix, end, endtransformed);
-#if COLLISIONPARANOID >= 3
- Con_Printf("trans(%f %f %f -> %f %f %f, %f %f %f -> %f %f %f)", start[0], start[1], start[2], starttransformed[0], starttransformed[1], starttransformed[2], end[0], end[1], end[2], endtransformed[0], endtransformed[1], endtransformed[2]);
-#endif
-
- if (model && model->TraceBox)
- {
- int frame;
- frame = (int)ent->fields.server->frame;
- frame = bound(0, frame, (model->numframes - 1));
- model->TraceBox(model, frame, &trace, starttransformed, mins, maxs, endtransformed, hitsupercontents);
- }
- else
- Collision_ClipTrace_Box(&trace, ent->fields.server->mins, ent->fields.server->maxs, starttransformed, mins, maxs, endtransformed, hitsupercontents, ent->fields.server->solid == SOLID_CORPSE ? SUPERCONTENTS_CORPSE : SUPERCONTENTS_BODY, 0, NULL);
- trace.fraction = bound(0, trace.fraction, 1);
- trace.realfraction = bound(0, trace.realfraction, 1);
-
- if (trace.fraction < 1)
- {
- VectorLerp(start, trace.fraction, end, trace.endpos);
- VectorCopy(trace.plane.normal, tempnormal);
- Matrix4x4_Transform3x3(&matrix, tempnormal, trace.plane.normal);
- // FIXME: should recalc trace.plane.dist
+ else if (passedict->fields.server->solid == SOLID_CORPSE)
+ return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY;
+ else
+ return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE;
}
else
- VectorCopy(end, trace.endpos);
-
- return trace;
-}
-
-/*
-==================
-SV_Move_ClipToWorld
-==================
-*/
-trace_t SV_Move_ClipToWorld(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int movetype, int hitsupercontents)
-{
- trace_t trace;
- memset(&trace, 0, sizeof(trace));
- trace.fraction = trace.realfraction = 1;
- sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, start, mins, maxs, end, hitsupercontents);
- trace.fraction = bound(0, trace.fraction, 1);
- trace.realfraction = bound(0, trace.realfraction, 1);
- VectorLerp(start, trace.fraction, end, trace.endpos);
- return trace;
+ return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE;
}
/*
==================
*/
#if COLLISIONPARANOID >= 1
-trace_t SV_Move_(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict)
+trace_t SV_Move_(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask)
#else
-trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict)
+trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask)
#endif
{
vec3_t hullmins, hullmaxs;
int i;
- int hitsupercontentsmask;
int passedictprog;
qboolean pointtrace;
prvm_edict_t *traceowner, *touch;
- prvm_eval_t *val;
trace_t trace;
// bounding box of entire move area
vec3_t clipboxmins, clipboxmaxs;
vec3_t clipstart, clipend;
// trace results
trace_t cliptrace;
+ // matrices to transform into/out of other entity's space
+ matrix4x4_t matrix, imatrix;
+ // model of other entity
+ model_t *model;
+ // list of entities to test for collisions
int numtouchedicts;
prvm_edict_t *touchedicts[MAX_EDICTS];
Con_Printf("move(%f %f %f,%f %f %f)", clipstart[0], clipstart[1], clipstart[2], clipend[0], clipend[1], clipend[2]);
#endif
- if (passedict)
- {
- val = PRVM_EDICTFIELDVALUE(passedict, prog->fieldoffsets.dphitcontentsmask);
- if (val && val->_float)
- hitsupercontentsmask = (int)val->_float;
- else if (passedict->fields.server->solid == SOLID_SLIDEBOX)
- {
- if ((int)passedict->fields.server->flags & FL_MONSTER)
- hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_MONSTERCLIP;
- else
- hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP;
- }
- else if (passedict->fields.server->solid == SOLID_CORPSE)
- hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY;
- else
- hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE;
- }
- else
- hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE;
-
// clip to world
- cliptrace = SV_Move_ClipToWorld(clipstart, clipmins, clipmaxs, clipend, type, hitsupercontentsmask);
+ Collision_ClipToWorld(&cliptrace, sv.worldmodel, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask);
cliptrace.bmodelstartsolid = cliptrace.startsolid;
if (cliptrace.startsolid || cliptrace.fraction < 1)
cliptrace.ent = prog->edicts;
traceowner = passedict ? PRVM_PROG_TO_EDICT(passedict->fields.server->owner) : 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
numtouchedicts = World_EntitiesInBox(&sv.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
if (numtouchedicts > MAX_EDICTS)
{
}
// might interact, so do an exact clip
- if ((int)touch->fields.server->flags & FL_MONSTER)
- trace = SV_Move_ClipToEntity(touch, clipstart, clipmins2, clipmaxs2, clipend, type, hitsupercontentsmask);
- else
- trace = SV_Move_ClipToEntity(touch, clipstart, clipmins, clipmaxs, clipend, type, hitsupercontentsmask);
- // LordHavoc: take the 'best' answers from the new trace and combine with existing data
- if (trace.allsolid)
- cliptrace.allsolid = true;
- if (trace.startsolid)
+ model = NULL;
+ if ((int) touch->fields.server->solid == SOLID_BSP || type == MOVE_HITMODEL)
{
- if (touch->fields.server->solid == SOLID_BSP)
- cliptrace.bmodelstartsolid = true;
- cliptrace.startsolid = true;
- if (cliptrace.realfraction == 1)
- cliptrace.ent = touch;
+ unsigned int modelindex = (unsigned int)touch->fields.server->modelindex;
+ // if the modelindex is 0, it shouldn't be SOLID_BSP!
+ if (modelindex > 0 && modelindex < MAX_MODELS)
+ model = sv.models[(int)touch->fields.server->modelindex];
+ Matrix4x4_CreateFromQuakeEntity(&matrix, touch->fields.server->origin[0], touch->fields.server->origin[1], touch->fields.server->origin[2], touch->fields.server->angles[0], touch->fields.server->angles[1], touch->fields.server->angles[2], 1);
}
- // don't set this except on the world, because it can easily confuse
- // monsters underwater if there's a bmodel involved in the trace
- // (inopen && inwater is how they check water visibility)
- //if (trace.inopen)
- // cliptrace.inopen = true;
- if (trace.inwater)
- cliptrace.inwater = true;
- if (trace.realfraction < cliptrace.realfraction)
- {
- cliptrace.fraction = trace.fraction;
- cliptrace.realfraction = trace.realfraction;
- VectorCopy(trace.endpos, cliptrace.endpos);
- cliptrace.plane = trace.plane;
- cliptrace.ent = touch;
- cliptrace.hitsupercontents = trace.hitsupercontents;
- cliptrace.hitq3surfaceflags = trace.hitq3surfaceflags;
- cliptrace.hittexture = trace.hittexture;
- }
- cliptrace.startsupercontents |= trace.startsupercontents;
+ 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)
+ Collision_ClipToGenericEntity(&trace, model, touch->fields.server->frame, touch->fields.server->mins, touch->fields.server->maxs, SUPERCONTENTS_BODY, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask);
+ else
+ Collision_ClipToGenericEntity(&trace, model, touch->fields.server->frame, touch->fields.server->mins, touch->fields.server->maxs, SUPERCONTENTS_BODY, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask);
+ Collision_CombineTraces(&cliptrace, &trace, (void *)touch, touch->fields.server->solid == SOLID_BSP);
}
return cliptrace;
}
#if COLLISIONPARANOID >= 1
-trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict)
+trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask)
{
int endstuck;
trace_t trace;
vec3_t temp;
- trace = SV_Move_(start, mins, maxs, end, type, passedict);
+ trace = SV_Move_(start, mins, maxs, end, type, passedict, hitsupercontentsmask);
if (passedict)
{
VectorCopy(trace.endpos, temp);
- endstuck = SV_Move_(temp, mins, maxs, temp, type, passedict).startsolid;
+ endstuck = SV_Move_(temp, mins, maxs, temp, type, passedict, hitsupercontentsmask).startsolid;
#if COLLISIONPARANOID < 3
if (trace.startsolid || endstuck)
#endif
*/
static int SV_TestEntityPosition (prvm_edict_t *ent)
{
- trace_t trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, ent->fields.server->origin, MOVE_NOMONSTERS, ent);
+ trace_t trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, ent->fields.server->origin, MOVE_NOMONSTERS, ent, SUPERCONTENTS_SOLID);
if (trace.startsupercontents & SUPERCONTENTS_SOLID)
return true;
else
Two entities have touched, so run their touch functions
==================
*/
+extern void VM_SetTraceGlobals(const trace_t *trace);
void SV_Impact (prvm_edict_t *e1, trace_t *trace)
{
int old_self, old_other;
old_self = prog->globals.server->self;
old_other = prog->globals.server->other;
+ VM_SetTraceGlobals(trace);
+
prog->globals.server->time = sv.time;
if (!e1->priv.server->free && !e2->priv.server->free && e1->fields.server->touch && e1->fields.server->solid != SOLID_NOT)
{
prog->globals.server->self = PRVM_EDICT_TO_PROG(e1);
prog->globals.server->other = PRVM_EDICT_TO_PROG(e2);
- prog->globals.server->trace_allsolid = trace->allsolid;
- prog->globals.server->trace_startsolid = trace->startsolid;
- prog->globals.server->trace_fraction = trace->fraction;
- prog->globals.server->trace_inwater = trace->inwater;
- prog->globals.server->trace_inopen = trace->inopen;
- VectorCopy (trace->endpos, prog->globals.server->trace_endpos);
- VectorCopy (trace->plane.normal, prog->globals.server->trace_plane_normal);
- prog->globals.server->trace_plane_dist = trace->plane.dist;
- if (trace->ent)
- prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace->ent);
- else
- prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dpstartcontents)))
- val->_float = trace->startsupercontents;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitcontents)))
- val->_float = trace->hitsupercontents;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitq3surfaceflags)))
- val->_float = trace->hitq3surfaceflags;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphittexturename)))
- {
- if (trace->hittexture)
- val->string = PRVM_SetTempString(trace->hittexture->name);
- else
- val->string = 0;
- }
PRVM_ExecuteProgram (e1->fields.server->touch, "QC function self.touch is missing");
}
{
prog->globals.server->self = PRVM_EDICT_TO_PROG(e2);
prog->globals.server->other = PRVM_EDICT_TO_PROG(e1);
- prog->globals.server->trace_allsolid = false;
- prog->globals.server->trace_startsolid = false;
- prog->globals.server->trace_fraction = 1;
- prog->globals.server->trace_inwater = false;
- prog->globals.server->trace_inopen = true;
- VectorCopy (e2->fields.server->origin, prog->globals.server->trace_endpos);
- VectorSet (prog->globals.server->trace_plane_normal, 0, 0, 1);
- prog->globals.server->trace_plane_dist = 0;
+ VectorCopy(e2->fields.server->origin, prog->globals.server->trace_endpos);
+ VectorNegate(trace->plane.normal, prog->globals.server->trace_plane_normal);
+ prog->globals.server->trace_plane_dist = -trace->plane.dist;
prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(e1);
if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dpstartcontents)))
val->_float = 0;
*/
// LordHavoc: increased from 5 to 32
#define MAX_CLIP_PLANES 32
-int SV_FlyMove (prvm_edict_t *ent, float time, float *stepnormal)
+int SV_FlyMove (prvm_edict_t *ent, float time, float *stepnormal, int hitsupercontentsmask)
{
int blocked, bumpcount;
int i, j, impact, numplanes;
break;
VectorMA(ent->fields.server->origin, time_left, ent->fields.server->velocity, end);
- trace = SV_Move(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
+ trace = SV_Move(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, hitsupercontentsmask);
#if 0
//if (trace.fraction < 0.002)
{
start[2] += 3;//0.03125;
VectorMA(ent->fields.server->origin, time_left, ent->fields.server->velocity, end);
end[2] += 3;//0.03125;
- testtrace = SV_Move(start, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
+ testtrace = SV_Move(start, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, hitsupercontentsmask);
if (trace.fraction < testtrace.fraction && !testtrace.startsolid && (testtrace.fraction == 1 || DotProduct(trace.plane.normal, ent->fields.server->velocity) < DotProduct(testtrace.plane.normal, ent->fields.server->velocity)))
{
Con_Printf("got further (new %f > old %f)\n", testtrace.fraction, trace.fraction);
VectorMA(ent->fields.server->origin, time_left, ent->fields.server->velocity, end);
VectorMA(start, 3, planes[i], start);
VectorMA(end, 3, planes[i], end);
- testtrace = SV_Move(start, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
+ testtrace = SV_Move(start, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, hitsupercontentsmask);
if (trace.fraction < testtrace.fraction)
{
trace = testtrace;
{
// LordHavoc: fix the 'fall to your death in a wedge corner' glitch
// flag ONGROUND if there's ground under it
- trace = SV_Move(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
+ trace = SV_Move(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, hitsupercontentsmask);
}
*/
else
type = MOVE_NORMAL;
- trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, type, ent);
+ trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, type, ent, SV_GenericHitSuperContentsMask(ent));
if (trace.bmodelstartsolid && failonbmodelstartsolid)
return trace;
static prvm_edict_t *checkentities[MAX_EDICTS];
model_t *pushermodel;
trace_t trace;
+ matrix4x4_t pusherfinalmatrix, pusherfinalimatrix;
if (!pusher->fields.server->velocity[0] && !pusher->fields.server->velocity[1] && !pusher->fields.server->velocity[2] && !pusher->fields.server->avelocity[0] && !pusher->fields.server->avelocity[1] && !pusher->fields.server->avelocity[2])
{
pusher->fields.server->ltime += movetime;
SV_LinkEdict (pusher, false);
+ pushermodel = NULL;
+ if (pusher->fields.server->modelindex >= 1 && pusher->fields.server->modelindex < MAX_MODELS)
+ pushermodel = sv.models[(int)pusher->fields.server->modelindex];
+ Matrix4x4_CreateFromQuakeEntity(&pusherfinalmatrix, pusher->fields.server->origin[0], pusher->fields.server->origin[1], pusher->fields.server->origin[2], pusher->fields.server->angles[0], pusher->fields.server->angles[1], pusher->fields.server->angles[2], 1);
+ Matrix4x4_Invert_Simple(&pusherfinalimatrix, &pusherfinalmatrix);
+
savesolid = pusher->fields.server->solid;
// see if any solid entities are inside the final position
else
{
// if the entity is not inside the pusher's final position, leave it alone
- if (!SV_Move_ClipToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY).startsolid)
+ Collision_ClipToGenericEntity(&trace, pushermodel, pusher->fields.server->frame, pusher->fields.server->mins, pusher->fields.server->maxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
+ if (!trace.startsolid)
continue;
}
//Con_Printf("%s:%d frac %f startsolid %d bmodelstartsolid %d allsolid %d\n", __FILE__, __LINE__, trace.fraction, trace.startsolid, trace.bmodelstartsolid, trace.allsolid);
// if it is still inside the pusher, block
- if (SV_Move_ClipToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY).startsolid)
+ Collision_ClipToGenericEntity(&trace, pushermodel, pusher->fields.server->frame, pusher->fields.server->mins, pusher->fields.server->maxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
+ if (trace.startsolid)
{
// try moving the contacted entity a tiny bit further to account for precision errors
vec3_t move2;
VectorCopy (check->priv.server->moved_fromangles, check->fields.server->angles);
SV_PushEntity (check, move2, true);
pusher->fields.server->solid = savesolid;
- if (SV_Move_ClipToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY).startsolid)
+ Collision_ClipToGenericEntity(&trace, pushermodel, pusher->fields.server->frame, pusher->fields.server->mins, pusher->fields.server->maxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
+ if (trace.startsolid)
{
// try moving the contacted entity a tiny bit less to account for precision errors
pusher->fields.server->solid = SOLID_NOT;
VectorCopy (check->priv.server->moved_fromangles, check->fields.server->angles);
SV_PushEntity (check, move2, true);
pusher->fields.server->solid = savesolid;
- if (SV_Move_ClipToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY).startsolid)
+ Collision_ClipToGenericEntity(&trace, pushermodel, pusher->fields.server->frame, pusher->fields.server->mins, pusher->fields.server->maxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
+ if (trace.startsolid)
{
// still inside pusher, so it's really blocked
ent->fields.server->velocity[0] = oldvel[0];
ent->fields.server->velocity[1] = oldvel[1];
ent->fields.server->velocity[2] = 0;
- clip = SV_FlyMove (ent, 0.1, NULL);
+ clip = SV_FlyMove (ent, 0.1, NULL, SV_GenericHitSuperContentsMask(ent));
if (fabs(oldorg[1] - ent->fields.server->origin[1]) > 4
|| fabs(oldorg[0] - ent->fields.server->origin[0]) > 4)
VectorCopy (ent->fields.server->origin, start_origin);
VectorCopy (ent->fields.server->velocity, start_velocity);
- clip = SV_FlyMove (ent, sv.frametime, NULL);
+ clip = SV_FlyMove (ent, sv.frametime, NULL, SV_GenericHitSuperContentsMask(ent));
SV_CheckVelocity(ent);
// move forward
ent->fields.server->velocity[2] = 0;
- clip = SV_FlyMove (ent, sv.frametime, stepnormal);
+ clip = SV_FlyMove (ent, sv.frametime, stepnormal, SV_GenericHitSuperContentsMask(ent));
ent->fields.server->velocity[2] += start_velocity[2];
SV_CheckVelocity(ent);
ent->fields.server->flags -= FL_ONGROUND;
SV_AddGravity(ent);
SV_CheckVelocity(ent);
- SV_FlyMove(ent, sv.frametime, NULL);
+ SV_FlyMove(ent, sv.frametime, NULL, SV_GenericHitSuperContentsMask(ent));
SV_LinkEdict(ent, true);
}
}
SV_AddGravity(ent);
SV_CheckVelocity(ent);
- SV_FlyMove(ent, sv.frametime, NULL);
+ SV_FlyMove(ent, sv.frametime, NULL, SV_GenericHitSuperContentsMask(ent));
SV_LinkEdict(ent, true);
// just hit ground
if (!sv_freezenonclients.integer)
sv.time += sv.frametime;
}
-
-
-trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
-{
- int i;
- float gravity;
- vec3_t move, end;
- vec3_t original_origin;
- vec3_t original_velocity;
- vec3_t original_angles;
- vec3_t original_avelocity;
- prvm_eval_t *val;
- trace_t trace;
-
- VectorCopy(tossent->fields.server->origin , original_origin );
- VectorCopy(tossent->fields.server->velocity , original_velocity );
- VectorCopy(tossent->fields.server->angles , original_angles );
- VectorCopy(tossent->fields.server->avelocity, original_avelocity);
-
- val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
- if (val != NULL && val->_float != 0)
- gravity = val->_float;
- else
- gravity = 1.0;
- gravity *= sv_gravity.value * 0.05;
-
- for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
- {
- SV_CheckVelocity (tossent);
- tossent->fields.server->velocity[2] -= gravity;
- VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
- VectorScale (tossent->fields.server->velocity, 0.05, move);
- VectorAdd (tossent->fields.server->origin, move, end);
- trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent);
- VectorCopy (trace.endpos, tossent->fields.server->origin);
-
- if (trace.fraction < 1)
- break;
- }
-
- VectorCopy(original_origin , tossent->fields.server->origin );
- VectorCopy(original_velocity , tossent->fields.server->velocity );
- VectorCopy(original_angles , tossent->fields.server->angles );
- VectorCopy(original_avelocity, tossent->fields.server->avelocity);
-
- return trace;
-}
-
bottom[1] = top[1];
bottom[2] = top[2] - 160;
- tr = SV_Move (top, vec3_origin, vec3_origin, bottom, MOVE_NOMONSTERS, host_client->edict);
+ tr = SV_Move (top, vec3_origin, vec3_origin, bottom, MOVE_NOMONSTERS, host_client->edict, SUPERCONTENTS_SOLID);
// if looking at a wall, leave ideal the way is was
if (tr.startsolid)
return;
start[2] = host_client->edict->fields.server->origin[2] + host_client->edict->fields.server->mins[2];
stop[2] = start[2] - 34;
- trace = SV_Move (start, vec3_origin, vec3_origin, stop, MOVE_NOMONSTERS, host_client->edict);
+ trace = SV_Move (start, vec3_origin, vec3_origin, stop, MOVE_NOMONSTERS, host_client->edict, SV_GenericHitSuperContentsMask(host_client->edict));
if (trace.fraction == 1.0)
friction = sv_friction.value*sv_edgefriction.value;
"TW_SV_STEPCONTROL "
;
-/*
-==============
-PF_makevectors
-
-Writes new values for v_forward, v_up, and v_right based on angles
-makevectors(vector)
-==============
-*/
-void PF_makevectors (void)
-{
- AngleVectors (PRVM_G_VECTOR(OFS_PARM0), prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up);
-}
-
/*
=================
-PF_setorigin
+VM_SV_setorigin
This is the only valid way to move an object without using the physics of the world (setting velocity and waiting). Directly changing origin will not set internal links correctly, so clipping would be messed up. This should be called when an object is spawned, and then only if it is teleported.
setorigin (entity, origin)
=================
*/
-void PF_setorigin (void)
+static void VM_SV_setorigin (void)
{
prvm_edict_t *e;
float *org;
+ VM_SAFEPARMCOUNT(2, VM_setorigin);
+
e = PRVM_G_EDICT(OFS_PARM0);
if (e == prog->edicts)
{
/*
=================
-PF_setsize
+VM_SV_setsize
the size box is rotated by the current angle
LordHavoc: no it isn't...
setsize (entity, minvector, maxvector)
=================
*/
-void PF_setsize (void)
+static void VM_SV_setsize (void)
{
prvm_edict_t *e;
float *min, *max;
+ VM_SAFEPARMCOUNT(3, VM_setsize);
+
e = PRVM_G_EDICT(OFS_PARM0);
if (e == prog->edicts)
{
/*
=================
-PF_setmodel
+VM_SV_setmodel
setmodel(entity, model)
=================
*/
static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
-void PF_setmodel (void)
+static void VM_SV_setmodel (void)
{
prvm_edict_t *e;
model_t *mod;
int i;
+ VM_SAFEPARMCOUNT(2, VM_setmodel);
+
e = PRVM_G_EDICT(OFS_PARM0);
if (e == prog->edicts)
{
/*
=================
-PF_sprint
+VM_SV_sprint
single print to a specific client
sprint(clientent, value)
=================
*/
-void PF_sprint (void)
+static void VM_SV_sprint (void)
{
client_t *client;
int entnum;
char string[VM_STRINGTEMP_LENGTH];
+ VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
+
entnum = PRVM_G_EDICTNUM(OFS_PARM0);
if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
/*
=================
-PF_centerprint
+VM_SV_centerprint
single print to a specific client
centerprint(clientent, value)
=================
*/
-void PF_centerprint (void)
+static void VM_SV_centerprint (void)
{
client_t *client;
int entnum;
char string[VM_STRINGTEMP_LENGTH];
+ VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
+
entnum = PRVM_G_EDICTNUM(OFS_PARM0);
if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
/*
=================
-PF_particle
+VM_SV_particle
particle(origin, color, count)
=================
*/
-void PF_particle (void)
+static void VM_SV_particle (void)
{
float *org, *dir;
float color;
float count;
+ VM_SAFEPARMCOUNT(4, VM_SV_particle);
+
org = PRVM_G_VECTOR(OFS_PARM0);
dir = PRVM_G_VECTOR(OFS_PARM1);
color = PRVM_G_FLOAT(OFS_PARM2);
/*
=================
-PF_ambientsound
+VM_SV_ambientsound
=================
*/
-void PF_ambientsound (void)
+static void VM_SV_ambientsound (void)
{
const char *samp;
float *pos;
float vol, attenuation;
int soundnum, large;
+ VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
+
pos = PRVM_G_VECTOR (OFS_PARM0);
samp = PRVM_G_STRING(OFS_PARM1);
vol = PRVM_G_FLOAT(OFS_PARM2);
/*
=================
-PF_sound
+VM_SV_sound
Each entity can have eight independant sound sources, like voice,
weapon, feet, etc.
=================
*/
-void PF_sound (void)
+static void VM_SV_sound (void)
{
const char *sample;
int channel;
int volume;
float attenuation;
+ VM_SAFEPARMCOUNT(5, VM_SV_sound);
+
entity = PRVM_G_EDICT(OFS_PARM0);
channel = (int)PRVM_G_FLOAT(OFS_PARM1);
sample = PRVM_G_STRING(OFS_PARM2);
/*
=================
-PF_traceline
+VM_SV_traceline
Used for use tracing and shot targeting
Traces are blocked by bbox and exact bsp entityes, and also slide box entities
if the tryents flag is set.
-traceline (vector1, vector2, tryents)
+traceline (vector1, vector2, movetype, ignore)
=================
*/
-void PF_traceline (void)
+static void VM_SV_traceline (void)
{
float *v1, *v2;
trace_t trace;
int move;
prvm_edict_t *ent;
- prvm_eval_t *val;
+
+ VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
prog->xfunction->builtinsprofile += 30;
if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
PRVM_ERROR("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
- trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent);
-
- prog->globals.server->trace_allsolid = trace.allsolid;
- prog->globals.server->trace_startsolid = trace.startsolid;
- prog->globals.server->trace_fraction = trace.fraction;
- prog->globals.server->trace_inwater = trace.inwater;
- prog->globals.server->trace_inopen = trace.inopen;
- VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
- VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
- prog->globals.server->trace_plane_dist = trace.plane.dist;
- if (trace.ent)
- prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
- else
- prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dpstartcontents)))
- val->_float = trace.startsupercontents;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitcontents)))
- val->_float = trace.hitsupercontents;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitq3surfaceflags)))
- val->_float = trace.hitq3surfaceflags;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphittexturename)))
- {
- if (trace.hittexture)
- val->string = PRVM_SetTempString(trace.hittexture->name);
- else
- val->string = 0;
- }
+ trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
+
+ VM_SetTraceGlobals(&trace);
}
/*
=================
-PF_tracebox
+VM_SV_tracebox
Used for use tracing and shot targeting
Traces are blocked by bbox and exact bsp entityes, and also slide box entities
=================
*/
// LordHavoc: added this for my own use, VERY useful, similar to traceline
-void PF_tracebox (void)
+static void VM_SV_tracebox (void)
{
float *v1, *v2, *m1, *m2;
trace_t trace;
int move;
prvm_edict_t *ent;
- prvm_eval_t *val;
+
+ VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
prog->xfunction->builtinsprofile += 30;
if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
PRVM_ERROR("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
- trace = SV_Move (v1, m1, m2, v2, move, ent);
-
- prog->globals.server->trace_allsolid = trace.allsolid;
- prog->globals.server->trace_startsolid = trace.startsolid;
- prog->globals.server->trace_fraction = trace.fraction;
- prog->globals.server->trace_inwater = trace.inwater;
- prog->globals.server->trace_inopen = trace.inopen;
- VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
- VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
- prog->globals.server->trace_plane_dist = trace.plane.dist;
- if (trace.ent)
- prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
+ trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
+
+ VM_SetTraceGlobals(&trace);
+}
+
+static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
+{
+ int i;
+ float gravity;
+ vec3_t move, end;
+ vec3_t original_origin;
+ vec3_t original_velocity;
+ vec3_t original_angles;
+ vec3_t original_avelocity;
+ prvm_eval_t *val;
+ trace_t trace;
+
+ VectorCopy(tossent->fields.server->origin , original_origin );
+ VectorCopy(tossent->fields.server->velocity , original_velocity );
+ VectorCopy(tossent->fields.server->angles , original_angles );
+ VectorCopy(tossent->fields.server->avelocity, original_avelocity);
+
+ val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
+ if (val != NULL && val->_float != 0)
+ gravity = val->_float;
else
- prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dpstartcontents)))
- val->_float = trace.startsupercontents;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitcontents)))
- val->_float = trace.hitsupercontents;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitq3surfaceflags)))
- val->_float = trace.hitq3surfaceflags;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphittexturename)))
- {
- if (trace.hittexture)
- val->string = PRVM_SetTempString(trace.hittexture->name);
- else
- val->string = 0;
+ gravity = 1.0;
+ gravity *= sv_gravity.value * 0.05;
+
+ for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
+ {
+ SV_CheckVelocity (tossent);
+ tossent->fields.server->velocity[2] -= gravity;
+ VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
+ VectorScale (tossent->fields.server->velocity, 0.05, move);
+ VectorAdd (tossent->fields.server->origin, move, end);
+ trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
+ VectorCopy (trace.endpos, tossent->fields.server->origin);
+
+ if (trace.fraction < 1)
+ break;
}
+
+ VectorCopy(original_origin , tossent->fields.server->origin );
+ VectorCopy(original_velocity , tossent->fields.server->velocity );
+ VectorCopy(original_angles , tossent->fields.server->angles );
+ VectorCopy(original_avelocity, tossent->fields.server->avelocity);
+
+ return trace;
}
-extern trace_t SV_Trace_Toss (prvm_edict_t *ent, prvm_edict_t *ignore);
-void PF_tracetoss (void)
+static void VM_SV_tracetoss (void)
{
trace_t trace;
prvm_edict_t *ent;
prvm_edict_t *ignore;
- prvm_eval_t *val;
+
+ VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
prog->xfunction->builtinsprofile += 600;
trace = SV_Trace_Toss (ent, ignore);
- prog->globals.server->trace_allsolid = trace.allsolid;
- prog->globals.server->trace_startsolid = trace.startsolid;
- prog->globals.server->trace_fraction = trace.fraction;
- prog->globals.server->trace_inwater = trace.inwater;
- prog->globals.server->trace_inopen = trace.inopen;
- VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
- VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
- prog->globals.server->trace_plane_dist = trace.plane.dist;
- if (trace.ent)
- prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
- else
- prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dpstartcontents)))
- val->_float = trace.startsupercontents;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitcontents)))
- val->_float = trace.hitsupercontents;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitq3surfaceflags)))
- val->_float = trace.hitq3surfaceflags;
- if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphittexturename)))
- {
- if (trace.hittexture)
- val->string = PRVM_SetTempString(trace.hittexture->name);
- else
- val->string = 0;
- }
-}
-
-
-/*
-=================
-PF_checkpos
-
-Returns true if the given entity can move to the given position from it's
-current position by walking or rolling.
-FIXME: make work...
-scalar checkpos (entity, vector)
-=================
-*/
-void PF_checkpos (void)
-{
+ VM_SetTraceGlobals(&trace);
}
//============================================================================
-int checkpvsbytes;
-unsigned char checkpvs[MAX_MAP_LEAFS/8];
+static int checkpvsbytes;
+static unsigned char checkpvs[MAX_MAP_LEAFS/8];
-int PF_newcheckclient (int check)
+static int VM_SV_newcheckclient (int check)
{
int i;
prvm_edict_t *ent;
/*
=================
-PF_checkclient
+VM_SV_checkclient
Returns a client (or object that has a client enemy) that would be a
valid target.
=================
*/
int c_invis, c_notvis;
-void PF_checkclient (void)
+static void VM_SV_checkclient (void)
{
prvm_edict_t *ent, *self;
vec3_t view;
+ VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
+
// find a new check if on a new frame
if (sv.time - sv.lastchecktime >= 0.1)
{
- sv.lastcheck = PF_newcheckclient (sv.lastcheck);
+ sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
sv.lastchecktime = sv.time;
}
/*
=================
-PF_stuffcmd
+VM_SV_stuffcmd
Sends text over to the client's execution buffer
stuffcmd (clientent, value, ...)
=================
*/
-void PF_stuffcmd (void)
+static void VM_SV_stuffcmd (void)
{
int entnum;
client_t *old;
char string[VM_STRINGTEMP_LENGTH];
+ VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
+
entnum = PRVM_G_EDICTNUM(OFS_PARM0);
if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
{
/*
=================
-PF_findradius
+VM_SV_findradius
Returns a chain of entities that have origins within a spherical area
findradius (origin, radius)
=================
*/
-void PF_findradius (void)
+static void VM_SV_findradius (void)
{
prvm_edict_t *ent, *chain;
vec_t radius, radius2;
int numtouchedicts;
prvm_edict_t *touchedicts[MAX_EDICTS];
+ VM_SAFEPARMCOUNT(2, VM_SV_findradius);
+
chain = (prvm_edict_t *)prog->edicts;
VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
VM_RETURN_EDICT(chain);
}
-void PF_precache_file (void)
-{ // precache_file is only used to copy files with qcc, it does nothing
- PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
-}
-
-
-void PF_precache_sound (void)
+static void VM_SV_precache_sound (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
}
-void PF_precache_model (void)
+static void VM_SV_precache_model (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
}
/*
===============
-PF_walkmove
+VM_SV_walkmove
-float(float yaw, float dist) walkmove
+float(float yaw, float dist[, settrace]) walkmove
===============
*/
-void PF_walkmove (void)
+static void VM_SV_walkmove (void)
{
prvm_edict_t *ent;
float yaw, dist;
vec3_t move;
mfunction_t *oldf;
int oldself;
+ qboolean settrace;
+
+ VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
// assume failure if it returns early
PRVM_G_FLOAT(OFS_RETURN) = 0;
}
yaw = PRVM_G_FLOAT(OFS_PARM0);
dist = PRVM_G_FLOAT(OFS_PARM1);
+ settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
return;
oldf = prog->xfunction;
oldself = prog->globals.server->self;
- PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
+ PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
// restore program state
/*
===============
-PF_droptofloor
+VM_SV_droptofloor
void() droptofloor
===============
*/
-void PF_droptofloor (void)
+static void VM_SV_droptofloor (void)
{
prvm_edict_t *ent;
vec3_t end;
trace_t trace;
+ VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
+
// assume failure if it returns early
PRVM_G_FLOAT(OFS_RETURN) = 0;
VectorCopy (ent->fields.server->origin, end);
end[2] -= 256;
- trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
+ trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
{
/*
===============
-PF_lightstyle
+VM_SV_lightstyle
void(float style, string value) lightstyle
===============
*/
-void PF_lightstyle (void)
+static void VM_SV_lightstyle (void)
{
int style;
const char *val;
client_t *client;
int j;
+ VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
+
style = (int)PRVM_G_FLOAT(OFS_PARM0);
val = PRVM_G_STRING(OFS_PARM1);
/*
=============
-PF_checkbottom
+VM_SV_checkbottom
=============
*/
-void PF_checkbottom (void)
+static void VM_SV_checkbottom (void)
{
+ VM_SAFEPARMCOUNT(0, VM_SV_checkbottom);
PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
}
/*
=============
-PF_pointcontents
+VM_SV_pointcontents
=============
*/
-void PF_pointcontents (void)
+static void VM_SV_pointcontents (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
}
/*
=============
-PF_aim
+VM_SV_aim
Pick a vector for the player to shoot along
vector aim(entity, missilespeed)
=============
*/
-void PF_aim (void)
+static void VM_SV_aim (void)
{
prvm_edict_t *ent, *check, *bestent;
vec3_t start, dir, end, bestdir;
float dist, bestdist;
float speed;
+ VM_SAFEPARMCOUNT(2, VM_SV_aim);
+
// assume failure if it returns early
VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
// if sv_aim is so high it can't possibly accept anything, skip out early
// try sending a trace straight
VectorCopy (prog->globals.server->v_forward, dir);
VectorMA (start, 2048, dir, end);
- tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
+ tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
&& (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
{
dist = DotProduct (dir, prog->globals.server->v_forward);
if (dist < bestdist)
continue; // to far to turn
- tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
+ tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
if (tr.ent == check)
{ // can shoot at this one
bestdist = dist;
return NULL;
}
-void PF_WriteByte (void)
+static void VM_SV_WriteByte (void)
{
+ VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
}
-void PF_WriteChar (void)
+static void VM_SV_WriteChar (void)
{
+ VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
}
-void PF_WriteShort (void)
+static void VM_SV_WriteShort (void)
{
+ VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
}
-void PF_WriteLong (void)
+static void VM_SV_WriteLong (void)
{
+ VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
}
-void PF_WriteAngle (void)
+static void VM_SV_WriteAngle (void)
{
+ VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
}
-void PF_WriteCoord (void)
+static void VM_SV_WriteCoord (void)
{
+ VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
}
-void PF_WriteString (void)
+static void VM_SV_WriteString (void)
{
+ VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
}
-void PF_WriteUnterminatedString (void)
+static void VM_SV_WriteUnterminatedString (void)
{
+ VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
}
-void PF_WriteEntity (void)
+static void VM_SV_WriteEntity (void)
{
+ VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
}
//////////////////////////////////////////////////////////
-void PF_makestatic (void)
+static void VM_SV_makestatic (void)
{
prvm_edict_t *ent;
int i, large;
+ VM_SAFEPARMCOUNT(1, VM_SV_makestatic);
+
ent = PRVM_G_EDICT(OFS_PARM0);
if (ent == prog->edicts)
{
/*
==============
-PF_setspawnparms
+VM_SV_setspawnparms
==============
*/
-void PF_setspawnparms (void)
+static void VM_SV_setspawnparms (void)
{
prvm_edict_t *ent;
int i;
client_t *client;
+ VM_SAFEPARMCOUNT(0, VM_SV_setspawnparms);
+
ent = PRVM_G_EDICT(OFS_PARM0);
i = PRVM_NUM_FOR_EDICT(ent);
if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
/*
=================
-PF_getlight
+VM_SV_getlight
Returns a color vector indicating the lighting at the requested point.
getlight(vector)
=================
*/
-void PF_getlight (void)
+static void VM_SV_getlight (void)
{
vec3_t ambientcolor, diffusecolor, diffusenormal;
vec_t *p;
+ VM_SAFEPARMCOUNT(1, VM_SV_getlight);
p = PRVM_G_VECTOR(OFS_PARM0);
VectorClear(ambientcolor);
VectorClear(diffusecolor);
VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
}
-void PF_registercvar (void)
-{
- const char *name, *value;
- name = PRVM_G_STRING(OFS_PARM0);
- value = PRVM_G_STRING(OFS_PARM1);
- PRVM_G_FLOAT(OFS_RETURN) = 0;
-
-// first check to see if it has already been defined
- if (Cvar_FindVar (name))
- return;
-
-// check for overlap with a command
- if (Cmd_Exists (name))
- {
- VM_Warning("PF_registercvar: %s is a command\n", name);
- return;
- }
-
- Cvar_Get(name, value, 0);
-
- PRVM_G_FLOAT(OFS_RETURN) = 1; // success
-}
-
typedef struct
{
unsigned char type; // 1/2/8 or other value if isn't used
// 1: string (4 stats carrying a total of 16 charactures)
// 2: float (one stat, float converted to an integer for transportation)
// 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
-void PF_SV_AddStat (void)
+static void VM_SV_AddStat (void)
{
int off, i;
unsigned char type;
+ VM_SAFEPARMCOUNT(2, VM_SV_AddStat);
+
if(!vm_autosentstats)
{
vm_autosentstats = (autosentstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(autosentstat_t));
/*
=================
-PF_copyentity
+VM_SV_copyentity
copies data from one entity to another
copyentity(src, dst)
=================
*/
-void PF_copyentity (void)
+static void VM_SV_copyentity (void)
{
prvm_edict_t *in, *out;
+ VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
in = PRVM_G_EDICT(OFS_PARM0);
if (in == prog->edicts)
{
VM_Warning("copyentity: can not modify free entity\n");
return;
}
- memcpy(out->fields.server, in->fields.server, prog->progs->entityfields * 4);
+ memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
+ SV_LinkEdict(out, false);
}
/*
=================
-PF_setcolor
+VM_SV_setcolor
sets the color of a client and broadcasts the update to all connected clients
setcolor(clientent, value)
=================
*/
-void PF_setcolor (void)
+static void VM_SV_setcolor (void)
{
client_t *client;
int entnum, i;
prvm_eval_t *val;
+ VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
entnum = PRVM_G_EDICTNUM(OFS_PARM0);
i = (int)PRVM_G_FLOAT(OFS_PARM1);
/*
=================
-PF_effect
+VM_SV_effect
effect(origin, modelname, startframe, framecount, framerate)
=================
*/
-void PF_effect (void)
+static void VM_SV_effect (void)
{
int i;
const char *s;
+ VM_SAFEPARMCOUNT(5, VM_SV_effect);
s = PRVM_G_STRING(OFS_PARM1);
if (!s[0])
{
SV_StartEffect(PRVM_G_VECTOR(OFS_PARM0), i, (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4));
}
-void PF_te_blood (void)
+static void VM_SV_te_blood (void)
{
+ VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
if (PRVM_G_FLOAT(OFS_PARM2) < 1)
return;
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
}
-void PF_te_bloodshower (void)
+static void VM_SV_te_bloodshower (void)
{
+ VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
if (PRVM_G_FLOAT(OFS_PARM3) < 1)
return;
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
}
-void PF_te_explosionrgb (void)
+static void VM_SV_te_explosionrgb (void)
{
+ VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
// origin
MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
}
-void PF_te_particlecube (void)
+static void VM_SV_te_particlecube (void)
{
+ VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
if (PRVM_G_FLOAT(OFS_PARM3) < 1)
return;
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
}
-void PF_te_particlerain (void)
+static void VM_SV_te_particlerain (void)
{
+ VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
if (PRVM_G_FLOAT(OFS_PARM3) < 1)
return;
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
}
-void PF_te_particlesnow (void)
+static void VM_SV_te_particlesnow (void)
{
+ VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
if (PRVM_G_FLOAT(OFS_PARM3) < 1)
return;
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
}
-void PF_te_spark (void)
+static void VM_SV_te_spark (void)
{
+ VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
if (PRVM_G_FLOAT(OFS_PARM2) < 1)
return;
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
}
-void PF_te_gunshotquad (void)
+static void VM_SV_te_gunshotquad (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
// origin
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
}
-void PF_te_spikequad (void)
+static void VM_SV_te_spikequad (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
// origin
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
}
-void PF_te_superspikequad (void)
+static void VM_SV_te_superspikequad (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
// origin
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
}
-void PF_te_explosionquad (void)
+static void VM_SV_te_explosionquad (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
// origin
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
}
-void PF_te_smallflash (void)
+static void VM_SV_te_smallflash (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
// origin
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
}
-void PF_te_customflash (void)
+static void VM_SV_te_customflash (void)
{
+ VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
return;
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
}
-void PF_te_gunshot (void)
+static void VM_SV_te_gunshot (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
// origin
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
}
-void PF_te_spike (void)
+static void VM_SV_te_spike (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SPIKE);
// origin
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
}
-void PF_te_superspike (void)
+static void VM_SV_te_superspike (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
// origin
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
}
-void PF_te_explosion (void)
+static void VM_SV_te_explosion (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
// origin
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
}
-void PF_te_tarexplosion (void)
+static void VM_SV_te_tarexplosion (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
// origin
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
}
-void PF_te_wizspike (void)
+static void VM_SV_te_wizspike (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
// origin
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
}
-void PF_te_knightspike (void)
+static void VM_SV_te_knightspike (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
// origin
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
}
-void PF_te_lavasplash (void)
+static void VM_SV_te_lavasplash (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
// origin
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
}
-void PF_te_teleport (void)
+static void VM_SV_te_teleport (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_TELEPORT);
// origin
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
}
-void PF_te_explosion2 (void)
+static void VM_SV_te_explosion2 (void)
{
+ VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
// origin
MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
}
-void PF_te_lightning1 (void)
+static void VM_SV_te_lightning1 (void)
{
+ VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
// owner entity
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
}
-void PF_te_lightning2 (void)
+static void VM_SV_te_lightning2 (void)
{
+ VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
// owner entity
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
}
-void PF_te_lightning3 (void)
+static void VM_SV_te_lightning3 (void)
{
+ VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
// owner entity
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
}
-void PF_te_beam (void)
+static void VM_SV_te_beam (void)
{
+ VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_BEAM);
// owner entity
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
}
-void PF_te_plasmaburn (void)
+static void VM_SV_te_plasmaburn (void)
{
+ VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
}
-void PF_te_flamejet (void)
+static void VM_SV_te_flamejet (void)
{
+ VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
MSG_WriteByte(&sv.datagram, svc_temp_entity);
MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
// org
//PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
-void PF_getsurfacenumpoints(void)
+static void VM_SV_getsurfacenumpoints(void)
{
model_t *model;
msurface_t *surface;
+ VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
// return 0 if no such surface
if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
{
PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
}
//PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
-void PF_getsurfacepoint(void)
+static void VM_SV_getsurfacepoint(void)
{
prvm_edict_t *ed;
model_t *model;
msurface_t *surface;
int pointnum;
+ VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
VectorClear(PRVM_G_VECTOR(OFS_RETURN));
ed = PRVM_G_EDICT(OFS_PARM0);
if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
}
//PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
-void PF_getsurfacenormal(void)
+static void VM_SV_getsurfacenormal(void)
{
model_t *model;
msurface_t *surface;
vec3_t normal;
+ VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
VectorClear(PRVM_G_VECTOR(OFS_RETURN));
if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
return;
VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
}
//PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
-void PF_getsurfacetexture(void)
+static void VM_SV_getsurfacetexture(void)
{
model_t *model;
msurface_t *surface;
+ VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
PRVM_G_INT(OFS_RETURN) = OFS_NULL;
if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
return;
PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
}
//PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
-void PF_getsurfacenearpoint(void)
+static void VM_SV_getsurfacenearpoint(void)
{
int surfacenum, best;
vec3_t clipped, p;
model_t *model;
msurface_t *surface;
vec_t *point;
+ VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
PRVM_G_FLOAT(OFS_RETURN) = -1;
ed = PRVM_G_EDICT(OFS_PARM0);
point = PRVM_G_VECTOR(OFS_PARM1);
PRVM_G_FLOAT(OFS_RETURN) = best;
}
//PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
-void PF_getsurfaceclippedpoint(void)
+static void VM_SV_getsurfaceclippedpoint(void)
{
prvm_edict_t *ed;
model_t *model;
msurface_t *surface;
vec3_t p, out;
+ VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
VectorClear(PRVM_G_VECTOR(OFS_RETURN));
ed = PRVM_G_EDICT(OFS_PARM0);
if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
//void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
//this function originally written by KrimZon, made shorter by LordHavoc
-void PF_clientcommand (void)
+static void VM_SV_clientcommand (void)
{
client_t *temp_client;
int i;
+ VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
//find client for this entity
i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
}
//void(entity e, entity tagentity, string tagname) setattachment = #443; // attachs e to a tag on tagentity (note: use "" to attach to entity origin/angles instead of a tag)
-void PF_setattachment (void)
+static void VM_SV_setattachment (void)
{
prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
prvm_eval_t *v;
int modelindex;
model_t *model;
+ VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
if (e == prog->edicts)
{
//float(entity ent, string tagname) gettagindex;
-void PF_gettagindex (void)
+static void VM_SV_gettagindex (void)
{
- prvm_edict_t *ent = PRVM_G_EDICT(OFS_PARM0);
- const char *tag_name = PRVM_G_STRING(OFS_PARM1);
+ prvm_edict_t *ent;
+ const char *tag_name;
int modelindex, tag_index;
+ VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
+
+ ent = PRVM_G_EDICT(OFS_PARM0);
+ tag_name = PRVM_G_STRING(OFS_PARM1);
+
if (ent == prog->edicts)
{
VM_Warning("gettagindex: can't affect world entity\n");
};
//vector(entity ent, float tagindex) gettaginfo;
-void PF_gettaginfo (void)
+static void VM_SV_gettaginfo (void)
{
- prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
- int tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
+ prvm_edict_t *e;
+ int tagindex;
matrix4x4_t tag_matrix;
int returncode;
+ VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
+
+ e = PRVM_G_EDICT(OFS_PARM0);
+ tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
+
returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
}
//void(entity clent) dropclient (DP_SV_DROPCLIENT)
-void PF_dropclient (void)
+static void VM_SV_dropclient (void)
{
int clientnum;
client_t *oldhostclient;
+ VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
if (clientnum < 0 || clientnum >= svs.maxclients)
{
}
//entity() spawnclient (DP_SV_BOTCLIENT)
-void PF_spawnclient (void)
+static void VM_SV_spawnclient (void)
{
int i;
prvm_edict_t *ed;
+ VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
prog->xfunction->builtinsprofile += 2;
ed = prog->edicts;
for (i = 0;i < svs.maxclients;i++)
}
//float(entity clent) clienttype (DP_SV_BOTCLIENT)
-void PF_clienttype (void)
+static void VM_SV_clienttype (void)
{
int clientnum;
+ VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
if (clientnum < 0 || clientnum >= svs.maxclients)
PRVM_G_FLOAT(OFS_RETURN) = 3;
PRVM_G_FLOAT(OFS_RETURN) = 2;
}
-void PF_edict_num (void)
+/*
+===============
+VM_SV_serverkey
+
+string(string key) serverkey
+===============
+*/
+void VM_SV_serverkey(void)
+{
+ char string[VM_STRINGTEMP_LENGTH];
+ VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
+ InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
+ PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
+}
+
+//#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
+static void VM_SV_setmodelindex (void)
+{
+ prvm_edict_t *e;
+ model_t *mod;
+ int i;
+ VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
+
+ e = PRVM_G_EDICT(OFS_PARM0);
+ if (e == prog->edicts)
+ {
+ VM_Warning("setmodelindex: can not modify world entity\n");
+ return;
+ }
+ if (e->priv.server->free)
+ {
+ VM_Warning("setmodelindex: can not modify free entity\n");
+ return;
+ }
+ i = (int)PRVM_G_FLOAT(OFS_PARM1);
+ if (i <= 0 || i > MAX_MODELS)
+ {
+ VM_Warning("setmodelindex: invalid modelindex\n");
+ return;
+ }
+ if (!sv.model_precache[i][0])
+ {
+ VM_Warning("setmodelindex: model not precached\n");
+ return;
+ }
+
+ e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
+ e->fields.server->modelindex = i;
+
+ mod = sv.models[i];
+
+ if (mod)
+ {
+ if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
+ SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
+ else
+ SetMinMaxSize (e, quakemins, quakemaxs, true);
+ }
+ else
+ SetMinMaxSize (e, vec3_origin, vec3_origin, true);
+}
+
+//#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
+static void VM_SV_modelnameforindex (void)
+{
+ int i;
+ VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
+
+ PRVM_G_INT(OFS_RETURN) = OFS_NULL;
+
+ i = (int)PRVM_G_FLOAT(OFS_PARM0);
+ if (i <= 0 || i > MAX_MODELS)
+ {
+ VM_Warning("modelnameforindex: invalid modelindex\n");
+ return;
+ }
+ if (!sv.model_precache[i][0])
+ {
+ VM_Warning("modelnameforindex: model not precached\n");
+ return;
+ }
+
+ PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
+}
+
+//#335 float(string effectname) particleeffectnum (EXT_CSQC)
+static void VM_SV_particleeffectnum (void)
{
- VM_RETURN_EDICT(PRVM_EDICT_NUM((int)PRVM_G_FLOAT(OFS_PARM0)));
+ int i;
+ VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
+ i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
+ if (i == 0)
+ i = -1;
+ PRVM_G_FLOAT(OFS_RETURN) = i;
}
// #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
}
prvm_builtin_t vm_sv_builtins[] = {
-NULL, // #0
-PF_makevectors, // #1 void(vector ang) makevectors
-PF_setorigin, // #2 void(entity e, vector o) setorigin
-PF_setmodel, // #3 void(entity e, string m) setmodel
-PF_setsize, // #4 void(entity e, vector min, vector max) setsize
-NULL, // #5 void(entity e, vector min, vector max) setabssize
-VM_break, // #6 void() break
-VM_random, // #7 float() random
-PF_sound, // #8 void(entity e, float chan, string samp) sound
-VM_normalize, // #9 vector(vector v) normalize
-VM_error, // #10 void(string e) error
-VM_objerror, // #11 void(string e) objerror
-VM_vlen, // #12 float(vector v) vlen
-VM_vectoyaw, // #13 float(vector v) vectoyaw
-VM_spawn, // #14 entity() spawn
-VM_remove, // #15 void(entity e) remove
-PF_traceline, // #16 float(vector v1, vector v2, float tryents) traceline
-PF_checkclient, // #17 entity() clientlist
-VM_find, // #18 entity(entity start, .string fld, string match) find
-PF_precache_sound, // #19 void(string s) precache_sound
-PF_precache_model, // #20 void(string s) precache_model
-PF_stuffcmd, // #21 void(entity client, string s)stuffcmd
-PF_findradius, // #22 entity(vector org, float rad) findradius
-VM_bprint, // #23 void(string s) bprint
-PF_sprint, // #24 void(entity client, string s) sprint
-VM_dprint, // #25 void(string s) dprint
-VM_ftos, // #26 void(string s) ftos
-VM_vtos, // #27 void(string s) vtos
-VM_coredump, // #28 void() coredump
-VM_traceon, // #29 void() traceon
-VM_traceoff, // #30 void() traceoff
-VM_eprint, // #31 void(entity e) eprint
-PF_walkmove, // #32 float(float yaw, float dist) walkmove
-NULL, // #33
-PF_droptofloor, // #34 float() droptofloor
-PF_lightstyle, // #35 void(float style, string value) lightstyle
-VM_rint, // #36 float(float v) rint
-VM_floor, // #37 float(float v) floor
-VM_ceil, // #38 float(float v) ceil
-NULL, // #39
-PF_checkbottom, // #40 float(entity e) checkbottom
-PF_pointcontents, // #41 float(vector v) pointcontents
-NULL, // #42
-VM_fabs, // #43 float(float f) fabs
-PF_aim, // #44 vector(entity e, float speed) aim
-VM_cvar, // #45 float(string s) cvar
-VM_localcmd, // #46 void(string s) localcmd
-VM_nextent, // #47 entity(entity e) nextent
-PF_particle, // #48 void(vector o, vector d, float color, float count) particle
-VM_changeyaw, // #49 void() ChangeYaw
-NULL, // #50
-VM_vectoangles, // #51 vector(vector v) vectoangles
-PF_WriteByte, // #52 void(float to, float f) WriteByte
-PF_WriteChar, // #53 void(float to, float f) WriteChar
-PF_WriteShort, // #54 void(float to, float f) WriteShort
-PF_WriteLong, // #55 void(float to, float f) WriteLong
-PF_WriteCoord, // #56 void(float to, float f) WriteCoord
-PF_WriteAngle, // #57 void(float to, float f) WriteAngle
-PF_WriteString, // #58 void(float to, string s) WriteString
-PF_WriteEntity, // #59 void(float to, entity e) WriteEntity
-VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW)
-VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW)
-VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW)
-VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH)
-PF_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS)
-VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS)
-NULL, // #66
-SV_MoveToGoal, // #67 void(float step) movetogoal
-PF_precache_file, // #68 string(string s) precache_file
-PF_makestatic, // #69 void(entity e) makestatic
-VM_changelevel, // #70 void(string s) changelevel
-NULL, // #71
-VM_cvar_set, // #72 void(string var, string val) cvar_set
-PF_centerprint, // #73 void(entity client, strings) centerprint
-PF_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound
-PF_precache_model, // #75 string(string s) precache_model2
-PF_precache_sound, // #76 string(string s) precache_sound2
-PF_precache_file, // #77 string(string s) precache_file2
-PF_setspawnparms, // #78 void(entity e) setspawnparms
-NULL, // #79
-NULL, // #80
-VM_stof, // #81 float(string s) stof (FRIK_FILE)
-NULL, // #82
-NULL, // #83
-NULL, // #84
-NULL, // #85
-NULL, // #86
-NULL, // #87
-NULL, // #88
-NULL, // #89
-PF_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
-VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
-PF_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
-PF_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
-VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
-VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
-VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
-VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
-VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
-VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
-NULL, // #100
-NULL, // #101
-NULL, // #102
-NULL, // #103
-NULL, // #104
-NULL, // #105
-NULL, // #106
-NULL, // #107
-NULL, // #108
-NULL, // #109
-VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
-VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
-VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
-VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
-VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
-VM_strcat, // #115 string(string s1, string s2) strcat (FRIK_FILE)
-VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
-VM_stov, // #117 vector(string) stov (FRIK_FILE)
-VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
-VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
-e10, e10, e10, e10, e10, e10, e10, e10, // #120-199
+NULL, // #0 NULL function (not callable) (QUAKE)
+VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
+VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
+VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
+VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
+NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
+VM_break, // #6 void() break (QUAKE)
+VM_random, // #7 float() random (QUAKE)
+VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
+VM_normalize, // #9 vector(vector v) normalize (QUAKE)
+VM_error, // #10 void(string e) error (QUAKE)
+VM_objerror, // #11 void(string e) objerror (QUAKE)
+VM_vlen, // #12 float(vector v) vlen (QUAKE)
+VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
+VM_spawn, // #14 entity() spawn (QUAKE)
+VM_remove, // #15 void(entity e) remove (QUAKE)
+VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
+VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
+VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
+VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
+VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
+VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
+VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
+VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
+VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
+VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
+VM_ftos, // #26 string(float f) ftos (QUAKE)
+VM_vtos, // #27 string(vector v) vtos (QUAKE)
+VM_coredump, // #28 void() coredump (QUAKE)
+VM_traceon, // #29 void() traceon (QUAKE)
+VM_traceoff, // #30 void() traceoff (QUAKE)
+VM_eprint, // #31 void(entity e) eprint (QUAKE)
+VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
+NULL, // #33 (QUAKE)
+VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
+VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
+VM_rint, // #36 float(float v) rint (QUAKE)
+VM_floor, // #37 float(float v) floor (QUAKE)
+VM_ceil, // #38 float(float v) ceil (QUAKE)
+NULL, // #39 (QUAKE)
+VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
+VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
+NULL, // #42 (QUAKE)
+VM_fabs, // #43 float(float f) fabs (QUAKE)
+VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
+VM_cvar, // #45 float(string s) cvar (QUAKE)
+VM_localcmd, // #46 void(string s) localcmd (QUAKE)
+VM_nextent, // #47 entity(entity e) nextent (QUAKE)
+VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
+VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
+NULL, // #50 (QUAKE)
+VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
+VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
+VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
+VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
+VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
+VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
+VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
+VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
+VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
+VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
+VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
+VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
+VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
+VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
+VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
+NULL, // #66 (QUAKE)
+SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
+VM_precache_file, // #68 string(string s) precache_file (QUAKE)
+VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
+VM_changelevel, // #70 void(string s) changelevel (QUAKE)
+NULL, // #71 (QUAKE)
+VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
+VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
+VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
+VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
+VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
+VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
+VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
+NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
+NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
+VM_stof, // #81 float(string s) stof (FRIK_FILE)
+NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
+NULL, // #83 (QUAKE)
+NULL, // #84 (QUAKE)
+NULL, // #85 (QUAKE)
+NULL, // #86 (QUAKE)
+NULL, // #87 (QUAKE)
+NULL, // #88 (QUAKE)
+NULL, // #89 (QUAKE)
+VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
+VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
+VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
+VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
+VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
+VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
+VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
+VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
+VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
+VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
+// FrikaC and Telejano range #100-#199
+NULL, // #100
+NULL, // #101
+NULL, // #102
+NULL, // #103
+NULL, // #104
+NULL, // #105
+NULL, // #106
+NULL, // #107
+NULL, // #108
+NULL, // #109
+VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
+VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
+VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
+VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
+VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
+VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
+VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
+VM_stov, // #117 vector(string) stov (FRIK_FILE)
+VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
+VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
+NULL, // #120
+NULL, // #121
+NULL, // #122
+NULL, // #123
+NULL, // #124
+NULL, // #125
+NULL, // #126
+NULL, // #127
+NULL, // #128
+NULL, // #129
+NULL, // #130
+NULL, // #131
+NULL, // #132
+NULL, // #133
+NULL, // #134
+NULL, // #135
+NULL, // #136
+NULL, // #137
+NULL, // #138
+NULL, // #139
+NULL, // #140
+NULL, // #141
+NULL, // #142
+NULL, // #143
+NULL, // #144
+NULL, // #145
+NULL, // #146
+NULL, // #147
+NULL, // #148
+NULL, // #149
+NULL, // #150
+NULL, // #151
+NULL, // #152
+NULL, // #153
+NULL, // #154
+NULL, // #155
+NULL, // #156
+NULL, // #157
+NULL, // #158
+NULL, // #159
+NULL, // #160
+NULL, // #161
+NULL, // #162
+NULL, // #163
+NULL, // #164
+NULL, // #165
+NULL, // #166
+NULL, // #167
+NULL, // #168
+NULL, // #169
+NULL, // #170
+NULL, // #171
+NULL, // #172
+NULL, // #173
+NULL, // #174
+NULL, // #175
+NULL, // #176
+NULL, // #177
+NULL, // #178
+NULL, // #179
+NULL, // #180
+NULL, // #181
+NULL, // #182
+NULL, // #183
+NULL, // #184
+NULL, // #185
+NULL, // #186
+NULL, // #187
+NULL, // #188
+NULL, // #189
+NULL, // #190
+NULL, // #191
+NULL, // #192
+NULL, // #193
+NULL, // #194
+NULL, // #195
+NULL, // #196
+NULL, // #197
+NULL, // #198
+NULL, // #199
// FTEQW range #200-#299
-NULL, // #200
-NULL, // #201
-NULL, // #202
-NULL, // #203
-NULL, // #204
-NULL, // #205
-NULL, // #206
-NULL, // #207
-NULL, // #208
-NULL, // #209
-NULL, // #210
-NULL, // #211
-NULL, // #212
-NULL, // #213
-NULL, // #214
-NULL, // #215
-NULL, // #216
-NULL, // #217
-VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
-NULL, // #219
-e10, // #220-#229
-e10, // #230-#239
-e10, // #240-#249
-e10, // #250-#259
-e10, // #260-#269
-e10, // #270-#279
-e10, // #280-#289
-e10, // #290-#299
-e10, // #300-309
-e10, // #310-319
-e10, // #320-329
-NULL, // #330
-NULL, // #331
-NULL, // #332
-NULL, // #333
-NULL, // #334
-NULL, // #335
-VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
-VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
-NULL, // #338
-VM_print, // #339 void(string, ...) print (DP_SV_PRINT)
-e10, // #340-349
-e10, // #350-359
-e10, // #360-369
-e10, // #370-379
-e10, // #380-389
-e10, // #390-399
-VM_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
-PF_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
-VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
-VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
-PF_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
-PF_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
-PF_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
-PF_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
-PF_te_particlecube, // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE)
-PF_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
-PF_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
-PF_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
-PF_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
-PF_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
-PF_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
-PF_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
-PF_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
-PF_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
-PF_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
-PF_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
-PF_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
-PF_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
-PF_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
-PF_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
-PF_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
-PF_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
-PF_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
-PF_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
-PF_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
-PF_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
-PF_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
-PF_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
-VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
-PF_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
-PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
-PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
-PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
-PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
-PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
-PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
-PF_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
-VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
-VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
-PF_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
-VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
-VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
-VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
-VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
-VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
-VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
-VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
-PF_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
-PF_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
-PF_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
-PF_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
-PF_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
-PF_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
-PF_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
-NULL, // #458
-PF_edict_num, // #459 entity(float num) (??)
-VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
-VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
-VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
-VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
-VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
-VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
-VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
-VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
-VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
-VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
-PF_SV_AddStat, // #470 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
-VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
-VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
-VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
-VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
-VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
-VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
-VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
-VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
-NULL, // #478
-NULL, // #479
-e10, e10 // #480-499 (LordHavoc)
+NULL, // #200
+NULL, // #201
+NULL, // #202
+NULL, // #203
+NULL, // #204
+NULL, // #205
+NULL, // #206
+NULL, // #207
+NULL, // #208
+NULL, // #209
+NULL, // #210
+NULL, // #211
+NULL, // #212
+NULL, // #213
+NULL, // #214
+NULL, // #215
+NULL, // #216
+NULL, // #217
+VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
+NULL, // #219
+NULL, // #220
+NULL, // #221
+VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
+VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
+NULL, // #224
+NULL, // #225
+NULL, // #226
+NULL, // #227
+VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
+NULL, // #229
+NULL, // #230
+NULL, // #231
+VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
+NULL, // #233
+NULL, // #234
+NULL, // #235
+NULL, // #236
+NULL, // #237
+NULL, // #238
+NULL, // #239
+NULL, // #240
+NULL, // #241
+NULL, // #242
+NULL, // #243
+NULL, // #244
+NULL, // #245
+NULL, // #246
+NULL, // #247
+NULL, // #248
+NULL, // #249
+NULL, // #250
+NULL, // #251
+NULL, // #252
+NULL, // #253
+NULL, // #254
+NULL, // #255
+NULL, // #256
+NULL, // #257
+NULL, // #258
+NULL, // #259
+NULL, // #260
+NULL, // #261
+NULL, // #262
+NULL, // #263
+NULL, // #264
+NULL, // #265
+NULL, // #266
+NULL, // #267
+NULL, // #268
+NULL, // #269
+NULL, // #270
+NULL, // #271
+NULL, // #272
+NULL, // #273
+NULL, // #274
+NULL, // #275
+NULL, // #276
+NULL, // #277
+NULL, // #278
+NULL, // #279
+NULL, // #280
+NULL, // #281
+NULL, // #282
+NULL, // #283
+NULL, // #284
+NULL, // #285
+NULL, // #286
+NULL, // #287
+NULL, // #288
+NULL, // #289
+NULL, // #290
+NULL, // #291
+NULL, // #292
+NULL, // #293
+NULL, // #294
+NULL, // #295
+NULL, // #296
+NULL, // #297
+NULL, // #298
+NULL, // #299
+// CSQC range #300-#399
+NULL, // #300 void() clearscene (EXT_CSQC)
+NULL, // #301 void(float mask) addentities (EXT_CSQC)
+NULL, // #302 void(entity ent) addentity (EXT_CSQC)
+NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
+NULL, // #304 void() renderscene (EXT_CSQC)
+NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
+NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
+NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
+NULL, // #308 void() R_EndPolygon
+NULL, // #309
+NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
+NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
+NULL, // #312
+NULL, // #313
+NULL, // #314
+NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
+NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
+NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
+NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
+NULL, // #319 void(string name) freepic (EXT_CSQC)
+NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
+NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
+NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
+NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
+NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
+NULL, // #325 void(void) drawresetcliparea
+NULL, // #326
+NULL, // #327
+NULL, // #328
+NULL, // #329
+NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
+NULL, // #331 float(float stnum) getstati (EXT_CSQC)
+NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
+VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
+VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
+VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
+VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
+VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
+NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
+VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
+NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
+NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
+NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
+NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
+NULL, // #344 vector() getmousepos (EXT_CSQC)
+NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
+NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
+NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
+NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
+NULL, // #349 float() isdemo (EXT_CSQC)
+VM_isserver, // #350 float() isserver (EXT_CSQC)
+NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
+NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
+VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
+VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
+NULL, // #355
+NULL, // #356
+NULL, // #357
+NULL, // #358
+NULL, // #359
+NULL, // #360 float() readbyte (EXT_CSQC)
+NULL, // #361 float() readchar (EXT_CSQC)
+NULL, // #362 float() readshort (EXT_CSQC)
+NULL, // #363 float() readlong (EXT_CSQC)
+NULL, // #364 float() readcoord (EXT_CSQC)
+NULL, // #365 float() readangle (EXT_CSQC)
+NULL, // #366 string() readstring (EXT_CSQC)
+NULL, // #367 float() readfloat (EXT_CSQC)
+NULL, // #368
+NULL, // #369
+NULL, // #370
+NULL, // #371
+NULL, // #372
+NULL, // #373
+NULL, // #374
+NULL, // #375
+NULL, // #376
+NULL, // #377
+NULL, // #378
+NULL, // #379
+NULL, // #380
+NULL, // #381
+NULL, // #382
+NULL, // #383
+NULL, // #384
+NULL, // #385
+NULL, // #386
+NULL, // #387
+NULL, // #388
+NULL, // #389
+NULL, // #390
+NULL, // #391
+NULL, // #392
+NULL, // #393
+NULL, // #394
+NULL, // #395
+NULL, // #396
+NULL, // #397
+NULL, // #398
+NULL, // #399
+// LordHavoc's range #400-#499
+VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
+VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
+VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
+VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
+VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
+VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
+VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
+VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
+VM_SV_te_particlecube, // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE)
+VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
+VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
+VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
+VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
+VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
+VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
+VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
+VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
+VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
+VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
+VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
+VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
+VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
+VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
+VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
+VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
+VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
+VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
+VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
+VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
+VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
+VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
+VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
+VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
+VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
+VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
+VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
+VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
+VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
+VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
+VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
+VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
+VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
+VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
+VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
+VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
+VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
+VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
+VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
+VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
+VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
+VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
+VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
+VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
+VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
+VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
+VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
+VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
+VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
+NULL, // #458
+VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
+VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
+VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
+VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
+VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
+VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
+VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
+VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
+VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
+VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
+VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
+NULL, // #470
+VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
+VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
+VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
+VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
+VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
+VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
+VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
+VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
+NULL, // #479
+NULL, // #480
+NULL, // #481
+NULL, // #482
+NULL, // #483
+NULL, // #484
+NULL, // #485
+NULL, // #486
+NULL, // #487
+NULL, // #488
+NULL, // #489
+NULL, // #490
+NULL, // #491
+NULL, // #492
+NULL, // #493
+NULL, // #494
+NULL, // #495
+NULL, // #496
+NULL, // #497
+NULL, // #498
+NULL, // #499
};
const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
0 bug darkplaces client: it has been reported that sometimes level changes on quakeworld servers don't load a map, this may be related to downloading? (Baker)
0 bug darkplaces client: name (and probably other userinfo properties) are not being set when entering a qw server?
0 bug darkplaces loader: make rtlight entity loader support q3map/q3map2 lights properly, they use a spawnflag for LINEAR mode, by default they use 1/(x*x) falloff (Carni, motorsep)
+0 bug darkplaces physics: when riding a lift down (such as near the start of e1m1), the player is not being pulled down, unlike in quake, this can cause repeated fall damage on very fast lifts (scar3crow)
0 bug darkplaces readme: commandline options are slightly out of date, update them (Baker)
0 bug darkplaces readme: it would be a very good idea to add documentation of sv_gameplayfix_* cvars in the readme as a means to run broken mods (xaGe)
0 bug darkplaces renderer: GL13 path has broken handling of unlit surfaces in Nexuiz toxic.bsp - the small red light surfaces are black in GL13 path (m0rfar)
chase_dest[0] = vieworg[0] + forward[0] * dist;
chase_dest[1] = vieworg[1] + forward[1] * dist;
chase_dest[2] = vieworg[2] + forward[2] * dist + camup;
- trace = CL_TraceBox(vieworg, vec3_origin, vec3_origin, chase_dest, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, false);
+ trace = CL_Move(vieworg, vec3_origin, vec3_origin, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false);
VectorMAMAM(1, trace.endpos, 8, forward, 4, trace.plane.normal, vieworg);
}
else