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