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