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