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