6 //============================================================================
11 char *vm_sv_extensions =
16 "DP_CON_ALIASPARAMETERS "
22 "DP_CSQC_ENTITYNOCULL "
23 "DP_CSQC_ENTITYTRANSPARENTSORTING_OFFSET "
24 "DP_CSQC_MULTIFRAME_INTERPOLATION "
25 "DP_CSQC_BOXPARTICLES "
26 "DP_CSQC_SPAWNPARTICLE "
27 "DP_CSQC_QUERYRENDERENTITY "
40 "DP_EF_RESTARTANIM_BIT "
45 "DP_ENT_CUSTOMCOLORMAP "
46 "DP_ENT_EXTERIORMODELTOCLIENT "
49 "DP_ENT_LOWPRECISION "
53 "DP_GFX_EXTERNALTEXTURES "
54 "DP_GFX_EXTERNALTEXTURES_PERMAP "
56 "DP_GFX_MODEL_INTERPOLATION "
57 "DP_GFX_QUAKE3MODELTAGS "
61 "DP_HALFLIFE_MAP_CVAR "
64 "DP_LIGHTSTYLE_STATICVALUE "
68 "DP_MOVETYPEBOUNCEMISSILE "
71 "DP_QC_ASINACOSATANATAN2TAN "
77 "DP_QC_CVAR_DEFSTRING "
78 "DP_QC_CVAR_DESCRIPTION "
85 "DP_QC_EXTRESPONSEPACKET "
87 "DP_QC_FINDCHAINFLAGS "
88 "DP_QC_FINDCHAINFLOAT "
89 "DP_QC_FINDCHAIN_TOFIELD "
95 "DP_QC_GETSURFACETRIANGLE "
96 "DP_QC_GETSURFACEPOINTATTRIBUTE "
98 "DP_QC_GETTAGINFO_BONEPROPERTIES "
100 "DP_QC_GETTIME_CDTRACK "
103 "DP_QC_MULTIPLETEMPSTRINGS "
104 "DP_QC_NUM_FOR_EDICT "
106 "DP_QC_SINCOSSQRTPOW "
109 "DP_QC_STRINGBUFFERS "
110 "DP_QC_STRINGBUFFERS_CVARLIST "
111 "DP_QC_STRINGCOLORFUNCTIONS "
112 "DP_QC_STRING_CASE_FUNCTIONS "
114 "DP_QC_TOKENIZEBYSEPARATOR "
115 "DP_QC_TOKENIZE_CONSOLE "
118 "DP_QC_TRACE_MOVETYPE_HITMODEL "
119 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
120 "DP_QC_UNLIMITEDTEMPSTRINGS "
123 "DP_QC_VECTOANGLES_WITH_ROLL "
124 "DP_QC_VECTORVECTORS "
131 "DP_SKELETONOBJECTS "
132 "DP_SND_DIRECTIONLESSATTNNONE "
137 "DP_SND_GETSOUNDTIME "
139 "DP_VIDEO_SUBTITLES "
143 "DP_SV_BOUNCEFACTOR "
144 "DP_SV_CLIENTCAMERA "
145 "DP_SV_CLIENTCOLORS "
148 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
149 "DP_SV_DISCARDABLEDEMO "
150 "DP_SV_DRAWONLYTOCLIENT "
153 "DP_SV_ENTITYCONTENTSTRANSITION "
154 "DP_SV_MODELFLAGS_AS_EFFECTS "
155 "DP_SV_MOVETYPESTEP_LANDEVENT "
157 "DP_SV_NODRAWTOCLIENT "
158 "DP_SV_ONENTITYNOSPAWNFUNCTION "
159 "DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
161 "DP_SV_PING_PACKETLOSS "
162 "DP_SV_PLAYERPHYSICS "
163 "DP_SV_POINTPARTICLES "
165 "DP_SV_PRECACHEANYTIME "
169 "DP_SV_ROTATINGBMODEL "
173 "DP_SV_SPAWNFUNC_PREFIX "
174 "DP_SV_WRITEPICTURE "
175 "DP_SV_WRITEUNTERMINATEDSTRING "
179 "DP_TE_EXPLOSIONRGB "
181 "DP_TE_PARTICLECUBE "
182 "DP_TE_PARTICLERAIN "
183 "DP_TE_PARTICLESNOW "
185 "DP_TE_QUADEFFECTS1 "
188 "DP_TE_STANDARDEFFECTBUILTINS "
189 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
193 "FTE_CSQC_SKELETONOBJECTS "
196 "KRIMZON_SV_PARSECLIENTCOMMAND "
199 "NEXUIZ_PLAYERMODEL "
201 "PRYDON_CLIENTCURSOR "
202 "TENEBRAE_GFX_DLIGHTS "
205 //"EXT_CSQC " // not ready yet
212 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.
214 setorigin (entity, origin)
217 static void VM_SV_setorigin (void)
222 VM_SAFEPARMCOUNT(2, VM_setorigin);
224 e = PRVM_G_EDICT(OFS_PARM0);
225 if (e == prog->edicts)
227 VM_Warning("setorigin: can not modify world entity\n");
230 if (e->priv.server->free)
232 VM_Warning("setorigin: can not modify free entity\n");
235 org = PRVM_G_VECTOR(OFS_PARM1);
236 VectorCopy (org, e->fields.server->origin);
240 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
241 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
245 for (i=0 ; i<3 ; i++)
247 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
249 // set derived values
250 VectorCopy (min, e->fields.server->mins);
251 VectorCopy (max, e->fields.server->maxs);
252 VectorSubtract (max, min, e->fields.server->size);
261 the size box is rotated by the current angle
262 LordHavoc: no it isn't...
264 setsize (entity, minvector, maxvector)
267 static void VM_SV_setsize (void)
272 VM_SAFEPARMCOUNT(3, VM_setsize);
274 e = PRVM_G_EDICT(OFS_PARM0);
275 if (e == prog->edicts)
277 VM_Warning("setsize: can not modify world entity\n");
280 if (e->priv.server->free)
282 VM_Warning("setsize: can not modify free entity\n");
285 min = PRVM_G_VECTOR(OFS_PARM1);
286 max = PRVM_G_VECTOR(OFS_PARM2);
287 SetMinMaxSize (e, min, max, false);
295 setmodel(entity, model)
298 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
299 static void VM_SV_setmodel (void)
305 VM_SAFEPARMCOUNT(2, VM_setmodel);
307 e = PRVM_G_EDICT(OFS_PARM0);
308 if (e == prog->edicts)
310 VM_Warning("setmodel: can not modify world entity\n");
313 if (e->priv.server->free)
315 VM_Warning("setmodel: can not modify free entity\n");
318 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
319 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
320 e->fields.server->modelindex = i;
322 mod = SV_GetModelByIndex(i);
326 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
327 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
329 SetMinMaxSize (e, quakemins, quakemaxs, true);
332 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
339 single print to a specific client
341 sprint(clientent, value)
344 static void VM_SV_sprint (void)
348 char string[VM_STRINGTEMP_LENGTH];
350 VM_VarString(1, string, sizeof(string));
352 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
354 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
355 // LordHavoc: div0 requested that sprintto world operate like print
362 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
364 VM_Warning("tried to centerprint to a non-client\n");
368 client = svs.clients + entnum-1;
369 if (!client->netconnection)
372 MSG_WriteChar(&client->netconnection->message,svc_print);
373 MSG_WriteString(&client->netconnection->message, string);
381 single print to a specific client
383 centerprint(clientent, value)
386 static void VM_SV_centerprint (void)
390 char string[VM_STRINGTEMP_LENGTH];
392 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
394 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
396 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
398 VM_Warning("tried to centerprint to a non-client\n");
402 client = svs.clients + entnum-1;
403 if (!client->netconnection)
406 VM_VarString(1, string, sizeof(string));
407 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
408 MSG_WriteString(&client->netconnection->message, string);
415 particle(origin, color, count)
418 static void VM_SV_particle (void)
424 VM_SAFEPARMCOUNT(4, VM_SV_particle);
426 org = PRVM_G_VECTOR(OFS_PARM0);
427 dir = PRVM_G_VECTOR(OFS_PARM1);
428 color = PRVM_G_FLOAT(OFS_PARM2);
429 count = PRVM_G_FLOAT(OFS_PARM3);
430 SV_StartParticle (org, dir, (int)color, (int)count);
440 static void VM_SV_ambientsound (void)
444 float vol, attenuation;
447 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
449 pos = PRVM_G_VECTOR (OFS_PARM0);
450 samp = PRVM_G_STRING(OFS_PARM1);
451 vol = PRVM_G_FLOAT(OFS_PARM2);
452 attenuation = PRVM_G_FLOAT(OFS_PARM3);
454 // check to see if samp was properly precached
455 soundnum = SV_SoundIndex(samp, 1);
463 // add an svc_spawnambient command to the level signon packet
466 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
468 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
470 MSG_WriteVector(&sv.signon, pos, sv.protocol);
472 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
473 MSG_WriteShort (&sv.signon, soundnum);
475 MSG_WriteByte (&sv.signon, soundnum);
477 MSG_WriteByte (&sv.signon, (int)(vol*255));
478 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
486 Each entity can have eight independant sound sources, like voice,
489 Channel 0 is an auto-allocate channel, the others override anything
490 already running on that entity/channel pair.
492 An attenuation of 0 will play full volume everywhere in the level.
493 Larger attenuations will drop off.
497 static void VM_SV_sound (void)
501 prvm_edict_t *entity;
505 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
507 entity = PRVM_G_EDICT(OFS_PARM0);
508 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
509 sample = PRVM_G_STRING(OFS_PARM2);
510 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
511 attenuation = PRVM_G_FLOAT(OFS_PARM4);
514 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
518 if (volume < 0 || volume > 255)
520 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
524 if (attenuation < 0 || attenuation > 4)
526 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
530 if (channel < 0 || channel > 7)
532 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
536 SV_StartSound (entity, channel, sample, volume, attenuation);
543 Follows the same logic as VM_SV_sound, except instead of
544 an entity, an origin for the sound is provided, and channel
545 is omitted (since no entity is being tracked).
549 static void VM_SV_pointsound(void)
556 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
558 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
559 sample = PRVM_G_STRING(OFS_PARM1);
560 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
561 attenuation = PRVM_G_FLOAT(OFS_PARM3);
563 if (volume < 0 || volume > 255)
565 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
569 if (attenuation < 0 || attenuation > 4)
571 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
575 SV_StartPointSound (org, sample, volume, attenuation);
582 Used for use tracing and shot targeting
583 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
584 if the tryents flag is set.
586 traceline (vector1, vector2, movetype, ignore)
589 static void VM_SV_traceline (void)
596 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
598 prog->xfunction->builtinsprofile += 30;
600 v1 = PRVM_G_VECTOR(OFS_PARM0);
601 v2 = PRVM_G_VECTOR(OFS_PARM1);
602 move = (int)PRVM_G_FLOAT(OFS_PARM2);
603 ent = PRVM_G_EDICT(OFS_PARM3);
605 if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
606 PRVM_ERROR("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
608 trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
610 VM_SetTraceGlobals(&trace);
618 Used for use tracing and shot targeting
619 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
620 if the tryents flag is set.
622 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
625 // LordHavoc: added this for my own use, VERY useful, similar to traceline
626 static void VM_SV_tracebox (void)
628 float *v1, *v2, *m1, *m2;
633 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
635 prog->xfunction->builtinsprofile += 30;
637 v1 = PRVM_G_VECTOR(OFS_PARM0);
638 m1 = PRVM_G_VECTOR(OFS_PARM1);
639 m2 = PRVM_G_VECTOR(OFS_PARM2);
640 v2 = PRVM_G_VECTOR(OFS_PARM3);
641 move = (int)PRVM_G_FLOAT(OFS_PARM4);
642 ent = PRVM_G_EDICT(OFS_PARM5);
644 if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
645 PRVM_ERROR("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
647 trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
649 VM_SetTraceGlobals(&trace);
652 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
657 vec3_t original_origin;
658 vec3_t original_velocity;
659 vec3_t original_angles;
660 vec3_t original_avelocity;
664 VectorCopy(tossent->fields.server->origin , original_origin );
665 VectorCopy(tossent->fields.server->velocity , original_velocity );
666 VectorCopy(tossent->fields.server->angles , original_angles );
667 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
669 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
670 if (val != NULL && val->_float != 0)
671 gravity = val->_float;
674 gravity *= sv_gravity.value * 0.025;
676 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
678 SV_CheckVelocity (tossent);
679 tossent->fields.server->velocity[2] -= gravity;
680 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
681 VectorScale (tossent->fields.server->velocity, 0.05, move);
682 VectorAdd (tossent->fields.server->origin, move, end);
683 trace = SV_TraceBox(tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
684 VectorCopy (trace.endpos, tossent->fields.server->origin);
685 tossent->fields.server->velocity[2] -= gravity;
687 if (trace.fraction < 1)
691 VectorCopy(original_origin , tossent->fields.server->origin );
692 VectorCopy(original_velocity , tossent->fields.server->velocity );
693 VectorCopy(original_angles , tossent->fields.server->angles );
694 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
699 static void VM_SV_tracetoss (void)
703 prvm_edict_t *ignore;
705 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
707 prog->xfunction->builtinsprofile += 600;
709 ent = PRVM_G_EDICT(OFS_PARM0);
710 if (ent == prog->edicts)
712 VM_Warning("tracetoss: can not use world entity\n");
715 ignore = PRVM_G_EDICT(OFS_PARM1);
717 trace = SV_Trace_Toss (ent, ignore);
719 VM_SetTraceGlobals(&trace);
722 //============================================================================
724 static int checkpvsbytes;
725 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
727 static int VM_SV_newcheckclient (int check)
733 // cycle to the next one
735 check = bound(1, check, svs.maxclients);
736 if (check == svs.maxclients)
744 prog->xfunction->builtinsprofile++;
746 if (i == svs.maxclients+1)
748 // look up the client's edict
749 ent = PRVM_EDICT_NUM(i);
750 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
751 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
753 // found a valid client (possibly the same one again)
757 // get the PVS for the entity
758 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
760 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
761 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
770 Returns a client (or object that has a client enemy) that would be a
773 If there is more than one valid option, they are cycled each frame
775 If (self.origin + self.viewofs) is not in the PVS of the current target,
776 it is not returned at all.
781 int c_invis, c_notvis;
782 static void VM_SV_checkclient (void)
784 prvm_edict_t *ent, *self;
787 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
789 // find a new check if on a new frame
790 if (sv.time - sv.lastchecktime >= 0.1)
792 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
793 sv.lastchecktime = sv.time;
796 // return check if it might be visible
797 ent = PRVM_EDICT_NUM(sv.lastcheck);
798 if (ent->priv.server->free || ent->fields.server->health <= 0)
800 VM_RETURN_EDICT(prog->edicts);
804 // if current entity can't possibly see the check entity, return 0
805 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
806 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
807 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
810 VM_RETURN_EDICT(prog->edicts);
814 // might be able to see it
816 VM_RETURN_EDICT(ent);
819 //============================================================================
825 Checks if an entity is in a point's PVS.
826 Should be fast but can be inexact.
828 float checkpvs(vector viewpos, entity viewee) = #240;
831 static void VM_SV_checkpvs (void)
834 prvm_edict_t *viewee;
839 unsigned char fatpvs[MAX_MAP_LEAFS/8];
842 VM_SAFEPARMCOUNT(2, VM_SV_checkpvs);
843 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos);
844 viewee = PRVM_G_EDICT(OFS_PARM1);
846 if(viewee->priv.server->free)
848 VM_Warning("checkpvs: can not check free entity\n");
849 PRVM_G_FLOAT(OFS_RETURN) = 4;
854 if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
856 // no PVS support on this worldmodel... darn
857 PRVM_G_FLOAT(OFS_RETURN) = 3;
860 pvs = sv.worldmodel->brush.GetPVS(sv.worldmodel, viewpos);
863 // viewpos isn't in any PVS... darn
864 PRVM_G_FLOAT(OFS_RETURN) = 2;
867 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
869 // using fat PVS like FTEQW does (slow)
870 if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
872 // no PVS support on this worldmodel... darn
873 PRVM_G_FLOAT(OFS_RETURN) = 3;
876 fatpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
879 // viewpos isn't in any PVS... darn
880 PRVM_G_FLOAT(OFS_RETURN) = 2;
883 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
892 Sends text over to the client's execution buffer
894 stuffcmd (clientent, value, ...)
897 static void VM_SV_stuffcmd (void)
901 char string[VM_STRINGTEMP_LENGTH];
903 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
905 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
906 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
908 VM_Warning("Can't stuffcmd to a non-client\n");
912 VM_VarString(1, string, sizeof(string));
915 host_client = svs.clients + entnum-1;
916 Host_ClientCommands ("%s", string);
924 Returns a chain of entities that have origins within a spherical area
926 findradius (origin, radius)
929 static void VM_SV_findradius (void)
931 prvm_edict_t *ent, *chain;
932 vec_t radius, radius2;
933 vec3_t org, eorg, mins, maxs;
936 static prvm_edict_t *touchedicts[MAX_EDICTS];
939 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findradius);
942 chainfield = PRVM_G_INT(OFS_PARM2);
944 chainfield = prog->fieldoffsets.chain;
946 PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
948 chain = (prvm_edict_t *)prog->edicts;
950 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
951 radius = PRVM_G_FLOAT(OFS_PARM1);
952 radius2 = radius * radius;
954 mins[0] = org[0] - (radius + 1);
955 mins[1] = org[1] - (radius + 1);
956 mins[2] = org[2] - (radius + 1);
957 maxs[0] = org[0] + (radius + 1);
958 maxs[1] = org[1] + (radius + 1);
959 maxs[2] = org[2] + (radius + 1);
960 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
961 if (numtouchedicts > MAX_EDICTS)
963 // this never happens
964 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
965 numtouchedicts = MAX_EDICTS;
967 for (i = 0;i < numtouchedicts;i++)
969 ent = touchedicts[i];
970 prog->xfunction->builtinsprofile++;
971 // Quake did not return non-solid entities but darkplaces does
972 // (note: this is the reason you can't blow up fallen zombies)
973 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
975 // LordHavoc: compare against bounding box rather than center so it
976 // doesn't miss large objects, and use DotProduct instead of Length
977 // for a major speedup
978 VectorSubtract(org, ent->fields.server->origin, eorg);
979 if (sv_gameplayfix_findradiusdistancetobox.integer)
981 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
982 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
983 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
986 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
987 if (DotProduct(eorg, eorg) < radius2)
989 PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
994 VM_RETURN_EDICT(chain);
997 static void VM_SV_precache_sound (void)
999 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
1000 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
1003 static void VM_SV_precache_model (void)
1005 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
1006 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
1007 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
1014 float(float yaw, float dist[, settrace]) walkmove
1017 static void VM_SV_walkmove (void)
1026 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
1028 // assume failure if it returns early
1029 PRVM_G_FLOAT(OFS_RETURN) = 0;
1031 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1032 if (ent == prog->edicts)
1034 VM_Warning("walkmove: can not modify world entity\n");
1037 if (ent->priv.server->free)
1039 VM_Warning("walkmove: can not modify free entity\n");
1042 yaw = PRVM_G_FLOAT(OFS_PARM0);
1043 dist = PRVM_G_FLOAT(OFS_PARM1);
1044 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
1046 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1049 yaw = yaw*M_PI*2 / 360;
1051 move[0] = cos(yaw)*dist;
1052 move[1] = sin(yaw)*dist;
1055 // save program state, because SV_movestep may call other progs
1056 oldf = prog->xfunction;
1057 oldself = prog->globals.server->self;
1059 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
1062 // restore program state
1063 prog->xfunction = oldf;
1064 prog->globals.server->self = oldself;
1074 static void VM_SV_droptofloor (void)
1080 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
1082 // assume failure if it returns early
1083 PRVM_G_FLOAT(OFS_RETURN) = 0;
1085 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1086 if (ent == prog->edicts)
1088 VM_Warning("droptofloor: can not modify world entity\n");
1091 if (ent->priv.server->free)
1093 VM_Warning("droptofloor: can not modify free entity\n");
1097 VectorCopy (ent->fields.server->origin, end);
1100 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
1101 SV_UnstickEntity(ent);
1103 trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1104 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
1107 VectorSet(offset, 0.5f * (ent->fields.server->mins[0] + ent->fields.server->maxs[0]), 0.5f * (ent->fields.server->mins[1] + ent->fields.server->maxs[1]), ent->fields.server->mins[2]);
1108 VectorAdd(ent->fields.server->origin, offset, org);
1109 trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1110 VectorSubtract(trace.endpos, offset, trace.endpos);
1111 if (trace.startsolid)
1113 Con_DPrintf("droptofloor at %f %f %f - COULD NOT FIX BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
1114 SV_UnstickEntity(ent);
1116 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1117 ent->fields.server->groundentity = 0;
1118 PRVM_G_FLOAT(OFS_RETURN) = 1;
1120 else if (trace.fraction < 1)
1122 Con_DPrintf("droptofloor at %f %f %f - FIXED BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
1123 VectorCopy (trace.endpos, ent->fields.server->origin);
1124 SV_UnstickEntity(ent);
1126 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1127 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1128 PRVM_G_FLOAT(OFS_RETURN) = 1;
1129 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1130 ent->priv.server->suspendedinairflag = true;
1135 if (trace.fraction != 1)
1137 if (trace.fraction < 1)
1138 VectorCopy (trace.endpos, ent->fields.server->origin);
1140 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1141 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1142 PRVM_G_FLOAT(OFS_RETURN) = 1;
1143 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1144 ent->priv.server->suspendedinairflag = true;
1153 void(float style, string value) lightstyle
1156 static void VM_SV_lightstyle (void)
1163 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1165 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1166 val = PRVM_G_STRING(OFS_PARM1);
1168 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1169 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1172 // change the string in sv
1173 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1175 // send message to all clients on this server
1176 if (sv.state != ss_active)
1179 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1181 if (client->active && client->netconnection)
1183 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1184 MSG_WriteChar (&client->netconnection->message,style);
1185 MSG_WriteString (&client->netconnection->message, val);
1195 static void VM_SV_checkbottom (void)
1197 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1198 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1206 static void VM_SV_pointcontents (void)
1208 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1209 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1216 Pick a vector for the player to shoot along
1217 vector aim(entity, missilespeed)
1220 static void VM_SV_aim (void)
1222 prvm_edict_t *ent, *check, *bestent;
1223 vec3_t start, dir, end, bestdir;
1226 float dist, bestdist;
1229 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1231 // assume failure if it returns early
1232 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1233 // if sv_aim is so high it can't possibly accept anything, skip out early
1234 if (sv_aim.value >= 1)
1237 ent = PRVM_G_EDICT(OFS_PARM0);
1238 if (ent == prog->edicts)
1240 VM_Warning("aim: can not use world entity\n");
1243 if (ent->priv.server->free)
1245 VM_Warning("aim: can not use free entity\n");
1248 //speed = PRVM_G_FLOAT(OFS_PARM1);
1250 VectorCopy (ent->fields.server->origin, start);
1253 // try sending a trace straight
1254 VectorCopy (prog->globals.server->v_forward, dir);
1255 VectorMA (start, 2048, dir, end);
1256 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1257 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1258 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1260 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1265 // try all possible entities
1266 VectorCopy (dir, bestdir);
1267 bestdist = sv_aim.value;
1270 check = PRVM_NEXT_EDICT(prog->edicts);
1271 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1273 prog->xfunction->builtinsprofile++;
1274 if (check->fields.server->takedamage != DAMAGE_AIM)
1278 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1279 continue; // don't aim at teammate
1280 for (j=0 ; j<3 ; j++)
1281 end[j] = check->fields.server->origin[j]
1282 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1283 VectorSubtract (end, start, dir);
1284 VectorNormalize (dir);
1285 dist = DotProduct (dir, prog->globals.server->v_forward);
1286 if (dist < bestdist)
1287 continue; // to far to turn
1288 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1289 if (tr.ent == check)
1290 { // can shoot at this one
1298 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1299 dist = DotProduct (dir, prog->globals.server->v_forward);
1300 VectorScale (prog->globals.server->v_forward, dist, end);
1302 VectorNormalize (end);
1303 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1307 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1312 ===============================================================================
1316 ===============================================================================
1319 #define MSG_BROADCAST 0 // unreliable to all
1320 #define MSG_ONE 1 // reliable to one (msg_entity)
1321 #define MSG_ALL 2 // reliable to all
1322 #define MSG_INIT 3 // write to the init string
1323 #define MSG_ENTITY 5
1325 sizebuf_t *WriteDest (void)
1331 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1335 return &sv.datagram;
1338 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1339 entnum = PRVM_NUM_FOR_EDICT(ent);
1340 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1342 VM_Warning ("WriteDest: tried to write to non-client\n");
1343 return &sv.reliable_datagram;
1346 return &svs.clients[entnum-1].netconnection->message;
1349 VM_Warning ("WriteDest: bad destination\n");
1351 return &sv.reliable_datagram;
1357 return sv.writeentitiestoclient_msg;
1363 static void VM_SV_WriteByte (void)
1365 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1366 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1369 static void VM_SV_WriteChar (void)
1371 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1372 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1375 static void VM_SV_WriteShort (void)
1377 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1378 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1381 static void VM_SV_WriteLong (void)
1383 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1384 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1387 static void VM_SV_WriteAngle (void)
1389 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1390 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1393 static void VM_SV_WriteCoord (void)
1395 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1396 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1399 static void VM_SV_WriteString (void)
1401 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1402 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1405 static void VM_SV_WriteUnterminatedString (void)
1407 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1408 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1412 static void VM_SV_WriteEntity (void)
1414 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1415 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1418 // writes a picture as at most size bytes of data
1420 // IMGNAME \0 SIZE(short) IMGDATA
1421 // if failed to read/compress:
1423 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1424 static void VM_SV_WritePicture (void)
1426 const char *imgname;
1430 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1432 imgname = PRVM_G_STRING(OFS_PARM1);
1433 size = (int) PRVM_G_FLOAT(OFS_PARM2);
1437 MSG_WriteString(WriteDest(), imgname);
1438 if(Image_Compress(imgname, size, &buf, &size))
1441 MSG_WriteShort(WriteDest(), size);
1442 SZ_Write(WriteDest(), (unsigned char *) buf, size);
1447 MSG_WriteShort(WriteDest(), 0);
1451 //////////////////////////////////////////////////////////
1453 static void VM_SV_makestatic (void)
1458 // allow 0 parameters due to an id1 qc bug in which this function is used
1459 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1460 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1462 if (prog->argc >= 1)
1463 ent = PRVM_G_EDICT(OFS_PARM0);
1465 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1466 if (ent == prog->edicts)
1468 VM_Warning("makestatic: can not modify world entity\n");
1471 if (ent->priv.server->free)
1473 VM_Warning("makestatic: can not modify free entity\n");
1478 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1483 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1484 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1485 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1487 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1489 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1490 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1491 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1495 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1496 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1497 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1500 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1501 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1502 for (i=0 ; i<3 ; i++)
1504 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1505 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1508 // throw the entity away now
1512 //=============================================================================
1519 static void VM_SV_setspawnparms (void)
1525 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1527 ent = PRVM_G_EDICT(OFS_PARM0);
1528 i = PRVM_NUM_FOR_EDICT(ent);
1529 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1531 Con_Print("tried to setspawnparms on a non-client\n");
1535 // copy spawn parms out of the client_t
1536 client = svs.clients + i-1;
1537 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1538 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1545 Returns a color vector indicating the lighting at the requested point.
1547 (Internal Operation note: actually measures the light beneath the point, just like
1548 the model lighting on the client)
1553 static void VM_SV_getlight (void)
1555 vec3_t ambientcolor, diffusecolor, diffusenormal;
1557 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1558 p = PRVM_G_VECTOR(OFS_PARM0);
1559 VectorClear(ambientcolor);
1560 VectorClear(diffusecolor);
1561 VectorClear(diffusenormal);
1562 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1563 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1564 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1569 unsigned char type; // 1/2/8 or other value if isn't used
1573 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1574 static int vm_customstats_last;
1576 void VM_CustomStats_Clear (void)
1580 Z_Free(vm_customstats);
1581 vm_customstats = NULL;
1582 vm_customstats_last = -1;
1586 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1594 for(i=0; i<vm_customstats_last+1 ;i++)
1596 if(!vm_customstats[i].type)
1598 switch(vm_customstats[i].type)
1600 //string as 16 bytes
1603 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1604 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1605 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1606 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1607 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1609 //float field sent as-is
1611 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1613 //integer value of float field
1615 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1623 // void(float index, float type, .void field) SV_AddStat = #232;
1624 // Set up an auto-sent player stat.
1625 // Client's get thier own fields sent to them. Index may not be less than 32.
1626 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1627 // 1: string (4 stats carrying a total of 16 charactures)
1628 // 2: float (one stat, float converted to an integer for transportation)
1629 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1630 static void VM_SV_AddStat (void)
1635 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1639 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1642 VM_Warning("PF_SV_AddStat: not enough memory\n");
1646 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1647 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1648 off = PRVM_G_INT (OFS_PARM2);
1653 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1656 if(i >= (MAX_CL_STATS-32))
1658 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1661 if(i > (MAX_CL_STATS-32-4) && type == 1)
1663 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1666 vm_customstats[i].type = type;
1667 vm_customstats[i].fieldoffset = off;
1668 if(vm_customstats_last < i)
1669 vm_customstats_last = i;
1676 copies data from one entity to another
1678 copyentity(src, dst)
1681 static void VM_SV_copyentity (void)
1683 prvm_edict_t *in, *out;
1684 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1685 in = PRVM_G_EDICT(OFS_PARM0);
1686 if (in == prog->edicts)
1688 VM_Warning("copyentity: can not read world entity\n");
1691 if (in->priv.server->free)
1693 VM_Warning("copyentity: can not read free entity\n");
1696 out = PRVM_G_EDICT(OFS_PARM1);
1697 if (out == prog->edicts)
1699 VM_Warning("copyentity: can not modify world entity\n");
1702 if (out->priv.server->free)
1704 VM_Warning("copyentity: can not modify free entity\n");
1707 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1716 sets the color of a client and broadcasts the update to all connected clients
1718 setcolor(clientent, value)
1721 static void VM_SV_setcolor (void)
1727 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1728 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1729 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1731 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1733 Con_Print("tried to setcolor a non-client\n");
1737 client = svs.clients + entnum-1;
1740 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1742 client->edict->fields.server->team = (i & 15) + 1;
1745 if (client->old_colors != client->colors)
1747 client->old_colors = client->colors;
1748 // send notification to all clients
1749 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1750 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1751 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1759 effect(origin, modelname, startframe, framecount, framerate)
1762 static void VM_SV_effect (void)
1766 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1767 s = PRVM_G_STRING(OFS_PARM1);
1770 VM_Warning("effect: no model specified\n");
1774 i = SV_ModelIndex(s, 1);
1777 VM_Warning("effect: model not precached\n");
1781 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1783 VM_Warning("effect: framecount < 1\n");
1787 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1789 VM_Warning("effect: framerate < 1\n");
1793 SV_StartEffect(PRVM_G_VECTOR(OFS_PARM0), i, (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4));
1796 static void VM_SV_te_blood (void)
1798 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1799 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1801 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1802 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1804 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1805 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1806 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1808 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1809 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1810 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1812 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1813 SV_FlushBroadcastMessages();
1816 static void VM_SV_te_bloodshower (void)
1818 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1819 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1821 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1822 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1824 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1825 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1826 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1828 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1829 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1830 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1834 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1835 SV_FlushBroadcastMessages();
1838 static void VM_SV_te_explosionrgb (void)
1840 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1841 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1842 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1844 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1845 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1846 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1848 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1849 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1850 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1851 SV_FlushBroadcastMessages();
1854 static void VM_SV_te_particlecube (void)
1856 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1857 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1859 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1860 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1862 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1863 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1864 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1866 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1867 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1871 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1872 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1874 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1876 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1877 // gravity true/false
1878 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1880 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1881 SV_FlushBroadcastMessages();
1884 static void VM_SV_te_particlerain (void)
1886 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1887 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1889 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1890 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1892 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1893 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1894 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1896 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1897 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1898 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1902 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1904 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1906 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1907 SV_FlushBroadcastMessages();
1910 static void VM_SV_te_particlesnow (void)
1912 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1913 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1915 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1916 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1918 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1919 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1920 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1922 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1923 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1924 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1926 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1927 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1928 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1930 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1932 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1933 SV_FlushBroadcastMessages();
1936 static void VM_SV_te_spark (void)
1938 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1939 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1941 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1942 MSG_WriteByte(&sv.datagram, TE_SPARK);
1944 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1945 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1946 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1948 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1949 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1950 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1952 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1953 SV_FlushBroadcastMessages();
1956 static void VM_SV_te_gunshotquad (void)
1958 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1959 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1960 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1962 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1963 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1964 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1965 SV_FlushBroadcastMessages();
1968 static void VM_SV_te_spikequad (void)
1970 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1971 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1972 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1974 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1976 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1977 SV_FlushBroadcastMessages();
1980 static void VM_SV_te_superspikequad (void)
1982 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1983 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1984 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1986 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1987 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1988 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1989 SV_FlushBroadcastMessages();
1992 static void VM_SV_te_explosionquad (void)
1994 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1995 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1996 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1998 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1999 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2000 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2001 SV_FlushBroadcastMessages();
2004 static void VM_SV_te_smallflash (void)
2006 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
2007 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2008 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2010 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2011 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2012 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2013 SV_FlushBroadcastMessages();
2016 static void VM_SV_te_customflash (void)
2018 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
2019 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2021 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2022 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2024 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2025 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2026 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2028 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2030 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
2032 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
2033 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
2034 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
2035 SV_FlushBroadcastMessages();
2038 static void VM_SV_te_gunshot (void)
2040 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
2041 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2042 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2044 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2045 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2046 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2047 SV_FlushBroadcastMessages();
2050 static void VM_SV_te_spike (void)
2052 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
2053 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2054 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2056 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2057 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2058 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2059 SV_FlushBroadcastMessages();
2062 static void VM_SV_te_superspike (void)
2064 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
2065 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2066 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2068 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2069 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2070 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2071 SV_FlushBroadcastMessages();
2074 static void VM_SV_te_explosion (void)
2076 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
2077 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2078 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2080 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2081 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2082 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2083 SV_FlushBroadcastMessages();
2086 static void VM_SV_te_tarexplosion (void)
2088 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
2089 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2090 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2092 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2093 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2094 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2095 SV_FlushBroadcastMessages();
2098 static void VM_SV_te_wizspike (void)
2100 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
2101 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2102 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2104 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2105 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2106 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2107 SV_FlushBroadcastMessages();
2110 static void VM_SV_te_knightspike (void)
2112 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2113 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2114 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2116 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2117 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2118 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2119 SV_FlushBroadcastMessages();
2122 static void VM_SV_te_lavasplash (void)
2124 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2125 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2126 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2128 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2129 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2130 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2131 SV_FlushBroadcastMessages();
2134 static void VM_SV_te_teleport (void)
2136 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2137 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2138 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2140 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2141 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2142 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2143 SV_FlushBroadcastMessages();
2146 static void VM_SV_te_explosion2 (void)
2148 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2149 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2150 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2152 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2153 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2154 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2156 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2157 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2158 SV_FlushBroadcastMessages();
2161 static void VM_SV_te_lightning1 (void)
2163 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2164 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2165 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2167 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2169 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2170 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2171 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2173 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2174 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2175 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2176 SV_FlushBroadcastMessages();
2179 static void VM_SV_te_lightning2 (void)
2181 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2182 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2183 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2185 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2187 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2188 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2189 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2191 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2192 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2193 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2194 SV_FlushBroadcastMessages();
2197 static void VM_SV_te_lightning3 (void)
2199 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2200 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2201 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2203 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2205 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2206 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2207 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2209 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2210 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2211 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2212 SV_FlushBroadcastMessages();
2215 static void VM_SV_te_beam (void)
2217 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2218 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2219 MSG_WriteByte(&sv.datagram, TE_BEAM);
2221 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2223 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2224 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2225 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2227 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2228 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2229 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2230 SV_FlushBroadcastMessages();
2233 static void VM_SV_te_plasmaburn (void)
2235 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2236 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2237 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2238 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2239 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2240 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2241 SV_FlushBroadcastMessages();
2244 static void VM_SV_te_flamejet (void)
2246 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2247 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2248 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2250 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2251 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2252 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2254 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2255 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2256 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2258 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2259 SV_FlushBroadcastMessages();
2262 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2263 //this function originally written by KrimZon, made shorter by LordHavoc
2264 static void VM_SV_clientcommand (void)
2266 client_t *temp_client;
2268 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2270 //find client for this entity
2271 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2272 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2274 Con_Print("PF_clientcommand: entity is not a client\n");
2278 temp_client = host_client;
2279 host_client = svs.clients + i;
2280 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2281 host_client = temp_client;
2284 //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)
2285 static void VM_SV_setattachment (void)
2287 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2288 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2289 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2292 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2294 if (e == prog->edicts)
2296 VM_Warning("setattachment: can not modify world entity\n");
2299 if (e->priv.server->free)
2301 VM_Warning("setattachment: can not modify free entity\n");
2305 if (tagentity == NULL)
2306 tagentity = prog->edicts;
2308 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2310 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2312 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2315 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2317 model = SV_GetModelFromEdict(tagentity);
2320 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2322 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);
2325 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));
2329 /////////////////////////////////////////
2330 // DP_MD3_TAGINFO extension coded by VorteX
2332 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2336 i = (int)e->fields.server->modelindex;
2337 if (i < 1 || i >= MAX_MODELS)
2340 return Mod_Alias_GetTagIndexForName(SV_GetModelByIndex(i), (int)e->fields.server->skin, tagname);
2343 int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
2350 Matrix4x4_CreateIdentity(tag_localmatrix);
2352 if (tagindex >= 0 && (model = SV_GetModelFromEdict(e)) && model->num_bones)
2354 r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, e->priv.server->frameblend, &e->priv.server->skeleton, tagindex - 1, parentindex, tagname, tag_localmatrix);
2365 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2369 float pitchsign = 1;
2372 val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
2373 if (val && val->_float != 0)
2374 scale = val->_float;
2377 Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] + ent->fields.server->view_ofs[2], ent->fields.server->v_angle[0], ent->fields.server->v_angle[1], ent->fields.server->v_angle[2], scale * cl_viewmodel_scale.value);
2380 pitchsign = SV_GetPitchSign(ent);
2381 Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], pitchsign * ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], scale);
2385 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2388 if (tagindex >= 0 && (model = SV_GetModelFromEdict(ent)) && model->animscenes)
2390 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2391 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2392 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2393 return Mod_Alias_GetTagMatrix(model, ent->priv.server->frameblend, &ent->priv.server->skeleton, tagindex, out);
2395 *out = identitymatrix;
2399 // Warnings/errors code:
2400 // 0 - normal (everything all-right)
2403 // 3 - null or non-precached model
2404 // 4 - no tags with requested index
2405 // 5 - runaway loop at attachment chain
2406 extern cvar_t cl_bob;
2407 extern cvar_t cl_bobcycle;
2408 extern cvar_t cl_bobup;
2409 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2413 int modelindex, attachloop;
2414 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2417 *out = identitymatrix; // warnings and errors return identical matrix
2419 if (ent == prog->edicts)
2421 if (ent->priv.server->free)
2424 modelindex = (int)ent->fields.server->modelindex;
2425 if (modelindex <= 0 || modelindex >= MAX_MODELS)
2428 model = SV_GetModelByIndex(modelindex);
2430 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2431 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2432 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2434 tagmatrix = identitymatrix;
2435 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2439 if (attachloop >= 256) // prevent runaway looping
2441 // apply transformation by child's tagindex on parent entity and then
2442 // by parent entity itself
2443 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2444 if (ret && attachloop == 0)
2446 SV_GetEntityMatrix(ent, &entitymatrix, false);
2447 Matrix4x4_Concat(&tagmatrix, &attachmatrix, out);
2448 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2449 // next iteration we process the parent entity
2450 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2452 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2453 ent = PRVM_EDICT_NUM(val->edict);
2460 // RENDER_VIEWMODEL magic
2461 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2463 Matrix4x4_Copy(&tagmatrix, out);
2464 ent = PRVM_EDICT_NUM(val->edict);
2466 SV_GetEntityMatrix(ent, &entitymatrix, true);
2467 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2470 // Cl_bob, ported from rendering code
2471 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2474 // LordHavoc: this code is *weird*, but not replacable (I think it
2475 // should be done in QC on the server, but oh well, quake is quake)
2476 // LordHavoc: figured out bobup: the time at which the sin is at 180
2477 // degrees (which allows lengthening or squishing the peak or valley)
2478 cycle = sv.time/cl_bobcycle.value;
2479 cycle -= (int)cycle;
2480 if (cycle < cl_bobup.value)
2481 cycle = sin(M_PI * cycle / cl_bobup.value);
2483 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2484 // bob is proportional to velocity in the xy plane
2485 // (don't count Z, or jumping messes it up)
2486 bob = sqrt(ent->fields.server->velocity[0]*ent->fields.server->velocity[0] + ent->fields.server->velocity[1]*ent->fields.server->velocity[1])*cl_bob.value;
2487 bob = bob*0.3 + bob*0.7*cycle;
2488 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2495 //float(entity ent, string tagname) gettagindex;
2497 static void VM_SV_gettagindex (void)
2500 const char *tag_name;
2503 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2505 ent = PRVM_G_EDICT(OFS_PARM0);
2506 tag_name = PRVM_G_STRING(OFS_PARM1);
2508 if (ent == prog->edicts)
2510 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
2513 if (ent->priv.server->free)
2515 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
2520 if (!SV_GetModelFromEdict(ent))
2521 Con_DPrintf("VM_SV_gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2524 tag_index = SV_GetTagIndex(ent, tag_name);
2526 if(developer_extra.integer)
2527 Con_DPrintf("VM_SV_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2529 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2532 //vector(entity ent, float tagindex) gettaginfo;
2533 static void VM_SV_gettaginfo (void)
2537 matrix4x4_t tag_matrix;
2538 matrix4x4_t tag_localmatrix;
2540 const char *tagname;
2543 vec3_t fo, le, up, trans;
2544 const dp_model_t *model;
2546 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2548 e = PRVM_G_EDICT(OFS_PARM0);
2549 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2551 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2552 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, le, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2553 VectorScale(le, -1, prog->globals.server->v_right);
2554 model = SV_GetModelFromEdict(e);
2555 VM_GenerateFrameGroupBlend(e->priv.server->framegroupblend, e);
2556 VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model);
2557 VM_UpdateEdictSkeleton(e, model, e->priv.server->frameblend);
2558 SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
2559 Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
2561 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
2562 val->_float = parentindex;
2563 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
2564 val->string = tagname ? PRVM_SetTempString(tagname) : 0;
2565 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
2566 VectorCopy(trans, val->vector);
2567 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
2568 VectorCopy(fo, val->vector);
2569 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
2570 VectorScale(le, -1, val->vector);
2571 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
2572 VectorCopy(up, val->vector);
2577 VM_Warning("gettagindex: can't affect world entity\n");
2580 VM_Warning("gettagindex: can't affect free entity\n");
2583 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2586 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2589 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2594 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2595 static void VM_SV_dropclient (void)
2598 client_t *oldhostclient;
2599 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2600 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2601 if (clientnum < 0 || clientnum >= svs.maxclients)
2603 VM_Warning("dropclient: not a client\n");
2606 if (!svs.clients[clientnum].active)
2608 VM_Warning("dropclient: that client slot is not connected\n");
2611 oldhostclient = host_client;
2612 host_client = svs.clients + clientnum;
2613 SV_DropClient(false);
2614 host_client = oldhostclient;
2617 //entity() spawnclient (DP_SV_BOTCLIENT)
2618 static void VM_SV_spawnclient (void)
2622 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2623 prog->xfunction->builtinsprofile += 2;
2625 for (i = 0;i < svs.maxclients;i++)
2627 if (!svs.clients[i].active)
2629 prog->xfunction->builtinsprofile += 100;
2630 SV_ConnectClient (i, NULL);
2631 // this has to be set or else ClientDisconnect won't be called
2632 // we assume the qc will call ClientConnect...
2633 svs.clients[i].clientconnectcalled = true;
2634 ed = PRVM_EDICT_NUM(i + 1);
2638 VM_RETURN_EDICT(ed);
2641 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2642 static void VM_SV_clienttype (void)
2645 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2646 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2647 if (clientnum < 0 || clientnum >= svs.maxclients)
2648 PRVM_G_FLOAT(OFS_RETURN) = 3;
2649 else if (!svs.clients[clientnum].active)
2650 PRVM_G_FLOAT(OFS_RETURN) = 0;
2651 else if (svs.clients[clientnum].netconnection)
2652 PRVM_G_FLOAT(OFS_RETURN) = 1;
2654 PRVM_G_FLOAT(OFS_RETURN) = 2;
2661 string(string key) serverkey
2664 void VM_SV_serverkey(void)
2666 char string[VM_STRINGTEMP_LENGTH];
2667 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2668 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2669 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2672 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2673 static void VM_SV_setmodelindex (void)
2678 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2680 e = PRVM_G_EDICT(OFS_PARM0);
2681 if (e == prog->edicts)
2683 VM_Warning("setmodelindex: can not modify world entity\n");
2686 if (e->priv.server->free)
2688 VM_Warning("setmodelindex: can not modify free entity\n");
2691 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2692 if (i <= 0 || i >= MAX_MODELS)
2694 VM_Warning("setmodelindex: invalid modelindex\n");
2697 if (!sv.model_precache[i][0])
2699 VM_Warning("setmodelindex: model not precached\n");
2703 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2704 e->fields.server->modelindex = i;
2706 mod = SV_GetModelByIndex(i);
2710 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2711 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2713 SetMinMaxSize (e, quakemins, quakemaxs, true);
2716 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2719 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2720 static void VM_SV_modelnameforindex (void)
2723 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2725 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2727 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2728 if (i <= 0 || i >= MAX_MODELS)
2730 VM_Warning("modelnameforindex: invalid modelindex\n");
2733 if (!sv.model_precache[i][0])
2735 VM_Warning("modelnameforindex: model not precached\n");
2739 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2742 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2743 static void VM_SV_particleeffectnum (void)
2746 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2747 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2750 PRVM_G_FLOAT(OFS_RETURN) = i;
2753 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2754 static void VM_SV_trailparticles (void)
2756 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2758 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2761 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2762 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2763 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2764 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2765 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2766 SV_FlushBroadcastMessages();
2769 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2770 static void VM_SV_pointparticles (void)
2772 int effectnum, count;
2774 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2776 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2779 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2780 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2781 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2782 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2783 if (count == 1 && !VectorLength2(vel))
2786 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2787 MSG_WriteShort(&sv.datagram, effectnum);
2788 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2792 // 1+2+12+12+2=29 bytes
2793 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2794 MSG_WriteShort(&sv.datagram, effectnum);
2795 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2796 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2797 MSG_WriteShort(&sv.datagram, count);
2800 SV_FlushBroadcastMessages();
2803 //PF_setpause, // void(float pause) setpause = #531;
2804 static void VM_SV_setpause(void) {
2806 pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
2807 if (pauseValue != 0) { //pause the game
2809 sv.pausedstart = Sys_DoubleTime();
2810 } else { //disable pause, in case it was enabled
2811 if (sv.paused != 0) {
2816 // send notification to all clients
2817 MSG_WriteByte(&sv.reliable_datagram, svc_setpause);
2818 MSG_WriteByte(&sv.reliable_datagram, sv.paused);
2821 // #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.
2822 static void VM_SV_skel_create(void)
2824 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
2825 dp_model_t *model = SV_GetModelByIndex(modelindex);
2826 skeleton_t *skeleton;
2828 PRVM_G_FLOAT(OFS_RETURN) = 0;
2829 if (!model || !model->num_bones)
2831 for (i = 0;i < MAX_EDICTS;i++)
2832 if (!prog->skeletons[i])
2834 if (i == MAX_EDICTS)
2836 prog->skeletons[i] = skeleton = Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
2837 PRVM_G_FLOAT(OFS_RETURN) = i + 1;
2838 skeleton->model = model;
2839 skeleton->relativetransforms = (matrix4x4_t *)(skeleton+1);
2840 // initialize to identity matrices
2841 for (i = 0;i < skeleton->model->num_bones;i++)
2842 skeleton->relativetransforms[i] = identitymatrix;
2845 // #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
2846 static void VM_SV_skel_build(void)
2848 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2849 skeleton_t *skeleton;
2850 prvm_edict_t *ed = PRVM_G_EDICT(OFS_PARM1);
2851 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM2);
2852 float retainfrac = PRVM_G_FLOAT(OFS_PARM3);
2853 int firstbone = PRVM_G_FLOAT(OFS_PARM4) - 1;
2854 int lastbone = PRVM_G_FLOAT(OFS_PARM5) - 1;
2855 dp_model_t *model = SV_GetModelByIndex(modelindex);
2860 framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS];
2861 frameblend_t frameblend[MAX_FRAMEBLENDS];
2862 matrix4x4_t blendedmatrix;
2864 PRVM_G_FLOAT(OFS_RETURN) = 0;
2865 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2867 firstbone = max(0, firstbone);
2868 lastbone = min(lastbone, model->num_bones - 1);
2869 lastbone = min(lastbone, skeleton->model->num_bones - 1);
2870 VM_GenerateFrameGroupBlend(framegroupblend, ed);
2871 VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model);
2872 blendfrac = 1.0f - retainfrac;
2873 for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
2874 frameblend[numblends].lerp *= blendfrac;
2875 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
2877 memset(&blendedmatrix, 0, sizeof(blendedmatrix));
2878 Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac);
2879 for (blendindex = 0;blendindex < numblends;blendindex++)
2881 Matrix4x4_FromBonePose6s(&matrix, model->num_posescale, model->data_poses6s + 6 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
2882 Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp);
2884 skeleton->relativetransforms[bonenum] = blendedmatrix;
2886 PRVM_G_FLOAT(OFS_RETURN) = skeletonindex + 1;
2889 // #265 float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS) returns how many bones exist in the created skeleton
2890 static void VM_SV_skel_get_numbones(void)
2892 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2893 skeleton_t *skeleton;
2894 PRVM_G_FLOAT(OFS_RETURN) = 0;
2895 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2897 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->num_bones;
2900 // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) returns name of bone (as a tempstring)
2901 static void VM_SV_skel_get_bonename(void)
2903 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2904 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2905 skeleton_t *skeleton;
2906 PRVM_G_INT(OFS_RETURN) = 0;
2907 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2909 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2911 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(skeleton->model->data_bones[bonenum].name);
2914 // #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)
2915 static void VM_SV_skel_get_boneparent(void)
2917 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2918 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2919 skeleton_t *skeleton;
2920 PRVM_G_FLOAT(OFS_RETURN) = 0;
2921 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2923 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2925 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->data_bones[bonenum].parent + 1;
2928 // #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
2929 static void VM_SV_skel_find_bone(void)
2931 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2932 const char *tagname = PRVM_G_STRING(OFS_PARM1);
2933 skeleton_t *skeleton;
2934 PRVM_G_FLOAT(OFS_RETURN) = 0;
2935 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2937 PRVM_G_FLOAT(OFS_RETURN) = Mod_Alias_GetTagIndexForName(skeleton->model, 0, tagname) + 1;
2940 // #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)
2941 static void VM_SV_skel_get_bonerel(void)
2943 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2944 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2945 skeleton_t *skeleton;
2947 vec3_t forward, left, up, origin;
2948 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2949 VectorClear(prog->globals.client->v_forward);
2950 VectorClear(prog->globals.client->v_right);
2951 VectorClear(prog->globals.client->v_up);
2952 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2954 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2956 matrix = skeleton->relativetransforms[bonenum];
2957 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2958 VectorCopy(forward, prog->globals.client->v_forward);
2959 VectorNegate(left, prog->globals.client->v_right);
2960 VectorCopy(up, prog->globals.client->v_up);
2961 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
2964 // #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)
2965 static void VM_SV_skel_get_boneabs(void)
2967 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2968 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2969 skeleton_t *skeleton;
2972 vec3_t forward, left, up, origin;
2973 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2974 VectorClear(prog->globals.client->v_forward);
2975 VectorClear(prog->globals.client->v_right);
2976 VectorClear(prog->globals.client->v_up);
2977 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2979 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2981 matrix = skeleton->relativetransforms[bonenum];
2982 // convert to absolute
2983 while ((bonenum = skeleton->model->data_bones[bonenum].parent) >= 0)
2986 Matrix4x4_Concat(&matrix, &skeleton->relativetransforms[bonenum], &temp);
2988 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2989 VectorCopy(forward, prog->globals.client->v_forward);
2990 VectorNegate(left, prog->globals.client->v_right);
2991 VectorCopy(up, prog->globals.client->v_up);
2992 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
2995 // #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)
2996 static void VM_SV_skel_set_bone(void)
2998 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2999 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3000 vec3_t forward, left, up, origin;
3001 skeleton_t *skeleton;
3003 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3005 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3007 VectorCopy(prog->globals.client->v_forward, forward);
3008 VectorNegate(prog->globals.client->v_right, left);
3009 VectorCopy(prog->globals.client->v_up, up);
3010 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3011 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3012 skeleton->relativetransforms[bonenum] = matrix;
3015 // #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)
3016 static void VM_SV_skel_mul_bone(void)
3018 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3019 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3020 vec3_t forward, left, up, origin;
3021 skeleton_t *skeleton;
3024 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3026 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3028 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3029 VectorCopy(prog->globals.client->v_forward, forward);
3030 VectorNegate(prog->globals.client->v_right, left);
3031 VectorCopy(prog->globals.client->v_up, up);
3032 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3033 temp = skeleton->relativetransforms[bonenum];
3034 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3037 // #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)
3038 static void VM_SV_skel_mul_bones(void)
3040 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3041 int firstbone = PRVM_G_FLOAT(OFS_PARM1) - 1;
3042 int lastbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3044 vec3_t forward, left, up, origin;
3045 skeleton_t *skeleton;
3048 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3050 VectorCopy(PRVM_G_VECTOR(OFS_PARM3), origin);
3051 VectorCopy(prog->globals.client->v_forward, forward);
3052 VectorNegate(prog->globals.client->v_right, left);
3053 VectorCopy(prog->globals.client->v_up, up);
3054 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3055 firstbone = max(0, firstbone);
3056 lastbone = min(lastbone, skeleton->model->num_bones - 1);
3057 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3059 temp = skeleton->relativetransforms[bonenum];
3060 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3064 // #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
3065 static void VM_SV_skel_copybones(void)
3067 int skeletonindexdst = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3068 int skeletonindexsrc = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3069 int firstbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3070 int lastbone = PRVM_G_FLOAT(OFS_PARM3) - 1;
3072 skeleton_t *skeletondst;
3073 skeleton_t *skeletonsrc;
3074 if (skeletonindexdst < 0 || skeletonindexdst >= MAX_EDICTS || !(skeletondst = prog->skeletons[skeletonindexdst]))
3076 if (skeletonindexsrc < 0 || skeletonindexsrc >= MAX_EDICTS || !(skeletonsrc = prog->skeletons[skeletonindexsrc]))
3078 firstbone = max(0, firstbone);
3079 lastbone = min(lastbone, skeletondst->model->num_bones - 1);
3080 lastbone = min(lastbone, skeletonsrc->model->num_bones - 1);
3081 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3082 skeletondst->relativetransforms[bonenum] = skeletonsrc->relativetransforms[bonenum];
3085 // #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)
3086 static void VM_SV_skel_delete(void)
3088 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3089 skeleton_t *skeleton;
3090 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3093 prog->skeletons[skeletonindex] = NULL;
3096 // #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
3097 static void VM_SV_frameforname(void)
3099 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3100 dp_model_t *model = SV_GetModelByIndex(modelindex);
3101 const char *name = PRVM_G_STRING(OFS_PARM1);
3103 PRVM_G_FLOAT(OFS_RETURN) = -1;
3104 if (!model || !model->animscenes)
3106 for (i = 0;i < model->numframes;i++)
3108 if (!strcasecmp(model->animscenes[i].name, name))
3110 PRVM_G_FLOAT(OFS_RETURN) = i;
3116 // #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.
3117 static void VM_SV_frameduration(void)
3119 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3120 dp_model_t *model = SV_GetModelByIndex(modelindex);
3121 int framenum = (int)PRVM_G_FLOAT(OFS_PARM1);
3122 PRVM_G_FLOAT(OFS_RETURN) = 0;
3123 if (!model || !model->animscenes || framenum < 0 || framenum >= model->numframes)
3125 if (model->animscenes[framenum].framerate)
3126 PRVM_G_FLOAT(OFS_RETURN) = model->animscenes[framenum].framecount / model->animscenes[framenum].framerate;
3130 prvm_builtin_t vm_sv_builtins[] = {
3131 NULL, // #0 NULL function (not callable) (QUAKE)
3132 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
3133 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
3134 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
3135 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
3136 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
3137 VM_break, // #6 void() break (QUAKE)
3138 VM_random, // #7 float() random (QUAKE)
3139 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
3140 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
3141 VM_error, // #10 void(string e) error (QUAKE)
3142 VM_objerror, // #11 void(string e) objerror (QUAKE)
3143 VM_vlen, // #12 float(vector v) vlen (QUAKE)
3144 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
3145 VM_spawn, // #14 entity() spawn (QUAKE)
3146 VM_remove, // #15 void(entity e) remove (QUAKE)
3147 VM_SV_traceline, // #16 void(vector v1, vector v2, float tryents) traceline (QUAKE)
3148 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
3149 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
3150 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
3151 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
3152 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
3153 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
3154 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
3155 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
3156 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
3157 VM_ftos, // #26 string(float f) ftos (QUAKE)
3158 VM_vtos, // #27 string(vector v) vtos (QUAKE)
3159 VM_coredump, // #28 void() coredump (QUAKE)
3160 VM_traceon, // #29 void() traceon (QUAKE)
3161 VM_traceoff, // #30 void() traceoff (QUAKE)
3162 VM_eprint, // #31 void(entity e) eprint (QUAKE)
3163 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
3164 NULL, // #33 (QUAKE)
3165 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
3166 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
3167 VM_rint, // #36 float(float v) rint (QUAKE)
3168 VM_floor, // #37 float(float v) floor (QUAKE)
3169 VM_ceil, // #38 float(float v) ceil (QUAKE)
3170 NULL, // #39 (QUAKE)
3171 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
3172 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
3173 NULL, // #42 (QUAKE)
3174 VM_fabs, // #43 float(float f) fabs (QUAKE)
3175 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
3176 VM_cvar, // #45 float(string s) cvar (QUAKE)
3177 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
3178 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
3179 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
3180 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
3181 NULL, // #50 (QUAKE)
3182 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
3183 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
3184 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
3185 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
3186 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
3187 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
3188 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
3189 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
3190 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
3191 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
3192 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
3193 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
3194 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
3195 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
3196 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
3197 NULL, // #66 (QUAKE)
3198 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
3199 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
3200 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
3201 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
3202 NULL, // #71 (QUAKE)
3203 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
3204 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
3205 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
3206 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
3207 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
3208 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
3209 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
3210 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
3211 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
3212 VM_stof, // #81 float(string s) stof (FRIK_FILE)
3213 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
3214 NULL, // #83 (QUAKE)
3215 NULL, // #84 (QUAKE)
3216 NULL, // #85 (QUAKE)
3217 NULL, // #86 (QUAKE)
3218 NULL, // #87 (QUAKE)
3219 NULL, // #88 (QUAKE)
3220 NULL, // #89 (QUAKE)
3221 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
3222 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
3223 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
3224 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
3225 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
3226 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3227 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3228 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3229 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3230 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3231 // FrikaC and Telejano range #100-#199
3242 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3243 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3244 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3245 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3246 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3247 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3248 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3249 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3250 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3251 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3332 // FTEQW range #200-#299
3351 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3354 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3355 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3356 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3357 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3358 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3359 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3360 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3361 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3362 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3363 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3365 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3373 VM_SV_checkpvs, // #240 float(vector viewpos, entity viewee) checkpvs;
3396 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.
3397 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
3398 VM_SV_skel_get_numbones, // #265 float(float skel) skel_get_numbones = #265; // (DP_SKELETONOBJECTS) returns how many bones exist in the created skeleton
3399 VM_SV_skel_get_bonename, // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (DP_SKELETONOBJECTS) returns name of bone (as a tempstring)
3400 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)
3401 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
3402 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)
3403 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)
3404 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)
3405 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)
3406 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)
3407 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
3408 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)
3409 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
3410 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.
3433 // CSQC range #300-#399
3434 NULL, // #300 void() clearscene (EXT_CSQC)
3435 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3436 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3437 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3438 NULL, // #304 void() renderscene (EXT_CSQC)
3439 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3440 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3441 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3442 NULL, // #308 void() R_EndPolygon
3444 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3445 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3449 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3450 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3451 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3452 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3453 NULL, // #319 void(string name) freepic (EXT_CSQC)
3454 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3455 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3456 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3457 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3458 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3459 NULL, // #325 void(void) drawresetcliparea
3464 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3465 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3466 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3467 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3468 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3469 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3470 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3471 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3472 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3473 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3474 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3475 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3476 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3477 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3478 NULL, // #344 vector() getmousepos (EXT_CSQC)
3479 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3480 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3481 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3482 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3483 NULL, // #349 float() isdemo (EXT_CSQC)
3484 VM_isserver, // #350 float() isserver (EXT_CSQC)
3485 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3486 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3487 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3488 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3494 NULL, // #360 float() readbyte (EXT_CSQC)
3495 NULL, // #361 float() readchar (EXT_CSQC)
3496 NULL, // #362 float() readshort (EXT_CSQC)
3497 NULL, // #363 float() readlong (EXT_CSQC)
3498 NULL, // #364 float() readcoord (EXT_CSQC)
3499 NULL, // #365 float() readangle (EXT_CSQC)
3500 NULL, // #366 string() readstring (EXT_CSQC)
3501 NULL, // #367 float() readfloat (EXT_CSQC)
3534 // LordHavoc's range #400-#499
3535 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3536 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3537 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3538 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3539 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3540 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3541 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3542 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3543 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)
3544 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3545 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3546 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3547 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3548 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3549 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3550 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3551 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3552 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3553 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3554 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3555 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3556 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3557 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3558 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3559 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3560 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3561 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3562 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3563 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3564 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3565 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3566 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3567 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3568 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3569 VM_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3570 VM_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3571 VM_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3572 VM_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3573 VM_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3574 VM_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3575 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3576 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3577 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3578 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3579 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3580 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3581 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3582 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3583 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3584 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3585 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3586 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3587 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3588 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3589 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3590 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3591 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3592 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3594 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3595 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3596 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3597 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3598 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3599 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3600 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3601 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3602 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3603 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3604 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3606 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3607 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3608 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3609 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3610 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3611 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3612 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3613 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3614 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3615 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3616 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3617 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3618 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3619 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3620 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3621 VM_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3629 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3630 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3631 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3632 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3633 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3634 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3635 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3636 VM_SV_WritePicture, // #501
3638 VM_whichpack, // #503 string(string) whichpack = #503;
3645 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3646 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3647 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3648 VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3649 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3650 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3651 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3652 VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
3653 VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
3654 VM_gettime, // #519 float(float timer) gettime = #519; (DP_QC_GETTIME)
3664 VM_loadfromdata, // #529
3665 VM_loadfromfile, // #530
3666 VM_SV_setpause, // #531 void(float pause) setpause = #531;
3668 VM_getsoundtime, // #533 float(entity e, float channel) getsoundtime = #533; (DP_SND_GETSOUNDTIME)
3669 VM_soundlength, // #534 float(string sample) soundlength = #534; (DP_SND_GETSOUNDTIME)
3740 VM_callfunction, // #605
3741 VM_writetofile, // #606
3742 VM_isfunction, // #607
3748 VM_parseentitydata, // #613
3759 VM_SV_getextresponse, // #624 string getextresponse(void)
3762 VM_sprintf, // #627 string sprintf(string format, ...)
3763 VM_getsurfacenumtriangles, // #628 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACETRIANGLE)
3764 VM_getsurfacetriangle, // #629 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACETRIANGLE)
3768 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3770 void VM_SV_Cmd_Init(void)
3775 void VM_SV_Cmd_Reset(void)
3777 World_End(&sv.world);
3778 if(prog->funcoffsets.SV_Shutdown)
3780 func_t s = prog->funcoffsets.SV_Shutdown;
3781 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3782 PRVM_ExecuteProgram(s,"SV_Shutdown() required");