]> icculus.org git repositories - divverent/darkplaces.git/blob - clvm_cmds.c
cleaned up client qc, menu qc, and server qc VM initialization a bit so they have...
[divverent/darkplaces.git] / clvm_cmds.c
1 #include "prvm_cmds.h"
2 #include "csprogs.h"
3 #include "cl_collision.h"
4 #include "r_shadow.h"
5
6 //============================================================================
7 // Client
8 //[515]: unsolved PROBLEMS
9 //- finish player physics code (cs_runplayerphysics)
10 //- EntWasFreed ?
11 //- RF_DEPTHHACK is not like it should be
12 //- add builtin that sets cl.viewangles instead of reading "input_angles" global
13 //- finish lines support for R_Polygon***
14 //- insert selecttraceline into traceline somehow
15
16 //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)
17 //4 feature darkplaces csqc: add builtins to clientside qc for gl calls
18
19 //[515]: really need new list ?
20 char *vm_cl_extensions =
21 "BX_WAL_SUPPORT "
22 "DP_CON_SET "
23 "DP_CON_SETA "
24 "DP_CON_STARTMAP "
25 "DP_EF_ADDITIVE "
26 "DP_EF_BLUE "
27 "DP_EF_FLAME "
28 "DP_EF_FULLBRIGHT "
29 "DP_EF_NODEPTHTEST "
30 "DP_EF_NODRAW "
31 "DP_EF_NOSHADOW "
32 "DP_EF_RED "
33 "DP_EF_STARDUST "
34 "DP_ENT_ALPHA "
35 "DP_ENT_CUSTOMCOLORMAP "
36 "DP_ENT_GLOW "
37 "DP_ENT_SCALE "
38 "DP_GFX_EXTERNALTEXTURES "
39 "DP_GFX_EXTERNALTEXTURES_PERMAP "
40 "DP_GFX_FOG "
41 "DP_GFX_QUAKE3MODELTAGS "
42 "DP_GFX_SKINFILES "
43 "DP_GFX_SKYBOX "
44 "DP_HALFLIFE_MAP "
45 "DP_HALFLIFE_MAP_CVAR "
46 "DP_HALFLIFE_SPRITE "
47 "DP_INPUTBUTTONS "
48 "DP_LITSPRITES "
49 "DP_LITSUPPORT "
50 "DP_MONSTERWALK "
51 "DP_MOVETYPEBOUNCEMISSILE "
52 "DP_MOVETYPEFOLLOW "
53 "DP_QC_ASINACOSATANATAN2TAN "
54 "DP_QC_CHANGEPITCH "
55 "DP_QC_COPYENTITY "
56 "DP_QC_CVAR_STRING "
57 "DP_QC_ETOS "
58 "DP_QC_FINDCHAIN "
59 "DP_QC_FINDCHAINFLAGS "
60 "DP_QC_FINDCHAINFLOAT "
61 "DP_QC_FINDFLAGS "
62 "DP_QC_FINDFLOAT "
63 "DP_QC_FS_SEARCH " // Black: same as in the menu qc
64 "DP_QC_GETLIGHT "
65 "DP_QC_GETSURFACE "
66 "DP_QC_GETTAGINFO "
67 "DP_QC_MINMAXBOUND "
68 "DP_QC_MULTIPLETEMPSTRINGS "
69 "DP_QC_RANDOMVEC "
70 "DP_QC_SINCOSSQRTPOW "
71 //"DP_QC_STRINGBUFFERS "        //[515]: not needed ?
72 "DP_QC_STRFTIME "
73 "DP_QC_STRINGCOLORFUNCTIONS "
74 "DP_QC_TRACEBOX "
75 //"DP_QC_TRACETOSS "
76 "DP_QC_TRACE_MOVETYPE_HITMODEL "
77 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
78 "DP_QC_UNLIMITEDTEMPSTRINGS "
79 "DP_QC_VECTORVECTORS "
80 "DP_QUAKE2_MODEL "
81 "DP_QUAKE2_SPRITE "
82 "DP_QUAKE3_MAP "
83 "DP_QUAKE3_MODEL "
84 "DP_REGISTERCVAR "
85 "DP_SND_DIRECTIONLESSATTNNONE "
86 "DP_SND_FAKETRACKS "
87 "DP_SND_OGGVORBIS "
88 "DP_SND_STEREOWAV "
89 "DP_SOLIDCORPSE "
90 "DP_SPRITE32 "
91 "DP_SV_EFFECT "
92 "DP_SV_ROTATINGBMODEL "
93 "DP_SV_SLOWMO "
94 "DP_TE_BLOOD "
95 "DP_TE_BLOODSHOWER "
96 "DP_TE_CUSTOMFLASH "
97 "DP_TE_EXPLOSIONRGB "
98 "DP_TE_FLAMEJET "
99 "DP_TE_PARTICLECUBE "
100 "DP_TE_PARTICLERAIN "
101 "DP_TE_PARTICLESNOW "
102 "DP_TE_PLASMABURN "
103 "DP_TE_QUADEFFECTS1 "
104 "DP_TE_SMALLFLASH "
105 "DP_TE_SPARK "
106 "DP_TE_STANDARDEFFECTBUILTINS "
107 "EXT_BITSHIFT "
108 "EXT_CSQC "
109 "FRIK_FILE "
110 "KRIMZON_SV_PARSECLIENTCOMMAND "
111 "NEH_CMD_PLAY2 "
112 "NXQ_GFX_LETTERBOX "
113 "PRYDON_CLIENTCURSOR "
114 "TENEBRAE_GFX_DLIGHTS "
115 "TW_SV_STEPCONTROL "
116 "NEXUIZ_PLAYERMODEL "
117 "NEXUIZ_PLAYERSKIN "
118 ;
119
120 sfx_t *S_FindName(const char *name);
121 void PF_registercvar (void);
122 int Sbar_GetPlayer (int index);
123 void Sbar_SortFrags (void);
124 void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius);
125 void CSQC_RelinkAllEntities (int drawmask);
126 void CSQC_RelinkCSQCEntities (void);
127 char *Key_GetBind (int key);
128 model_t *CSQC_GetModelByIndex(int modelindex);
129 model_t *CSQC_GetModelFromEntity(prvm_edict_t *ed);
130 void CL_LinkEdict(prvm_edict_t *ed);
131
132
133
134
135
136
137 // #1 void(vector ang) makevectors
138 void VM_CL_makevectors (void)
139 {
140         VM_SAFEPARMCOUNT(1, VM_CL_makevectors);
141         AngleVectors (PRVM_G_VECTOR(OFS_PARM0), prog->globals.client->v_forward, prog->globals.client->v_right, prog->globals.client->v_up);
142 }
143
144 // #2 void(entity e, vector o) setorigin
145 void VM_CL_setorigin (void)
146 {
147         prvm_edict_t    *e;
148         float   *org;
149
150         e = PRVM_G_EDICT(OFS_PARM0);
151         if (e == prog->edicts)
152         {
153                 VM_Warning("setorigin: can not modify world entity\n");
154                 return;
155         }
156         if (e->priv.required->free)
157         {
158                 VM_Warning("setorigin: can not modify free entity\n");
159                 return;
160         }
161         org = PRVM_G_VECTOR(OFS_PARM1);
162         VectorCopy (org, e->fields.client->origin);
163         CL_LinkEdict(e);
164 }
165
166 // #3 void(entity e, string m) setmodel
167 void VM_CL_setmodel (void)
168 {
169         prvm_edict_t    *e;
170         const char              *m;
171         struct model_s  *mod;
172         int                             i;
173
174         VM_SAFEPARMCOUNT(2, VM_CL_setmodel);
175
176         e = PRVM_G_EDICT(OFS_PARM0);
177         m = PRVM_G_STRING(OFS_PARM1);
178         for (i = 0;i < MAX_MODELS && cl.csqc_model_precache[i];i++)
179         {
180                 if (!strcmp(cl.csqc_model_precache[i]->name, m))
181                 {
182                         e->fields.client->model = PRVM_SetEngineString(cl.csqc_model_precache[i]->name);
183                         e->fields.client->modelindex = -(i+1);
184                         return;
185                 }
186         }
187
188         for (i = 0;i < MAX_MODELS;i++)
189         {
190                 mod = cl.model_precache[i];
191                 if (mod && !strcmp(mod->name, m))
192                 {
193                         e->fields.client->model = PRVM_SetEngineString(mod->name);
194                         e->fields.client->modelindex = i;
195                         return;
196                 }
197         }
198
199         e->fields.client->modelindex = 0;
200         e->fields.client->model = 0;
201 }
202
203 // #4 void(entity e, vector min, vector max) setsize
204 void VM_CL_setsize (void)
205 {
206         prvm_edict_t    *e;
207         float                   *min, *max;
208         VM_SAFEPARMCOUNT(3, VM_CL_setsize);
209
210         e = PRVM_G_EDICT(OFS_PARM0);
211         if (e == prog->edicts)
212         {
213                 VM_Warning("setsize: can not modify world entity\n");
214                 return;
215         }
216         if (e->priv.server->free)
217         {
218                 VM_Warning("setsize: can not modify free entity\n");
219                 return;
220         }
221         min = PRVM_G_VECTOR(OFS_PARM1);
222         max = PRVM_G_VECTOR(OFS_PARM2);
223
224         VectorCopy (min, e->fields.client->mins);
225         VectorCopy (max, e->fields.client->maxs);
226         VectorSubtract (max, min, e->fields.client->size);
227
228         CL_LinkEdict(e);
229 }
230
231 // #8 void(entity e, float chan, string samp) sound
232 void VM_CL_sound (void)
233 {
234         const char                      *sample;
235         int                                     channel;
236         prvm_edict_t            *entity;
237         int                             volume;
238         float                           attenuation;
239
240         VM_SAFEPARMCOUNT(5, VM_CL_sound);
241
242         entity = PRVM_G_EDICT(OFS_PARM0);
243         channel = (int)PRVM_G_FLOAT(OFS_PARM1);
244         sample = PRVM_G_STRING(OFS_PARM2);
245         volume = (int)(PRVM_G_FLOAT(OFS_PARM3)*255.0f);
246         attenuation = PRVM_G_FLOAT(OFS_PARM4);
247
248         if (volume < 0 || volume > 255)
249         {
250                 VM_Warning("VM_CL_sound: volume must be in range 0-1\n");
251                 return;
252         }
253
254         if (attenuation < 0 || attenuation > 4)
255         {
256                 VM_Warning("VM_CL_sound: attenuation must be in range 0-4\n");
257                 return;
258         }
259
260         if (channel < 0 || channel > 7)
261         {
262                 VM_Warning("VM_CL_sound: channel must be in range 0-7\n");
263                 return;
264         }
265
266         S_StartSound(32768 + PRVM_NUM_FOR_EDICT(entity), channel, S_FindName(sample), entity->fields.client->origin, volume, attenuation);
267 }
268
269 // #14 entity() spawn
270 void VM_CL_spawn (void)
271 {
272         prvm_edict_t *ed;
273         ed = PRVM_ED_Alloc();
274         ed->fields.client->entnum = PRVM_NUM_FOR_EDICT(ed);     //[515]: not needed any more ?
275         VM_RETURN_EDICT(ed);
276 }
277
278 // #16 float(vector v1, vector v2, float tryents) traceline
279 void VM_CL_traceline (void)
280 {
281         float   *v1, *v2;
282         trace_t trace;
283         int             ent;
284
285         v1 = PRVM_G_VECTOR(OFS_PARM0);
286         v2 = PRVM_G_VECTOR(OFS_PARM1);
287
288         trace = CL_TraceBox(v1, vec3_origin, vec3_origin, v2, 1, &ent, 1, false);
289
290         prog->globals.client->trace_allsolid = trace.allsolid;
291         prog->globals.client->trace_startsolid = trace.startsolid;
292         prog->globals.client->trace_fraction = trace.fraction;
293         prog->globals.client->trace_inwater = trace.inwater;
294         prog->globals.client->trace_inopen = trace.inopen;
295         VectorCopy (trace.endpos, prog->globals.client->trace_endpos);
296         VectorCopy (trace.plane.normal, prog->globals.client->trace_plane_normal);
297         prog->globals.client->trace_plane_dist =  trace.plane.dist;
298         if (ent)
299                 prog->globals.client->trace_ent = ent;
300         else
301                 prog->globals.client->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
302 }
303
304 // #19 void(string s) precache_sound
305 void VM_CL_precache_sound (void)
306 {
307         VM_SAFEPARMCOUNT(1, VM_CL_precache_sound);
308         S_PrecacheSound(PRVM_G_STRING(OFS_PARM0), true, false);
309 }
310
311 // #20 void(string s) precache_model
312 void VM_CL_precache_model (void)
313 {
314         const char      *name;
315         int                     i;
316         model_t         *m;
317
318         VM_SAFEPARMCOUNT(1, VM_CL_precache_model);
319
320         name = PRVM_G_STRING(OFS_PARM0);
321         for (i = 1;i < MAX_MODELS && cl.csqc_model_precache[i];i++)
322         {
323                 if(!strcmp(cl.csqc_model_precache[i]->name, name))
324                 {
325                         PRVM_G_FLOAT(OFS_RETURN) = -(i+1);
326                         return;
327                 }
328         }
329         PRVM_G_FLOAT(OFS_RETURN) = 0;
330         m = Mod_ForName(name, false, false, false);
331         if(m && m->loaded)
332         {
333                 for (i = 1;i < MAX_MODELS;i++)
334                 {
335                         if (!cl.csqc_model_precache[i])
336                         {
337                                 cl.csqc_model_precache[i] = (model_t*)m;
338                                 PRVM_G_FLOAT(OFS_RETURN) = -(i+1);
339                                 return;
340                         }
341                 }
342                 VM_Warning("VM_CL_precache_model: no free models\n");
343                 return;
344         }
345         VM_Warning("VM_CL_precache_model: model \"%s\" not found\n", name);
346 }
347
348 int CSQC_EntitiesInBox (vec3_t mins, vec3_t maxs, int maxlist, prvm_edict_t **list)
349 {
350         prvm_edict_t    *ent;
351         int                             i, k;
352
353         ent = PRVM_NEXT_EDICT(prog->edicts);
354         for(k=0,i=1; i<prog->num_edicts ;i++, ent = PRVM_NEXT_EDICT(ent))
355         {
356                 if (ent->priv.required->free)
357                         continue;
358 //              VectorAdd(ent->fields.client->origin, ent->fields.client->mins, ent->fields.client->absmin);
359 //              VectorAdd(ent->fields.client->origin, ent->fields.client->maxs, ent->fields.client->absmax);
360                 if(BoxesOverlap(mins, maxs, ent->fields.client->absmin, ent->fields.client->absmax))
361                         list[k++] = ent;
362         }
363         return k;
364 }
365
366 // #22 entity(vector org, float rad) findradius
367 void VM_CL_findradius (void)
368 {
369         prvm_edict_t    *ent, *chain;
370         vec_t                   radius, radius2;
371         vec3_t                  org, eorg, mins, maxs;
372         int                             i, numtouchedicts;
373         prvm_edict_t    *touchedicts[MAX_EDICTS];
374
375         chain = (prvm_edict_t *)prog->edicts;
376
377         VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
378         radius = PRVM_G_FLOAT(OFS_PARM1);
379         radius2 = radius * radius;
380
381         mins[0] = org[0] - (radius + 1);
382         mins[1] = org[1] - (radius + 1);
383         mins[2] = org[2] - (radius + 1);
384         maxs[0] = org[0] + (radius + 1);
385         maxs[1] = org[1] + (radius + 1);
386         maxs[2] = org[2] + (radius + 1);
387         numtouchedicts = CSQC_EntitiesInBox(mins, maxs, MAX_EDICTS, touchedicts);
388         if (numtouchedicts > MAX_EDICTS)
389         {
390                 // this never happens   //[515]: for what then ?
391                 Con_Printf("CSQC_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
392                 numtouchedicts = MAX_EDICTS;
393         }
394         for (i = 0;i < numtouchedicts;i++)
395         {
396                 ent = touchedicts[i];
397                 // Quake did not return non-solid entities but darkplaces does
398                 // (note: this is the reason you can't blow up fallen zombies)
399                 if (ent->fields.client->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
400                         continue;
401                 // LordHavoc: compare against bounding box rather than center so it
402                 // doesn't miss large objects, and use DotProduct instead of Length
403                 // for a major speedup
404                 VectorSubtract(org, ent->fields.client->origin, eorg);
405                 if (sv_gameplayfix_findradiusdistancetobox.integer)
406                 {
407                         eorg[0] -= bound(ent->fields.client->mins[0], eorg[0], ent->fields.client->maxs[0]);
408                         eorg[1] -= bound(ent->fields.client->mins[1], eorg[1], ent->fields.client->maxs[1]);
409                         eorg[2] -= bound(ent->fields.client->mins[2], eorg[2], ent->fields.client->maxs[2]);
410                 }
411                 else
412                         VectorMAMAM(1, eorg, 0.5f, ent->fields.client->mins, 0.5f, ent->fields.client->maxs, eorg);
413                 if (DotProduct(eorg, eorg) < radius2)
414                 {
415                         ent->fields.client->chain = PRVM_EDICT_TO_PROG(chain);
416                         chain = ent;
417                 }
418         }
419
420         VM_RETURN_EDICT(chain);
421 }
422
423 // #34 float() droptofloor
424 void VM_CL_droptofloor (void)
425 {
426         prvm_edict_t            *ent;
427         vec3_t                          end;
428         trace_t                         trace;
429         int                                     i;
430
431         // assume failure if it returns early
432         PRVM_G_FLOAT(OFS_RETURN) = 0;
433
434         ent = PRVM_PROG_TO_EDICT(prog->globals.client->self);
435         if (ent == prog->edicts)
436         {
437                 VM_Warning("droptofloor: can not modify world entity\n");
438                 return;
439         }
440         if (ent->priv.server->free)
441         {
442                 VM_Warning("droptofloor: can not modify free entity\n");
443                 return;
444         }
445
446         VectorCopy (ent->fields.client->origin, end);
447         end[2] -= 256;
448
449         trace = CL_TraceBox(ent->fields.client->origin, ent->fields.client->mins, ent->fields.client->maxs, end, 1, &i, 1, false);
450
451         if (trace.fraction != 1)
452         {
453                 VectorCopy (trace.endpos, ent->fields.client->origin);
454                 ent->fields.client->flags = (int)ent->fields.client->flags | FL_ONGROUND;
455 //              ent->fields.client->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
456                 PRVM_G_FLOAT(OFS_RETURN) = 1;
457                 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
458 //              ent->priv.server->suspendedinairflag = true;
459         }
460 }
461
462 // #35 void(float style, string value) lightstyle
463 void VM_CL_lightstyle (void)
464 {
465         int                     i;
466         const char      *c;
467
468         VM_SAFEPARMCOUNT(2, VM_CL_lightstyle);
469
470         i = (int)PRVM_G_FLOAT(OFS_PARM0);
471         c = PRVM_G_STRING(OFS_PARM1);
472         if (i >= cl.max_lightstyle)
473         {
474                 VM_Warning("VM_CL_lightstyle >= MAX_LIGHTSTYLES\n");
475                 return;
476         }
477         strlcpy (cl.lightstyle[i].map,  MSG_ReadString(), sizeof (cl.lightstyle[i].map));
478         cl.lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
479         cl.lightstyle[i].length = (int)strlen(cl.lightstyle[i].map);
480 }
481
482 // #40 float(entity e) checkbottom
483 void VM_CL_checkbottom (void)
484 {
485         static int              cs_yes, cs_no;
486         prvm_edict_t    *ent;
487         vec3_t                  mins, maxs, start, stop;
488         trace_t                 trace;
489         int                             x, y, hit;
490         float                   mid, bottom;
491
492         VM_SAFEPARMCOUNT(1, VM_CL_checkbottom);
493         ent = PRVM_G_EDICT(OFS_PARM0);
494         PRVM_G_FLOAT(OFS_RETURN) = 0;
495
496         VectorAdd (ent->fields.client->origin, ent->fields.client->mins, mins);
497         VectorAdd (ent->fields.client->origin, ent->fields.client->maxs, maxs);
498
499 // if all of the points under the corners are solid world, don't bother
500 // with the tougher checks
501 // the corners must be within 16 of the midpoint
502         start[2] = mins[2] - 1;
503         for     (x=0 ; x<=1 ; x++)
504                 for     (y=0 ; y<=1 ; y++)
505                 {
506                         start[0] = x ? maxs[0] : mins[0];
507                         start[1] = y ? maxs[1] : mins[1];
508                         if (!(CL_PointSuperContents(start) & (SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY)))
509                                 goto realcheck;
510                 }
511
512         cs_yes++;
513         PRVM_G_FLOAT(OFS_RETURN) = true;
514         return;         // we got out easy
515
516 realcheck:
517         cs_no++;
518 //
519 // check it for real...
520 //
521         start[2] = mins[2];
522
523 // the midpoint must be within 16 of the bottom
524         start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
525         start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
526         stop[2] = start[2] - 2*sv_stepheight.value;
527         trace = CL_TraceBox (start, vec3_origin, vec3_origin, stop, 1, &hit, 1, true);
528
529         if (trace.fraction == 1.0)
530                 return;
531
532         mid = bottom = trace.endpos[2];
533
534 // the corners must be within 16 of the midpoint
535         for     (x=0 ; x<=1 ; x++)
536                 for     (y=0 ; y<=1 ; y++)
537                 {
538                         start[0] = stop[0] = x ? maxs[0] : mins[0];
539                         start[1] = stop[1] = y ? maxs[1] : mins[1];
540
541                         trace = CL_TraceBox (start, vec3_origin, vec3_origin, stop, 1, &hit, 1, true);
542
543                         if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
544                                 bottom = trace.endpos[2];
545                         if (trace.fraction == 1.0 || mid - trace.endpos[2] > sv_stepheight.value)
546                                 return;
547                 }
548
549         cs_yes++;
550         PRVM_G_FLOAT(OFS_RETURN) = true;
551 }
552
553 // #41 float(vector v) pointcontents
554 void VM_CL_pointcontents (void)
555 {
556         VM_SAFEPARMCOUNT(1, VM_CL_pointcontents);
557         PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, CL_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
558 }
559
560 // #48 void(vector o, vector d, float color, float count) particle
561 void VM_CL_particle (void)
562 {
563         float   *org, *dir;
564         int             count;
565         unsigned char   color;
566         VM_SAFEPARMCOUNT(4, VM_CL_particle);
567
568         org = PRVM_G_VECTOR(OFS_PARM0);
569         dir = PRVM_G_VECTOR(OFS_PARM1);
570         color = (int)PRVM_G_FLOAT(OFS_PARM2);
571         count = (int)PRVM_G_FLOAT(OFS_PARM3);
572         CL_ParticleEffect(EFFECT_SVC_PARTICLE, count, org, org, dir, dir, NULL, color);
573 }
574
575 // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS)
576 void VM_CL_tracetoss (void)
577 {
578 /*      trace_t trace;
579         prvm_edict_t    *ent;
580         prvm_edict_t    *ignore;
581
582         ent = PRVM_G_EDICT(OFS_PARM0);
583         if (ent == prog->edicts)
584         {
585                 VM_Warning("tracetoss: can not use world entity\n");
586                 return;
587         }
588         ignore = PRVM_G_EDICT(OFS_PARM1);
589
590 //FIXME
591         trace = SV_Trace_Toss (ent, ignore);
592
593         prog->globals.server->trace_allsolid = trace.allsolid;
594         prog->globals.server->trace_startsolid = trace.startsolid;
595         prog->globals.server->trace_fraction = trace.fraction;
596         prog->globals.server->trace_inwater = trace.inwater;
597         prog->globals.server->trace_inopen = trace.inopen;
598         VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
599         VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
600         prog->globals.server->trace_plane_dist =  trace.plane.dist;
601         if (trace.ent)
602                 prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
603         else
604                 prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
605 */
606 }
607
608 // #74 void(vector pos, string samp, float vol, float atten) ambientsound
609 void VM_CL_ambientsound (void)
610 {
611         float   *f;
612         sfx_t   *s;
613         VM_SAFEPARMCOUNT(4, VM_CL_ambientsound);
614         s = S_FindName(PRVM_G_STRING(OFS_PARM0));
615         f = PRVM_G_VECTOR(OFS_PARM1);
616         S_StaticSound (s, f, PRVM_G_FLOAT(OFS_PARM2), PRVM_G_FLOAT(OFS_PARM3)*64);
617 }
618
619 // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
620 void VM_CL_tracebox (void)
621 {
622         float   *v1, *v2, *m1, *m2;
623         trace_t trace;
624         int             ent;
625
626         v1 = PRVM_G_VECTOR(OFS_PARM0);
627         m1 = PRVM_G_VECTOR(OFS_PARM1);
628         m2 = PRVM_G_VECTOR(OFS_PARM2);
629         v2 = PRVM_G_VECTOR(OFS_PARM3);
630
631         trace = CL_TraceBox(v1, m1, m2, v2, 1, &ent, 1, false);
632
633         prog->globals.client->trace_allsolid = trace.allsolid;
634         prog->globals.client->trace_startsolid = trace.startsolid;
635         prog->globals.client->trace_fraction = trace.fraction;
636         prog->globals.client->trace_inwater = trace.inwater;
637         prog->globals.client->trace_inopen = trace.inopen;
638         VectorCopy (trace.endpos, prog->globals.client->trace_endpos);
639         VectorCopy (trace.plane.normal, prog->globals.client->trace_plane_normal);
640         prog->globals.client->trace_plane_dist =  trace.plane.dist;
641         if (ent)
642                 prog->globals.client->trace_ent = ent;
643         else
644                 prog->globals.client->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
645 }
646
647 // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
648 void VM_CL_getlight (void)
649 {
650         vec3_t ambientcolor, diffusecolor, diffusenormal;
651         vec_t *p;
652
653         VM_SAFEPARMCOUNT(1, VM_CL_getlight);
654
655         p = PRVM_G_VECTOR(OFS_PARM0);
656         VectorClear(ambientcolor);
657         VectorClear(diffusecolor);
658         VectorClear(diffusenormal);
659         if (cl.worldmodel && cl.worldmodel->brush.LightPoint)
660                 cl.worldmodel->brush.LightPoint(cl.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
661         VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
662 }
663
664
665 //============================================================================
666 //[515]: SCENE MANAGER builtins
667 extern qboolean CSQC_AddRenderEdict (prvm_edict_t *ed);//csprogs.c
668
669 matrix4x4_t csqc_listenermatrix;
670 qboolean csqc_usecsqclistener = false;//[515]: per-frame
671
672 static void CSQC_R_RecalcView (void)
673 {
674         extern matrix4x4_t viewmodelmatrix;
675         Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], 1);
676         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);
677 }
678
679 void CL_RelinkLightFlashes(void);
680 //#300 void() clearscene (EXT_CSQC)
681 void VM_R_ClearScene (void)
682 {
683         VM_SAFEPARMCOUNT(0, VM_R_ClearScene);
684         // clear renderable entity and light lists
685         r_refdef.numentities = 0;
686         r_refdef.numlights = 0;
687 }
688
689 //#301 void(float mask) addentities (EXT_CSQC)
690 extern void CSQC_Predraw (prvm_edict_t *ed);//csprogs.c
691 extern void CSQC_Think (prvm_edict_t *ed);//csprogs.c
692 void VM_R_AddEntities (void)
693 {
694         int                     i, drawmask;
695         prvm_edict_t *ed;
696         VM_SAFEPARMCOUNT(1, VM_R_AddEntities);
697         drawmask = (int)PRVM_G_FLOAT(OFS_PARM0);
698         CSQC_RelinkAllEntities(drawmask);
699         CL_RelinkLightFlashes();
700
701         prog->globals.client->time = cl.time;
702         for(i=1;i<prog->num_edicts;i++)
703         {
704                 ed = &prog->edicts[i];
705                 if(ed->priv.required->free)
706                         continue;
707                 VectorAdd(ed->fields.client->origin, ed->fields.client->mins, ed->fields.client->absmin);
708                 VectorAdd(ed->fields.client->origin, ed->fields.client->maxs, ed->fields.client->absmax);
709                 CSQC_Think(ed);
710                 if(ed->priv.required->free)
711                         continue;
712                 // note that for RF_USEAXIS entities, Predraw sets v_forward/v_right/v_up globals that are read by CSQC_AddRenderEdict
713                 CSQC_Predraw(ed);
714                 if(ed->priv.required->free)
715                         continue;
716                 if(!((int)ed->fields.client->drawmask & drawmask))
717                         continue;
718                 CSQC_AddRenderEdict(ed);
719         }
720 }
721
722 //#302 void(entity ent) addentity (EXT_CSQC)
723 void VM_R_AddEntity (void)
724 {
725         VM_SAFEPARMCOUNT(1, VM_R_AddEntity);
726         CSQC_AddRenderEdict(PRVM_G_EDICT(OFS_PARM0));
727 }
728
729 //#303 float(float property, ...) setproperty (EXT_CSQC)
730 void VM_R_SetView (void)
731 {
732         int             c;
733         float   *f;
734         float   k;
735
736         if(prog->argc < 2)
737                 VM_SAFEPARMCOUNT(2, VM_R_SetView);
738
739         c = (int)PRVM_G_FLOAT(OFS_PARM0);
740         f = PRVM_G_VECTOR(OFS_PARM1);
741         k = PRVM_G_FLOAT(OFS_PARM1);
742
743         switch(c)
744         {
745         case VF_MIN:                    r_view.x = (int)f[0];
746                                                         r_view.y = (int)f[1];
747                                                         break;
748         case VF_MIN_X:                  r_view.x = (int)k;
749                                                         break;
750         case VF_MIN_Y:                  r_view.y = (int)k;
751                                                         break;
752         case VF_SIZE:                   r_view.width = (int)f[0];
753                                                         r_view.height = (int)f[1];
754                                                         break;
755         case VF_SIZE_Y:                 r_view.width = (int)k;
756                                                         break;
757         case VF_SIZE_X:                 r_view.height = (int)k;
758                                                         break;
759         case VF_VIEWPORT:               r_view.x = (int)f[0];
760                                                         r_view.y = (int)f[1];
761                                                         r_view.z = 0;
762                                                         // TODO: make sure that view_z and view_depth are set properly even if csqc does not set them!
763                                                         f = PRVM_G_VECTOR(OFS_PARM2);
764                                                         r_view.width = (int)f[0];
765                                                         r_view.height = (int)f[1];
766                                                         r_view.depth = 1;
767                                                         break;
768         case VF_FOV:                    //r_refdef.fov_x = f[0]; // FIXME!
769                                                         //r_refdef.fov_y = f[1]; // FIXME!
770                                                         break;
771         case VF_FOVX:                   //r_refdef.fov_x = k; // FIXME!
772                                                         break;
773         case VF_FOVY:                   //r_refdef.fov_y = k; // FIXME!
774                                                         break;
775         case VF_ORIGIN:                 VectorCopy(f, csqc_origin);
776                                                         CSQC_R_RecalcView();
777                                                         break;
778         case VF_ORIGIN_X:               csqc_origin[0] = k;
779                                                         CSQC_R_RecalcView();
780                                                         break;
781         case VF_ORIGIN_Y:               csqc_origin[1] = k;
782                                                         CSQC_R_RecalcView();
783                                                         break;
784         case VF_ORIGIN_Z:               csqc_origin[2] = k;
785                                                         CSQC_R_RecalcView();
786                                                         break;
787         case VF_ANGLES:                 VectorCopy(f, csqc_angles);
788                                                         CSQC_R_RecalcView();
789                                                         break;
790         case VF_ANGLES_X:               csqc_angles[0] = k;
791                                                         CSQC_R_RecalcView();
792                                                         break;
793         case VF_ANGLES_Y:               csqc_angles[1] = k;
794                                                         CSQC_R_RecalcView();
795                                                         break;
796         case VF_ANGLES_Z:               csqc_angles[2] = k;
797                                                         CSQC_R_RecalcView();
798                                                         break;
799         case VF_DRAWWORLD:              cl.csqc_vidvars.drawworld = k;
800                                                         break;
801         case VF_DRAWENGINESBAR: cl.csqc_vidvars.drawenginesbar = k;
802                                                         break;
803         case VF_DRAWCROSSHAIR:  cl.csqc_vidvars.drawcrosshair = k;
804                                                         break;
805
806         case VF_CL_VIEWANGLES:  VectorCopy(f, cl.viewangles);
807                                                         break;
808         case VF_CL_VIEWANGLES_X:cl.viewangles[0] = k;
809                                                         break;
810         case VF_CL_VIEWANGLES_Y:cl.viewangles[1] = k;
811                                                         break;
812         case VF_CL_VIEWANGLES_Z:cl.viewangles[2] = k;
813                                                         break;
814
815         default:                                PRVM_G_FLOAT(OFS_RETURN) = 0;
816                                                         VM_Warning("VM_R_SetView : unknown parm %i\n", c);
817                                                         return;
818         }
819         PRVM_G_FLOAT(OFS_RETURN) = 1;
820 }
821
822 extern void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit);
823 //#304 void() renderscene (EXT_CSQC)
824 void VM_R_RenderScene (void) //#134
825 {
826         int i;
827         VM_SAFEPARMCOUNT(0, VM_R_RenderScene);
828         // we need to update any RENDER_VIEWMODEL entities at this point because
829         // csqc supplies its own view matrix
830         for (i = 1;i < cl.num_entities;i++)
831         {
832                 if (cl.entities_active[i])
833                 {
834                         entity_t *ent = cl.entities + i;
835                         if ((ent->render.flags & RENDER_VIEWMODEL) || ent->state_current.tagentity)
836                                 CL_UpdateNetworkEntity(ent, 32);
837                 }
838         }
839         // and of course the engine viewmodel needs updating as well
840         CL_UpdateNetworkEntity(&cl.viewent, 32);
841         // now draw stuff!
842         R_RenderView();
843 }
844
845 //#305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
846 void VM_R_AddDynamicLight (void)
847 {
848         float           *pos, *col;
849         matrix4x4_t     matrix;
850         VM_SAFEPARMCOUNT(3, VM_R_AddDynamicLight);
851
852         // if we've run out of dlights, just return
853         if (r_refdef.numlights >= MAX_DLIGHTS)
854                 return;
855
856         pos = PRVM_G_VECTOR(OFS_PARM0);
857         col = PRVM_G_VECTOR(OFS_PARM2);
858         Matrix4x4_CreateFromQuakeEntity(&matrix, pos[0], pos[1], pos[2], 0, 0, 0, PRVM_G_FLOAT(OFS_PARM1));
859         R_RTLight_Update(&r_refdef.lights[r_refdef.numlights++], false, &matrix, col, -1, NULL, true, 1, 0.25, 0, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
860 }
861
862 //============================================================================
863
864 //#310 vector (vector v) cs_unproject (EXT_CSQC)
865 void VM_CL_unproject (void)
866 {
867         float   *f;
868         vec3_t  temp;
869
870         VM_SAFEPARMCOUNT(1, VM_CL_unproject);
871         f = PRVM_G_VECTOR(OFS_PARM0);
872         VectorSet(temp, f[2], f[0] * f[2] * -r_view.frustum_x * 2.0 / r_view.width, f[1] * f[2] * -r_view.frustum_y * 2.0 / r_view.height);
873         Matrix4x4_Transform(&r_view.matrix, temp, PRVM_G_VECTOR(OFS_RETURN));
874 }
875
876 //#311 vector (vector v) cs_project (EXT_CSQC)
877 void VM_CL_project (void)
878 {
879         float   *f;
880         vec3_t  v;
881         matrix4x4_t m;
882
883         VM_SAFEPARMCOUNT(1, VM_CL_project);
884         f = PRVM_G_VECTOR(OFS_PARM0);
885         Matrix4x4_Invert_Simple(&m, &r_view.matrix);
886         Matrix4x4_Transform(&m, f, v);
887         VectorSet(PRVM_G_VECTOR(OFS_RETURN), v[1]/v[0]/-r_view.frustum_x*0.5*r_view.width, v[2]/v[0]/-r_view.frustum_y*r_view.height*0.5, v[0]);
888 }
889
890 //#330 float(float stnum) getstatf (EXT_CSQC)
891 void VM_CL_getstatf (void)
892 {
893         int i;
894         union
895         {
896                 float f;
897                 int l;
898         }dat;
899         VM_SAFEPARMCOUNT(1, VM_CL_getstatf);
900         i = (int)PRVM_G_FLOAT(OFS_PARM0);
901         if(i < 0 || i >= MAX_CL_STATS)
902         {
903                 VM_Warning("VM_CL_getstatf: index>=MAX_CL_STATS or index<0\n");
904                 return;
905         }
906         dat.l = cl.stats[i];
907         PRVM_G_FLOAT(OFS_RETURN) =  dat.f;
908 }
909
910 //#331 float(float stnum) getstati (EXT_CSQC)
911 void VM_CL_getstati (void)
912 {
913         int i, index;
914         VM_SAFEPARMCOUNT(1, VM_CL_getstati);
915         index = (int)PRVM_G_FLOAT(OFS_PARM0);
916
917         if(index < 0 || index >= MAX_CL_STATS)
918         {
919                 VM_Warning("VM_CL_getstati: index>=MAX_CL_STATS or index<0\n");
920                 return;
921         }
922         i = cl.stats[index];
923         PRVM_G_FLOAT(OFS_RETURN) = i;
924 }
925
926 //#332 string(float firststnum) getstats (EXT_CSQC)
927 void VM_CL_getstats (void)
928 {
929         int i;
930         char t[17];
931         VM_SAFEPARMCOUNT(1, VM_CL_getstats);
932         i = (int)PRVM_G_FLOAT(OFS_PARM0);
933         if(i < 0 || i > MAX_CL_STATS-4)
934         {
935                 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
936                 VM_Warning("VM_CL_getstats: index>MAX_CL_STATS-4 or index<0\n");
937                 return;
938         }
939         strlcpy(t, (char*)&cl.stats[i], sizeof(t));
940         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
941 }
942
943 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
944 void VM_CL_setmodelindex (void)
945 {
946         int                             i;
947         prvm_edict_t    *t;
948         struct model_s  *model;
949
950         VM_SAFEPARMCOUNT(2, VM_CL_setmodelindex);
951
952         t = PRVM_G_EDICT(OFS_PARM0);
953
954         i = (int)PRVM_G_FLOAT(OFS_PARM1);
955
956         t->fields.client->model = 0;
957         t->fields.client->modelindex = 0;
958
959         if (!i)
960                 return;
961
962         model = CSQC_GetModelByIndex(i);
963         if (!model)
964         {
965                 VM_Warning("VM_CL_setmodelindex: null model\n");
966                 return;
967         }
968         t->fields.client->model = PRVM_SetEngineString(model->name);
969         t->fields.client->modelindex = i;
970 }
971
972 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
973 void VM_CL_modelnameforindex (void)
974 {
975         model_t *model;
976
977         VM_SAFEPARMCOUNT(1, VM_CL_modelnameforindex);
978
979         PRVM_G_INT(OFS_RETURN) = OFS_NULL;
980         model = CSQC_GetModelByIndex((int)PRVM_G_FLOAT(OFS_PARM0));
981         PRVM_G_INT(OFS_RETURN) = model ? PRVM_SetEngineString(model->name) : 0;
982 }
983
984 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
985 void VM_CL_particleeffectnum (void)
986 {
987         int                     i;
988         VM_SAFEPARMCOUNT(1, VM_CL_particleeffectnum);
989         i = CL_ParticleEffectIndexForName(PRVM_G_STRING(OFS_PARM0));
990         if (i == 0)
991                 i = -1;
992         PRVM_G_FLOAT(OFS_RETURN) = i;
993 }
994
995 // #336 void(entity ent, float effectnum, vector start, vector end[, float color]) trailparticles (EXT_CSQC)
996 void VM_CL_trailparticles (void)
997 {
998         int                             i;
999         float                   *start, *end;
1000         prvm_edict_t    *t;
1001         VM_SAFEPARMCOUNT(4, VM_CL_trailparticles);
1002
1003         t = PRVM_G_EDICT(OFS_PARM0);
1004         i               = (int)PRVM_G_FLOAT(OFS_PARM1);
1005         start   = PRVM_G_VECTOR(OFS_PARM2);
1006         end             = PRVM_G_VECTOR(OFS_PARM3);
1007
1008         CL_ParticleEffect(i, VectorDistance(start, end), start, end, t->fields.client->velocity, t->fields.client->velocity, NULL, (int)PRVM_G_FLOAT(OFS_PARM4));
1009 }
1010
1011 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
1012 void VM_CL_pointparticles (void)
1013 {
1014         int                     i, n;
1015         float           *f, *v;
1016         VM_SAFEPARMCOUNT(4, VM_CL_pointparticles);
1017         i = (int)PRVM_G_FLOAT(OFS_PARM0);
1018         f = PRVM_G_VECTOR(OFS_PARM1);
1019         v = PRVM_G_VECTOR(OFS_PARM2);
1020         n = (int)PRVM_G_FLOAT(OFS_PARM3);
1021         CL_ParticleEffect(i, n, f, f, v, v, NULL, 0);
1022 }
1023
1024 //#338 void(string s) cprint (EXT_CSQC)
1025 void VM_CL_centerprint (void)
1026 {
1027         char s[VM_STRINGTEMP_LENGTH];
1028         if(prog->argc < 1)
1029                 VM_SAFEPARMCOUNT(1, VM_CL_centerprint);
1030         VM_VarString(0, s, sizeof(s));
1031         SCR_CenterPrint(s);
1032 }
1033
1034 //#342 string(float keynum) getkeybind (EXT_CSQC)
1035 void VM_CL_getkeybind (void)
1036 {
1037         VM_SAFEPARMCOUNT(1, VM_CL_getkeybind);
1038         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(Key_GetBind((int)PRVM_G_FLOAT(OFS_PARM0)));
1039 }
1040
1041 //#343 void(float usecursor) setcursormode (EXT_CSQC)
1042 void VM_CL_setcursormode (void)
1043 {
1044         VM_SAFEPARMCOUNT(1, VM_CL_setcursormode);
1045         cl.csqc_wantsmousemove = PRVM_G_FLOAT(OFS_PARM0);
1046         cl_ignoremousemove = true;
1047 }
1048
1049 //#345 float(float framenum) getinputstate (EXT_CSQC)
1050 void VM_CL_getinputstate (void)
1051 {
1052         int i, frame;
1053         VM_SAFEPARMCOUNT(1, VM_CL_getinputstate);
1054         frame = (int)PRVM_G_FLOAT(OFS_PARM0);
1055         for (i = 0;i < cl.movement_numqueue;i++)
1056                 if (cl.movement_queue[i].sequence == frame)
1057                 {
1058                         VectorCopy(cl.movement_queue[i].viewangles, prog->globals.client->input_angles);
1059                         //prog->globals.client->input_buttons = cl.movement_queue[i].//FIXME
1060                         VectorCopy(cl.movement_queue[i].move, prog->globals.client->input_movevalues);
1061                         prog->globals.client->input_timelength = cl.movement_queue[i].frametime;
1062                         if(cl.movement_queue[i].crouch)
1063                         {
1064                                 VectorCopy(cl.playercrouchmins, prog->globals.client->pmove_mins);
1065                                 VectorCopy(cl.playercrouchmaxs, prog->globals.client->pmove_maxs);
1066                         }
1067                         else
1068                         {
1069                                 VectorCopy(cl.playerstandmins, prog->globals.client->pmove_mins);
1070                                 VectorCopy(cl.playerstandmaxs, prog->globals.client->pmove_maxs);
1071                         }
1072                 }
1073 }
1074
1075 //#346 void(float sens) setsensitivityscaler (EXT_CSQC)
1076 void VM_CL_setsensitivityscale (void)
1077 {
1078         VM_SAFEPARMCOUNT(1, VM_CL_setsensitivityscale);
1079         cl.sensitivityscale = PRVM_G_FLOAT(OFS_PARM0);
1080 }
1081
1082 //#347 void() runstandardplayerphysics (EXT_CSQC)
1083 void VM_CL_runplayerphysics (void)
1084 {
1085 }
1086
1087 //#348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
1088 void VM_CL_getplayerkey (void)
1089 {
1090         int                     i;
1091         char            t[128];
1092         const char      *c;
1093
1094         VM_SAFEPARMCOUNT(2, VM_CL_getplayerkey);
1095
1096         i = (int)PRVM_G_FLOAT(OFS_PARM0);
1097         c = PRVM_G_STRING(OFS_PARM1);
1098         PRVM_G_INT(OFS_RETURN) = OFS_NULL;
1099         Sbar_SortFrags();
1100
1101         i = Sbar_GetPlayer(i);
1102         if(i < 0)
1103                 return;
1104
1105         t[0] = 0;
1106
1107         if(!strcasecmp(c, "name"))
1108                 strlcpy(t, cl.scores[i].name, sizeof(t));
1109         else
1110                 if(!strcasecmp(c, "frags"))
1111                         sprintf(t, "%i", cl.scores[i].frags);
1112         else
1113                 if(!strcasecmp(c, "ping"))
1114                         sprintf(t, "%i", cl.scores[i].qw_ping);
1115         else
1116                 if(!strcasecmp(c, "entertime"))
1117                         sprintf(t, "%f", cl.scores[i].qw_entertime);
1118         else
1119                 if(!strcasecmp(c, "colors"))
1120                         sprintf(t, "%i", cl.scores[i].colors);
1121         else
1122                 if(!strcasecmp(c, "topcolor"))
1123                         sprintf(t, "%i", cl.scores[i].colors & 0xf0);
1124         else
1125                 if(!strcasecmp(c, "bottomcolor"))
1126                         sprintf(t, "%i", (cl.scores[i].colors &15)<<4);
1127         else
1128                 if(!strcasecmp(c, "viewentity"))
1129                         sprintf(t, "%i", i+1);
1130         if(!t[0])
1131                 return;
1132         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
1133 }
1134
1135 //#349 float() isdemo (EXT_CSQC)
1136 void VM_CL_isdemo (void)
1137 {
1138         PRVM_G_FLOAT(OFS_RETURN) = cls.demoplayback;
1139 }
1140
1141 //#351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
1142 void VM_CL_setlistener (void)
1143 {
1144         VM_SAFEPARMCOUNT(4, VM_CL_setlistener);
1145         Matrix4x4_FromVectors(&csqc_listenermatrix, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), PRVM_G_VECTOR(OFS_PARM3), PRVM_G_VECTOR(OFS_PARM0));
1146         csqc_usecsqclistener = true;    //use csqc listener at this frame
1147 }
1148
1149 //#352 void(string cmdname) registercommand (EXT_CSQC)
1150 void VM_CL_registercmd (void)
1151 {
1152         char *t;
1153         VM_SAFEPARMCOUNT(1, VM_CL_registercmd);
1154         if(!Cmd_Exists(PRVM_G_STRING(OFS_PARM0)))
1155         {
1156                 size_t alloclen;
1157
1158                 alloclen = strlen(PRVM_G_STRING(OFS_PARM0)) + 1;
1159                 t = (char *)Z_Malloc(alloclen);
1160                 memcpy(t, PRVM_G_STRING(OFS_PARM0), alloclen);
1161                 Cmd_AddCommand(t, NULL, "console command created by QuakeC");
1162         }
1163         else
1164                 Cmd_AddCommand(PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC");
1165
1166 }
1167
1168 //#354 float() playernum (EXT_CSQC)
1169 void VM_CL_playernum (void)
1170 {
1171         int i, k;
1172
1173         VM_SAFEPARMCOUNT(0, VM_CL_playernum);
1174
1175         for(i=k=0 ; i<cl.maxclients ; i++)
1176                 if(cl.scores[i].name[0])
1177                         k++;
1178         PRVM_G_FLOAT(OFS_RETURN) = k;
1179 }
1180
1181 //#355 float() cl_onground (EXT_CSQC)
1182 void VM_CL_onground (void)
1183 {
1184         PRVM_G_FLOAT(OFS_RETURN) = cl.onground;
1185 }
1186
1187 //#360 float() readbyte (EXT_CSQC)
1188 void VM_CL_ReadByte (void)
1189 {
1190         PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadByte();
1191 }
1192
1193 //#361 float() readchar (EXT_CSQC)
1194 void VM_CL_ReadChar (void)
1195 {
1196         PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadChar();
1197 }
1198
1199 //#362 float() readshort (EXT_CSQC)
1200 void VM_CL_ReadShort (void)
1201 {
1202         PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadShort();
1203 }
1204
1205 //#363 float() readlong (EXT_CSQC)
1206 void VM_CL_ReadLong (void)
1207 {
1208         PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadLong();
1209 }
1210
1211 //#364 float() readcoord (EXT_CSQC)
1212 void VM_CL_ReadCoord (void)
1213 {
1214         PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadCoord(cls.protocol);
1215 }
1216
1217 //#365 float() readangle (EXT_CSQC)
1218 void VM_CL_ReadAngle (void)
1219 {
1220         PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadAngle(cls.protocol);
1221 }
1222
1223 //#366 string() readstring (EXT_CSQC)
1224 void VM_CL_ReadString (void)
1225 {
1226         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(MSG_ReadString());
1227 }
1228
1229 //#367 float() readfloat (EXT_CSQC)
1230 void VM_CL_ReadFloat (void)
1231 {
1232         PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadFloat();
1233 }
1234
1235 //=================================================================//
1236
1237 // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
1238 void VM_CL_effect (void)
1239 {
1240         VM_SAFEPARMCOUNT(5, VM_CL_effect);
1241         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));
1242 }
1243
1244 // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
1245 void VM_CL_te_blood (void)
1246 {
1247         float   *pos;
1248         vec3_t  pos2;
1249         VM_SAFEPARMCOUNT(3, VM_CL_te_blood);
1250         if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1251                 return;
1252         pos = PRVM_G_VECTOR(OFS_PARM0);
1253         CL_FindNonSolidLocation(pos, pos2, 4);
1254         CL_ParticleEffect(EFFECT_TE_BLOOD, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM1), NULL, 0);
1255 }
1256
1257 // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
1258 void VM_CL_te_bloodshower (void)
1259 {
1260         vec_t speed;
1261         vec3_t vel1, vel2;
1262         VM_SAFEPARMCOUNT(4, VM_CL_te_bloodshower);
1263         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1264                 return;
1265         speed = PRVM_G_FLOAT(OFS_PARM2);
1266         vel1[0] = -speed;
1267         vel1[1] = -speed;
1268         vel1[2] = -speed;
1269         vel2[0] = speed;
1270         vel2[1] = speed;
1271         vel2[2] = speed;
1272         CL_ParticleEffect(EFFECT_TE_BLOOD, PRVM_G_FLOAT(OFS_PARM3), PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), vel1, vel2, NULL, 0);
1273 }
1274
1275 // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
1276 void VM_CL_te_explosionrgb (void)
1277 {
1278         float           *pos;
1279         vec3_t          pos2;
1280         matrix4x4_t     tempmatrix;
1281         VM_SAFEPARMCOUNT(2, VM_CL_te_explosionrgb);
1282         pos = PRVM_G_VECTOR(OFS_PARM0);
1283         CL_FindNonSolidLocation(pos, pos2, 10);
1284         CL_ParticleExplosion(pos2);
1285         Matrix4x4_CreateTranslate(&tempmatrix, pos2[0], pos2[1], pos2[2]);
1286         CL_AllocLightFlash(NULL, &tempmatrix, 350, PRVM_G_VECTOR(OFS_PARM1)[0], PRVM_G_VECTOR(OFS_PARM1)[1], PRVM_G_VECTOR(OFS_PARM1)[2], 700, 0.5, 0, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1287 }
1288
1289 // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE)
1290 void VM_CL_te_particlecube (void)
1291 {
1292         VM_SAFEPARMCOUNT(7, VM_CL_te_particlecube);
1293         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));
1294 }
1295
1296 // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
1297 void VM_CL_te_particlerain (void)
1298 {
1299         VM_SAFEPARMCOUNT(5, VM_CL_te_particlerain);
1300         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);
1301 }
1302
1303 // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
1304 void VM_CL_te_particlesnow (void)
1305 {
1306         VM_SAFEPARMCOUNT(5, VM_CL_te_particlesnow);
1307         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);
1308 }
1309
1310 // #411 void(vector org, vector vel, float howmany) te_spark
1311 void VM_CL_te_spark (void)
1312 {
1313         float           *pos;
1314         vec3_t          pos2;
1315         VM_SAFEPARMCOUNT(3, VM_CL_te_spark);
1316
1317         pos = PRVM_G_VECTOR(OFS_PARM0);
1318         CL_FindNonSolidLocation(pos, pos2, 4);
1319         CL_ParticleEffect(EFFECT_TE_SPARK, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM1), NULL, 0);
1320 }
1321
1322 // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
1323 void VM_CL_te_gunshotquad (void)
1324 {
1325         float           *pos;
1326         vec3_t          pos2;
1327         VM_SAFEPARMCOUNT(1, VM_CL_te_gunshotquad);
1328
1329         pos = PRVM_G_VECTOR(OFS_PARM0);
1330         CL_FindNonSolidLocation(pos, pos2, 4);
1331         CL_ParticleEffect(EFFECT_TE_GUNSHOTQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1332 }
1333
1334 // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
1335 void VM_CL_te_spikequad (void)
1336 {
1337         float           *pos;
1338         vec3_t          pos2;
1339         int                     rnd;
1340         VM_SAFEPARMCOUNT(1, VM_CL_te_spikequad);
1341
1342         pos = PRVM_G_VECTOR(OFS_PARM0);
1343         CL_FindNonSolidLocation(pos, pos2, 4);
1344         CL_ParticleEffect(EFFECT_TE_SPIKEQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1345         if (rand() % 5)                 S_StartSound(-1, 0, cl.sfx_tink1, pos2, 1, 1);
1346         else
1347         {
1348                 rnd = rand() & 3;
1349                 if (rnd == 1)           S_StartSound(-1, 0, cl.sfx_ric1, pos2, 1, 1);
1350                 else if (rnd == 2)      S_StartSound(-1, 0, cl.sfx_ric2, pos2, 1, 1);
1351                 else                            S_StartSound(-1, 0, cl.sfx_ric3, pos2, 1, 1);
1352         }
1353 }
1354
1355 // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
1356 void VM_CL_te_superspikequad (void)
1357 {
1358         float           *pos;
1359         vec3_t          pos2;
1360         int                     rnd;
1361         VM_SAFEPARMCOUNT(1, VM_CL_te_superspikequad);
1362
1363         pos = PRVM_G_VECTOR(OFS_PARM0);
1364         CL_FindNonSolidLocation(pos, pos2, 4);
1365         CL_ParticleEffect(EFFECT_TE_SUPERSPIKEQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1366         if (rand() % 5)                 S_StartSound(-1, 0, cl.sfx_tink1, pos, 1, 1);
1367         else
1368         {
1369                 rnd = rand() & 3;
1370                 if (rnd == 1)           S_StartSound(-1, 0, cl.sfx_ric1, pos2, 1, 1);
1371                 else if (rnd == 2)      S_StartSound(-1, 0, cl.sfx_ric2, pos2, 1, 1);
1372                 else                            S_StartSound(-1, 0, cl.sfx_ric3, pos2, 1, 1);
1373         }
1374 }
1375
1376 // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
1377 void VM_CL_te_explosionquad (void)
1378 {
1379         float           *pos;
1380         vec3_t          pos2;
1381         VM_SAFEPARMCOUNT(1, VM_CL_te_explosionquad);
1382
1383         pos = PRVM_G_VECTOR(OFS_PARM0);
1384         CL_FindNonSolidLocation(pos, pos2, 10);
1385         CL_ParticleEffect(EFFECT_TE_EXPLOSIONQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1386         S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1);
1387 }
1388
1389 // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
1390 void VM_CL_te_smallflash (void)
1391 {
1392         float           *pos;
1393         vec3_t          pos2;
1394         VM_SAFEPARMCOUNT(1, VM_CL_te_smallflash);
1395
1396         pos = PRVM_G_VECTOR(OFS_PARM0);
1397         CL_FindNonSolidLocation(pos, pos2, 10);
1398         CL_ParticleEffect(EFFECT_TE_SMALLFLASH, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1399 }
1400
1401 // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
1402 void VM_CL_te_customflash (void)
1403 {
1404         float           *pos;
1405         vec3_t          pos2;
1406         matrix4x4_t     tempmatrix;
1407         VM_SAFEPARMCOUNT(4, VM_CL_te_customflash);
1408
1409         pos = PRVM_G_VECTOR(OFS_PARM0);
1410         CL_FindNonSolidLocation(pos, pos2, 4);
1411         Matrix4x4_CreateTranslate(&tempmatrix, pos2[0], pos2[1], pos2[2]);
1412         CL_AllocLightFlash(NULL, &tempmatrix, PRVM_G_FLOAT(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM3)[0], PRVM_G_VECTOR(OFS_PARM3)[1], PRVM_G_VECTOR(OFS_PARM3)[2], PRVM_G_FLOAT(OFS_PARM1) / PRVM_G_FLOAT(OFS_PARM2), PRVM_G_FLOAT(OFS_PARM2), 0, -1, true, 1, 0.25, 1, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1413 }
1414
1415 // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
1416 void VM_CL_te_gunshot (void)
1417 {
1418         float           *pos;
1419         vec3_t          pos2;
1420         VM_SAFEPARMCOUNT(1, VM_CL_te_gunshot);
1421
1422         pos = PRVM_G_VECTOR(OFS_PARM0);
1423         CL_FindNonSolidLocation(pos, pos2, 4);
1424         CL_ParticleEffect(EFFECT_TE_GUNSHOT, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1425 }
1426
1427 // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
1428 void VM_CL_te_spike (void)
1429 {
1430         float           *pos;
1431         vec3_t          pos2;
1432         int                     rnd;
1433         VM_SAFEPARMCOUNT(1, VM_CL_te_spike);
1434
1435         pos = PRVM_G_VECTOR(OFS_PARM0);
1436         CL_FindNonSolidLocation(pos, pos2, 4);
1437         CL_ParticleEffect(EFFECT_TE_SPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1438         if (rand() % 5)                 S_StartSound(-1, 0, cl.sfx_tink1, pos2, 1, 1);
1439         else
1440         {
1441                 rnd = rand() & 3;
1442                 if (rnd == 1)           S_StartSound(-1, 0, cl.sfx_ric1, pos2, 1, 1);
1443                 else if (rnd == 2)      S_StartSound(-1, 0, cl.sfx_ric2, pos2, 1, 1);
1444                 else                            S_StartSound(-1, 0, cl.sfx_ric3, pos2, 1, 1);
1445         }
1446 }
1447
1448 // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
1449 void VM_CL_te_superspike (void)
1450 {
1451         float           *pos;
1452         vec3_t          pos2;
1453         int                     rnd;
1454         VM_SAFEPARMCOUNT(1, VM_CL_te_superspike);
1455
1456         pos = PRVM_G_VECTOR(OFS_PARM0);
1457         CL_FindNonSolidLocation(pos, pos2, 4);
1458         CL_ParticleEffect(EFFECT_TE_SUPERSPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1459         if (rand() % 5)                 S_StartSound(-1, 0, cl.sfx_tink1, pos2, 1, 1);
1460         else
1461         {
1462                 rnd = rand() & 3;
1463                 if (rnd == 1)           S_StartSound(-1, 0, cl.sfx_ric1, pos2, 1, 1);
1464                 else if (rnd == 2)      S_StartSound(-1, 0, cl.sfx_ric2, pos2, 1, 1);
1465                 else                            S_StartSound(-1, 0, cl.sfx_ric3, pos2, 1, 1);
1466         }
1467 }
1468
1469 // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
1470 void VM_CL_te_explosion (void)
1471 {
1472         float           *pos;
1473         vec3_t          pos2;
1474         VM_SAFEPARMCOUNT(1, VM_CL_te_explosion);
1475
1476         pos = PRVM_G_VECTOR(OFS_PARM0);
1477         CL_FindNonSolidLocation(pos, pos2, 10);
1478         CL_ParticleEffect(EFFECT_TE_EXPLOSION, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1479         S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1);
1480 }
1481
1482 // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
1483 void VM_CL_te_tarexplosion (void)
1484 {
1485         float           *pos;
1486         vec3_t          pos2;
1487         VM_SAFEPARMCOUNT(1, VM_CL_te_tarexplosion);
1488
1489         pos = PRVM_G_VECTOR(OFS_PARM0);
1490         CL_FindNonSolidLocation(pos, pos2, 10);
1491         CL_ParticleEffect(EFFECT_TE_TAREXPLOSION, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1492         S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1);
1493 }
1494
1495 // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
1496 void VM_CL_te_wizspike (void)
1497 {
1498         float           *pos;
1499         vec3_t          pos2;
1500         VM_SAFEPARMCOUNT(1, VM_CL_te_wizspike);
1501
1502         pos = PRVM_G_VECTOR(OFS_PARM0);
1503         CL_FindNonSolidLocation(pos, pos2, 4);
1504         CL_ParticleEffect(EFFECT_TE_WIZSPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1505         S_StartSound(-1, 0, cl.sfx_wizhit, pos2, 1, 1);
1506 }
1507
1508 // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
1509 void VM_CL_te_knightspike (void)
1510 {
1511         float           *pos;
1512         vec3_t          pos2;
1513         VM_SAFEPARMCOUNT(1, VM_CL_te_knightspike);
1514
1515         pos = PRVM_G_VECTOR(OFS_PARM0);
1516         CL_FindNonSolidLocation(pos, pos2, 4);
1517         CL_ParticleEffect(EFFECT_TE_KNIGHTSPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1518         S_StartSound(-1, 0, cl.sfx_knighthit, pos2, 1, 1);
1519 }
1520
1521 // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
1522 void VM_CL_te_lavasplash (void)
1523 {
1524         VM_SAFEPARMCOUNT(1, VM_CL_te_lavasplash);
1525         CL_ParticleEffect(EFFECT_TE_LAVASPLASH, 1, PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM0), vec3_origin, vec3_origin, NULL, 0);
1526 }
1527
1528 // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
1529 void VM_CL_te_teleport (void)
1530 {
1531         VM_SAFEPARMCOUNT(1, VM_CL_te_teleport);
1532         CL_ParticleEffect(EFFECT_TE_TELEPORT, 1, PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM0), vec3_origin, vec3_origin, NULL, 0);
1533 }
1534
1535 // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
1536 void VM_CL_te_explosion2 (void)
1537 {
1538         float           *pos;
1539         vec3_t          pos2, color;
1540         matrix4x4_t     tempmatrix;
1541         int                     colorStart, colorLength;
1542         unsigned char           *tempcolor;
1543         VM_SAFEPARMCOUNT(3, VM_CL_te_explosion2);
1544
1545         pos = PRVM_G_VECTOR(OFS_PARM0);
1546         colorStart = (int)PRVM_G_FLOAT(OFS_PARM1);
1547         colorLength = (int)PRVM_G_FLOAT(OFS_PARM2);
1548         CL_FindNonSolidLocation(pos, pos2, 10);
1549         CL_ParticleExplosion2(pos2, colorStart, colorLength);
1550         tempcolor = (unsigned char *)&palette_complete[(rand()%colorLength) + colorStart];
1551         color[0] = tempcolor[0] * (2.0f / 255.0f);
1552         color[1] = tempcolor[1] * (2.0f / 255.0f);
1553         color[2] = tempcolor[2] * (2.0f / 255.0f);
1554         Matrix4x4_CreateTranslate(&tempmatrix, pos2[0], pos2[1], pos2[2]);
1555         CL_AllocLightFlash(NULL, &tempmatrix, 350, color[0], color[1], color[2], 700, 0.5, 0, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
1556         S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1);
1557 }
1558
1559
1560 // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
1561 void VM_CL_te_lightning1 (void)
1562 {
1563         VM_SAFEPARMCOUNT(3, VM_CL_te_lightning1);
1564         CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt, true);
1565 }
1566
1567 // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
1568 void VM_CL_te_lightning2 (void)
1569 {
1570         VM_SAFEPARMCOUNT(3, VM_CL_te_lightning2);
1571         CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt2, true);
1572 }
1573
1574 // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
1575 void VM_CL_te_lightning3 (void)
1576 {
1577         VM_SAFEPARMCOUNT(3, VM_CL_te_lightning3);
1578         CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt3, false);
1579 }
1580
1581 // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
1582 void VM_CL_te_beam (void)
1583 {
1584         VM_SAFEPARMCOUNT(3, VM_CL_te_beam);
1585         CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_beam, false);
1586 }
1587
1588 // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
1589 void VM_CL_te_plasmaburn (void)
1590 {
1591         float           *pos;
1592         vec3_t          pos2;
1593         VM_SAFEPARMCOUNT(1, VM_CL_te_plasmaburn);
1594
1595         pos = PRVM_G_VECTOR(OFS_PARM0);
1596         CL_FindNonSolidLocation(pos, pos2, 4);
1597         CL_ParticleEffect(EFFECT_TE_PLASMABURN, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
1598 }
1599
1600
1601 //====================================================================
1602 //DP_QC_GETSURFACE
1603
1604 extern void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out);
1605
1606 static msurface_t *cl_getsurface(model_t *model, int surfacenum)
1607 {
1608         if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
1609                 return NULL;
1610         return model->data_surfaces + surfacenum + model->firstmodelsurface;
1611 }
1612
1613 // #434 float(entity e, float s) getsurfacenumpoints
1614 void VM_CL_getsurfacenumpoints(void)
1615 {
1616         model_t *model = CSQC_GetModelFromEntity(PRVM_G_EDICT(OFS_PARM0));
1617         msurface_t *surface;
1618         // return 0 if no such surface
1619         if (!model || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
1620         {
1621                 PRVM_G_FLOAT(OFS_RETURN) = 0;
1622                 return;
1623         }
1624
1625         // note: this (incorrectly) assumes it is a simple polygon
1626         PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
1627 }
1628
1629 // #435 vector(entity e, float s, float n) getsurfacepoint
1630 void VM_CL_getsurfacepoint(void)
1631 {
1632         prvm_edict_t *ed;
1633         model_t *model;
1634         msurface_t *surface;
1635         int pointnum;
1636         VectorClear(PRVM_G_VECTOR(OFS_RETURN));
1637         ed = PRVM_G_EDICT(OFS_PARM0);
1638         if (!(model = CSQC_GetModelFromEntity(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
1639                 return;
1640         // note: this (incorrectly) assumes it is a simple polygon
1641         pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
1642         if (pointnum < 0 || pointnum >= surface->num_vertices)
1643                 return;
1644         // FIXME: implement rotation/scaling
1645         VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.client->origin, PRVM_G_VECTOR(OFS_RETURN));
1646 }
1647
1648 // #436 vector(entity e, float s) getsurfacenormal
1649 void VM_CL_getsurfacenormal(void)
1650 {
1651         model_t *model;
1652         msurface_t *surface;
1653         vec3_t normal;
1654         VectorClear(PRVM_G_VECTOR(OFS_RETURN));
1655         if (!(model = CSQC_GetModelFromEntity(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
1656                 return;
1657         // FIXME: implement rotation/scaling
1658         // note: this (incorrectly) assumes it is a simple polygon
1659         // note: this only returns the first triangle, so it doesn't work very
1660         // well for curved surfaces or arbitrary meshes
1661         TriangleNormal((model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex), (model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex) + 3, (model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex) + 6, normal);
1662         VectorNormalize(normal);
1663         VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
1664 }
1665
1666 // #437 string(entity e, float s) getsurfacetexture
1667 void VM_CL_getsurfacetexture(void)
1668 {
1669         model_t *model;
1670         msurface_t *surface;
1671         PRVM_G_INT(OFS_RETURN) = OFS_NULL;
1672         if (!(model = CSQC_GetModelFromEntity(PRVM_G_EDICT(OFS_PARM0))) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
1673                 return;
1674         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
1675 }
1676
1677 // #438 float(entity e, vector p) getsurfacenearpoint
1678 void VM_CL_getsurfacenearpoint(void)
1679 {
1680         int surfacenum, best;
1681         vec3_t clipped, p;
1682         vec_t dist, bestdist;
1683         prvm_edict_t *ed;
1684         model_t *model = NULL;
1685         msurface_t *surface;
1686         vec_t *point;
1687         PRVM_G_FLOAT(OFS_RETURN) = -1;
1688         ed = PRVM_G_EDICT(OFS_PARM0);
1689         if(!(model = CSQC_GetModelFromEntity(ed)) || !model->num_surfaces)
1690                 return;
1691
1692         // FIXME: implement rotation/scaling
1693         point = PRVM_G_VECTOR(OFS_PARM1);
1694         VectorSubtract(point, ed->fields.client->origin, p);
1695         best = -1;
1696         bestdist = 1000000000;
1697         for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
1698         {
1699                 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
1700                 // first see if the nearest point on the surface's box is closer than the previous match
1701                 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
1702                 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
1703                 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
1704                 dist = VectorLength2(clipped);
1705                 if (dist < bestdist)
1706                 {
1707                         // it is, check the nearest point on the actual geometry
1708                         clippointtosurface(model, surface, p, clipped);
1709                         VectorSubtract(clipped, p, clipped);
1710                         dist += VectorLength2(clipped);
1711                         if (dist < bestdist)
1712                         {
1713                                 // that's closer too, store it as the best match
1714                                 best = surfacenum;
1715                                 bestdist = dist;
1716                         }
1717                 }
1718         }
1719         PRVM_G_FLOAT(OFS_RETURN) = best;
1720 }
1721
1722 // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint
1723 void VM_CL_getsurfaceclippedpoint(void)
1724 {
1725         prvm_edict_t *ed;
1726         model_t *model;
1727         msurface_t *surface;
1728         vec3_t p, out;
1729         VectorClear(PRVM_G_VECTOR(OFS_RETURN));
1730         ed = PRVM_G_EDICT(OFS_PARM0);
1731         if (!(model = CSQC_GetModelFromEntity(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
1732                 return;
1733         // FIXME: implement rotation/scaling
1734         VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.client->origin, p);
1735         clippointtosurface(model, surface, p, out);
1736         // FIXME: implement rotation/scaling
1737         VectorAdd(out, ed->fields.client->origin, PRVM_G_VECTOR(OFS_RETURN));
1738 }
1739
1740 // #443 void(entity e, entity tagentity, string tagname) setattachment
1741 void VM_CL_setattachment (void)
1742 {
1743         prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
1744         prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
1745         const char *tagname = PRVM_G_STRING(OFS_PARM2);
1746         prvm_eval_t *v;
1747         int modelindex;
1748         model_t *model;
1749
1750         if (e == prog->edicts)
1751         {
1752                 VM_Warning("setattachment: can not modify world entity\n");
1753                 return;
1754         }
1755         if (e->priv.server->free)
1756         {
1757                 VM_Warning("setattachment: can not modify free entity\n");
1758                 return;
1759         }
1760
1761         if (tagentity == NULL)
1762                 tagentity = prog->edicts;
1763
1764         v = PRVM_GETEDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
1765         if (v)
1766                 v->edict = PRVM_EDICT_TO_PROG(tagentity);
1767
1768         v = PRVM_GETEDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
1769         if (v)
1770                 v->_float = 0;
1771         if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
1772         {
1773                 modelindex = (int)tagentity->fields.client->modelindex;
1774                 model = CSQC_GetModelByIndex(modelindex);
1775                 if (model)
1776                 {
1777                         v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.client->skin, tagname);
1778                         if (v->_float == 0)
1779                                 Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity), model->name);
1780                 }
1781                 else
1782                         Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity));
1783         }
1784 }
1785
1786 /////////////////////////////////////////
1787 // DP_MD3_TAGINFO extension coded by VorteX
1788
1789 int CL_GetTagIndex (prvm_edict_t *e, const char *tagname)
1790 {
1791         model_t *model = CSQC_GetModelFromEntity(e);
1792         if (model)
1793                 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.client->skin, tagname);
1794         else
1795                 return -1;
1796 };
1797
1798 // Warnings/errors code:
1799 // 0 - normal (everything all-right)
1800 // 1 - world entity
1801 // 2 - free entity
1802 // 3 - null or non-precached model
1803 // 4 - no tags with requested index
1804 // 5 - runaway loop at attachment chain
1805 extern cvar_t cl_bob;
1806 extern cvar_t cl_bobcycle;
1807 extern cvar_t cl_bobup;
1808 int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
1809 {
1810         prvm_eval_t *val;
1811         int reqframe, attachloop;
1812         matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
1813         prvm_edict_t *attachent;
1814         model_t *model;
1815
1816         *out = identitymatrix; // warnings and errors return identical matrix
1817
1818         if (ent == prog->edicts)
1819                 return 1;
1820         if (ent->priv.server->free)
1821                 return 2;
1822
1823         model = CSQC_GetModelFromEntity(ent);
1824
1825         if(!model)
1826                 return 3;
1827
1828         if (ent->fields.client->frame >= 0 && ent->fields.client->frame < model->numframes && model->animscenes)
1829                 reqframe = model->animscenes[(int)ent->fields.client->frame].firstframe;
1830         else
1831                 reqframe = 0; // if model has wrong frame, engine automatically switches to model first frame
1832
1833         // get initial tag matrix
1834         if (tagindex)
1835         {
1836                 int ret = Mod_Alias_GetTagMatrix(model, reqframe, tagindex - 1, &tagmatrix);
1837                 if (ret)
1838                         return ret;
1839         }
1840         else
1841                 tagmatrix = identitymatrix;
1842
1843         if ((val = PRVM_GETEDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
1844         { // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
1845                 attachloop = 0;
1846                 do
1847                 {
1848                         attachent = PRVM_EDICT_NUM(val->edict); // to this it entity our entity is attached
1849                         val = PRVM_GETEDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index);
1850
1851                         model = CSQC_GetModelFromEntity(attachent);
1852
1853                         if (model && val->_float >= 1 && model->animscenes && attachent->fields.client->frame >= 0 && attachent->fields.client->frame < model->numframes)
1854                                 Mod_Alias_GetTagMatrix(model, model->animscenes[(int)attachent->fields.client->frame].firstframe, (int)val->_float - 1, &attachmatrix);
1855                         else
1856                                 attachmatrix = identitymatrix;
1857
1858                         // apply transformation by child entity matrix
1859                         val = PRVM_GETEDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
1860                         if (val->_float == 0)
1861                                 val->_float = 1;
1862                         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);
1863                         Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
1864                         Matrix4x4_Copy(&tagmatrix, out);
1865
1866                         // finally transformate by matrix of tag on parent entity
1867                         Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
1868                         Matrix4x4_Copy(&tagmatrix, out);
1869
1870                         ent = attachent;
1871                         attachloop += 1;
1872                         if (attachloop > 255) // prevent runaway looping
1873                                 return 5;
1874                 }
1875                 while ((val = PRVM_GETEDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict);
1876         }
1877
1878         // normal or RENDER_VIEWMODEL entity (or main parent entity on attach chain)
1879         val = PRVM_GETEDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
1880         if (val->_float == 0)
1881                 val->_float = 1;
1882         // Alias models have inverse pitch, bmodels can't have tags, so don't check for modeltype...
1883         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);
1884         Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
1885
1886         if ((val = PRVM_GETEDICTFIELDVALUE(ent, prog->fieldoffsets.renderflags)) && (RF_VIEWMODEL & (int)val->_float))
1887         {// RENDER_VIEWMODEL magic
1888                 Matrix4x4_Copy(&tagmatrix, out);
1889
1890                 val = PRVM_GETEDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
1891                 if (val->_float == 0)
1892                         val->_float = 1;
1893
1894                 Matrix4x4_CreateFromQuakeEntity(&entitymatrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], val->_float);
1895                 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
1896
1897                 /*
1898                 // Cl_bob, ported from rendering code
1899                 if (ent->fields.client->health > 0 && cl_bob.value && cl_bobcycle.value)
1900                 {
1901                         double bob, cycle;
1902                         // LordHavoc: this code is *weird*, but not replacable (I think it
1903                         // should be done in QC on the server, but oh well, quake is quake)
1904                         // LordHavoc: figured out bobup: the time at which the sin is at 180
1905                         // degrees (which allows lengthening or squishing the peak or valley)
1906                         cycle = sv.time/cl_bobcycle.value;
1907                         cycle -= (int)cycle;
1908                         if (cycle < cl_bobup.value)
1909                                 cycle = sin(M_PI * cycle / cl_bobup.value);
1910                         else
1911                                 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
1912                         // bob is proportional to velocity in the xy plane
1913                         // (don't count Z, or jumping messes it up)
1914                         bob = sqrt(ent->fields.client->velocity[0]*ent->fields.client->velocity[0] + ent->fields.client->velocity[1]*ent->fields.client->velocity[1])*cl_bob.value;
1915                         bob = bob*0.3 + bob*0.7*cycle;
1916                         Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
1917                 }
1918                 */
1919         }
1920         return 0;
1921 }
1922
1923 // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
1924 void VM_CL_gettagindex (void)
1925 {
1926         prvm_edict_t *ent = PRVM_G_EDICT(OFS_PARM0);
1927         const char *tag_name = PRVM_G_STRING(OFS_PARM1);
1928         int modelindex, tag_index;
1929
1930         if (ent == prog->edicts)
1931         {
1932                 VM_Warning("gettagindex: can't affect world entity\n");
1933                 return;
1934         }
1935         if (ent->priv.server->free)
1936         {
1937                 VM_Warning("gettagindex: can't affect free entity\n");
1938                 return;
1939         }
1940
1941         modelindex = (int)ent->fields.client->modelindex;
1942         if(modelindex < 0)
1943                 modelindex = -(modelindex+1);
1944         tag_index = 0;
1945         if (modelindex <= 0 || modelindex >= MAX_MODELS)
1946                 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
1947         else
1948         {
1949                 tag_index = CL_GetTagIndex(ent, tag_name);
1950                 if (tag_index == 0)
1951                         Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
1952         }
1953         PRVM_G_FLOAT(OFS_RETURN) = tag_index;
1954 }
1955
1956 // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
1957 void VM_CL_gettaginfo (void)
1958 {
1959         prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
1960         int tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
1961         matrix4x4_t tag_matrix;
1962         int returncode;
1963
1964         returncode = CL_GetTagMatrix(&tag_matrix, e, tagindex);
1965         Matrix4x4_ToVectors(&tag_matrix, prog->globals.client->v_forward, prog->globals.client->v_right, prog->globals.client->v_up, PRVM_G_VECTOR(OFS_RETURN));
1966
1967         switch(returncode)
1968         {
1969                 case 1:
1970                         VM_Warning("gettagindex: can't affect world entity\n");
1971                         break;
1972                 case 2:
1973                         VM_Warning("gettagindex: can't affect free entity\n");
1974                         break;
1975                 case 3:
1976                         Con_DPrintf("CL_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
1977                         break;
1978                 case 4:
1979                         Con_DPrintf("CL_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
1980                         break;
1981                 case 5:
1982                         Con_DPrintf("CL_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
1983                         break;
1984         }
1985 }
1986
1987 //=================================================
1988 //[515]: here goes test/unfinished/etc.
1989
1990 //[515]: check if it is what it should be
1991 void VM_WasFreed (void)
1992 {
1993         prvm_edict_t    *e;
1994         VM_SAFEPARMCOUNT(1, VM_WasFreed);
1995
1996         e = PRVM_G_EDICT(OFS_PARM0);
1997         if (!e->priv.required->free || (e->priv.required->free && (e->priv.required->freetime < 2 || (prog->globals.client->time - e->priv.required->freetime) > 0.5 )))
1998                 PRVM_G_FLOAT(OFS_RETURN) = false;
1999         else
2000                 PRVM_G_FLOAT(OFS_RETURN) = true;
2001 }
2002
2003 void VM_CL_select_cube (void)
2004 {
2005         int             i;
2006         float   *mins2, *maxs2;
2007         prvm_edict_t    *ent, *chain;
2008         vec3_t  mins1, maxs1;
2009
2010         VM_SAFEPARMCOUNT(2, VM_CL_select_cube);
2011
2012         if (prog->fieldoffsets.chain < 0)
2013                 PRVM_ERROR("VM_findchain: %s doesnt have a chain field !\n", PRVM_NAME);
2014
2015         chain = prog->edicts;
2016
2017         mins2 = PRVM_G_VECTOR(OFS_PARM0);
2018         maxs2 = PRVM_G_VECTOR(OFS_PARM1);
2019
2020         ent = PRVM_NEXT_EDICT(prog->edicts);
2021         for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
2022         {
2023                 if (ent->priv.required->free)
2024                         continue;
2025                 VectorCopy(ent->fields.client->origin, mins1);
2026                 VectorAdd(mins1, ent->fields.client->maxs, maxs1);
2027                 VectorAdd(mins1, ent->fields.client->mins, mins1);
2028                 if (mins1[0] > maxs2[0] || mins1[1] > maxs2[1] || mins1[2] > maxs2[2])
2029                         continue;
2030                 if (maxs1[0] < mins2[0] || maxs1[1] < mins2[1] || maxs1[2] < mins2[2])
2031                         continue;
2032                 PRVM_E_INT(ent,prog->fieldoffsets.chain) = PRVM_NUM_FOR_EDICT(chain);
2033                 chain = ent;
2034         }
2035
2036         VM_RETURN_EDICT(chain);
2037 }
2038
2039 void VM_CL_select_super (void)
2040 {
2041 /*      int             i;
2042         float   *v[8];
2043         prvm_edict_t    *ent, *chain;
2044         vec3_t  mins1, maxs1;
2045
2046         VM_SAFEPARMCOUNT(8, VM_findchain);
2047         for(i=0;i<8;i++)
2048                 v[i] = PRVM_G_VECTOR(OFS_PARM0+i*3);
2049
2050         if (prog->fieldoffsets.chain < 0)
2051                 PRVM_ERROR("VM_findchain: %s doesnt have a chain field !\n", PRVM_NAME);
2052
2053         chain = prog->edicts;
2054
2055         mins2 = PRVM_G_VECTOR(OFS_PARM0);
2056         maxs2 = PRVM_G_VECTOR(OFS_PARM1);
2057
2058         ent = PRVM_NEXT_EDICT(prog->edicts);
2059         for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
2060         {
2061                 if (ent->priv.required->free)
2062                         continue;
2063                 VectorCopy(ent->fields.client->origin, mins1);
2064                 VectorAdd(mins1, ent->fields.client->maxs, maxs1);
2065                 VectorAdd(mins1, ent->fields.client->mins, mins1);
2066                 if (mins1[0] > maxs2[0] || mins1[1] > maxs2[1] || mins1[2] > maxs2[2])
2067                         continue;
2068                 if (maxs1[0] < mins2[0] || maxs1[1] < mins2[1] || maxs1[2] < mins2[2])
2069                         continue;
2070                 PRVM_E_INT(ent,prog->fieldoffsets.chain) = PRVM_NUM_FOR_EDICT(chain);
2071                 chain = ent;
2072         }
2073
2074         VM_RETURN_EDICT(chain);*/
2075 }
2076
2077 static int Is_Text_Color (char c, char t)
2078 {
2079         int a = 0;
2080         char c2 = c - (c & 128);
2081         char t2 = t - (t & 128);
2082
2083         if(c != STRING_COLOR_TAG && c2 != STRING_COLOR_TAG)             return 0;
2084         if(t >= '0' && t <= '9')                a = 1;
2085         if(t2 >= '0' && t2 <= '9')              a = 1;
2086 /*      if(t >= 'A' && t <= 'Z')                a = 2;
2087         if(t2 >= 'A' && t2 <= 'Z')              a = 2;
2088
2089         if(a == 1 && scr_colortext.integer > 0)
2090                 return 1;
2091         if(a == 2 && scr_multifonts.integer > 0)
2092                 return 2;
2093 */
2094         return a;
2095 }
2096
2097 void VM_uncolorstring (void) //#170
2098 {
2099         const char      *in;
2100         char            out[VM_STRINGTEMP_LENGTH];
2101         int                     k = 0, i = 0;
2102
2103         VM_SAFEPARMCOUNT(1, VM_uncolorstring);
2104         in = PRVM_G_STRING(OFS_PARM0);
2105         VM_CheckEmptyString (in);
2106
2107         while (in[k])
2108         {
2109                 if(in[k+1])
2110                 if(Is_Text_Color(in[k], in[k+1]) == 1/* || (in[k] == '&' && in[k+1] == 'r')*/)
2111                 {
2112                         k += 2;
2113                         continue;
2114                 }
2115                 out[i] = in[k];
2116                 ++k;
2117                 ++i;
2118         }
2119         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(out);
2120 }
2121
2122 void VM_CL_selecttraceline (void)
2123 {
2124         float   *v1, *v2;
2125         int             ent, ignore, csqcents;
2126
2127         v1 = PRVM_G_VECTOR(OFS_PARM0);
2128         v2 = PRVM_G_VECTOR(OFS_PARM1);
2129         ignore = (int)PRVM_G_FLOAT(OFS_PARM2);
2130         csqcents = (int)PRVM_G_FLOAT(OFS_PARM3);
2131         ent = 0;
2132
2133         if (csqcents)
2134         {
2135                 VM_Warning("VM_CL_selecttraceline: csqcents flag not supported anymore, and this function is deprecated\n");
2136                 return;
2137         }
2138         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);
2139         PRVM_G_FLOAT(OFS_RETURN) = ent;
2140 }
2141
2142 void VM_charindex (void)
2143 {
2144         const char *s;
2145         s = PRVM_G_STRING(OFS_PARM0);
2146         if((unsigned)PRVM_G_FLOAT(OFS_PARM1) > strlen(s))
2147                 return;
2148         PRVM_G_FLOAT(OFS_RETURN) = (unsigned char)s[(int)PRVM_G_FLOAT(OFS_PARM1)];
2149 }
2150
2151 //#223 string(float c, ...) chr2str (FTE_STRINGS)
2152 void VM_chr2str (void)
2153 {
2154         char    t[128];
2155         int             i;
2156         for(i = 0;i < prog->argc && i < (int)sizeof(t) - 1;i++)
2157                 t[i] = (unsigned char)PRVM_G_FLOAT(OFS_PARM0+i*3);
2158         t[i] = 0;
2159         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(t);
2160 }
2161
2162 //#228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2163 void VM_strncmp (void)
2164 {
2165         const char *s1, *s2;
2166         VM_SAFEPARMCOUNT(1, VM_strncmp);
2167         s1 = PRVM_G_STRING(OFS_PARM0);
2168         s2 = PRVM_G_STRING(OFS_PARM1);
2169         PRVM_G_FLOAT(OFS_RETURN) = strncmp(s1, s2, (size_t)PRVM_G_FLOAT(OFS_PARM2));
2170 }
2171
2172 //============================================================================
2173 //============================================================================
2174
2175 prvm_builtin_t vm_cl_builtins[] = {
2176 0,  // to be consistent with the old vm
2177 VM_CL_makevectors,                      // #1 void(vector ang) makevectors
2178 VM_CL_setorigin,                        // #2 void(entity e, vector o) setorigin
2179 VM_CL_setmodel,                         // #3 void(entity e, string m) setmodel
2180 VM_CL_setsize,                          // #4 void(entity e, vector min, vector max) setsize
2181 0,
2182 VM_break,                                       // #6 void() break
2183 VM_random,                                      // #7 float() random
2184 VM_CL_sound,                            // #8 void(entity e, float chan, string samp) sound
2185 VM_normalize,                           // #9 vector(vector v) normalize
2186 VM_error,                                       // #10 void(string e) error
2187 VM_objerror,                            // #11 void(string e) objerror
2188 VM_vlen,                                        // #12 float(vector v) vlen
2189 VM_vectoyaw,                            // #13 float(vector v) vectoyaw
2190 VM_CL_spawn,                            // #14 entity() spawn
2191 VM_remove,                                      // #15 void(entity e) remove
2192 VM_CL_traceline,                        // #16 float(vector v1, vector v2, float tryents) traceline
2193 0,
2194 VM_find,                                        // #18 entity(entity start, .string fld, string match) find
2195 VM_CL_precache_sound,           // #19 void(string s) precache_sound
2196 VM_CL_precache_model,           // #20 void(string s) precache_model
2197 0,
2198 VM_CL_findradius,                       // #22 entity(vector org, float rad) findradius
2199 0,
2200 0,
2201 VM_dprint,                                      // #25 void(string s) dprint
2202 VM_ftos,                                        // #26 void(string s) ftos
2203 VM_vtos,                                        // #27 void(string s) vtos
2204 VM_coredump,                            // #28 void() coredump
2205 VM_traceon,                                     // #29 void() traceon
2206 VM_traceoff,                            // #30 void() traceoff
2207 VM_eprint,                                      // #31 void(entity e) eprint
2208 0,
2209 NULL,                                           // #33
2210 VM_CL_droptofloor,                      // #34 float() droptofloor
2211 VM_CL_lightstyle,                       // #35 void(float style, string value) lightstyle
2212 VM_rint,                                        // #36 float(float v) rint
2213 VM_floor,                                       // #37 float(float v) floor
2214 VM_ceil,                                        // #38 float(float v) ceil
2215 NULL,                                           // #39
2216 VM_CL_checkbottom,                      // #40 float(entity e) checkbottom
2217 VM_CL_pointcontents,            // #41 float(vector v) pointcontents
2218 NULL,                                           // #42
2219 VM_fabs,                                        // #43 float(float f) fabs
2220 0,
2221 VM_cvar,                                        // #45 float(string s) cvar
2222 VM_localcmd,                            // #46 void(string s) localcmd
2223 VM_nextent,                                     // #47 entity(entity e) nextent
2224 VM_CL_particle,                         // #48 void(vector o, vector d, float color, float count) particle
2225 VM_changeyaw,                           // #49 void(entity ent) ChangeYaw
2226 NULL,                                           // #50
2227 VM_vectoangles,                         // #51 vector(vector v) vectoangles
2228 0,                      // #52 void(float to, float f) WriteByte
2229 0,                      // #53 void(float to, float f) WriteChar
2230 0,                      // #54 void(float to, float f) WriteShort
2231 0,                      // #55 void(float to, float f) WriteLong
2232 0,                      // #56 void(float to, float f) WriteCoord
2233 0,                      // #57 void(float to, float f) WriteAngle
2234 0,                      // #58 void(float to, string s) WriteString
2235 0,
2236 VM_sin,                                         // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW)
2237 VM_cos,                                         // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW)
2238 VM_sqrt,                                        // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW)
2239 VM_changepitch,                         // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH)
2240 VM_CL_tracetoss,                        // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS)
2241 VM_etos,                                        // #65 string(entity ent) etos (DP_QC_ETOS)
2242 NULL,                                           // #66
2243 0,                                                              // #67
2244 0,                                                              // #68
2245 0,                                                              // #69
2246 0,                                                              // #70
2247 NULL,                                           // #71
2248 VM_cvar_set,                            // #72 void(string var, string val) cvar_set
2249 0,                                                              // #73
2250 VM_CL_ambientsound,                     // #74 void(vector pos, string samp, float vol, float atten) ambientsound
2251 VM_CL_precache_model,           // #75 string(string s) precache_model2
2252 VM_CL_precache_sound,           // #76 string(string s) precache_sound2
2253 0,                                                              // #77
2254 VM_chr,                                         // #78
2255 NULL,                                           // #79
2256 NULL,                                           // #80
2257 VM_stof,                                        // #81 float(string s) stof (FRIK_FILE)
2258 NULL,                                           // #82
2259 NULL,                                           // #83
2260 NULL,                                           // #84
2261 NULL,                                           // #85
2262 NULL,                                           // #86
2263 NULL,                                           // #87
2264 NULL,                                           // #88
2265 NULL,                                           // #89
2266 VM_CL_tracebox,                         // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2267 VM_randomvec,                           // #91 vector() randomvec (DP_QC_RANDOMVEC)
2268 VM_CL_getlight,                         // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2269 PF_registercvar,                        // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2270 VM_min,                                         // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2271 VM_max,                                         // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2272 VM_bound,                                       // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2273 VM_pow,                                         // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2274 VM_findfloat,                           // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2275 VM_checkextension,                      // #99 float(string s) checkextension (the basis of the extension system)
2276 NULL,                                           // #100
2277 NULL,                                           // #101
2278 NULL,                                           // #102
2279 NULL,                                           // #103
2280 NULL,                                           // #104
2281 NULL,                                           // #105
2282 NULL,                                           // #106
2283 NULL,                                           // #107
2284 NULL,                                           // #108
2285 NULL,                                           // #109
2286 VM_fopen,                                       // #110 float(string filename, float mode) fopen (FRIK_FILE)
2287 VM_fclose,                                      // #111 void(float fhandle) fclose (FRIK_FILE)
2288 VM_fgets,                                       // #112 string(float fhandle) fgets (FRIK_FILE)
2289 VM_fputs,                                       // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2290 VM_strlen,                                      // #114 float(string s) strlen (FRIK_FILE)
2291 VM_strcat,                                      // #115 string(string s1, string s2) strcat (FRIK_FILE)
2292 VM_substring,                           // #116 string(string s, float start, float length) substring (FRIK_FILE)
2293 VM_stov,                                        // #117 vector(string) stov (FRIK_FILE)
2294 VM_strzone,                                     // #118 string(string s) strzone (FRIK_FILE)
2295 VM_strunzone,                           // #119 void(string s) strunzone (FRIK_FILE)
2296
2297 e10, e10, e10, e10, e10, e10, e10, e10,         // #120-199
2298 e10,    //#200-209
2299 0,      //#210
2300 0,      //#211
2301 0,      //#212
2302 0,      //#213
2303 0,      //#214
2304 0,      //#215
2305 0,      //#216
2306 0,      //#217
2307 VM_bitshift,                            //#218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2308 0,      //#219
2309 0,      //#220
2310 0,      //#221
2311 VM_charindex,                           //#222 float(string str, float ofs) str2chr (FTE_STRINGS)
2312 VM_chr2str,                                     //#223 string(float c, ...) chr2str (FTE_STRINGS)
2313 0,      //#224
2314 0,      //#225
2315 0,      //#226
2316 0,      //#227
2317 VM_strncmp,                                     //#228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2318 0,
2319 e10, e10, e10, e10, e10, e10, e10,      // #230-299
2320
2321 //======CSQC start=======//
2322 //3d world (buffer/buffering) operations
2323 VM_R_ClearScene,                        //#300 void() clearscene (EXT_CSQC)
2324 VM_R_AddEntities,                       //#301 void(float mask) addentities (EXT_CSQC)
2325 VM_R_AddEntity,                         //#302 void(entity ent) addentity (EXT_CSQC)
2326 VM_R_SetView,                           //#303 float(float property, ...) setproperty (EXT_CSQC)
2327 VM_R_RenderScene,                       //#304 void() renderscene (EXT_CSQC)
2328 VM_R_AddDynamicLight,           //#305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2329 VM_R_PolygonBegin,                      //#306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2330 VM_R_PolygonVertex,                     //#307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2331 VM_R_PolygonEnd,                        //#308 void() R_EndPolygon
2332 0,                      //#309
2333
2334 //maths stuff that uses the current view settings
2335 VM_CL_unproject,                        //#310 vector (vector v) cs_unproject (EXT_CSQC)
2336 VM_CL_project,                          //#311 vector (vector v) cs_project (EXT_CSQC)
2337 0,                      //#312
2338 0,                      //#313
2339 0,                      //#314
2340
2341 //2d (immediate) operations
2342 VM_drawline,                            //#315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
2343 VM_iscachedpic,                         //#316 float(string name) iscachedpic (EXT_CSQC)
2344 VM_precache_pic,                        //#317 string(string name, float trywad) precache_pic (EXT_CSQC)
2345 VM_getimagesize,                        //#318 vector(string picname) draw_getimagesize (EXT_CSQC)
2346 VM_freepic,                                     //#319 void(string name) freepic (EXT_CSQC)
2347 VM_drawcharacter,                       //#320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
2348 VM_drawstring,                          //#321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
2349 VM_drawpic,                                     //#322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
2350 VM_drawfill,                            //#323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
2351 VM_drawsetcliparea,                     //#324 void(float x, float y, float width, float height) drawsetcliparea
2352 VM_drawresetcliparea,           //#325 void(void) drawresetcliparea
2353 0,                      //#326
2354 0,                      //#327
2355 0,                      //#328
2356 0,                      //#329
2357
2358 VM_CL_getstatf,                         //#330 float(float stnum) getstatf (EXT_CSQC)
2359 VM_CL_getstati,                         //#331 float(float stnum) getstati (EXT_CSQC)
2360 VM_CL_getstats,                         //#332 string(float firststnum) getstats (EXT_CSQC)
2361 VM_CL_setmodelindex,            //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2362 VM_CL_modelnameforindex,        //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2363 VM_CL_particleeffectnum,        //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2364 VM_CL_trailparticles,           //#336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2365 VM_CL_pointparticles,           //#337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
2366 VM_CL_centerprint,                      //#338 void(string s) cprint (EXT_CSQC)
2367 VM_print,                                       //#339 void(string s) print (EXT_CSQC)
2368 VM_keynumtostring,                      //#340 string(float keynum) keynumtostring (EXT_CSQC)
2369 VM_stringtokeynum,                      //#341 float(string keyname) stringtokeynum (EXT_CSQC)
2370 VM_CL_getkeybind,                       //#342 string(float keynum) getkeybind (EXT_CSQC)
2371 VM_CL_setcursormode,            //#343 void(float usecursor) setcursormode (EXT_CSQC)
2372 VM_getmousepos,                         //#344 vector() getmousepos (EXT_CSQC)
2373 VM_CL_getinputstate,            //#345 float(float framenum) getinputstate (EXT_CSQC)
2374 VM_CL_setsensitivityscale,      //#346 void(float sens) setsensitivityscaler (EXT_CSQC)
2375 VM_CL_runplayerphysics,         //#347 void() runstandardplayerphysics (EXT_CSQC)
2376 VM_CL_getplayerkey,                     //#348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
2377 VM_CL_isdemo,                           //#349 float() isdemo (EXT_CSQC)
2378 VM_isserver,                            //#350 float() isserver (EXT_CSQC)
2379 VM_CL_setlistener,                      //#351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
2380 VM_CL_registercmd,                      //#352 void(string cmdname) registercommand (EXT_CSQC)
2381 VM_WasFreed,                            //#353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
2382 VM_CL_playernum,                        //#354 float() playernum
2383 VM_CL_onground,                         //#355 float() cl_onground (EXT_CSQC)
2384 VM_charindex,                           //#356 float(string s, float num) charindex
2385 VM_CL_selecttraceline,          //#357 float(vector start, vector end, float ignore, float csqcents) selecttraceline
2386 0,                      //#358
2387 0,                      //#359
2388 VM_CL_ReadByte,                         //#360 float() readbyte (EXT_CSQC)
2389 VM_CL_ReadChar,                         //#361 float() readchar (EXT_CSQC)
2390 VM_CL_ReadShort,                        //#362 float() readshort (EXT_CSQC)
2391 VM_CL_ReadLong,                         //#363 float() readlong (EXT_CSQC)
2392 VM_CL_ReadCoord,                        //#364 float() readcoord (EXT_CSQC)
2393 VM_CL_ReadAngle,                        //#365 float() readangle (EXT_CSQC)
2394 VM_CL_ReadString,                       //#366 string() readstring (EXT_CSQC)
2395 VM_CL_ReadFloat,                        //#367 float() readfloat (EXT_CSQC)
2396 0,                      //#368
2397 0,                      //#369
2398 0,                      //#370
2399 0,                      //#371
2400 0,                      //#372
2401 0,                      //#373
2402 0,                      //#374
2403 0,                      //#375
2404 0,                      //#376
2405 0,                      //#377
2406 0,                      //#378
2407 0,                      //#379
2408 0,                      //#380
2409 0,                      //#381
2410 0,                      //#382
2411 0,                      //#383
2412 0,                      //#384
2413 0,                      //#385
2414 0,                      //#386
2415 0,                      //#387
2416 0,                      //#388
2417 0,                      //#389
2418 0,                      //#390
2419 0,                      //#391
2420 0,                      //#392
2421 0,                      //#393
2422 0,                      //#394
2423 0,                      //#395
2424 0,                      //#396
2425 0,                      //#397
2426 0,                      //#398
2427 0,                      //#399
2428 //=========CSQC end========//
2429
2430 VM_copyentity,                                  // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
2431 0,
2432 VM_findchain,                                   // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
2433 VM_findchainfloat,                              // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
2434 VM_CL_effect,                                   // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
2435 VM_CL_te_blood,                                 // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
2436 VM_CL_te_bloodshower,                   // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
2437 VM_CL_te_explosionrgb,                  // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
2438 VM_CL_te_particlecube,                  // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE)
2439 VM_CL_te_particlerain,                  // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
2440 VM_CL_te_particlesnow,                  // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
2441 VM_CL_te_spark,                                 // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
2442 VM_CL_te_gunshotquad,                   // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
2443 VM_CL_te_spikequad,                             // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
2444 VM_CL_te_superspikequad,                // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
2445 VM_CL_te_explosionquad,                 // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
2446 VM_CL_te_smallflash,                    // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
2447 VM_CL_te_customflash,                   // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
2448 VM_CL_te_gunshot,                               // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
2449 VM_CL_te_spike,                                 // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
2450 VM_CL_te_superspike,                    // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
2451 VM_CL_te_explosion,                             // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
2452 VM_CL_te_tarexplosion,                  // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
2453 VM_CL_te_wizspike,                              // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
2454 VM_CL_te_knightspike,                   // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
2455 VM_CL_te_lavasplash,                    // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
2456 VM_CL_te_teleport,                              // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
2457 VM_CL_te_explosion2,                    // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
2458 VM_CL_te_lightning1,                    // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
2459 VM_CL_te_lightning2,                    // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
2460 VM_CL_te_lightning3,                    // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
2461 VM_CL_te_beam,                                  // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
2462 VM_vectorvectors,                               // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
2463 VM_CL_te_plasmaburn,                    // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
2464 VM_CL_getsurfacenumpoints,              // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
2465 VM_CL_getsurfacepoint,                  // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
2466 VM_CL_getsurfacenormal,                 // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
2467 VM_CL_getsurfacetexture,                // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
2468 VM_CL_getsurfacenearpoint,              // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
2469 VM_CL_getsurfaceclippedpoint,   // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
2470 0,                                                                      // #440
2471 VM_tokenize,                            // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
2472 VM_argv,                                        // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
2473 VM_CL_setattachment,            // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
2474 VM_search_begin,                        // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
2475 VM_search_end,                          // #445 void(float handle) search_end (DP_FS_SEARCH)
2476 VM_search_getsize,                      // #446 float(float handle) search_getsize (DP_FS_SEARCH)
2477 VM_search_getfilename,          // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
2478 VM_cvar_string,                         // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
2479 VM_findflags,                           // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
2480 VM_findchainflags,                      // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
2481 VM_CL_gettagindex,                      // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
2482 VM_CL_gettaginfo,                       // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
2483 0,                                                              // #453
2484 0,                                                              // #454
2485 0,                                                              // #455
2486 NULL,                                           // #456
2487 NULL,                                           // #457
2488 NULL,                                           // #458
2489 NULL,                                           // #459
2490 VM_buf_create,                          // #460 float() buf_create (DP_QC_STRINGBUFFERS)
2491 VM_buf_del,                                     // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
2492 VM_buf_getsize,                         // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
2493 VM_buf_copy,                            // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
2494 VM_buf_sort,                            // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
2495 VM_buf_implode,                         // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
2496 VM_bufstr_get,                          // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
2497 VM_bufstr_set,                          // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
2498 VM_bufstr_add,                          // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
2499 VM_bufstr_free,                         // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
2500 NULL,                                           // #470
2501 VM_asin,                                        // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
2502 VM_acos,                                        // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
2503 VM_atan,                                        // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
2504 VM_atan2,                                       // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
2505 VM_tan,                                         // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
2506 VM_strlennocol,                         // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
2507 VM_strdecolorize,                       // #477 string(string s) : DRESK - Decolorized String (DP_QC_STRINGCOLORFUNCTIONS)
2508 VM_strftime,                            // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
2509 NULL,                                           // #479
2510 e10, e10                        // #480-499 (LordHavoc)
2511 };
2512
2513 const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);
2514
2515 void VM_CL_Cmd_Init(void)
2516 {
2517 }
2518
2519 void VM_CL_Cmd_Reset(void)
2520 {
2521 }
2522