//4 feature darkplaces csqc: add builtin to clientside qc for reading triangles of model meshes (useful to orient a ui along a triangle of a model mesh)
//4 feature darkplaces csqc: add builtins to clientside qc for gl calls
-//[515]: really need new list ?
-char *vm_cl_extensions =
-"BX_WAL_SUPPORT "
-"DP_CON_SET "
-"DP_CON_SETA "
-"DP_CON_STARTMAP "
-"DP_EF_ADDITIVE "
-"DP_EF_BLUE "
-"DP_EF_FLAME "
-"DP_EF_FULLBRIGHT "
-"DP_EF_NODEPTHTEST "
-"DP_EF_NODRAW "
-"DP_EF_NOSHADOW "
-"DP_EF_RED "
-"DP_EF_STARDUST "
-"DP_ENT_ALPHA "
-"DP_ENT_CUSTOMCOLORMAP "
-"DP_ENT_GLOW "
-"DP_ENT_SCALE "
-"DP_GFX_EXTERNALTEXTURES "
-"DP_GFX_EXTERNALTEXTURES_PERMAP "
-"DP_GFX_FOG "
-"DP_GFX_QUAKE3MODELTAGS "
-"DP_GFX_SKINFILES "
-"DP_GFX_SKYBOX "
-"DP_HALFLIFE_MAP "
-"DP_HALFLIFE_MAP_CVAR "
-"DP_HALFLIFE_SPRITE "
-"DP_INPUTBUTTONS "
-"DP_LITSPRITES "
-"DP_LITSUPPORT "
-"DP_MONSTERWALK "
-"DP_MOVETYPEBOUNCEMISSILE "
-"DP_MOVETYPEFOLLOW "
-"DP_QC_ASINACOSATANATAN2TAN "
-"DP_QC_CHANGEPITCH "
-"DP_QC_COPYENTITY "
-"DP_QC_CVAR_STRING "
-"DP_QC_ETOS "
-"DP_QC_FINDCHAIN "
-"DP_QC_FINDCHAINFLAGS "
-"DP_QC_FINDCHAINFLOAT "
-"DP_QC_FINDFLAGS "
-"DP_QC_FINDFLOAT "
-"DP_QC_FS_SEARCH " // Black: same as in the menu qc
-"DP_QC_GETLIGHT "
-"DP_QC_GETSURFACE "
-"DP_QC_GETTAGINFO "
-"DP_QC_MINMAXBOUND "
-"DP_QC_MULTIPLETEMPSTRINGS "
-"DP_QC_RANDOMVEC "
-"DP_QC_SINCOSSQRTPOW "
-//"DP_QC_STRINGBUFFERS " //[515]: not needed ?
-"DP_QC_STRFTIME "
-"DP_QC_STRINGCOLORFUNCTIONS "
-"DP_QC_TRACEBOX "
-//"DP_QC_TRACETOSS "
-"DP_QC_TRACE_MOVETYPE_HITMODEL "
-"DP_QC_TRACE_MOVETYPE_WORLDONLY "
-"DP_QC_UNLIMITEDTEMPSTRINGS "
-"DP_QC_VECTORVECTORS "
-"DP_QUAKE2_MODEL "
-"DP_QUAKE2_SPRITE "
-"DP_QUAKE3_MAP "
-"DP_QUAKE3_MODEL "
-"DP_REGISTERCVAR "
-"DP_SND_DIRECTIONLESSATTNNONE "
-"DP_SND_FAKETRACKS "
-"DP_SND_OGGVORBIS "
-"DP_SND_STEREOWAV "
-"DP_SOLIDCORPSE "
-"DP_SPRITE32 "
-"DP_SV_EFFECT "
-"DP_SV_ROTATINGBMODEL "
-"DP_SV_SLOWMO "
-"DP_TE_BLOOD "
-"DP_TE_BLOODSHOWER "
-"DP_TE_CUSTOMFLASH "
-"DP_TE_EXPLOSIONRGB "
-"DP_TE_FLAMEJET "
-"DP_TE_PARTICLECUBE "
-"DP_TE_PARTICLERAIN "
-"DP_TE_PARTICLESNOW "
-"DP_TE_PLASMABURN "
-"DP_TE_QUADEFFECTS1 "
-"DP_TE_SMALLFLASH "
-"DP_TE_SPARK "
-"DP_TE_STANDARDEFFECTBUILTINS "
-"EXT_BITSHIFT "
-"EXT_CSQC "
-"FRIK_FILE "
-"KRIMZON_SV_PARSECLIENTCOMMAND "
-"NEH_CMD_PLAY2 "
-"NXQ_GFX_LETTERBOX "
-"PRYDON_CLIENTCURSOR "
-"TENEBRAE_GFX_DLIGHTS "
-"TW_SV_STEPCONTROL "
-"NEXUIZ_PLAYERMODEL "
-"NEXUIZ_PLAYERSKIN "
-;
-
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;
prvm_edict_t *entity;
- int volume;
+ float volume;
float attenuation;
VM_SAFEPARMCOUNT(5, VM_CL_sound);
entity = PRVM_G_EDICT(OFS_PARM0);
channel = (int)PRVM_G_FLOAT(OFS_PARM1);
sample = PRVM_G_STRING(OFS_PARM2);
- volume = (int)(PRVM_G_FLOAT(OFS_PARM3)*255.0f);
+ volume = PRVM_G_FLOAT(OFS_PARM3);
attenuation = PRVM_G_FLOAT(OFS_PARM4);
- if (volume < 0 || volume > 255)
+ if (volume < 0 || volume > 1)
{
VM_Warning("VM_CL_sound: volume must be in range 0-1\n");
return;
S_StartSound(32768 + PRVM_NUM_FOR_EDICT(entity), channel, S_FindName(sample), entity->fields.client->origin, volume, attenuation);
}
+// #483 void(vector origin, string sample, float volume, float attenuation) pointsound
+static void VM_CL_pointsound(void)
+{
+ const char *sample;
+ float volume;
+ float attenuation;
+ vec3_t org;
+
+ VM_SAFEPARMCOUNT(4, VM_CL_pointsound);
+
+ VectorCopy( PRVM_G_VECTOR(OFS_PARM0), org);
+ sample = PRVM_G_STRING(OFS_PARM1);
+ volume = PRVM_G_FLOAT(OFS_PARM2);
+ attenuation = PRVM_G_FLOAT(OFS_PARM3);
+
+ if (volume < 0 || volume > 1)
+ {
+ VM_Warning("VM_CL_pointsound: volume must be in range 0-1\n");
+ return;
+ }
+
+ if (attenuation < 0 || attenuation > 4)
+ {
+ VM_Warning("VM_CL_pointsound: attenuation must be in range 0-4\n");
+ return;
+ }
+
+ // Send World Entity as Entity to Play Sound (for CSQC, that is 32768)
+ S_StartSound(32768, 0, S_FindName(sample), org, volume, attenuation);
+}
+
// #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
- 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;
+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_Move(v1, m1, m2, v2, move, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
+
+ VM_SetTraceGlobals(&trace);
+}
+
+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.movevars_gravity * 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;
{
if (ent->priv.required->free)
continue;
-// 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);
if(BoxesOverlap(mins, maxs, ent->fields.client->absmin, ent->fields.client->absmax))
list[k++] = ent;
}
}
// #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);
eorg[2] -= bound(ent->fields.client->mins[2], eorg[2], ent->fields.client->maxs[2]);
}
else
- VectorMAMAM(1, eorg, 0.5f, ent->fields.client->mins, 0.5f, ent->fields.client->maxs, eorg);
+ VectorMAMAM(1, eorg, -0.5f, ent->fields.client->mins, -0.5f, ent->fields.client->maxs, eorg);
if (DotProduct(eorg, eorg) < radius2)
{
ent->fields.client->chain = PRVM_EDICT_TO_PROG(chain);
}
// #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;
//[515]: SCENE MANAGER builtins
extern qboolean CSQC_AddRenderEdict (prvm_edict_t *ed);//csprogs.c
-matrix4x4_t csqc_listenermatrix;
-qboolean csqc_usecsqclistener = false;//[515]: per-frame
-
static void CSQC_R_RecalcView (void)
{
extern matrix4x4_t viewmodelmatrix;
- Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], 1);
- Matrix4x4_CreateFromQuakeEntity(&viewmodelmatrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], cl_viewmodel_scale.value);
+ Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], 1);
+ Matrix4x4_CreateFromQuakeEntity(&viewmodelmatrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], cl_viewmodel_scale.value);
}
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;
+ // FIXME: restore these to the values from VM_CL_UpdateView
+ r_view.x = 0;
+ r_view.y = 0;
+ r_view.z = 0;
+ r_view.width = vid.width;
+ r_view.height = vid.height;
+ r_view.depth = 1;
+ // FIXME: restore frustum_x/frustum_y
+ r_view.useperspective = true;
+ r_view.frustum_y = tan(scr_fov.value * M_PI / 360.0) * (3.0/4.0) * cl.viewzoom;
+ r_view.frustum_x = r_view.frustum_y * (float)r_view.width / (float)r_view.height / vid_pixelheight.value;
+ r_view.frustum_x *= r_refdef.frustumscale_x;
+ r_view.frustum_y *= r_refdef.frustumscale_y;
+ r_view.ortho_x = scr_fov.value * (3.0 / 4.0) * (float)r_view.width / (float)r_view.height / vid_pixelheight.value;
+ r_view.ortho_y = scr_fov.value * (3.0 / 4.0);
+ // FIXME: restore cl.csqc_origin
+ // FIXME: restore cl.csqc_angles
+ cl.csqc_vidvars.drawworld = true;
+ cl.csqc_vidvars.drawenginesbar = false;
+ cl.csqc_vidvars.drawcrosshair = false;
}
//#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();
ed = &prog->edicts[i];
if(ed->priv.required->free)
continue;
- VectorAdd(ed->fields.client->origin, ed->fields.client->mins, ed->fields.client->absmin);
- VectorAdd(ed->fields.client->origin, ed->fields.client->maxs, ed->fields.client->absmax);
CSQC_Think(ed);
if(ed->priv.required->free)
continue;
}
//#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);
switch(c)
{
- case VF_MIN: r_view.x = (int)f[0];
- r_view.y = (int)f[1];
+ case VF_MIN: r_view.x = (int)(f[0] * vid.width / vid_conwidth.value);
+ r_view.y = (int)(f[1] * vid.height / vid_conheight.value);
break;
- case VF_MIN_X: r_view.x = (int)k;
+ case VF_MIN_X: r_view.x = (int)(k * vid.width / vid_conwidth.value);
break;
- case VF_MIN_Y: r_view.y = (int)k;
+ case VF_MIN_Y: r_view.y = (int)(k * vid.height / vid_conheight.value);
break;
- case VF_SIZE: r_view.width = (int)f[0];
- r_view.height = (int)f[1];
+ case VF_SIZE: r_view.width = (int)(f[0] * vid.width / vid_conwidth.value);
+ r_view.height = (int)(f[1] * vid.height / vid_conheight.value);
break;
- case VF_SIZE_Y: r_view.width = (int)k;
+ case VF_SIZE_Y: r_view.width = (int)(k * vid.width / vid_conwidth.value);
break;
- case VF_SIZE_X: r_view.height = (int)k;
+ case VF_SIZE_X: r_view.height = (int)(k * vid.height / vid_conheight.value);
break;
- case VF_VIEWPORT: r_view.x = (int)f[0];
- r_view.y = (int)f[1];
- r_view.z = 0;
- // TODO: make sure that view_z and view_depth are set properly even if csqc does not set them!
+ case VF_VIEWPORT: r_view.x = (int)(f[0] * vid.width / vid_conwidth.value);
+ r_view.y = (int)(f[1] * vid.height / vid_conheight.value);
f = PRVM_G_VECTOR(OFS_PARM2);
- r_view.width = (int)f[0];
- r_view.height = (int)f[1];
- r_view.depth = 1;
+ r_view.width = (int)(f[0] * vid.width / vid_conwidth.value);
+ r_view.height = (int)(f[1] * vid.height / vid_conheight.value);
break;
- case VF_FOV: //r_refdef.fov_x = f[0]; // FIXME!
- //r_refdef.fov_y = f[1]; // FIXME!
+ case VF_FOV: r_view.frustum_x = tan(f[0] * M_PI / 360.0);r_view.ortho_x = f[0];
+ r_view.frustum_y = tan(f[1] * M_PI / 360.0);r_view.ortho_y = f[1];
break;
- case VF_FOVX: //r_refdef.fov_x = k; // FIXME!
+ case VF_FOVX: r_view.frustum_x = tan(k * M_PI / 360.0);r_view.ortho_x = k;
break;
- case VF_FOVY: //r_refdef.fov_y = k; // FIXME!
+ case VF_FOVY: r_view.frustum_y = tan(k * M_PI / 360.0);r_view.ortho_y = k;
break;
- case VF_ORIGIN: VectorCopy(f, csqc_origin);
+ case VF_ORIGIN: VectorCopy(f, cl.csqc_origin);
CSQC_R_RecalcView();
break;
- case VF_ORIGIN_X: csqc_origin[0] = k;
+ case VF_ORIGIN_X: cl.csqc_origin[0] = k;
CSQC_R_RecalcView();
break;
- case VF_ORIGIN_Y: csqc_origin[1] = k;
+ case VF_ORIGIN_Y: cl.csqc_origin[1] = k;
CSQC_R_RecalcView();
break;
- case VF_ORIGIN_Z: csqc_origin[2] = k;
+ case VF_ORIGIN_Z: cl.csqc_origin[2] = k;
CSQC_R_RecalcView();
break;
- case VF_ANGLES: VectorCopy(f, csqc_angles);
+ case VF_ANGLES: VectorCopy(f, cl.csqc_angles);
CSQC_R_RecalcView();
break;
- case VF_ANGLES_X: csqc_angles[0] = k;
+ case VF_ANGLES_X: cl.csqc_angles[0] = k;
CSQC_R_RecalcView();
break;
- case VF_ANGLES_Y: csqc_angles[1] = k;
+ case VF_ANGLES_Y: cl.csqc_angles[1] = k;
CSQC_R_RecalcView();
break;
- case VF_ANGLES_Z: csqc_angles[2] = k;
+ case VF_ANGLES_Z: cl.csqc_angles[2] = k;
CSQC_R_RecalcView();
break;
case VF_DRAWWORLD: cl.csqc_vidvars.drawworld = k;
case VF_CL_VIEWANGLES_Z:cl.viewangles[2] = k;
break;
+ case VF_PERSPECTIVE: r_view.useperspective = k != 0;
+ 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++)
- {
- if (cl.entities_active[i])
- {
- entity_t *ent = cl.entities + i;
- if ((ent->render.flags & RENDER_VIEWMODEL) || ent->state_current.tagentity)
- CL_UpdateNetworkEntity(ent, 32);
- }
- }
- // and of course the engine viewmodel needs updating as well
- CL_UpdateNetworkEntity(&cl.viewent, 32);
+ CL_UpdateViewEntities();
// now draw stuff!
R_RenderView();
}
//#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);
+ int firstbit, bitcount;
+
+ VM_SAFEPARMCOUNTRANGE(1, 3, VM_CL_getstati);
+
index = (int)PRVM_G_FLOAT(OFS_PARM0);
+ if (prog->argc > 1)
+ {
+ firstbit = (int)PRVM_G_FLOAT(OFS_PARM1);
+ if (prog->argc > 2)
+ bitcount = (int)PRVM_G_FLOAT(OFS_PARM2);
+ else
+ bitcount = 1;
+ }
+ else
+ {
+ firstbit = 0;
+ bitcount = 32;
+ }
if(index < 0 || index >= MAX_CL_STATS)
{
return;
}
i = cl.stats[index];
+ if (bitcount != 32) //32 causes the mask to overflow, so there's nothing to subtract from.
+ i = (((unsigned int)i)&(((1<<bitcount)-1)<<firstbit))>>firstbit;
PRVM_G_FLOAT(OFS_RETURN) = i;
}
//#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];
else
if(!strcasecmp(c, "ping"))
sprintf(t, "%i", cl.scores[i].qw_ping);
+ else
+ if(!strcasecmp(c, "pl"))
+ sprintf(t, "%i", cl.scores[i].qw_packetloss);
else
if(!strcasecmp(c, "entertime"))
sprintf(t, "%f", cl.scores[i].qw_entertime);
}
//#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));
- csqc_usecsqclistener = true; //use csqc listener at this frame
+ Matrix4x4_FromVectors(&cl.csqc_listenermatrix, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), PRVM_G_VECTOR(OFS_PARM3), PRVM_G_VECTOR(OFS_PARM0));
+ cl.csqc_usecsqclistener = true; //use csqc listener at this frame
}
//#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.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);
+
+ // 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 | EF_ADDITIVE | EF_NODEPTHTEST)) && (staticent->render.alpha >= 1))
+ 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;
CL_ParticleEffect(EFFECT_TE_SPARK, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM1), NULL, 0);
}
+extern cvar_t cl_sound_ric_gunshot;
// #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;
+ int rnd;
VM_SAFEPARMCOUNT(1, VM_CL_te_gunshotquad);
pos = PRVM_G_VECTOR(OFS_PARM0);
CL_FindNonSolidLocation(pos, pos2, 4);
CL_ParticleEffect(EFFECT_TE_GUNSHOTQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
+ if(cl_sound_ric_gunshot.integer >= 2)
+ {
+ if (rand() % 5) S_StartSound(-1, 0, cl.sfx_tink1, pos2, 1, 1);
+ else
+ {
+ rnd = rand() & 3;
+ if (rnd == 1) S_StartSound(-1, 0, cl.sfx_ric1, pos2, 1, 1);
+ else if (rnd == 2) S_StartSound(-1, 0, cl.sfx_ric2, pos2, 1, 1);
+ else S_StartSound(-1, 0, cl.sfx_ric3, pos2, 1, 1);
+ }
+ }
}
// #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;
+ int rnd;
VM_SAFEPARMCOUNT(1, VM_CL_te_gunshot);
pos = PRVM_G_VECTOR(OFS_PARM0);
CL_FindNonSolidLocation(pos, pos2, 4);
CL_ParticleEffect(EFFECT_TE_GUNSHOT, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
+ if(cl_sound_ric_gunshot.integer == 1 || cl_sound_ric_gunshot.integer == 3)
+ {
+ if (rand() % 5) S_StartSound(-1, 0, cl.sfx_tink1, pos2, 1, 1);
+ else
+ {
+ rnd = rand() & 3;
+ if (rnd == 1) S_StartSound(-1, 0, cl.sfx_ric1, pos2, 1, 1);
+ else if (rnd == 2) S_StartSound(-1, 0, cl.sfx_ric2, pos2, 1, 1);
+ else S_StartSound(-1, 0, cl.sfx_ric3, pos2, 1, 1);
+ }
+ }
}
// #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;
- v = PRVM_GETEDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
+ v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
if (v)
v->edict = PRVM_EDICT_TO_PROG(tagentity);
- v = PRVM_GETEDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
+ v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
if (v)
v->_float = 0;
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;
else
tagmatrix = identitymatrix;
- if ((val = PRVM_GETEDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
+ if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
{ // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
attachloop = 0;
do
{
attachent = PRVM_EDICT_NUM(val->edict); // to this it entity our entity is attached
- val = PRVM_GETEDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index);
+ 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);
attachmatrix = identitymatrix;
// apply transformation by child entity matrix
- val = PRVM_GETEDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
+ val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
if (val->_float == 0)
val->_float = 1;
Matrix4x4_CreateFromQuakeEntity(&entitymatrix, 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], val->_float);
if (attachloop > 255) // prevent runaway looping
return 5;
}
- while ((val = PRVM_GETEDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict);
+ while ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict);
}
// normal or RENDER_VIEWMODEL entity (or main parent entity on attach chain)
- val = PRVM_GETEDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
+ val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
if (val->_float == 0)
val->_float = 1;
// Alias models have inverse pitch, bmodels can't have tags, so don't check for modeltype...
Matrix4x4_CreateFromQuakeEntity(&entitymatrix, 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], val->_float);
Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
- if ((val = PRVM_GETEDICTFIELDVALUE(ent, prog->fieldoffsets.renderflags)) && (RF_VIEWMODEL & (int)val->_float))
+ if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.renderflags)) && (RF_VIEWMODEL & (int)val->_float))
{// RENDER_VIEWMODEL magic
Matrix4x4_Copy(&tagmatrix, out);
- val = PRVM_GETEDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
+ val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
if (val->_float == 0)
val->_float = 1;
- Matrix4x4_CreateFromQuakeEntity(&entitymatrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], val->_float);
+ Matrix4x4_CreateFromQuakeEntity(&entitymatrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], val->_float);
Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
/*
// should be done in QC on the server, but oh well, quake is quake)
// LordHavoc: figured out bobup: the time at which the sin is at 180
// degrees (which allows lengthening or squishing the peak or valley)
- cycle = sv.time/cl_bobcycle.value;
+ cycle = cl.time/cl_bobcycle.value;
cycle -= (int)cycle;
if (cycle < cl_bobup.value)
cycle = sin(M_PI * cycle / cl_bobup.value);
}
// #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_E_INT(ent,prog->fieldoffsets.chain) = 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_E_INT(ent,prog->fieldoffsets.chain) = 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;
}
- out[i] = in[k];
- ++k;
- ++i;
+
+ 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;
+ }
+ 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
+VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
+VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
+VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
+VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
+VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
+VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
+VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
+VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
+VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
+VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
+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
+VM_drawcolorcodedstring, // #326 float drawcolorcodedstring(vector position, string text, vector scale, vector rgb, float alpha, float flag) (EXT_CSQC)
+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_QC_FS_SEARCH)
+VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
+VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
+VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_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)
+VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
+VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
+VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
+VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
+VM_CL_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
+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;
+ }
}