]> icculus.org git repositories - divverent/darkplaces.git/blob - svvm_cmds.c
FTE_QC_CHECKPVS
[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         float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2611         if (scale == 0)
2612                 scale = 1;
2613         if (viewmatrix)
2614                 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);
2615         else
2616                 Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], -ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], scale * cl_viewmodel_scale.value);
2617 }
2618
2619 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2620 {
2621         int modelindex;
2622         int frame;
2623         dp_model_t *model;
2624         if (tagindex >= 0
2625          && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2626          && (model = sv.models[(int)ent->fields.server->modelindex])
2627          && model->animscenes)
2628         {
2629                 // if model has wrong frame, engine automatically switches to model first frame
2630                 frame = (int)ent->fields.server->frame;
2631                 if (frame < 0 || frame >= model->numframes)
2632                         frame = 0;
2633                 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2634         }
2635         *out = identitymatrix;
2636         return 0;
2637 }
2638
2639 // Warnings/errors code:
2640 // 0 - normal (everything all-right)
2641 // 1 - world entity
2642 // 2 - free entity
2643 // 3 - null or non-precached model
2644 // 4 - no tags with requested index
2645 // 5 - runaway loop at attachment chain
2646 extern cvar_t cl_bob;
2647 extern cvar_t cl_bobcycle;
2648 extern cvar_t cl_bobup;
2649 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2650 {
2651         int ret;
2652         prvm_eval_t *val;
2653         int modelindex, attachloop;
2654         matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2655         dp_model_t *model;
2656
2657         *out = identitymatrix; // warnings and errors return identical matrix
2658
2659         if (ent == prog->edicts)
2660                 return 1;
2661         if (ent->priv.server->free)
2662                 return 2;
2663
2664         modelindex = (int)ent->fields.server->modelindex;
2665         if (modelindex <= 0 || modelindex > MAX_MODELS)
2666                 return 3;
2667
2668         model = sv.models[modelindex];
2669
2670         tagmatrix = identitymatrix;
2671         // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2672         attachloop = 0;
2673         for (;;)
2674         {
2675                 if (attachloop >= 256) // prevent runaway looping
2676                         return 5;
2677                 // apply transformation by child's tagindex on parent entity and then
2678                 // by parent entity itself
2679                 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2680                 if (ret && attachloop == 0)
2681                         return ret;
2682                 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2683                 SV_GetEntityMatrix(ent, &entitymatrix, false);
2684                 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2685                 // next iteration we process the parent entity
2686                 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2687                 {
2688                         tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2689                         ent = PRVM_EDICT_NUM(val->edict);
2690                 }
2691                 else
2692                         break;
2693                 attachloop++;
2694         }
2695
2696         // RENDER_VIEWMODEL magic
2697         if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2698         {
2699                 Matrix4x4_Copy(&tagmatrix, out);
2700                 ent = PRVM_EDICT_NUM(val->edict);
2701
2702                 SV_GetEntityMatrix(ent, &entitymatrix, true);
2703                 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2704
2705                 /*
2706                 // Cl_bob, ported from rendering code
2707                 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2708                 {
2709                         double bob, cycle;
2710                         // LordHavoc: this code is *weird*, but not replacable (I think it
2711                         // should be done in QC on the server, but oh well, quake is quake)
2712                         // LordHavoc: figured out bobup: the time at which the sin is at 180
2713                         // degrees (which allows lengthening or squishing the peak or valley)
2714                         cycle = sv.time/cl_bobcycle.value;
2715                         cycle -= (int)cycle;
2716                         if (cycle < cl_bobup.value)
2717                                 cycle = sin(M_PI * cycle / cl_bobup.value);
2718                         else
2719                                 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2720                         // bob is proportional to velocity in the xy plane
2721                         // (don't count Z, or jumping messes it up)
2722                         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;
2723                         bob = bob*0.3 + bob*0.7*cycle;
2724                         Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2725                 }
2726                 */
2727         }
2728         return 0;
2729 }
2730
2731 //float(entity ent, string tagname) gettagindex;
2732
2733 static void VM_SV_gettagindex (void)
2734 {
2735         prvm_edict_t *ent;
2736         const char *tag_name;
2737         int modelindex, tag_index;
2738
2739         VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2740
2741         ent = PRVM_G_EDICT(OFS_PARM0);
2742         tag_name = PRVM_G_STRING(OFS_PARM1);
2743
2744         if (ent == prog->edicts)
2745         {
2746                 VM_Warning("gettagindex: can't affect world entity\n");
2747                 return;
2748         }
2749         if (ent->priv.server->free)
2750         {
2751                 VM_Warning("gettagindex: can't affect free entity\n");
2752                 return;
2753         }
2754
2755         modelindex = (int)ent->fields.server->modelindex;
2756         tag_index = 0;
2757         if (modelindex <= 0 || modelindex > MAX_MODELS)
2758                 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2759         else
2760         {
2761                 tag_index = SV_GetTagIndex(ent, tag_name);
2762                 if (tag_index == 0)
2763                         if(developer.integer >= 100)
2764                                 Con_Printf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2765         }
2766         PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2767 };
2768
2769 //vector(entity ent, float tagindex) gettaginfo;
2770 static void VM_SV_gettaginfo (void)
2771 {
2772         prvm_edict_t *e;
2773         int tagindex;
2774         matrix4x4_t tag_matrix;
2775         matrix4x4_t tag_localmatrix;
2776         int parentindex;
2777         const char *tagname;
2778         int returncode;
2779         prvm_eval_t *val;
2780         vec3_t fo, ri, up, trans;
2781
2782         VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2783
2784         e = PRVM_G_EDICT(OFS_PARM0);
2785         tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2786
2787         returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2788         Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2789         SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
2790         Matrix4x4_ToVectors(&tag_localmatrix, fo, ri, up, trans);
2791
2792         if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
2793                 val->_float = parentindex;
2794         if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
2795                 val->string = tagname ? PRVM_SetTempString(tagname) : 0;
2796         if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
2797                 VectorCopy(trans, val->vector);
2798         if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
2799                 VectorCopy(fo, val->vector);
2800         if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
2801                 VectorCopy(ri, val->vector);
2802         if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
2803                 VectorCopy(up, val->vector);
2804
2805         switch(returncode)
2806         {
2807                 case 1:
2808                         VM_Warning("gettagindex: can't affect world entity\n");
2809                         break;
2810                 case 2:
2811                         VM_Warning("gettagindex: can't affect free entity\n");
2812                         break;
2813                 case 3:
2814                         Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2815                         break;
2816                 case 4:
2817                         Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2818                         break;
2819                 case 5:
2820                         Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2821                         break;
2822         }
2823 }
2824
2825 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2826 static void VM_SV_dropclient (void)
2827 {
2828         int clientnum;
2829         client_t *oldhostclient;
2830         VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2831         clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2832         if (clientnum < 0 || clientnum >= svs.maxclients)
2833         {
2834                 VM_Warning("dropclient: not a client\n");
2835                 return;
2836         }
2837         if (!svs.clients[clientnum].active)
2838         {
2839                 VM_Warning("dropclient: that client slot is not connected\n");
2840                 return;
2841         }
2842         oldhostclient = host_client;
2843         host_client = svs.clients + clientnum;
2844         SV_DropClient(false);
2845         host_client = oldhostclient;
2846 }
2847
2848 //entity() spawnclient (DP_SV_BOTCLIENT)
2849 static void VM_SV_spawnclient (void)
2850 {
2851         int i;
2852         prvm_edict_t    *ed;
2853         VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2854         prog->xfunction->builtinsprofile += 2;
2855         ed = prog->edicts;
2856         for (i = 0;i < svs.maxclients;i++)
2857         {
2858                 if (!svs.clients[i].active)
2859                 {
2860                         prog->xfunction->builtinsprofile += 100;
2861                         SV_ConnectClient (i, NULL);
2862                         // this has to be set or else ClientDisconnect won't be called
2863                         // we assume the qc will call ClientConnect...
2864                         svs.clients[i].clientconnectcalled = true;
2865                         ed = PRVM_EDICT_NUM(i + 1);
2866                         break;
2867                 }
2868         }
2869         VM_RETURN_EDICT(ed);
2870 }
2871
2872 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2873 static void VM_SV_clienttype (void)
2874 {
2875         int clientnum;
2876         VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2877         clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2878         if (clientnum < 0 || clientnum >= svs.maxclients)
2879                 PRVM_G_FLOAT(OFS_RETURN) = 3;
2880         else if (!svs.clients[clientnum].active)
2881                 PRVM_G_FLOAT(OFS_RETURN) = 0;
2882         else if (svs.clients[clientnum].netconnection)
2883                 PRVM_G_FLOAT(OFS_RETURN) = 1;
2884         else
2885                 PRVM_G_FLOAT(OFS_RETURN) = 2;
2886 }
2887
2888 /*
2889 ===============
2890 VM_SV_serverkey
2891
2892 string(string key) serverkey
2893 ===============
2894 */
2895 void VM_SV_serverkey(void)
2896 {
2897         char string[VM_STRINGTEMP_LENGTH];
2898         VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2899         InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2900         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2901 }
2902
2903 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2904 static void VM_SV_setmodelindex (void)
2905 {
2906         prvm_edict_t    *e;
2907         dp_model_t      *mod;
2908         int             i;
2909         VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2910
2911         e = PRVM_G_EDICT(OFS_PARM0);
2912         if (e == prog->edicts)
2913         {
2914                 VM_Warning("setmodelindex: can not modify world entity\n");
2915                 return;
2916         }
2917         if (e->priv.server->free)
2918         {
2919                 VM_Warning("setmodelindex: can not modify free entity\n");
2920                 return;
2921         }
2922         i = (int)PRVM_G_FLOAT(OFS_PARM1);
2923         if (i <= 0 || i > MAX_MODELS)
2924         {
2925                 VM_Warning("setmodelindex: invalid modelindex\n");
2926                 return;
2927         }
2928         if (!sv.model_precache[i][0])
2929         {
2930                 VM_Warning("setmodelindex: model not precached\n");
2931                 return;
2932         }
2933
2934         e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2935         e->fields.server->modelindex = i;
2936
2937         mod = sv.models[i];
2938
2939         if (mod)
2940         {
2941                 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2942                         SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2943                 else
2944                         SetMinMaxSize (e, quakemins, quakemaxs, true);
2945         }
2946         else
2947                 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2948 }
2949
2950 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2951 static void VM_SV_modelnameforindex (void)
2952 {
2953         int i;
2954         VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2955
2956         PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2957
2958         i = (int)PRVM_G_FLOAT(OFS_PARM0);
2959         if (i <= 0 || i > MAX_MODELS)
2960         {
2961                 VM_Warning("modelnameforindex: invalid modelindex\n");
2962                 return;
2963         }
2964         if (!sv.model_precache[i][0])
2965         {
2966                 VM_Warning("modelnameforindex: model not precached\n");
2967                 return;
2968         }
2969
2970         PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2971 }
2972
2973 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2974 static void VM_SV_particleeffectnum (void)
2975 {
2976         int                     i;
2977         VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2978         i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2979         if (i == 0)
2980                 i = -1;
2981         PRVM_G_FLOAT(OFS_RETURN) = i;
2982 }
2983
2984 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2985 static void VM_SV_trailparticles (void)
2986 {
2987         VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2988
2989         if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2990                 return;
2991
2992         MSG_WriteByte(&sv.datagram, svc_trailparticles);
2993         MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2994         MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2995         MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2996         MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2997         SV_FlushBroadcastMessages();
2998 }
2999
3000 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
3001 static void VM_SV_pointparticles (void)
3002 {
3003         int effectnum, count;
3004         vec3_t org, vel;
3005         VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
3006
3007         if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
3008                 return;
3009
3010         effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
3011         VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
3012         VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
3013         count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
3014         if (count == 1 && !VectorLength2(vel))
3015         {
3016                 // 1+2+12=15 bytes
3017                 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
3018                 MSG_WriteShort(&sv.datagram, effectnum);
3019                 MSG_WriteVector(&sv.datagram, org, sv.protocol);
3020         }
3021         else
3022         {
3023                 // 1+2+12+12+2=29 bytes
3024                 MSG_WriteByte(&sv.datagram, svc_pointparticles);
3025                 MSG_WriteShort(&sv.datagram, effectnum);
3026                 MSG_WriteVector(&sv.datagram, org, sv.protocol);
3027                 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
3028                 MSG_WriteShort(&sv.datagram, count);
3029         }
3030
3031         SV_FlushBroadcastMessages();
3032 }
3033
3034 //PF_setpause,    // void(float pause) setpause = #531;
3035 static void VM_SV_setpause(void) {
3036         int pauseValue;
3037         pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
3038         if (pauseValue != 0) { //pause the game
3039                 sv.paused = 1;
3040                 sv.pausedstart = Sys_DoubleTime();
3041         } else { //disable pause, in case it was enabled
3042                 if (sv.paused != 0) {
3043                         sv.paused = 0;
3044                         sv.pausedstart = 0;
3045                 }
3046         }
3047         // send notification to all clients
3048         MSG_WriteByte(&sv.reliable_datagram, svc_setpause);
3049         MSG_WriteByte(&sv.reliable_datagram, sv.paused);
3050 }
3051
3052 prvm_builtin_t vm_sv_builtins[] = {
3053 NULL,                                                   // #0 NULL function (not callable) (QUAKE)
3054 VM_makevectors,                                 // #1 void(vector ang) makevectors (QUAKE)
3055 VM_SV_setorigin,                                // #2 void(entity e, vector o) setorigin (QUAKE)
3056 VM_SV_setmodel,                                 // #3 void(entity e, string m) setmodel (QUAKE)
3057 VM_SV_setsize,                                  // #4 void(entity e, vector min, vector max) setsize (QUAKE)
3058 NULL,                                                   // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
3059 VM_break,                                               // #6 void() break (QUAKE)
3060 VM_random,                                              // #7 float() random (QUAKE)
3061 VM_SV_sound,                                    // #8 void(entity e, float chan, string samp) sound (QUAKE)
3062 VM_normalize,                                   // #9 vector(vector v) normalize (QUAKE)
3063 VM_error,                                               // #10 void(string e) error (QUAKE)
3064 VM_objerror,                                    // #11 void(string e) objerror (QUAKE)
3065 VM_vlen,                                                // #12 float(vector v) vlen (QUAKE)
3066 VM_vectoyaw,                                    // #13 float(vector v) vectoyaw (QUAKE)
3067 VM_spawn,                                               // #14 entity() spawn (QUAKE)
3068 VM_remove,                                              // #15 void(entity e) remove (QUAKE)
3069 VM_SV_traceline,                                // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
3070 VM_SV_checkclient,                              // #17 entity() checkclient (QUAKE)
3071 VM_find,                                                // #18 entity(entity start, .string fld, string match) find (QUAKE)
3072 VM_SV_precache_sound,                   // #19 void(string s) precache_sound (QUAKE)
3073 VM_SV_precache_model,                   // #20 void(string s) precache_model (QUAKE)
3074 VM_SV_stuffcmd,                                 // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
3075 VM_SV_findradius,                               // #22 entity(vector org, float rad) findradius (QUAKE)
3076 VM_bprint,                                              // #23 void(string s, ...) bprint (QUAKE)
3077 VM_SV_sprint,                                   // #24 void(entity client, string s, ...) sprint (QUAKE)
3078 VM_dprint,                                              // #25 void(string s, ...) dprint (QUAKE)
3079 VM_ftos,                                                // #26 string(float f) ftos (QUAKE)
3080 VM_vtos,                                                // #27 string(vector v) vtos (QUAKE)
3081 VM_coredump,                                    // #28 void() coredump (QUAKE)
3082 VM_traceon,                                             // #29 void() traceon (QUAKE)
3083 VM_traceoff,                                    // #30 void() traceoff (QUAKE)
3084 VM_eprint,                                              // #31 void(entity e) eprint (QUAKE)
3085 VM_SV_walkmove,                                 // #32 float(float yaw, float dist) walkmove (QUAKE)
3086 NULL,                                                   // #33 (QUAKE)
3087 VM_SV_droptofloor,                              // #34 float() droptofloor (QUAKE)
3088 VM_SV_lightstyle,                               // #35 void(float style, string value) lightstyle (QUAKE)
3089 VM_rint,                                                // #36 float(float v) rint (QUAKE)
3090 VM_floor,                                               // #37 float(float v) floor (QUAKE)
3091 VM_ceil,                                                // #38 float(float v) ceil (QUAKE)
3092 NULL,                                                   // #39 (QUAKE)
3093 VM_SV_checkbottom,                              // #40 float(entity e) checkbottom (QUAKE)
3094 VM_SV_pointcontents,                    // #41 float(vector v) pointcontents (QUAKE)
3095 NULL,                                                   // #42 (QUAKE)
3096 VM_fabs,                                                // #43 float(float f) fabs (QUAKE)
3097 VM_SV_aim,                                              // #44 vector(entity e, float speed) aim (QUAKE)
3098 VM_cvar,                                                // #45 float(string s) cvar (QUAKE)
3099 VM_localcmd,                                    // #46 void(string s) localcmd (QUAKE)
3100 VM_nextent,                                             // #47 entity(entity e) nextent (QUAKE)
3101 VM_SV_particle,                                 // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
3102 VM_changeyaw,                                   // #49 void() ChangeYaw (QUAKE)
3103 NULL,                                                   // #50 (QUAKE)
3104 VM_vectoangles,                                 // #51 vector(vector v) vectoangles (QUAKE)
3105 VM_SV_WriteByte,                                // #52 void(float to, float f) WriteByte (QUAKE)
3106 VM_SV_WriteChar,                                // #53 void(float to, float f) WriteChar (QUAKE)
3107 VM_SV_WriteShort,                               // #54 void(float to, float f) WriteShort (QUAKE)
3108 VM_SV_WriteLong,                                // #55 void(float to, float f) WriteLong (QUAKE)
3109 VM_SV_WriteCoord,                               // #56 void(float to, float f) WriteCoord (QUAKE)
3110 VM_SV_WriteAngle,                               // #57 void(float to, float f) WriteAngle (QUAKE)
3111 VM_SV_WriteString,                              // #58 void(float to, string s) WriteString (QUAKE)
3112 VM_SV_WriteEntity,                              // #59 void(float to, entity e) WriteEntity (QUAKE)
3113 VM_sin,                                                 // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
3114 VM_cos,                                                 // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
3115 VM_sqrt,                                                // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
3116 VM_changepitch,                                 // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
3117 VM_SV_tracetoss,                                // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
3118 VM_etos,                                                // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
3119 NULL,                                                   // #66 (QUAKE)
3120 SV_MoveToGoal,                                  // #67 void(float step) movetogoal (QUAKE)
3121 VM_precache_file,                               // #68 string(string s) precache_file (QUAKE)
3122 VM_SV_makestatic,                               // #69 void(entity e) makestatic (QUAKE)
3123 VM_changelevel,                                 // #70 void(string s) changelevel (QUAKE)
3124 NULL,                                                   // #71 (QUAKE)
3125 VM_cvar_set,                                    // #72 void(string var, string val) cvar_set (QUAKE)
3126 VM_SV_centerprint,                              // #73 void(entity client, strings) centerprint (QUAKE)
3127 VM_SV_ambientsound,                             // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
3128 VM_SV_precache_model,                   // #75 string(string s) precache_model2 (QUAKE)
3129 VM_SV_precache_sound,                   // #76 string(string s) precache_sound2 (QUAKE)
3130 VM_precache_file,                               // #77 string(string s) precache_file2 (QUAKE)
3131 VM_SV_setspawnparms,                    // #78 void(entity e) setspawnparms (QUAKE)
3132 NULL,                                                   // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
3133 NULL,                                                   // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
3134 VM_stof,                                                // #81 float(string s) stof (FRIK_FILE)
3135 NULL,                                                   // #82 void(vector where, float set) multicast (QUAKEWORLD)
3136 NULL,                                                   // #83 (QUAKE)
3137 NULL,                                                   // #84 (QUAKE)
3138 NULL,                                                   // #85 (QUAKE)
3139 NULL,                                                   // #86 (QUAKE)
3140 NULL,                                                   // #87 (QUAKE)
3141 NULL,                                                   // #88 (QUAKE)
3142 NULL,                                                   // #89 (QUAKE)
3143 VM_SV_tracebox,                                 // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
3144 VM_randomvec,                                   // #91 vector() randomvec (DP_QC_RANDOMVEC)
3145 VM_SV_getlight,                                 // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
3146 VM_registercvar,                                // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
3147 VM_min,                                                 // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
3148 VM_max,                                                 // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3149 VM_bound,                                               // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3150 VM_pow,                                                 // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3151 VM_findfloat,                                   // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3152 VM_checkextension,                              // #99 float(string s) checkextension (the basis of the extension system)
3153 // FrikaC and Telejano range  #100-#199
3154 NULL,                                                   // #100
3155 NULL,                                                   // #101
3156 NULL,                                                   // #102
3157 NULL,                                                   // #103
3158 NULL,                                                   // #104
3159 NULL,                                                   // #105
3160 NULL,                                                   // #106
3161 NULL,                                                   // #107
3162 NULL,                                                   // #108
3163 NULL,                                                   // #109
3164 VM_fopen,                                               // #110 float(string filename, float mode) fopen (FRIK_FILE)
3165 VM_fclose,                                              // #111 void(float fhandle) fclose (FRIK_FILE)
3166 VM_fgets,                                               // #112 string(float fhandle) fgets (FRIK_FILE)
3167 VM_fputs,                                               // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3168 VM_strlen,                                              // #114 float(string s) strlen (FRIK_FILE)
3169 VM_strcat,                                              // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3170 VM_substring,                                   // #116 string(string s, float start, float length) substring (FRIK_FILE)
3171 VM_stov,                                                // #117 vector(string) stov (FRIK_FILE)
3172 VM_strzone,                                             // #118 string(string s) strzone (FRIK_FILE)
3173 VM_strunzone,                                   // #119 void(string s) strunzone (FRIK_FILE)
3174 NULL,                                                   // #120
3175 NULL,                                                   // #121
3176 NULL,                                                   // #122
3177 NULL,                                                   // #123
3178 NULL,                                                   // #124
3179 NULL,                                                   // #125
3180 NULL,                                                   // #126
3181 NULL,                                                   // #127
3182 NULL,                                                   // #128
3183 NULL,                                                   // #129
3184 NULL,                                                   // #130
3185 NULL,                                                   // #131
3186 NULL,                                                   // #132
3187 NULL,                                                   // #133
3188 NULL,                                                   // #134
3189 NULL,                                                   // #135
3190 NULL,                                                   // #136
3191 NULL,                                                   // #137
3192 NULL,                                                   // #138
3193 NULL,                                                   // #139
3194 NULL,                                                   // #140
3195 NULL,                                                   // #141
3196 NULL,                                                   // #142
3197 NULL,                                                   // #143
3198 NULL,                                                   // #144
3199 NULL,                                                   // #145
3200 NULL,                                                   // #146
3201 NULL,                                                   // #147
3202 NULL,                                                   // #148
3203 NULL,                                                   // #149
3204 NULL,                                                   // #150
3205 NULL,                                                   // #151
3206 NULL,                                                   // #152
3207 NULL,                                                   // #153
3208 NULL,                                                   // #154
3209 NULL,                                                   // #155
3210 NULL,                                                   // #156
3211 NULL,                                                   // #157
3212 NULL,                                                   // #158
3213 NULL,                                                   // #159
3214 NULL,                                                   // #160
3215 NULL,                                                   // #161
3216 NULL,                                                   // #162
3217 NULL,                                                   // #163
3218 NULL,                                                   // #164
3219 NULL,                                                   // #165
3220 NULL,                                                   // #166
3221 NULL,                                                   // #167
3222 NULL,                                                   // #168
3223 NULL,                                                   // #169
3224 NULL,                                                   // #170
3225 NULL,                                                   // #171
3226 NULL,                                                   // #172
3227 NULL,                                                   // #173
3228 NULL,                                                   // #174
3229 NULL,                                                   // #175
3230 NULL,                                                   // #176
3231 NULL,                                                   // #177
3232 NULL,                                                   // #178
3233 NULL,                                                   // #179
3234 NULL,                                                   // #180
3235 NULL,                                                   // #181
3236 NULL,                                                   // #182
3237 NULL,                                                   // #183
3238 NULL,                                                   // #184
3239 NULL,                                                   // #185
3240 NULL,                                                   // #186
3241 NULL,                                                   // #187
3242 NULL,                                                   // #188
3243 NULL,                                                   // #189
3244 NULL,                                                   // #190
3245 NULL,                                                   // #191
3246 NULL,                                                   // #192
3247 NULL,                                                   // #193
3248 NULL,                                                   // #194
3249 NULL,                                                   // #195
3250 NULL,                                                   // #196
3251 NULL,                                                   // #197
3252 NULL,                                                   // #198
3253 NULL,                                                   // #199
3254 // FTEQW range #200-#299
3255 NULL,                                                   // #200
3256 NULL,                                                   // #201
3257 NULL,                                                   // #202
3258 NULL,                                                   // #203
3259 NULL,                                                   // #204
3260 NULL,                                                   // #205
3261 NULL,                                                   // #206
3262 NULL,                                                   // #207
3263 NULL,                                                   // #208
3264 NULL,                                                   // #209
3265 NULL,                                                   // #210
3266 NULL,                                                   // #211
3267 NULL,                                                   // #212
3268 NULL,                                                   // #213
3269 NULL,                                                   // #214
3270 NULL,                                                   // #215
3271 NULL,                                                   // #216
3272 NULL,                                                   // #217
3273 VM_bitshift,                                    // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3274 NULL,                                                   // #219
3275 NULL,                                                   // #220
3276 VM_strstrofs,                                   // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3277 VM_str2chr,                                             // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3278 VM_chr2str,                                             // #223 string(float c, ...) chr2str (FTE_STRINGS)
3279 VM_strconv,                                             // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3280 VM_strpad,                                              // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3281 VM_infoadd,                                             // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3282 VM_infoget,                                             // #227 string(string info, string key) infoget (FTE_STRINGS)
3283 VM_strncmp,                                             // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3284 VM_strncasecmp,                                 // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3285 VM_strncasecmp,                                 // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3286 NULL,                                                   // #231
3287 VM_SV_AddStat,                                  // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3288 NULL,                                                   // #233
3289 NULL,                                                   // #234
3290 NULL,                                                   // #235
3291 NULL,                                                   // #236
3292 NULL,                                                   // #237
3293 NULL,                                                   // #238
3294 NULL,                                                   // #239
3295 VM_SV_checkpvs,                                 // #240 float(vector viewpos, entity viewee) checkpvs;
3296 NULL,                                                   // #241
3297 NULL,                                                   // #242
3298 NULL,                                                   // #243
3299 NULL,                                                   // #244
3300 NULL,                                                   // #245
3301 NULL,                                                   // #246
3302 NULL,                                                   // #247
3303 NULL,                                                   // #248
3304 NULL,                                                   // #249
3305 NULL,                                                   // #250
3306 NULL,                                                   // #251
3307 NULL,                                                   // #252
3308 NULL,                                                   // #253
3309 NULL,                                                   // #254
3310 NULL,                                                   // #255
3311 NULL,                                                   // #256
3312 NULL,                                                   // #257
3313 NULL,                                                   // #258
3314 NULL,                                                   // #259
3315 NULL,                                                   // #260
3316 NULL,                                                   // #261
3317 NULL,                                                   // #262
3318 NULL,                                                   // #263
3319 NULL,                                                   // #264
3320 NULL,                                                   // #265
3321 NULL,                                                   // #266
3322 NULL,                                                   // #267
3323 NULL,                                                   // #268
3324 NULL,                                                   // #269
3325 NULL,                                                   // #270
3326 NULL,                                                   // #271
3327 NULL,                                                   // #272
3328 NULL,                                                   // #273
3329 NULL,                                                   // #274
3330 NULL,                                                   // #275
3331 NULL,                                                   // #276
3332 NULL,                                                   // #277
3333 NULL,                                                   // #278
3334 NULL,                                                   // #279
3335 NULL,                                                   // #280
3336 NULL,                                                   // #281
3337 NULL,                                                   // #282
3338 NULL,                                                   // #283
3339 NULL,                                                   // #284
3340 NULL,                                                   // #285
3341 NULL,                                                   // #286
3342 NULL,                                                   // #287
3343 NULL,                                                   // #288
3344 NULL,                                                   // #289
3345 NULL,                                                   // #290
3346 NULL,                                                   // #291
3347 NULL,                                                   // #292
3348 NULL,                                                   // #293
3349 NULL,                                                   // #294
3350 NULL,                                                   // #295
3351 NULL,                                                   // #296
3352 NULL,                                                   // #297
3353 NULL,                                                   // #298
3354 NULL,                                                   // #299
3355 // CSQC range #300-#399
3356 NULL,                                                   // #300 void() clearscene (EXT_CSQC)
3357 NULL,                                                   // #301 void(float mask) addentities (EXT_CSQC)
3358 NULL,                                                   // #302 void(entity ent) addentity (EXT_CSQC)
3359 NULL,                                                   // #303 float(float property, ...) setproperty (EXT_CSQC)
3360 NULL,                                                   // #304 void() renderscene (EXT_CSQC)
3361 NULL,                                                   // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3362 NULL,                                                   // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3363 NULL,                                                   // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3364 NULL,                                                   // #308 void() R_EndPolygon
3365 NULL,                                                   // #309
3366 NULL,                                                   // #310 vector (vector v) cs_unproject (EXT_CSQC)
3367 NULL,                                                   // #311 vector (vector v) cs_project (EXT_CSQC)
3368 NULL,                                                   // #312
3369 NULL,                                                   // #313
3370 NULL,                                                   // #314
3371 NULL,                                                   // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3372 NULL,                                                   // #316 float(string name) iscachedpic (EXT_CSQC)
3373 NULL,                                                   // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3374 NULL,                                                   // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3375 NULL,                                                   // #319 void(string name) freepic (EXT_CSQC)
3376 NULL,                                                   // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3377 NULL,                                                   // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3378 NULL,                                                   // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3379 NULL,                                                   // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3380 NULL,                                                   // #324 void(float x, float y, float width, float height) drawsetcliparea
3381 NULL,                                                   // #325 void(void) drawresetcliparea
3382 NULL,                                                   // #326
3383 NULL,                                                   // #327
3384 NULL,                                                   // #328
3385 NULL,                                                   // #329
3386 NULL,                                                   // #330 float(float stnum) getstatf (EXT_CSQC)
3387 NULL,                                                   // #331 float(float stnum) getstati (EXT_CSQC)
3388 NULL,                                                   // #332 string(float firststnum) getstats (EXT_CSQC)
3389 VM_SV_setmodelindex,                    // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3390 VM_SV_modelnameforindex,                // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3391 VM_SV_particleeffectnum,                // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3392 VM_SV_trailparticles,                   // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3393 VM_SV_pointparticles,                   // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3394 NULL,                                                   // #338 void(string s, ...) centerprint (EXT_CSQC)
3395 VM_print,                                               // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3396 NULL,                                                   // #340 string(float keynum) keynumtostring (EXT_CSQC)
3397 NULL,                                                   // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3398 NULL,                                                   // #342 string(float keynum) getkeybind (EXT_CSQC)
3399 NULL,                                                   // #343 void(float usecursor) setcursormode (EXT_CSQC)
3400 NULL,                                                   // #344 vector() getmousepos (EXT_CSQC)
3401 NULL,                                                   // #345 float(float framenum) getinputstate (EXT_CSQC)
3402 NULL,                                                   // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3403 NULL,                                                   // #347 void() runstandardplayerphysics (EXT_CSQC)
3404 NULL,                                                   // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3405 NULL,                                                   // #349 float() isdemo (EXT_CSQC)
3406 VM_isserver,                                    // #350 float() isserver (EXT_CSQC)
3407 NULL,                                                   // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3408 NULL,                                                   // #352 void(string cmdname) registercommand (EXT_CSQC)
3409 VM_wasfreed,                                    // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3410 VM_SV_serverkey,                                // #354 string(string key) serverkey (EXT_CSQC)
3411 NULL,                                                   // #355
3412 NULL,                                                   // #356
3413 NULL,                                                   // #357
3414 NULL,                                                   // #358
3415 NULL,                                                   // #359
3416 NULL,                                                   // #360 float() readbyte (EXT_CSQC)
3417 NULL,                                                   // #361 float() readchar (EXT_CSQC)
3418 NULL,                                                   // #362 float() readshort (EXT_CSQC)
3419 NULL,                                                   // #363 float() readlong (EXT_CSQC)
3420 NULL,                                                   // #364 float() readcoord (EXT_CSQC)
3421 NULL,                                                   // #365 float() readangle (EXT_CSQC)
3422 NULL,                                                   // #366 string() readstring (EXT_CSQC)
3423 NULL,                                                   // #367 float() readfloat (EXT_CSQC)
3424 NULL,                                                   // #368
3425 NULL,                                                   // #369
3426 NULL,                                                   // #370
3427 NULL,                                                   // #371
3428 NULL,                                                   // #372
3429 NULL,                                                   // #373
3430 NULL,                                                   // #374
3431 NULL,                                                   // #375
3432 NULL,                                                   // #376
3433 NULL,                                                   // #377
3434 NULL,                                                   // #378
3435 NULL,                                                   // #379
3436 NULL,                                                   // #380
3437 NULL,                                                   // #381
3438 NULL,                                                   // #382
3439 NULL,                                                   // #383
3440 NULL,                                                   // #384
3441 NULL,                                                   // #385
3442 NULL,                                                   // #386
3443 NULL,                                                   // #387
3444 NULL,                                                   // #388
3445 NULL,                                                   // #389
3446 NULL,                                                   // #390
3447 NULL,                                                   // #391
3448 NULL,                                                   // #392
3449 NULL,                                                   // #393
3450 NULL,                                                   // #394
3451 NULL,                                                   // #395
3452 NULL,                                                   // #396
3453 NULL,                                                   // #397
3454 NULL,                                                   // #398
3455 NULL,                                                   // #399
3456 // LordHavoc's range #400-#499
3457 VM_SV_copyentity,                               // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3458 VM_SV_setcolor,                                 // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3459 VM_findchain,                                   // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3460 VM_findchainfloat,                              // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3461 VM_SV_effect,                                   // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3462 VM_SV_te_blood,                                 // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3463 VM_SV_te_bloodshower,                   // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3464 VM_SV_te_explosionrgb,                  // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3465 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)
3466 VM_SV_te_particlerain,                  // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3467 VM_SV_te_particlesnow,                  // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3468 VM_SV_te_spark,                                 // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3469 VM_SV_te_gunshotquad,                   // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3470 VM_SV_te_spikequad,                             // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3471 VM_SV_te_superspikequad,                // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3472 VM_SV_te_explosionquad,                 // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3473 VM_SV_te_smallflash,                    // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3474 VM_SV_te_customflash,                   // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3475 VM_SV_te_gunshot,                               // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3476 VM_SV_te_spike,                                 // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3477 VM_SV_te_superspike,                    // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3478 VM_SV_te_explosion,                             // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3479 VM_SV_te_tarexplosion,                  // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3480 VM_SV_te_wizspike,                              // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3481 VM_SV_te_knightspike,                   // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3482 VM_SV_te_lavasplash,                    // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3483 VM_SV_te_teleport,                              // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3484 VM_SV_te_explosion2,                    // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3485 VM_SV_te_lightning1,                    // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3486 VM_SV_te_lightning2,                    // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3487 VM_SV_te_lightning3,                    // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3488 VM_SV_te_beam,                                  // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3489 VM_vectorvectors,                               // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3490 VM_SV_te_plasmaburn,                    // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3491 VM_SV_getsurfacenumpoints,              // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3492 VM_SV_getsurfacepoint,                  // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3493 VM_SV_getsurfacenormal,                 // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3494 VM_SV_getsurfacetexture,                // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3495 VM_SV_getsurfacenearpoint,              // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3496 VM_SV_getsurfaceclippedpoint,   // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3497 VM_SV_clientcommand,                    // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3498 VM_tokenize,                                    // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3499 VM_argv,                                                // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3500 VM_SV_setattachment,                    // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3501 VM_search_begin,                                // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3502 VM_search_end,                                  // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3503 VM_search_getsize,                              // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3504 VM_search_getfilename,                  // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3505 VM_cvar_string,                                 // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3506 VM_findflags,                                   // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3507 VM_findchainflags,                              // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3508 VM_SV_gettagindex,                              // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3509 VM_SV_gettaginfo,                               // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3510 VM_SV_dropclient,                               // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3511 VM_SV_spawnclient,                              // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3512 VM_SV_clienttype,                               // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3513 VM_SV_WriteUnterminatedString,  // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3514 VM_SV_te_flamejet,                              // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3515 NULL,                                                   // #458
3516 VM_ftoe,                                                // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3517 VM_buf_create,                                  // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3518 VM_buf_del,                                             // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3519 VM_buf_getsize,                                 // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3520 VM_buf_copy,                                    // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3521 VM_buf_sort,                                    // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3522 VM_buf_implode,                                 // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3523 VM_bufstr_get,                                  // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3524 VM_bufstr_set,                                  // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3525 VM_bufstr_add,                                  // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3526 VM_bufstr_free,                                 // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3527 NULL,                                                   // #470
3528 VM_asin,                                                // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3529 VM_acos,                                                // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3530 VM_atan,                                                // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3531 VM_atan2,                                               // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3532 VM_tan,                                                 // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3533 VM_strlennocol,                                 // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3534 VM_strdecolorize,                               // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3535 VM_strftime,                                    // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3536 VM_tokenizebyseparator,                 // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3537 VM_strtolower,                                  // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3538 VM_strtoupper,                                  // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3539 VM_cvar_defstring,                              // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3540 VM_SV_pointsound,                               // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3541 VM_strreplace,                                  // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3542 VM_strireplace,                                 // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3543 VM_SV_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3544 NULL,                                                   // #487
3545 NULL,                                                   // #488
3546 NULL,                                                   // #489
3547 NULL,                                                   // #490
3548 NULL,                                                   // #491
3549 NULL,                                                   // #492
3550 NULL,                                                   // #493
3551 VM_crc16,                                               // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3552 VM_cvar_type,                                   // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3553 VM_numentityfields,                             // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3554 VM_entityfieldname,                             // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3555 VM_entityfieldtype,                             // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3556 VM_getentityfieldstring,                // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3557 VM_putentityfieldstring,                // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3558 VM_SV_WritePicture,                             // #501
3559 NULL,                                                   // #502
3560 VM_whichpack,                                   // #503 string(string) whichpack = #503;
3561 NULL,                                                   // #504
3562 NULL,                                                   // #505
3563 NULL,                                                   // #506
3564 NULL,                                                   // #507
3565 NULL,                                                   // #508
3566 NULL,                                                   // #509
3567 VM_uri_escape,                                  // #510 string(string in) uri_escape = #510;
3568 VM_uri_unescape,                                // #511 string(string in) uri_unescape = #511;
3569 VM_etof,                                        // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3570 VM_uri_get,                                             // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3571 VM_tokenize_console,                                    // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3572 VM_argv_start_index,                                    // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3573 VM_argv_end_index,                                              // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3574 VM_buf_cvarlist,                                                // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
3575 VM_cvar_description,                                    // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
3576 NULL,                                                   // #519
3577 NULL,                                                   // #520
3578 NULL,                                                   // #521
3579 NULL,                                                   // #522
3580 NULL,                                                   // #523
3581 NULL,                                                   // #524
3582 NULL,                                                   // #525
3583 NULL,                                                   // #526
3584 NULL,                                                   // #527
3585 NULL,                                                   // #528
3586 NULL,                                                   // #529
3587 NULL,                                                   // #530
3588 VM_SV_setpause,                                 // #531 void(float pause) setpause = #531;
3589 NULL,                                                   // #532
3590 };
3591
3592 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3593
3594 void VM_SV_Cmd_Init(void)
3595 {
3596         VM_Cmd_Init();
3597 }
3598
3599 void VM_SV_Cmd_Reset(void)
3600 {
3601         if(prog->funcoffsets.SV_Shutdown)
3602         {
3603                 func_t s = prog->funcoffsets.SV_Shutdown;
3604                 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3605                 PRVM_ExecuteProgram(s,"SV_Shutdown() required");
3606         }
3607
3608         VM_Cmd_Reset();
3609 }
3610