]> icculus.org git repositories - divverent/darkplaces.git/blob - svvm_cmds.c
fix v_flipped in cs_unproject (it was correct in cs_project) if a view port is set up
[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_LOWPRECISION "
42 "DP_ENT_SCALE "
43 "DP_ENT_VIEWMODEL "
44 "DP_GECKO_SUPPORT "
45 "DP_GFX_EXTERNALTEXTURES "
46 "DP_GFX_EXTERNALTEXTURES_PERMAP "
47 "DP_GFX_FOG "
48 "DP_GFX_QUAKE3MODELTAGS "
49 "DP_GFX_SKINFILES "
50 "DP_GFX_SKYBOX "
51 "DP_GFX_MODEL_INTERPOLATION "
52 "DP_HALFLIFE_MAP "
53 "DP_HALFLIFE_MAP_CVAR "
54 "DP_HALFLIFE_SPRITE "
55 "DP_INPUTBUTTONS "
56 "DP_LITSPRITES "
57 "DP_LITSUPPORT "
58 "DP_MONSTERWALK "
59 "DP_MOVETYPEBOUNCEMISSILE "
60 "DP_MOVETYPEFOLLOW "
61 "DP_NULL_MODEL "
62 "DP_QC_ASINACOSATANATAN2TAN "
63 "DP_QC_CHANGEPITCH "
64 "DP_QC_CMD "
65 "DP_QC_COPYENTITY "
66 "DP_QC_CRC16 "
67 "DP_QC_CVAR_DEFSTRING "
68 "DP_QC_CVAR_DESCRIPTION "
69 "DP_QC_CVAR_STRING "
70 "DP_QC_CVAR_TYPE "
71 "DP_QC_EDICT_NUM "
72 "DP_QC_ENTITYDATA "
73 "DP_QC_ETOS "
74 "DP_QC_EXTRESPONSEPACKET "
75 "DP_QC_FINDCHAIN "
76 "DP_QC_FINDCHAIN_TOFIELD "
77 "DP_QC_FINDCHAINFLAGS "
78 "DP_QC_FINDCHAINFLOAT "
79 "DP_QC_FINDFLAGS "
80 "DP_QC_FINDFLOAT "
81 "DP_QC_FS_SEARCH "
82 "DP_QC_GETLIGHT "
83 "DP_QC_GETSURFACE "
84 "DP_QC_GETSURFACEPOINTATTRIBUTE "
85 "DP_QC_GETTAGINFO "
86 "DP_QC_GETTAGINFO_BONEPROPERTIES "
87 "DP_QC_GETTIME "
88 "DP_QC_GETTIME_CDTRACK "
89 "DP_QC_MINMAXBOUND "
90 "DP_QC_MULTIPLETEMPSTRINGS "
91 "DP_QC_NUM_FOR_EDICT "
92 "DP_QC_RANDOMVEC "
93 "DP_QC_SINCOSSQRTPOW "
94 "DP_QC_STRFTIME "
95 "DP_QC_STRINGBUFFERS "
96 "DP_QC_STRINGBUFFERS_CVARLIST "
97 "DP_QC_STRINGCOLORFUNCTIONS "
98 "DP_QC_STRING_CASE_FUNCTIONS "
99 "DP_QC_STRREPLACE "
100 "DP_QC_TOKENIZEBYSEPARATOR "
101 "DP_QC_TOKENIZE_CONSOLE "
102 "DP_QC_TRACEBOX "
103 "DP_QC_TRACETOSS "
104 "DP_QC_TRACE_MOVETYPE_HITMODEL "
105 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
106 "DP_QC_UNLIMITEDTEMPSTRINGS "
107 "DP_QC_URI_ESCAPE "
108 "DP_QC_URI_GET "
109 "DP_QC_VECTOANGLES_WITH_ROLL "
110 "DP_QC_VECTORVECTORS "
111 "DP_QC_WHICHPACK "
112 "DP_QUAKE2_MODEL "
113 "DP_QUAKE2_SPRITE "
114 "DP_QUAKE3_MAP "
115 "DP_QUAKE3_MODEL "
116 "DP_REGISTERCVAR "
117 "DP_SND_DIRECTIONLESSATTNNONE "
118 "DP_SND_FAKETRACKS "
119 "DP_SND_OGGVORBIS "
120 "DP_SND_STEREOWAV "
121 "DP_SOLIDCORPSE "
122 "DP_SPRITE32 "
123 "DP_SV_BOTCLIENT "
124 "DP_SV_BOUNCEFACTOR "
125 "DP_SV_CLIENTCOLORS "
126 "DP_SV_CLIENTNAME "
127 "DP_SV_CMD "
128 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
129 "DP_SV_DRAWONLYTOCLIENT "
130 "DP_SV_DROPCLIENT "
131 "DP_SV_EFFECT "
132 "DP_SV_ENTITYCONTENTSTRANSITION "
133 "DP_SV_MODELFLAGS_AS_EFFECTS "
134 "DP_SV_MOVETYPESTEP_LANDEVENT "
135 "DP_SV_NETADDRESS "
136 "DP_SV_NODRAWTOCLIENT "
137 "DP_SV_ONENTITYNOSPAWNFUNCTION "
138 "DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
139 "DP_SV_PING "
140 "DP_SV_PLAYERPHYSICS "
141 "DP_SV_POINTPARTICLES "
142 "DP_SV_POINTSOUND "
143 "DP_SV_PRECACHEANYTIME "
144 "DP_SV_PRINT "
145 "DP_SV_PUNCHVECTOR "
146 "DP_SV_QCSTATUS "
147 "DP_SV_ROTATINGBMODEL "
148 "DP_SV_SETCOLOR "
149 "DP_SV_SHUTDOWN "
150 "DP_SV_SLOWMO "
151 "DP_SV_SPAWNFUNC_PREFIX "
152 "DP_SV_WRITEPICTURE "
153 "DP_SV_WRITEUNTERMINATEDSTRING "
154 "DP_TE_BLOOD "
155 "DP_TE_BLOODSHOWER "
156 "DP_TE_CUSTOMFLASH "
157 "DP_TE_EXPLOSIONRGB "
158 "DP_TE_FLAMEJET "
159 "DP_TE_PARTICLECUBE "
160 "DP_TE_PARTICLERAIN "
161 "DP_TE_PARTICLESNOW "
162 "DP_TE_PLASMABURN "
163 "DP_TE_QUADEFFECTS1 "
164 "DP_TE_SMALLFLASH "
165 "DP_TE_SPARK "
166 "DP_TE_STANDARDEFFECTBUILTINS "
167 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
168 "DP_VIEWZOOM "
169 "EXT_BITSHIFT "
170 "FRIK_FILE "
171 "FTE_QC_CHECKPVS "
172 "FTE_STRINGS "
173 "KRIMZON_SV_PARSECLIENTCOMMAND "
174 "NEH_CMD_PLAY2 "
175 "NEH_RESTOREGAME "
176 "NEXUIZ_PLAYERMODEL "
177 "NXQ_GFX_LETTERBOX "
178 "PRYDON_CLIENTCURSOR "
179 "TENEBRAE_GFX_DLIGHTS "
180 "TW_SV_STEPCONTROL "
181 "ZQ_PAUSE "
182 //"EXT_CSQC " // not ready yet
183 ;
184
185 /*
186 =================
187 VM_SV_setorigin
188
189 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.
190
191 setorigin (entity, origin)
192 =================
193 */
194 static void VM_SV_setorigin (void)
195 {
196         prvm_edict_t    *e;
197         float   *org;
198
199         VM_SAFEPARMCOUNT(2, VM_setorigin);
200
201         e = PRVM_G_EDICT(OFS_PARM0);
202         if (e == prog->edicts)
203         {
204                 VM_Warning("setorigin: can not modify world entity\n");
205                 return;
206         }
207         if (e->priv.server->free)
208         {
209                 VM_Warning("setorigin: can not modify free entity\n");
210                 return;
211         }
212         org = PRVM_G_VECTOR(OFS_PARM1);
213         VectorCopy (org, e->fields.server->origin);
214         SV_LinkEdict (e, false);
215 }
216
217 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
218 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
219 {
220         int             i;
221
222         for (i=0 ; i<3 ; i++)
223                 if (min[i] > max[i])
224                         PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
225
226 // set derived values
227         VectorCopy (min, e->fields.server->mins);
228         VectorCopy (max, e->fields.server->maxs);
229         VectorSubtract (max, min, e->fields.server->size);
230
231         SV_LinkEdict (e, false);
232 }
233
234 /*
235 =================
236 VM_SV_setsize
237
238 the size box is rotated by the current angle
239 LordHavoc: no it isn't...
240
241 setsize (entity, minvector, maxvector)
242 =================
243 */
244 static void VM_SV_setsize (void)
245 {
246         prvm_edict_t    *e;
247         float   *min, *max;
248
249         VM_SAFEPARMCOUNT(3, VM_setsize);
250
251         e = PRVM_G_EDICT(OFS_PARM0);
252         if (e == prog->edicts)
253         {
254                 VM_Warning("setsize: can not modify world entity\n");
255                 return;
256         }
257         if (e->priv.server->free)
258         {
259                 VM_Warning("setsize: can not modify free entity\n");
260                 return;
261         }
262         min = PRVM_G_VECTOR(OFS_PARM1);
263         max = PRVM_G_VECTOR(OFS_PARM2);
264         SetMinMaxSize (e, min, max, false);
265 }
266
267
268 /*
269 =================
270 VM_SV_setmodel
271
272 setmodel(entity, model)
273 =================
274 */
275 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
276 static void VM_SV_setmodel (void)
277 {
278         prvm_edict_t    *e;
279         dp_model_t      *mod;
280         int             i;
281
282         VM_SAFEPARMCOUNT(2, VM_setmodel);
283
284         e = PRVM_G_EDICT(OFS_PARM0);
285         if (e == prog->edicts)
286         {
287                 VM_Warning("setmodel: can not modify world entity\n");
288                 return;
289         }
290         if (e->priv.server->free)
291         {
292                 VM_Warning("setmodel: can not modify free entity\n");
293                 return;
294         }
295         i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
296         e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
297         e->fields.server->modelindex = i;
298
299         mod = sv.models[i];
300
301         if (mod)
302         {
303                 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
304                         SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
305                 else
306                         SetMinMaxSize (e, quakemins, quakemaxs, true);
307         }
308         else
309                 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
310 }
311
312 /*
313 =================
314 VM_SV_sprint
315
316 single print to a specific client
317
318 sprint(clientent, value)
319 =================
320 */
321 static void VM_SV_sprint (void)
322 {
323         client_t        *client;
324         int                     entnum;
325         char string[VM_STRINGTEMP_LENGTH];
326
327         VM_VarString(1, string, sizeof(string));
328
329         VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
330
331         entnum = PRVM_G_EDICTNUM(OFS_PARM0);
332         // LordHavoc: div0 requested that sprintto world  operate like print
333         if (entnum == 0)
334         {
335                 Con_Print(string);
336                 return;
337         }
338
339         if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
340         {
341                 VM_Warning("tried to centerprint to a non-client\n");
342                 return;
343         }
344
345         client = svs.clients + entnum-1;
346         if (!client->netconnection)
347                 return;
348
349         MSG_WriteChar(&client->netconnection->message,svc_print);
350         MSG_WriteString(&client->netconnection->message, string);
351 }
352
353
354 /*
355 =================
356 VM_SV_centerprint
357
358 single print to a specific client
359
360 centerprint(clientent, value)
361 =================
362 */
363 static void VM_SV_centerprint (void)
364 {
365         client_t        *client;
366         int                     entnum;
367         char string[VM_STRINGTEMP_LENGTH];
368
369         VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
370
371         entnum = PRVM_G_EDICTNUM(OFS_PARM0);
372
373         if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
374         {
375                 VM_Warning("tried to centerprint to a non-client\n");
376                 return;
377         }
378
379         client = svs.clients + entnum-1;
380         if (!client->netconnection)
381                 return;
382
383         VM_VarString(1, string, sizeof(string));
384         MSG_WriteChar(&client->netconnection->message,svc_centerprint);
385         MSG_WriteString(&client->netconnection->message, string);
386 }
387
388 /*
389 =================
390 VM_SV_particle
391
392 particle(origin, color, count)
393 =================
394 */
395 static void VM_SV_particle (void)
396 {
397         float           *org, *dir;
398         float           color;
399         float           count;
400
401         VM_SAFEPARMCOUNT(4, VM_SV_particle);
402
403         org = PRVM_G_VECTOR(OFS_PARM0);
404         dir = PRVM_G_VECTOR(OFS_PARM1);
405         color = PRVM_G_FLOAT(OFS_PARM2);
406         count = PRVM_G_FLOAT(OFS_PARM3);
407         SV_StartParticle (org, dir, (int)color, (int)count);
408 }
409
410
411 /*
412 =================
413 VM_SV_ambientsound
414
415 =================
416 */
417 static void VM_SV_ambientsound (void)
418 {
419         const char      *samp;
420         float           *pos;
421         float           vol, attenuation;
422         int                     soundnum, large;
423
424         VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
425
426         pos = PRVM_G_VECTOR (OFS_PARM0);
427         samp = PRVM_G_STRING(OFS_PARM1);
428         vol = PRVM_G_FLOAT(OFS_PARM2);
429         attenuation = PRVM_G_FLOAT(OFS_PARM3);
430
431 // check to see if samp was properly precached
432         soundnum = SV_SoundIndex(samp, 1);
433         if (!soundnum)
434                 return;
435
436         large = false;
437         if (soundnum >= 256)
438                 large = true;
439
440         // add an svc_spawnambient command to the level signon packet
441
442         if (large)
443                 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
444         else
445                 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
446
447         MSG_WriteVector(&sv.signon, pos, sv.protocol);
448
449         if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
450                 MSG_WriteShort (&sv.signon, soundnum);
451         else
452                 MSG_WriteByte (&sv.signon, soundnum);
453
454         MSG_WriteByte (&sv.signon, (int)(vol*255));
455         MSG_WriteByte (&sv.signon, (int)(attenuation*64));
456
457 }
458
459 /*
460 =================
461 VM_SV_sound
462
463 Each entity can have eight independant sound sources, like voice,
464 weapon, feet, etc.
465
466 Channel 0 is an auto-allocate channel, the others override anything
467 already running on that entity/channel pair.
468
469 An attenuation of 0 will play full volume everywhere in the level.
470 Larger attenuations will drop off.
471
472 =================
473 */
474 static void VM_SV_sound (void)
475 {
476         const char      *sample;
477         int                     channel;
478         prvm_edict_t            *entity;
479         int             volume;
480         float attenuation;
481
482         VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
483
484         entity = PRVM_G_EDICT(OFS_PARM0);
485         channel = (int)PRVM_G_FLOAT(OFS_PARM1);
486         sample = PRVM_G_STRING(OFS_PARM2);
487         volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
488         attenuation = PRVM_G_FLOAT(OFS_PARM4);
489         if (prog->argc < 5)
490         {
491                 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
492                 attenuation = 1;
493         }
494
495         if (volume < 0 || volume > 255)
496         {
497                 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
498                 return;
499         }
500
501         if (attenuation < 0 || attenuation > 4)
502         {
503                 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
504                 return;
505         }
506
507         if (channel < 0 || channel > 7)
508         {
509                 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
510                 return;
511         }
512
513         SV_StartSound (entity, channel, sample, volume, attenuation);
514 }
515
516 /*
517 =================
518 VM_SV_pointsound
519
520 Follows the same logic as VM_SV_sound, except instead of
521 an entity, an origin for the sound is provided, and channel
522 is omitted (since no entity is being tracked).
523
524 =================
525 */
526 static void VM_SV_pointsound(void)
527 {
528         const char      *sample;
529         int             volume;
530         float           attenuation;
531         vec3_t          org;
532
533         VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
534
535         VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
536         sample = PRVM_G_STRING(OFS_PARM1);
537         volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
538         attenuation = PRVM_G_FLOAT(OFS_PARM3);
539
540         if (volume < 0 || volume > 255)
541         {
542                 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
543                 return;
544         }
545
546         if (attenuation < 0 || attenuation > 4)
547         {
548                 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
549                 return;
550         }
551
552         SV_StartPointSound (org, sample, volume, attenuation);
553 }
554
555 /*
556 =================
557 VM_SV_traceline
558
559 Used for use tracing and shot targeting
560 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
561 if the tryents flag is set.
562
563 traceline (vector1, vector2, movetype, ignore)
564 =================
565 */
566 static void VM_SV_traceline (void)
567 {
568         float   *v1, *v2;
569         trace_t trace;
570         int             move;
571         prvm_edict_t    *ent;
572
573         VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
574
575         prog->xfunction->builtinsprofile += 30;
576
577         v1 = PRVM_G_VECTOR(OFS_PARM0);
578         v2 = PRVM_G_VECTOR(OFS_PARM1);
579         move = (int)PRVM_G_FLOAT(OFS_PARM2);
580         ent = PRVM_G_EDICT(OFS_PARM3);
581
582         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]))
583                 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));
584
585         trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
586
587         VM_SetTraceGlobals(&trace);
588 }
589
590
591 /*
592 =================
593 VM_SV_tracebox
594
595 Used for use tracing and shot targeting
596 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
597 if the tryents flag is set.
598
599 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
600 =================
601 */
602 // LordHavoc: added this for my own use, VERY useful, similar to traceline
603 static void VM_SV_tracebox (void)
604 {
605         float   *v1, *v2, *m1, *m2;
606         trace_t trace;
607         int             move;
608         prvm_edict_t    *ent;
609
610         VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
611
612         prog->xfunction->builtinsprofile += 30;
613
614         v1 = PRVM_G_VECTOR(OFS_PARM0);
615         m1 = PRVM_G_VECTOR(OFS_PARM1);
616         m2 = PRVM_G_VECTOR(OFS_PARM2);
617         v2 = PRVM_G_VECTOR(OFS_PARM3);
618         move = (int)PRVM_G_FLOAT(OFS_PARM4);
619         ent = PRVM_G_EDICT(OFS_PARM5);
620
621         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]))
622                 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));
623
624         trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
625
626         VM_SetTraceGlobals(&trace);
627 }
628
629 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
630 {
631         int i;
632         float gravity;
633         vec3_t move, end;
634         vec3_t original_origin;
635         vec3_t original_velocity;
636         vec3_t original_angles;
637         vec3_t original_avelocity;
638         prvm_eval_t *val;
639         trace_t trace;
640
641         VectorCopy(tossent->fields.server->origin   , original_origin   );
642         VectorCopy(tossent->fields.server->velocity , original_velocity );
643         VectorCopy(tossent->fields.server->angles   , original_angles   );
644         VectorCopy(tossent->fields.server->avelocity, original_avelocity);
645
646         val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
647         if (val != NULL && val->_float != 0)
648                 gravity = val->_float;
649         else
650                 gravity = 1.0;
651         gravity *= sv_gravity.value * 0.025;
652
653         for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
654         {
655                 SV_CheckVelocity (tossent);
656                 tossent->fields.server->velocity[2] -= gravity;
657                 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
658                 VectorScale (tossent->fields.server->velocity, 0.05, move);
659                 VectorAdd (tossent->fields.server->origin, move, end);
660                 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
661                 VectorCopy (trace.endpos, tossent->fields.server->origin);
662                 tossent->fields.server->velocity[2] -= gravity;
663
664                 if (trace.fraction < 1)
665                         break;
666         }
667
668         VectorCopy(original_origin   , tossent->fields.server->origin   );
669         VectorCopy(original_velocity , tossent->fields.server->velocity );
670         VectorCopy(original_angles   , tossent->fields.server->angles   );
671         VectorCopy(original_avelocity, tossent->fields.server->avelocity);
672
673         return trace;
674 }
675
676 static void VM_SV_tracetoss (void)
677 {
678         trace_t trace;
679         prvm_edict_t    *ent;
680         prvm_edict_t    *ignore;
681
682         VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
683
684         prog->xfunction->builtinsprofile += 600;
685
686         ent = PRVM_G_EDICT(OFS_PARM0);
687         if (ent == prog->edicts)
688         {
689                 VM_Warning("tracetoss: can not use world entity\n");
690                 return;
691         }
692         ignore = PRVM_G_EDICT(OFS_PARM1);
693
694         trace = SV_Trace_Toss (ent, ignore);
695
696         VM_SetTraceGlobals(&trace);
697 }
698
699 //============================================================================
700
701 static int checkpvsbytes;
702 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
703
704 static int VM_SV_newcheckclient (int check)
705 {
706         int             i;
707         prvm_edict_t    *ent;
708         vec3_t  org;
709
710 // cycle to the next one
711
712         check = bound(1, check, svs.maxclients);
713         if (check == svs.maxclients)
714                 i = 1;
715         else
716                 i = check + 1;
717
718         for ( ;  ; i++)
719         {
720                 // count the cost
721                 prog->xfunction->builtinsprofile++;
722                 // wrap around
723                 if (i == svs.maxclients+1)
724                         i = 1;
725                 // look up the client's edict
726                 ent = PRVM_EDICT_NUM(i);
727                 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
728                 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
729                         continue;
730                 // found a valid client (possibly the same one again)
731                 break;
732         }
733
734 // get the PVS for the entity
735         VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
736         checkpvsbytes = 0;
737         if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
738                 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
739
740         return i;
741 }
742
743 /*
744 =================
745 VM_SV_checkclient
746
747 Returns a client (or object that has a client enemy) that would be a
748 valid target.
749
750 If there is more than one valid option, they are cycled each frame
751
752 If (self.origin + self.viewofs) is not in the PVS of the current target,
753 it is not returned at all.
754
755 name checkclient ()
756 =================
757 */
758 int c_invis, c_notvis;
759 static void VM_SV_checkclient (void)
760 {
761         prvm_edict_t    *ent, *self;
762         vec3_t  view;
763
764         VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
765
766         // find a new check if on a new frame
767         if (sv.time - sv.lastchecktime >= 0.1)
768         {
769                 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
770                 sv.lastchecktime = sv.time;
771         }
772
773         // return check if it might be visible
774         ent = PRVM_EDICT_NUM(sv.lastcheck);
775         if (ent->priv.server->free || ent->fields.server->health <= 0)
776         {
777                 VM_RETURN_EDICT(prog->edicts);
778                 return;
779         }
780
781         // if current entity can't possibly see the check entity, return 0
782         self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
783         VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
784         if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
785         {
786                 c_notvis++;
787                 VM_RETURN_EDICT(prog->edicts);
788                 return;
789         }
790
791         // might be able to see it
792         c_invis++;
793         VM_RETURN_EDICT(ent);
794 }
795
796 //============================================================================
797
798 /*
799 =================
800 VM_SV_checkpvs
801
802 Checks if an entity is in a point's PVS.
803 Should be fast but can be inexact.
804
805 float checkpvs(vector viewpos, entity viewee) = #240;
806 =================
807 */
808 static void VM_SV_checkpvs (void)
809 {
810         vec3_t viewpos;
811         prvm_edict_t *viewee;
812 #if 1
813         unsigned char *pvs;
814 #else
815         static int fatpvsbytes;
816         static unsigned char fatpvs[MAX_MAP_LEAFS/8];
817 #endif
818
819         VM_SAFEPARMCOUNT(2, VM_SV_checkpvs);
820         VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos);
821         viewee = PRVM_G_EDICT(OFS_PARM1);
822
823         if(viewee->priv.server->free)
824         {
825                 VM_Warning("checkpvs: can not check free entity\n");
826                 PRVM_G_FLOAT(OFS_RETURN) = 4;
827                 return;
828         }
829
830 #if 1
831         if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
832         {
833                 // no PVS support on this worldmodel... darn
834                 PRVM_G_FLOAT(OFS_RETURN) = 3;
835                 return;
836         }
837         pvs = sv.worldmodel->brush.GetPVS(sv.worldmodel, viewpos);
838         if(!pvs)
839         {
840                 // viewpos isn't in any PVS... darn
841                 PRVM_G_FLOAT(OFS_RETURN) = 2;
842                 return;
843         }
844         PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
845 #else
846         // using fat PVS like FTEQW does (slow)
847         if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
848         {
849                 // no PVS support on this worldmodel... darn
850                 PRVM_G_FLOAT(OFS_RETURN) = 3;
851                 return;
852         }
853         fatpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
854         if(!fatpvsbytes)
855         {
856                 // viewpos isn't in any PVS... darn
857                 PRVM_G_FLOAT(OFS_RETURN) = 2;
858                 return;
859         }
860         PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
861 #endif
862 }
863
864
865 /*
866 =================
867 VM_SV_stuffcmd
868
869 Sends text over to the client's execution buffer
870
871 stuffcmd (clientent, value, ...)
872 =================
873 */
874 static void VM_SV_stuffcmd (void)
875 {
876         int             entnum;
877         client_t        *old;
878         char    string[VM_STRINGTEMP_LENGTH];
879
880         VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
881
882         entnum = PRVM_G_EDICTNUM(OFS_PARM0);
883         if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
884         {
885                 VM_Warning("Can't stuffcmd to a non-client\n");
886                 return;
887         }
888
889         VM_VarString(1, string, sizeof(string));
890
891         old = host_client;
892         host_client = svs.clients + entnum-1;
893         Host_ClientCommands ("%s", string);
894         host_client = old;
895 }
896
897 /*
898 =================
899 VM_SV_findradius
900
901 Returns a chain of entities that have origins within a spherical area
902
903 findradius (origin, radius)
904 =================
905 */
906 static void VM_SV_findradius (void)
907 {
908         prvm_edict_t *ent, *chain;
909         vec_t radius, radius2;
910         vec3_t org, eorg, mins, maxs;
911         int i;
912         int numtouchedicts;
913         prvm_edict_t *touchedicts[MAX_EDICTS];
914         int chainfield;
915
916         VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findradius);
917
918         if(prog->argc == 3)
919                 chainfield = PRVM_G_INT(OFS_PARM2);
920         else
921                 chainfield = prog->fieldoffsets.chain;
922         if (chainfield < 0)
923                 PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
924
925         chain = (prvm_edict_t *)prog->edicts;
926
927         VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
928         radius = PRVM_G_FLOAT(OFS_PARM1);
929         radius2 = radius * radius;
930
931         mins[0] = org[0] - (radius + 1);
932         mins[1] = org[1] - (radius + 1);
933         mins[2] = org[2] - (radius + 1);
934         maxs[0] = org[0] + (radius + 1);
935         maxs[1] = org[1] + (radius + 1);
936         maxs[2] = org[2] + (radius + 1);
937         numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
938         if (numtouchedicts > MAX_EDICTS)
939         {
940                 // this never happens
941                 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
942                 numtouchedicts = MAX_EDICTS;
943         }
944         for (i = 0;i < numtouchedicts;i++)
945         {
946                 ent = touchedicts[i];
947                 prog->xfunction->builtinsprofile++;
948                 // Quake did not return non-solid entities but darkplaces does
949                 // (note: this is the reason you can't blow up fallen zombies)
950                 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
951                         continue;
952                 // LordHavoc: compare against bounding box rather than center so it
953                 // doesn't miss large objects, and use DotProduct instead of Length
954                 // for a major speedup
955                 VectorSubtract(org, ent->fields.server->origin, eorg);
956                 if (sv_gameplayfix_findradiusdistancetobox.integer)
957                 {
958                         eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
959                         eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
960                         eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
961                 }
962                 else
963                         VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
964                 if (DotProduct(eorg, eorg) < radius2)
965                 {
966                         PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
967                         chain = ent;
968                 }
969         }
970
971         VM_RETURN_EDICT(chain);
972 }
973
974 static void VM_SV_precache_sound (void)
975 {
976         VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
977         PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
978 }
979
980 static void VM_SV_precache_model (void)
981 {
982         VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
983         SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
984         PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
985 }
986
987 /*
988 ===============
989 VM_SV_walkmove
990
991 float(float yaw, float dist[, settrace]) walkmove
992 ===============
993 */
994 static void VM_SV_walkmove (void)
995 {
996         prvm_edict_t    *ent;
997         float   yaw, dist;
998         vec3_t  move;
999         mfunction_t     *oldf;
1000         int     oldself;
1001         qboolean        settrace;
1002
1003         VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
1004
1005         // assume failure if it returns early
1006         PRVM_G_FLOAT(OFS_RETURN) = 0;
1007
1008         ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1009         if (ent == prog->edicts)
1010         {
1011                 VM_Warning("walkmove: can not modify world entity\n");
1012                 return;
1013         }
1014         if (ent->priv.server->free)
1015         {
1016                 VM_Warning("walkmove: can not modify free entity\n");
1017                 return;
1018         }
1019         yaw = PRVM_G_FLOAT(OFS_PARM0);
1020         dist = PRVM_G_FLOAT(OFS_PARM1);
1021         settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
1022
1023         if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1024                 return;
1025
1026         yaw = yaw*M_PI*2 / 360;
1027
1028         move[0] = cos(yaw)*dist;
1029         move[1] = sin(yaw)*dist;
1030         move[2] = 0;
1031
1032 // save program state, because SV_movestep may call other progs
1033         oldf = prog->xfunction;
1034         oldself = prog->globals.server->self;
1035
1036         PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
1037
1038
1039 // restore program state
1040         prog->xfunction = oldf;
1041         prog->globals.server->self = oldself;
1042 }
1043
1044 /*
1045 ===============
1046 VM_SV_droptofloor
1047
1048 void() droptofloor
1049 ===============
1050 */
1051 static void VM_SV_droptofloor (void)
1052 {
1053         prvm_edict_t            *ent;
1054         vec3_t          end;
1055         trace_t         trace;
1056
1057         VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
1058
1059         // assume failure if it returns early
1060         PRVM_G_FLOAT(OFS_RETURN) = 0;
1061
1062         ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1063         if (ent == prog->edicts)
1064         {
1065                 VM_Warning("droptofloor: can not modify world entity\n");
1066                 return;
1067         }
1068         if (ent->priv.server->free)
1069         {
1070                 VM_Warning("droptofloor: can not modify free entity\n");
1071                 return;
1072         }
1073
1074         VectorCopy (ent->fields.server->origin, end);
1075         end[2] -= 256;
1076
1077         if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
1078                 SV_UnstickEntity(ent);
1079
1080         trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1081         if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
1082         {
1083                 vec3_t offset, org;
1084                 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]);
1085                 VectorAdd(ent->fields.server->origin, offset, org);
1086                 trace = SV_Move (org, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1087                 VectorSubtract(trace.endpos, offset, trace.endpos);
1088                 if (trace.startsolid)
1089                 {
1090                         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]);
1091                         SV_UnstickEntity(ent);
1092                         SV_LinkEdict (ent, false);
1093                         ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1094                         ent->fields.server->groundentity = 0;
1095                         PRVM_G_FLOAT(OFS_RETURN) = 1;
1096                 }
1097                 else if (trace.fraction < 1)
1098                 {
1099                         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]);
1100                         VectorCopy (trace.endpos, ent->fields.server->origin);
1101                         SV_UnstickEntity(ent);
1102                         SV_LinkEdict (ent, false);
1103                         ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1104                         ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1105                         PRVM_G_FLOAT(OFS_RETURN) = 1;
1106                         // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1107                         ent->priv.server->suspendedinairflag = true;
1108                 }
1109         }
1110         else
1111         {
1112                 if (trace.fraction != 1)
1113                 {
1114                         if (trace.fraction < 1)
1115                                 VectorCopy (trace.endpos, ent->fields.server->origin);
1116                         SV_LinkEdict (ent, false);
1117                         ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1118                         ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1119                         PRVM_G_FLOAT(OFS_RETURN) = 1;
1120                         // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1121                         ent->priv.server->suspendedinairflag = true;
1122                 }
1123         }
1124 }
1125
1126 /*
1127 ===============
1128 VM_SV_lightstyle
1129
1130 void(float style, string value) lightstyle
1131 ===============
1132 */
1133 static void VM_SV_lightstyle (void)
1134 {
1135         int             style;
1136         const char      *val;
1137         client_t        *client;
1138         int                     j;
1139
1140         VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1141
1142         style = (int)PRVM_G_FLOAT(OFS_PARM0);
1143         val = PRVM_G_STRING(OFS_PARM1);
1144
1145         if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1146                 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1147         }
1148
1149 // change the string in sv
1150         strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1151
1152 // send message to all clients on this server
1153         if (sv.state != ss_active)
1154                 return;
1155
1156         for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1157         {
1158                 if (client->active && client->netconnection)
1159                 {
1160                         MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1161                         MSG_WriteChar (&client->netconnection->message,style);
1162                         MSG_WriteString (&client->netconnection->message, val);
1163                 }
1164         }
1165 }
1166
1167 /*
1168 =============
1169 VM_SV_checkbottom
1170 =============
1171 */
1172 static void VM_SV_checkbottom (void)
1173 {
1174         VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1175         PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1176 }
1177
1178 /*
1179 =============
1180 VM_SV_pointcontents
1181 =============
1182 */
1183 static void VM_SV_pointcontents (void)
1184 {
1185         VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1186         PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1187 }
1188
1189 /*
1190 =============
1191 VM_SV_aim
1192
1193 Pick a vector for the player to shoot along
1194 vector aim(entity, missilespeed)
1195 =============
1196 */
1197 static void VM_SV_aim (void)
1198 {
1199         prvm_edict_t    *ent, *check, *bestent;
1200         vec3_t  start, dir, end, bestdir;
1201         int             i, j;
1202         trace_t tr;
1203         float   dist, bestdist;
1204         float   speed;
1205
1206         VM_SAFEPARMCOUNT(2, VM_SV_aim);
1207
1208         // assume failure if it returns early
1209         VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1210         // if sv_aim is so high it can't possibly accept anything, skip out early
1211         if (sv_aim.value >= 1)
1212                 return;
1213
1214         ent = PRVM_G_EDICT(OFS_PARM0);
1215         if (ent == prog->edicts)
1216         {
1217                 VM_Warning("aim: can not use world entity\n");
1218                 return;
1219         }
1220         if (ent->priv.server->free)
1221         {
1222                 VM_Warning("aim: can not use free entity\n");
1223                 return;
1224         }
1225         speed = PRVM_G_FLOAT(OFS_PARM1);
1226
1227         VectorCopy (ent->fields.server->origin, start);
1228         start[2] += 20;
1229
1230 // try sending a trace straight
1231         VectorCopy (prog->globals.server->v_forward, dir);
1232         VectorMA (start, 2048, dir, end);
1233         tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1234         if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1235         && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1236         {
1237                 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1238                 return;
1239         }
1240
1241
1242 // try all possible entities
1243         VectorCopy (dir, bestdir);
1244         bestdist = sv_aim.value;
1245         bestent = NULL;
1246
1247         check = PRVM_NEXT_EDICT(prog->edicts);
1248         for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1249         {
1250                 prog->xfunction->builtinsprofile++;
1251                 if (check->fields.server->takedamage != DAMAGE_AIM)
1252                         continue;
1253                 if (check == ent)
1254                         continue;
1255                 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1256                         continue;       // don't aim at teammate
1257                 for (j=0 ; j<3 ; j++)
1258                         end[j] = check->fields.server->origin[j]
1259                         + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1260                 VectorSubtract (end, start, dir);
1261                 VectorNormalize (dir);
1262                 dist = DotProduct (dir, prog->globals.server->v_forward);
1263                 if (dist < bestdist)
1264                         continue;       // to far to turn
1265                 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1266                 if (tr.ent == check)
1267                 {       // can shoot at this one
1268                         bestdist = dist;
1269                         bestent = check;
1270                 }
1271         }
1272
1273         if (bestent)
1274         {
1275                 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1276                 dist = DotProduct (dir, prog->globals.server->v_forward);
1277                 VectorScale (prog->globals.server->v_forward, dist, end);
1278                 end[2] = dir[2];
1279                 VectorNormalize (end);
1280                 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1281         }
1282         else
1283         {
1284                 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1285         }
1286 }
1287
1288 /*
1289 ===============================================================================
1290
1291 MESSAGE WRITING
1292
1293 ===============================================================================
1294 */
1295
1296 #define MSG_BROADCAST   0               // unreliable to all
1297 #define MSG_ONE                 1               // reliable to one (msg_entity)
1298 #define MSG_ALL                 2               // reliable to all
1299 #define MSG_INIT                3               // write to the init string
1300 #define MSG_ENTITY              5
1301
1302 sizebuf_t *WriteDest (void)
1303 {
1304         int             entnum;
1305         int             dest;
1306         prvm_edict_t    *ent;
1307
1308         dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1309         switch (dest)
1310         {
1311         case MSG_BROADCAST:
1312                 return &sv.datagram;
1313
1314         case MSG_ONE:
1315                 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1316                 entnum = PRVM_NUM_FOR_EDICT(ent);
1317                 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1318                 {
1319                         VM_Warning ("WriteDest: tried to write to non-client\n");
1320                         return &sv.reliable_datagram;
1321                 }
1322                 else
1323                         return &svs.clients[entnum-1].netconnection->message;
1324
1325         default:
1326                 VM_Warning ("WriteDest: bad destination\n");
1327         case MSG_ALL:
1328                 return &sv.reliable_datagram;
1329
1330         case MSG_INIT:
1331                 return &sv.signon;
1332
1333         case MSG_ENTITY:
1334                 return sv.writeentitiestoclient_msg;
1335         }
1336
1337         return NULL;
1338 }
1339
1340 static void VM_SV_WriteByte (void)
1341 {
1342         VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1343         MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1344 }
1345
1346 static void VM_SV_WriteChar (void)
1347 {
1348         VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1349         MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1350 }
1351
1352 static void VM_SV_WriteShort (void)
1353 {
1354         VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1355         MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1356 }
1357
1358 static void VM_SV_WriteLong (void)
1359 {
1360         VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1361         MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1362 }
1363
1364 static void VM_SV_WriteAngle (void)
1365 {
1366         VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1367         MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1368 }
1369
1370 static void VM_SV_WriteCoord (void)
1371 {
1372         VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1373         MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1374 }
1375
1376 static void VM_SV_WriteString (void)
1377 {
1378         VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1379         MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1380 }
1381
1382 static void VM_SV_WriteUnterminatedString (void)
1383 {
1384         VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1385         MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1386 }
1387
1388
1389 static void VM_SV_WriteEntity (void)
1390 {
1391         VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1392         MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1393 }
1394
1395 // writes a picture as at most size bytes of data
1396 // message:
1397 //   IMGNAME \0 SIZE(short) IMGDATA
1398 // if failed to read/compress:
1399 //   IMGNAME \0 \0 \0
1400 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1401 static void VM_SV_WritePicture (void)
1402 {
1403         const char *imgname;
1404         void *buf;
1405         size_t size;
1406
1407         VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1408
1409         imgname = PRVM_G_STRING(OFS_PARM1);
1410         size = (int) PRVM_G_FLOAT(OFS_PARM2);
1411         if(size > 65535)
1412                 size = 65535;
1413
1414         MSG_WriteString(WriteDest(), imgname);
1415         if(Image_Compress(imgname, size, &buf, &size))
1416         {
1417                 // actual picture
1418                 MSG_WriteShort(WriteDest(), size);
1419                 SZ_Write(WriteDest(), (unsigned char *) buf, size);
1420         }
1421         else
1422         {
1423                 // placeholder
1424                 MSG_WriteShort(WriteDest(), 0);
1425         }
1426 }
1427
1428 //////////////////////////////////////////////////////////
1429
1430 static void VM_SV_makestatic (void)
1431 {
1432         prvm_edict_t *ent;
1433         int i, large;
1434
1435         // allow 0 parameters due to an id1 qc bug in which this function is used
1436         // with no parameters (but directly after setmodel with self in OFS_PARM0)
1437         VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1438
1439         if (prog->argc >= 1)
1440                 ent = PRVM_G_EDICT(OFS_PARM0);
1441         else
1442                 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1443         if (ent == prog->edicts)
1444         {
1445                 VM_Warning("makestatic: can not modify world entity\n");
1446                 return;
1447         }
1448         if (ent->priv.server->free)
1449         {
1450                 VM_Warning("makestatic: can not modify free entity\n");
1451                 return;
1452         }
1453
1454         large = false;
1455         if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1456                 large = true;
1457
1458         if (large)
1459         {
1460                 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1461                 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1462                 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1463         }
1464         else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1465         {
1466                 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1467                 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1468                 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1469         }
1470         else
1471         {
1472                 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1473                 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1474                 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1475         }
1476
1477         MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1478         MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1479         for (i=0 ; i<3 ; i++)
1480         {
1481                 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1482                 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1483         }
1484
1485 // throw the entity away now
1486         PRVM_ED_Free (ent);
1487 }
1488
1489 //=============================================================================
1490
1491 /*
1492 ==============
1493 VM_SV_setspawnparms
1494 ==============
1495 */
1496 static void VM_SV_setspawnparms (void)
1497 {
1498         prvm_edict_t    *ent;
1499         int             i;
1500         client_t        *client;
1501
1502         VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1503
1504         ent = PRVM_G_EDICT(OFS_PARM0);
1505         i = PRVM_NUM_FOR_EDICT(ent);
1506         if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1507         {
1508                 Con_Print("tried to setspawnparms on a non-client\n");
1509                 return;
1510         }
1511
1512         // copy spawn parms out of the client_t
1513         client = svs.clients + i-1;
1514         for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1515                 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1516 }
1517
1518 /*
1519 =================
1520 VM_SV_getlight
1521
1522 Returns a color vector indicating the lighting at the requested point.
1523
1524 (Internal Operation note: actually measures the light beneath the point, just like
1525                           the model lighting on the client)
1526
1527 getlight(vector)
1528 =================
1529 */
1530 static void VM_SV_getlight (void)
1531 {
1532         vec3_t ambientcolor, diffusecolor, diffusenormal;
1533         vec_t *p;
1534         VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1535         p = PRVM_G_VECTOR(OFS_PARM0);
1536         VectorClear(ambientcolor);
1537         VectorClear(diffusecolor);
1538         VectorClear(diffusenormal);
1539         if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1540                 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1541         VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1542 }
1543
1544 typedef struct
1545 {
1546         unsigned char   type;   // 1/2/8 or other value if isn't used
1547         int             fieldoffset;
1548 }customstat_t;
1549
1550 static customstat_t *vm_customstats = NULL;     //[515]: it starts from 0, not 32
1551 static int vm_customstats_last;
1552
1553 void VM_CustomStats_Clear (void)
1554 {
1555         if(vm_customstats)
1556         {
1557                 Z_Free(vm_customstats);
1558                 vm_customstats = NULL;
1559                 vm_customstats_last = -1;
1560         }
1561 }
1562
1563 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1564 {
1565         int                     i;
1566         char            s[17];
1567
1568         if(!vm_customstats)
1569                 return;
1570
1571         for(i=0; i<vm_customstats_last+1 ;i++)
1572         {
1573                 if(!vm_customstats[i].type)
1574                         continue;
1575                 switch(vm_customstats[i].type)
1576                 {
1577                 //string as 16 bytes
1578                 case 1:
1579                         memset(s, 0, 17);
1580                         strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1581                         stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1582                         stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1583                         stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1584                         stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1585                         break;
1586                 //float field sent as-is
1587                 case 8:
1588                         stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1589                         break;
1590                 //integer value of float field
1591                 case 2:
1592                         stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1593                         break;
1594                 default:
1595                         break;
1596                 }
1597         }
1598 }
1599
1600 // void(float index, float type, .void field) SV_AddStat = #232;
1601 // Set up an auto-sent player stat.
1602 // Client's get thier own fields sent to them. Index may not be less than 32.
1603 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1604 //          1: string (4 stats carrying a total of 16 charactures)
1605 //          2: float (one stat, float converted to an integer for transportation)
1606 //          8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1607 static void VM_SV_AddStat (void)
1608 {
1609         int             off, i;
1610         unsigned char   type;
1611
1612         VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1613
1614         if(!vm_customstats)
1615         {
1616                 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1617                 if(!vm_customstats)
1618                 {
1619                         VM_Warning("PF_SV_AddStat: not enough memory\n");
1620                         return;
1621                 }
1622         }
1623         i               = (int)PRVM_G_FLOAT(OFS_PARM0);
1624         type    = (int)PRVM_G_FLOAT(OFS_PARM1);
1625         off             = PRVM_G_INT  (OFS_PARM2);
1626         i -= 32;
1627
1628         if(i < 0)
1629         {
1630                 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1631                 return;
1632         }
1633         if(i >= (MAX_CL_STATS-32))
1634         {
1635                 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1636                 return;
1637         }
1638         if(i > (MAX_CL_STATS-32-4) && type == 1)
1639         {
1640                 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1641                 return;
1642         }
1643         vm_customstats[i].type          = type;
1644         vm_customstats[i].fieldoffset   = off;
1645         if(vm_customstats_last < i)
1646                 vm_customstats_last = i;
1647 }
1648
1649 /*
1650 =================
1651 VM_SV_copyentity
1652
1653 copies data from one entity to another
1654
1655 copyentity(src, dst)
1656 =================
1657 */
1658 static void VM_SV_copyentity (void)
1659 {
1660         prvm_edict_t *in, *out;
1661         VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1662         in = PRVM_G_EDICT(OFS_PARM0);
1663         if (in == prog->edicts)
1664         {
1665                 VM_Warning("copyentity: can not read world entity\n");
1666                 return;
1667         }
1668         if (in->priv.server->free)
1669         {
1670                 VM_Warning("copyentity: can not read free entity\n");
1671                 return;
1672         }
1673         out = PRVM_G_EDICT(OFS_PARM1);
1674         if (out == prog->edicts)
1675         {
1676                 VM_Warning("copyentity: can not modify world entity\n");
1677                 return;
1678         }
1679         if (out->priv.server->free)
1680         {
1681                 VM_Warning("copyentity: can not modify free entity\n");
1682                 return;
1683         }
1684         memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1685         SV_LinkEdict(out, false);
1686 }
1687
1688
1689 /*
1690 =================
1691 VM_SV_setcolor
1692
1693 sets the color of a client and broadcasts the update to all connected clients
1694
1695 setcolor(clientent, value)
1696 =================
1697 */
1698 static void VM_SV_setcolor (void)
1699 {
1700         client_t *client;
1701         int entnum, i;
1702         prvm_eval_t *val;
1703
1704         VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1705         entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1706         i = (int)PRVM_G_FLOAT(OFS_PARM1);
1707
1708         if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1709         {
1710                 Con_Print("tried to setcolor a non-client\n");
1711                 return;
1712         }
1713
1714         client = svs.clients + entnum-1;
1715         if (client->edict)
1716         {
1717                 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1718                         val->_float = i;
1719                 client->edict->fields.server->team = (i & 15) + 1;
1720         }
1721         client->colors = i;
1722         if (client->old_colors != client->colors)
1723         {
1724                 client->old_colors = client->colors;
1725                 // send notification to all clients
1726                 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1727                 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1728                 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1729         }
1730 }
1731
1732 /*
1733 =================
1734 VM_SV_effect
1735
1736 effect(origin, modelname, startframe, framecount, framerate)
1737 =================
1738 */
1739 static void VM_SV_effect (void)
1740 {
1741         int i;
1742         const char *s;
1743         VM_SAFEPARMCOUNT(5, VM_SV_effect);
1744         s = PRVM_G_STRING(OFS_PARM1);
1745         if (!s[0])
1746         {
1747                 VM_Warning("effect: no model specified\n");
1748                 return;
1749         }
1750
1751         i = SV_ModelIndex(s, 1);
1752         if (!i)
1753         {
1754                 VM_Warning("effect: model not precached\n");
1755                 return;
1756         }
1757
1758         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1759         {
1760                 VM_Warning("effect: framecount < 1\n");
1761                 return;
1762         }
1763
1764         if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1765         {
1766                 VM_Warning("effect: framerate < 1\n");
1767                 return;
1768         }
1769
1770         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));
1771 }
1772
1773 static void VM_SV_te_blood (void)
1774 {
1775         VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1776         if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1777                 return;
1778         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1779         MSG_WriteByte(&sv.datagram, TE_BLOOD);
1780         // origin
1781         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1782         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1783         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1784         // velocity
1785         MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1786         MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1787         MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1788         // count
1789         MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1790         SV_FlushBroadcastMessages();
1791 }
1792
1793 static void VM_SV_te_bloodshower (void)
1794 {
1795         VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1796         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1797                 return;
1798         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1799         MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1800         // min
1801         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1802         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1803         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1804         // max
1805         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1806         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1807         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1808         // speed
1809         MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1810         // count
1811         MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1812         SV_FlushBroadcastMessages();
1813 }
1814
1815 static void VM_SV_te_explosionrgb (void)
1816 {
1817         VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1818         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1819         MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1820         // origin
1821         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1822         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1823         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1824         // color
1825         MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1826         MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1827         MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1828         SV_FlushBroadcastMessages();
1829 }
1830
1831 static void VM_SV_te_particlecube (void)
1832 {
1833         VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1834         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1835                 return;
1836         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1837         MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1838         // min
1839         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1840         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1841         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1842         // max
1843         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1844         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1845         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1846         // velocity
1847         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1848         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1849         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1850         // count
1851         MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1852         // color
1853         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1854         // gravity true/false
1855         MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1856         // randomvel
1857         MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1858         SV_FlushBroadcastMessages();
1859 }
1860
1861 static void VM_SV_te_particlerain (void)
1862 {
1863         VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1864         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1865                 return;
1866         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1867         MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1868         // min
1869         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1870         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1871         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1872         // max
1873         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1874         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1875         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1876         // velocity
1877         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1878         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1879         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1880         // count
1881         MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1882         // color
1883         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1884         SV_FlushBroadcastMessages();
1885 }
1886
1887 static void VM_SV_te_particlesnow (void)
1888 {
1889         VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1890         if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1891                 return;
1892         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1893         MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1894         // min
1895         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1896         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1897         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1898         // max
1899         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1900         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1901         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1902         // velocity
1903         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1904         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1905         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1906         // count
1907         MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1908         // color
1909         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1910         SV_FlushBroadcastMessages();
1911 }
1912
1913 static void VM_SV_te_spark (void)
1914 {
1915         VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1916         if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1917                 return;
1918         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1919         MSG_WriteByte(&sv.datagram, TE_SPARK);
1920         // origin
1921         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1922         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1923         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1924         // velocity
1925         MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1926         MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1927         MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1928         // count
1929         MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1930         SV_FlushBroadcastMessages();
1931 }
1932
1933 static void VM_SV_te_gunshotquad (void)
1934 {
1935         VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1936         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1937         MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1938         // origin
1939         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1940         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1941         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1942         SV_FlushBroadcastMessages();
1943 }
1944
1945 static void VM_SV_te_spikequad (void)
1946 {
1947         VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1948         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1949         MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1950         // origin
1951         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1952         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1953         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1954         SV_FlushBroadcastMessages();
1955 }
1956
1957 static void VM_SV_te_superspikequad (void)
1958 {
1959         VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1960         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1961         MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1962         // origin
1963         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1964         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1965         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1966         SV_FlushBroadcastMessages();
1967 }
1968
1969 static void VM_SV_te_explosionquad (void)
1970 {
1971         VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1972         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1973         MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1974         // origin
1975         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1976         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1977         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1978         SV_FlushBroadcastMessages();
1979 }
1980
1981 static void VM_SV_te_smallflash (void)
1982 {
1983         VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1984         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1985         MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1986         // origin
1987         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1988         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1989         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1990         SV_FlushBroadcastMessages();
1991 }
1992
1993 static void VM_SV_te_customflash (void)
1994 {
1995         VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1996         if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1997                 return;
1998         MSG_WriteByte(&sv.datagram, svc_temp_entity);
1999         MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2000         // origin
2001         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2002         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2003         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2004         // radius
2005         MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2006         // lifetime
2007         MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
2008         // color
2009         MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
2010         MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
2011         MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
2012         SV_FlushBroadcastMessages();
2013 }
2014
2015 static void VM_SV_te_gunshot (void)
2016 {
2017         VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
2018         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2019         MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2020         // origin
2021         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2022         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2023         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2024         SV_FlushBroadcastMessages();
2025 }
2026
2027 static void VM_SV_te_spike (void)
2028 {
2029         VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
2030         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2031         MSG_WriteByte(&sv.datagram, TE_SPIKE);
2032         // origin
2033         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2034         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2035         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2036         SV_FlushBroadcastMessages();
2037 }
2038
2039 static void VM_SV_te_superspike (void)
2040 {
2041         VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
2042         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2043         MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2044         // origin
2045         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2046         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2047         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2048         SV_FlushBroadcastMessages();
2049 }
2050
2051 static void VM_SV_te_explosion (void)
2052 {
2053         VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
2054         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2055         MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2056         // origin
2057         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2058         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2059         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2060         SV_FlushBroadcastMessages();
2061 }
2062
2063 static void VM_SV_te_tarexplosion (void)
2064 {
2065         VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
2066         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2067         MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2068         // origin
2069         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2070         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2071         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2072         SV_FlushBroadcastMessages();
2073 }
2074
2075 static void VM_SV_te_wizspike (void)
2076 {
2077         VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
2078         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2079         MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2080         // origin
2081         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2082         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2083         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2084         SV_FlushBroadcastMessages();
2085 }
2086
2087 static void VM_SV_te_knightspike (void)
2088 {
2089         VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2090         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2091         MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2092         // origin
2093         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2094         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2095         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2096         SV_FlushBroadcastMessages();
2097 }
2098
2099 static void VM_SV_te_lavasplash (void)
2100 {
2101         VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2102         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2103         MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2104         // origin
2105         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2106         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2107         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2108         SV_FlushBroadcastMessages();
2109 }
2110
2111 static void VM_SV_te_teleport (void)
2112 {
2113         VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2114         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2115         MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2116         // origin
2117         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2118         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2119         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2120         SV_FlushBroadcastMessages();
2121 }
2122
2123 static void VM_SV_te_explosion2 (void)
2124 {
2125         VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2126         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2127         MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2128         // origin
2129         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2130         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2131         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2132         // color
2133         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2134         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2135         SV_FlushBroadcastMessages();
2136 }
2137
2138 static void VM_SV_te_lightning1 (void)
2139 {
2140         VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2141         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2142         MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2143         // owner entity
2144         MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2145         // start
2146         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2147         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2148         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2149         // end
2150         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2151         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2152         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2153         SV_FlushBroadcastMessages();
2154 }
2155
2156 static void VM_SV_te_lightning2 (void)
2157 {
2158         VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2159         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2160         MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2161         // owner entity
2162         MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2163         // start
2164         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2165         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2166         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2167         // end
2168         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2169         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2170         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2171         SV_FlushBroadcastMessages();
2172 }
2173
2174 static void VM_SV_te_lightning3 (void)
2175 {
2176         VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2177         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2178         MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2179         // owner entity
2180         MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2181         // start
2182         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2183         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2184         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2185         // end
2186         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2187         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2188         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2189         SV_FlushBroadcastMessages();
2190 }
2191
2192 static void VM_SV_te_beam (void)
2193 {
2194         VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2195         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2196         MSG_WriteByte(&sv.datagram, TE_BEAM);
2197         // owner entity
2198         MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2199         // start
2200         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2201         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2202         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2203         // end
2204         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2205         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2206         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2207         SV_FlushBroadcastMessages();
2208 }
2209
2210 static void VM_SV_te_plasmaburn (void)
2211 {
2212         VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2213         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2214         MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2215         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2216         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2217         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2218         SV_FlushBroadcastMessages();
2219 }
2220
2221 static void VM_SV_te_flamejet (void)
2222 {
2223         VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2224         MSG_WriteByte(&sv.datagram, svc_temp_entity);
2225         MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2226         // org
2227         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2228         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2229         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2230         // vel
2231         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2232         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2233         MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2234         // count
2235         MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2236         SV_FlushBroadcastMessages();
2237 }
2238
2239 void clippointtosurface(dp_model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2240 {
2241         int i, j, k;
2242         float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2243         const int *e;
2244         bestdist = 1000000000;
2245         VectorCopy(p, out);
2246         for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2247         {
2248                 // clip original point to each triangle of the surface and find the
2249                 // triangle that is closest
2250                 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2251                 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2252                 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2253                 TriangleNormal(v[0], v[1], v[2], facenormal);
2254                 VectorNormalize(facenormal);
2255                 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2256                 VectorMA(p, offsetdist, facenormal, temp);
2257                 for (j = 0, k = 2;j < 3;k = j, j++)
2258                 {
2259                         VectorSubtract(v[k], v[j], edgenormal);
2260                         CrossProduct(edgenormal, facenormal, sidenormal);
2261                         VectorNormalize(sidenormal);
2262                         offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2263                         if (offsetdist < 0)
2264                                 VectorMA(temp, offsetdist, sidenormal, temp);
2265                 }
2266                 dist = VectorDistance2(temp, p);
2267                 if (bestdist > dist)
2268                 {
2269                         bestdist = dist;
2270                         VectorCopy(temp, out);
2271                 }
2272         }
2273 }
2274
2275 static dp_model_t *getmodel(prvm_edict_t *ed)
2276 {
2277         int modelindex;
2278         if (!ed || ed->priv.server->free)
2279                 return NULL;
2280         modelindex = (int)ed->fields.server->modelindex;
2281         if (modelindex < 1 || modelindex >= MAX_MODELS)
2282                 return NULL;
2283         return sv.models[modelindex];
2284 }
2285
2286 static msurface_t *getsurface(dp_model_t *model, int surfacenum)
2287 {
2288         if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2289                 return NULL;
2290         return model->data_surfaces + surfacenum + model->firstmodelsurface;
2291 }
2292
2293
2294 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2295 static void VM_SV_getsurfacenumpoints(void)
2296 {
2297         dp_model_t *model;
2298         msurface_t *surface;
2299         VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2300         // return 0 if no such surface
2301         if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2302         {
2303                 PRVM_G_FLOAT(OFS_RETURN) = 0;
2304                 return;
2305         }
2306
2307         // note: this (incorrectly) assumes it is a simple polygon
2308         PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2309 }
2310 //PF_getsurfacepoint,     // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2311 static void VM_SV_getsurfacepoint(void)
2312 {
2313         prvm_edict_t *ed;
2314         dp_model_t *model;
2315         msurface_t *surface;
2316         int pointnum;
2317         VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2318         VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2319         ed = PRVM_G_EDICT(OFS_PARM0);
2320         if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2321                 return;
2322         // note: this (incorrectly) assumes it is a simple polygon
2323         pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2324         if (pointnum < 0 || pointnum >= surface->num_vertices)
2325                 return;
2326         // FIXME: implement rotation/scaling
2327         VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2328 }
2329 //PF_getsurfacepointattribute,     // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
2330 // float SPA_POSITION = 0;
2331 // float SPA_S_AXIS = 1;
2332 // float SPA_T_AXIS = 2;
2333 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2334 // float SPA_TEXCOORDS0 = 4;
2335 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2336 // float SPA_LIGHTMAP0_COLOR = 6;
2337 static void VM_SV_getsurfacepointattribute(void)
2338 {
2339         prvm_edict_t *ed;
2340         dp_model_t *model;
2341         msurface_t *surface;
2342         int pointnum;
2343         int attributetype;
2344
2345         VM_SAFEPARMCOUNT(4, VM_SV_getsurfacepoint);
2346         VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2347         ed = PRVM_G_EDICT(OFS_PARM0);
2348         if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2349                 return;
2350         // note: this (incorrectly) assumes it is a simple polygon
2351         pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2352         if (pointnum < 0 || pointnum >= surface->num_vertices)
2353                 return;
2354         // FIXME: implement rotation/scaling
2355         attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
2356
2357         switch( attributetype ) {
2358                 // float SPA_POSITION = 0;
2359                 case 0:
2360                         VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2361                         break;
2362                 // float SPA_S_AXIS = 1;
2363                 case 1:
2364                         VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2365                         break;
2366                 // float SPA_T_AXIS = 2;
2367                 case 2:
2368                         VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2369                         break;
2370                 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2371                 case 3:
2372                         VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2373                         break;
2374                 // float SPA_TEXCOORDS0 = 4;
2375                 case 4: {
2376                         float *ret = PRVM_G_VECTOR(OFS_RETURN);
2377                         float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2];
2378                         ret[0] = texcoord[0];
2379                         ret[1] = texcoord[1];
2380                         ret[2] = 0.0f;
2381                         break;
2382                 }
2383                 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2384                 case 5: {
2385                         float *ret = PRVM_G_VECTOR(OFS_RETURN);
2386                         float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2];
2387                         ret[0] = texcoord[0];
2388                         ret[1] = texcoord[1];
2389                         ret[2] = 0.0f;
2390                         break;
2391                 }
2392                 // float SPA_LIGHTMAP0_COLOR = 6;
2393                 case 6:
2394                         // ignore alpha for now..
2395                         VectorCopy( &(model->surfmesh.data_lightmapcolor4f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
2396                         break;
2397                 default:
2398                         VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
2399                         break;
2400         }
2401 }
2402 //PF_getsurfacenormal,    // #436 vector(entity e, float s) getsurfacenormal = #436;
2403 static void VM_SV_getsurfacenormal(void)
2404 {
2405         dp_model_t *model;
2406         msurface_t *surface;
2407         vec3_t normal;
2408         VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2409         VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2410         if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2411                 return;
2412         // FIXME: implement rotation/scaling
2413         // note: this (incorrectly) assumes it is a simple polygon
2414         // note: this only returns the first triangle, so it doesn't work very
2415         // well for curved surfaces or arbitrary meshes
2416         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);
2417         VectorNormalize(normal);
2418         VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2419 }
2420 //PF_getsurfacetexture,   // #437 string(entity e, float s) getsurfacetexture = #437;
2421 static void VM_SV_getsurfacetexture(void)
2422 {
2423         dp_model_t *model;
2424         msurface_t *surface;
2425         VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2426         PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2427         if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2428                 return;
2429         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2430 }
2431 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2432 static void VM_SV_getsurfacenearpoint(void)
2433 {
2434         int surfacenum, best;
2435         vec3_t clipped, p;
2436         vec_t dist, bestdist;
2437         prvm_edict_t *ed;
2438         dp_model_t *model;
2439         msurface_t *surface;
2440         vec_t *point;
2441         VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2442         PRVM_G_FLOAT(OFS_RETURN) = -1;
2443         ed = PRVM_G_EDICT(OFS_PARM0);
2444         point = PRVM_G_VECTOR(OFS_PARM1);
2445
2446         if (!ed || ed->priv.server->free)
2447                 return;
2448         model = getmodel(ed);
2449         if (!model || !model->num_surfaces)
2450                 return;
2451
2452         // FIXME: implement rotation/scaling
2453         VectorSubtract(point, ed->fields.server->origin, p);
2454         best = -1;
2455         bestdist = 1000000000;
2456         for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2457         {
2458                 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2459                 // first see if the nearest point on the surface's box is closer than the previous match
2460                 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2461                 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2462                 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2463                 dist = VectorLength2(clipped);
2464                 if (dist < bestdist)
2465                 {
2466                         // it is, check the nearest point on the actual geometry
2467                         clippointtosurface(model, surface, p, clipped);
2468                         VectorSubtract(clipped, p, clipped);
2469                         dist += VectorLength2(clipped);
2470                         if (dist < bestdist)
2471                         {
2472                                 // that's closer too, store it as the best match
2473                                 best = surfacenum;
2474                                 bestdist = dist;
2475                         }
2476                 }
2477         }
2478         PRVM_G_FLOAT(OFS_RETURN) = best;
2479 }
2480 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2481 static void VM_SV_getsurfaceclippedpoint(void)
2482 {
2483         prvm_edict_t *ed;
2484         dp_model_t *model;
2485         msurface_t *surface;
2486         vec3_t p, out;
2487         VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2488         VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2489         ed = PRVM_G_EDICT(OFS_PARM0);
2490         if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2491                 return;
2492         // FIXME: implement rotation/scaling
2493         VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2494         clippointtosurface(model, surface, p, out);
2495         // FIXME: implement rotation/scaling
2496         VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2497 }
2498
2499 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2500 //this function originally written by KrimZon, made shorter by LordHavoc
2501 static void VM_SV_clientcommand (void)
2502 {
2503         client_t *temp_client;
2504         int i;
2505         VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2506
2507         //find client for this entity
2508         i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2509         if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2510         {
2511                 Con_Print("PF_clientcommand: entity is not a client\n");
2512                 return;
2513         }
2514
2515         temp_client = host_client;
2516         host_client = svs.clients + i;
2517         Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2518         host_client = temp_client;
2519 }
2520
2521 //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)
2522 static void VM_SV_setattachment (void)
2523 {
2524         prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2525         prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2526         const char *tagname = PRVM_G_STRING(OFS_PARM2);
2527         prvm_eval_t *v;
2528         int modelindex;
2529         dp_model_t *model;
2530         VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2531
2532         if (e == prog->edicts)
2533         {
2534                 VM_Warning("setattachment: can not modify world entity\n");
2535                 return;
2536         }
2537         if (e->priv.server->free)
2538         {
2539                 VM_Warning("setattachment: can not modify free entity\n");
2540                 return;
2541         }
2542
2543         if (tagentity == NULL)
2544                 tagentity = prog->edicts;
2545
2546         v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2547         if (v)
2548                 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2549
2550         v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2551         if (v)
2552                 v->_float = 0;
2553         if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2554         {
2555                 modelindex = (int)tagentity->fields.server->modelindex;
2556                 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2557                 {
2558                         v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2559                         if (v->_float == 0)
2560                                 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);
2561                 }
2562                 else
2563                         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));
2564         }
2565 }
2566
2567 /////////////////////////////////////////
2568 // DP_MD3_TAGINFO extension coded by VorteX
2569
2570 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2571 {
2572         int i;
2573         dp_model_t *model;
2574
2575         i = (int)e->fields.server->modelindex;
2576         if (i < 1 || i >= MAX_MODELS)
2577                 return -1;
2578         model = sv.models[i];
2579
2580         return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2581 }
2582
2583 int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
2584 {
2585         int r;
2586         dp_model_t *model;
2587         int frame;
2588         int modelindex;
2589
2590         *tagname = NULL;
2591         *parentindex = 0;
2592         Matrix4x4_CreateIdentity(tag_localmatrix);
2593
2594         if (tagindex >= 0
2595          && (modelindex = (int)e->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2596          && (model = sv.models[(int)e->fields.server->modelindex])
2597          && model->animscenes)
2598         {
2599                 frame = (int)e->fields.server->frame;
2600                 if (frame < 0 || frame >= model->numframes)
2601                         frame = 0;
2602
2603                 r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, model->animscenes[frame].firstframe, tagindex - 1, parentindex, tagname, tag_localmatrix);
2604
2605                 if(!r) // success?
2606                         *parentindex += 1;
2607
2608                 return r;
2609         }
2610
2611         return 1;
2612 }
2613
2614 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2615 {
2616         prvm_eval_t *val;
2617         float scale;
2618         float pitchsign;
2619         int modelindex;
2620         dp_model_t *model;
2621
2622         scale = 1;
2623         val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
2624         if (val && val->_float != 0)
2625                 scale = val->_float;
2626         
2627         if (viewmatrix)
2628                 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);
2629         else
2630         {
2631                 pitchsign = 1;
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