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