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