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