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