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