]> icculus.org git repositories - divverent/darkplaces.git/blob - svvm_cmds.c
changed collision nudging to behave like quake2/3, properly handling shallow impacts...
[divverent/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"}; //"0.93"}; // LordHavoc: disabled autoaim by default
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         VM_SAFEPARMCOUNT(1, VM_SV_makestatic);
1196
1197         ent = PRVM_G_EDICT(OFS_PARM0);
1198         if (ent == prog->edicts)
1199         {
1200                 VM_Warning("makestatic: can not modify world entity\n");
1201                 return;
1202         }
1203         if (ent->priv.server->free)
1204         {
1205                 VM_Warning("makestatic: can not modify free entity\n");
1206                 return;
1207         }
1208
1209         large = false;
1210         if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1211                 large = true;
1212
1213         if (large)
1214         {
1215                 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1216                 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1217                 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1218         }
1219         else
1220         {
1221                 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1222                 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1223                 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1224         }
1225
1226         MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1227         MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1228         for (i=0 ; i<3 ; i++)
1229         {
1230                 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1231                 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1232         }
1233
1234 // throw the entity away now
1235         PRVM_ED_Free (ent);
1236 }
1237
1238 //=============================================================================
1239
1240 /*
1241 ==============
1242 VM_SV_setspawnparms
1243 ==============
1244 */
1245 static void VM_SV_setspawnparms (void)
1246 {
1247         prvm_edict_t    *ent;
1248         int             i;
1249         client_t        *client;
1250
1251         VM_SAFEPARMCOUNT(0, VM_SV_setspawnparms);
1252
1253         ent = PRVM_G_EDICT(OFS_PARM0);
1254         i = PRVM_NUM_FOR_EDICT(ent);
1255         if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1256         {
1257                 Con_Print("tried to setspawnparms on a non-client\n");
1258                 return;
1259         }
1260
1261         // copy spawn parms out of the client_t
1262         client = svs.clients + i-1;
1263         for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1264                 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1265 }
1266
1267 /*
1268 =================
1269 VM_SV_getlight
1270
1271 Returns a color vector indicating the lighting at the requested point.
1272
1273 (Internal Operation note: actually measures the light beneath the point, just like
1274                           the model lighting on the client)
1275
1276 getlight(vector)
1277 =================
1278 */
1279 static void VM_SV_getlight (void)
1280 {
1281         vec3_t ambientcolor, diffusecolor, diffusenormal;
1282         vec_t *p;
1283         VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1284         p = PRVM_G_VECTOR(OFS_PARM0);
1285         VectorClear(ambientcolor);
1286         VectorClear(diffusecolor);
1287         VectorClear(diffusenormal);
1288         if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1289                 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1290         VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1291 }
1292
1293 typedef struct
1294 {
1295         unsigned char   type;   // 1/2/8 or other value if isn't used
1296         int             fieldoffset;
1297 }autosentstat_t;
1298
1299 static autosentstat_t *vm_autosentstats = NULL; //[515]: it starts from 0, not 32
1300 static int vm_autosentstats_last;
1301
1302 void VM_AutoSentStats_Clear (void)
1303 {
1304         if(vm_autosentstats)
1305         {
1306                 Z_Free(vm_autosentstats);
1307                 vm_autosentstats = NULL;
1308                 vm_autosentstats_last = -1;
1309         }
1310 }
1311
1312 //[515]: add check if even bigger ? "try to use two stats, cause it's too big" ?
1313 #define VM_SENDSTAT(a,b,c)\
1314 {\
1315 /*      if((c))*/\
1316         if((c)==(unsigned char)(c))\
1317         {\
1318                 MSG_WriteByte((a), svc_updatestatubyte);\
1319                 MSG_WriteByte((a), (b));\
1320                 MSG_WriteByte((a), (c));\
1321         }\
1322         else\
1323         {\
1324                 MSG_WriteByte((a), svc_updatestat);\
1325                 MSG_WriteByte((a), (b));\
1326                 MSG_WriteLong((a), (c));\
1327         }\
1328 }\
1329
1330 void VM_SV_WriteAutoSentStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1331 {
1332         int                     i, v, *si;
1333         char            s[17];
1334         const char      *t;
1335         qboolean        send;
1336         union
1337         {
1338                 float   f;
1339                 int             i;
1340         }k;
1341
1342         if(!vm_autosentstats)
1343                 return;
1344
1345         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);
1346
1347         for(i=0; i<vm_autosentstats_last+1 ;i++)
1348         {
1349                 if(!vm_autosentstats[i].type)
1350                         continue;
1351                 switch(vm_autosentstats[i].type)
1352                 {
1353                 //string
1354                 case 1:
1355                         t = PRVM_E_STRING(ent, vm_autosentstats[i].fieldoffset);
1356                         if(t && t[0])
1357                         {
1358                                 memset(s, 0, 17);
1359                                 strlcpy(s, t, 16);
1360                                 si = (int*)s;
1361                                 if (!send)
1362                                 {
1363                                         stats[i+32] = si[0];
1364                                         stats[i+33] = si[1];
1365                                         stats[i+34] = si[2];
1366                                         stats[i+35] = si[3];
1367                                 }
1368                                 else
1369                                 {
1370                                         VM_SENDSTAT(msg, i+32, si[0]);
1371                                         VM_SENDSTAT(msg, i+33, si[1]);
1372                                         VM_SENDSTAT(msg, i+34, si[2]);
1373                                         VM_SENDSTAT(msg, i+35, si[3]);
1374                                 }
1375                         }
1376                         break;
1377                 //float
1378                 case 2:
1379                         k.f = PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset);       //[515]: use PRVM_E_INT ?
1380                         k.i = LittleLong (k.i);
1381                         if (!send)
1382                                 stats[i+32] = k.i;
1383                         else
1384                                 VM_SENDSTAT(msg, i+32, k.i);
1385                         break;
1386                 //integer
1387                 case 8:
1388                         v = (int)PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset);    //[515]: use PRVM_E_INT ?
1389                         if (!send)
1390                                 stats[i+32] = v;
1391                         else
1392                                 VM_SENDSTAT(msg, i+32, v);
1393                         break;
1394                 default:
1395                         break;
1396                 }
1397         }
1398 }
1399
1400 // void(float index, float type, .void field) SV_AddStat = #232;
1401 // Set up an auto-sent player stat.
1402 // Client's get thier own fields sent to them. Index may not be less than 32.
1403 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1404 //          1: string (4 stats carrying a total of 16 charactures)
1405 //          2: float (one stat, float converted to an integer for transportation)
1406 //          8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1407 static void VM_SV_AddStat (void)
1408 {
1409         int             off, i;
1410         unsigned char   type;
1411
1412         VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1413
1414         if(!vm_autosentstats)
1415         {
1416                 vm_autosentstats = (autosentstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(autosentstat_t));
1417                 if(!vm_autosentstats)
1418                 {
1419                         VM_Warning("PF_SV_AddStat: not enough memory\n");
1420                         return;
1421                 }
1422         }
1423         i               = (int)PRVM_G_FLOAT(OFS_PARM0);
1424         type    = (int)PRVM_G_FLOAT(OFS_PARM1);
1425         off             = PRVM_G_INT  (OFS_PARM2);
1426         i -= 32;
1427
1428         if(i < 0)
1429         {
1430                 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1431                 return;
1432         }
1433         if(i >= (MAX_CL_STATS-32))
1434         {
1435                 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1436                 return;
1437         }
1438         if(i > (MAX_CL_STATS-32-4) && type == 1)
1439         {
1440                 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1441                 return;
1442         }
1443         vm_autosentstats[i].type                = type;
1444         vm_autosentstats[i].fieldoffset = off;
1445         if(vm_autosentstats_last < i)
1446                 vm_autosentstats_last = i;
1447 }
1448
1449 /*
1450 =================
1451 VM_SV_copyentity
1452
1453 copies data from one entity to another
1454
1455 copyentity(src, dst)
1456 =================
1457 */
1458 static void VM_SV_copyentity (void)
1459 {
1460         prvm_edict_t *in, *out;
1461         VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1462         in = PRVM_G_EDICT(OFS_PARM0);
1463         if (in == prog->edicts)
1464         {
1465                 VM_Warning("copyentity: can not read world entity\n");
1466                 return;
1467         }
1468         if (in->priv.server->free)
1469         {
1470                 VM_Warning("copyentity: can not read free entity\n");
1471                 return;
1472         }
1473         out = PRVM_G_EDICT(OFS_PARM1);
1474         if (out == prog->edicts)
1475         {
1476                 VM_Warning("copyentity: can not modify world entity\n");
1477                 return;
1478         }
1479         if (out->priv.server->free)
1480         {
1481                 VM_Warning("copyentity: can not modify free entity\n");
1482                 return;
1483         }
1484         memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1485         SV_LinkEdict(out, false);
1486 }
1487
1488
1489 /*
1490 =================
1491 VM_SV_setcolor
1492
1493 sets the color of a client and broadcasts the update to all connected clients
1494
1495 setcolor(clientent, value)
1496 =================
1497 */
1498 static void VM_SV_setcolor (void)
1499 {
1500         client_t *client;
1501         int entnum, i;
1502         prvm_eval_t *val;
1503
1504         VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1505         entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1506         i = (int)PRVM_G_FLOAT(OFS_PARM1);
1507
1508         if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1509         {
1510                 Con_Print("tried to setcolor a non-client\n");
1511                 return;
1512         }
1513
1514         client = svs.clients + entnum-1;
1515         if (client->edict)
1516         {
1517                 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1518                         val->_float = i;
1519                 client->edict->fields.server->team = (i & 15) + 1;
1520         }
1521         client->colors = i;
1522         if (client->old_colors != client->colors)
1523         {
1524                 client->old_colors = client->colors;
1525                 // send notification to all clients
1526                 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1527                 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1528                 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1529         }
1530 }
1531
1532 /*
1533 =================
1534 VM_SV_effect
1535
1536 effect(origin, modelname, startframe, framecount, framerate)
1537 =================
1538 */
1539 static void VM_SV_effect (void)
1540 {
1541         int i;
1542         const char *s;
1543         VM_SAFEPARMCOUNT(5, VM_SV_effect);
1544         s = PRVM_G_STRING(OFS_PARM1);
1545         if (!s[0])
1546         {
1547                 VM_Warning("effect: no model specified\n");
1548                 return;
1549         }
1550
1551         i = SV_ModelIndex(s, 1);
1552         if (!i)
1553         {
1554                 VM_Warning("effect: model not precached\n");
1555                 return;
1556         }
1557
1558         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1559         {
1560                 VM_Warning("effect: framecount < 1\n");
1561                 return;
1562         }
1563
1564         if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1565         {
1566                 VM_Warning("effect: framerate < 1\n");
1567                 return;
1568         }
1569
1570         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));
1571 }
1572
1573 static void VM_SV_te_blood (void)
1574 {
1575         VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1576         if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1577                 return;
1578         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1579         MSG_WriteByte(&sv.datagram, TE_BLOOD);
1580         // origin
1581         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1582         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1583         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1584         // velocity
1585         MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1586         MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1587         MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1588         // count
1589         MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1590 }
1591
1592 static void VM_SV_te_bloodshower (void)
1593 {
1594         VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1595         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1596                 return;
1597         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1598         MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1599         // min
1600         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1601         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1602         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1603         // max
1604         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1605         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1606         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1607         // speed
1608         MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1609         // count
1610         MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1611 }
1612
1613 static void VM_SV_te_explosionrgb (void)
1614 {
1615         VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1616         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1617         MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1618         // origin
1619         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1620         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1621         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1622         // color
1623         MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1624         MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1625         MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1626 }
1627
1628 static void VM_SV_te_particlecube (void)
1629 {
1630         VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1631         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1632                 return;
1633         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1634         MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1635         // min
1636         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1637         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1638         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1639         // max
1640         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1641         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1642         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1643         // velocity
1644         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1645         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1646         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1647         // count
1648         MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1649         // color
1650         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1651         // gravity true/false
1652         MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1653         // randomvel
1654         MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1655 }
1656
1657 static void VM_SV_te_particlerain (void)
1658 {
1659         VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1660         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1661                 return;
1662         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1663         MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1664         // min
1665         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1666         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1667         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1668         // max
1669         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1670         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1671         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1672         // velocity
1673         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1674         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1675         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1676         // count
1677         MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1678         // color
1679         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1680 }
1681
1682 static void VM_SV_te_particlesnow (void)
1683 {
1684         VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1685         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1686                 return;
1687         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1688         MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1689         // min
1690         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1691         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1692         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1693         // max
1694         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1695         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1696         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1697         // velocity
1698         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1699         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1700         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1701         // count
1702         MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1703         // color
1704         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1705 }
1706
1707 static void VM_SV_te_spark (void)
1708 {
1709         VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1710         if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1711                 return;
1712         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1713         MSG_WriteByte(&sv.datagram, TE_SPARK);
1714         // origin
1715         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1716         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1717         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1718         // velocity
1719         MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1720         MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1721         MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1722         // count
1723         MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1724 }
1725
1726 static void VM_SV_te_gunshotquad (void)
1727 {
1728         VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1729         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1730         MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1731         // origin
1732         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1733         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1734         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1735 }
1736
1737 static void VM_SV_te_spikequad (void)
1738 {
1739         VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1740         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1741         MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1742         // origin
1743         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1744         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1745         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1746 }
1747
1748 static void VM_SV_te_superspikequad (void)
1749 {
1750         VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1751         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1752         MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1753         // origin
1754         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1755         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1756         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1757 }
1758
1759 static void VM_SV_te_explosionquad (void)
1760 {
1761         VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1762         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1763         MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1764         // origin
1765         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1766         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1767         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1768 }
1769
1770 static void VM_SV_te_smallflash (void)
1771 {
1772         VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1773         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1774         MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1775         // origin
1776         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1777         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1778         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1779 }
1780
1781 static void VM_SV_te_customflash (void)
1782 {
1783         VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1784         if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1785                 return;
1786         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1787         MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1788         // origin
1789         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1790         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1791         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1792         // radius
1793         MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1794         // lifetime
1795         MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1796         // color
1797         MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1798         MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1799         MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1800 }
1801
1802 static void VM_SV_te_gunshot (void)
1803 {
1804         VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1805         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1806         MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1807         // origin
1808         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1809         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1810         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1811 }
1812
1813 static void VM_SV_te_spike (void)
1814 {
1815         VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1816         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1817         MSG_WriteByte(&sv.datagram, TE_SPIKE);
1818         // origin
1819         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1820         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1821         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1822 }
1823
1824 static void VM_SV_te_superspike (void)
1825 {
1826         VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1827         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1828         MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1829         // origin
1830         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1831         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1832         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1833 }
1834
1835 static void VM_SV_te_explosion (void)
1836 {
1837         VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1838         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1839         MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1840         // origin
1841         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1842         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1843         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1844 }
1845
1846 static void VM_SV_te_tarexplosion (void)
1847 {
1848         VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1849         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1850         MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1851         // origin
1852         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1853         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1854         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1855 }
1856
1857 static void VM_SV_te_wizspike (void)
1858 {
1859         VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1860         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1861         MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1862         // origin
1863         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1864         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1865         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1866 }
1867
1868 static void VM_SV_te_knightspike (void)
1869 {
1870         VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1871         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1872         MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1873         // origin
1874         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1875         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1876         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1877 }
1878
1879 static void VM_SV_te_lavasplash (void)
1880 {
1881         VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1882         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1883         MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1884         // origin
1885         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1886         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1887         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1888 }
1889
1890 static void VM_SV_te_teleport (void)
1891 {
1892         VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1893         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1894         MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1895         // origin
1896         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1897         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1898         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1899 }
1900
1901 static void VM_SV_te_explosion2 (void)
1902 {
1903         VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1904         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1905         MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1906         // origin
1907         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1908         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1909         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1910         // color
1911         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1912         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1913 }
1914
1915 static void VM_SV_te_lightning1 (void)
1916 {
1917         VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1918         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1919         MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1920         // owner entity
1921         MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1922         // start
1923         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1924         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1925         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1926         // end
1927         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1928         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1929         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1930 }
1931
1932 static void VM_SV_te_lightning2 (void)
1933 {
1934         VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1935         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1936         MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1937         // owner entity
1938         MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1939         // start
1940         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1941         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1942         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1943         // end
1944         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1945         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1946         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1947 }
1948
1949 static void VM_SV_te_lightning3 (void)
1950 {
1951         VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1952         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1953         MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1954         // owner entity
1955         MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1956         // start
1957         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1958         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1959         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1960         // end
1961         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1962         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1963         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1964 }
1965
1966 static void VM_SV_te_beam (void)
1967 {
1968         VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1969         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1970         MSG_WriteByte(&sv.datagram, TE_BEAM);
1971         // owner entity
1972         MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1973         // start
1974         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1975         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1976         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1977         // end
1978         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1979         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1980         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1981 }
1982
1983 static void VM_SV_te_plasmaburn (void)
1984 {
1985         VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
1986         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1987         MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
1988         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1989         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1990         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1991 }
1992
1993 static void VM_SV_te_flamejet (void)
1994 {
1995         VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
1996         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1997         MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
1998         // org
1999         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2000         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2001         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2002         // vel
2003         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2004         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2005         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2006         // count
2007         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2008 }
2009
2010 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2011 {
2012         int i, j, k;
2013         float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2014         const int *e;
2015         bestdist = 1000000000;
2016         VectorCopy(p, out);
2017         for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2018         {
2019                 // clip original point to each triangle of the surface and find the
2020                 // triangle that is closest
2021                 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2022                 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2023                 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2024                 TriangleNormal(v[0], v[1], v[2], facenormal);
2025                 VectorNormalize(facenormal);
2026                 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2027                 VectorMA(p, offsetdist, facenormal, temp);
2028                 for (j = 0, k = 2;j < 3;k = j, j++)
2029                 {
2030                         VectorSubtract(v[k], v[j], edgenormal);
2031                         CrossProduct(edgenormal, facenormal, sidenormal);
2032                         VectorNormalize(sidenormal);
2033                         offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2034                         if (offsetdist < 0)
2035                                 VectorMA(temp, offsetdist, sidenormal, temp);
2036                 }
2037                 dist = VectorDistance2(temp, p);
2038                 if (bestdist > dist)
2039                 {
2040                         bestdist = dist;
2041                         VectorCopy(temp, out);
2042                 }
2043         }
2044 }
2045
2046 static model_t *getmodel(prvm_edict_t *ed)
2047 {
2048         int modelindex;
2049         if (!ed || ed->priv.server->free)
2050                 return NULL;
2051         modelindex = (int)ed->fields.server->modelindex;
2052         if (modelindex < 1 || modelindex >= MAX_MODELS)
2053                 return NULL;
2054         return sv.models[modelindex];
2055 }
2056
2057 static msurface_t *getsurface(model_t *model, int surfacenum)
2058 {
2059         if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2060                 return NULL;
2061         return model->data_surfaces + surfacenum + model->firstmodelsurface;
2062 }
2063
2064
2065 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2066 static void VM_SV_getsurfacenumpoints(void)
2067 {
2068         model_t *model;
2069         msurface_t *surface;
2070         VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2071         // return 0 if no such surface
2072         if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2073         {
2074                 PRVM_G_FLOAT(OFS_RETURN) = 0;
2075                 return;
2076         }
2077
2078         // note: this (incorrectly) assumes it is a simple polygon
2079         PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2080 }
2081 //PF_getsurfacepoint,     // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2082 static void VM_SV_getsurfacepoint(void)
2083 {
2084         prvm_edict_t *ed;
2085         model_t *model;
2086         msurface_t *surface;
2087         int pointnum;
2088         VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2089         VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2090         ed = PRVM_G_EDICT(OFS_PARM0);
2091         if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2092                 return;
2093         // note: this (incorrectly) assumes it is a simple polygon
2094         pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2095         if (pointnum < 0 || pointnum >= surface->num_vertices)
2096                 return;
2097         // FIXME: implement rotation/scaling
2098         VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2099 }
2100 //PF_getsurfacenormal,    // #436 vector(entity e, float s) getsurfacenormal = #436;
2101 static void VM_SV_getsurfacenormal(void)
2102 {
2103         model_t *model;
2104         msurface_t *surface;
2105         vec3_t normal;
2106         VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2107         VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2108         if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2109                 return;
2110         // FIXME: implement rotation/scaling
2111         // note: this (incorrectly) assumes it is a simple polygon
2112         // note: this only returns the first triangle, so it doesn't work very
2113         // well for curved surfaces or arbitrary meshes
2114         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);
2115         VectorNormalize(normal);
2116         VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2117 }
2118 //PF_getsurfacetexture,   // #437 string(entity e, float s) getsurfacetexture = #437;
2119 static void VM_SV_getsurfacetexture(void)
2120 {
2121         model_t *model;
2122         msurface_t *surface;
2123         VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2124         PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2125         if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2126                 return;
2127         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2128 }
2129 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2130 static void VM_SV_getsurfacenearpoint(void)
2131 {
2132         int surfacenum, best;
2133         vec3_t clipped, p;
2134         vec_t dist, bestdist;
2135         prvm_edict_t *ed;
2136         model_t *model;
2137         msurface_t *surface;
2138         vec_t *point;
2139         VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2140         PRVM_G_FLOAT(OFS_RETURN) = -1;
2141         ed = PRVM_G_EDICT(OFS_PARM0);
2142         point = PRVM_G_VECTOR(OFS_PARM1);
2143
2144         if (!ed || ed->priv.server->free)
2145                 return;
2146         model = getmodel(ed);
2147         if (!model || !model->num_surfaces)
2148                 return;
2149
2150         // FIXME: implement rotation/scaling
2151         VectorSubtract(point, ed->fields.server->origin, p);
2152         best = -1;
2153         bestdist = 1000000000;
2154         for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2155         {
2156                 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2157                 // first see if the nearest point on the surface's box is closer than the previous match
2158                 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2159                 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2160                 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2161                 dist = VectorLength2(clipped);
2162                 if (dist < bestdist)
2163                 {
2164                         // it is, check the nearest point on the actual geometry
2165                         clippointtosurface(model, surface, p, clipped);
2166                         VectorSubtract(clipped, p, clipped);
2167                         dist += VectorLength2(clipped);
2168                         if (dist < bestdist)
2169                         {
2170                                 // that's closer too, store it as the best match
2171                                 best = surfacenum;
2172                                 bestdist = dist;
2173                         }
2174                 }
2175         }
2176         PRVM_G_FLOAT(OFS_RETURN) = best;
2177 }
2178 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2179 static void VM_SV_getsurfaceclippedpoint(void)
2180 {
2181         prvm_edict_t *ed;
2182         model_t *model;
2183         msurface_t *surface;
2184         vec3_t p, out;
2185         VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2186         VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2187         ed = PRVM_G_EDICT(OFS_PARM0);
2188         if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2189                 return;
2190         // FIXME: implement rotation/scaling
2191         VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2192         clippointtosurface(model, surface, p, out);
2193         // FIXME: implement rotation/scaling
2194         VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2195 }
2196
2197 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2198 //this function originally written by KrimZon, made shorter by LordHavoc
2199 static void VM_SV_clientcommand (void)
2200 {
2201         client_t *temp_client;
2202         int i;
2203         VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2204
2205         //find client for this entity
2206         i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2207         if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2208         {
2209                 Con_Print("PF_clientcommand: entity is not a client\n");
2210                 return;
2211         }
2212
2213         temp_client = host_client;
2214         host_client = svs.clients + i;
2215         Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2216         host_client = temp_client;
2217 }
2218
2219 //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)
2220 static void VM_SV_setattachment (void)
2221 {
2222         prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2223         prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2224         const char *tagname = PRVM_G_STRING(OFS_PARM2);
2225         prvm_eval_t *v;
2226         int modelindex;
2227         model_t *model;
2228         VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2229
2230         if (e == prog->edicts)
2231         {
2232                 VM_Warning("setattachment: can not modify world entity\n");
2233                 return;
2234         }
2235         if (e->priv.server->free)
2236         {
2237                 VM_Warning("setattachment: can not modify free entity\n");
2238                 return;
2239         }
2240
2241         if (tagentity == NULL)
2242                 tagentity = prog->edicts;
2243
2244         v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2245         if (v)
2246                 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2247
2248         v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2249         if (v)
2250                 v->_float = 0;
2251         if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2252         {
2253                 modelindex = (int)tagentity->fields.server->modelindex;
2254                 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2255                 {
2256                         v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2257                         if (v->_float == 0)
2258                                 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);
2259                 }
2260                 else
2261                         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));
2262         }
2263 }
2264
2265 /////////////////////////////////////////
2266 // DP_MD3_TAGINFO extension coded by VorteX
2267
2268 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2269 {
2270         int i;
2271         model_t *model;
2272
2273         i = (int)e->fields.server->modelindex;
2274         if (i < 1 || i >= MAX_MODELS)
2275                 return -1;
2276         model = sv.models[i];
2277
2278         return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2279 };
2280
2281 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2282 {
2283         float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2284         if (scale == 0)
2285                 scale = 1;
2286         if (viewmatrix)
2287                 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);
2288         else
2289                 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);
2290 }
2291
2292 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2293 {
2294         int modelindex;
2295         int frame;
2296         model_t *model;
2297         if (tagindex >= 0
2298          && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2299          && (model = sv.models[(int)ent->fields.server->modelindex])
2300          && model->animscenes)
2301         {
2302                 // if model has wrong frame, engine automatically switches to model first frame
2303                 frame = (int)ent->fields.server->frame;
2304                 if (frame < 0 || frame >= model->numframes)
2305                         frame = 0;
2306                 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2307         }
2308         *out = identitymatrix;
2309         return 0;
2310 }
2311
2312 // Warnings/errors code:
2313 // 0 - normal (everything all-right)
2314 // 1 - world entity
2315 // 2 - free entity
2316 // 3 - null or non-precached model
2317 // 4 - no tags with requested index
2318 // 5 - runaway loop at attachment chain
2319 extern cvar_t cl_bob;
2320 extern cvar_t cl_bobcycle;
2321 extern cvar_t cl_bobup;
2322 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2323 {
2324         int ret;
2325         prvm_eval_t *val;
2326         int modelindex, attachloop;
2327         matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2328         model_t *model;
2329
2330         *out = identitymatrix; // warnings and errors return identical matrix
2331
2332         if (ent == prog->edicts)
2333                 return 1;
2334         if (ent->priv.server->free)
2335                 return 2;
2336
2337         modelindex = (int)ent->fields.server->modelindex;
2338         if (modelindex <= 0 || modelindex > MAX_MODELS)
2339                 return 3;
2340
2341         model = sv.models[modelindex];
2342
2343         tagmatrix = identitymatrix;
2344         // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2345         attachloop = 0;
2346         for (;;)
2347         {
2348                 if (attachloop >= 256) // prevent runaway looping
2349                         return 5;
2350                 // apply transformation by child's tagindex on parent entity and then
2351                 // by parent entity itself
2352                 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2353                 if (ret && attachloop == 0)
2354                         return ret;
2355                 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2356                 SV_GetEntityMatrix(ent, &entitymatrix, false);
2357                 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2358                 // next iteration we process the parent entity
2359                 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2360                 {
2361                         tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2362                         ent = PRVM_EDICT_NUM(val->edict);
2363                 }
2364                 else
2365                         break;
2366                 attachloop++;
2367         }
2368
2369         // RENDER_VIEWMODEL magic
2370         if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2371         {
2372                 Matrix4x4_Copy(&tagmatrix, out);
2373                 ent = PRVM_EDICT_NUM(val->edict);
2374
2375                 SV_GetEntityMatrix(ent, &entitymatrix, true);
2376                 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2377
2378                 /*
2379                 // Cl_bob, ported from rendering code
2380                 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2381                 {
2382                         double bob, cycle;
2383                         // LordHavoc: this code is *weird*, but not replacable (I think it
2384                         // should be done in QC on the server, but oh well, quake is quake)
2385                         // LordHavoc: figured out bobup: the time at which the sin is at 180
2386                         // degrees (which allows lengthening or squishing the peak or valley)
2387                         cycle = sv.time/cl_bobcycle.value;
2388                         cycle -= (int)cycle;
2389                         if (cycle < cl_bobup.value)
2390                                 cycle = sin(M_PI * cycle / cl_bobup.value);
2391                         else
2392                                 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2393                         // bob is proportional to velocity in the xy plane
2394                         // (don't count Z, or jumping messes it up)
2395                         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;
2396                         bob = bob*0.3 + bob*0.7*cycle;
2397                         Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2398                 }
2399                 */
2400         }
2401         return 0;
2402 }
2403
2404 //float(entity ent, string tagname) gettagindex;
2405
2406 static void VM_SV_gettagindex (void)
2407 {
2408         prvm_edict_t *ent;
2409         const char *tag_name;
2410         int modelindex, tag_index;
2411
2412         VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2413
2414         ent = PRVM_G_EDICT(OFS_PARM0);
2415         tag_name = PRVM_G_STRING(OFS_PARM1);
2416
2417         if (ent == prog->edicts)
2418         {
2419                 VM_Warning("gettagindex: can't affect world entity\n");
2420                 return;
2421         }
2422         if (ent->priv.server->free)
2423         {
2424                 VM_Warning("gettagindex: can't affect free entity\n");
2425                 return;
2426         }
2427
2428         modelindex = (int)ent->fields.server->modelindex;
2429         tag_index = 0;
2430         if (modelindex <= 0 || modelindex > MAX_MODELS)
2431                 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2432         else
2433         {
2434                 tag_index = SV_GetTagIndex(ent, tag_name);
2435                 if (tag_index == 0)
2436                         Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2437         }
2438         PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2439 };
2440
2441 //vector(entity ent, float tagindex) gettaginfo;
2442 static void VM_SV_gettaginfo (void)
2443 {
2444         prvm_edict_t *e;
2445         int tagindex;
2446         matrix4x4_t tag_matrix;
2447         int returncode;
2448
2449         VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2450
2451         e = PRVM_G_EDICT(OFS_PARM0);
2452         tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2453
2454         returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2455         Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2456
2457         switch(returncode)
2458         {
2459                 case 1:
2460                         VM_Warning("gettagindex: can't affect world entity\n");
2461                         break;
2462                 case 2:
2463                         VM_Warning("gettagindex: can't affect free entity\n");
2464                         break;
2465                 case 3:
2466                         Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2467                         break;
2468                 case 4:
2469                         Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2470                         break;
2471                 case 5:
2472                         Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2473                         break;
2474         }
2475 }
2476
2477 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2478 static void VM_SV_dropclient (void)
2479 {
2480         int clientnum;
2481         client_t *oldhostclient;
2482         VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2483         clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2484         if (clientnum < 0 || clientnum >= svs.maxclients)
2485         {
2486                 VM_Warning("dropclient: not a client\n");
2487                 return;
2488         }
2489         if (!svs.clients[clientnum].active)
2490         {
2491                 VM_Warning("dropclient: that client slot is not connected\n");
2492                 return;
2493         }
2494         oldhostclient = host_client;
2495         host_client = svs.clients + clientnum;
2496         SV_DropClient(false);
2497         host_client = oldhostclient;
2498 }
2499
2500 //entity() spawnclient (DP_SV_BOTCLIENT)
2501 static void VM_SV_spawnclient (void)
2502 {
2503         int i;
2504         prvm_edict_t    *ed;
2505         VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2506         prog->xfunction->builtinsprofile += 2;
2507         ed = prog->edicts;
2508         for (i = 0;i < svs.maxclients;i++)
2509         {
2510                 if (!svs.clients[i].active)
2511                 {
2512                         prog->xfunction->builtinsprofile += 100;
2513                         SV_ConnectClient (i, NULL);
2514                         // this has to be set or else ClientDisconnect won't be called
2515                         // we assume the qc will call ClientConnect...
2516                         svs.clients[i].clientconnectcalled = true;
2517                         ed = PRVM_EDICT_NUM(i + 1);
2518                         break;
2519                 }
2520         }
2521         VM_RETURN_EDICT(ed);
2522 }
2523
2524 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2525 static void VM_SV_clienttype (void)
2526 {
2527         int clientnum;
2528         VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2529         clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2530         if (clientnum < 0 || clientnum >= svs.maxclients)
2531                 PRVM_G_FLOAT(OFS_RETURN) = 3;
2532         else if (!svs.clients[clientnum].active)
2533                 PRVM_G_FLOAT(OFS_RETURN) = 0;
2534         else if (svs.clients[clientnum].netconnection)
2535                 PRVM_G_FLOAT(OFS_RETURN) = 1;
2536         else
2537                 PRVM_G_FLOAT(OFS_RETURN) = 2;
2538 }
2539
2540 /*
2541 ===============
2542 VM_SV_serverkey
2543
2544 string(string key) serverkey
2545 ===============
2546 */
2547 void VM_SV_serverkey(void)
2548 {
2549         char string[VM_STRINGTEMP_LENGTH];
2550         VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2551         InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2552         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2553 }
2554
2555 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2556 static void VM_SV_setmodelindex (void)
2557 {
2558         prvm_edict_t    *e;
2559         model_t *mod;
2560         int             i;
2561         VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2562
2563         e = PRVM_G_EDICT(OFS_PARM0);
2564         if (e == prog->edicts)
2565         {
2566                 VM_Warning("setmodelindex: can not modify world entity\n");
2567                 return;
2568         }
2569         if (e->priv.server->free)
2570         {
2571                 VM_Warning("setmodelindex: can not modify free entity\n");
2572                 return;
2573         }
2574         i = (int)PRVM_G_FLOAT(OFS_PARM1);
2575         if (i <= 0 || i > MAX_MODELS)
2576         {
2577                 VM_Warning("setmodelindex: invalid modelindex\n");
2578                 return;
2579         }
2580         if (!sv.model_precache[i][0])
2581         {
2582                 VM_Warning("setmodelindex: model not precached\n");
2583                 return;
2584         }
2585
2586         e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2587         e->fields.server->modelindex = i;
2588
2589         mod = sv.models[i];
2590
2591         if (mod)
2592         {
2593                 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2594                         SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2595                 else
2596                         SetMinMaxSize (e, quakemins, quakemaxs, true);
2597         }
2598         else
2599                 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2600 }
2601
2602 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2603 static void VM_SV_modelnameforindex (void)
2604 {
2605         int i;
2606         VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2607
2608         PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2609
2610         i = (int)PRVM_G_FLOAT(OFS_PARM0);
2611         if (i <= 0 || i > MAX_MODELS)
2612         {
2613                 VM_Warning("modelnameforindex: invalid modelindex\n");
2614                 return;
2615         }
2616         if (!sv.model_precache[i][0])
2617         {
2618                 VM_Warning("modelnameforindex: model not precached\n");
2619                 return;
2620         }
2621
2622         PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2623 }
2624
2625 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2626 static void VM_SV_particleeffectnum (void)
2627 {
2628         int                     i;
2629         VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2630         i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2631         if (i == 0)
2632                 i = -1;
2633         PRVM_G_FLOAT(OFS_RETURN) = i;
2634 }
2635
2636 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2637 static void VM_SV_trailparticles (void)
2638 {
2639         VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2640
2641         MSG_WriteByte(&sv.datagram, svc_trailparticles);
2642         MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2643         MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2644         MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2645         MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2646 }
2647
2648 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2649 static void VM_SV_pointparticles (void)
2650 {
2651         VM_SAFEPARMCOUNT(4, VM_SV_pointparticles);
2652
2653         MSG_WriteByte(&sv.datagram, svc_pointparticles);
2654         MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM0));
2655         MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1), sv.protocol);
2656         MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2657         MSG_WriteShort(&sv.datagram, bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535));
2658 }
2659
2660 prvm_builtin_t vm_sv_builtins[] = {
2661 NULL,                                                   // #0 NULL function (not callable) (QUAKE)
2662 VM_makevectors,                                 // #1 void(vector ang) makevectors (QUAKE)
2663 VM_SV_setorigin,                                // #2 void(entity e, vector o) setorigin (QUAKE)
2664 VM_SV_setmodel,                                 // #3 void(entity e, string m) setmodel (QUAKE)
2665 VM_SV_setsize,                                  // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2666 NULL,                                                   // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2667 VM_break,                                               // #6 void() break (QUAKE)
2668 VM_random,                                              // #7 float() random (QUAKE)
2669 VM_SV_sound,                                    // #8 void(entity e, float chan, string samp) sound (QUAKE)
2670 VM_normalize,                                   // #9 vector(vector v) normalize (QUAKE)
2671 VM_error,                                               // #10 void(string e) error (QUAKE)
2672 VM_objerror,                                    // #11 void(string e) objerror (QUAKE)
2673 VM_vlen,                                                // #12 float(vector v) vlen (QUAKE)
2674 VM_vectoyaw,                                    // #13 float(vector v) vectoyaw (QUAKE)
2675 VM_spawn,                                               // #14 entity() spawn (QUAKE)
2676 VM_remove,                                              // #15 void(entity e) remove (QUAKE)
2677 VM_SV_traceline,                                // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2678 VM_SV_checkclient,                              // #17 entity() checkclient (QUAKE)
2679 VM_find,                                                // #18 entity(entity start, .string fld, string match) find (QUAKE)
2680 VM_SV_precache_sound,                   // #19 void(string s) precache_sound (QUAKE)
2681 VM_SV_precache_model,                   // #20 void(string s) precache_model (QUAKE)
2682 VM_SV_stuffcmd,                                 // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2683 VM_SV_findradius,                               // #22 entity(vector org, float rad) findradius (QUAKE)
2684 VM_bprint,                                              // #23 void(string s, ...) bprint (QUAKE)
2685 VM_SV_sprint,                                   // #24 void(entity client, string s, ...) sprint (QUAKE)
2686 VM_dprint,                                              // #25 void(string s, ...) dprint (QUAKE)
2687 VM_ftos,                                                // #26 string(float f) ftos (QUAKE)
2688 VM_vtos,                                                // #27 string(vector v) vtos (QUAKE)
2689 VM_coredump,                                    // #28 void() coredump (QUAKE)
2690 VM_traceon,                                             // #29 void() traceon (QUAKE)
2691 VM_traceoff,                                    // #30 void() traceoff (QUAKE)
2692 VM_eprint,                                              // #31 void(entity e) eprint (QUAKE)
2693 VM_SV_walkmove,                                 // #32 float(float yaw, float dist) walkmove (QUAKE)
2694 NULL,                                                   // #33 (QUAKE)
2695 VM_SV_droptofloor,                              // #34 float() droptofloor (QUAKE)
2696 VM_SV_lightstyle,                               // #35 void(float style, string value) lightstyle (QUAKE)
2697 VM_rint,                                                // #36 float(float v) rint (QUAKE)
2698 VM_floor,                                               // #37 float(float v) floor (QUAKE)
2699 VM_ceil,                                                // #38 float(float v) ceil (QUAKE)
2700 NULL,                                                   // #39 (QUAKE)
2701 VM_SV_checkbottom,                              // #40 float(entity e) checkbottom (QUAKE)
2702 VM_SV_pointcontents,                    // #41 float(vector v) pointcontents (QUAKE)
2703 NULL,                                                   // #42 (QUAKE)
2704 VM_fabs,                                                // #43 float(float f) fabs (QUAKE)
2705 VM_SV_aim,                                              // #44 vector(entity e, float speed) aim (QUAKE)
2706 VM_cvar,                                                // #45 float(string s) cvar (QUAKE)
2707 VM_localcmd,                                    // #46 void(string s) localcmd (QUAKE)
2708 VM_nextent,                                             // #47 entity(entity e) nextent (QUAKE)
2709 VM_SV_particle,                                 // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2710 VM_changeyaw,                                   // #49 void() ChangeYaw (QUAKE)
2711 NULL,                                                   // #50 (QUAKE)
2712 VM_vectoangles,                                 // #51 vector(vector v) vectoangles (QUAKE)
2713 VM_SV_WriteByte,                                // #52 void(float to, float f) WriteByte (QUAKE)
2714 VM_SV_WriteChar,                                // #53 void(float to, float f) WriteChar (QUAKE)
2715 VM_SV_WriteShort,                               // #54 void(float to, float f) WriteShort (QUAKE)
2716 VM_SV_WriteLong,                                // #55 void(float to, float f) WriteLong (QUAKE)
2717 VM_SV_WriteCoord,                               // #56 void(float to, float f) WriteCoord (QUAKE)
2718 VM_SV_WriteAngle,                               // #57 void(float to, float f) WriteAngle (QUAKE)
2719 VM_SV_WriteString,                              // #58 void(float to, string s) WriteString (QUAKE)
2720 VM_SV_WriteEntity,                              // #59 void(float to, entity e) WriteEntity (QUAKE)
2721 VM_sin,                                                 // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2722 VM_cos,                                                 // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2723 VM_sqrt,                                                // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2724 VM_changepitch,                                 // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2725 VM_SV_tracetoss,                                // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2726 VM_etos,                                                // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2727 NULL,                                                   // #66 (QUAKE)
2728 SV_MoveToGoal,                                  // #67 void(float step) movetogoal (QUAKE)
2729 VM_precache_file,                               // #68 string(string s) precache_file (QUAKE)
2730 VM_SV_makestatic,                               // #69 void(entity e) makestatic (QUAKE)
2731 VM_changelevel,                                 // #70 void(string s) changelevel (QUAKE)
2732 NULL,                                                   // #71 (QUAKE)
2733 VM_cvar_set,                                    // #72 void(string var, string val) cvar_set (QUAKE)
2734 VM_SV_centerprint,                              // #73 void(entity client, strings) centerprint (QUAKE)
2735 VM_SV_ambientsound,                             // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2736 VM_SV_precache_model,                   // #75 string(string s) precache_model2 (QUAKE)
2737 VM_SV_precache_sound,                   // #76 string(string s) precache_sound2 (QUAKE)
2738 VM_precache_file,                               // #77 string(string s) precache_file2 (QUAKE)
2739 VM_SV_setspawnparms,                    // #78 void(entity e) setspawnparms (QUAKE)
2740 NULL,                                                   // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2741 NULL,                                                   // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2742 VM_stof,                                                // #81 float(string s) stof (FRIK_FILE)
2743 NULL,                                                   // #82 void(vector where, float set) multicast (QUAKEWORLD)
2744 NULL,                                                   // #83 (QUAKE)
2745 NULL,                                                   // #84 (QUAKE)
2746 NULL,                                                   // #85 (QUAKE)
2747 NULL,                                                   // #86 (QUAKE)
2748 NULL,                                                   // #87 (QUAKE)
2749 NULL,                                                   // #88 (QUAKE)
2750 NULL,                                                   // #89 (QUAKE)
2751 VM_SV_tracebox,                                 // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2752 VM_randomvec,                                   // #91 vector() randomvec (DP_QC_RANDOMVEC)
2753 VM_SV_getlight,                                 // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2754 VM_registercvar,                                // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2755 VM_min,                                                 // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2756 VM_max,                                                 // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2757 VM_bound,                                               // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2758 VM_pow,                                                 // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2759 VM_findfloat,                                   // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2760 VM_checkextension,                              // #99 float(string s) checkextension (the basis of the extension system)
2761 // FrikaC and Telejano range  #100-#199
2762 NULL,                                                   // #100
2763 NULL,                                                   // #101
2764 NULL,                                                   // #102
2765 NULL,                                                   // #103
2766 NULL,                                                   // #104
2767 NULL,                                                   // #105
2768 NULL,                                                   // #106
2769 NULL,                                                   // #107
2770 NULL,                                                   // #108
2771 NULL,                                                   // #109
2772 VM_fopen,                                               // #110 float(string filename, float mode) fopen (FRIK_FILE)
2773 VM_fclose,                                              // #111 void(float fhandle) fclose (FRIK_FILE)
2774 VM_fgets,                                               // #112 string(float fhandle) fgets (FRIK_FILE)
2775 VM_fputs,                                               // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2776 VM_strlen,                                              // #114 float(string s) strlen (FRIK_FILE)
2777 VM_strcat,                                              // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2778 VM_substring,                                   // #116 string(string s, float start, float length) substring (FRIK_FILE)
2779 VM_stov,                                                // #117 vector(string) stov (FRIK_FILE)
2780 VM_strzone,                                             // #118 string(string s) strzone (FRIK_FILE)
2781 VM_strunzone,                                   // #119 void(string s) strunzone (FRIK_FILE)
2782 NULL,                                                   // #120
2783 NULL,                                                   // #121
2784 NULL,                                                   // #122
2785 NULL,                                                   // #123
2786 NULL,                                                   // #124
2787 NULL,                                                   // #125
2788 NULL,                                                   // #126
2789 NULL,                                                   // #127
2790 NULL,                                                   // #128
2791 NULL,                                                   // #129
2792 NULL,                                                   // #130
2793 NULL,                                                   // #131
2794 NULL,                                                   // #132
2795 NULL,                                                   // #133
2796 NULL,                                                   // #134
2797 NULL,                                                   // #135
2798 NULL,                                                   // #136
2799 NULL,                                                   // #137
2800 NULL,                                                   // #138
2801 NULL,                                                   // #139
2802 NULL,                                                   // #140
2803 NULL,                                                   // #141
2804 NULL,                                                   // #142
2805 NULL,                                                   // #143
2806 NULL,                                                   // #144
2807 NULL,                                                   // #145
2808 NULL,                                                   // #146
2809 NULL,                                                   // #147
2810 NULL,                                                   // #148
2811 NULL,                                                   // #149
2812 NULL,                                                   // #150
2813 NULL,                                                   // #151
2814 NULL,                                                   // #152
2815 NULL,                                                   // #153
2816 NULL,                                                   // #154
2817 NULL,                                                   // #155
2818 NULL,                                                   // #156
2819 NULL,                                                   // #157
2820 NULL,                                                   // #158
2821 NULL,                                                   // #159
2822 NULL,                                                   // #160
2823 NULL,                                                   // #161
2824 NULL,                                                   // #162
2825 NULL,                                                   // #163
2826 NULL,                                                   // #164
2827 NULL,                                                   // #165
2828 NULL,                                                   // #166
2829 NULL,                                                   // #167
2830 NULL,                                                   // #168
2831 NULL,                                                   // #169
2832 NULL,                                                   // #170
2833 NULL,                                                   // #171
2834 NULL,                                                   // #172
2835 NULL,                                                   // #173
2836 NULL,                                                   // #174
2837 NULL,                                                   // #175
2838 NULL,                                                   // #176
2839 NULL,                                                   // #177
2840 NULL,                                                   // #178
2841 NULL,                                                   // #179
2842 NULL,                                                   // #180
2843 NULL,                                                   // #181
2844 NULL,                                                   // #182
2845 NULL,                                                   // #183
2846 NULL,                                                   // #184
2847 NULL,                                                   // #185
2848 NULL,                                                   // #186
2849 NULL,                                                   // #187
2850 NULL,                                                   // #188
2851 NULL,                                                   // #189
2852 NULL,                                                   // #190
2853 NULL,                                                   // #191
2854 NULL,                                                   // #192
2855 NULL,                                                   // #193
2856 NULL,                                                   // #194
2857 NULL,                                                   // #195
2858 NULL,                                                   // #196
2859 NULL,                                                   // #197
2860 NULL,                                                   // #198
2861 NULL,                                                   // #199
2862 // FTEQW range #200-#299
2863 NULL,                                                   // #200
2864 NULL,                                                   // #201
2865 NULL,                                                   // #202
2866 NULL,                                                   // #203
2867 NULL,                                                   // #204
2868 NULL,                                                   // #205
2869 NULL,                                                   // #206
2870 NULL,                                                   // #207
2871 NULL,                                                   // #208
2872 NULL,                                                   // #209
2873 NULL,                                                   // #210
2874 NULL,                                                   // #211
2875 NULL,                                                   // #212
2876 NULL,                                                   // #213
2877 NULL,                                                   // #214
2878 NULL,                                                   // #215
2879 NULL,                                                   // #216
2880 NULL,                                                   // #217
2881 VM_bitshift,                                    // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2882 NULL,                                                   // #219
2883 NULL,                                                   // #220
2884 NULL,                                                   // #221
2885 VM_str2chr,                                             // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2886 VM_chr2str,                                             // #223 string(float c, ...) chr2str (FTE_STRINGS)
2887 NULL,                                                   // #224
2888 NULL,                                                   // #225
2889 NULL,                                                   // #226
2890 NULL,                                                   // #227
2891 VM_strncmp,                                             // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2892 NULL,                                                   // #229
2893 NULL,                                                   // #230
2894 NULL,                                                   // #231
2895 VM_SV_AddStat,                                  // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2896 NULL,                                                   // #233
2897 NULL,                                                   // #234
2898 NULL,                                                   // #235
2899 NULL,                                                   // #236
2900 NULL,                                                   // #237
2901 NULL,                                                   // #238
2902 NULL,                                                   // #239
2903 NULL,                                                   // #240
2904 NULL,                                                   // #241
2905 NULL,                                                   // #242
2906 NULL,                                                   // #243
2907 NULL,                                                   // #244
2908 NULL,                                                   // #245
2909 NULL,                                                   // #246
2910 NULL,                                                   // #247
2911 NULL,                                                   // #248
2912 NULL,                                                   // #249
2913 NULL,                                                   // #250
2914 NULL,                                                   // #251
2915 NULL,                                                   // #252
2916 NULL,                                                   // #253
2917 NULL,                                                   // #254
2918 NULL,                                                   // #255
2919 NULL,                                                   // #256
2920 NULL,                                                   // #257
2921 NULL,                                                   // #258
2922 NULL,                                                   // #259
2923 NULL,                                                   // #260
2924 NULL,                                                   // #261
2925 NULL,                                                   // #262
2926 NULL,                                                   // #263
2927 NULL,                                                   // #264
2928 NULL,                                                   // #265
2929 NULL,                                                   // #266
2930 NULL,                                                   // #267
2931 NULL,                                                   // #268
2932 NULL,                                                   // #269
2933 NULL,                                                   // #270
2934 NULL,                                                   // #271
2935 NULL,                                                   // #272
2936 NULL,                                                   // #273
2937 NULL,                                                   // #274
2938 NULL,                                                   // #275
2939 NULL,                                                   // #276
2940 NULL,                                                   // #277
2941 NULL,                                                   // #278
2942 NULL,                                                   // #279
2943 NULL,                                                   // #280
2944 NULL,                                                   // #281
2945 NULL,                                                   // #282
2946 NULL,                                                   // #283
2947 NULL,                                                   // #284
2948 NULL,                                                   // #285
2949 NULL,                                                   // #286
2950 NULL,                                                   // #287
2951 NULL,                                                   // #288
2952 NULL,                                                   // #289
2953 NULL,                                                   // #290
2954 NULL,                                                   // #291
2955 NULL,                                                   // #292
2956 NULL,                                                   // #293
2957 NULL,                                                   // #294
2958 NULL,                                                   // #295
2959 NULL,                                                   // #296
2960 NULL,                                                   // #297
2961 NULL,                                                   // #298
2962 NULL,                                                   // #299
2963 // CSQC range #300-#399
2964 NULL,                                                   // #300 void() clearscene (EXT_CSQC)
2965 NULL,                                                   // #301 void(float mask) addentities (EXT_CSQC)
2966 NULL,                                                   // #302 void(entity ent) addentity (EXT_CSQC)
2967 NULL,                                                   // #303 float(float property, ...) setproperty (EXT_CSQC)
2968 NULL,                                                   // #304 void() renderscene (EXT_CSQC)
2969 NULL,                                                   // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2970 NULL,                                                   // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2971 NULL,                                                   // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2972 NULL,                                                   // #308 void() R_EndPolygon
2973 NULL,                                                   // #309
2974 NULL,                                                   // #310 vector (vector v) cs_unproject (EXT_CSQC)
2975 NULL,                                                   // #311 vector (vector v) cs_project (EXT_CSQC)
2976 NULL,                                                   // #312
2977 NULL,                                                   // #313
2978 NULL,                                                   // #314
2979 NULL,                                                   // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
2980 NULL,                                                   // #316 float(string name) iscachedpic (EXT_CSQC)
2981 NULL,                                                   // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
2982 NULL,                                                   // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
2983 NULL,                                                   // #319 void(string name) freepic (EXT_CSQC)
2984 NULL,                                                   // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
2985 NULL,                                                   // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
2986 NULL,                                                   // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
2987 NULL,                                                   // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
2988 NULL,                                                   // #324 void(float x, float y, float width, float height) drawsetcliparea
2989 NULL,                                                   // #325 void(void) drawresetcliparea
2990 NULL,                                                   // #326
2991 NULL,                                                   // #327
2992 NULL,                                                   // #328
2993 NULL,                                                   // #329
2994 NULL,                                                   // #330 float(float stnum) getstatf (EXT_CSQC)
2995 NULL,                                                   // #331 float(float stnum) getstati (EXT_CSQC)
2996 NULL,                                                   // #332 string(float firststnum) getstats (EXT_CSQC)
2997 VM_SV_setmodelindex,                    // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2998 VM_SV_modelnameforindex,                // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2999 VM_SV_particleeffectnum,                // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3000 VM_SV_trailparticles,                   // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3001 VM_SV_pointparticles,                   // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3002 NULL,                                                   // #338 void(string s, ...) centerprint (EXT_CSQC)
3003 VM_print,                                               // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3004 NULL,                                                   // #340 string(float keynum) keynumtostring (EXT_CSQC)
3005 NULL,                                                   // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3006 NULL,                                                   // #342 string(float keynum) getkeybind (EXT_CSQC)
3007 NULL,                                                   // #343 void(float usecursor) setcursormode (EXT_CSQC)
3008 NULL,                                                   // #344 vector() getmousepos (EXT_CSQC)
3009 NULL,                                                   // #345 float(float framenum) getinputstate (EXT_CSQC)
3010 NULL,                                                   // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3011 NULL,                                                   // #347 void() runstandardplayerphysics (EXT_CSQC)
3012 NULL,                                                   // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3013 NULL,                                                   // #349 float() isdemo (EXT_CSQC)
3014 VM_isserver,                                    // #350 float() isserver (EXT_CSQC)
3015 NULL,                                                   // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3016 NULL,                                                   // #352 void(string cmdname) registercommand (EXT_CSQC)
3017 VM_wasfreed,                                    // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3018 VM_SV_serverkey,                                // #354 string(string key) serverkey (EXT_CSQC)
3019 NULL,                                                   // #355
3020 NULL,                                                   // #356
3021 NULL,                                                   // #357
3022 NULL,                                                   // #358
3023 NULL,                                                   // #359
3024 NULL,                                                   // #360 float() readbyte (EXT_CSQC)
3025 NULL,                                                   // #361 float() readchar (EXT_CSQC)
3026 NULL,                                                   // #362 float() readshort (EXT_CSQC)
3027 NULL,                                                   // #363 float() readlong (EXT_CSQC)
3028 NULL,                                                   // #364 float() readcoord (EXT_CSQC)
3029 NULL,                                                   // #365 float() readangle (EXT_CSQC)
3030 NULL,                                                   // #366 string() readstring (EXT_CSQC)
3031 NULL,                                                   // #367 float() readfloat (EXT_CSQC)
3032 NULL,                                                   // #368
3033 NULL,                                                   // #369
3034 NULL,                                                   // #370
3035 NULL,                                                   // #371
3036 NULL,                                                   // #372
3037 NULL,                                                   // #373
3038 NULL,                                                   // #374
3039 NULL,                                                   // #375
3040 NULL,                                                   // #376
3041 NULL,                                                   // #377
3042 NULL,                                                   // #378
3043 NULL,                                                   // #379
3044 NULL,                                                   // #380
3045 NULL,                                                   // #381
3046 NULL,                                                   // #382
3047 NULL,                                                   // #383
3048 NULL,                                                   // #384
3049 NULL,                                                   // #385
3050 NULL,                                                   // #386
3051 NULL,                                                   // #387
3052 NULL,                                                   // #388
3053 NULL,                                                   // #389
3054 NULL,                                                   // #390
3055 NULL,                                                   // #391
3056 NULL,                                                   // #392
3057 NULL,                                                   // #393
3058 NULL,                                                   // #394
3059 NULL,                                                   // #395
3060 NULL,                                                   // #396
3061 NULL,                                                   // #397
3062 NULL,                                                   // #398
3063 NULL,                                                   // #399
3064 // LordHavoc's range #400-#499
3065 VM_SV_copyentity,                               // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3066 VM_SV_setcolor,                                 // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3067 VM_findchain,                                   // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3068 VM_findchainfloat,                              // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3069 VM_SV_effect,                                   // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3070 VM_SV_te_blood,                                 // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3071 VM_SV_te_bloodshower,                   // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3072 VM_SV_te_explosionrgb,                  // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3073 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)
3074 VM_SV_te_particlerain,                  // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3075 VM_SV_te_particlesnow,                  // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3076 VM_SV_te_spark,                                 // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3077 VM_SV_te_gunshotquad,                   // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3078 VM_SV_te_spikequad,                             // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3079 VM_SV_te_superspikequad,                // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3080 VM_SV_te_explosionquad,                 // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3081 VM_SV_te_smallflash,                    // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3082 VM_SV_te_customflash,                   // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3083 VM_SV_te_gunshot,                               // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3084 VM_SV_te_spike,                                 // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3085 VM_SV_te_superspike,                    // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3086 VM_SV_te_explosion,                             // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3087 VM_SV_te_tarexplosion,                  // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3088 VM_SV_te_wizspike,                              // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3089 VM_SV_te_knightspike,                   // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3090 VM_SV_te_lavasplash,                    // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3091 VM_SV_te_teleport,                              // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3092 VM_SV_te_explosion2,                    // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3093 VM_SV_te_lightning1,                    // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3094 VM_SV_te_lightning2,                    // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3095 VM_SV_te_lightning3,                    // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3096 VM_SV_te_beam,                                  // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3097 VM_vectorvectors,                               // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3098 VM_SV_te_plasmaburn,                    // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3099 VM_SV_getsurfacenumpoints,              // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3100 VM_SV_getsurfacepoint,                  // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3101 VM_SV_getsurfacenormal,                 // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3102 VM_SV_getsurfacetexture,                // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3103 VM_SV_getsurfacenearpoint,              // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3104 VM_SV_getsurfaceclippedpoint,   // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3105 VM_SV_clientcommand,                    // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3106 VM_tokenize,                                    // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3107 VM_argv,                                                // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3108 VM_SV_setattachment,                    // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3109 VM_search_begin,                                // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
3110 VM_search_end,                                  // #445 void(float handle) search_end (DP_FS_SEARCH)
3111 VM_search_getsize,                              // #446 float(float handle) search_getsize (DP_FS_SEARCH)
3112 VM_search_getfilename,                  // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
3113 VM_cvar_string,                                 // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3114 VM_findflags,                                   // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3115 VM_findchainflags,                              // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3116 VM_SV_gettagindex,                              // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3117 VM_SV_gettaginfo,                               // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3118 VM_SV_dropclient,                               // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3119 VM_SV_spawnclient,                              // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3120 VM_SV_clienttype,                               // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3121 VM_SV_WriteUnterminatedString,  // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3122 VM_SV_te_flamejet,                              // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3123 NULL,                                                   // #458
3124 VM_ftoe,                                                // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3125 VM_buf_create,                                  // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3126 VM_buf_del,                                             // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3127 VM_buf_getsize,                                 // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3128 VM_buf_copy,                                    // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3129 VM_buf_sort,                                    // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3130 VM_buf_implode,                                 // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3131 VM_bufstr_get,                                  // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3132 VM_bufstr_set,                                  // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3133 VM_bufstr_add,                                  // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3134 VM_bufstr_free,                                 // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3135 NULL,                                                   // #470
3136 VM_asin,                                                // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3137 VM_acos,                                                // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3138 VM_atan,                                                // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3139 VM_atan2,                                               // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3140 VM_tan,                                                 // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3141 VM_strlennocol,                                 // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3142 VM_strdecolorize,                               // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3143 VM_strftime,                                    // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3144 NULL,                                                   // #479
3145 NULL,                                                   // #480
3146 NULL,                                                   // #481
3147 NULL,                                                   // #482
3148 NULL,                                                   // #483
3149 NULL,                                                   // #484
3150 NULL,                                                   // #485
3151 NULL,                                                   // #486
3152 NULL,                                                   // #487
3153 NULL,                                                   // #488
3154 NULL,                                                   // #489
3155 NULL,                                                   // #490
3156 NULL,                                                   // #491
3157 NULL,                                                   // #492
3158 NULL,                                                   // #493
3159 NULL,                                                   // #494
3160 NULL,                                                   // #495
3161 NULL,                                                   // #496
3162 NULL,                                                   // #497
3163 NULL,                                                   // #498
3164 NULL,                                                   // #499
3165 };
3166
3167 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3168
3169 void VM_SV_Cmd_Init(void)
3170 {
3171         VM_Cmd_Init();
3172 }
3173
3174 void VM_SV_Cmd_Reset(void)
3175 {
3176         VM_Cmd_Reset();
3177 }
3178