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