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