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_SPAWNPARTICLE "
26 "DP_CSQC_QUERYRENDERENTITY "
39 "DP_EF_RESTARTANIM_BIT "
44 "DP_ENT_CUSTOMCOLORMAP "
45 "DP_ENT_EXTERIORMODELTOCLIENT "
48 "DP_ENT_LOWPRECISION "
52 "DP_GFX_EXTERNALTEXTURES "
53 "DP_GFX_EXTERNALTEXTURES_PERMAP "
55 "DP_GFX_MODEL_INTERPOLATION "
56 "DP_GFX_QUAKE3MODELTAGS "
60 "DP_HALFLIFE_MAP_CVAR "
63 "DP_LIGHTSTYLE_STATICVALUE "
67 "DP_MOVETYPEBOUNCEMISSILE "
70 "DP_QC_ASINACOSATANATAN2TAN "
76 "DP_QC_CVAR_DEFSTRING "
77 "DP_QC_CVAR_DESCRIPTION "
84 "DP_QC_EXTRESPONSEPACKET "
86 "DP_QC_FINDCHAINFLAGS "
87 "DP_QC_FINDCHAINFLOAT "
88 "DP_QC_FINDCHAIN_TOFIELD "
94 "DP_QC_GETSURFACETRIANGLE "
95 "DP_QC_GETSURFACEPOINTATTRIBUTE "
97 "DP_QC_GETTAGINFO_BONEPROPERTIES "
99 "DP_QC_GETTIME_CDTRACK "
102 "DP_QC_MULTIPLETEMPSTRINGS "
103 "DP_QC_NUM_FOR_EDICT "
105 "DP_QC_SINCOSSQRTPOW "
108 "DP_QC_STRINGBUFFERS "
109 "DP_QC_STRINGBUFFERS_CVARLIST "
110 "DP_QC_STRINGCOLORFUNCTIONS "
111 "DP_QC_STRING_CASE_FUNCTIONS "
113 "DP_QC_TOKENIZEBYSEPARATOR "
114 "DP_QC_TOKENIZE_CONSOLE "
117 "DP_QC_TRACE_MOVETYPE_HITMODEL "
118 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
119 "DP_QC_UNLIMITEDTEMPSTRINGS "
122 "DP_QC_VECTOANGLES_WITH_ROLL "
123 "DP_QC_VECTORVECTORS "
130 "DP_SKELETONOBJECTS "
131 "DP_SND_DIRECTIONLESSATTNNONE "
136 "DP_SND_GETSOUNDTIME "
138 "DP_VIDEO_SUBTITLES "
142 "DP_SV_BOUNCEFACTOR "
143 "DP_SV_CLIENTCAMERA "
144 "DP_SV_CLIENTCOLORS "
147 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
148 "DP_SV_DISCARDABLEDEMO "
149 "DP_SV_DRAWONLYTOCLIENT "
152 "DP_SV_ENTITYCONTENTSTRANSITION "
153 "DP_SV_MODELFLAGS_AS_EFFECTS "
154 "DP_SV_MOVETYPESTEP_LANDEVENT "
156 "DP_SV_NODRAWTOCLIENT "
157 "DP_SV_ONENTITYNOSPAWNFUNCTION "
158 "DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
160 "DP_SV_PING_PACKETLOSS "
161 "DP_SV_PLAYERPHYSICS "
162 "DP_SV_POINTPARTICLES "
164 "DP_SV_PRECACHEANYTIME "
168 "DP_SV_ROTATINGBMODEL "
172 "DP_SV_SPAWNFUNC_PREFIX "
173 "DP_SV_WRITEPICTURE "
174 "DP_SV_WRITEUNTERMINATEDSTRING "
178 "DP_TE_EXPLOSIONRGB "
180 "DP_TE_PARTICLECUBE "
181 "DP_TE_PARTICLERAIN "
182 "DP_TE_PARTICLESNOW "
184 "DP_TE_QUADEFFECTS1 "
187 "DP_TE_STANDARDEFFECTBUILTINS "
188 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
192 "FTE_CSQC_SKELETONOBJECTS "
195 "KRIMZON_SV_PARSECLIENTCOMMAND "
198 "NEXUIZ_PLAYERMODEL "
200 "PRYDON_CLIENTCURSOR "
201 "TENEBRAE_GFX_DLIGHTS "
204 //"EXT_CSQC " // not ready yet
211 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.
213 setorigin (entity, origin)
216 static void VM_SV_setorigin (void)
221 VM_SAFEPARMCOUNT(2, VM_setorigin);
223 e = PRVM_G_EDICT(OFS_PARM0);
224 if (e == prog->edicts)
226 VM_Warning("setorigin: can not modify world entity\n");
229 if (e->priv.server->free)
231 VM_Warning("setorigin: can not modify free entity\n");
234 org = PRVM_G_VECTOR(OFS_PARM1);
235 VectorCopy (org, e->fields.server->origin);
239 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
240 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
244 for (i=0 ; i<3 ; i++)
246 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
248 // set derived values
249 VectorCopy (min, e->fields.server->mins);
250 VectorCopy (max, e->fields.server->maxs);
251 VectorSubtract (max, min, e->fields.server->size);
260 the size box is rotated by the current angle
261 LordHavoc: no it isn't...
263 setsize (entity, minvector, maxvector)
266 static void VM_SV_setsize (void)
271 VM_SAFEPARMCOUNT(3, VM_setsize);
273 e = PRVM_G_EDICT(OFS_PARM0);
274 if (e == prog->edicts)
276 VM_Warning("setsize: can not modify world entity\n");
279 if (e->priv.server->free)
281 VM_Warning("setsize: can not modify free entity\n");
284 min = PRVM_G_VECTOR(OFS_PARM1);
285 max = PRVM_G_VECTOR(OFS_PARM2);
286 SetMinMaxSize (e, min, max, false);
294 setmodel(entity, model)
297 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
298 static void VM_SV_setmodel (void)
304 VM_SAFEPARMCOUNT(2, VM_setmodel);
306 e = PRVM_G_EDICT(OFS_PARM0);
307 if (e == prog->edicts)
309 VM_Warning("setmodel: can not modify world entity\n");
312 if (e->priv.server->free)
314 VM_Warning("setmodel: can not modify free entity\n");
317 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
318 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
319 e->fields.server->modelindex = i;
321 mod = SV_GetModelByIndex(i);
325 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
326 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
328 SetMinMaxSize (e, quakemins, quakemaxs, true);
331 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
338 single print to a specific client
340 sprint(clientent, value)
343 static void VM_SV_sprint (void)
347 char string[VM_STRINGTEMP_LENGTH];
349 VM_VarString(1, string, sizeof(string));
351 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
353 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
354 // LordHavoc: div0 requested that sprintto world operate like print
361 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
363 VM_Warning("tried to centerprint to a non-client\n");
367 client = svs.clients + entnum-1;
368 if (!client->netconnection)
371 MSG_WriteChar(&client->netconnection->message,svc_print);
372 MSG_WriteString(&client->netconnection->message, string);
380 single print to a specific client
382 centerprint(clientent, value)
385 static void VM_SV_centerprint (void)
389 char string[VM_STRINGTEMP_LENGTH];
391 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
393 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
395 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
397 VM_Warning("tried to centerprint to a non-client\n");
401 client = svs.clients + entnum-1;
402 if (!client->netconnection)
405 VM_VarString(1, string, sizeof(string));
406 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
407 MSG_WriteString(&client->netconnection->message, string);
414 particle(origin, color, count)
417 static void VM_SV_particle (void)
423 VM_SAFEPARMCOUNT(4, VM_SV_particle);
425 org = PRVM_G_VECTOR(OFS_PARM0);
426 dir = PRVM_G_VECTOR(OFS_PARM1);
427 color = PRVM_G_FLOAT(OFS_PARM2);
428 count = PRVM_G_FLOAT(OFS_PARM3);
429 SV_StartParticle (org, dir, (int)color, (int)count);
439 static void VM_SV_ambientsound (void)
443 float vol, attenuation;
446 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
448 pos = PRVM_G_VECTOR (OFS_PARM0);
449 samp = PRVM_G_STRING(OFS_PARM1);
450 vol = PRVM_G_FLOAT(OFS_PARM2);
451 attenuation = PRVM_G_FLOAT(OFS_PARM3);
453 // check to see if samp was properly precached
454 soundnum = SV_SoundIndex(samp, 1);
462 // add an svc_spawnambient command to the level signon packet
465 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
467 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
469 MSG_WriteVector(&sv.signon, pos, sv.protocol);
471 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
472 MSG_WriteShort (&sv.signon, soundnum);
474 MSG_WriteByte (&sv.signon, soundnum);
476 MSG_WriteByte (&sv.signon, (int)(vol*255));
477 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
485 Each entity can have eight independant sound sources, like voice,
488 Channel 0 is an auto-allocate channel, the others override anything
489 already running on that entity/channel pair.
491 An attenuation of 0 will play full volume everywhere in the level.
492 Larger attenuations will drop off.
496 static void VM_SV_sound (void)
500 prvm_edict_t *entity;
504 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
506 entity = PRVM_G_EDICT(OFS_PARM0);
507 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
508 sample = PRVM_G_STRING(OFS_PARM2);
509 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
510 attenuation = PRVM_G_FLOAT(OFS_PARM4);
513 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
517 if (volume < 0 || volume > 255)
519 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
523 if (attenuation < 0 || attenuation > 4)
525 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
529 if (channel < 0 || channel > 7)
531 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
535 SV_StartSound (entity, channel, sample, volume, attenuation);
542 Follows the same logic as VM_SV_sound, except instead of
543 an entity, an origin for the sound is provided, and channel
544 is omitted (since no entity is being tracked).
548 static void VM_SV_pointsound(void)
555 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
557 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
558 sample = PRVM_G_STRING(OFS_PARM1);
559 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
560 attenuation = PRVM_G_FLOAT(OFS_PARM3);
562 if (volume < 0 || volume > 255)
564 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
568 if (attenuation < 0 || attenuation > 4)
570 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
574 SV_StartPointSound (org, sample, volume, attenuation);
581 Used for use tracing and shot targeting
582 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
583 if the tryents flag is set.
585 traceline (vector1, vector2, movetype, ignore)
588 static void VM_SV_traceline (void)
595 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
597 prog->xfunction->builtinsprofile += 30;
599 v1 = PRVM_G_VECTOR(OFS_PARM0);
600 v2 = PRVM_G_VECTOR(OFS_PARM1);
601 move = (int)PRVM_G_FLOAT(OFS_PARM2);
602 ent = PRVM_G_EDICT(OFS_PARM3);
604 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]))
605 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));
607 trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
609 VM_SetTraceGlobals(&trace);
617 Used for use tracing and shot targeting
618 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
619 if the tryents flag is set.
621 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
624 // LordHavoc: added this for my own use, VERY useful, similar to traceline
625 static void VM_SV_tracebox (void)
627 float *v1, *v2, *m1, *m2;
632 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
634 prog->xfunction->builtinsprofile += 30;
636 v1 = PRVM_G_VECTOR(OFS_PARM0);
637 m1 = PRVM_G_VECTOR(OFS_PARM1);
638 m2 = PRVM_G_VECTOR(OFS_PARM2);
639 v2 = PRVM_G_VECTOR(OFS_PARM3);
640 move = (int)PRVM_G_FLOAT(OFS_PARM4);
641 ent = PRVM_G_EDICT(OFS_PARM5);
643 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]))
644 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));
646 trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
648 VM_SetTraceGlobals(&trace);
651 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
656 vec3_t original_origin;
657 vec3_t original_velocity;
658 vec3_t original_angles;
659 vec3_t original_avelocity;
663 VectorCopy(tossent->fields.server->origin , original_origin );
664 VectorCopy(tossent->fields.server->velocity , original_velocity );
665 VectorCopy(tossent->fields.server->angles , original_angles );
666 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
668 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
669 if (val != NULL && val->_float != 0)
670 gravity = val->_float;
673 gravity *= sv_gravity.value * 0.025;
675 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
677 SV_CheckVelocity (tossent);
678 tossent->fields.server->velocity[2] -= gravity;
679 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
680 VectorScale (tossent->fields.server->velocity, 0.05, move);
681 VectorAdd (tossent->fields.server->origin, move, end);
682 trace = SV_TraceBox(tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
683 VectorCopy (trace.endpos, tossent->fields.server->origin);
684 tossent->fields.server->velocity[2] -= gravity;
686 if (trace.fraction < 1)
690 VectorCopy(original_origin , tossent->fields.server->origin );
691 VectorCopy(original_velocity , tossent->fields.server->velocity );
692 VectorCopy(original_angles , tossent->fields.server->angles );
693 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
698 static void VM_SV_tracetoss (void)
702 prvm_edict_t *ignore;
704 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
706 prog->xfunction->builtinsprofile += 600;
708 ent = PRVM_G_EDICT(OFS_PARM0);
709 if (ent == prog->edicts)
711 VM_Warning("tracetoss: can not use world entity\n");
714 ignore = PRVM_G_EDICT(OFS_PARM1);
716 trace = SV_Trace_Toss (ent, ignore);
718 VM_SetTraceGlobals(&trace);
721 //============================================================================
723 static int checkpvsbytes;
724 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
726 static int VM_SV_newcheckclient (int check)
732 // cycle to the next one
734 check = bound(1, check, svs.maxclients);
735 if (check == svs.maxclients)
743 prog->xfunction->builtinsprofile++;
745 if (i == svs.maxclients+1)
747 // look up the client's edict
748 ent = PRVM_EDICT_NUM(i);
749 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
750 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
752 // found a valid client (possibly the same one again)
756 // get the PVS for the entity
757 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
759 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
760 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
769 Returns a client (or object that has a client enemy) that would be a
772 If there is more than one valid option, they are cycled each frame
774 If (self.origin + self.viewofs) is not in the PVS of the current target,
775 it is not returned at all.
780 int c_invis, c_notvis;
781 static void VM_SV_checkclient (void)
783 prvm_edict_t *ent, *self;
786 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
788 // find a new check if on a new frame
789 if (sv.time - sv.lastchecktime >= 0.1)
791 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
792 sv.lastchecktime = sv.time;
795 // return check if it might be visible
796 ent = PRVM_EDICT_NUM(sv.lastcheck);
797 if (ent->priv.server->free || ent->fields.server->health <= 0)
799 VM_RETURN_EDICT(prog->edicts);
803 // if current entity can't possibly see the check entity, return 0
804 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
805 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
806 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
809 VM_RETURN_EDICT(prog->edicts);
813 // might be able to see it
815 VM_RETURN_EDICT(ent);
818 //============================================================================
824 Checks if an entity is in a point's PVS.
825 Should be fast but can be inexact.
827 float checkpvs(vector viewpos, entity viewee) = #240;
830 static void VM_SV_checkpvs (void)
833 prvm_edict_t *viewee;
838 unsigned char fatpvs[MAX_MAP_LEAFS/8];
841 VM_SAFEPARMCOUNT(2, VM_SV_checkpvs);
842 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos);
843 viewee = PRVM_G_EDICT(OFS_PARM1);
845 if(viewee->priv.server->free)
847 VM_Warning("checkpvs: can not check free entity\n");
848 PRVM_G_FLOAT(OFS_RETURN) = 4;
853 if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
855 // no PVS support on this worldmodel... darn
856 PRVM_G_FLOAT(OFS_RETURN) = 3;
859 pvs = sv.worldmodel->brush.GetPVS(sv.worldmodel, viewpos);
862 // viewpos isn't in any PVS... darn
863 PRVM_G_FLOAT(OFS_RETURN) = 2;
866 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
868 // using fat PVS like FTEQW does (slow)
869 if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
871 // no PVS support on this worldmodel... darn
872 PRVM_G_FLOAT(OFS_RETURN) = 3;
875 fatpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
878 // viewpos isn't in any PVS... darn
879 PRVM_G_FLOAT(OFS_RETURN) = 2;
882 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
891 Sends text over to the client's execution buffer
893 stuffcmd (clientent, value, ...)
896 static void VM_SV_stuffcmd (void)
900 char string[VM_STRINGTEMP_LENGTH];
902 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
904 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
905 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
907 VM_Warning("Can't stuffcmd to a non-client\n");
911 VM_VarString(1, string, sizeof(string));
914 host_client = svs.clients + entnum-1;
915 Host_ClientCommands ("%s", string);
923 Returns a chain of entities that have origins within a spherical area
925 findradius (origin, radius)
928 static void VM_SV_findradius (void)
930 prvm_edict_t *ent, *chain;
931 vec_t radius, radius2;
932 vec3_t org, eorg, mins, maxs;
935 static prvm_edict_t *touchedicts[MAX_EDICTS];
938 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findradius);
941 chainfield = PRVM_G_INT(OFS_PARM2);
943 chainfield = prog->fieldoffsets.chain;
945 PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
947 chain = (prvm_edict_t *)prog->edicts;
949 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
950 radius = PRVM_G_FLOAT(OFS_PARM1);
951 radius2 = radius * radius;
953 mins[0] = org[0] - (radius + 1);
954 mins[1] = org[1] - (radius + 1);
955 mins[2] = org[2] - (radius + 1);
956 maxs[0] = org[0] + (radius + 1);
957 maxs[1] = org[1] + (radius + 1);
958 maxs[2] = org[2] + (radius + 1);
959 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
960 if (numtouchedicts > MAX_EDICTS)
962 // this never happens
963 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
964 numtouchedicts = MAX_EDICTS;
966 for (i = 0;i < numtouchedicts;i++)
968 ent = touchedicts[i];
969 prog->xfunction->builtinsprofile++;
970 // Quake did not return non-solid entities but darkplaces does
971 // (note: this is the reason you can't blow up fallen zombies)
972 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
974 // LordHavoc: compare against bounding box rather than center so it
975 // doesn't miss large objects, and use DotProduct instead of Length
976 // for a major speedup
977 VectorSubtract(org, ent->fields.server->origin, eorg);
978 if (sv_gameplayfix_findradiusdistancetobox.integer)
980 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
981 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
982 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
985 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
986 if (DotProduct(eorg, eorg) < radius2)
988 PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
993 VM_RETURN_EDICT(chain);
996 static void VM_SV_precache_sound (void)
998 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
999 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
1002 static void VM_SV_precache_model (void)
1004 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
1005 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
1006 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
1013 float(float yaw, float dist[, settrace]) walkmove
1016 static void VM_SV_walkmove (void)
1025 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
1027 // assume failure if it returns early
1028 PRVM_G_FLOAT(OFS_RETURN) = 0;
1030 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1031 if (ent == prog->edicts)
1033 VM_Warning("walkmove: can not modify world entity\n");
1036 if (ent->priv.server->free)
1038 VM_Warning("walkmove: can not modify free entity\n");
1041 yaw = PRVM_G_FLOAT(OFS_PARM0);
1042 dist = PRVM_G_FLOAT(OFS_PARM1);
1043 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
1045 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1048 yaw = yaw*M_PI*2 / 360;
1050 move[0] = cos(yaw)*dist;
1051 move[1] = sin(yaw)*dist;
1054 // save program state, because SV_movestep may call other progs
1055 oldf = prog->xfunction;
1056 oldself = prog->globals.server->self;
1058 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
1061 // restore program state
1062 prog->xfunction = oldf;
1063 prog->globals.server->self = oldself;
1073 static void VM_SV_droptofloor (void)
1079 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
1081 // assume failure if it returns early
1082 PRVM_G_FLOAT(OFS_RETURN) = 0;
1084 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1085 if (ent == prog->edicts)
1087 VM_Warning("droptofloor: can not modify world entity\n");
1090 if (ent->priv.server->free)
1092 VM_Warning("droptofloor: can not modify free entity\n");
1096 VectorCopy (ent->fields.server->origin, end);
1099 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
1100 SV_UnstickEntity(ent);
1102 trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1103 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
1106 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]);
1107 VectorAdd(ent->fields.server->origin, offset, org);
1108 trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1109 VectorSubtract(trace.endpos, offset, trace.endpos);
1110 if (trace.startsolid)
1112 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]);
1113 SV_UnstickEntity(ent);
1115 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1116 ent->fields.server->groundentity = 0;
1117 PRVM_G_FLOAT(OFS_RETURN) = 1;
1119 else if (trace.fraction < 1)
1121 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]);
1122 VectorCopy (trace.endpos, ent->fields.server->origin);
1123 SV_UnstickEntity(ent);
1125 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1126 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1127 PRVM_G_FLOAT(OFS_RETURN) = 1;
1128 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1129 ent->priv.server->suspendedinairflag = true;
1134 if (trace.fraction != 1)
1136 if (trace.fraction < 1)
1137 VectorCopy (trace.endpos, ent->fields.server->origin);
1139 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1140 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1141 PRVM_G_FLOAT(OFS_RETURN) = 1;
1142 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1143 ent->priv.server->suspendedinairflag = true;
1152 void(float style, string value) lightstyle
1155 static void VM_SV_lightstyle (void)
1162 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1164 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1165 val = PRVM_G_STRING(OFS_PARM1);
1167 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1168 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1171 // change the string in sv
1172 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1174 // send message to all clients on this server
1175 if (sv.state != ss_active)
1178 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1180 if (client->active && client->netconnection)
1182 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1183 MSG_WriteChar (&client->netconnection->message,style);
1184 MSG_WriteString (&client->netconnection->message, val);
1194 static void VM_SV_checkbottom (void)
1196 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1197 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1205 static void VM_SV_pointcontents (void)
1207 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1208 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1215 Pick a vector for the player to shoot along
1216 vector aim(entity, missilespeed)
1219 static void VM_SV_aim (void)
1221 prvm_edict_t *ent, *check, *bestent;
1222 vec3_t start, dir, end, bestdir;
1225 float dist, bestdist;
1228 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1230 // assume failure if it returns early
1231 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1232 // if sv_aim is so high it can't possibly accept anything, skip out early
1233 if (sv_aim.value >= 1)
1236 ent = PRVM_G_EDICT(OFS_PARM0);
1237 if (ent == prog->edicts)
1239 VM_Warning("aim: can not use world entity\n");
1242 if (ent->priv.server->free)
1244 VM_Warning("aim: can not use free entity\n");
1247 //speed = PRVM_G_FLOAT(OFS_PARM1);
1249 VectorCopy (ent->fields.server->origin, start);
1252 // try sending a trace straight
1253 VectorCopy (prog->globals.server->v_forward, dir);
1254 VectorMA (start, 2048, dir, end);
1255 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1256 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1257 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1259 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1264 // try all possible entities
1265 VectorCopy (dir, bestdir);
1266 bestdist = sv_aim.value;
1269 check = PRVM_NEXT_EDICT(prog->edicts);
1270 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1272 prog->xfunction->builtinsprofile++;
1273 if (check->fields.server->takedamage != DAMAGE_AIM)
1277 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1278 continue; // don't aim at teammate
1279 for (j=0 ; j<3 ; j++)
1280 end[j] = check->fields.server->origin[j]
1281 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1282 VectorSubtract (end, start, dir);
1283 VectorNormalize (dir);
1284 dist = DotProduct (dir, prog->globals.server->v_forward);
1285 if (dist < bestdist)
1286 continue; // to far to turn
1287 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1288 if (tr.ent == check)
1289 { // can shoot at this one
1297 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1298 dist = DotProduct (dir, prog->globals.server->v_forward);
1299 VectorScale (prog->globals.server->v_forward, dist, end);
1301 VectorNormalize (end);
1302 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1306 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1311 ===============================================================================
1315 ===============================================================================
1318 #define MSG_BROADCAST 0 // unreliable to all
1319 #define MSG_ONE 1 // reliable to one (msg_entity)
1320 #define MSG_ALL 2 // reliable to all
1321 #define MSG_INIT 3 // write to the init string
1322 #define MSG_ENTITY 5
1324 sizebuf_t *WriteDest (void)
1330 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1334 return &sv.datagram;
1337 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1338 entnum = PRVM_NUM_FOR_EDICT(ent);
1339 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1341 VM_Warning ("WriteDest: tried to write to non-client\n");
1342 return &sv.reliable_datagram;
1345 return &svs.clients[entnum-1].netconnection->message;
1348 VM_Warning ("WriteDest: bad destination\n");
1350 return &sv.reliable_datagram;
1356 return sv.writeentitiestoclient_msg;
1362 static void VM_SV_WriteByte (void)
1364 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1365 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1368 static void VM_SV_WriteChar (void)
1370 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1371 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1374 static void VM_SV_WriteShort (void)
1376 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1377 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1380 static void VM_SV_WriteLong (void)
1382 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1383 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1386 static void VM_SV_WriteAngle (void)
1388 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1389 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1392 static void VM_SV_WriteCoord (void)
1394 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1395 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1398 static void VM_SV_WriteString (void)
1400 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1401 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1404 static void VM_SV_WriteUnterminatedString (void)
1406 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1407 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1411 static void VM_SV_WriteEntity (void)
1413 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1414 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1417 // writes a picture as at most size bytes of data
1419 // IMGNAME \0 SIZE(short) IMGDATA
1420 // if failed to read/compress:
1422 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1423 static void VM_SV_WritePicture (void)
1425 const char *imgname;
1429 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1431 imgname = PRVM_G_STRING(OFS_PARM1);
1432 size = (int) PRVM_G_FLOAT(OFS_PARM2);
1436 MSG_WriteString(WriteDest(), imgname);
1437 if(Image_Compress(imgname, size, &buf, &size))
1440 MSG_WriteShort(WriteDest(), size);
1441 SZ_Write(WriteDest(), (unsigned char *) buf, size);
1446 MSG_WriteShort(WriteDest(), 0);
1450 //////////////////////////////////////////////////////////
1452 static void VM_SV_makestatic (void)
1457 // allow 0 parameters due to an id1 qc bug in which this function is used
1458 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1459 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1461 if (prog->argc >= 1)
1462 ent = PRVM_G_EDICT(OFS_PARM0);
1464 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1465 if (ent == prog->edicts)
1467 VM_Warning("makestatic: can not modify world entity\n");
1470 if (ent->priv.server->free)
1472 VM_Warning("makestatic: can not modify free entity\n");
1477 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1482 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1483 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1484 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1486 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1488 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1489 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1490 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1494 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1495 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1496 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1499 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1500 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1501 for (i=0 ; i<3 ; i++)
1503 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1504 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1507 // throw the entity away now
1511 //=============================================================================
1518 static void VM_SV_setspawnparms (void)
1524 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1526 ent = PRVM_G_EDICT(OFS_PARM0);
1527 i = PRVM_NUM_FOR_EDICT(ent);
1528 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1530 Con_Print("tried to setspawnparms on a non-client\n");
1534 // copy spawn parms out of the client_t
1535 client = svs.clients + i-1;
1536 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1537 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1544 Returns a color vector indicating the lighting at the requested point.
1546 (Internal Operation note: actually measures the light beneath the point, just like
1547 the model lighting on the client)
1552 static void VM_SV_getlight (void)
1554 vec3_t ambientcolor, diffusecolor, diffusenormal;
1556 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1557 p = PRVM_G_VECTOR(OFS_PARM0);
1558 VectorClear(ambientcolor);
1559 VectorClear(diffusecolor);
1560 VectorClear(diffusenormal);
1561 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1562 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1563 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1568 unsigned char type; // 1/2/8 or other value if isn't used
1572 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1573 static int vm_customstats_last;
1575 void VM_CustomStats_Clear (void)
1579 Z_Free(vm_customstats);
1580 vm_customstats = NULL;
1581 vm_customstats_last = -1;
1585 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1593 for(i=0; i<vm_customstats_last+1 ;i++)
1595 if(!vm_customstats[i].type)
1597 switch(vm_customstats[i].type)
1599 //string as 16 bytes
1602 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1603 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1604 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1605 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1606 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1608 //float field sent as-is
1610 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1612 //integer value of float field
1614 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1622 // void(float index, float type, .void field) SV_AddStat = #232;
1623 // Set up an auto-sent player stat.
1624 // Client's get thier own fields sent to them. Index may not be less than 32.
1625 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1626 // 1: string (4 stats carrying a total of 16 charactures)
1627 // 2: float (one stat, float converted to an integer for transportation)
1628 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1629 static void VM_SV_AddStat (void)
1634 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1638 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1641 VM_Warning("PF_SV_AddStat: not enough memory\n");
1645 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1646 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1647 off = PRVM_G_INT (OFS_PARM2);
1652 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1655 if(i >= (MAX_CL_STATS-32))
1657 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1660 if(i > (MAX_CL_STATS-32-4) && type == 1)
1662 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1665 vm_customstats[i].type = type;
1666 vm_customstats[i].fieldoffset = off;
1667 if(vm_customstats_last < i)
1668 vm_customstats_last = i;
1675 copies data from one entity to another
1677 copyentity(src, dst)
1680 static void VM_SV_copyentity (void)
1682 prvm_edict_t *in, *out;
1683 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1684 in = PRVM_G_EDICT(OFS_PARM0);
1685 if (in == prog->edicts)
1687 VM_Warning("copyentity: can not read world entity\n");
1690 if (in->priv.server->free)
1692 VM_Warning("copyentity: can not read free entity\n");
1695 out = PRVM_G_EDICT(OFS_PARM1);
1696 if (out == prog->edicts)
1698 VM_Warning("copyentity: can not modify world entity\n");
1701 if (out->priv.server->free)
1703 VM_Warning("copyentity: can not modify free entity\n");
1706 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1715 sets the color of a client and broadcasts the update to all connected clients
1717 setcolor(clientent, value)
1720 static void VM_SV_setcolor (void)
1726 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1727 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1728 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1730 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1732 Con_Print("tried to setcolor a non-client\n");
1736 client = svs.clients + entnum-1;
1739 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1741 client->edict->fields.server->team = (i & 15) + 1;
1744 if (client->old_colors != client->colors)
1746 client->old_colors = client->colors;
1747 // send notification to all clients
1748 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1749 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1750 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1758 effect(origin, modelname, startframe, framecount, framerate)
1761 static void VM_SV_effect (void)
1765 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1766 s = PRVM_G_STRING(OFS_PARM1);
1769 VM_Warning("effect: no model specified\n");
1773 i = SV_ModelIndex(s, 1);
1776 VM_Warning("effect: model not precached\n");
1780 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1782 VM_Warning("effect: framecount < 1\n");
1786 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1788 VM_Warning("effect: framerate < 1\n");
1792 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));
1795 static void VM_SV_te_blood (void)
1797 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1798 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1800 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1801 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1803 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1804 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1805 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1807 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1808 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1809 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1811 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1812 SV_FlushBroadcastMessages();
1815 static void VM_SV_te_bloodshower (void)
1817 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1818 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1820 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1821 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1823 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1824 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1825 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1827 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1828 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1829 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1831 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1833 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1834 SV_FlushBroadcastMessages();
1837 static void VM_SV_te_explosionrgb (void)
1839 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1840 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1841 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1843 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1844 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1845 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1847 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1848 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1849 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1850 SV_FlushBroadcastMessages();
1853 static void VM_SV_te_particlecube (void)
1855 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1856 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1858 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1859 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1861 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1862 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1863 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1865 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1866 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1867 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1871 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1873 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1875 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1876 // gravity true/false
1877 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1879 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1880 SV_FlushBroadcastMessages();
1883 static void VM_SV_te_particlerain (void)
1885 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1886 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1888 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1889 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1891 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1892 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1893 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1895 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1896 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1897 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1899 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1903 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1905 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1906 SV_FlushBroadcastMessages();
1909 static void VM_SV_te_particlesnow (void)
1911 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1912 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1914 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1915 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1917 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1918 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1919 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1921 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1922 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1923 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1925 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1926 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1927 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1929 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1931 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1932 SV_FlushBroadcastMessages();
1935 static void VM_SV_te_spark (void)
1937 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1938 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1940 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1941 MSG_WriteByte(&sv.datagram, TE_SPARK);
1943 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1944 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1945 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1947 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1948 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1949 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1951 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1952 SV_FlushBroadcastMessages();
1955 static void VM_SV_te_gunshotquad (void)
1957 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1958 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1959 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1961 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1962 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1963 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1964 SV_FlushBroadcastMessages();
1967 static void VM_SV_te_spikequad (void)
1969 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1970 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1971 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1974 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1976 SV_FlushBroadcastMessages();
1979 static void VM_SV_te_superspikequad (void)
1981 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1982 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1983 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1985 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1986 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1987 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1988 SV_FlushBroadcastMessages();
1991 static void VM_SV_te_explosionquad (void)
1993 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1994 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1995 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1997 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1998 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1999 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2000 SV_FlushBroadcastMessages();
2003 static void VM_SV_te_smallflash (void)
2005 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
2006 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2007 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2009 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2010 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2011 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2012 SV_FlushBroadcastMessages();
2015 static void VM_SV_te_customflash (void)
2017 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
2018 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2020 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2021 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2023 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2024 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2025 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2027 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2029 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
2031 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
2032 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
2033 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
2034 SV_FlushBroadcastMessages();
2037 static void VM_SV_te_gunshot (void)
2039 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
2040 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2041 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2043 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2044 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2045 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2046 SV_FlushBroadcastMessages();
2049 static void VM_SV_te_spike (void)
2051 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
2052 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2053 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2055 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2056 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2057 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2058 SV_FlushBroadcastMessages();
2061 static void VM_SV_te_superspike (void)
2063 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
2064 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2065 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2067 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2068 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2069 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2070 SV_FlushBroadcastMessages();
2073 static void VM_SV_te_explosion (void)
2075 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
2076 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2077 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2079 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2080 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2081 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2082 SV_FlushBroadcastMessages();
2085 static void VM_SV_te_tarexplosion (void)
2087 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
2088 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2089 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2091 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2092 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2093 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2094 SV_FlushBroadcastMessages();
2097 static void VM_SV_te_wizspike (void)
2099 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
2100 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2101 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2103 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2104 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2105 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2106 SV_FlushBroadcastMessages();
2109 static void VM_SV_te_knightspike (void)
2111 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2112 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2113 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2115 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2116 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2117 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2118 SV_FlushBroadcastMessages();
2121 static void VM_SV_te_lavasplash (void)
2123 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2124 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2125 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2127 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2128 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2129 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2130 SV_FlushBroadcastMessages();
2133 static void VM_SV_te_teleport (void)
2135 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2136 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2137 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2139 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2140 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2141 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2142 SV_FlushBroadcastMessages();
2145 static void VM_SV_te_explosion2 (void)
2147 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2148 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2149 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2151 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2152 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2153 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2155 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2156 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2157 SV_FlushBroadcastMessages();
2160 static void VM_SV_te_lightning1 (void)
2162 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2163 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2164 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2166 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2168 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2169 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2170 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2172 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2173 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2174 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2175 SV_FlushBroadcastMessages();
2178 static void VM_SV_te_lightning2 (void)
2180 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2181 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2182 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2184 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2186 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2187 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2188 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2190 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2191 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2192 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2193 SV_FlushBroadcastMessages();
2196 static void VM_SV_te_lightning3 (void)
2198 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2199 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2200 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2202 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2204 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2205 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2206 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2208 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2209 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2210 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2211 SV_FlushBroadcastMessages();
2214 static void VM_SV_te_beam (void)
2216 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2217 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2218 MSG_WriteByte(&sv.datagram, TE_BEAM);
2220 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2222 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2223 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2224 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2226 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2227 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2228 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2229 SV_FlushBroadcastMessages();
2232 static void VM_SV_te_plasmaburn (void)
2234 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2235 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2236 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2237 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2238 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2239 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2240 SV_FlushBroadcastMessages();
2243 static void VM_SV_te_flamejet (void)
2245 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2246 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2247 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2249 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2250 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2251 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2253 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2254 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2255 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2257 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2258 SV_FlushBroadcastMessages();
2261 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2262 //this function originally written by KrimZon, made shorter by LordHavoc
2263 static void VM_SV_clientcommand (void)
2265 client_t *temp_client;
2267 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2269 //find client for this entity
2270 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2271 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2273 Con_Print("PF_clientcommand: entity is not a client\n");
2277 temp_client = host_client;
2278 host_client = svs.clients + i;
2279 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2280 host_client = temp_client;
2283 //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)
2284 static void VM_SV_setattachment (void)
2286 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2287 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2288 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2291 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2293 if (e == prog->edicts)
2295 VM_Warning("setattachment: can not modify world entity\n");
2298 if (e->priv.server->free)
2300 VM_Warning("setattachment: can not modify free entity\n");
2304 if (tagentity == NULL)
2305 tagentity = prog->edicts;
2307 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2309 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2311 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2314 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2316 model = SV_GetModelFromEdict(tagentity);
2319 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2321 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);
2324 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));
2328 /////////////////////////////////////////
2329 // DP_MD3_TAGINFO extension coded by VorteX
2331 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2335 i = (int)e->fields.server->modelindex;
2336 if (i < 1 || i >= MAX_MODELS)
2339 return Mod_Alias_GetTagIndexForName(SV_GetModelByIndex(i), (int)e->fields.server->skin, tagname);
2342 int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
2349 Matrix4x4_CreateIdentity(tag_localmatrix);
2351 if (tagindex >= 0 && (model = SV_GetModelFromEdict(e)) && model->num_bones)
2353 r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, e->priv.server->frameblend, &e->priv.server->skeleton, tagindex - 1, parentindex, tagname, tag_localmatrix);
2364 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2368 float pitchsign = 1;
2371 val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
2372 if (val && val->_float != 0)
2373 scale = val->_float;
2376 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);
2379 pitchsign = SV_GetPitchSign(ent);
2380 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);
2384 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2387 if (tagindex >= 0 && (model = SV_GetModelFromEdict(ent)) && model->animscenes)
2389 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2390 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2391 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2392 return Mod_Alias_GetTagMatrix(model, ent->priv.server->frameblend, &ent->priv.server->skeleton, tagindex, out);
2394 *out = identitymatrix;
2398 // Warnings/errors code:
2399 // 0 - normal (everything all-right)
2402 // 3 - null or non-precached model
2403 // 4 - no tags with requested index
2404 // 5 - runaway loop at attachment chain
2405 extern cvar_t cl_bob;
2406 extern cvar_t cl_bobcycle;
2407 extern cvar_t cl_bobup;
2408 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2412 int modelindex, attachloop;
2413 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2416 *out = identitymatrix; // warnings and errors return identical matrix
2418 if (ent == prog->edicts)
2420 if (ent->priv.server->free)
2423 modelindex = (int)ent->fields.server->modelindex;
2424 if (modelindex <= 0 || modelindex >= MAX_MODELS)
2427 model = SV_GetModelByIndex(modelindex);
2429 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2430 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2431 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2433 tagmatrix = identitymatrix;
2434 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2438 if (attachloop >= 256) // prevent runaway looping
2440 // apply transformation by child's tagindex on parent entity and then
2441 // by parent entity itself
2442 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2443 if (ret && attachloop == 0)
2445 SV_GetEntityMatrix(ent, &entitymatrix, false);
2446 Matrix4x4_Concat(&tagmatrix, &attachmatrix, out);
2447 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2448 // next iteration we process the parent entity
2449 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2451 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2452 ent = PRVM_EDICT_NUM(val->edict);
2459 // RENDER_VIEWMODEL magic
2460 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2462 Matrix4x4_Copy(&tagmatrix, out);
2463 ent = PRVM_EDICT_NUM(val->edict);
2465 SV_GetEntityMatrix(ent, &entitymatrix, true);
2466 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2469 // Cl_bob, ported from rendering code
2470 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2473 // LordHavoc: this code is *weird*, but not replacable (I think it
2474 // should be done in QC on the server, but oh well, quake is quake)
2475 // LordHavoc: figured out bobup: the time at which the sin is at 180
2476 // degrees (which allows lengthening or squishing the peak or valley)
2477 cycle = sv.time/cl_bobcycle.value;
2478 cycle -= (int)cycle;
2479 if (cycle < cl_bobup.value)
2480 cycle = sin(M_PI * cycle / cl_bobup.value);
2482 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2483 // bob is proportional to velocity in the xy plane
2484 // (don't count Z, or jumping messes it up)
2485 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;
2486 bob = bob*0.3 + bob*0.7*cycle;
2487 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2494 //float(entity ent, string tagname) gettagindex;
2496 static void VM_SV_gettagindex (void)
2499 const char *tag_name;
2502 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2504 ent = PRVM_G_EDICT(OFS_PARM0);
2505 tag_name = PRVM_G_STRING(OFS_PARM1);
2507 if (ent == prog->edicts)
2509 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
2512 if (ent->priv.server->free)
2514 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
2519 if (!SV_GetModelFromEdict(ent))
2520 Con_DPrintf("VM_SV_gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2523 tag_index = SV_GetTagIndex(ent, tag_name);
2525 if(developer_extra.integer)
2526 Con_DPrintf("VM_SV_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2528 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2531 //vector(entity ent, float tagindex) gettaginfo;
2532 static void VM_SV_gettaginfo (void)
2536 matrix4x4_t tag_matrix;
2537 matrix4x4_t tag_localmatrix;
2539 const char *tagname;
2542 vec3_t fo, le, up, trans;
2543 const dp_model_t *model;
2545 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2547 e = PRVM_G_EDICT(OFS_PARM0);
2548 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2550 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2551 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, le, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2552 VectorScale(le, -1, prog->globals.server->v_right);
2553 model = SV_GetModelFromEdict(e);
2554 VM_GenerateFrameGroupBlend(e->priv.server->framegroupblend, e);
2555 VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model);
2556 VM_UpdateEdictSkeleton(e, model, e->priv.server->frameblend);
2557 SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
2558 Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
2560 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
2561 val->_float = parentindex;
2562 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
2563 val->string = tagname ? PRVM_SetTempString(tagname) : 0;
2564 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
2565 VectorCopy(trans, val->vector);
2566 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
2567 VectorCopy(fo, val->vector);
2568 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
2569 VectorScale(le, -1, val->vector);
2570 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
2571 VectorCopy(up, val->vector);
2576 VM_Warning("gettagindex: can't affect world entity\n");
2579 VM_Warning("gettagindex: can't affect free entity\n");
2582 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2585 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2588 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2593 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2594 static void VM_SV_dropclient (void)
2597 client_t *oldhostclient;
2598 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2599 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2600 if (clientnum < 0 || clientnum >= svs.maxclients)
2602 VM_Warning("dropclient: not a client\n");
2605 if (!svs.clients[clientnum].active)
2607 VM_Warning("dropclient: that client slot is not connected\n");
2610 oldhostclient = host_client;
2611 host_client = svs.clients + clientnum;
2612 SV_DropClient(false);
2613 host_client = oldhostclient;
2616 //entity() spawnclient (DP_SV_BOTCLIENT)
2617 static void VM_SV_spawnclient (void)
2621 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2622 prog->xfunction->builtinsprofile += 2;
2624 for (i = 0;i < svs.maxclients;i++)
2626 if (!svs.clients[i].active)
2628 prog->xfunction->builtinsprofile += 100;
2629 SV_ConnectClient (i, NULL);
2630 // this has to be set or else ClientDisconnect won't be called
2631 // we assume the qc will call ClientConnect...
2632 svs.clients[i].clientconnectcalled = true;
2633 ed = PRVM_EDICT_NUM(i + 1);
2637 VM_RETURN_EDICT(ed);
2640 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2641 static void VM_SV_clienttype (void)
2644 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2645 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2646 if (clientnum < 0 || clientnum >= svs.maxclients)
2647 PRVM_G_FLOAT(OFS_RETURN) = 3;
2648 else if (!svs.clients[clientnum].active)
2649 PRVM_G_FLOAT(OFS_RETURN) = 0;
2650 else if (svs.clients[clientnum].netconnection)
2651 PRVM_G_FLOAT(OFS_RETURN) = 1;
2653 PRVM_G_FLOAT(OFS_RETURN) = 2;
2660 string(string key) serverkey
2663 void VM_SV_serverkey(void)
2665 char string[VM_STRINGTEMP_LENGTH];
2666 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2667 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2668 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2671 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2672 static void VM_SV_setmodelindex (void)
2677 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2679 e = PRVM_G_EDICT(OFS_PARM0);
2680 if (e == prog->edicts)
2682 VM_Warning("setmodelindex: can not modify world entity\n");
2685 if (e->priv.server->free)
2687 VM_Warning("setmodelindex: can not modify free entity\n");
2690 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2691 if (i <= 0 || i >= MAX_MODELS)
2693 VM_Warning("setmodelindex: invalid modelindex\n");
2696 if (!sv.model_precache[i][0])
2698 VM_Warning("setmodelindex: model not precached\n");
2702 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2703 e->fields.server->modelindex = i;
2705 mod = SV_GetModelByIndex(i);
2709 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2710 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2712 SetMinMaxSize (e, quakemins, quakemaxs, true);
2715 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2718 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2719 static void VM_SV_modelnameforindex (void)
2722 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2724 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2726 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2727 if (i <= 0 || i >= MAX_MODELS)
2729 VM_Warning("modelnameforindex: invalid modelindex\n");
2732 if (!sv.model_precache[i][0])
2734 VM_Warning("modelnameforindex: model not precached\n");
2738 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2741 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2742 static void VM_SV_particleeffectnum (void)
2745 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2746 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2749 PRVM_G_FLOAT(OFS_RETURN) = i;
2752 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2753 static void VM_SV_trailparticles (void)
2755 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2757 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2760 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2761 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2762 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2763 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2764 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2765 SV_FlushBroadcastMessages();
2768 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2769 static void VM_SV_pointparticles (void)
2771 int effectnum, count;
2773 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2775 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2778 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2779 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2780 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2781 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2782 if (count == 1 && !VectorLength2(vel))
2785 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2786 MSG_WriteShort(&sv.datagram, effectnum);
2787 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2791 // 1+2+12+12+2=29 bytes
2792 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2793 MSG_WriteShort(&sv.datagram, effectnum);
2794 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2795 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2796 MSG_WriteShort(&sv.datagram, count);
2799 SV_FlushBroadcastMessages();
2802 //PF_setpause, // void(float pause) setpause = #531;
2803 static void VM_SV_setpause(void) {
2805 pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
2806 if (pauseValue != 0) { //pause the game
2808 sv.pausedstart = Sys_DoubleTime();
2809 } else { //disable pause, in case it was enabled
2810 if (sv.paused != 0) {
2815 // send notification to all clients
2816 MSG_WriteByte(&sv.reliable_datagram, svc_setpause);
2817 MSG_WriteByte(&sv.reliable_datagram, sv.paused);
2820 // #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.
2821 static void VM_SV_skel_create(void)
2823 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
2824 dp_model_t *model = SV_GetModelByIndex(modelindex);
2825 skeleton_t *skeleton;
2827 PRVM_G_FLOAT(OFS_RETURN) = 0;
2828 if (!model || !model->num_bones)
2830 for (i = 0;i < MAX_EDICTS;i++)
2831 if (!prog->skeletons[i])
2833 if (i == MAX_EDICTS)
2835 prog->skeletons[i] = skeleton = Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
2836 PRVM_G_FLOAT(OFS_RETURN) = i + 1;
2837 skeleton->model = model;
2838 skeleton->relativetransforms = (matrix4x4_t *)(skeleton+1);
2839 // initialize to identity matrices
2840 for (i = 0;i < skeleton->model->num_bones;i++)
2841 skeleton->relativetransforms[i] = identitymatrix;
2844 // #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
2845 static void VM_SV_skel_build(void)
2847 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2848 skeleton_t *skeleton;
2849 prvm_edict_t *ed = PRVM_G_EDICT(OFS_PARM1);
2850 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM2);
2851 float retainfrac = PRVM_G_FLOAT(OFS_PARM3);
2852 int firstbone = PRVM_G_FLOAT(OFS_PARM4) - 1;
2853 int lastbone = PRVM_G_FLOAT(OFS_PARM5) - 1;
2854 dp_model_t *model = SV_GetModelByIndex(modelindex);
2859 framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS];
2860 frameblend_t frameblend[MAX_FRAMEBLENDS];
2861 matrix4x4_t blendedmatrix;
2863 PRVM_G_FLOAT(OFS_RETURN) = 0;
2864 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2866 firstbone = max(0, firstbone);
2867 lastbone = min(lastbone, model->num_bones - 1);
2868 lastbone = min(lastbone, skeleton->model->num_bones - 1);
2869 VM_GenerateFrameGroupBlend(framegroupblend, ed);
2870 VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model);
2871 blendfrac = 1.0f - retainfrac;
2872 for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
2873 frameblend[numblends].lerp *= blendfrac;
2874 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
2876 memset(&blendedmatrix, 0, sizeof(blendedmatrix));
2877 Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac);
2878 for (blendindex = 0;blendindex < numblends;blendindex++)
2880 Matrix4x4_FromBonePose6s(&matrix, model->num_posescale, model->data_poses6s + 6 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
2881 Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp);
2883 skeleton->relativetransforms[bonenum] = blendedmatrix;
2885 PRVM_G_FLOAT(OFS_RETURN) = skeletonindex + 1;
2888 // #265 float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS) returns how many bones exist in the created skeleton
2889 static void VM_SV_skel_get_numbones(void)
2891 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2892 skeleton_t *skeleton;
2893 PRVM_G_FLOAT(OFS_RETURN) = 0;
2894 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2896 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->num_bones;
2899 // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) returns name of bone (as a tempstring)
2900 static void VM_SV_skel_get_bonename(void)
2902 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2903 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2904 skeleton_t *skeleton;
2905 PRVM_G_INT(OFS_RETURN) = 0;
2906 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2908 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2910 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(skeleton->model->data_bones[bonenum].name);
2913 // #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)
2914 static void VM_SV_skel_get_boneparent(void)
2916 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2917 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2918 skeleton_t *skeleton;
2919 PRVM_G_FLOAT(OFS_RETURN) = 0;
2920 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2922 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2924 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->data_bones[bonenum].parent + 1;
2927 // #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
2928 static void VM_SV_skel_find_bone(void)
2930 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2931 const char *tagname = PRVM_G_STRING(OFS_PARM1);
2932 skeleton_t *skeleton;
2933 PRVM_G_FLOAT(OFS_RETURN) = 0;
2934 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2936 PRVM_G_FLOAT(OFS_RETURN) = Mod_Alias_GetTagIndexForName(skeleton->model, 0, tagname) + 1;
2939 // #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)
2940 static void VM_SV_skel_get_bonerel(void)
2942 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2943 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2944 skeleton_t *skeleton;
2946 vec3_t forward, left, up, origin;
2947 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2948 VectorClear(prog->globals.client->v_forward);
2949 VectorClear(prog->globals.client->v_right);
2950 VectorClear(prog->globals.client->v_up);
2951 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2953 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2955 matrix = skeleton->relativetransforms[bonenum];
2956 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2957 VectorCopy(forward, prog->globals.client->v_forward);
2958 VectorNegate(left, prog->globals.client->v_right);
2959 VectorCopy(up, prog->globals.client->v_up);
2960 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
2963 // #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)
2964 static void VM_SV_skel_get_boneabs(void)
2966 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2967 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2968 skeleton_t *skeleton;
2971 vec3_t forward, left, up, origin;
2972 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2973 VectorClear(prog->globals.client->v_forward);
2974 VectorClear(prog->globals.client->v_right);
2975 VectorClear(prog->globals.client->v_up);
2976 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2978 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2980 matrix = skeleton->relativetransforms[bonenum];
2981 // convert to absolute
2982 while ((bonenum = skeleton->model->data_bones[bonenum].parent) >= 0)
2985 Matrix4x4_Concat(&matrix, &skeleton->relativetransforms[bonenum], &temp);
2987 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2988 VectorCopy(forward, prog->globals.client->v_forward);
2989 VectorNegate(left, prog->globals.client->v_right);
2990 VectorCopy(up, prog->globals.client->v_up);
2991 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
2994 // #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)
2995 static void VM_SV_skel_set_bone(void)
2997 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2998 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2999 vec3_t forward, left, up, origin;
3000 skeleton_t *skeleton;
3002 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3004 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3006 VectorCopy(prog->globals.client->v_forward, forward);
3007 VectorNegate(prog->globals.client->v_right, left);
3008 VectorCopy(prog->globals.client->v_up, up);
3009 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3010 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3011 skeleton->relativetransforms[bonenum] = matrix;
3014 // #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)
3015 static void VM_SV_skel_mul_bone(void)
3017 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3018 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3019 vec3_t forward, left, up, origin;
3020 skeleton_t *skeleton;
3023 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3025 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3027 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3028 VectorCopy(prog->globals.client->v_forward, forward);
3029 VectorNegate(prog->globals.client->v_right, left);
3030 VectorCopy(prog->globals.client->v_up, up);
3031 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3032 temp = skeleton->relativetransforms[bonenum];
3033 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3036 // #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)
3037 static void VM_SV_skel_mul_bones(void)
3039 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3040 int firstbone = PRVM_G_FLOAT(OFS_PARM1) - 1;
3041 int lastbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3043 vec3_t forward, left, up, origin;
3044 skeleton_t *skeleton;
3047 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3049 VectorCopy(PRVM_G_VECTOR(OFS_PARM3), origin);
3050 VectorCopy(prog->globals.client->v_forward, forward);
3051 VectorNegate(prog->globals.client->v_right, left);
3052 VectorCopy(prog->globals.client->v_up, up);
3053 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3054 firstbone = max(0, firstbone);
3055 lastbone = min(lastbone, skeleton->model->num_bones - 1);
3056 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3058 temp = skeleton->relativetransforms[bonenum];
3059 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3063 // #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
3064 static void VM_SV_skel_copybones(void)
3066 int skeletonindexdst = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3067 int skeletonindexsrc = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3068 int firstbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3069 int lastbone = PRVM_G_FLOAT(OFS_PARM3) - 1;
3071 skeleton_t *skeletondst;
3072 skeleton_t *skeletonsrc;
3073 if (skeletonindexdst < 0 || skeletonindexdst >= MAX_EDICTS || !(skeletondst = prog->skeletons[skeletonindexdst]))
3075 if (skeletonindexsrc < 0 || skeletonindexsrc >= MAX_EDICTS || !(skeletonsrc = prog->skeletons[skeletonindexsrc]))
3077 firstbone = max(0, firstbone);
3078 lastbone = min(lastbone, skeletondst->model->num_bones - 1);
3079 lastbone = min(lastbone, skeletonsrc->model->num_bones - 1);
3080 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3081 skeletondst->relativetransforms[bonenum] = skeletonsrc->relativetransforms[bonenum];
3084 // #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)
3085 static void VM_SV_skel_delete(void)
3087 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3088 skeleton_t *skeleton;
3089 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3092 prog->skeletons[skeletonindex] = NULL;
3095 // #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
3096 static void VM_SV_frameforname(void)
3098 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3099 dp_model_t *model = SV_GetModelByIndex(modelindex);
3100 const char *name = PRVM_G_STRING(OFS_PARM1);
3102 PRVM_G_FLOAT(OFS_RETURN) = -1;
3103 if (!model || !model->animscenes)
3105 for (i = 0;i < model->numframes;i++)
3107 if (!strcasecmp(model->animscenes[i].name, name))
3109 PRVM_G_FLOAT(OFS_RETURN) = i;
3115 // #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.
3116 static void VM_SV_frameduration(void)
3118 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3119 dp_model_t *model = SV_GetModelByIndex(modelindex);
3120 int framenum = (int)PRVM_G_FLOAT(OFS_PARM1);
3121 PRVM_G_FLOAT(OFS_RETURN) = 0;
3122 if (!model || !model->animscenes || framenum < 0 || framenum >= model->numframes)
3124 if (model->animscenes[framenum].framerate)
3125 PRVM_G_FLOAT(OFS_RETURN) = model->animscenes[framenum].framecount / model->animscenes[framenum].framerate;
3129 prvm_builtin_t vm_sv_builtins[] = {
3130 NULL, // #0 NULL function (not callable) (QUAKE)
3131 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
3132 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
3133 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
3134 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
3135 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
3136 VM_break, // #6 void() break (QUAKE)
3137 VM_random, // #7 float() random (QUAKE)
3138 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
3139 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
3140 VM_error, // #10 void(string e) error (QUAKE)
3141 VM_objerror, // #11 void(string e) objerror (QUAKE)
3142 VM_vlen, // #12 float(vector v) vlen (QUAKE)
3143 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
3144 VM_spawn, // #14 entity() spawn (QUAKE)
3145 VM_remove, // #15 void(entity e) remove (QUAKE)
3146 VM_SV_traceline, // #16 void(vector v1, vector v2, float tryents) traceline (QUAKE)
3147 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
3148 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
3149 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
3150 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
3151 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
3152 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
3153 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
3154 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
3155 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
3156 VM_ftos, // #26 string(float f) ftos (QUAKE)
3157 VM_vtos, // #27 string(vector v) vtos (QUAKE)
3158 VM_coredump, // #28 void() coredump (QUAKE)
3159 VM_traceon, // #29 void() traceon (QUAKE)
3160 VM_traceoff, // #30 void() traceoff (QUAKE)
3161 VM_eprint, // #31 void(entity e) eprint (QUAKE)
3162 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
3163 NULL, // #33 (QUAKE)
3164 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
3165 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
3166 VM_rint, // #36 float(float v) rint (QUAKE)
3167 VM_floor, // #37 float(float v) floor (QUAKE)
3168 VM_ceil, // #38 float(float v) ceil (QUAKE)
3169 NULL, // #39 (QUAKE)
3170 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
3171 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
3172 NULL, // #42 (QUAKE)
3173 VM_fabs, // #43 float(float f) fabs (QUAKE)
3174 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
3175 VM_cvar, // #45 float(string s) cvar (QUAKE)
3176 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
3177 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
3178 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
3179 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
3180 NULL, // #50 (QUAKE)
3181 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
3182 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
3183 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
3184 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
3185 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
3186 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
3187 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
3188 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
3189 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
3190 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
3191 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
3192 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
3193 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
3194 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
3195 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
3196 NULL, // #66 (QUAKE)
3197 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
3198 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
3199 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
3200 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
3201 NULL, // #71 (QUAKE)
3202 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
3203 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
3204 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
3205 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
3206 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
3207 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
3208 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
3209 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
3210 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
3211 VM_stof, // #81 float(string s) stof (FRIK_FILE)
3212 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
3213 NULL, // #83 (QUAKE)
3214 NULL, // #84 (QUAKE)
3215 NULL, // #85 (QUAKE)
3216 NULL, // #86 (QUAKE)
3217 NULL, // #87 (QUAKE)
3218 NULL, // #88 (QUAKE)
3219 NULL, // #89 (QUAKE)
3220 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
3221 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
3222 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
3223 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
3224 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
3225 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3226 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3227 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3228 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3229 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3230 // FrikaC and Telejano range #100-#199
3241 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3242 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3243 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3244 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3245 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3246 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3247 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3248 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3249 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3250 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3331 // FTEQW range #200-#299
3350 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3353 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3354 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3355 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3356 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3357 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3358 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3359 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3360 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3361 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3362 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3364 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3372 VM_SV_checkpvs, // #240 float(vector viewpos, entity viewee) checkpvs;
3395 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.
3396 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
3397 VM_SV_skel_get_numbones, // #265 float(float skel) skel_get_numbones = #265; // (DP_SKELETONOBJECTS) returns how many bones exist in the created skeleton
3398 VM_SV_skel_get_bonename, // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (DP_SKELETONOBJECTS) returns name of bone (as a tempstring)
3399 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)
3400 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
3401 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)
3402 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)
3403 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)
3404 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)
3405 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)
3406 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
3407 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)
3408 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
3409 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.
3432 // CSQC range #300-#399
3433 NULL, // #300 void() clearscene (EXT_CSQC)
3434 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3435 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3436 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3437 NULL, // #304 void() renderscene (EXT_CSQC)
3438 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3439 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3440 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3441 NULL, // #308 void() R_EndPolygon
3443 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3444 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3448 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3449 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3450 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3451 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3452 NULL, // #319 void(string name) freepic (EXT_CSQC)
3453 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3454 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3455 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3456 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3457 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3458 NULL, // #325 void(void) drawresetcliparea
3463 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3464 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3465 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3466 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3467 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3468 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3469 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3470 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3471 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3472 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3473 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3474 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3475 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3476 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3477 NULL, // #344 vector() getmousepos (EXT_CSQC)
3478 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3479 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3480 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3481 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3482 NULL, // #349 float() isdemo (EXT_CSQC)
3483 VM_isserver, // #350 float() isserver (EXT_CSQC)
3484 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3485 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3486 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3487 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3493 NULL, // #360 float() readbyte (EXT_CSQC)
3494 NULL, // #361 float() readchar (EXT_CSQC)
3495 NULL, // #362 float() readshort (EXT_CSQC)
3496 NULL, // #363 float() readlong (EXT_CSQC)
3497 NULL, // #364 float() readcoord (EXT_CSQC)
3498 NULL, // #365 float() readangle (EXT_CSQC)
3499 NULL, // #366 string() readstring (EXT_CSQC)
3500 NULL, // #367 float() readfloat (EXT_CSQC)
3533 // LordHavoc's range #400-#499
3534 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3535 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3536 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3537 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3538 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3539 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3540 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3541 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3542 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)
3543 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3544 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3545 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3546 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3547 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3548 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3549 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3550 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3551 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3552 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3553 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3554 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3555 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3556 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3557 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3558 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3559 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3560 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3561 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3562 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3563 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3564 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3565 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3566 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3567 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3568 VM_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3569 VM_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3570 VM_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3571 VM_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3572 VM_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3573 VM_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3574 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3575 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3576 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3577 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3578 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3579 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3580 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3581 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3582 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3583 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3584 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3585 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3586 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3587 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3588 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3589 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3590 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3591 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3593 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3594 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3595 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3596 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3597 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3598 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3599 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3600 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3601 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3602 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3603 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3605 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3606 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3607 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3608 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3609 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3610 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3611 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3612 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3613 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3614 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3615 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3616 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3617 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3618 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3619 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3620 VM_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3628 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3629 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3630 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3631 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3632 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3633 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3634 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3635 VM_SV_WritePicture, // #501
3637 VM_whichpack, // #503 string(string) whichpack = #503;
3644 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3645 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3646 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3647 VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3648 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3649 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3650 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3651 VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
3652 VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
3653 VM_gettime, // #519 float(float timer) gettime = #519; (DP_QC_GETTIME)
3663 VM_loadfromdata, // #529
3664 VM_loadfromfile, // #530
3665 VM_SV_setpause, // #531 void(float pause) setpause = #531;
3667 VM_getsoundtime, // #533 float(entity e, float channel) getsoundtime = #533; (DP_SND_GETSOUNDTIME)
3668 VM_soundlength, // #534 float(string sample) soundlength = #534; (DP_SND_GETSOUNDTIME)
3739 VM_callfunction, // #605
3740 VM_writetofile, // #606
3741 VM_isfunction, // #607
3747 VM_parseentitydata, // #613
3758 VM_SV_getextresponse, // #624 string getextresponse(void)
3761 VM_sprintf, // #627 string sprintf(string format, ...)
3762 VM_getsurfacenumtriangles, // #628 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACETRIANGLE)
3763 VM_getsurfacetriangle, // #629 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACETRIANGLE)
3767 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3769 void VM_SV_Cmd_Init(void)
3774 void VM_SV_Cmd_Reset(void)
3776 World_End(&sv.world);
3777 if(prog->funcoffsets.SV_Shutdown)
3779 func_t s = prog->funcoffsets.SV_Shutdown;
3780 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3781 PRVM_ExecuteProgram(s,"SV_Shutdown() required");