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