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