removed trailing comments on cvar declarations and Cmd_AddCommand calls
[xonotic/darkplaces.git] / svvm_cmds.c
1 #include "prvm_cmds.h"
2
3 //============================================================================
4 // Server
5
6 cvar_t sv_aim = {CVAR_SAVE, "sv_aim", "2", "maximum cosine angle for quake's vertical autoaim, a value above 1 completely disables the autoaim, quake used 0.93"};
7
8
9 char *vm_sv_extensions =
10 "BX_WAL_SUPPORT "
11 "DP_BUTTONCHAT "
12 "DP_BUTTONUSE "
13 "DP_CL_LOADSKY "
14 "DP_CON_ALIASPARAMETERS "
15 "DP_CON_EXPANDCVAR "
16 "DP_CON_SET "
17 "DP_CON_SETA "
18 "DP_CON_STARTMAP "
19 "DP_EF_ADDITIVE "
20 "DP_EF_BLUE "
21 "DP_EF_DOUBLESIDED "
22 "DP_EF_FLAME "
23 "DP_EF_FULLBRIGHT "
24 "DP_EF_NODEPTHTEST "
25 "DP_EF_NODRAW "
26 "DP_EF_NOSHADOW "
27 "DP_EF_RED "
28 "DP_EF_STARDUST "
29 "DP_ENT_ALPHA "
30 "DP_ENT_COLORMOD "
31 "DP_ENT_CUSTOMCOLORMAP "
32 "DP_ENT_EXTERIORMODELTOCLIENT "
33 "DP_ENT_GLOW "
34 "DP_ENT_LOWPRECISION "
35 "DP_ENT_SCALE "
36 "DP_ENT_VIEWMODEL "
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 "
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_STRFTIME "
71 "DP_QC_STRINGBUFFERS "
72 "DP_QC_STRINGCOLORFUNCTIONS "
73 "DP_QC_TRACEBOX "
74 "DP_QC_TRACETOSS "
75 "DP_QC_TRACE_MOVETYPE_HITMODEL "
76 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
77 "DP_QC_UNLIMITEDTEMPSTRINGS "
78 "DP_QC_VECTORVECTORS "
79 "DP_QUAKE2_MODEL "
80 "DP_QUAKE2_SPRITE "
81 "DP_QUAKE3_MAP "
82 "DP_QUAKE3_MODEL "
83 "DP_REGISTERCVAR "
84 "DP_SND_DIRECTIONLESSATTNNONE "
85 "DP_SND_FAKETRACKS "
86 "DP_SND_OGGVORBIS "
87 "DP_SND_STEREOWAV "
88 "DP_SOLIDCORPSE "
89 "DP_SPRITE32 "
90 "DP_SV_BOTCLIENT "
91 "DP_SV_CLIENTCOLORS "
92 "DP_SV_CLIENTNAME "
93 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
94 "DP_SV_DRAWONLYTOCLIENT "
95 "DP_SV_DROPCLIENT "
96 "DP_SV_EFFECT "
97 "DP_SV_ENTITYCONTENTSTRANSITION "
98 "DP_SV_NODRAWTOCLIENT "
99 "DP_SV_PING "
100 "DP_SV_PLAYERPHYSICS "
101 "DP_SV_PRECACHEANYTIME "
102 "DP_SV_PRINT "
103 "DP_SV_PUNCHVECTOR "
104 "DP_SV_ROTATINGBMODEL "
105 "DP_SV_SETCOLOR "
106 "DP_SV_SLOWMO "
107 "DP_SV_WRITEUNTERMINATEDSTRING "
108 "DP_TE_BLOOD "
109 "DP_TE_BLOODSHOWER "
110 "DP_TE_CUSTOMFLASH "
111 "DP_TE_EXPLOSIONRGB "
112 "DP_TE_FLAMEJET "
113 "DP_TE_PARTICLECUBE "
114 "DP_TE_PARTICLERAIN "
115 "DP_TE_PARTICLESNOW "
116 "DP_TE_PLASMABURN "
117 "DP_TE_QUADEFFECTS1 "
118 "DP_TE_SMALLFLASH "
119 "DP_TE_SPARK "
120 "DP_TE_STANDARDEFFECTBUILTINS "
121 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
122 "DP_VIEWZOOM "
123 "EXT_BITSHIFT "
124 //"EXT_CSQC " // not ready yet
125 "FRIK_FILE "
126 "KRIMZON_SV_PARSECLIENTCOMMAND "
127 "NEH_CMD_PLAY2 "
128 "NEH_RESTOREGAME "
129 "NEXUIZ_PLAYERMODEL "
130 "NXQ_GFX_LETTERBOX "
131 "PRYDON_CLIENTCURSOR "
132 "TENEBRAE_GFX_DLIGHTS "
133 "TW_SV_STEPCONTROL "
134 ;
135
136 /*
137 =================
138 VM_SV_setorigin
139
140 This is the only valid way to move an object without using the physics of the world (setting velocity and waiting).  Directly changing origin will not set internal links correctly, so clipping would be messed up.  This should be called when an object is spawned, and then only if it is teleported.
141
142 setorigin (entity, origin)
143 =================
144 */
145 static void VM_SV_setorigin (void)
146 {
147         prvm_edict_t    *e;
148         float   *org;
149
150         VM_SAFEPARMCOUNT(2, VM_setorigin);
151
152         e = PRVM_G_EDICT(OFS_PARM0);
153         if (e == prog->edicts)
154         {
155                 VM_Warning("setorigin: can not modify world entity\n");
156                 return;
157         }
158         if (e->priv.server->free)
159         {
160                 VM_Warning("setorigin: can not modify free entity\n");
161                 return;
162         }
163         org = PRVM_G_VECTOR(OFS_PARM1);
164         VectorCopy (org, e->fields.server->origin);
165         SV_LinkEdict (e, false);
166 }
167
168
169 void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
170 {
171         int             i;
172
173         for (i=0 ; i<3 ; i++)
174                 if (min[i] > max[i])
175                         PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
176
177 // set derived values
178         VectorCopy (min, e->fields.server->mins);
179         VectorCopy (max, e->fields.server->maxs);
180         VectorSubtract (max, min, e->fields.server->size);
181
182         SV_LinkEdict (e, false);
183 }
184
185 /*
186 =================
187 VM_SV_setsize
188
189 the size box is rotated by the current angle
190 LordHavoc: no it isn't...
191
192 setsize (entity, minvector, maxvector)
193 =================
194 */
195 static void VM_SV_setsize (void)
196 {
197         prvm_edict_t    *e;
198         float   *min, *max;
199
200         VM_SAFEPARMCOUNT(3, VM_setsize);
201
202         e = PRVM_G_EDICT(OFS_PARM0);
203         if (e == prog->edicts)
204         {
205                 VM_Warning("setsize: can not modify world entity\n");
206                 return;
207         }
208         if (e->priv.server->free)
209         {
210                 VM_Warning("setsize: can not modify free entity\n");
211                 return;
212         }
213         min = PRVM_G_VECTOR(OFS_PARM1);
214         max = PRVM_G_VECTOR(OFS_PARM2);
215         SetMinMaxSize (e, min, max, false);
216 }
217
218
219 /*
220 =================
221 VM_SV_setmodel
222
223 setmodel(entity, model)
224 =================
225 */
226 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
227 static void VM_SV_setmodel (void)
228 {
229         prvm_edict_t    *e;
230         model_t *mod;
231         int             i;
232
233         VM_SAFEPARMCOUNT(2, VM_setmodel);
234
235         e = PRVM_G_EDICT(OFS_PARM0);
236         if (e == prog->edicts)
237         {
238                 VM_Warning("setmodel: can not modify world entity\n");
239                 return;
240         }
241         if (e->priv.server->free)
242         {
243                 VM_Warning("setmodel: can not modify free entity\n");
244                 return;
245         }
246         i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
247         e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
248         e->fields.server->modelindex = i;
249
250         mod = sv.models[i];
251
252         if (mod)
253         {
254                 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
255                         SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
256                 else
257                         SetMinMaxSize (e, quakemins, quakemaxs, true);
258         }
259         else
260                 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
261 }
262
263 /*
264 =================
265 VM_SV_sprint
266
267 single print to a specific client
268
269 sprint(clientent, value)
270 =================
271 */
272 static void VM_SV_sprint (void)
273 {
274         client_t        *client;
275         int                     entnum;
276         char string[VM_STRINGTEMP_LENGTH];
277
278         VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
279
280         entnum = PRVM_G_EDICTNUM(OFS_PARM0);
281
282         if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
283         {
284                 VM_Warning("tried to centerprint to a non-client\n");
285                 return;
286         }
287
288         client = svs.clients + entnum-1;
289         if (!client->netconnection)
290                 return;
291
292         VM_VarString(1, string, sizeof(string));
293         MSG_WriteChar(&client->netconnection->message,svc_print);
294         MSG_WriteString(&client->netconnection->message, string);
295 }
296
297
298 /*
299 =================
300 VM_SV_centerprint
301
302 single print to a specific client
303
304 centerprint(clientent, value)
305 =================
306 */
307 static void VM_SV_centerprint (void)
308 {
309         client_t        *client;
310         int                     entnum;
311         char string[VM_STRINGTEMP_LENGTH];
312
313         VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
314
315         entnum = PRVM_G_EDICTNUM(OFS_PARM0);
316
317         if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
318         {
319                 VM_Warning("tried to centerprint to a non-client\n");
320                 return;
321         }
322
323         client = svs.clients + entnum-1;
324         if (!client->netconnection)
325                 return;
326
327         VM_VarString(1, string, sizeof(string));
328         MSG_WriteChar(&client->netconnection->message,svc_centerprint);
329         MSG_WriteString(&client->netconnection->message, string);
330 }
331
332 /*
333 =================
334 VM_SV_particle
335
336 particle(origin, color, count)
337 =================
338 */
339 static void VM_SV_particle (void)
340 {
341         float           *org, *dir;
342         float           color;
343         float           count;
344
345         VM_SAFEPARMCOUNT(4, VM_SV_particle);
346
347         org = PRVM_G_VECTOR(OFS_PARM0);
348         dir = PRVM_G_VECTOR(OFS_PARM1);
349         color = PRVM_G_FLOAT(OFS_PARM2);
350         count = PRVM_G_FLOAT(OFS_PARM3);
351         SV_StartParticle (org, dir, (int)color, (int)count);
352 }
353
354
355 /*
356 =================
357 VM_SV_ambientsound
358
359 =================
360 */
361 static void VM_SV_ambientsound (void)
362 {
363         const char      *samp;
364         float           *pos;
365         float           vol, attenuation;
366         int                     soundnum, large;
367
368         VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
369
370         pos = PRVM_G_VECTOR (OFS_PARM0);
371         samp = PRVM_G_STRING(OFS_PARM1);
372         vol = PRVM_G_FLOAT(OFS_PARM2);
373         attenuation = PRVM_G_FLOAT(OFS_PARM3);
374
375 // check to see if samp was properly precached
376         soundnum = SV_SoundIndex(samp, 1);
377         if (!soundnum)
378                 return;
379
380         large = false;
381         if (soundnum >= 256)
382                 large = true;
383
384         // add an svc_spawnambient command to the level signon packet
385
386         if (large)
387                 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
388         else
389                 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
390
391         MSG_WriteVector(&sv.signon, pos, sv.protocol);
392
393         if (large)
394                 MSG_WriteShort (&sv.signon, soundnum);
395         else
396                 MSG_WriteByte (&sv.signon, soundnum);
397
398         MSG_WriteByte (&sv.signon, (int)(vol*255));
399         MSG_WriteByte (&sv.signon, (int)(attenuation*64));
400
401 }
402
403 /*
404 =================
405 VM_SV_sound
406
407 Each entity can have eight independant sound sources, like voice,
408 weapon, feet, etc.
409
410 Channel 0 is an auto-allocate channel, the others override anything
411 already running on that entity/channel pair.
412
413 An attenuation of 0 will play full volume everywhere in the level.
414 Larger attenuations will drop off.
415
416 =================
417 */
418 static void VM_SV_sound (void)
419 {
420         const char      *sample;
421         int                     channel;
422         prvm_edict_t            *entity;
423         int             volume;
424         float attenuation;
425
426         VM_SAFEPARMCOUNT(5, VM_SV_sound);
427
428         entity = PRVM_G_EDICT(OFS_PARM0);
429         channel = (int)PRVM_G_FLOAT(OFS_PARM1);
430         sample = PRVM_G_STRING(OFS_PARM2);
431         volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
432         attenuation = PRVM_G_FLOAT(OFS_PARM4);
433
434         if (volume < 0 || volume > 255)
435         {
436                 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
437                 return;
438         }
439
440         if (attenuation < 0 || attenuation > 4)
441         {
442                 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
443                 return;
444         }
445
446         if (channel < 0 || channel > 7)
447         {
448                 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
449                 return;
450         }
451
452         SV_StartSound (entity, channel, sample, volume, attenuation);
453 }
454
455 /*
456 =================
457 VM_SV_traceline
458
459 Used for use tracing and shot targeting
460 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
461 if the tryents flag is set.
462
463 traceline (vector1, vector2, movetype, ignore)
464 =================
465 */
466 static void VM_SV_traceline (void)
467 {
468         float   *v1, *v2;
469         trace_t trace;
470         int             move;
471         prvm_edict_t    *ent;
472
473         VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
474
475         prog->xfunction->builtinsprofile += 30;
476
477         v1 = PRVM_G_VECTOR(OFS_PARM0);
478         v2 = PRVM_G_VECTOR(OFS_PARM1);
479         move = (int)PRVM_G_FLOAT(OFS_PARM2);
480         ent = PRVM_G_EDICT(OFS_PARM3);
481
482         if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
483                 PRVM_ERROR("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
484
485         trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
486
487         VM_SetTraceGlobals(&trace);
488 }
489
490
491 /*
492 =================
493 VM_SV_tracebox
494
495 Used for use tracing and shot targeting
496 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
497 if the tryents flag is set.
498
499 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
500 =================
501 */
502 // LordHavoc: added this for my own use, VERY useful, similar to traceline
503 static void VM_SV_tracebox (void)
504 {
505         float   *v1, *v2, *m1, *m2;
506         trace_t trace;
507         int             move;
508         prvm_edict_t    *ent;
509
510         VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
511
512         prog->xfunction->builtinsprofile += 30;
513
514         v1 = PRVM_G_VECTOR(OFS_PARM0);
515         m1 = PRVM_G_VECTOR(OFS_PARM1);
516         m2 = PRVM_G_VECTOR(OFS_PARM2);
517         v2 = PRVM_G_VECTOR(OFS_PARM3);
518         move = (int)PRVM_G_FLOAT(OFS_PARM4);
519         ent = PRVM_G_EDICT(OFS_PARM5);
520
521         if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
522                 PRVM_ERROR("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
523
524         trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
525
526         VM_SetTraceGlobals(&trace);
527 }
528
529 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
530 {
531         int i;
532         float gravity;
533         vec3_t move, end;
534         vec3_t original_origin;
535         vec3_t original_velocity;
536         vec3_t original_angles;
537         vec3_t original_avelocity;
538         prvm_eval_t *val;
539         trace_t trace;
540
541         VectorCopy(tossent->fields.server->origin   , original_origin   );
542         VectorCopy(tossent->fields.server->velocity , original_velocity );
543         VectorCopy(tossent->fields.server->angles   , original_angles   );
544         VectorCopy(tossent->fields.server->avelocity, original_avelocity);
545
546         val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
547         if (val != NULL && val->_float != 0)
548                 gravity = val->_float;
549         else
550                 gravity = 1.0;
551         gravity *= sv_gravity.value * 0.05;
552
553         for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
554         {
555                 SV_CheckVelocity (tossent);
556                 tossent->fields.server->velocity[2] -= gravity;
557                 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
558                 VectorScale (tossent->fields.server->velocity, 0.05, move);
559                 VectorAdd (tossent->fields.server->origin, move, end);
560                 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
561                 VectorCopy (trace.endpos, tossent->fields.server->origin);
562
563                 if (trace.fraction < 1)
564                         break;
565         }
566
567         VectorCopy(original_origin   , tossent->fields.server->origin   );
568         VectorCopy(original_velocity , tossent->fields.server->velocity );
569         VectorCopy(original_angles   , tossent->fields.server->angles   );
570         VectorCopy(original_avelocity, tossent->fields.server->avelocity);
571
572         return trace;
573 }
574
575 static void VM_SV_tracetoss (void)
576 {
577         trace_t trace;
578         prvm_edict_t    *ent;
579         prvm_edict_t    *ignore;
580
581         VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
582
583         prog->xfunction->builtinsprofile += 600;
584
585         ent = PRVM_G_EDICT(OFS_PARM0);
586         if (ent == prog->edicts)
587         {
588                 VM_Warning("tracetoss: can not use world entity\n");
589                 return;
590         }
591         ignore = PRVM_G_EDICT(OFS_PARM1);
592
593         trace = SV_Trace_Toss (ent, ignore);
594
595         VM_SetTraceGlobals(&trace);
596 }
597
598 //============================================================================
599
600 static int checkpvsbytes;
601 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
602
603 static int VM_SV_newcheckclient (int check)
604 {
605         int             i;
606         prvm_edict_t    *ent;
607         vec3_t  org;
608
609 // cycle to the next one
610
611         check = bound(1, check, svs.maxclients);
612         if (check == svs.maxclients)
613                 i = 1;
614         else
615                 i = check + 1;
616
617         for ( ;  ; i++)
618         {
619                 // count the cost
620                 prog->xfunction->builtinsprofile++;
621                 // wrap around
622                 if (i == svs.maxclients+1)
623                         i = 1;
624                 // look up the client's edict
625                 ent = PRVM_EDICT_NUM(i);
626                 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
627                 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
628                         continue;
629                 // found a valid client (possibly the same one again)
630                 break;
631         }
632
633 // get the PVS for the entity
634         VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
635         checkpvsbytes = 0;
636         if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
637                 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
638
639         return i;
640 }
641
642 /*
643 =================
644 VM_SV_checkclient
645
646 Returns a client (or object that has a client enemy) that would be a
647 valid target.
648
649 If there is more than one valid option, they are cycled each frame
650
651 If (self.origin + self.viewofs) is not in the PVS of the current target,
652 it is not returned at all.
653
654 name checkclient ()
655 =================
656 */
657 int c_invis, c_notvis;
658 static void VM_SV_checkclient (void)
659 {
660         prvm_edict_t    *ent, *self;
661         vec3_t  view;
662
663         VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
664
665         // find a new check if on a new frame
666         if (sv.time - sv.lastchecktime >= 0.1)
667         {
668                 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
669                 sv.lastchecktime = sv.time;
670         }
671
672         // return check if it might be visible
673         ent = PRVM_EDICT_NUM(sv.lastcheck);
674         if (ent->priv.server->free || ent->fields.server->health <= 0)
675         {
676                 VM_RETURN_EDICT(prog->edicts);
677                 return;
678         }
679
680         // if current entity can't possibly see the check entity, return 0
681         self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
682         VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
683         if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
684         {
685                 c_notvis++;
686                 VM_RETURN_EDICT(prog->edicts);
687                 return;
688         }
689
690         // might be able to see it
691         c_invis++;
692         VM_RETURN_EDICT(ent);
693 }
694
695 //============================================================================
696
697
698 /*
699 =================
700 VM_SV_stuffcmd
701
702 Sends text over to the client's execution buffer
703
704 stuffcmd (clientent, value, ...)
705 =================
706 */
707 static void VM_SV_stuffcmd (void)
708 {
709         int             entnum;
710         client_t        *old;
711         char    string[VM_STRINGTEMP_LENGTH];
712
713         VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
714
715         entnum = PRVM_G_EDICTNUM(OFS_PARM0);
716         if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
717         {
718                 VM_Warning("Can't stuffcmd to a non-client\n");
719                 return;
720         }
721
722         VM_VarString(1, string, sizeof(string));
723
724         old = host_client;
725         host_client = svs.clients + entnum-1;
726         Host_ClientCommands ("%s", string);
727         host_client = old;
728 }
729
730 /*
731 =================
732 VM_SV_findradius
733
734 Returns a chain of entities that have origins within a spherical area
735
736 findradius (origin, radius)
737 =================
738 */
739 static void VM_SV_findradius (void)
740 {
741         prvm_edict_t *ent, *chain;
742         vec_t radius, radius2;
743         vec3_t org, eorg, mins, maxs;
744         int i;
745         int numtouchedicts;
746         prvm_edict_t *touchedicts[MAX_EDICTS];
747
748         VM_SAFEPARMCOUNT(2, VM_SV_findradius);
749
750         chain = (prvm_edict_t *)prog->edicts;
751
752         VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
753         radius = PRVM_G_FLOAT(OFS_PARM1);
754         radius2 = radius * radius;
755
756         mins[0] = org[0] - (radius + 1);
757         mins[1] = org[1] - (radius + 1);
758         mins[2] = org[2] - (radius + 1);
759         maxs[0] = org[0] + (radius + 1);
760         maxs[1] = org[1] + (radius + 1);
761         maxs[2] = org[2] + (radius + 1);
762         numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
763         if (numtouchedicts > MAX_EDICTS)
764         {
765                 // this never happens
766                 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
767                 numtouchedicts = MAX_EDICTS;
768         }
769         for (i = 0;i < numtouchedicts;i++)
770         {
771                 ent = touchedicts[i];
772                 prog->xfunction->builtinsprofile++;
773                 // Quake did not return non-solid entities but darkplaces does
774                 // (note: this is the reason you can't blow up fallen zombies)
775                 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
776                         continue;
777                 // LordHavoc: compare against bounding box rather than center so it
778                 // doesn't miss large objects, and use DotProduct instead of Length
779                 // for a major speedup
780                 VectorSubtract(org, ent->fields.server->origin, eorg);
781                 if (sv_gameplayfix_findradiusdistancetobox.integer)
782                 {
783                         eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
784                         eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
785                         eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
786                 }
787                 else
788                         VectorMAMAM(1, eorg, 0.5f, ent->fields.server->mins, 0.5f, ent->fields.server->maxs, eorg);
789                 if (DotProduct(eorg, eorg) < radius2)
790                 {
791                         ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
792                         chain = ent;
793                 }
794         }
795
796         VM_RETURN_EDICT(chain);
797 }
798
799 static void VM_SV_precache_sound (void)
800 {
801         VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
802         SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
803         PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
804 }
805
806 static void VM_SV_precache_model (void)
807 {
808         VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
809         SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
810         PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
811 }
812
813 /*
814 ===============
815 VM_SV_walkmove
816
817 float(float yaw, float dist[, settrace]) walkmove
818 ===============
819 */
820 static void VM_SV_walkmove (void)
821 {
822         prvm_edict_t    *ent;
823         float   yaw, dist;
824         vec3_t  move;
825         mfunction_t     *oldf;
826         int     oldself;
827         qboolean        settrace;
828
829         VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
830
831         // assume failure if it returns early
832         PRVM_G_FLOAT(OFS_RETURN) = 0;
833
834         ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
835         if (ent == prog->edicts)
836         {
837                 VM_Warning("walkmove: can not modify world entity\n");
838                 return;
839         }
840         if (ent->priv.server->free)
841         {
842                 VM_Warning("walkmove: can not modify free entity\n");
843                 return;
844         }
845         yaw = PRVM_G_FLOAT(OFS_PARM0);
846         dist = PRVM_G_FLOAT(OFS_PARM1);
847         settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
848
849         if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
850                 return;
851
852         yaw = yaw*M_PI*2 / 360;
853
854         move[0] = cos(yaw)*dist;
855         move[1] = sin(yaw)*dist;
856         move[2] = 0;
857
858 // save program state, because SV_movestep may call other progs
859         oldf = prog->xfunction;
860         oldself = prog->globals.server->self;
861
862         PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
863
864
865 // restore program state
866         prog->xfunction = oldf;
867         prog->globals.server->self = oldself;
868 }
869
870 /*
871 ===============
872 VM_SV_droptofloor
873
874 void() droptofloor
875 ===============
876 */
877 static void VM_SV_droptofloor (void)
878 {
879         prvm_edict_t            *ent;
880         vec3_t          end;
881         trace_t         trace;
882
883         VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
884
885         // assume failure if it returns early
886         PRVM_G_FLOAT(OFS_RETURN) = 0;
887
888         ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
889         if (ent == prog->edicts)
890         {
891                 VM_Warning("droptofloor: can not modify world entity\n");
892                 return;
893         }
894         if (ent->priv.server->free)
895         {
896                 VM_Warning("droptofloor: can not modify free entity\n");
897                 return;
898         }
899
900         VectorCopy (ent->fields.server->origin, end);
901         end[2] -= 256;
902
903         trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
904
905         if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
906         {
907                 if (trace.fraction < 1)
908                         VectorCopy (trace.endpos, ent->fields.server->origin);
909                 SV_LinkEdict (ent, false);
910                 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
911                 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
912                 PRVM_G_FLOAT(OFS_RETURN) = 1;
913                 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
914                 ent->priv.server->suspendedinairflag = true;
915         }
916 }
917
918 /*
919 ===============
920 VM_SV_lightstyle
921
922 void(float style, string value) lightstyle
923 ===============
924 */
925 static void VM_SV_lightstyle (void)
926 {
927         int             style;
928         const char      *val;
929         client_t        *client;
930         int                     j;
931
932         VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
933
934         style = (int)PRVM_G_FLOAT(OFS_PARM0);
935         val = PRVM_G_STRING(OFS_PARM1);
936
937         if( (unsigned) style >= MAX_LIGHTSTYLES ) {
938                 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
939         }
940
941 // change the string in sv
942         strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
943
944 // send message to all clients on this server
945         if (sv.state != ss_active)
946                 return;
947
948         for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
949         {
950                 if (client->active && client->netconnection)
951                 {
952                         MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
953                         MSG_WriteChar (&client->netconnection->message,style);
954                         MSG_WriteString (&client->netconnection->message, val);
955                 }
956         }
957 }
958
959 /*
960 =============
961 VM_SV_checkbottom
962 =============
963 */
964 static void VM_SV_checkbottom (void)
965 {
966         VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
967         PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
968 }
969
970 /*
971 =============
972 VM_SV_pointcontents
973 =============
974 */
975 static void VM_SV_pointcontents (void)
976 {
977         VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
978         PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
979 }
980
981 /*
982 =============
983 VM_SV_aim
984
985 Pick a vector for the player to shoot along
986 vector aim(entity, missilespeed)
987 =============
988 */
989 static void VM_SV_aim (void)
990 {
991         prvm_edict_t    *ent, *check, *bestent;
992         vec3_t  start, dir, end, bestdir;
993         int             i, j;
994         trace_t tr;
995         float   dist, bestdist;
996         float   speed;
997
998         VM_SAFEPARMCOUNT(2, VM_SV_aim);
999
1000         // assume failure if it returns early
1001         VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1002         // if sv_aim is so high it can't possibly accept anything, skip out early
1003         if (sv_aim.value >= 1)
1004                 return;
1005
1006         ent = PRVM_G_EDICT(OFS_PARM0);
1007         if (ent == prog->edicts)
1008         {
1009                 VM_Warning("aim: can not use world entity\n");
1010                 return;
1011         }
1012         if (ent->priv.server->free)
1013         {
1014                 VM_Warning("aim: can not use free entity\n");
1015                 return;
1016         }
1017         speed = PRVM_G_FLOAT(OFS_PARM1);
1018
1019         VectorCopy (ent->fields.server->origin, start);
1020         start[2] += 20;
1021
1022 // try sending a trace straight
1023         VectorCopy (prog->globals.server->v_forward, dir);
1024         VectorMA (start, 2048, dir, end);
1025         tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1026         if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1027         && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1028         {
1029                 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1030                 return;
1031         }
1032
1033
1034 // try all possible entities
1035         VectorCopy (dir, bestdir);
1036         bestdist = sv_aim.value;
1037         bestent = NULL;
1038
1039         check = PRVM_NEXT_EDICT(prog->edicts);
1040         for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1041         {
1042                 prog->xfunction->builtinsprofile++;
1043                 if (check->fields.server->takedamage != DAMAGE_AIM)
1044                         continue;
1045                 if (check == ent)
1046                         continue;
1047                 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1048                         continue;       // don't aim at teammate
1049                 for (j=0 ; j<3 ; j++)
1050                         end[j] = check->fields.server->origin[j]
1051                         + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1052                 VectorSubtract (end, start, dir);
1053                 VectorNormalize (dir);
1054                 dist = DotProduct (dir, prog->globals.server->v_forward);
1055                 if (dist < bestdist)
1056                         continue;       // to far to turn
1057                 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1058                 if (tr.ent == check)
1059                 {       // can shoot at this one
1060                         bestdist = dist;
1061                         bestent = check;
1062                 }
1063         }
1064
1065         if (bestent)
1066         {
1067                 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1068                 dist = DotProduct (dir, prog->globals.server->v_forward);
1069                 VectorScale (prog->globals.server->v_forward, dist, end);
1070                 end[2] = dir[2];
1071                 VectorNormalize (end);
1072                 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1073         }
1074         else
1075         {
1076                 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1077         }
1078 }
1079
1080 /*
1081 ===============================================================================
1082
1083 MESSAGE WRITING
1084
1085 ===============================================================================
1086 */
1087
1088 #define MSG_BROADCAST   0               // unreliable to all
1089 #define MSG_ONE                 1               // reliable to one (msg_entity)
1090 #define MSG_ALL                 2               // reliable to all
1091 #define MSG_INIT                3               // write to the init string
1092 #define MSG_ENTITY              5
1093
1094 sizebuf_t *WriteDest (void)
1095 {
1096         int             entnum;
1097         int             dest;
1098         prvm_edict_t    *ent;
1099         extern sizebuf_t *sv2csqcbuf;
1100
1101         dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1102         switch (dest)
1103         {
1104         case MSG_BROADCAST:
1105                 return &sv.datagram;
1106
1107         case MSG_ONE:
1108                 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1109                 entnum = PRVM_NUM_FOR_EDICT(ent);
1110                 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1111                 {
1112                         VM_Warning ("WriteDest: tried to write to non-client\n");
1113                         return &sv.reliable_datagram;
1114                 }
1115                 else
1116                         return &svs.clients[entnum-1].netconnection->message;
1117
1118         default:
1119                 VM_Warning ("WriteDest: bad destination\n");
1120         case MSG_ALL:
1121                 return &sv.reliable_datagram;
1122
1123         case MSG_INIT:
1124                 return &sv.signon;
1125
1126         case MSG_ENTITY:
1127                 return sv2csqcbuf;
1128         }
1129
1130         return NULL;
1131 }
1132
1133 static void VM_SV_WriteByte (void)
1134 {
1135         VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1136         MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1137 }
1138
1139 static void VM_SV_WriteChar (void)
1140 {
1141         VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1142         MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1143 }
1144
1145 static void VM_SV_WriteShort (void)
1146 {
1147         VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1148         MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1149 }
1150
1151 static void VM_SV_WriteLong (void)
1152 {
1153         VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1154         MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1155 }
1156
1157 static void VM_SV_WriteAngle (void)
1158 {
1159         VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1160         MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1161 }
1162
1163 static void VM_SV_WriteCoord (void)
1164 {
1165         VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1166         MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1167 }
1168
1169 static void VM_SV_WriteString (void)
1170 {
1171         VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1172         MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1173 }
1174
1175 static void VM_SV_WriteUnterminatedString (void)
1176 {
1177         VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1178         MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1179 }
1180
1181
1182 static void VM_SV_WriteEntity (void)
1183 {
1184         VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1185         MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1186 }
1187
1188 //////////////////////////////////////////////////////////
1189
1190 static void VM_SV_makestatic (void)
1191 {
1192         prvm_edict_t *ent;
1193         int i, large;
1194
1195         // allow 0 parameters due to an id1 qc bug in which this function is used
1196         // with no parameters (but directly after setmodel with self in OFS_PARM0)
1197         VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1198
1199         if (prog->argc >= 1)
1200                 ent = PRVM_G_EDICT(OFS_PARM0);
1201         else
1202                 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1203         if (ent == prog->edicts)
1204         {
1205                 VM_Warning("makestatic: can not modify world entity\n");
1206                 return;
1207         }
1208         if (ent->priv.server->free)
1209         {
1210                 VM_Warning("makestatic: can not modify free entity\n");
1211                 return;
1212         }
1213
1214         large = false;
1215         if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1216                 large = true;
1217
1218         if (large)
1219         {
1220                 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1221                 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1222                 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1223         }
1224         else
1225         {
1226                 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1227                 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1228                 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1229         }
1230
1231         MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1232         MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1233         for (i=0 ; i<3 ; i++)
1234         {
1235                 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1236                 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1237         }
1238
1239 // throw the entity away now
1240         PRVM_ED_Free (ent);
1241 }
1242
1243 //=============================================================================
1244
1245 /*
1246 ==============
1247 VM_SV_setspawnparms
1248 ==============
1249 */
1250 static void VM_SV_setspawnparms (void)
1251 {
1252         prvm_edict_t    *ent;
1253         int             i;
1254         client_t        *client;
1255
1256         VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1257
1258         ent = PRVM_G_EDICT(OFS_PARM0);
1259         i = PRVM_NUM_FOR_EDICT(ent);
1260         if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1261         {
1262                 Con_Print("tried to setspawnparms on a non-client\n");
1263                 return;
1264         }
1265
1266         // copy spawn parms out of the client_t
1267         client = svs.clients + i-1;
1268         for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1269                 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1270 }
1271
1272 /*
1273 =================
1274 VM_SV_getlight
1275
1276 Returns a color vector indicating the lighting at the requested point.
1277
1278 (Internal Operation note: actually measures the light beneath the point, just like
1279                           the model lighting on the client)
1280
1281 getlight(vector)
1282 =================
1283 */
1284 static void VM_SV_getlight (void)
1285 {
1286         vec3_t ambientcolor, diffusecolor, diffusenormal;
1287         vec_t *p;
1288         VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1289         p = PRVM_G_VECTOR(OFS_PARM0);
1290         VectorClear(ambientcolor);
1291         VectorClear(diffusecolor);
1292         VectorClear(diffusenormal);
1293         if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1294                 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1295         VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1296 }
1297
1298 typedef struct
1299 {
1300         unsigned char   type;   // 1/2/8 or other value if isn't used
1301         int             fieldoffset;
1302 }autosentstat_t;
1303
1304 static autosentstat_t *vm_autosentstats = NULL; //[515]: it starts from 0, not 32
1305 static int vm_autosentstats_last;
1306
1307 void VM_AutoSentStats_Clear (void)
1308 {
1309         if(vm_autosentstats)
1310         {
1311                 Z_Free(vm_autosentstats);
1312                 vm_autosentstats = NULL;
1313                 vm_autosentstats_last = -1;
1314         }
1315 }
1316
1317 //[515]: add check if even bigger ? "try to use two stats, cause it's too big" ?
1318 #define VM_SENDSTAT(a,b,c)\
1319 {\
1320 /*      if((c))*/\
1321         if((c)==(unsigned char)(c))\
1322         {\
1323                 MSG_WriteByte((a), svc_updatestatubyte);\
1324                 MSG_WriteByte((a), (b));\
1325                 MSG_WriteByte((a), (c));\
1326         }\
1327         else\
1328         {\
1329                 MSG_WriteByte((a), svc_updatestat);\
1330                 MSG_WriteByte((a), (b));\
1331                 MSG_WriteLong((a), (c));\
1332         }\
1333 }\
1334
1335 void VM_SV_WriteAutoSentStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1336 {
1337         int                     i, v, *si;
1338         char            s[17];
1339         const char      *t;
1340         qboolean        send;
1341         union
1342         {
1343                 float   f;
1344                 int             i;
1345         }k;
1346
1347         if(!vm_autosentstats)
1348                 return;
1349
1350         send = (sv.protocol != PROTOCOL_QUAKE && sv.protocol != PROTOCOL_QUAKEDP && sv.protocol != PROTOCOL_NEHAHRAMOVIE && sv.protocol != PROTOCOL_DARKPLACES1 && sv.protocol != PROTOCOL_DARKPLACES2 && sv.protocol != PROTOCOL_DARKPLACES3 && sv.protocol != PROTOCOL_DARKPLACES4 && sv.protocol != PROTOCOL_DARKPLACES5);
1351
1352         for(i=0; i<vm_autosentstats_last+1 ;i++)
1353         {
1354                 if(!vm_autosentstats[i].type)
1355                         continue;
1356                 switch(vm_autosentstats[i].type)
1357                 {
1358                 //string
1359                 case 1:
1360                         t = PRVM_E_STRING(ent, vm_autosentstats[i].fieldoffset);
1361                         if(t && t[0])
1362                         {
1363                                 memset(s, 0, 17);
1364                                 strlcpy(s, t, 16);
1365                                 si = (int*)s;
1366                                 if (!send)
1367                                 {
1368                                         stats[i+32] = si[0];
1369                                         stats[i+33] = si[1];
1370                                         stats[i+34] = si[2];
1371                                         stats[i+35] = si[3];
1372                                 }
1373                                 else
1374                                 {
1375                                         VM_SENDSTAT(msg, i+32, si[0]);
1376                                         VM_SENDSTAT(msg, i+33, si[1]);
1377                                         VM_SENDSTAT(msg, i+34, si[2]);
1378                                         VM_SENDSTAT(msg, i+35, si[3]);
1379                                 }
1380                         }
1381                         break;
1382                 //float
1383                 case 2:
1384                         k.f = PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset);       //[515]: use PRVM_E_INT ?
1385                         k.i = LittleLong (k.i);
1386                         if (!send)
1387                                 stats[i+32] = k.i;
1388                         else
1389                                 VM_SENDSTAT(msg, i+32, k.i);
1390                         break;
1391                 //integer
1392                 case 8:
1393                         v = (int)PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset);    //[515]: use PRVM_E_INT ?
1394                         if (!send)
1395                                 stats[i+32] = v;
1396                         else
1397                                 VM_SENDSTAT(msg, i+32, v);
1398                         break;
1399                 default:
1400                         break;
1401                 }
1402         }
1403 }
1404
1405 // void(float index, float type, .void field) SV_AddStat = #232;
1406 // Set up an auto-sent player stat.
1407 // Client's get thier own fields sent to them. Index may not be less than 32.
1408 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1409 //          1: string (4 stats carrying a total of 16 charactures)
1410 //          2: float (one stat, float converted to an integer for transportation)
1411 //          8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1412 static void VM_SV_AddStat (void)
1413 {
1414         int             off, i;
1415         unsigned char   type;
1416
1417         VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1418
1419         if(!vm_autosentstats)
1420         {
1421                 vm_autosentstats = (autosentstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(autosentstat_t));
1422                 if(!vm_autosentstats)
1423                 {
1424                         VM_Warning("PF_SV_AddStat: not enough memory\n");
1425                         return;
1426                 }
1427         }
1428         i               = (int)PRVM_G_FLOAT(OFS_PARM0);
1429         type    = (int)PRVM_G_FLOAT(OFS_PARM1);
1430         off             = PRVM_G_INT  (OFS_PARM2);
1431         i -= 32;
1432
1433         if(i < 0)
1434         {
1435                 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1436                 return;
1437         }
1438         if(i >= (MAX_CL_STATS-32))
1439         {
1440                 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1441                 return;
1442         }
1443         if(i > (MAX_CL_STATS-32-4) && type == 1)
1444         {
1445                 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1446                 return;
1447         }
1448         vm_autosentstats[i].type                = type;
1449         vm_autosentstats[i].fieldoffset = off;
1450         if(vm_autosentstats_last < i)
1451                 vm_autosentstats_last = i;
1452 }
1453
1454 /*
1455 =================
1456 VM_SV_copyentity
1457
1458 copies data from one entity to another
1459
1460 copyentity(src, dst)
1461 =================
1462 */
1463 static void VM_SV_copyentity (void)
1464 {
1465         prvm_edict_t *in, *out;
1466         VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1467         in = PRVM_G_EDICT(OFS_PARM0);
1468         if (in == prog->edicts)
1469         {
1470                 VM_Warning("copyentity: can not read world entity\n");
1471                 return;
1472         }
1473         if (in->priv.server->free)
1474         {
1475                 VM_Warning("copyentity: can not read free entity\n");
1476                 return;
1477         }
1478         out = PRVM_G_EDICT(OFS_PARM1);
1479         if (out == prog->edicts)
1480         {
1481                 VM_Warning("copyentity: can not modify world entity\n");
1482                 return;
1483         }
1484         if (out->priv.server->free)
1485         {
1486                 VM_Warning("copyentity: can not modify free entity\n");
1487                 return;
1488         }
1489         memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1490         SV_LinkEdict(out, false);
1491 }
1492
1493
1494 /*
1495 =================
1496 VM_SV_setcolor
1497
1498 sets the color of a client and broadcasts the update to all connected clients
1499
1500 setcolor(clientent, value)
1501 =================
1502 */
1503 static void VM_SV_setcolor (void)
1504 {
1505         client_t *client;
1506         int entnum, i;
1507         prvm_eval_t *val;
1508
1509         VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1510         entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1511         i = (int)PRVM_G_FLOAT(OFS_PARM1);
1512
1513         if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1514         {
1515                 Con_Print("tried to setcolor a non-client\n");
1516                 return;
1517         }
1518
1519         client = svs.clients + entnum-1;
1520         if (client->edict)
1521         {
1522                 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1523                         val->_float = i;
1524                 client->edict->fields.server->team = (i & 15) + 1;
1525         }
1526         client->colors = i;
1527         if (client->old_colors != client->colors)
1528         {
1529                 client->old_colors = client->colors;
1530                 // send notification to all clients
1531                 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1532                 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1533                 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1534         }
1535 }
1536
1537 /*
1538 =================
1539 VM_SV_effect
1540
1541 effect(origin, modelname, startframe, framecount, framerate)
1542 =================
1543 */
1544 static void VM_SV_effect (void)
1545 {
1546         int i;
1547         const char *s;
1548         VM_SAFEPARMCOUNT(5, VM_SV_effect);
1549         s = PRVM_G_STRING(OFS_PARM1);
1550         if (!s[0])
1551         {
1552                 VM_Warning("effect: no model specified\n");
1553                 return;
1554         }
1555
1556         i = SV_ModelIndex(s, 1);
1557         if (!i)
1558         {
1559                 VM_Warning("effect: model not precached\n");
1560                 return;
1561         }
1562
1563         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1564         {
1565                 VM_Warning("effect: framecount < 1\n");
1566                 return;
1567         }
1568
1569         if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1570         {
1571                 VM_Warning("effect: framerate < 1\n");
1572                 return;
1573         }
1574
1575         SV_StartEffect(PRVM_G_VECTOR(OFS_PARM0), i, (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4));
1576 }
1577
1578 static void VM_SV_te_blood (void)
1579 {
1580         VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1581         if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1582                 return;
1583         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1584         MSG_WriteByte(&sv.datagram, TE_BLOOD);
1585         // origin
1586         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1587         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1588         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1589         // velocity
1590         MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1591         MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1592         MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1593         // count
1594         MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1595 }
1596
1597 static void VM_SV_te_bloodshower (void)
1598 {
1599         VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1600         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1601                 return;
1602         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1603         MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1604         // min
1605         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1606         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1607         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1608         // max
1609         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1610         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1611         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1612         // speed
1613         MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1614         // count
1615         MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1616 }
1617
1618 static void VM_SV_te_explosionrgb (void)
1619 {
1620         VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1621         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1622         MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1623         // origin
1624         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1625         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1626         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1627         // color
1628         MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1629         MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1630         MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1631 }
1632
1633 static void VM_SV_te_particlecube (void)
1634 {
1635         VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1636         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1637                 return;
1638         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1639         MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1640         // min
1641         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1642         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1643         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1644         // max
1645         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1646         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1647         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1648         // velocity
1649         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1650         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1651         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1652         // count
1653         MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1654         // color
1655         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1656         // gravity true/false
1657         MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1658         // randomvel
1659         MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1660 }
1661
1662 static void VM_SV_te_particlerain (void)
1663 {
1664         VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1665         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1666                 return;
1667         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1668         MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1669         // min
1670         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1671         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1672         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1673         // max
1674         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1675         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1676         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1677         // velocity
1678         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1679         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1680         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1681         // count
1682         MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1683         // color
1684         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1685 }
1686
1687 static void VM_SV_te_particlesnow (void)
1688 {
1689         VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1690         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1691                 return;
1692         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1693         MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1694         // min
1695         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1696         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1697         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1698         // max
1699         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1700         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1701         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1702         // velocity
1703         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1704         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1705         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1706         // count
1707         MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1708         // color
1709         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1710 }
1711
1712 static void VM_SV_te_spark (void)
1713 {
1714         VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1715         if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1716                 return;
1717         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1718         MSG_WriteByte(&sv.datagram, TE_SPARK);
1719         // origin
1720         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1721         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1722         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1723         // velocity
1724         MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1725         MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1726         MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1727         // count
1728         MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1729 }
1730
1731 static void VM_SV_te_gunshotquad (void)
1732 {
1733         VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1734         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1735         MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1736         // origin
1737         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1738         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1739         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1740 }
1741
1742 static void VM_SV_te_spikequad (void)
1743 {
1744         VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1745         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1746         MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1747         // origin
1748         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1749         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1750         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1751 }
1752
1753 static void VM_SV_te_superspikequad (void)
1754 {
1755         VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1756         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1757         MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1758         // origin
1759         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1760         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1761         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1762 }
1763
1764 static void VM_SV_te_explosionquad (void)
1765 {
1766         VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1767         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1768         MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1769         // origin
1770         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1771         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1772         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1773 }
1774
1775 static void VM_SV_te_smallflash (void)
1776 {
1777         VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1778         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1779         MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1780         // origin
1781         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1782         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1783         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1784 }
1785
1786 static void VM_SV_te_customflash (void)
1787 {
1788         VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1789         if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1790                 return;
1791         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1792         MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1793         // origin
1794         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1795         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1796         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1797         // radius
1798         MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1799         // lifetime
1800         MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1801         // color
1802         MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1803         MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1804         MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1805 }
1806
1807 static void VM_SV_te_gunshot (void)
1808 {
1809         VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1810         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1811         MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1812         // origin
1813         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1814         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1815         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1816 }
1817
1818 static void VM_SV_te_spike (void)
1819 {
1820         VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1821         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1822         MSG_WriteByte(&sv.datagram, TE_SPIKE);
1823         // origin
1824         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1825         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1826         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1827 }
1828
1829 static void VM_SV_te_superspike (void)
1830 {
1831         VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1832         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1833         MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1834         // origin
1835         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1836         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1837         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1838 }
1839
1840 static void VM_SV_te_explosion (void)
1841 {
1842         VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1843         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1844         MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1845         // origin
1846         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1847         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1848         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1849 }
1850
1851 static void VM_SV_te_tarexplosion (void)
1852 {
1853         VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1854         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1855         MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1856         // origin
1857         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1858         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1859         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1860 }
1861
1862 static void VM_SV_te_wizspike (void)
1863 {
1864         VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1865         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1866         MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1867         // origin
1868         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1869         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1870         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1871 }
1872
1873 static void VM_SV_te_knightspike (void)
1874 {
1875         VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1876         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1877         MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1878         // origin
1879         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1880         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1881         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1882 }
1883
1884 static void VM_SV_te_lavasplash (void)
1885 {
1886         VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1887         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1888         MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1889         // origin
1890         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1891         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1892         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1893 }
1894
1895 static void VM_SV_te_teleport (void)
1896 {
1897         VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1898         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1899         MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1900         // origin
1901         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1902         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1903         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1904 }
1905
1906 static void VM_SV_te_explosion2 (void)
1907 {
1908         VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1909         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1910         MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1911         // origin
1912         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1913         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1914         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1915         // color
1916         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1917         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1918 }
1919
1920 static void VM_SV_te_lightning1 (void)
1921 {
1922         VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1923         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1924         MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1925         // owner entity
1926         MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1927         // start
1928         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1929         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1930         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1931         // end
1932         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1933         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1934         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1935 }
1936
1937 static void VM_SV_te_lightning2 (void)
1938 {
1939         VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1940         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1941         MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1942         // owner entity
1943         MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1944         // start
1945         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1946         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1947         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1948         // end
1949         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1950         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1951         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1952 }
1953
1954 static void VM_SV_te_lightning3 (void)
1955 {
1956         VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1957         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1958         MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1959         // owner entity
1960         MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1961         // start
1962         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1963         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1964         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1965         // end
1966         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1967         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1968         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1969 }
1970
1971 static void VM_SV_te_beam (void)
1972 {
1973         VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1974         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1975         MSG_WriteByte(&sv.datagram, TE_BEAM);
1976         // owner entity
1977         MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1978         // start
1979         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1980         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1981         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1982         // end
1983         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1984         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1985         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1986 }
1987
1988 static void VM_SV_te_plasmaburn (void)
1989 {
1990         VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
1991         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1992         MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
1993         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1994         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1995         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1996 }
1997
1998 static void VM_SV_te_flamejet (void)
1999 {
2000         VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2001         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2002         MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2003         // org
2004         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2005         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2006         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2007         // vel
2008         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2009         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2010         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2011         // count
2012         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2013 }
2014
2015 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2016 {
2017         int i, j, k;
2018         float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2019         const int *e;
2020         bestdist = 1000000000;
2021         VectorCopy(p, out);
2022         for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2023         {
2024                 // clip original point to each triangle of the surface and find the
2025                 // triangle that is closest
2026                 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2027                 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2028                 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2029                 TriangleNormal(v[0], v[1], v[2], facenormal);
2030                 VectorNormalize(facenormal);
2031                 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2032                 VectorMA(p, offsetdist, facenormal, temp);
2033                 for (j = 0, k = 2;j < 3;k = j, j++)
2034                 {
2035                         VectorSubtract(v[k], v[j], edgenormal);
2036                         CrossProduct(edgenormal, facenormal, sidenormal);
2037                         VectorNormalize(sidenormal);
2038                         offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2039                         if (offsetdist < 0)
2040                                 VectorMA(temp, offsetdist, sidenormal, temp);
2041                 }
2042                 dist = VectorDistance2(temp, p);
2043                 if (bestdist > dist)
2044                 {
2045                         bestdist = dist;
2046                         VectorCopy(temp, out);
2047                 }
2048         }
2049 }
2050
2051 static model_t *getmodel(prvm_edict_t *ed)
2052 {
2053         int modelindex;
2054         if (!ed || ed->priv.server->free)
2055                 return NULL;
2056         modelindex = (int)ed->fields.server->modelindex;
2057         if (modelindex < 1 || modelindex >= MAX_MODELS)
2058                 return NULL;
2059         return sv.models[modelindex];
2060 }
2061
2062 static msurface_t *getsurface(model_t *model, int surfacenum)
2063 {
2064         if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2065                 return NULL;
2066         return model->data_surfaces + surfacenum + model->firstmodelsurface;
2067 }
2068
2069
2070 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2071 static void VM_SV_getsurfacenumpoints(void)
2072 {
2073         model_t *model;
2074         msurface_t *surface;
2075         VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2076         // return 0 if no such surface
2077         if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2078         {
2079                 PRVM_G_FLOAT(OFS_RETURN) = 0;
2080                 return;
2081         }
2082
2083         // note: this (incorrectly) assumes it is a simple polygon
2084         PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2085 }
2086 //PF_getsurfacepoint,     // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2087 static void VM_SV_getsurfacepoint(void)
2088 {
2089         prvm_edict_t *ed;
2090         model_t *model;
2091         msurface_t *surface;
2092         int pointnum;
2093         VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2094         VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2095         ed = PRVM_G_EDICT(OFS_PARM0);
2096         if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2097                 return;
2098         // note: this (incorrectly) assumes it is a simple polygon
2099         pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2100         if (pointnum < 0 || pointnum >= surface->num_vertices)
2101                 return;
2102         // FIXME: implement rotation/scaling
2103         VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2104 }
2105 //PF_getsurfacenormal,    // #436 vector(entity e, float s) getsurfacenormal = #436;
2106 static void VM_SV_getsurfacenormal(void)
2107 {
2108         model_t *model;
2109         msurface_t *surface;
2110         vec3_t normal;
2111         VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2112         VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2113         if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2114                 return;
2115         // FIXME: implement rotation/scaling
2116         // note: this (incorrectly) assumes it is a simple polygon
2117         // note: this only returns the first triangle, so it doesn't work very
2118         // well for curved surfaces or arbitrary meshes
2119         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);
2120         VectorNormalize(normal);
2121         VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2122 }
2123 //PF_getsurfacetexture,   // #437 string(entity e, float s) getsurfacetexture = #437;
2124 static void VM_SV_getsurfacetexture(void)
2125 {
2126         model_t *model;
2127         msurface_t *surface;
2128         VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2129         PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2130         if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2131                 return;
2132         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2133 }
2134 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2135 static void VM_SV_getsurfacenearpoint(void)
2136 {
2137         int surfacenum, best;
2138         vec3_t clipped, p;
2139         vec_t dist, bestdist;
2140         prvm_edict_t *ed;
2141         model_t *model;
2142         msurface_t *surface;
2143         vec_t *point;
2144         VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2145         PRVM_G_FLOAT(OFS_RETURN) = -1;
2146         ed = PRVM_G_EDICT(OFS_PARM0);
2147         point = PRVM_G_VECTOR(OFS_PARM1);
2148
2149         if (!ed || ed->priv.server->free)
2150                 return;
2151         model = getmodel(ed);
2152         if (!model || !model->num_surfaces)
2153                 return;
2154
2155         // FIXME: implement rotation/scaling
2156         VectorSubtract(point, ed->fields.server->origin, p);
2157         best = -1;
2158         bestdist = 1000000000;
2159         for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2160         {
2161                 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2162                 // first see if the nearest point on the surface's box is closer than the previous match
2163                 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2164                 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2165                 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2166                 dist = VectorLength2(clipped);
2167                 if (dist < bestdist)
2168                 {
2169                         // it is, check the nearest point on the actual geometry
2170                         clippointtosurface(model, surface, p, clipped);
2171                         VectorSubtract(clipped, p, clipped);
2172                         dist += VectorLength2(clipped);
2173                         if (dist < bestdist)
2174                         {
2175                                 // that's closer too, store it as the best match
2176                                 best = surfacenum;
2177                                 bestdist = dist;
2178                         }
2179                 }
2180         }
2181         PRVM_G_FLOAT(OFS_RETURN) = best;
2182 }
2183 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2184 static void VM_SV_getsurfaceclippedpoint(void)
2185 {
2186         prvm_edict_t *ed;
2187         model_t *model;
2188         msurface_t *surface;
2189         vec3_t p, out;
2190         VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2191         VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2192         ed = PRVM_G_EDICT(OFS_PARM0);
2193         if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2194                 return;
2195         // FIXME: implement rotation/scaling
2196         VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2197         clippointtosurface(model, surface, p, out);
2198         // FIXME: implement rotation/scaling
2199         VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2200 }
2201
2202 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2203 //this function originally written by KrimZon, made shorter by LordHavoc
2204 static void VM_SV_clientcommand (void)
2205 {
2206         client_t *temp_client;
2207         int i;
2208         VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2209
2210         //find client for this entity
2211         i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2212         if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2213         {
2214                 Con_Print("PF_clientcommand: entity is not a client\n");
2215                 return;
2216         }
2217
2218         temp_client = host_client;
2219         host_client = svs.clients + i;
2220         Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2221         host_client = temp_client;
2222 }
2223
2224 //void(entity e, entity tagentity, string tagname) setattachment = #443; // attachs e to a tag on tagentity (note: use "" to attach to entity origin/angles instead of a tag)
2225 static void VM_SV_setattachment (void)
2226 {
2227         prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2228         prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2229         const char *tagname = PRVM_G_STRING(OFS_PARM2);
2230         prvm_eval_t *v;
2231         int modelindex;
2232         model_t *model;
2233         VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2234
2235         if (e == prog->edicts)
2236         {
2237                 VM_Warning("setattachment: can not modify world entity\n");
2238                 return;
2239         }
2240         if (e->priv.server->free)
2241         {
2242                 VM_Warning("setattachment: can not modify free entity\n");
2243                 return;
2244         }
2245
2246         if (tagentity == NULL)
2247                 tagentity = prog->edicts;
2248
2249         v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2250         if (v)
2251                 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2252
2253         v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2254         if (v)
2255                 v->_float = 0;
2256         if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2257         {
2258                 modelindex = (int)tagentity->fields.server->modelindex;
2259                 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2260                 {
2261                         v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2262                         if (v->_float == 0)
2263                                 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);
2264                 }
2265                 else
2266                         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));
2267         }
2268 }
2269
2270 /////////////////////////////////////////
2271 // DP_MD3_TAGINFO extension coded by VorteX
2272
2273 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2274 {
2275         int i;
2276         model_t *model;
2277
2278         i = (int)e->fields.server->modelindex;
2279         if (i < 1 || i >= MAX_MODELS)
2280                 return -1;
2281         model = sv.models[i];
2282
2283         return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2284 };
2285
2286 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2287 {
2288         float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2289         if (scale == 0)
2290                 scale = 1;
2291         if (viewmatrix)
2292                 Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] + ent->fields.server->view_ofs[2], ent->fields.server->v_angle[0], ent->fields.server->v_angle[1], ent->fields.server->v_angle[2], scale);
2293         else
2294                 Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], -ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], scale * cl_viewmodel_scale.value);
2295 }
2296
2297 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2298 {
2299         int modelindex;
2300         int frame;
2301         model_t *model;
2302         if (tagindex >= 0
2303          && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2304          && (model = sv.models[(int)ent->fields.server->modelindex])
2305          && model->animscenes)
2306         {
2307                 // if model has wrong frame, engine automatically switches to model first frame
2308                 frame = (int)ent->fields.server->frame;
2309                 if (frame < 0 || frame >= model->numframes)
2310                         frame = 0;
2311                 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2312         }
2313         *out = identitymatrix;
2314         return 0;
2315 }
2316
2317 // Warnings/errors code:
2318 // 0 - normal (everything all-right)
2319 // 1 - world entity
2320 // 2 - free entity
2321 // 3 - null or non-precached model
2322 // 4 - no tags with requested index
2323 // 5 - runaway loop at attachment chain
2324 extern cvar_t cl_bob;
2325 extern cvar_t cl_bobcycle;
2326 extern cvar_t cl_bobup;
2327 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2328 {
2329         int ret;
2330         prvm_eval_t *val;
2331         int modelindex, attachloop;
2332         matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2333         model_t *model;
2334
2335         *out = identitymatrix; // warnings and errors return identical matrix
2336
2337         if (ent == prog->edicts)
2338                 return 1;
2339         if (ent->priv.server->free)
2340                 return 2;
2341
2342         modelindex = (int)ent->fields.server->modelindex;
2343         if (modelindex <= 0 || modelindex > MAX_MODELS)
2344                 return 3;
2345
2346         model = sv.models[modelindex];
2347
2348         tagmatrix = identitymatrix;
2349         // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2350         attachloop = 0;
2351         for (;;)
2352         {
2353                 if (attachloop >= 256) // prevent runaway looping
2354                         return 5;
2355                 // apply transformation by child's tagindex on parent entity and then
2356                 // by parent entity itself
2357                 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2358                 if (ret && attachloop == 0)
2359                         return ret;
2360                 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2361                 SV_GetEntityMatrix(ent, &entitymatrix, false);
2362                 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2363                 // next iteration we process the parent entity
2364                 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2365                 {
2366                         tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2367                         ent = PRVM_EDICT_NUM(val->edict);
2368                 }
2369                 else
2370                         break;
2371                 attachloop++;
2372         }
2373
2374         // RENDER_VIEWMODEL magic
2375         if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2376         {
2377                 Matrix4x4_Copy(&tagmatrix, out);
2378                 ent = PRVM_EDICT_NUM(val->edict);
2379
2380                 SV_GetEntityMatrix(ent, &entitymatrix, true);
2381                 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2382
2383                 /*
2384                 // Cl_bob, ported from rendering code
2385                 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2386                 {
2387                         double bob, cycle;
2388                         // LordHavoc: this code is *weird*, but not replacable (I think it
2389                         // should be done in QC on the server, but oh well, quake is quake)
2390                         // LordHavoc: figured out bobup: the time at which the sin is at 180
2391                         // degrees (which allows lengthening or squishing the peak or valley)
2392                         cycle = sv.time/cl_bobcycle.value;
2393                         cycle -= (int)cycle;
2394                         if (cycle < cl_bobup.value)
2395                                 cycle = sin(M_PI * cycle / cl_bobup.value);
2396                         else
2397                                 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2398                         // bob is proportional to velocity in the xy plane
2399                         // (don't count Z, or jumping messes it up)
2400                         bob = sqrt(ent->fields.server->velocity[0]*ent->fields.server->velocity[0] + ent->fields.server->velocity[1]*ent->fields.server->velocity[1])*cl_bob.value;
2401                         bob = bob*0.3 + bob*0.7*cycle;
2402                         Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2403                 }
2404                 */
2405         }
2406         return 0;
2407 }
2408
2409 //float(entity ent, string tagname) gettagindex;
2410
2411 static void VM_SV_gettagindex (void)
2412 {
2413         prvm_edict_t *ent;
2414         const char *tag_name;
2415         int modelindex, tag_index;
2416
2417         VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2418
2419         ent = PRVM_G_EDICT(OFS_PARM0);
2420         tag_name = PRVM_G_STRING(OFS_PARM1);
2421
2422         if (ent == prog->edicts)
2423         {
2424                 VM_Warning("gettagindex: can't affect world entity\n");
2425                 return;
2426         }
2427         if (ent->priv.server->free)
2428         {
2429                 VM_Warning("gettagindex: can't affect free entity\n");
2430                 return;
2431         }
2432
2433         modelindex = (int)ent->fields.server->modelindex;
2434         tag_index = 0;
2435         if (modelindex <= 0 || modelindex > MAX_MODELS)
2436                 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2437         else
2438         {
2439                 tag_index = SV_GetTagIndex(ent, tag_name);
2440                 if (tag_index == 0)
2441                         Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2442         }
2443         PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2444 };
2445
2446 //vector(entity ent, float tagindex) gettaginfo;
2447 static void VM_SV_gettaginfo (void)
2448 {
2449         prvm_edict_t *e;
2450         int tagindex;
2451         matrix4x4_t tag_matrix;
2452         int returncode;
2453
2454         VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2455
2456         e = PRVM_G_EDICT(OFS_PARM0);
2457         tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2458
2459         returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2460         Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2461
2462         switch(returncode)
2463         {
2464                 case 1:
2465                         VM_Warning("gettagindex: can't affect world entity\n");
2466                         break;
2467                 case 2:
2468                         VM_Warning("gettagindex: can't affect free entity\n");
2469                         break;
2470                 case 3:
2471                         Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2472                         break;
2473                 case 4:
2474                         Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2475                         break;
2476                 case 5:
2477                         Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2478                         break;
2479         }
2480 }
2481
2482 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2483 static void VM_SV_dropclient (void)
2484 {
2485         int clientnum;
2486         client_t *oldhostclient;
2487         VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2488         clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2489         if (clientnum < 0 || clientnum >= svs.maxclients)
2490         {
2491                 VM_Warning("dropclient: not a client\n");
2492                 return;
2493         }
2494         if (!svs.clients[clientnum].active)
2495         {
2496                 VM_Warning("dropclient: that client slot is not connected\n");
2497                 return;
2498         }
2499         oldhostclient = host_client;
2500         host_client = svs.clients + clientnum;
2501         SV_DropClient(false);
2502         host_client = oldhostclient;
2503 }
2504
2505 //entity() spawnclient (DP_SV_BOTCLIENT)
2506 static void VM_SV_spawnclient (void)
2507 {
2508         int i;
2509         prvm_edict_t    *ed;
2510         VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2511         prog->xfunction->builtinsprofile += 2;
2512         ed = prog->edicts;
2513         for (i = 0;i < svs.maxclients;i++)
2514         {
2515                 if (!svs.clients[i].active)
2516                 {
2517                         prog->xfunction->builtinsprofile += 100;
2518                         SV_ConnectClient (i, NULL);
2519                         // this has to be set or else ClientDisconnect won't be called
2520                         // we assume the qc will call ClientConnect...
2521                         svs.clients[i].clientconnectcalled = true;
2522                         ed = PRVM_EDICT_NUM(i + 1);
2523                         break;
2524                 }
2525         }
2526         VM_RETURN_EDICT(ed);
2527 }
2528
2529 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2530 static void VM_SV_clienttype (void)
2531 {
2532         int clientnum;
2533         VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2534         clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2535         if (clientnum < 0 || clientnum >= svs.maxclients)
2536                 PRVM_G_FLOAT(OFS_RETURN) = 3;
2537         else if (!svs.clients[clientnum].active)
2538                 PRVM_G_FLOAT(OFS_RETURN) = 0;
2539         else if (svs.clients[clientnum].netconnection)
2540                 PRVM_G_FLOAT(OFS_RETURN) = 1;
2541         else
2542                 PRVM_G_FLOAT(OFS_RETURN) = 2;
2543 }
2544
2545 /*
2546 ===============
2547 VM_SV_serverkey
2548
2549 string(string key) serverkey
2550 ===============
2551 */
2552 void VM_SV_serverkey(void)
2553 {
2554         char string[VM_STRINGTEMP_LENGTH];
2555         VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2556         InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2557         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2558 }
2559
2560 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2561 static void VM_SV_setmodelindex (void)
2562 {
2563         prvm_edict_t    *e;
2564         model_t *mod;
2565         int             i;
2566         VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2567
2568         e = PRVM_G_EDICT(OFS_PARM0);
2569         if (e == prog->edicts)
2570         {
2571                 VM_Warning("setmodelindex: can not modify world entity\n");
2572                 return;
2573         }
2574         if (e->priv.server->free)
2575         {
2576                 VM_Warning("setmodelindex: can not modify free entity\n");
2577                 return;
2578         }
2579         i = (int)PRVM_G_FLOAT(OFS_PARM1);
2580         if (i <= 0 || i > MAX_MODELS)
2581         {
2582                 VM_Warning("setmodelindex: invalid modelindex\n");
2583                 return;
2584         }
2585         if (!sv.model_precache[i][0])
2586         {
2587                 VM_Warning("setmodelindex: model not precached\n");
2588                 return;
2589         }
2590
2591         e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2592         e->fields.server->modelindex = i;
2593
2594         mod = sv.models[i];
2595
2596         if (mod)
2597         {
2598                 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2599                         SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2600                 else
2601                         SetMinMaxSize (e, quakemins, quakemaxs, true);
2602         }
2603         else
2604                 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2605 }
2606
2607 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2608 static void VM_SV_modelnameforindex (void)
2609 {
2610         int i;
2611         VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2612
2613         PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2614
2615         i = (int)PRVM_G_FLOAT(OFS_PARM0);
2616         if (i <= 0 || i > MAX_MODELS)
2617         {
2618                 VM_Warning("modelnameforindex: invalid modelindex\n");
2619                 return;
2620         }
2621         if (!sv.model_precache[i][0])
2622         {
2623                 VM_Warning("modelnameforindex: model not precached\n");
2624                 return;
2625         }
2626
2627         PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2628 }
2629
2630 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2631 static void VM_SV_particleeffectnum (void)
2632 {
2633         int                     i;
2634         VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2635         i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2636         if (i == 0)
2637                 i = -1;
2638         PRVM_G_FLOAT(OFS_RETURN) = i;
2639 }
2640
2641 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2642 static void VM_SV_trailparticles (void)
2643 {
2644         VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2645
2646         MSG_WriteByte(&sv.datagram, svc_trailparticles);
2647         MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2648         MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2649         MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2650         MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2651 }
2652
2653 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2654 static void VM_SV_pointparticles (void)
2655 {
2656         VM_SAFEPARMCOUNT(4, VM_SV_pointparticles);
2657
2658         MSG_WriteByte(&sv.datagram, svc_pointparticles);
2659         MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM0));
2660         MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1), sv.protocol);
2661         MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2662         MSG_WriteShort(&sv.datagram, bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535));
2663 }
2664
2665 prvm_builtin_t vm_sv_builtins[] = {
2666 NULL,                                                   // #0 NULL function (not callable) (QUAKE)
2667 VM_makevectors,                                 // #1 void(vector ang) makevectors (QUAKE)
2668 VM_SV_setorigin,                                // #2 void(entity e, vector o) setorigin (QUAKE)
2669 VM_SV_setmodel,                                 // #3 void(entity e, string m) setmodel (QUAKE)
2670 VM_SV_setsize,                                  // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2671 NULL,                                                   // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2672 VM_break,                                               // #6 void() break (QUAKE)
2673 VM_random,                                              // #7 float() random (QUAKE)
2674 VM_SV_sound,                                    // #8 void(entity e, float chan, string samp) sound (QUAKE)
2675 VM_normalize,                                   // #9 vector(vector v) normalize (QUAKE)
2676 VM_error,                                               // #10 void(string e) error (QUAKE)
2677 VM_objerror,                                    // #11 void(string e) objerror (QUAKE)
2678 VM_vlen,                                                // #12 float(vector v) vlen (QUAKE)
2679 VM_vectoyaw,                                    // #13 float(vector v) vectoyaw (QUAKE)
2680 VM_spawn,                                               // #14 entity() spawn (QUAKE)
2681 VM_remove,                                              // #15 void(entity e) remove (QUAKE)
2682 VM_SV_traceline,                                // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2683 VM_SV_checkclient,                              // #17 entity() checkclient (QUAKE)
2684 VM_find,                                                // #18 entity(entity start, .string fld, string match) find (QUAKE)
2685 VM_SV_precache_sound,                   // #19 void(string s) precache_sound (QUAKE)
2686 VM_SV_precache_model,                   // #20 void(string s) precache_model (QUAKE)
2687 VM_SV_stuffcmd,                                 // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2688 VM_SV_findradius,                               // #22 entity(vector org, float rad) findradius (QUAKE)
2689 VM_bprint,                                              // #23 void(string s, ...) bprint (QUAKE)
2690 VM_SV_sprint,                                   // #24 void(entity client, string s, ...) sprint (QUAKE)
2691 VM_dprint,                                              // #25 void(string s, ...) dprint (QUAKE)
2692 VM_ftos,                                                // #26 string(float f) ftos (QUAKE)
2693 VM_vtos,                                                // #27 string(vector v) vtos (QUAKE)
2694 VM_coredump,                                    // #28 void() coredump (QUAKE)
2695 VM_traceon,                                             // #29 void() traceon (QUAKE)
2696 VM_traceoff,                                    // #30 void() traceoff (QUAKE)
2697 VM_eprint,                                              // #31 void(entity e) eprint (QUAKE)
2698 VM_SV_walkmove,                                 // #32 float(float yaw, float dist) walkmove (QUAKE)
2699 NULL,                                                   // #33 (QUAKE)
2700 VM_SV_droptofloor,                              // #34 float() droptofloor (QUAKE)
2701 VM_SV_lightstyle,                               // #35 void(float style, string value) lightstyle (QUAKE)
2702 VM_rint,                                                // #36 float(float v) rint (QUAKE)
2703 VM_floor,                                               // #37 float(float v) floor (QUAKE)
2704 VM_ceil,                                                // #38 float(float v) ceil (QUAKE)
2705 NULL,                                                   // #39 (QUAKE)
2706 VM_SV_checkbottom,                              // #40 float(entity e) checkbottom (QUAKE)
2707 VM_SV_pointcontents,                    // #41 float(vector v) pointcontents (QUAKE)
2708 NULL,                                                   // #42 (QUAKE)
2709 VM_fabs,                                                // #43 float(float f) fabs (QUAKE)
2710 VM_SV_aim,                                              // #44 vector(entity e, float speed) aim (QUAKE)
2711 VM_cvar,                                                // #45 float(string s) cvar (QUAKE)
2712 VM_localcmd,                                    // #46 void(string s) localcmd (QUAKE)
2713 VM_nextent,                                             // #47 entity(entity e) nextent (QUAKE)
2714 VM_SV_particle,                                 // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2715 VM_changeyaw,                                   // #49 void() ChangeYaw (QUAKE)
2716 NULL,                                                   // #50 (QUAKE)
2717 VM_vectoangles,                                 // #51 vector(vector v) vectoangles (QUAKE)
2718 VM_SV_WriteByte,                                // #52 void(float to, float f) WriteByte (QUAKE)
2719 VM_SV_WriteChar,                                // #53 void(float to, float f) WriteChar (QUAKE)
2720 VM_SV_WriteShort,                               // #54 void(float to, float f) WriteShort (QUAKE)
2721 VM_SV_WriteLong,                                // #55 void(float to, float f) WriteLong (QUAKE)
2722 VM_SV_WriteCoord,                               // #56 void(float to, float f) WriteCoord (QUAKE)
2723 VM_SV_WriteAngle,                               // #57 void(float to, float f) WriteAngle (QUAKE)
2724 VM_SV_WriteString,                              // #58 void(float to, string s) WriteString (QUAKE)
2725 VM_SV_WriteEntity,                              // #59 void(float to, entity e) WriteEntity (QUAKE)
2726 VM_sin,                                                 // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2727 VM_cos,                                                 // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2728 VM_sqrt,                                                // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2729 VM_changepitch,                                 // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2730 VM_SV_tracetoss,                                // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2731 VM_etos,                                                // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2732 NULL,                                                   // #66 (QUAKE)
2733 SV_MoveToGoal,                                  // #67 void(float step) movetogoal (QUAKE)
2734 VM_precache_file,                               // #68 string(string s) precache_file (QUAKE)
2735 VM_SV_makestatic,                               // #69 void(entity e) makestatic (QUAKE)
2736 VM_changelevel,                                 // #70 void(string s) changelevel (QUAKE)
2737 NULL,                                                   // #71 (QUAKE)
2738 VM_cvar_set,                                    // #72 void(string var, string val) cvar_set (QUAKE)
2739 VM_SV_centerprint,                              // #73 void(entity client, strings) centerprint (QUAKE)
2740 VM_SV_ambientsound,                             // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2741 VM_SV_precache_model,                   // #75 string(string s) precache_model2 (QUAKE)
2742 VM_SV_precache_sound,                   // #76 string(string s) precache_sound2 (QUAKE)
2743 VM_precache_file,                               // #77 string(string s) precache_file2 (QUAKE)
2744 VM_SV_setspawnparms,                    // #78 void(entity e) setspawnparms (QUAKE)
2745 NULL,                                                   // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2746 NULL,                                                   // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2747 VM_stof,                                                // #81 float(string s) stof (FRIK_FILE)
2748 NULL,                                                   // #82 void(vector where, float set) multicast (QUAKEWORLD)
2749 NULL,                                                   // #83 (QUAKE)
2750 NULL,                                                   // #84 (QUAKE)
2751 NULL,                                                   // #85 (QUAKE)
2752 NULL,                                                   // #86 (QUAKE)
2753 NULL,                                                   // #87 (QUAKE)
2754 NULL,                                                   // #88 (QUAKE)
2755 NULL,                                                   // #89 (QUAKE)
2756 VM_SV_tracebox,                                 // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2757 VM_randomvec,                                   // #91 vector() randomvec (DP_QC_RANDOMVEC)
2758 VM_SV_getlight,                                 // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2759 VM_registercvar,                                // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2760 VM_min,                                                 // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2761 VM_max,                                                 // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2762 VM_bound,                                               // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2763 VM_pow,                                                 // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2764 VM_findfloat,                                   // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2765 VM_checkextension,                              // #99 float(string s) checkextension (the basis of the extension system)
2766 // FrikaC and Telejano range  #100-#199
2767 NULL,                                                   // #100
2768 NULL,                                                   // #101
2769 NULL,                                                   // #102
2770 NULL,                                                   // #103
2771 NULL,                                                   // #104
2772 NULL,                                                   // #105
2773 NULL,                                                   // #106
2774 NULL,                                                   // #107
2775 NULL,                                                   // #108
2776 NULL,                                                   // #109
2777 VM_fopen,                                               // #110 float(string filename, float mode) fopen (FRIK_FILE)
2778 VM_fclose,                                              // #111 void(float fhandle) fclose (FRIK_FILE)
2779 VM_fgets,                                               // #112 string(float fhandle) fgets (FRIK_FILE)
2780 VM_fputs,                                               // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2781 VM_strlen,                                              // #114 float(string s) strlen (FRIK_FILE)
2782 VM_strcat,                                              // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2783 VM_substring,                                   // #116 string(string s, float start, float length) substring (FRIK_FILE)
2784 VM_stov,                                                // #117 vector(string) stov (FRIK_FILE)
2785 VM_strzone,                                             // #118 string(string s) strzone (FRIK_FILE)
2786 VM_strunzone,                                   // #119 void(string s) strunzone (FRIK_FILE)
2787 NULL,                                                   // #120
2788 NULL,                                                   // #121
2789 NULL,                                                   // #122
2790 NULL,                                                   // #123
2791 NULL,                                                   // #124
2792 NULL,                                                   // #125
2793 NULL,                                                   // #126
2794 NULL,                                                   // #127
2795 NULL,                                                   // #128
2796 NULL,                                                   // #129
2797 NULL,                                                   // #130
2798 NULL,                                                   // #131
2799 NULL,                                                   // #132
2800 NULL,                                                   // #133
2801 NULL,                                                   // #134
2802 NULL,                                                   // #135
2803 NULL,                                                   // #136
2804 NULL,                                                   // #137
2805 NULL,                                                   // #138
2806 NULL,                                                   // #139
2807 NULL,                                                   // #140
2808 NULL,                                                   // #141
2809 NULL,                                                   // #142
2810 NULL,                                                   // #143
2811 NULL,                                                   // #144
2812 NULL,                                                   // #145
2813 NULL,                                                   // #146
2814 NULL,                                                   // #147
2815 NULL,                                                   // #148
2816 NULL,                                                   // #149
2817 NULL,                                                   // #150
2818 NULL,                                                   // #151
2819 NULL,                                                   // #152
2820 NULL,                                                   // #153
2821 NULL,                                                   // #154
2822 NULL,                                                   // #155
2823 NULL,                                                   // #156
2824 NULL,                                                   // #157
2825 NULL,                                                   // #158
2826 NULL,                                                   // #159
2827 NULL,                                                   // #160
2828 NULL,                                                   // #161
2829 NULL,                                                   // #162
2830 NULL,                                                   // #163
2831 NULL,                                                   // #164
2832 NULL,                                                   // #165
2833 NULL,                                                   // #166
2834 NULL,                                                   // #167
2835 NULL,                                                   // #168
2836 NULL,                                                   // #169
2837 NULL,                                                   // #170
2838 NULL,                                                   // #171
2839 NULL,                                                   // #172
2840 NULL,                                                   // #173
2841 NULL,                                                   // #174
2842 NULL,                                                   // #175
2843 NULL,                                                   // #176
2844 NULL,                                                   // #177
2845 NULL,                                                   // #178
2846 NULL,                                                   // #179
2847 NULL,                                                   // #180
2848 NULL,                                                   // #181
2849 NULL,                                                   // #182
2850 NULL,                                                   // #183
2851 NULL,                                                   // #184
2852 NULL,                                                   // #185
2853 NULL,                                                   // #186
2854 NULL,                                                   // #187
2855 NULL,                                                   // #188
2856 NULL,                                                   // #189
2857 NULL,                                                   // #190
2858 NULL,                                                   // #191
2859 NULL,                                                   // #192
2860 NULL,                                                   // #193
2861 NULL,                                                   // #194
2862 NULL,                                                   // #195
2863 NULL,                                                   // #196
2864 NULL,                                                   // #197
2865 NULL,                                                   // #198
2866 NULL,                                                   // #199
2867 // FTEQW range #200-#299
2868 NULL,                                                   // #200
2869 NULL,                                                   // #201
2870 NULL,                                                   // #202
2871 NULL,                                                   // #203
2872 NULL,                                                   // #204
2873 NULL,                                                   // #205
2874 NULL,                                                   // #206
2875 NULL,                                                   // #207
2876 NULL,                                                   // #208
2877 NULL,                                                   // #209
2878 NULL,                                                   // #210
2879 NULL,                                                   // #211
2880 NULL,                                                   // #212
2881 NULL,                                                   // #213
2882 NULL,                                                   // #214
2883 NULL,                                                   // #215
2884 NULL,                                                   // #216
2885 NULL,                                                   // #217
2886 VM_bitshift,                                    // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2887 NULL,                                                   // #219
2888 NULL,                                                   // #220
2889 NULL,                                                   // #221
2890 VM_str2chr,                                             // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2891 VM_chr2str,                                             // #223 string(float c, ...) chr2str (FTE_STRINGS)
2892 NULL,                                                   // #224
2893 NULL,                                                   // #225
2894 NULL,                                                   // #226
2895 NULL,                                                   // #227
2896 VM_strncmp,                                             // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2897 NULL,                                                   // #229
2898 NULL,                                                   // #230
2899 NULL,                                                   // #231
2900 VM_SV_AddStat,                                  // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2901 NULL,                                                   // #233
2902 NULL,                                                   // #234
2903 NULL,                                                   // #235
2904 NULL,                                                   // #236
2905 NULL,                                                   // #237
2906 NULL,                                                   // #238
2907 NULL,                                                   // #239
2908 NULL,                                                   // #240
2909 NULL,                                                   // #241
2910 NULL,                                                   // #242
2911 NULL,                                                   // #243
2912 NULL,                                                   // #244
2913 NULL,                                                   // #245
2914 NULL,                                                   // #246
2915 NULL,                                                   // #247
2916 NULL,                                                   // #248
2917 NULL,                                                   // #249
2918 NULL,                                                   // #250
2919 NULL,                                                   // #251
2920 NULL,                                                   // #252
2921 NULL,                                                   // #253
2922 NULL,                                                   // #254
2923 NULL,                                                   // #255
2924 NULL,                                                   // #256
2925 NULL,                                                   // #257
2926 NULL,                                                   // #258
2927 NULL,                                                   // #259
2928 NULL,                                                   // #260
2929 NULL,                                                   // #261
2930 NULL,                                                   // #262
2931 NULL,                                                   // #263
2932 NULL,                                                   // #264
2933 NULL,                                                   // #265
2934 NULL,                                                   // #266
2935 NULL,                                                   // #267
2936 NULL,                                                   // #268
2937 NULL,                                                   // #269
2938 NULL,                                                   // #270
2939 NULL,                                                   // #271
2940 NULL,                                                   // #272
2941 NULL,                                                   // #273
2942 NULL,                                                   // #274
2943 NULL,                                                   // #275
2944 NULL,                                                   // #276
2945 NULL,                                                   // #277
2946 NULL,                                                   // #278
2947 NULL,                                                   // #279
2948 NULL,                                                   // #280
2949 NULL,                                                   // #281
2950 NULL,                                                   // #282
2951 NULL,                                                   // #283
2952 NULL,                                                   // #284
2953 NULL,                                                   // #285
2954 NULL,                                                   // #286
2955 NULL,                                                   // #287
2956 NULL,                                                   // #288
2957 NULL,                                                   // #289
2958 NULL,                                                   // #290
2959 NULL,                                                   // #291
2960 NULL,                                                   // #292
2961 NULL,                                                   // #293
2962 NULL,                                                   // #294
2963 NULL,                                                   // #295
2964 NULL,                                                   // #296
2965 NULL,                                                   // #297
2966 NULL,                                                   // #298
2967 NULL,                                                   // #299
2968 // CSQC range #300-#399
2969 NULL,                                                   // #300 void() clearscene (EXT_CSQC)
2970 NULL,                                                   // #301 void(float mask) addentities (EXT_CSQC)
2971 NULL,                                                   // #302 void(entity ent) addentity (EXT_CSQC)
2972 NULL,                                                   // #303 float(float property, ...) setproperty (EXT_CSQC)
2973 NULL,                                                   // #304 void() renderscene (EXT_CSQC)
2974 NULL,                                                   // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2975 NULL,                                                   // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2976 NULL,                                                   // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2977 NULL,                                                   // #308 void() R_EndPolygon
2978 NULL,                                                   // #309
2979 NULL,                                                   // #310 vector (vector v) cs_unproject (EXT_CSQC)
2980 NULL,                                                   // #311 vector (vector v) cs_project (EXT_CSQC)
2981 NULL,                                                   // #312
2982 NULL,                                                   // #313
2983 NULL,                                                   // #314
2984 NULL,                                                   // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
2985 NULL,                                                   // #316 float(string name) iscachedpic (EXT_CSQC)
2986 NULL,                                                   // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
2987 NULL,                                                   // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
2988 NULL,                                                   // #319 void(string name) freepic (EXT_CSQC)
2989 NULL,                                                   // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
2990 NULL,                                                   // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
2991 NULL,                                                   // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
2992 NULL,                                                   // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
2993 NULL,                                                   // #324 void(float x, float y, float width, float height) drawsetcliparea
2994 NULL,                                                   // #325 void(void) drawresetcliparea
2995 NULL,                                                   // #326
2996 NULL,                                                   // #327
2997 NULL,                                                   // #328
2998 NULL,                                                   // #329
2999 NULL,                                                   // #330 float(float stnum) getstatf (EXT_CSQC)
3000 NULL,                                                   // #331 float(float stnum) getstati (EXT_CSQC)
3001 NULL,                                                   // #332 string(float firststnum) getstats (EXT_CSQC)
3002 VM_SV_setmodelindex,                    // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3003 VM_SV_modelnameforindex,                // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3004 VM_SV_particleeffectnum,                // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3005 VM_SV_trailparticles,                   // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3006 VM_SV_pointparticles,                   // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3007 NULL,                                                   // #338 void(string s, ...) centerprint (EXT_CSQC)
3008 VM_print,                                               // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3009 NULL,                                                   // #340 string(float keynum) keynumtostring (EXT_CSQC)
3010 NULL,                                                   // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3011 NULL,                                                   // #342 string(float keynum) getkeybind (EXT_CSQC)
3012 NULL,                                                   // #343 void(float usecursor) setcursormode (EXT_CSQC)
3013 NULL,                                                   // #344 vector() getmousepos (EXT_CSQC)
3014 NULL,                                                   // #345 float(float framenum) getinputstate (EXT_CSQC)
3015 NULL,                                                   // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3016 NULL,                                                   // #347 void() runstandardplayerphysics (EXT_CSQC)
3017 NULL,                                                   // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3018 NULL,                                                   // #349 float() isdemo (EXT_CSQC)
3019 VM_isserver,                                    // #350 float() isserver (EXT_CSQC)
3020 NULL,                                                   // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3021 NULL,                                                   // #352 void(string cmdname) registercommand (EXT_CSQC)
3022 VM_wasfreed,                                    // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3023 VM_SV_serverkey,                                // #354 string(string key) serverkey (EXT_CSQC)
3024 NULL,                                                   // #355
3025 NULL,                                                   // #356
3026 NULL,                                                   // #357
3027 NULL,                                                   // #358
3028 NULL,                                                   // #359
3029 NULL,                                                   // #360 float() readbyte (EXT_CSQC)
3030 NULL,                                                   // #361 float() readchar (EXT_CSQC)
3031 NULL,                                                   // #362 float() readshort (EXT_CSQC)
3032 NULL,                                                   // #363 float() readlong (EXT_CSQC)
3033 NULL,                                                   // #364 float() readcoord (EXT_CSQC)
3034 NULL,                                                   // #365 float() readangle (EXT_CSQC)
3035 NULL,                                                   // #366 string() readstring (EXT_CSQC)
3036 NULL,                                                   // #367 float() readfloat (EXT_CSQC)
3037 NULL,                                                   // #368
3038 NULL,                                                   // #369
3039 NULL,                                                   // #370
3040 NULL,                                                   // #371
3041 NULL,                                                   // #372
3042 NULL,                                                   // #373
3043 NULL,                                                   // #374
3044 NULL,                                                   // #375
3045 NULL,                                                   // #376
3046 NULL,                                                   // #377
3047 NULL,                                                   // #378
3048 NULL,                                                   // #379
3049 NULL,                                                   // #380
3050 NULL,                                                   // #381
3051 NULL,                                                   // #382
3052 NULL,                                                   // #383
3053 NULL,                                                   // #384
3054 NULL,                                                   // #385
3055 NULL,                                                   // #386
3056 NULL,                                                   // #387
3057 NULL,                                                   // #388
3058 NULL,                                                   // #389
3059 NULL,                                                   // #390
3060 NULL,                                                   // #391
3061 NULL,                                                   // #392
3062 NULL,                                                   // #393
3063 NULL,                                                   // #394
3064 NULL,                                                   // #395
3065 NULL,                                                   // #396
3066 NULL,                                                   // #397
3067 NULL,                                                   // #398
3068 NULL,                                                   // #399
3069 // LordHavoc's range #400-#499
3070 VM_SV_copyentity,                               // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3071 VM_SV_setcolor,                                 // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3072 VM_findchain,                                   // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3073 VM_findchainfloat,                              // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3074 VM_SV_effect,                                   // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3075 VM_SV_te_blood,                                 // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3076 VM_SV_te_bloodshower,                   // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3077 VM_SV_te_explosionrgb,                  // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3078 VM_SV_te_particlecube,                  // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE)
3079 VM_SV_te_particlerain,                  // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3080 VM_SV_te_particlesnow,                  // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3081 VM_SV_te_spark,                                 // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3082 VM_SV_te_gunshotquad,                   // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3083 VM_SV_te_spikequad,                             // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3084 VM_SV_te_superspikequad,                // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3085 VM_SV_te_explosionquad,                 // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3086 VM_SV_te_smallflash,                    // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3087 VM_SV_te_customflash,                   // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3088 VM_SV_te_gunshot,                               // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3089 VM_SV_te_spike,                                 // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3090 VM_SV_te_superspike,                    // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3091 VM_SV_te_explosion,                             // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3092 VM_SV_te_tarexplosion,                  // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3093 VM_SV_te_wizspike,                              // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3094 VM_SV_te_knightspike,                   // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3095 VM_SV_te_lavasplash,                    // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3096 VM_SV_te_teleport,                              // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3097 VM_SV_te_explosion2,                    // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3098 VM_SV_te_lightning1,                    // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3099 VM_SV_te_lightning2,                    // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3100 VM_SV_te_lightning3,                    // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3101 VM_SV_te_beam,                                  // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3102 VM_vectorvectors,                               // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3103 VM_SV_te_plasmaburn,                    // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3104 VM_SV_getsurfacenumpoints,              // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3105 VM_SV_getsurfacepoint,                  // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3106 VM_SV_getsurfacenormal,                 // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3107 VM_SV_getsurfacetexture,                // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3108 VM_SV_getsurfacenearpoint,              // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3109 VM_SV_getsurfaceclippedpoint,   // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3110 VM_SV_clientcommand,                    // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3111 VM_tokenize,                                    // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3112 VM_argv,                                                // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3113 VM_SV_setattachment,                    // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3114 VM_search_begin,                                // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
3115 VM_search_end,                                  // #445 void(float handle) search_end (DP_FS_SEARCH)
3116 VM_search_getsize,                              // #446 float(float handle) search_getsize (DP_FS_SEARCH)
3117 VM_search_getfilename,                  // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
3118 VM_cvar_string,                                 // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3119 VM_findflags,                                   // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3120 VM_findchainflags,                              // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3121 VM_SV_gettagindex,                              // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3122 VM_SV_gettaginfo,                               // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3123 VM_SV_dropclient,                               // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3124 VM_SV_spawnclient,                              // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3125 VM_SV_clienttype,                               // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3126 VM_SV_WriteUnterminatedString,  // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3127 VM_SV_te_flamejet,                              // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3128 NULL,                                                   // #458
3129 VM_ftoe,                                                // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3130 VM_buf_create,                                  // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3131 VM_buf_del,                                             // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3132 VM_buf_getsize,                                 // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3133 VM_buf_copy,                                    // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3134 VM_buf_sort,                                    // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3135 VM_buf_implode,                                 // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3136 VM_bufstr_get,                                  // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3137 VM_bufstr_set,                                  // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3138 VM_bufstr_add,                                  // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3139 VM_bufstr_free,                                 // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3140 NULL,                                                   // #470
3141 VM_asin,                                                // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3142 VM_acos,                                                // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3143 VM_atan,                                                // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3144 VM_atan2,                                               // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3145 VM_tan,                                                 // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3146 VM_strlennocol,                                 // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3147 VM_strdecolorize,                               // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3148 VM_strftime,                                    // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3149 NULL,                                                   // #479
3150 NULL,                                                   // #480
3151 NULL,                                                   // #481
3152 NULL,                                                   // #482
3153 NULL,                                                   // #483
3154 NULL,                                                   // #484
3155 NULL,                                                   // #485
3156 NULL,                                                   // #486
3157 NULL,                                                   // #487
3158 NULL,                                                   // #488
3159 NULL,                                                   // #489
3160 NULL,                                                   // #490
3161 NULL,                                                   // #491
3162 NULL,                                                   // #492
3163 NULL,                                                   // #493
3164 NULL,                                                   // #494
3165 NULL,                                                   // #495
3166 NULL,                                                   // #496
3167 NULL,                                                   // #497
3168 NULL,                                                   // #498
3169 NULL,                                                   // #499
3170 };
3171
3172 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3173
3174 void VM_SV_Cmd_Init(void)