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