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