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