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