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