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