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