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 "
140 "DP_SV_BOUNCEFACTOR "
141 "DP_SV_CLIENTCAMERA "
142 "DP_SV_CLIENTCOLORS "
145 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
146 "DP_SV_DRAWONLYTOCLIENT "
149 "DP_SV_ENTITYCONTENTSTRANSITION "
150 "DP_SV_MODELFLAGS_AS_EFFECTS "
151 "DP_SV_MOVETYPESTEP_LANDEVENT "
153 "DP_SV_NODRAWTOCLIENT "
154 "DP_SV_ONENTITYNOSPAWNFUNCTION "
155 "DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
157 "DP_SV_PING_PACKETLOSS "
158 "DP_SV_PLAYERPHYSICS "
159 "DP_SV_POINTPARTICLES "
161 "DP_SV_PRECACHEANYTIME "
165 "DP_SV_ROTATINGBMODEL "
169 "DP_SV_SPAWNFUNC_PREFIX "
170 "DP_SV_WRITEPICTURE "
171 "DP_SV_WRITEUNTERMINATEDSTRING "
175 "DP_TE_EXPLOSIONRGB "
177 "DP_TE_PARTICLECUBE "
178 "DP_TE_PARTICLERAIN "
179 "DP_TE_PARTICLESNOW "
181 "DP_TE_QUADEFFECTS1 "
184 "DP_TE_STANDARDEFFECTBUILTINS "
185 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
189 "FTE_CSQC_SKELETONOBJECTS "
192 "KRIMZON_SV_PARSECLIENTCOMMAND "
195 "NEXUIZ_PLAYERMODEL "
197 "PRYDON_CLIENTCURSOR "
198 "TENEBRAE_GFX_DLIGHTS "
201 //"EXT_CSQC " // not ready yet
208 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.
210 setorigin (entity, origin)
213 static void VM_SV_setorigin (void)
218 VM_SAFEPARMCOUNT(2, VM_setorigin);
220 e = PRVM_G_EDICT(OFS_PARM0);
221 if (e == prog->edicts)
223 VM_Warning("setorigin: can not modify world entity\n");
226 if (e->priv.server->free)
228 VM_Warning("setorigin: can not modify free entity\n");
231 org = PRVM_G_VECTOR(OFS_PARM1);
232 VectorCopy (org, e->fields.server->origin);
236 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
237 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
241 for (i=0 ; i<3 ; i++)
243 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
245 // set derived values
246 VectorCopy (min, e->fields.server->mins);
247 VectorCopy (max, e->fields.server->maxs);
248 VectorSubtract (max, min, e->fields.server->size);
257 the size box is rotated by the current angle
258 LordHavoc: no it isn't...
260 setsize (entity, minvector, maxvector)
263 static void VM_SV_setsize (void)
268 VM_SAFEPARMCOUNT(3, VM_setsize);
270 e = PRVM_G_EDICT(OFS_PARM0);
271 if (e == prog->edicts)
273 VM_Warning("setsize: can not modify world entity\n");
276 if (e->priv.server->free)
278 VM_Warning("setsize: can not modify free entity\n");
281 min = PRVM_G_VECTOR(OFS_PARM1);
282 max = PRVM_G_VECTOR(OFS_PARM2);
283 SetMinMaxSize (e, min, max, false);
291 setmodel(entity, model)
294 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
295 static void VM_SV_setmodel (void)
301 VM_SAFEPARMCOUNT(2, VM_setmodel);
303 e = PRVM_G_EDICT(OFS_PARM0);
304 if (e == prog->edicts)
306 VM_Warning("setmodel: can not modify world entity\n");
309 if (e->priv.server->free)
311 VM_Warning("setmodel: can not modify free entity\n");
314 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
315 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
316 e->fields.server->modelindex = i;
318 mod = SV_GetModelByIndex(i);
322 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
323 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
325 SetMinMaxSize (e, quakemins, quakemaxs, true);
328 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
335 single print to a specific client
337 sprint(clientent, value)
340 static void VM_SV_sprint (void)
344 char string[VM_STRINGTEMP_LENGTH];
346 VM_VarString(1, string, sizeof(string));
348 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
350 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
351 // LordHavoc: div0 requested that sprintto world operate like print
358 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
360 VM_Warning("tried to centerprint to a non-client\n");
364 client = svs.clients + entnum-1;
365 if (!client->netconnection)
368 MSG_WriteChar(&client->netconnection->message,svc_print);
369 MSG_WriteString(&client->netconnection->message, string);
377 single print to a specific client
379 centerprint(clientent, value)
382 static void VM_SV_centerprint (void)
386 char string[VM_STRINGTEMP_LENGTH];
388 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
390 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
392 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
394 VM_Warning("tried to centerprint to a non-client\n");
398 client = svs.clients + entnum-1;
399 if (!client->netconnection)
402 VM_VarString(1, string, sizeof(string));
403 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
404 MSG_WriteString(&client->netconnection->message, string);
411 particle(origin, color, count)
414 static void VM_SV_particle (void)
420 VM_SAFEPARMCOUNT(4, VM_SV_particle);
422 org = PRVM_G_VECTOR(OFS_PARM0);
423 dir = PRVM_G_VECTOR(OFS_PARM1);
424 color = PRVM_G_FLOAT(OFS_PARM2);
425 count = PRVM_G_FLOAT(OFS_PARM3);
426 SV_StartParticle (org, dir, (int)color, (int)count);
436 static void VM_SV_ambientsound (void)
440 float vol, attenuation;
443 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
445 pos = PRVM_G_VECTOR (OFS_PARM0);
446 samp = PRVM_G_STRING(OFS_PARM1);
447 vol = PRVM_G_FLOAT(OFS_PARM2);
448 attenuation = PRVM_G_FLOAT(OFS_PARM3);
450 // check to see if samp was properly precached
451 soundnum = SV_SoundIndex(samp, 1);
459 // add an svc_spawnambient command to the level signon packet
462 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
464 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
466 MSG_WriteVector(&sv.signon, pos, sv.protocol);
468 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
469 MSG_WriteShort (&sv.signon, soundnum);
471 MSG_WriteByte (&sv.signon, soundnum);
473 MSG_WriteByte (&sv.signon, (int)(vol*255));
474 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
482 Each entity can have eight independant sound sources, like voice,
485 Channel 0 is an auto-allocate channel, the others override anything
486 already running on that entity/channel pair.
488 An attenuation of 0 will play full volume everywhere in the level.
489 Larger attenuations will drop off.
493 static void VM_SV_sound (void)
497 prvm_edict_t *entity;
501 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
503 entity = PRVM_G_EDICT(OFS_PARM0);
504 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
505 sample = PRVM_G_STRING(OFS_PARM2);
506 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
507 attenuation = PRVM_G_FLOAT(OFS_PARM4);
510 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
514 if (volume < 0 || volume > 255)
516 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
520 if (attenuation < 0 || attenuation > 4)
522 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
526 if (channel < 0 || channel > 7)
528 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
532 SV_StartSound (entity, channel, sample, volume, attenuation);
539 Follows the same logic as VM_SV_sound, except instead of
540 an entity, an origin for the sound is provided, and channel
541 is omitted (since no entity is being tracked).
545 static void VM_SV_pointsound(void)
552 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
554 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
555 sample = PRVM_G_STRING(OFS_PARM1);
556 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
557 attenuation = PRVM_G_FLOAT(OFS_PARM3);
559 if (volume < 0 || volume > 255)
561 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
565 if (attenuation < 0 || attenuation > 4)
567 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
571 SV_StartPointSound (org, sample, volume, attenuation);
578 Used for use tracing and shot targeting
579 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
580 if the tryents flag is set.
582 traceline (vector1, vector2, movetype, ignore)
585 static void VM_SV_traceline (void)
592 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
594 prog->xfunction->builtinsprofile += 30;
596 v1 = PRVM_G_VECTOR(OFS_PARM0);
597 v2 = PRVM_G_VECTOR(OFS_PARM1);
598 move = (int)PRVM_G_FLOAT(OFS_PARM2);
599 ent = PRVM_G_EDICT(OFS_PARM3);
601 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]))
602 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));
604 trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
606 VM_SetTraceGlobals(&trace);
614 Used for use tracing and shot targeting
615 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
616 if the tryents flag is set.
618 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
621 // LordHavoc: added this for my own use, VERY useful, similar to traceline
622 static void VM_SV_tracebox (void)
624 float *v1, *v2, *m1, *m2;
629 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
631 prog->xfunction->builtinsprofile += 30;
633 v1 = PRVM_G_VECTOR(OFS_PARM0);
634 m1 = PRVM_G_VECTOR(OFS_PARM1);
635 m2 = PRVM_G_VECTOR(OFS_PARM2);
636 v2 = PRVM_G_VECTOR(OFS_PARM3);
637 move = (int)PRVM_G_FLOAT(OFS_PARM4);
638 ent = PRVM_G_EDICT(OFS_PARM5);
640 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]))
641 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));
643 trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
645 VM_SetTraceGlobals(&trace);
648 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
653 vec3_t original_origin;
654 vec3_t original_velocity;
655 vec3_t original_angles;
656 vec3_t original_avelocity;
660 VectorCopy(tossent->fields.server->origin , original_origin );
661 VectorCopy(tossent->fields.server->velocity , original_velocity );
662 VectorCopy(tossent->fields.server->angles , original_angles );
663 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
665 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
666 if (val != NULL && val->_float != 0)
667 gravity = val->_float;
670 gravity *= sv_gravity.value * 0.025;
672 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
674 SV_CheckVelocity (tossent);
675 tossent->fields.server->velocity[2] -= gravity;
676 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
677 VectorScale (tossent->fields.server->velocity, 0.05, move);
678 VectorAdd (tossent->fields.server->origin, move, end);
679 trace = SV_TraceBox(tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
680 VectorCopy (trace.endpos, tossent->fields.server->origin);
681 tossent->fields.server->velocity[2] -= gravity;
683 if (trace.fraction < 1)
687 VectorCopy(original_origin , tossent->fields.server->origin );
688 VectorCopy(original_velocity , tossent->fields.server->velocity );
689 VectorCopy(original_angles , tossent->fields.server->angles );
690 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
695 static void VM_SV_tracetoss (void)
699 prvm_edict_t *ignore;
701 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
703 prog->xfunction->builtinsprofile += 600;
705 ent = PRVM_G_EDICT(OFS_PARM0);
706 if (ent == prog->edicts)
708 VM_Warning("tracetoss: can not use world entity\n");
711 ignore = PRVM_G_EDICT(OFS_PARM1);
713 trace = SV_Trace_Toss (ent, ignore);
715 VM_SetTraceGlobals(&trace);
718 //============================================================================
720 static int checkpvsbytes;
721 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
723 static int VM_SV_newcheckclient (int check)
729 // cycle to the next one
731 check = bound(1, check, svs.maxclients);
732 if (check == svs.maxclients)
740 prog->xfunction->builtinsprofile++;
742 if (i == svs.maxclients+1)
744 // look up the client's edict
745 ent = PRVM_EDICT_NUM(i);
746 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
747 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
749 // found a valid client (possibly the same one again)
753 // get the PVS for the entity
754 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
756 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
757 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
766 Returns a client (or object that has a client enemy) that would be a
769 If there is more than one valid option, they are cycled each frame
771 If (self.origin + self.viewofs) is not in the PVS of the current target,
772 it is not returned at all.
777 int c_invis, c_notvis;
778 static void VM_SV_checkclient (void)
780 prvm_edict_t *ent, *self;
783 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
785 // find a new check if on a new frame
786 if (sv.time - sv.lastchecktime >= 0.1)
788 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
789 sv.lastchecktime = sv.time;
792 // return check if it might be visible
793 ent = PRVM_EDICT_NUM(sv.lastcheck);
794 if (ent->priv.server->free || ent->fields.server->health <= 0)
796 VM_RETURN_EDICT(prog->edicts);
800 // if current entity can't possibly see the check entity, return 0
801 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
802 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
803 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
806 VM_RETURN_EDICT(prog->edicts);
810 // might be able to see it
812 VM_RETURN_EDICT(ent);
815 //============================================================================
821 Checks if an entity is in a point's PVS.
822 Should be fast but can be inexact.
824 float checkpvs(vector viewpos, entity viewee) = #240;
827 static void VM_SV_checkpvs (void)
830 prvm_edict_t *viewee;
835 unsigned char fatpvs[MAX_MAP_LEAFS/8];
838 VM_SAFEPARMCOUNT(2, VM_SV_checkpvs);
839 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos);
840 viewee = PRVM_G_EDICT(OFS_PARM1);
842 if(viewee->priv.server->free)
844 VM_Warning("checkpvs: can not check free entity\n");
845 PRVM_G_FLOAT(OFS_RETURN) = 4;
850 if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
852 // no PVS support on this worldmodel... darn
853 PRVM_G_FLOAT(OFS_RETURN) = 3;
856 pvs = sv.worldmodel->brush.GetPVS(sv.worldmodel, viewpos);
859 // viewpos isn't in any PVS... darn
860 PRVM_G_FLOAT(OFS_RETURN) = 2;
863 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
865 // using fat PVS like FTEQW does (slow)
866 if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
868 // no PVS support on this worldmodel... darn
869 PRVM_G_FLOAT(OFS_RETURN) = 3;
872 fatpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
875 // viewpos isn't in any PVS... darn
876 PRVM_G_FLOAT(OFS_RETURN) = 2;
879 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
888 Sends text over to the client's execution buffer
890 stuffcmd (clientent, value, ...)
893 static void VM_SV_stuffcmd (void)
897 char string[VM_STRINGTEMP_LENGTH];
899 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
901 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
902 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
904 VM_Warning("Can't stuffcmd to a non-client\n");
908 VM_VarString(1, string, sizeof(string));
911 host_client = svs.clients + entnum-1;
912 Host_ClientCommands ("%s", string);
920 Returns a chain of entities that have origins within a spherical area
922 findradius (origin, radius)
925 static void VM_SV_findradius (void)
927 prvm_edict_t *ent, *chain;
928 vec_t radius, radius2;
929 vec3_t org, eorg, mins, maxs;
932 static prvm_edict_t *touchedicts[MAX_EDICTS];
935 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findradius);
938 chainfield = PRVM_G_INT(OFS_PARM2);
940 chainfield = prog->fieldoffsets.chain;
942 PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
944 chain = (prvm_edict_t *)prog->edicts;
946 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
947 radius = PRVM_G_FLOAT(OFS_PARM1);
948 radius2 = radius * radius;
950 mins[0] = org[0] - (radius + 1);
951 mins[1] = org[1] - (radius + 1);
952 mins[2] = org[2] - (radius + 1);
953 maxs[0] = org[0] + (radius + 1);
954 maxs[1] = org[1] + (radius + 1);
955 maxs[2] = org[2] + (radius + 1);
956 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
957 if (numtouchedicts > MAX_EDICTS)
959 // this never happens
960 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
961 numtouchedicts = MAX_EDICTS;
963 for (i = 0;i < numtouchedicts;i++)
965 ent = touchedicts[i];
966 prog->xfunction->builtinsprofile++;
967 // Quake did not return non-solid entities but darkplaces does
968 // (note: this is the reason you can't blow up fallen zombies)
969 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
971 // LordHavoc: compare against bounding box rather than center so it
972 // doesn't miss large objects, and use DotProduct instead of Length
973 // for a major speedup
974 VectorSubtract(org, ent->fields.server->origin, eorg);
975 if (sv_gameplayfix_findradiusdistancetobox.integer)
977 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
978 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
979 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
982 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
983 if (DotProduct(eorg, eorg) < radius2)
985 PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
990 VM_RETURN_EDICT(chain);
993 static void VM_SV_precache_sound (void)
995 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
996 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
999 static void VM_SV_precache_model (void)
1001 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
1002 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
1003 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
1010 float(float yaw, float dist[, settrace]) walkmove
1013 static void VM_SV_walkmove (void)
1022 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
1024 // assume failure if it returns early
1025 PRVM_G_FLOAT(OFS_RETURN) = 0;
1027 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1028 if (ent == prog->edicts)
1030 VM_Warning("walkmove: can not modify world entity\n");
1033 if (ent->priv.server->free)
1035 VM_Warning("walkmove: can not modify free entity\n");
1038 yaw = PRVM_G_FLOAT(OFS_PARM0);
1039 dist = PRVM_G_FLOAT(OFS_PARM1);
1040 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
1042 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1045 yaw = yaw*M_PI*2 / 360;
1047 move[0] = cos(yaw)*dist;
1048 move[1] = sin(yaw)*dist;
1051 // save program state, because SV_movestep may call other progs
1052 oldf = prog->xfunction;
1053 oldself = prog->globals.server->self;
1055 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
1058 // restore program state
1059 prog->xfunction = oldf;
1060 prog->globals.server->self = oldself;
1070 static void VM_SV_droptofloor (void)
1076 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
1078 // assume failure if it returns early
1079 PRVM_G_FLOAT(OFS_RETURN) = 0;
1081 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1082 if (ent == prog->edicts)
1084 VM_Warning("droptofloor: can not modify world entity\n");
1087 if (ent->priv.server->free)
1089 VM_Warning("droptofloor: can not modify free entity\n");
1093 VectorCopy (ent->fields.server->origin, end);
1096 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
1097 SV_UnstickEntity(ent);
1099 trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1100 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
1103 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]);
1104 VectorAdd(ent->fields.server->origin, offset, org);
1105 trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1106 VectorSubtract(trace.endpos, offset, trace.endpos);
1107 if (trace.startsolid)
1109 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]);
1110 SV_UnstickEntity(ent);
1112 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1113 ent->fields.server->groundentity = 0;
1114 PRVM_G_FLOAT(OFS_RETURN) = 1;
1116 else if (trace.fraction < 1)
1118 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]);
1119 VectorCopy (trace.endpos, ent->fields.server->origin);
1120 SV_UnstickEntity(ent);
1122 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1123 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1124 PRVM_G_FLOAT(OFS_RETURN) = 1;
1125 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1126 ent->priv.server->suspendedinairflag = true;
1131 if (trace.fraction != 1)
1133 if (trace.fraction < 1)
1134 VectorCopy (trace.endpos, ent->fields.server->origin);
1136 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1137 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1138 PRVM_G_FLOAT(OFS_RETURN) = 1;
1139 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1140 ent->priv.server->suspendedinairflag = true;
1149 void(float style, string value) lightstyle
1152 static void VM_SV_lightstyle (void)
1159 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1161 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1162 val = PRVM_G_STRING(OFS_PARM1);
1164 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1165 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1168 // change the string in sv
1169 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1171 // send message to all clients on this server
1172 if (sv.state != ss_active)
1175 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1177 if (client->active && client->netconnection)
1179 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1180 MSG_WriteChar (&client->netconnection->message,style);
1181 MSG_WriteString (&client->netconnection->message, val);
1191 static void VM_SV_checkbottom (void)
1193 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1194 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1202 static void VM_SV_pointcontents (void)
1204 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1205 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1212 Pick a vector for the player to shoot along
1213 vector aim(entity, missilespeed)
1216 static void VM_SV_aim (void)
1218 prvm_edict_t *ent, *check, *bestent;
1219 vec3_t start, dir, end, bestdir;
1222 float dist, bestdist;
1225 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1227 // assume failure if it returns early
1228 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1229 // if sv_aim is so high it can't possibly accept anything, skip out early
1230 if (sv_aim.value >= 1)
1233 ent = PRVM_G_EDICT(OFS_PARM0);
1234 if (ent == prog->edicts)
1236 VM_Warning("aim: can not use world entity\n");
1239 if (ent->priv.server->free)
1241 VM_Warning("aim: can not use free entity\n");
1244 //speed = PRVM_G_FLOAT(OFS_PARM1);
1246 VectorCopy (ent->fields.server->origin, start);
1249 // try sending a trace straight
1250 VectorCopy (prog->globals.server->v_forward, dir);
1251 VectorMA (start, 2048, dir, end);
1252 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1253 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1254 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1256 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1261 // try all possible entities
1262 VectorCopy (dir, bestdir);
1263 bestdist = sv_aim.value;
1266 check = PRVM_NEXT_EDICT(prog->edicts);
1267 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1269 prog->xfunction->builtinsprofile++;
1270 if (check->fields.server->takedamage != DAMAGE_AIM)
1274 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1275 continue; // don't aim at teammate
1276 for (j=0 ; j<3 ; j++)
1277 end[j] = check->fields.server->origin[j]
1278 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1279 VectorSubtract (end, start, dir);
1280 VectorNormalize (dir);
1281 dist = DotProduct (dir, prog->globals.server->v_forward);
1282 if (dist < bestdist)
1283 continue; // to far to turn
1284 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1285 if (tr.ent == check)
1286 { // can shoot at this one
1294 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1295 dist = DotProduct (dir, prog->globals.server->v_forward);
1296 VectorScale (prog->globals.server->v_forward, dist, end);
1298 VectorNormalize (end);
1299 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1303 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1308 ===============================================================================
1312 ===============================================================================
1315 #define MSG_BROADCAST 0 // unreliable to all
1316 #define MSG_ONE 1 // reliable to one (msg_entity)
1317 #define MSG_ALL 2 // reliable to all
1318 #define MSG_INIT 3 // write to the init string
1319 #define MSG_ENTITY 5
1321 sizebuf_t *WriteDest (void)
1327 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1331 return &sv.datagram;
1334 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1335 entnum = PRVM_NUM_FOR_EDICT(ent);
1336 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1338 VM_Warning ("WriteDest: tried to write to non-client\n");
1339 return &sv.reliable_datagram;
1342 return &svs.clients[entnum-1].netconnection->message;
1345 VM_Warning ("WriteDest: bad destination\n");
1347 return &sv.reliable_datagram;
1353 return sv.writeentitiestoclient_msg;
1359 static void VM_SV_WriteByte (void)
1361 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1362 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1365 static void VM_SV_WriteChar (void)
1367 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1368 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1371 static void VM_SV_WriteShort (void)
1373 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1374 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1377 static void VM_SV_WriteLong (void)
1379 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1380 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1383 static void VM_SV_WriteAngle (void)
1385 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1386 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1389 static void VM_SV_WriteCoord (void)
1391 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1392 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1395 static void VM_SV_WriteString (void)
1397 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1398 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1401 static void VM_SV_WriteUnterminatedString (void)
1403 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1404 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1408 static void VM_SV_WriteEntity (void)
1410 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1411 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1414 // writes a picture as at most size bytes of data
1416 // IMGNAME \0 SIZE(short) IMGDATA
1417 // if failed to read/compress:
1419 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1420 static void VM_SV_WritePicture (void)
1422 const char *imgname;
1426 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1428 imgname = PRVM_G_STRING(OFS_PARM1);
1429 size = (int) PRVM_G_FLOAT(OFS_PARM2);
1433 MSG_WriteString(WriteDest(), imgname);
1434 if(Image_Compress(imgname, size, &buf, &size))
1437 MSG_WriteShort(WriteDest(), size);
1438 SZ_Write(WriteDest(), (unsigned char *) buf, size);
1443 MSG_WriteShort(WriteDest(), 0);
1447 //////////////////////////////////////////////////////////
1449 static void VM_SV_makestatic (void)
1454 // allow 0 parameters due to an id1 qc bug in which this function is used
1455 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1456 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1458 if (prog->argc >= 1)
1459 ent = PRVM_G_EDICT(OFS_PARM0);
1461 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1462 if (ent == prog->edicts)
1464 VM_Warning("makestatic: can not modify world entity\n");
1467 if (ent->priv.server->free)
1469 VM_Warning("makestatic: can not modify free entity\n");
1474 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1479 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1480 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1481 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1483 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1485 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1486 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1487 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1491 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1492 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1493 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1496 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1497 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1498 for (i=0 ; i<3 ; i++)
1500 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1501 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1504 // throw the entity away now
1508 //=============================================================================
1515 static void VM_SV_setspawnparms (void)
1521 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1523 ent = PRVM_G_EDICT(OFS_PARM0);
1524 i = PRVM_NUM_FOR_EDICT(ent);
1525 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1527 Con_Print("tried to setspawnparms on a non-client\n");
1531 // copy spawn parms out of the client_t
1532 client = svs.clients + i-1;
1533 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1534 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1541 Returns a color vector indicating the lighting at the requested point.
1543 (Internal Operation note: actually measures the light beneath the point, just like
1544 the model lighting on the client)
1549 static void VM_SV_getlight (void)
1551 vec3_t ambientcolor, diffusecolor, diffusenormal;
1553 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1554 p = PRVM_G_VECTOR(OFS_PARM0);
1555 VectorClear(ambientcolor);
1556 VectorClear(diffusecolor);
1557 VectorClear(diffusenormal);
1558 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1559 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1560 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1565 unsigned char type; // 1/2/8 or other value if isn't used
1569 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1570 static int vm_customstats_last;
1572 void VM_CustomStats_Clear (void)
1576 Z_Free(vm_customstats);
1577 vm_customstats = NULL;
1578 vm_customstats_last = -1;
1582 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1590 for(i=0; i<vm_customstats_last+1 ;i++)
1592 if(!vm_customstats[i].type)
1594 switch(vm_customstats[i].type)
1596 //string as 16 bytes
1599 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1600 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1601 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1602 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1603 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1605 //float field sent as-is
1607 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1609 //integer value of float field
1611 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1619 // void(float index, float type, .void field) SV_AddStat = #232;
1620 // Set up an auto-sent player stat.
1621 // Client's get thier own fields sent to them. Index may not be less than 32.
1622 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1623 // 1: string (4 stats carrying a total of 16 charactures)
1624 // 2: float (one stat, float converted to an integer for transportation)
1625 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1626 static void VM_SV_AddStat (void)
1631 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1635 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1638 VM_Warning("PF_SV_AddStat: not enough memory\n");
1642 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1643 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1644 off = PRVM_G_INT (OFS_PARM2);
1649 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1652 if(i >= (MAX_CL_STATS-32))
1654 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1657 if(i > (MAX_CL_STATS-32-4) && type == 1)
1659 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1662 vm_customstats[i].type = type;
1663 vm_customstats[i].fieldoffset = off;
1664 if(vm_customstats_last < i)
1665 vm_customstats_last = i;
1672 copies data from one entity to another
1674 copyentity(src, dst)
1677 static void VM_SV_copyentity (void)
1679 prvm_edict_t *in, *out;
1680 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1681 in = PRVM_G_EDICT(OFS_PARM0);
1682 if (in == prog->edicts)
1684 VM_Warning("copyentity: can not read world entity\n");
1687 if (in->priv.server->free)
1689 VM_Warning("copyentity: can not read free entity\n");
1692 out = PRVM_G_EDICT(OFS_PARM1);
1693 if (out == prog->edicts)
1695 VM_Warning("copyentity: can not modify world entity\n");
1698 if (out->priv.server->free)
1700 VM_Warning("copyentity: can not modify free entity\n");
1703 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1712 sets the color of a client and broadcasts the update to all connected clients
1714 setcolor(clientent, value)
1717 static void VM_SV_setcolor (void)
1723 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1724 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1725 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1727 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1729 Con_Print("tried to setcolor a non-client\n");
1733 client = svs.clients + entnum-1;
1736 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1738 client->edict->fields.server->team = (i & 15) + 1;
1741 if (client->old_colors != client->colors)
1743 client->old_colors = client->colors;
1744 // send notification to all clients
1745 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1746 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1747 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1755 effect(origin, modelname, startframe, framecount, framerate)
1758 static void VM_SV_effect (void)
1762 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1763 s = PRVM_G_STRING(OFS_PARM1);
1766 VM_Warning("effect: no model specified\n");
1770 i = SV_ModelIndex(s, 1);
1773 VM_Warning("effect: model not precached\n");
1777 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1779 VM_Warning("effect: framecount < 1\n");
1783 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1785 VM_Warning("effect: framerate < 1\n");
1789 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));
1792 static void VM_SV_te_blood (void)
1794 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1795 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1797 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1798 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1800 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1801 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1802 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1804 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1805 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1806 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1808 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1809 SV_FlushBroadcastMessages();
1812 static void VM_SV_te_bloodshower (void)
1814 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1815 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1817 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1818 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1820 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1821 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1822 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1824 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1825 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1826 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1828 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1830 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1831 SV_FlushBroadcastMessages();
1834 static void VM_SV_te_explosionrgb (void)
1836 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1837 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1838 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1840 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1841 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1842 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1844 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1845 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1846 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1847 SV_FlushBroadcastMessages();
1850 static void VM_SV_te_particlecube (void)
1852 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1853 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1855 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1856 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1858 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1859 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1860 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1862 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1863 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1864 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1866 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1867 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1870 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1872 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1873 // gravity true/false
1874 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1876 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1877 SV_FlushBroadcastMessages();
1880 static void VM_SV_te_particlerain (void)
1882 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1883 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1885 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1886 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1888 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1889 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1890 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1892 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1893 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1894 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1896 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1897 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1898 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1900 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1902 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1903 SV_FlushBroadcastMessages();
1906 static void VM_SV_te_particlesnow (void)
1908 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1909 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1911 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1912 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1914 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1915 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1916 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1918 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1919 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1920 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1922 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1923 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1924 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1926 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1928 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1929 SV_FlushBroadcastMessages();
1932 static void VM_SV_te_spark (void)
1934 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1935 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1937 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1938 MSG_WriteByte(&sv.datagram, TE_SPARK);
1940 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1941 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1942 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1944 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1945 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1946 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1948 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1949 SV_FlushBroadcastMessages();
1952 static void VM_SV_te_gunshotquad (void)
1954 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1955 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1956 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1958 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1959 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1960 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1961 SV_FlushBroadcastMessages();
1964 static void VM_SV_te_spikequad (void)
1966 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1967 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1968 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1970 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1973 SV_FlushBroadcastMessages();
1976 static void VM_SV_te_superspikequad (void)
1978 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1979 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1980 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1982 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1983 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1984 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1985 SV_FlushBroadcastMessages();
1988 static void VM_SV_te_explosionquad (void)
1990 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1991 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1992 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1994 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1996 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1997 SV_FlushBroadcastMessages();
2000 static void VM_SV_te_smallflash (void)
2002 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
2003 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2004 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2006 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2007 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2008 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2009 SV_FlushBroadcastMessages();
2012 static void VM_SV_te_customflash (void)
2014 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
2015 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2017 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2018 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2020 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2021 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2022 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2024 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2026 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
2028 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
2029 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
2030 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
2031 SV_FlushBroadcastMessages();
2034 static void VM_SV_te_gunshot (void)
2036 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
2037 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2038 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2040 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2041 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2042 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2043 SV_FlushBroadcastMessages();
2046 static void VM_SV_te_spike (void)
2048 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
2049 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2050 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2052 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2053 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2054 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2055 SV_FlushBroadcastMessages();
2058 static void VM_SV_te_superspike (void)
2060 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
2061 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2062 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2064 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2065 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2066 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2067 SV_FlushBroadcastMessages();
2070 static void VM_SV_te_explosion (void)
2072 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
2073 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2074 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2076 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2077 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2078 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2079 SV_FlushBroadcastMessages();
2082 static void VM_SV_te_tarexplosion (void)
2084 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
2085 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2086 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2088 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2089 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2090 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2091 SV_FlushBroadcastMessages();
2094 static void VM_SV_te_wizspike (void)
2096 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
2097 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2098 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2100 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2101 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2102 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2103 SV_FlushBroadcastMessages();
2106 static void VM_SV_te_knightspike (void)
2108 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2109 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2110 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2112 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2113 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2114 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2115 SV_FlushBroadcastMessages();
2118 static void VM_SV_te_lavasplash (void)
2120 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2121 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2122 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2124 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2125 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2126 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2127 SV_FlushBroadcastMessages();
2130 static void VM_SV_te_teleport (void)
2132 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2133 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2134 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2136 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2137 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2138 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2139 SV_FlushBroadcastMessages();
2142 static void VM_SV_te_explosion2 (void)
2144 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2145 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2146 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2148 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2149 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2150 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2152 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2153 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2154 SV_FlushBroadcastMessages();
2157 static void VM_SV_te_lightning1 (void)
2159 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2160 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2161 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2163 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2165 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2166 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2167 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2169 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2170 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2171 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2172 SV_FlushBroadcastMessages();
2175 static void VM_SV_te_lightning2 (void)
2177 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2178 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2179 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2181 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2183 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2184 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2185 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2187 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2188 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2189 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2190 SV_FlushBroadcastMessages();
2193 static void VM_SV_te_lightning3 (void)
2195 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2196 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2197 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2199 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2201 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2202 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2203 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2205 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2206 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2207 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2208 SV_FlushBroadcastMessages();
2211 static void VM_SV_te_beam (void)
2213 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2214 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2215 MSG_WriteByte(&sv.datagram, TE_BEAM);
2217 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2219 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2220 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2221 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2223 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2224 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2225 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2226 SV_FlushBroadcastMessages();
2229 static void VM_SV_te_plasmaburn (void)
2231 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2232 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2233 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2234 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2235 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2236 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2237 SV_FlushBroadcastMessages();
2240 static void VM_SV_te_flamejet (void)
2242 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2243 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2244 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2246 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2247 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2248 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2250 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2251 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2252 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2254 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2255 SV_FlushBroadcastMessages();
2258 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2259 //this function originally written by KrimZon, made shorter by LordHavoc
2260 static void VM_SV_clientcommand (void)
2262 client_t *temp_client;
2264 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2266 //find client for this entity
2267 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2268 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2270 Con_Print("PF_clientcommand: entity is not a client\n");
2274 temp_client = host_client;
2275 host_client = svs.clients + i;
2276 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2277 host_client = temp_client;
2280 //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)
2281 static void VM_SV_setattachment (void)
2283 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2284 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2285 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2288 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2290 if (e == prog->edicts)
2292 VM_Warning("setattachment: can not modify world entity\n");
2295 if (e->priv.server->free)
2297 VM_Warning("setattachment: can not modify free entity\n");
2301 if (tagentity == NULL)
2302 tagentity = prog->edicts;
2304 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2306 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2308 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2311 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2313 model = SV_GetModelFromEdict(tagentity);
2316 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2318 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);
2321 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));
2325 /////////////////////////////////////////
2326 // DP_MD3_TAGINFO extension coded by VorteX
2328 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2332 i = (int)e->fields.server->modelindex;
2333 if (i < 1 || i >= MAX_MODELS)
2336 return Mod_Alias_GetTagIndexForName(SV_GetModelByIndex(i), (int)e->fields.server->skin, tagname);
2339 int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
2346 Matrix4x4_CreateIdentity(tag_localmatrix);
2348 if (tagindex >= 0 && (model = SV_GetModelFromEdict(e)) && model->num_bones)
2350 r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, e->priv.server->frameblend, &e->priv.server->skeleton, tagindex - 1, parentindex, tagname, tag_localmatrix);
2361 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2365 float pitchsign = 1;
2368 val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
2369 if (val && val->_float != 0)
2370 scale = val->_float;
2373 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);
2376 pitchsign = SV_GetPitchSign(ent);
2377 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);
2381 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2384 if (tagindex >= 0 && (model = SV_GetModelFromEdict(ent)) && model->animscenes)
2386 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2387 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2388 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2389 return Mod_Alias_GetTagMatrix(model, ent->priv.server->frameblend, &ent->priv.server->skeleton, tagindex, out);
2391 *out = identitymatrix;
2395 // Warnings/errors code:
2396 // 0 - normal (everything all-right)
2399 // 3 - null or non-precached model
2400 // 4 - no tags with requested index
2401 // 5 - runaway loop at attachment chain
2402 extern cvar_t cl_bob;
2403 extern cvar_t cl_bobcycle;
2404 extern cvar_t cl_bobup;
2405 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2409 int modelindex, attachloop;
2410 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2413 *out = identitymatrix; // warnings and errors return identical matrix
2415 if (ent == prog->edicts)
2417 if (ent->priv.server->free)
2420 modelindex = (int)ent->fields.server->modelindex;
2421 if (modelindex <= 0 || modelindex >= MAX_MODELS)
2424 model = SV_GetModelByIndex(modelindex);
2426 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2427 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2428 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2430 tagmatrix = identitymatrix;
2431 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2435 if (attachloop >= 256) // prevent runaway looping
2437 // apply transformation by child's tagindex on parent entity and then
2438 // by parent entity itself
2439 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2440 if (ret && attachloop == 0)
2442 SV_GetEntityMatrix(ent, &entitymatrix, false);
2443 Matrix4x4_Concat(&tagmatrix, &attachmatrix, out);
2444 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2445 // next iteration we process the parent entity
2446 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2448 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2449 ent = PRVM_EDICT_NUM(val->edict);
2456 // RENDER_VIEWMODEL magic
2457 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2459 Matrix4x4_Copy(&tagmatrix, out);
2460 ent = PRVM_EDICT_NUM(val->edict);
2462 SV_GetEntityMatrix(ent, &entitymatrix, true);
2463 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2466 // Cl_bob, ported from rendering code
2467 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2470 // LordHavoc: this code is *weird*, but not replacable (I think it
2471 // should be done in QC on the server, but oh well, quake is quake)
2472 // LordHavoc: figured out bobup: the time at which the sin is at 180
2473 // degrees (which allows lengthening or squishing the peak or valley)
2474 cycle = sv.time/cl_bobcycle.value;
2475 cycle -= (int)cycle;
2476 if (cycle < cl_bobup.value)
2477 cycle = sin(M_PI * cycle / cl_bobup.value);
2479 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2480 // bob is proportional to velocity in the xy plane
2481 // (don't count Z, or jumping messes it up)
2482 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;
2483 bob = bob*0.3 + bob*0.7*cycle;
2484 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2491 //float(entity ent, string tagname) gettagindex;
2493 static void VM_SV_gettagindex (void)
2496 const char *tag_name;
2499 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2501 ent = PRVM_G_EDICT(OFS_PARM0);
2502 tag_name = PRVM_G_STRING(OFS_PARM1);
2504 if (ent == prog->edicts)
2506 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
2509 if (ent->priv.server->free)
2511 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
2516 if (!SV_GetModelFromEdict(ent))
2517 Con_DPrintf("VM_SV_gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2520 tag_index = SV_GetTagIndex(ent, tag_name);
2522 if(developer_extra.integer)
2523 Con_DPrintf("VM_SV_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2525 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2528 //vector(entity ent, float tagindex) gettaginfo;
2529 static void VM_SV_gettaginfo (void)
2533 matrix4x4_t tag_matrix;
2534 matrix4x4_t tag_localmatrix;
2536 const char *tagname;
2539 vec3_t fo, le, up, trans;
2540 const dp_model_t *model;
2542 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2544 e = PRVM_G_EDICT(OFS_PARM0);
2545 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2547 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2548 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, le, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2549 VectorScale(le, -1, prog->globals.server->v_right);
2550 model = SV_GetModelFromEdict(e);
2551 VM_GenerateFrameGroupBlend(e->priv.server->framegroupblend, e);
2552 VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model);
2553 VM_UpdateEdictSkeleton(e, model, e->priv.server->frameblend);
2554 SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
2555 Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
2557 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
2558 val->_float = parentindex;
2559 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
2560 val->string = tagname ? PRVM_SetTempString(tagname) : 0;
2561 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
2562 VectorCopy(trans, val->vector);
2563 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
2564 VectorCopy(fo, val->vector);
2565 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
2566 VectorScale(le, -1, val->vector);
2567 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
2568 VectorCopy(up, val->vector);
2573 VM_Warning("gettagindex: can't affect world entity\n");
2576 VM_Warning("gettagindex: can't affect free entity\n");
2579 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2582 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2585 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2590 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2591 static void VM_SV_dropclient (void)
2594 client_t *oldhostclient;
2595 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2596 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2597 if (clientnum < 0 || clientnum >= svs.maxclients)
2599 VM_Warning("dropclient: not a client\n");
2602 if (!svs.clients[clientnum].active)
2604 VM_Warning("dropclient: that client slot is not connected\n");
2607 oldhostclient = host_client;
2608 host_client = svs.clients + clientnum;
2609 SV_DropClient(false);
2610 host_client = oldhostclient;
2613 //entity() spawnclient (DP_SV_BOTCLIENT)
2614 static void VM_SV_spawnclient (void)
2618 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2619 prog->xfunction->builtinsprofile += 2;
2621 for (i = 0;i < svs.maxclients;i++)
2623 if (!svs.clients[i].active)
2625 prog->xfunction->builtinsprofile += 100;
2626 SV_ConnectClient (i, NULL);
2627 // this has to be set or else ClientDisconnect won't be called
2628 // we assume the qc will call ClientConnect...
2629 svs.clients[i].clientconnectcalled = true;
2630 ed = PRVM_EDICT_NUM(i + 1);
2634 VM_RETURN_EDICT(ed);
2637 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2638 static void VM_SV_clienttype (void)
2641 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2642 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2643 if (clientnum < 0 || clientnum >= svs.maxclients)
2644 PRVM_G_FLOAT(OFS_RETURN) = 3;
2645 else if (!svs.clients[clientnum].active)
2646 PRVM_G_FLOAT(OFS_RETURN) = 0;
2647 else if (svs.clients[clientnum].netconnection)
2648 PRVM_G_FLOAT(OFS_RETURN) = 1;
2650 PRVM_G_FLOAT(OFS_RETURN) = 2;
2657 string(string key) serverkey
2660 void VM_SV_serverkey(void)
2662 char string[VM_STRINGTEMP_LENGTH];
2663 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2664 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2665 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2668 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2669 static void VM_SV_setmodelindex (void)
2674 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2676 e = PRVM_G_EDICT(OFS_PARM0);
2677 if (e == prog->edicts)
2679 VM_Warning("setmodelindex: can not modify world entity\n");
2682 if (e->priv.server->free)
2684 VM_Warning("setmodelindex: can not modify free entity\n");
2687 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2688 if (i <= 0 || i >= MAX_MODELS)
2690 VM_Warning("setmodelindex: invalid modelindex\n");
2693 if (!sv.model_precache[i][0])
2695 VM_Warning("setmodelindex: model not precached\n");
2699 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2700 e->fields.server->modelindex = i;
2702 mod = SV_GetModelByIndex(i);
2706 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2707 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2709 SetMinMaxSize (e, quakemins, quakemaxs, true);
2712 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2715 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2716 static void VM_SV_modelnameforindex (void)
2719 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2721 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2723 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2724 if (i <= 0 || i >= MAX_MODELS)
2726 VM_Warning("modelnameforindex: invalid modelindex\n");
2729 if (!sv.model_precache[i][0])
2731 VM_Warning("modelnameforindex: model not precached\n");
2735 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2738 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2739 static void VM_SV_particleeffectnum (void)
2742 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2743 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2746 PRVM_G_FLOAT(OFS_RETURN) = i;
2749 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2750 static void VM_SV_trailparticles (void)
2752 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2754 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2757 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2758 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2759 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2760 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2761 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2762 SV_FlushBroadcastMessages();
2765 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2766 static void VM_SV_pointparticles (void)
2768 int effectnum, count;
2770 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2772 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2775 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2776 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2777 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2778 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2779 if (count == 1 && !VectorLength2(vel))
2782 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2783 MSG_WriteShort(&sv.datagram, effectnum);
2784 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2788 // 1+2+12+12+2=29 bytes
2789 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2790 MSG_WriteShort(&sv.datagram, effectnum);
2791 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2792 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2793 MSG_WriteShort(&sv.datagram, count);
2796 SV_FlushBroadcastMessages();
2799 //PF_setpause, // void(float pause) setpause = #531;
2800 static void VM_SV_setpause(void) {
2802 pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
2803 if (pauseValue != 0) { //pause the game
2805 sv.pausedstart = Sys_DoubleTime();
2806 } else { //disable pause, in case it was enabled
2807 if (sv.paused != 0) {
2812 // send notification to all clients
2813 MSG_WriteByte(&sv.reliable_datagram, svc_setpause);
2814 MSG_WriteByte(&sv.reliable_datagram, sv.paused);
2817 // #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.
2818 static void VM_SV_skel_create(void)
2820 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
2821 dp_model_t *model = SV_GetModelByIndex(modelindex);
2822 skeleton_t *skeleton;
2824 PRVM_G_FLOAT(OFS_RETURN) = 0;
2825 if (!model || !model->num_bones)
2827 for (i = 0;i < MAX_EDICTS;i++)
2828 if (!prog->skeletons[i])
2830 if (i == MAX_EDICTS)
2832 prog->skeletons[i] = skeleton = Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
2833 PRVM_G_FLOAT(OFS_RETURN) = i + 1;
2834 skeleton->model = model;
2835 skeleton->relativetransforms = (matrix4x4_t *)(skeleton+1);
2836 // initialize to identity matrices
2837 for (i = 0;i < skeleton->model->num_bones;i++)
2838 skeleton->relativetransforms[i] = identitymatrix;
2841 // #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
2842 static void VM_SV_skel_build(void)
2844 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2845 skeleton_t *skeleton;
2846 prvm_edict_t *ed = PRVM_G_EDICT(OFS_PARM1);
2847 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM2);
2848 float retainfrac = PRVM_G_FLOAT(OFS_PARM3);
2849 int firstbone = PRVM_G_FLOAT(OFS_PARM4) - 1;
2850 int lastbone = PRVM_G_FLOAT(OFS_PARM5) - 1;
2851 dp_model_t *model = SV_GetModelByIndex(modelindex);
2856 framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS];
2857 frameblend_t frameblend[MAX_FRAMEBLENDS];
2858 matrix4x4_t blendedmatrix;
2860 PRVM_G_FLOAT(OFS_RETURN) = 0;
2861 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2863 firstbone = max(0, firstbone);
2864 lastbone = min(lastbone, model->num_bones - 1);
2865 lastbone = min(lastbone, skeleton->model->num_bones - 1);
2866 VM_GenerateFrameGroupBlend(framegroupblend, ed);
2867 VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model);
2868 blendfrac = 1.0f - retainfrac;
2869 for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
2870 frameblend[numblends].lerp *= blendfrac;
2871 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
2873 memset(&blendedmatrix, 0, sizeof(blendedmatrix));
2874 Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac);
2875 for (blendindex = 0;blendindex < numblends;blendindex++)
2877 Matrix4x4_FromBonePose6s(&matrix, model->num_posescale, model->data_poses6s + 6 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
2878 Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp);
2880 skeleton->relativetransforms[bonenum] = blendedmatrix;
2882 PRVM_G_FLOAT(OFS_RETURN) = skeletonindex + 1;
2885 // #265 float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS) returns how many bones exist in the created skeleton
2886 static void VM_SV_skel_get_numbones(void)
2888 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2889 skeleton_t *skeleton;
2890 PRVM_G_FLOAT(OFS_RETURN) = 0;
2891 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2893 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->num_bones;
2896 // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) returns name of bone (as a tempstring)
2897 static void VM_SV_skel_get_bonename(void)
2899 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2900 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2901 skeleton_t *skeleton;
2902 PRVM_G_INT(OFS_RETURN) = 0;
2903 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2905 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2907 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(skeleton->model->data_bones[bonenum].name);
2910 // #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)
2911 static void VM_SV_skel_get_boneparent(void)
2913 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2914 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2915 skeleton_t *skeleton;
2916 PRVM_G_FLOAT(OFS_RETURN) = 0;
2917 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2919 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2921 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->data_bones[bonenum].parent + 1;
2924 // #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
2925 static void VM_SV_skel_find_bone(void)
2927 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2928 const char *tagname = PRVM_G_STRING(OFS_PARM1);
2929 skeleton_t *skeleton;
2930 PRVM_G_FLOAT(OFS_RETURN) = 0;
2931 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2933 PRVM_G_FLOAT(OFS_RETURN) = Mod_Alias_GetTagIndexForName(skeleton->model, 0, tagname) + 1;
2936 // #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)
2937 static void VM_SV_skel_get_bonerel(void)
2939 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2940 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2941 skeleton_t *skeleton;
2943 vec3_t forward, left, up, origin;
2944 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2945 VectorClear(prog->globals.client->v_forward);
2946 VectorClear(prog->globals.client->v_right);
2947 VectorClear(prog->globals.client->v_up);
2948 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2950 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2952 matrix = skeleton->relativetransforms[bonenum];
2953 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2954 VectorCopy(forward, prog->globals.client->v_forward);
2955 VectorNegate(left, prog->globals.client->v_right);
2956 VectorCopy(up, prog->globals.client->v_up);
2957 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
2960 // #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)
2961 static void VM_SV_skel_get_boneabs(void)
2963 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2964 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2965 skeleton_t *skeleton;
2968 vec3_t forward, left, up, origin;
2969 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2970 VectorClear(prog->globals.client->v_forward);
2971 VectorClear(prog->globals.client->v_right);
2972 VectorClear(prog->globals.client->v_up);
2973 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2975 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2977 matrix = skeleton->relativetransforms[bonenum];
2978 // convert to absolute
2979 while ((bonenum = skeleton->model->data_bones[bonenum].parent) >= 0)
2982 Matrix4x4_Concat(&matrix, &skeleton->relativetransforms[bonenum], &temp);
2984 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2985 VectorCopy(forward, prog->globals.client->v_forward);
2986 VectorNegate(left, prog->globals.client->v_right);
2987 VectorCopy(up, prog->globals.client->v_up);
2988 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
2991 // #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)
2992 static void VM_SV_skel_set_bone(void)
2994 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2995 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2996 vec3_t forward, left, up, origin;
2997 skeleton_t *skeleton;
2999 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3001 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3003 VectorCopy(prog->globals.client->v_forward, forward);
3004 VectorNegate(prog->globals.client->v_right, left);
3005 VectorCopy(prog->globals.client->v_up, up);
3006 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3007 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3008 skeleton->relativetransforms[bonenum] = matrix;
3011 // #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)
3012 static void VM_SV_skel_mul_bone(void)
3014 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3015 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3016 vec3_t forward, left, up, origin;
3017 skeleton_t *skeleton;
3020 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3022 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3024 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3025 VectorCopy(prog->globals.client->v_forward, forward);
3026 VectorNegate(prog->globals.client->v_right, left);
3027 VectorCopy(prog->globals.client->v_up, up);
3028 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3029 temp = skeleton->relativetransforms[bonenum];
3030 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3033 // #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)
3034 static void VM_SV_skel_mul_bones(void)
3036 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3037 int firstbone = PRVM_G_FLOAT(OFS_PARM1) - 1;
3038 int lastbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3040 vec3_t forward, left, up, origin;
3041 skeleton_t *skeleton;
3044 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3046 VectorCopy(PRVM_G_VECTOR(OFS_PARM3), origin);
3047 VectorCopy(prog->globals.client->v_forward, forward);
3048 VectorNegate(prog->globals.client->v_right, left);
3049 VectorCopy(prog->globals.client->v_up, up);
3050 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3051 firstbone = max(0, firstbone);
3052 lastbone = min(lastbone, skeleton->model->num_bones - 1);
3053 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3055 temp = skeleton->relativetransforms[bonenum];
3056 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3060 // #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
3061 static void VM_SV_skel_copybones(void)
3063 int skeletonindexdst = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3064 int skeletonindexsrc = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3065 int firstbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3066 int lastbone = PRVM_G_FLOAT(OFS_PARM3) - 1;
3068 skeleton_t *skeletondst;
3069 skeleton_t *skeletonsrc;
3070 if (skeletonindexdst < 0 || skeletonindexdst >= MAX_EDICTS || !(skeletondst = prog->skeletons[skeletonindexdst]))
3072 if (skeletonindexsrc < 0 || skeletonindexsrc >= MAX_EDICTS || !(skeletonsrc = prog->skeletons[skeletonindexsrc]))
3074 firstbone = max(0, firstbone);
3075 lastbone = min(lastbone, skeletondst->model->num_bones - 1);
3076 lastbone = min(lastbone, skeletonsrc->model->num_bones - 1);
3077 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3078 skeletondst->relativetransforms[bonenum] = skeletonsrc->relativetransforms[bonenum];
3081 // #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)
3082 static void VM_SV_skel_delete(void)
3084 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3085 skeleton_t *skeleton;
3086 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3089 prog->skeletons[skeletonindex] = NULL;
3092 // #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
3093 static void VM_SV_frameforname(void)
3095 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3096 dp_model_t *model = SV_GetModelByIndex(modelindex);
3097 const char *name = PRVM_G_STRING(OFS_PARM1);
3099 PRVM_G_FLOAT(OFS_RETURN) = -1;
3100 if (!model || !model->animscenes)
3102 for (i = 0;i < model->numframes;i++)
3104 if (!strcasecmp(model->animscenes[i].name, name))
3106 PRVM_G_FLOAT(OFS_RETURN) = i;
3112 // #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.
3113 static void VM_SV_frameduration(void)
3115 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3116 dp_model_t *model = SV_GetModelByIndex(modelindex);
3117 int framenum = (int)PRVM_G_FLOAT(OFS_PARM1);
3118 PRVM_G_FLOAT(OFS_RETURN) = 0;
3119 if (!model || !model->animscenes || framenum < 0 || framenum >= model->numframes)
3121 if (model->animscenes[framenum].framerate)
3122 PRVM_G_FLOAT(OFS_RETURN) = model->animscenes[framenum].framecount / model->animscenes[framenum].framerate;
3126 prvm_builtin_t vm_sv_builtins[] = {
3127 NULL, // #0 NULL function (not callable) (QUAKE)
3128 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
3129 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
3130 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
3131 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
3132 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
3133 VM_break, // #6 void() break (QUAKE)
3134 VM_random, // #7 float() random (QUAKE)
3135 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
3136 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
3137 VM_error, // #10 void(string e) error (QUAKE)
3138 VM_objerror, // #11 void(string e) objerror (QUAKE)
3139 VM_vlen, // #12 float(vector v) vlen (QUAKE)
3140 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
3141 VM_spawn, // #14 entity() spawn (QUAKE)
3142 VM_remove, // #15 void(entity e) remove (QUAKE)
3143 VM_SV_traceline, // #16 void(vector v1, vector v2, float tryents) traceline (QUAKE)
3144 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
3145 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
3146 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
3147 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
3148 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
3149 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
3150 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
3151 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
3152 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
3153 VM_ftos, // #26 string(float f) ftos (QUAKE)
3154 VM_vtos, // #27 string(vector v) vtos (QUAKE)
3155 VM_coredump, // #28 void() coredump (QUAKE)
3156 VM_traceon, // #29 void() traceon (QUAKE)
3157 VM_traceoff, // #30 void() traceoff (QUAKE)
3158 VM_eprint, // #31 void(entity e) eprint (QUAKE)
3159 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
3160 NULL, // #33 (QUAKE)
3161 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
3162 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
3163 VM_rint, // #36 float(float v) rint (QUAKE)
3164 VM_floor, // #37 float(float v) floor (QUAKE)
3165 VM_ceil, // #38 float(float v) ceil (QUAKE)
3166 NULL, // #39 (QUAKE)
3167 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
3168 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
3169 NULL, // #42 (QUAKE)
3170 VM_fabs, // #43 float(float f) fabs (QUAKE)
3171 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
3172 VM_cvar, // #45 float(string s) cvar (QUAKE)
3173 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
3174 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
3175 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
3176 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
3177 NULL, // #50 (QUAKE)
3178 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
3179 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
3180 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
3181 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
3182 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
3183 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
3184 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
3185 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
3186 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
3187 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
3188 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
3189 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
3190 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
3191 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
3192 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
3193 NULL, // #66 (QUAKE)
3194 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
3195 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
3196 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
3197 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
3198 NULL, // #71 (QUAKE)
3199 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
3200 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
3201 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
3202 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
3203 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
3204 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
3205 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
3206 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
3207 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
3208 VM_stof, // #81 float(string s) stof (FRIK_FILE)
3209 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
3210 NULL, // #83 (QUAKE)
3211 NULL, // #84 (QUAKE)
3212 NULL, // #85 (QUAKE)
3213 NULL, // #86 (QUAKE)
3214 NULL, // #87 (QUAKE)
3215 NULL, // #88 (QUAKE)
3216 NULL, // #89 (QUAKE)
3217 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
3218 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
3219 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
3220 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
3221 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
3222 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3223 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3224 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3225 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3226 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3227 // FrikaC and Telejano range #100-#199
3238 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3239 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3240 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3241 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3242 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3243 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3244 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3245 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3246 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3247 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3328 // FTEQW range #200-#299
3347 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3350 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3351 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3352 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3353 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3354 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3355 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3356 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3357 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3358 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3359 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3361 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3369 VM_SV_checkpvs, // #240 float(vector viewpos, entity viewee) checkpvs;
3392 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.
3393 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
3394 VM_SV_skel_get_numbones, // #265 float(float skel) skel_get_numbones = #265; // (DP_SKELETONOBJECTS) returns how many bones exist in the created skeleton
3395 VM_SV_skel_get_bonename, // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (DP_SKELETONOBJECTS) returns name of bone (as a tempstring)
3396 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)
3397 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
3398 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)
3399 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)
3400 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)
3401 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)
3402 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)
3403 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
3404 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)
3405 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
3406 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.
3429 // CSQC range #300-#399
3430 NULL, // #300 void() clearscene (EXT_CSQC)
3431 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3432 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3433 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3434 NULL, // #304 void() renderscene (EXT_CSQC)
3435 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3436 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3437 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3438 NULL, // #308 void() R_EndPolygon
3440 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3441 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3445 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3446 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3447 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3448 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3449 NULL, // #319 void(string name) freepic (EXT_CSQC)
3450 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3451 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3452 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3453 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3454 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3455 NULL, // #325 void(void) drawresetcliparea
3460 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3461 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3462 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3463 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3464 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3465 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3466 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3467 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3468 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3469 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3470 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3471 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3472 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3473 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3474 NULL, // #344 vector() getmousepos (EXT_CSQC)
3475 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3476 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3477 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3478 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3479 NULL, // #349 float() isdemo (EXT_CSQC)
3480 VM_isserver, // #350 float() isserver (EXT_CSQC)
3481 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3482 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3483 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3484 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3490 NULL, // #360 float() readbyte (EXT_CSQC)
3491 NULL, // #361 float() readchar (EXT_CSQC)
3492 NULL, // #362 float() readshort (EXT_CSQC)
3493 NULL, // #363 float() readlong (EXT_CSQC)
3494 NULL, // #364 float() readcoord (EXT_CSQC)
3495 NULL, // #365 float() readangle (EXT_CSQC)
3496 NULL, // #366 string() readstring (EXT_CSQC)
3497 NULL, // #367 float() readfloat (EXT_CSQC)
3530 // LordHavoc's range #400-#499
3531 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3532 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3533 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3534 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3535 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3536 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3537 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3538 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3539 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)
3540 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3541 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3542 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3543 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3544 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3545 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3546 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3547 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3548 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3549 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3550 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3551 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3552 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3553 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3554 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3555 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3556 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3557 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3558 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3559 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3560 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3561 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3562 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3563 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3564 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3565 VM_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3566 VM_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3567 VM_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3568 VM_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3569 VM_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3570 VM_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3571 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3572 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3573 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3574 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3575 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3576 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3577 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3578 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3579 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3580 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3581 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3582 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3583 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3584 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3585 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3586 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3587 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3588 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3590 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3591 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3592 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3593 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3594 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3595 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3596 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3597 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3598 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3599 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3600 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3602 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3603 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3604 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3605 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3606 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3607 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3608 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3609 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3610 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3611 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3612 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3613 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3614 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3615 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3616 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3617 VM_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3625 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3626 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3627 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3628 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3629 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3630 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3631 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3632 VM_SV_WritePicture, // #501
3634 VM_whichpack, // #503 string(string) whichpack = #503;
3641 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3642 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3643 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3644 VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3645 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3646 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3647 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3648 VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
3649 VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
3650 VM_gettime, // #519 float(float timer) gettime = #519; (DP_QC_GETTIME)
3660 VM_loadfromdata, // #529
3661 VM_loadfromfile, // #530
3662 VM_SV_setpause, // #531 void(float pause) setpause = #531;
3664 VM_getsoundtime, // #533 float(entity e, float channel) getsoundtime = #533; (DP_SND_GETSOUNDTIME)
3665 VM_soundlength, // #534 float(string sample) soundlength = #534; (DP_SND_GETSOUNDTIME)
3736 VM_callfunction, // #605
3737 VM_writetofile, // #606
3738 VM_isfunction, // #607
3744 VM_parseentitydata, // #613
3755 VM_SV_getextresponse, // #624 string getextresponse(void)
3758 VM_sprintf, // #627 string sprintf(string format, ...)
3759 VM_getsurfacenumtriangles, // #628 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACETRIANGLE)
3760 VM_getsurfacetriangle, // #629 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACETRIANGLE)
3764 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3766 void VM_SV_Cmd_Init(void)
3771 void VM_SV_Cmd_Reset(void)
3773 World_End(&sv.world);
3774 if(prog->funcoffsets.SV_Shutdown)
3776 func_t s = prog->funcoffsets.SV_Shutdown;
3777 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3778 PRVM_ExecuteProgram(s,"SV_Shutdown() required");