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