6 //============================================================================
11 char *vm_sv_extensions =
16 "DP_CON_ALIASPARAMETERS "
22 "DP_CSQC_ENTITYNOCULL "
23 "DP_CSQC_ENTITYTRANSPARENTSORTING_OFFSET "
24 "DP_CSQC_MULTIFRAME_INTERPOLATION "
25 "DP_CSQC_SPAWNPARTICLE "
26 "DP_CSQC_QUERYRENDERENTITY "
39 "DP_EF_RESTARTANIM_BIT "
44 "DP_ENT_CUSTOMCOLORMAP "
45 "DP_ENT_EXTERIORMODELTOCLIENT "
48 "DP_ENT_LOWPRECISION "
52 "DP_GFX_EXTERNALTEXTURES "
53 "DP_GFX_EXTERNALTEXTURES_PERMAP "
55 "DP_GFX_MODEL_INTERPOLATION "
56 "DP_GFX_QUAKE3MODELTAGS "
60 "DP_HALFLIFE_MAP_CVAR "
63 "DP_LIGHTSTYLE_STATICVALUE "
67 "DP_MOVETYPEBOUNCEMISSILE "
70 "DP_QC_ASINACOSATANATAN2TAN "
76 "DP_QC_CVAR_DEFSTRING "
77 "DP_QC_CVAR_DESCRIPTION "
84 "DP_QC_EXTRESPONSEPACKET "
86 "DP_QC_FINDCHAINFLAGS "
87 "DP_QC_FINDCHAINFLOAT "
88 "DP_QC_FINDCHAIN_TOFIELD "
94 "DP_QC_GETSURFACETRIANGLE "
95 "DP_QC_GETSURFACEPOINTATTRIBUTE "
97 "DP_QC_GETTAGINFO_BONEPROPERTIES "
99 "DP_QC_GETTIME_CDTRACK "
102 "DP_QC_MULTIPLETEMPSTRINGS "
103 "DP_QC_NUM_FOR_EDICT "
105 "DP_QC_SINCOSSQRTPOW "
108 "DP_QC_STRINGBUFFERS "
109 "DP_QC_STRINGBUFFERS_CVARLIST "
110 "DP_QC_STRINGCOLORFUNCTIONS "
111 "DP_QC_STRING_CASE_FUNCTIONS "
113 "DP_QC_TOKENIZEBYSEPARATOR "
114 "DP_QC_TOKENIZE_CONSOLE "
117 "DP_QC_TRACE_MOVETYPE_HITMODEL "
118 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
119 "DP_QC_UNLIMITEDTEMPSTRINGS "
122 "DP_QC_VECTOANGLES_WITH_ROLL "
123 "DP_QC_VECTORVECTORS "
130 "DP_SKELETONOBJECTS "
131 "DP_SND_DIRECTIONLESSATTNNONE "
136 "DP_SND_GETSOUNDTIME "
138 "DP_VIDEO_SUBTITLES "
142 "DP_SV_BOUNCEFACTOR "
143 "DP_SV_CLIENTCAMERA "
144 "DP_SV_CLIENTCOLORS "
147 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
148 "DP_SV_DRAWONLYTOCLIENT "
151 "DP_SV_ENTITYCONTENTSTRANSITION "
152 "DP_SV_MODELFLAGS_AS_EFFECTS "
153 "DP_SV_MOVETYPESTEP_LANDEVENT "
155 "DP_SV_NODRAWTOCLIENT "
156 "DP_SV_ONENTITYNOSPAWNFUNCTION "
157 "DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
159 "DP_SV_PING_PACKETLOSS "
160 "DP_SV_PLAYERPHYSICS "
161 "DP_SV_POINTPARTICLES "
163 "DP_SV_PRECACHEANYTIME "
167 "DP_SV_ROTATINGBMODEL "
171 "DP_SV_SPAWNFUNC_PREFIX "
172 "DP_SV_WRITEPICTURE "
173 "DP_SV_WRITEUNTERMINATEDSTRING "
177 "DP_TE_EXPLOSIONRGB "
179 "DP_TE_PARTICLECUBE "
180 "DP_TE_PARTICLERAIN "
181 "DP_TE_PARTICLESNOW "
183 "DP_TE_QUADEFFECTS1 "
186 "DP_TE_STANDARDEFFECTBUILTINS "
187 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
191 "FTE_CSQC_SKELETONOBJECTS "
194 "KRIMZON_SV_PARSECLIENTCOMMAND "
197 "NEXUIZ_PLAYERMODEL "
199 "PRYDON_CLIENTCURSOR "
200 "TENEBRAE_GFX_DLIGHTS "
203 //"EXT_CSQC " // not ready yet
210 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.
212 setorigin (entity, origin)
215 static void VM_SV_setorigin (void)
220 VM_SAFEPARMCOUNT(2, VM_setorigin);
222 e = PRVM_G_EDICT(OFS_PARM0);
223 if (e == prog->edicts)
225 VM_Warning("setorigin: can not modify world entity\n");
228 if (e->priv.server->free)
230 VM_Warning("setorigin: can not modify free entity\n");
233 org = PRVM_G_VECTOR(OFS_PARM1);
234 VectorCopy (org, e->fields.server->origin);
238 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
239 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
243 for (i=0 ; i<3 ; i++)
245 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
247 // set derived values
248 VectorCopy (min, e->fields.server->mins);
249 VectorCopy (max, e->fields.server->maxs);
250 VectorSubtract (max, min, e->fields.server->size);
259 the size box is rotated by the current angle
260 LordHavoc: no it isn't...
262 setsize (entity, minvector, maxvector)
265 static void VM_SV_setsize (void)
270 VM_SAFEPARMCOUNT(3, VM_setsize);
272 e = PRVM_G_EDICT(OFS_PARM0);
273 if (e == prog->edicts)
275 VM_Warning("setsize: can not modify world entity\n");
278 if (e->priv.server->free)
280 VM_Warning("setsize: can not modify free entity\n");
283 min = PRVM_G_VECTOR(OFS_PARM1);
284 max = PRVM_G_VECTOR(OFS_PARM2);
285 SetMinMaxSize (e, min, max, false);
293 setmodel(entity, model)
296 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
297 static void VM_SV_setmodel (void)
303 VM_SAFEPARMCOUNT(2, VM_setmodel);
305 e = PRVM_G_EDICT(OFS_PARM0);
306 if (e == prog->edicts)
308 VM_Warning("setmodel: can not modify world entity\n");
311 if (e->priv.server->free)
313 VM_Warning("setmodel: can not modify free entity\n");
316 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
317 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
318 e->fields.server->modelindex = i;
320 mod = SV_GetModelByIndex(i);
324 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
325 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
327 SetMinMaxSize (e, quakemins, quakemaxs, true);
330 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
337 single print to a specific client
339 sprint(clientent, value)
342 static void VM_SV_sprint (void)
346 char string[VM_STRINGTEMP_LENGTH];
348 VM_VarString(1, string, sizeof(string));
350 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
352 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
353 // LordHavoc: div0 requested that sprintto world operate like print
360 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
362 VM_Warning("tried to centerprint to a non-client\n");
366 client = svs.clients + entnum-1;
367 if (!client->netconnection)
370 MSG_WriteChar(&client->netconnection->message,svc_print);
371 MSG_WriteString(&client->netconnection->message, string);
379 single print to a specific client
381 centerprint(clientent, value)
384 static void VM_SV_centerprint (void)
388 char string[VM_STRINGTEMP_LENGTH];
390 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
392 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
394 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
396 VM_Warning("tried to centerprint to a non-client\n");
400 client = svs.clients + entnum-1;
401 if (!client->netconnection)
404 VM_VarString(1, string, sizeof(string));
405 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
406 MSG_WriteString(&client->netconnection->message, string);
413 particle(origin, color, count)
416 static void VM_SV_particle (void)
422 VM_SAFEPARMCOUNT(4, VM_SV_particle);
424 org = PRVM_G_VECTOR(OFS_PARM0);
425 dir = PRVM_G_VECTOR(OFS_PARM1);
426 color = PRVM_G_FLOAT(OFS_PARM2);
427 count = PRVM_G_FLOAT(OFS_PARM3);
428 SV_StartParticle (org, dir, (int)color, (int)count);
438 static void VM_SV_ambientsound (void)
442 float vol, attenuation;
445 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
447 pos = PRVM_G_VECTOR (OFS_PARM0);
448 samp = PRVM_G_STRING(OFS_PARM1);
449 vol = PRVM_G_FLOAT(OFS_PARM2);
450 attenuation = PRVM_G_FLOAT(OFS_PARM3);
452 // check to see if samp was properly precached
453 soundnum = SV_SoundIndex(samp, 1);
461 // add an svc_spawnambient command to the level signon packet
464 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
466 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
468 MSG_WriteVector(&sv.signon, pos, sv.protocol);
470 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
471 MSG_WriteShort (&sv.signon, soundnum);
473 MSG_WriteByte (&sv.signon, soundnum);
475 MSG_WriteByte (&sv.signon, (int)(vol*255));
476 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
484 Each entity can have eight independant sound sources, like voice,
487 Channel 0 is an auto-allocate channel, the others override anything
488 already running on that entity/channel pair.
490 An attenuation of 0 will play full volume everywhere in the level.
491 Larger attenuations will drop off.
495 static void VM_SV_sound (void)
499 prvm_edict_t *entity;
503 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
505 entity = PRVM_G_EDICT(OFS_PARM0);
506 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
507 sample = PRVM_G_STRING(OFS_PARM2);
508 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
509 attenuation = PRVM_G_FLOAT(OFS_PARM4);
512 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
516 if (volume < 0 || volume > 255)
518 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
522 if (attenuation < 0 || attenuation > 4)
524 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
528 if (channel < 0 || channel > 7)
530 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
534 SV_StartSound (entity, channel, sample, volume, attenuation);
541 Follows the same logic as VM_SV_sound, except instead of
542 an entity, an origin for the sound is provided, and channel
543 is omitted (since no entity is being tracked).
547 static void VM_SV_pointsound(void)
554 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
556 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
557 sample = PRVM_G_STRING(OFS_PARM1);
558 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
559 attenuation = PRVM_G_FLOAT(OFS_PARM3);
561 if (volume < 0 || volume > 255)
563 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
567 if (attenuation < 0 || attenuation > 4)
569 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
573 SV_StartPointSound (org, sample, volume, attenuation);
580 Used for use tracing and shot targeting
581 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
582 if the tryents flag is set.
584 traceline (vector1, vector2, movetype, ignore)
587 static void VM_SV_traceline (void)
594 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
596 prog->xfunction->builtinsprofile += 30;
598 v1 = PRVM_G_VECTOR(OFS_PARM0);
599 v2 = PRVM_G_VECTOR(OFS_PARM1);
600 move = (int)PRVM_G_FLOAT(OFS_PARM2);
601 ent = PRVM_G_EDICT(OFS_PARM3);
603 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]))
604 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));
606 trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
608 VM_SetTraceGlobals(&trace);
616 Used for use tracing and shot targeting
617 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
618 if the tryents flag is set.
620 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
623 // LordHavoc: added this for my own use, VERY useful, similar to traceline
624 static void VM_SV_tracebox (void)
626 float *v1, *v2, *m1, *m2;
631 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
633 prog->xfunction->builtinsprofile += 30;
635 v1 = PRVM_G_VECTOR(OFS_PARM0);
636 m1 = PRVM_G_VECTOR(OFS_PARM1);
637 m2 = PRVM_G_VECTOR(OFS_PARM2);
638 v2 = PRVM_G_VECTOR(OFS_PARM3);
639 move = (int)PRVM_G_FLOAT(OFS_PARM4);
640 ent = PRVM_G_EDICT(OFS_PARM5);
642 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]))
643 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));
645 trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
647 VM_SetTraceGlobals(&trace);
650 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
655 vec3_t original_origin;
656 vec3_t original_velocity;
657 vec3_t original_angles;
658 vec3_t original_avelocity;
662 VectorCopy(tossent->fields.server->origin , original_origin );
663 VectorCopy(tossent->fields.server->velocity , original_velocity );
664 VectorCopy(tossent->fields.server->angles , original_angles );
665 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
667 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
668 if (val != NULL && val->_float != 0)
669 gravity = val->_float;
672 gravity *= sv_gravity.value * 0.025;
674 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
676 SV_CheckVelocity (tossent);
677 tossent->fields.server->velocity[2] -= gravity;
678 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
679 VectorScale (tossent->fields.server->velocity, 0.05, move);
680 VectorAdd (tossent->fields.server->origin, move, end);
681 trace = SV_TraceBox(tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
682 VectorCopy (trace.endpos, tossent->fields.server->origin);
683 tossent->fields.server->velocity[2] -= gravity;
685 if (trace.fraction < 1)
689 VectorCopy(original_origin , tossent->fields.server->origin );
690 VectorCopy(original_velocity , tossent->fields.server->velocity );
691 VectorCopy(original_angles , tossent->fields.server->angles );
692 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
697 static void VM_SV_tracetoss (void)
701 prvm_edict_t *ignore;
703 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
705 prog->xfunction->builtinsprofile += 600;
707 ent = PRVM_G_EDICT(OFS_PARM0);
708 if (ent == prog->edicts)
710 VM_Warning("tracetoss: can not use world entity\n");
713 ignore = PRVM_G_EDICT(OFS_PARM1);
715 trace = SV_Trace_Toss (ent, ignore);
717 VM_SetTraceGlobals(&trace);
720 //============================================================================
722 static int checkpvsbytes;
723 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
725 static int VM_SV_newcheckclient (int check)
731 // cycle to the next one
733 check = bound(1, check, svs.maxclients);
734 if (check == svs.maxclients)
742 prog->xfunction->builtinsprofile++;
744 if (i == svs.maxclients+1)
746 // look up the client's edict
747 ent = PRVM_EDICT_NUM(i);
748 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
749 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
751 // found a valid client (possibly the same one again)
755 // get the PVS for the entity
756 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
758 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
759 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
768 Returns a client (or object that has a client enemy) that would be a
771 If there is more than one valid option, they are cycled each frame
773 If (self.origin + self.viewofs) is not in the PVS of the current target,
774 it is not returned at all.
779 int c_invis, c_notvis;
780 static void VM_SV_checkclient (void)
782 prvm_edict_t *ent, *self;
785 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
787 // find a new check if on a new frame
788 if (sv.time - sv.lastchecktime >= 0.1)
790 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
791 sv.lastchecktime = sv.time;
794 // return check if it might be visible
795 ent = PRVM_EDICT_NUM(sv.lastcheck);
796 if (ent->priv.server->free || ent->fields.server->health <= 0)
798 VM_RETURN_EDICT(prog->edicts);
802 // if current entity can't possibly see the check entity, return 0
803 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
804 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
805 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
808 VM_RETURN_EDICT(prog->edicts);
812 // might be able to see it
814 VM_RETURN_EDICT(ent);
817 //============================================================================
823 Checks if an entity is in a point's PVS.
824 Should be fast but can be inexact.
826 float checkpvs(vector viewpos, entity viewee) = #240;
829 static void VM_SV_checkpvs (void)
832 prvm_edict_t *viewee;
837 unsigned char fatpvs[MAX_MAP_LEAFS/8];
840 VM_SAFEPARMCOUNT(2, VM_SV_checkpvs);
841 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos);
842 viewee = PRVM_G_EDICT(OFS_PARM1);
844 if(viewee->priv.server->free)
846 VM_Warning("checkpvs: can not check free entity\n");
847 PRVM_G_FLOAT(OFS_RETURN) = 4;
852 if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
854 // no PVS support on this worldmodel... darn
855 PRVM_G_FLOAT(OFS_RETURN) = 3;
858 pvs = sv.worldmodel->brush.GetPVS(sv.worldmodel, viewpos);
861 // viewpos isn't in any PVS... darn
862 PRVM_G_FLOAT(OFS_RETURN) = 2;
865 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
867 // using fat PVS like FTEQW does (slow)
868 if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
870 // no PVS support on this worldmodel... darn
871 PRVM_G_FLOAT(OFS_RETURN) = 3;
874 fatpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
877 // viewpos isn't in any PVS... darn
878 PRVM_G_FLOAT(OFS_RETURN) = 2;
881 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
890 Sends text over to the client's execution buffer
892 stuffcmd (clientent, value, ...)
895 static void VM_SV_stuffcmd (void)
899 char string[VM_STRINGTEMP_LENGTH];
901 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
903 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
904 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
906 VM_Warning("Can't stuffcmd to a non-client\n");
910 VM_VarString(1, string, sizeof(string));
913 host_client = svs.clients + entnum-1;
914 Host_ClientCommands ("%s", string);
922 Returns a chain of entities that have origins within a spherical area
924 findradius (origin, radius)
927 static void VM_SV_findradius (void)
929 prvm_edict_t *ent, *chain;
930 vec_t radius, radius2;
931 vec3_t org, eorg, mins, maxs;
934 static prvm_edict_t *touchedicts[MAX_EDICTS];
937 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findradius);
940 chainfield = PRVM_G_INT(OFS_PARM2);
942 chainfield = prog->fieldoffsets.chain;
944 PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
946 chain = (prvm_edict_t *)prog->edicts;
948 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
949 radius = PRVM_G_FLOAT(OFS_PARM1);
950 radius2 = radius * radius;
952 mins[0] = org[0] - (radius + 1);
953 mins[1] = org[1] - (radius + 1);
954 mins[2] = org[2] - (radius + 1);
955 maxs[0] = org[0] + (radius + 1);
956 maxs[1] = org[1] + (radius + 1);
957 maxs[2] = org[2] + (radius + 1);
958 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
959 if (numtouchedicts > MAX_EDICTS)
961 // this never happens
962 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
963 numtouchedicts = MAX_EDICTS;
965 for (i = 0;i < numtouchedicts;i++)
967 ent = touchedicts[i];
968 prog->xfunction->builtinsprofile++;
969 // Quake did not return non-solid entities but darkplaces does
970 // (note: this is the reason you can't blow up fallen zombies)
971 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
973 // LordHavoc: compare against bounding box rather than center so it
974 // doesn't miss large objects, and use DotProduct instead of Length
975 // for a major speedup
976 VectorSubtract(org, ent->fields.server->origin, eorg);
977 if (sv_gameplayfix_findradiusdistancetobox.integer)
979 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
980 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
981 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
984 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
985 if (DotProduct(eorg, eorg) < radius2)
987 PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
992 VM_RETURN_EDICT(chain);
995 static void VM_SV_precache_sound (void)
997 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
998 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
1001 static void VM_SV_precache_model (void)
1003 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
1004 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
1005 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
1012 float(float yaw, float dist[, settrace]) walkmove
1015 static void VM_SV_walkmove (void)
1024 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
1026 // assume failure if it returns early
1027 PRVM_G_FLOAT(OFS_RETURN) = 0;
1029 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1030 if (ent == prog->edicts)
1032 VM_Warning("walkmove: can not modify world entity\n");
1035 if (ent->priv.server->free)
1037 VM_Warning("walkmove: can not modify free entity\n");
1040 yaw = PRVM_G_FLOAT(OFS_PARM0);
1041 dist = PRVM_G_FLOAT(OFS_PARM1);
1042 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
1044 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1047 yaw = yaw*M_PI*2 / 360;
1049 move[0] = cos(yaw)*dist;
1050 move[1] = sin(yaw)*dist;
1053 // save program state, because SV_movestep may call other progs
1054 oldf = prog->xfunction;
1055 oldself = prog->globals.server->self;
1057 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
1060 // restore program state
1061 prog->xfunction = oldf;
1062 prog->globals.server->self = oldself;
1072 static void VM_SV_droptofloor (void)
1078 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
1080 // assume failure if it returns early
1081 PRVM_G_FLOAT(OFS_RETURN) = 0;
1083 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1084 if (ent == prog->edicts)
1086 VM_Warning("droptofloor: can not modify world entity\n");
1089 if (ent->priv.server->free)
1091 VM_Warning("droptofloor: can not modify free entity\n");
1095 VectorCopy (ent->fields.server->origin, end);
1098 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
1099 SV_UnstickEntity(ent);
1101 trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1102 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
1105 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]);
1106 VectorAdd(ent->fields.server->origin, offset, org);
1107 trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1108 VectorSubtract(trace.endpos, offset, trace.endpos);
1109 if (trace.startsolid)
1111 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]);
1112 SV_UnstickEntity(ent);
1114 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1115 ent->fields.server->groundentity = 0;
1116 PRVM_G_FLOAT(OFS_RETURN) = 1;
1118 else if (trace.fraction < 1)
1120 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]);
1121 VectorCopy (trace.endpos, ent->fields.server->origin);
1122 SV_UnstickEntity(ent);
1124 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1125 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1126 PRVM_G_FLOAT(OFS_RETURN) = 1;
1127 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1128 ent->priv.server->suspendedinairflag = true;
1133 if (trace.fraction != 1)
1135 if (trace.fraction < 1)
1136 VectorCopy (trace.endpos, ent->fields.server->origin);
1138 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1139 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1140 PRVM_G_FLOAT(OFS_RETURN) = 1;
1141 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1142 ent->priv.server->suspendedinairflag = true;
1151 void(float style, string value) lightstyle
1154 static void VM_SV_lightstyle (void)
1161 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1163 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1164 val = PRVM_G_STRING(OFS_PARM1);
1166 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1167 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1170 // change the string in sv
1171 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1173 // send message to all clients on this server
1174 if (sv.state != ss_active)
1177 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1179 if (client->active && client->netconnection)
1181 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1182 MSG_WriteChar (&client->netconnection->message,style);
1183 MSG_WriteString (&client->netconnection->message, val);
1193 static void VM_SV_checkbottom (void)
1195 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1196 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1204 static void VM_SV_pointcontents (void)
1206 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1207 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1214 Pick a vector for the player to shoot along
1215 vector aim(entity, missilespeed)
1218 static void VM_SV_aim (void)
1220 prvm_edict_t *ent, *check, *bestent;
1221 vec3_t start, dir, end, bestdir;
1224 float dist, bestdist;
1227 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1229 // assume failure if it returns early
1230 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1231 // if sv_aim is so high it can't possibly accept anything, skip out early
1232 if (sv_aim.value >= 1)
1235 ent = PRVM_G_EDICT(OFS_PARM0);
1236 if (ent == prog->edicts)
1238 VM_Warning("aim: can not use world entity\n");
1241 if (ent->priv.server->free)
1243 VM_Warning("aim: can not use free entity\n");
1246 //speed = PRVM_G_FLOAT(OFS_PARM1);
1248 VectorCopy (ent->fields.server->origin, start);
1251 // try sending a trace straight
1252 VectorCopy (prog->globals.server->v_forward, dir);
1253 VectorMA (start, 2048, dir, end);
1254 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1255 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1256 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1258 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1263 // try all possible entities
1264 VectorCopy (dir, bestdir);
1265 bestdist = sv_aim.value;
1268 check = PRVM_NEXT_EDICT(prog->edicts);
1269 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1271 prog->xfunction->builtinsprofile++;
1272 if (check->fields.server->takedamage != DAMAGE_AIM)
1276 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1277 continue; // don't aim at teammate
1278 for (j=0 ; j<3 ; j++)
1279 end[j] = check->fields.server->origin[j]
1280 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1281 VectorSubtract (end, start, dir);
1282 VectorNormalize (dir);
1283 dist = DotProduct (dir, prog->globals.server->v_forward);
1284 if (dist < bestdist)
1285 continue; // to far to turn
1286 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1287 if (tr.ent == check)
1288 { // can shoot at this one
1296 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1297 dist = DotProduct (dir, prog->globals.server->v_forward);
1298 VectorScale (prog->globals.server->v_forward, dist, end);
1300 VectorNormalize (end);
1301 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1305 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1310 ===============================================================================
1314 ===============================================================================
1317 #define MSG_BROADCAST 0 // unreliable to all
1318 #define MSG_ONE 1 // reliable to one (msg_entity)
1319 #define MSG_ALL 2 // reliable to all
1320 #define MSG_INIT 3 // write to the init string
1321 #define MSG_ENTITY 5
1323 sizebuf_t *WriteDest (void)
1329 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1333 return &sv.datagram;
1336 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1337 entnum = PRVM_NUM_FOR_EDICT(ent);
1338 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1340 VM_Warning ("WriteDest: tried to write to non-client\n");
1341 return &sv.reliable_datagram;
1344 return &svs.clients[entnum-1].netconnection->message;
1347 VM_Warning ("WriteDest: bad destination\n");
1349 return &sv.reliable_datagram;
1355 return sv.writeentitiestoclient_msg;
1361 static void VM_SV_WriteByte (void)
1363 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1364 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1367 static void VM_SV_WriteChar (void)
1369 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1370 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1373 static void VM_SV_WriteShort (void)
1375 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1376 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1379 static void VM_SV_WriteLong (void)
1381 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1382 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1385 static void VM_SV_WriteAngle (void)
1387 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1388 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1391 static void VM_SV_WriteCoord (void)
1393 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1394 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1397 static void VM_SV_WriteString (void)
1399 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1400 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1403 static void VM_SV_WriteUnterminatedString (void)
1405 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1406 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1410 static void VM_SV_WriteEntity (void)
1412 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1413 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1416 // writes a picture as at most size bytes of data
1418 // IMGNAME \0 SIZE(short) IMGDATA
1419 // if failed to read/compress:
1421 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1422 static void VM_SV_WritePicture (void)
1424 const char *imgname;
1428 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1430 imgname = PRVM_G_STRING(OFS_PARM1);
1431 size = (int) PRVM_G_FLOAT(OFS_PARM2);
1435 MSG_WriteString(WriteDest(), imgname);
1436 if(Image_Compress(imgname, size, &buf, &size))
1439 MSG_WriteShort(WriteDest(), size);
1440 SZ_Write(WriteDest(), (unsigned char *) buf, size);
1445 MSG_WriteShort(WriteDest(), 0);
1449 //////////////////////////////////////////////////////////
1451 static void VM_SV_makestatic (void)
1456 // allow 0 parameters due to an id1 qc bug in which this function is used
1457 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1458 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1460 if (prog->argc >= 1)
1461 ent = PRVM_G_EDICT(OFS_PARM0);
1463 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1464 if (ent == prog->edicts)
1466 VM_Warning("makestatic: can not modify world entity\n");
1469 if (ent->priv.server->free)
1471 VM_Warning("makestatic: can not modify free entity\n");
1476 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1481 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1482 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1483 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1485 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1487 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1488 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1489 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1493 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1494 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1495 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1498 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1499 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1500 for (i=0 ; i<3 ; i++)
1502 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1503 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1506 // throw the entity away now
1510 //=============================================================================
1517 static void VM_SV_setspawnparms (void)
1523 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1525 ent = PRVM_G_EDICT(OFS_PARM0);
1526 i = PRVM_NUM_FOR_EDICT(ent);
1527 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1529 Con_Print("tried to setspawnparms on a non-client\n");
1533 // copy spawn parms out of the client_t
1534 client = svs.clients + i-1;
1535 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1536 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1543 Returns a color vector indicating the lighting at the requested point.
1545 (Internal Operation note: actually measures the light beneath the point, just like
1546 the model lighting on the client)
1551 static void VM_SV_getlight (void)
1553 vec3_t ambientcolor, diffusecolor, diffusenormal;
1555 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1556 p = PRVM_G_VECTOR(OFS_PARM0);
1557 VectorClear(ambientcolor);
1558 VectorClear(diffusecolor);
1559 VectorClear(diffusenormal);
1560 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1561 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1562 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1567 unsigned char type; // 1/2/8 or other value if isn't used
1571 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1572 static int vm_customstats_last;
1574 void VM_CustomStats_Clear (void)
1578 Z_Free(vm_customstats);
1579 vm_customstats = NULL;
1580 vm_customstats_last = -1;
1584 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1592 for(i=0; i<vm_customstats_last+1 ;i++)
1594 if(!vm_customstats[i].type)
1596 switch(vm_customstats[i].type)
1598 //string as 16 bytes
1601 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1602 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1603 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1604 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1605 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1607 //float field sent as-is
1609 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1611 //integer value of float field
1613 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1621 // void(float index, float type, .void field) SV_AddStat = #232;
1622 // Set up an auto-sent player stat.
1623 // Client's get thier own fields sent to them. Index may not be less than 32.
1624 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1625 // 1: string (4 stats carrying a total of 16 charactures)
1626 // 2: float (one stat, float converted to an integer for transportation)
1627 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1628 static void VM_SV_AddStat (void)
1633 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1637 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1640 VM_Warning("PF_SV_AddStat: not enough memory\n");
1644 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1645 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1646 off = PRVM_G_INT (OFS_PARM2);
1651 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1654 if(i >= (MAX_CL_STATS-32))
1656 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1659 if(i > (MAX_CL_STATS-32-4) && type == 1)
1661 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1664 vm_customstats[i].type = type;
1665 vm_customstats[i].fieldoffset = off;
1666 if(vm_customstats_last < i)
1667 vm_customstats_last = i;
1674 copies data from one entity to another
1676 copyentity(src, dst)
1679 static void VM_SV_copyentity (void)
1681 prvm_edict_t *in, *out;
1682 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1683 in = PRVM_G_EDICT(OFS_PARM0);
1684 if (in == prog->edicts)
1686 VM_Warning("copyentity: can not read world entity\n");
1689 if (in->priv.server->free)
1691 VM_Warning("copyentity: can not read free entity\n");
1694 out = PRVM_G_EDICT(OFS_PARM1);
1695 if (out == prog->edicts)
1697 VM_Warning("copyentity: can not modify world entity\n");
1700 if (out->priv.server->free)
1702 VM_Warning("copyentity: can not modify free entity\n");
1705 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1714 sets the color of a client and broadcasts the update to all connected clients
1716 setcolor(clientent, value)
1719 static void VM_SV_setcolor (void)
1725 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1726 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1727 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1729 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1731 Con_Print("tried to setcolor a non-client\n");
1735 client = svs.clients + entnum-1;
1738 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1740 client->edict->fields.server->team = (i & 15) + 1;
1743 if (client->old_colors != client->colors)
1745 client->old_colors = client->colors;
1746 // send notification to all clients
1747 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1748 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1749 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1757 effect(origin, modelname, startframe, framecount, framerate)
1760 static void VM_SV_effect (void)
1764 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1765 s = PRVM_G_STRING(OFS_PARM1);
1768 VM_Warning("effect: no model specified\n");
1772 i = SV_ModelIndex(s, 1);
1775 VM_Warning("effect: model not precached\n");
1779 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1781 VM_Warning("effect: framecount < 1\n");
1785 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1787 VM_Warning("effect: framerate < 1\n");
1791 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));
1794 static void VM_SV_te_blood (void)
1796 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1797 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1799 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1800 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1802 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1803 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1804 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1806 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1807 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1808 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1810 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1811 SV_FlushBroadcastMessages();
1814 static void VM_SV_te_bloodshower (void)
1816 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1817 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1819 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1820 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1822 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1823 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1824 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1826 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1827 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1828 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1830 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1832 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1833 SV_FlushBroadcastMessages();
1836 static void VM_SV_te_explosionrgb (void)
1838 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1839 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1840 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1842 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1843 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1844 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1846 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1847 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1848 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1849 SV_FlushBroadcastMessages();
1852 static void VM_SV_te_particlecube (void)
1854 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1855 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1857 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1858 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1860 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1861 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1862 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1864 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1865 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1866 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1872 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1874 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1875 // gravity true/false
1876 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1878 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1879 SV_FlushBroadcastMessages();
1882 static void VM_SV_te_particlerain (void)
1884 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1885 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1887 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1888 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1890 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1891 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1892 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1894 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1895 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1896 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1898 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1899 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1902 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1904 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1905 SV_FlushBroadcastMessages();
1908 static void VM_SV_te_particlesnow (void)
1910 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1911 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1913 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1914 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1916 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1917 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1918 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1920 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1921 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1922 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1924 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1925 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1926 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1928 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1930 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1931 SV_FlushBroadcastMessages();
1934 static void VM_SV_te_spark (void)
1936 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1937 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1939 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1940 MSG_WriteByte(&sv.datagram, TE_SPARK);
1942 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1943 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1944 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1946 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1947 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1948 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1950 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1951 SV_FlushBroadcastMessages();
1954 static void VM_SV_te_gunshotquad (void)
1956 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1957 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1958 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1960 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1961 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1962 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1963 SV_FlushBroadcastMessages();
1966 static void VM_SV_te_spikequad (void)
1968 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1969 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1970 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1974 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1975 SV_FlushBroadcastMessages();
1978 static void VM_SV_te_superspikequad (void)
1980 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1981 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1982 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1984 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1985 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1986 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1987 SV_FlushBroadcastMessages();
1990 static void VM_SV_te_explosionquad (void)
1992 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1993 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1994 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1996 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1997 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1998 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1999 SV_FlushBroadcastMessages();
2002 static void VM_SV_te_smallflash (void)
2004 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
2005 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2006 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2008 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2009 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2010 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2011 SV_FlushBroadcastMessages();
2014 static void VM_SV_te_customflash (void)
2016 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
2017 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2019 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2020 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2022 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2023 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2024 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2026 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2028 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
2030 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
2031 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
2032 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
2033 SV_FlushBroadcastMessages();
2036 static void VM_SV_te_gunshot (void)
2038 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
2039 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2040 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2042 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2043 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2044 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2045 SV_FlushBroadcastMessages();
2048 static void VM_SV_te_spike (void)
2050 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
2051 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2052 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2054 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2055 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2056 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2057 SV_FlushBroadcastMessages();
2060 static void VM_SV_te_superspike (void)
2062 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
2063 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2064 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2066 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2067 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2068 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2069 SV_FlushBroadcastMessages();
2072 static void VM_SV_te_explosion (void)
2074 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
2075 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2076 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2078 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2079 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2080 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2081 SV_FlushBroadcastMessages();
2084 static void VM_SV_te_tarexplosion (void)
2086 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
2087 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2088 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2090 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2091 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2092 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2093 SV_FlushBroadcastMessages();
2096 static void VM_SV_te_wizspike (void)
2098 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
2099 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2100 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2102 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2103 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2104 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2105 SV_FlushBroadcastMessages();
2108 static void VM_SV_te_knightspike (void)
2110 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2111 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2112 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2114 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2115 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2116 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2117 SV_FlushBroadcastMessages();
2120 static void VM_SV_te_lavasplash (void)
2122 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2123 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2124 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2126 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2127 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2128 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2129 SV_FlushBroadcastMessages();
2132 static void VM_SV_te_teleport (void)
2134 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2135 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2136 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2138 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2139 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2140 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2141 SV_FlushBroadcastMessages();
2144 static void VM_SV_te_explosion2 (void)
2146 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2147 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2148 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2150 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2151 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2152 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2154 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2155 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2156 SV_FlushBroadcastMessages();
2159 static void VM_SV_te_lightning1 (void)
2161 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2162 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2163 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2165 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2167 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2168 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2169 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2171 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2172 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2173 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2174 SV_FlushBroadcastMessages();
2177 static void VM_SV_te_lightning2 (void)
2179 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2180 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2181 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2183 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2185 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2186 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2187 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2189 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2190 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2191 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2192 SV_FlushBroadcastMessages();
2195 static void VM_SV_te_lightning3 (void)
2197 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2198 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2199 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2201 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2203 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2204 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2205 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2207 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2208 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2209 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2210 SV_FlushBroadcastMessages();
2213 static void VM_SV_te_beam (void)
2215 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2216 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2217 MSG_WriteByte(&sv.datagram, TE_BEAM);
2219 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2221 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2222 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2223 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2225 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2226 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2227 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2228 SV_FlushBroadcastMessages();
2231 static void VM_SV_te_plasmaburn (void)
2233 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2234 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2235 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2236 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2237 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2238 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2239 SV_FlushBroadcastMessages();
2242 static void VM_SV_te_flamejet (void)
2244 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2245 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2246 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2248 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2249 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2250 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2252 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2253 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2254 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2256 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2257 SV_FlushBroadcastMessages();
2260 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2261 //this function originally written by KrimZon, made shorter by LordHavoc
2262 static void VM_SV_clientcommand (void)
2264 client_t *temp_client;
2266 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2268 //find client for this entity
2269 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2270 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2272 Con_Print("PF_clientcommand: entity is not a client\n");
2276 temp_client = host_client;
2277 host_client = svs.clients + i;
2278 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2279 host_client = temp_client;
2282 //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)
2283 static void VM_SV_setattachment (void)
2285 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2286 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2287 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2290 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2292 if (e == prog->edicts)
2294 VM_Warning("setattachment: can not modify world entity\n");
2297 if (e->priv.server->free)
2299 VM_Warning("setattachment: can not modify free entity\n");
2303 if (tagentity == NULL)
2304 tagentity = prog->edicts;
2306 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2308 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2310 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2313 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2315 model = SV_GetModelFromEdict(tagentity);
2318 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2320 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);
2323 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));
2327 /////////////////////////////////////////
2328 // DP_MD3_TAGINFO extension coded by VorteX
2330 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2334 i = (int)e->fields.server->modelindex;
2335 if (i < 1 || i >= MAX_MODELS)
2338 return Mod_Alias_GetTagIndexForName(SV_GetModelByIndex(i), (int)e->fields.server->skin, tagname);
2341 int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
2348 Matrix4x4_CreateIdentity(tag_localmatrix);
2350 if (tagindex >= 0 && (model = SV_GetModelFromEdict(e)) && model->num_bones)
2352 r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, e->priv.server->frameblend, &e->priv.server->skeleton, tagindex - 1, parentindex, tagname, tag_localmatrix);
2363 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2367 float pitchsign = 1;
2370 val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
2371 if (val && val->_float != 0)
2372 scale = val->_float;
2375 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);
2378 pitchsign = SV_GetPitchSign(ent);
2379 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);
2383 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2386 if (tagindex >= 0 && (model = SV_GetModelFromEdict(ent)) && model->animscenes)
2388 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2389 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2390 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2391 return Mod_Alias_GetTagMatrix(model, ent->priv.server->frameblend, &ent->priv.server->skeleton, tagindex, out);
2393 *out = identitymatrix;
2397 // Warnings/errors code:
2398 // 0 - normal (everything all-right)
2401 // 3 - null or non-precached model
2402 // 4 - no tags with requested index
2403 // 5 - runaway loop at attachment chain
2404 extern cvar_t cl_bob;
2405 extern cvar_t cl_bobcycle;
2406 extern cvar_t cl_bobup;
2407 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2411 int modelindex, attachloop;
2412 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2415 *out = identitymatrix; // warnings and errors return identical matrix
2417 if (ent == prog->edicts)
2419 if (ent->priv.server->free)
2422 modelindex = (int)ent->fields.server->modelindex;
2423 if (modelindex <= 0 || modelindex >= MAX_MODELS)
2426 model = SV_GetModelByIndex(modelindex);
2428 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2429 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2430 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2432 tagmatrix = identitymatrix;
2433 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2437 if (attachloop >= 256) // prevent runaway looping
2439 // apply transformation by child's tagindex on parent entity and then
2440 // by parent entity itself
2441 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2442 if (ret && attachloop == 0)
2444 SV_GetEntityMatrix(ent, &entitymatrix, false);
2445 Matrix4x4_Concat(&tagmatrix, &attachmatrix, out);
2446 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2447 // next iteration we process the parent entity
2448 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2450 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2451 ent = PRVM_EDICT_NUM(val->edict);
2458 // RENDER_VIEWMODEL magic
2459 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2461 Matrix4x4_Copy(&tagmatrix, out);
2462 ent = PRVM_EDICT_NUM(val->edict);
2464 SV_GetEntityMatrix(ent, &entitymatrix, true);
2465 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2468 // Cl_bob, ported from rendering code
2469 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2472 // LordHavoc: this code is *weird*, but not replacable (I think it
2473 // should be done in QC on the server, but oh well, quake is quake)
2474 // LordHavoc: figured out bobup: the time at which the sin is at 180
2475 // degrees (which allows lengthening or squishing the peak or valley)
2476 cycle = sv.time/cl_bobcycle.value;
2477 cycle -= (int)cycle;
2478 if (cycle < cl_bobup.value)
2479 cycle = sin(M_PI * cycle / cl_bobup.value);
2481 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2482 // bob is proportional to velocity in the xy plane
2483 // (don't count Z, or jumping messes it up)
2484 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;
2485 bob = bob*0.3 + bob*0.7*cycle;
2486 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2493 //float(entity ent, string tagname) gettagindex;
2495 static void VM_SV_gettagindex (void)
2498 const char *tag_name;
2501 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2503 ent = PRVM_G_EDICT(OFS_PARM0);
2504 tag_name = PRVM_G_STRING(OFS_PARM1);
2506 if (ent == prog->edicts)
2508 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
2511 if (ent->priv.server->free)
2513 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
2518 if (!SV_GetModelFromEdict(ent))
2519 Con_DPrintf("VM_SV_gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2522 tag_index = SV_GetTagIndex(ent, tag_name);
2524 if(developer_extra.integer)
2525 Con_DPrintf("VM_SV_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2527 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2530 //vector(entity ent, float tagindex) gettaginfo;
2531 static void VM_SV_gettaginfo (void)
2535 matrix4x4_t tag_matrix;
2536 matrix4x4_t tag_localmatrix;
2538 const char *tagname;
2541 vec3_t fo, le, up, trans;
2542 const dp_model_t *model;
2544 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2546 e = PRVM_G_EDICT(OFS_PARM0);
2547 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2549 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2550 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, le, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2551 VectorScale(le, -1, prog->globals.server->v_right);
2552 model = SV_GetModelFromEdict(e);
2553 VM_GenerateFrameGroupBlend(e->priv.server->framegroupblend, e);
2554 VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model);
2555 VM_UpdateEdictSkeleton(e, model, e->priv.server->frameblend);
2556 SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
2557 Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
2559 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
2560 val->_float = parentindex;
2561 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
2562 val->string = tagname ? PRVM_SetTempString(tagname) : 0;
2563 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
2564 VectorCopy(trans, val->vector);
2565 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
2566 VectorCopy(fo, val->vector);
2567 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
2568 VectorScale(le, -1, val->vector);
2569 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
2570 VectorCopy(up, val->vector);
2575 VM_Warning("gettagindex: can't affect world entity\n");
2578 VM_Warning("gettagindex: can't affect free entity\n");
2581 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2584 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2587 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2592 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2593 static void VM_SV_dropclient (void)
2596 client_t *oldhostclient;
2597 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2598 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2599 if (clientnum < 0 || clientnum >= svs.maxclients)
2601 VM_Warning("dropclient: not a client\n");
2604 if (!svs.clients[clientnum].active)
2606 VM_Warning("dropclient: that client slot is not connected\n");
2609 oldhostclient = host_client;
2610 host_client = svs.clients + clientnum;
2611 SV_DropClient(false);
2612 host_client = oldhostclient;
2615 //entity() spawnclient (DP_SV_BOTCLIENT)
2616 static void VM_SV_spawnclient (void)
2620 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2621 prog->xfunction->builtinsprofile += 2;
2623 for (i = 0;i < svs.maxclients;i++)
2625 if (!svs.clients[i].active)
2627 prog->xfunction->builtinsprofile += 100;
2628 SV_ConnectClient (i, NULL);
2629 // this has to be set or else ClientDisconnect won't be called
2630 // we assume the qc will call ClientConnect...
2631 svs.clients[i].clientconnectcalled = true;
2632 ed = PRVM_EDICT_NUM(i + 1);
2636 VM_RETURN_EDICT(ed);
2639 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2640 static void VM_SV_clienttype (void)
2643 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2644 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2645 if (clientnum < 0 || clientnum >= svs.maxclients)
2646 PRVM_G_FLOAT(OFS_RETURN) = 3;
2647 else if (!svs.clients[clientnum].active)
2648 PRVM_G_FLOAT(OFS_RETURN) = 0;
2649 else if (svs.clients[clientnum].netconnection)
2650 PRVM_G_FLOAT(OFS_RETURN) = 1;
2652 PRVM_G_FLOAT(OFS_RETURN) = 2;
2659 string(string key) serverkey
2662 void VM_SV_serverkey(void)
2664 char string[VM_STRINGTEMP_LENGTH];
2665 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2666 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2667 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2670 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2671 static void VM_SV_setmodelindex (void)
2676 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2678 e = PRVM_G_EDICT(OFS_PARM0);
2679 if (e == prog->edicts)
2681 VM_Warning("setmodelindex: can not modify world entity\n");
2684 if (e->priv.server->free)
2686 VM_Warning("setmodelindex: can not modify free entity\n");
2689 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2690 if (i <= 0 || i >= MAX_MODELS)
2692 VM_Warning("setmodelindex: invalid modelindex\n");
2695 if (!sv.model_precache[i][0])
2697 VM_Warning("setmodelindex: model not precached\n");
2701 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2702 e->fields.server->modelindex = i;
2704 mod = SV_GetModelByIndex(i);
2708 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2709 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2711 SetMinMaxSize (e, quakemins, quakemaxs, true);
2714 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2717 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2718 static void VM_SV_modelnameforindex (void)
2721 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2723 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2725 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2726 if (i <= 0 || i >= MAX_MODELS)
2728 VM_Warning("modelnameforindex: invalid modelindex\n");
2731 if (!sv.model_precache[i][0])
2733 VM_Warning("modelnameforindex: model not precached\n");
2737 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2740 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2741 static void VM_SV_particleeffectnum (void)
2744 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2745 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2748 PRVM_G_FLOAT(OFS_RETURN) = i;
2751 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2752 static void VM_SV_trailparticles (void)
2754 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2756 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2759 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2760 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2761 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2762 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2763 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2764 SV_FlushBroadcastMessages();
2767 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2768 static void VM_SV_pointparticles (void)
2770 int effectnum, count;
2772 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2774 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2777 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2778 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2779 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2780 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2781 if (count == 1 && !VectorLength2(vel))
2784 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2785 MSG_WriteShort(&sv.datagram, effectnum);
2786 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2790 // 1+2+12+12+2=29 bytes
2791 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2792 MSG_WriteShort(&sv.datagram, effectnum);
2793 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2794 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2795 MSG_WriteShort(&sv.datagram, count);
2798 SV_FlushBroadcastMessages();
2801 //PF_setpause, // void(float pause) setpause = #531;
2802 static void VM_SV_setpause(void) {
2804 pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
2805 if (pauseValue != 0) { //pause the game
2807 sv.pausedstart = Sys_DoubleTime();
2808 } else { //disable pause, in case it was enabled
2809 if (sv.paused != 0) {
2814 // send notification to all clients
2815 MSG_WriteByte(&sv.reliable_datagram, svc_setpause);
2816 MSG_WriteByte(&sv.reliable_datagram, sv.paused);
2819 // #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.
2820 static void VM_SV_skel_create(void)
2822 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
2823 dp_model_t *model = SV_GetModelByIndex(modelindex);
2824 skeleton_t *skeleton;
2826 PRVM_G_FLOAT(OFS_RETURN) = 0;
2827 if (!model || !model->num_bones)
2829 for (i = 0;i < MAX_EDICTS;i++)
2830 if (!prog->skeletons[i])
2832 if (i == MAX_EDICTS)
2834 prog->skeletons[i] = skeleton = Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
2835 PRVM_G_FLOAT(OFS_RETURN) = i + 1;
2836 skeleton->model = model;
2837 skeleton->relativetransforms = (matrix4x4_t *)(skeleton+1);
2838 // initialize to identity matrices
2839 for (i = 0;i < skeleton->model->num_bones;i++)
2840 skeleton->relativetransforms[i] = identitymatrix;
2843 // #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
2844 static void VM_SV_skel_build(void)
2846 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2847 skeleton_t *skeleton;
2848 prvm_edict_t *ed = PRVM_G_EDICT(OFS_PARM1);
2849 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM2);
2850 float retainfrac = PRVM_G_FLOAT(OFS_PARM3);
2851 int firstbone = PRVM_G_FLOAT(OFS_PARM4) - 1;
2852 int lastbone = PRVM_G_FLOAT(OFS_PARM5) - 1;
2853 dp_model_t *model = SV_GetModelByIndex(modelindex);
2858 framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS];
2859 frameblend_t frameblend[MAX_FRAMEBLENDS];
2860 matrix4x4_t blendedmatrix;
2862 PRVM_G_FLOAT(OFS_RETURN) = 0;
2863 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2865 firstbone = max(0, firstbone);
2866 lastbone = min(lastbone, model->num_bones - 1);
2867 lastbone = min(lastbone, skeleton->model->num_bones - 1);
2868 VM_GenerateFrameGroupBlend(framegroupblend, ed);
2869 VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model);
2870 blendfrac = 1.0f - retainfrac;
2871 for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
2872 frameblend[numblends].lerp *= blendfrac;
2873 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
2875 memset(&blendedmatrix, 0, sizeof(blendedmatrix));
2876 Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac);
2877 for (blendindex = 0;blendindex < numblends;blendindex++)
2879 Matrix4x4_FromBonePose6s(&matrix, model->num_posescale, model->data_poses6s + 6 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
2880 Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp);
2882 skeleton->relativetransforms[bonenum] = blendedmatrix;
2884 PRVM_G_FLOAT(OFS_RETURN) = skeletonindex + 1;
2887 // #265 float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS) returns how many bones exist in the created skeleton
2888 static void VM_SV_skel_get_numbones(void)
2890 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2891 skeleton_t *skeleton;
2892 PRVM_G_FLOAT(OFS_RETURN) = 0;
2893 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2895 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->num_bones;
2898 // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) returns name of bone (as a tempstring)
2899 static void VM_SV_skel_get_bonename(void)
2901 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2902 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2903 skeleton_t *skeleton;
2904 PRVM_G_INT(OFS_RETURN) = 0;
2905 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2907 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2909 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(skeleton->model->data_bones[bonenum].name);
2912 // #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)
2913 static void VM_SV_skel_get_boneparent(void)
2915 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2916 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2917 skeleton_t *skeleton;
2918 PRVM_G_FLOAT(OFS_RETURN) = 0;
2919 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2921 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2923 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->data_bones[bonenum].parent + 1;
2926 // #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
2927 static void VM_SV_skel_find_bone(void)
2929 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2930 const char *tagname = PRVM_G_STRING(OFS_PARM1);
2931 skeleton_t *skeleton;
2932 PRVM_G_FLOAT(OFS_RETURN) = 0;
2933 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2935 PRVM_G_FLOAT(OFS_RETURN) = Mod_Alias_GetTagIndexForName(skeleton->model, 0, tagname) + 1;
2938 // #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)
2939 static void VM_SV_skel_get_bonerel(void)
2941 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2942 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2943 skeleton_t *skeleton;
2945 vec3_t forward, left, up, origin;
2946 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2947 VectorClear(prog->globals.client->v_forward);
2948 VectorClear(prog->globals.client->v_right);
2949 VectorClear(prog->globals.client->v_up);
2950 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2952 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2954 matrix = skeleton->relativetransforms[bonenum];
2955 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2956 VectorCopy(forward, prog->globals.client->v_forward);
2957 VectorNegate(left, prog->globals.client->v_right);
2958 VectorCopy(up, prog->globals.client->v_up);
2959 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
2962 // #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)
2963 static void VM_SV_skel_get_boneabs(void)
2965 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2966 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2967 skeleton_t *skeleton;
2970 vec3_t forward, left, up, origin;
2971 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2972 VectorClear(prog->globals.client->v_forward);
2973 VectorClear(prog->globals.client->v_right);
2974 VectorClear(prog->globals.client->v_up);
2975 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2977 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2979 matrix = skeleton->relativetransforms[bonenum];
2980 // convert to absolute
2981 while ((bonenum = skeleton->model->data_bones[bonenum].parent) >= 0)
2984 Matrix4x4_Concat(&matrix, &skeleton->relativetransforms[bonenum], &temp);
2986 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2987 VectorCopy(forward, prog->globals.client->v_forward);
2988 VectorNegate(left, prog->globals.client->v_right);
2989 VectorCopy(up, prog->globals.client->v_up);
2990 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
2993 // #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)
2994 static void VM_SV_skel_set_bone(void)
2996 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2997 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2998 vec3_t forward, left, up, origin;
2999 skeleton_t *skeleton;
3001 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3003 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3005 VectorCopy(prog->globals.client->v_forward, forward);
3006 VectorNegate(prog->globals.client->v_right, left);
3007 VectorCopy(prog->globals.client->v_up, up);
3008 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3009 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3010 skeleton->relativetransforms[bonenum] = matrix;
3013 // #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)
3014 static void VM_SV_skel_mul_bone(void)
3016 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3017 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3018 vec3_t forward, left, up, origin;
3019 skeleton_t *skeleton;
3022 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3024 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3026 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3027 VectorCopy(prog->globals.client->v_forward, forward);
3028 VectorNegate(prog->globals.client->v_right, left);
3029 VectorCopy(prog->globals.client->v_up, up);
3030 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3031 temp = skeleton->relativetransforms[bonenum];
3032 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3035 // #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)
3036 static void VM_SV_skel_mul_bones(void)
3038 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3039 int firstbone = PRVM_G_FLOAT(OFS_PARM1) - 1;
3040 int lastbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3042 vec3_t forward, left, up, origin;
3043 skeleton_t *skeleton;
3046 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3048 VectorCopy(PRVM_G_VECTOR(OFS_PARM3), origin);
3049 VectorCopy(prog->globals.client->v_forward, forward);
3050 VectorNegate(prog->globals.client->v_right, left);
3051 VectorCopy(prog->globals.client->v_up, up);
3052 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3053 firstbone = max(0, firstbone);
3054 lastbone = min(lastbone, skeleton->model->num_bones - 1);
3055 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3057 temp = skeleton->relativetransforms[bonenum];
3058 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3062 // #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
3063 static void VM_SV_skel_copybones(void)
3065 int skeletonindexdst = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3066 int skeletonindexsrc = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3067 int firstbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3068 int lastbone = PRVM_G_FLOAT(OFS_PARM3) - 1;
3070 skeleton_t *skeletondst;
3071 skeleton_t *skeletonsrc;
3072 if (skeletonindexdst < 0 || skeletonindexdst >= MAX_EDICTS || !(skeletondst = prog->skeletons[skeletonindexdst]))
3074 if (skeletonindexsrc < 0 || skeletonindexsrc >= MAX_EDICTS || !(skeletonsrc = prog->skeletons[skeletonindexsrc]))
3076 firstbone = max(0, firstbone);
3077 lastbone = min(lastbone, skeletondst->model->num_bones - 1);
3078 lastbone = min(lastbone, skeletonsrc->model->num_bones - 1);
3079 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3080 skeletondst->relativetransforms[bonenum] = skeletonsrc->relativetransforms[bonenum];
3083 // #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)
3084 static void VM_SV_skel_delete(void)
3086 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3087 skeleton_t *skeleton;
3088 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3091 prog->skeletons[skeletonindex] = NULL;
3094 // #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
3095 static void VM_SV_frameforname(void)
3097 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3098 dp_model_t *model = SV_GetModelByIndex(modelindex);
3099 const char *name = PRVM_G_STRING(OFS_PARM1);
3101 PRVM_G_FLOAT(OFS_RETURN) = -1;
3102 if (!model || !model->animscenes)
3104 for (i = 0;i < model->numframes;i++)
3106 if (!strcasecmp(model->animscenes[i].name, name))
3108 PRVM_G_FLOAT(OFS_RETURN) = i;
3114 // #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.
3115 static void VM_SV_frameduration(void)
3117 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3118 dp_model_t *model = SV_GetModelByIndex(modelindex);
3119 int framenum = (int)PRVM_G_FLOAT(OFS_PARM1);
3120 PRVM_G_FLOAT(OFS_RETURN) = 0;
3121 if (!model || !model->animscenes || framenum < 0 || framenum >= model->numframes)
3123 if (model->animscenes[framenum].framerate)
3124 PRVM_G_FLOAT(OFS_RETURN) = model->animscenes[framenum].framecount / model->animscenes[framenum].framerate;
3128 prvm_builtin_t vm_sv_builtins[] = {
3129 NULL, // #0 NULL function (not callable) (QUAKE)
3130 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
3131 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
3132 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
3133 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
3134 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
3135 VM_break, // #6 void() break (QUAKE)
3136 VM_random, // #7 float() random (QUAKE)
3137 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
3138 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
3139 VM_error, // #10 void(string e) error (QUAKE)
3140 VM_objerror, // #11 void(string e) objerror (QUAKE)
3141 VM_vlen, // #12 float(vector v) vlen (QUAKE)
3142 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
3143 VM_spawn, // #14 entity() spawn (QUAKE)
3144 VM_remove, // #15 void(entity e) remove (QUAKE)
3145 VM_SV_traceline, // #16 void(vector v1, vector v2, float tryents) traceline (QUAKE)
3146 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
3147 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
3148 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
3149 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
3150 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
3151 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
3152 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
3153 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
3154 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
3155 VM_ftos, // #26 string(float f) ftos (QUAKE)
3156 VM_vtos, // #27 string(vector v) vtos (QUAKE)
3157 VM_coredump, // #28 void() coredump (QUAKE)
3158 VM_traceon, // #29 void() traceon (QUAKE)
3159 VM_traceoff, // #30 void() traceoff (QUAKE)
3160 VM_eprint, // #31 void(entity e) eprint (QUAKE)
3161 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
3162 NULL, // #33 (QUAKE)
3163 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
3164 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
3165 VM_rint, // #36 float(float v) rint (QUAKE)
3166 VM_floor, // #37 float(float v) floor (QUAKE)
3167 VM_ceil, // #38 float(float v) ceil (QUAKE)
3168 NULL, // #39 (QUAKE)
3169 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
3170 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
3171 NULL, // #42 (QUAKE)
3172 VM_fabs, // #43 float(float f) fabs (QUAKE)
3173 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
3174 VM_cvar, // #45 float(string s) cvar (QUAKE)
3175 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
3176 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
3177 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
3178 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
3179 NULL, // #50 (QUAKE)
3180 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
3181 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
3182 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
3183 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
3184 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
3185 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
3186 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
3187 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
3188 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
3189 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
3190 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
3191 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
3192 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
3193 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
3194 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
3195 NULL, // #66 (QUAKE)
3196 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
3197 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
3198 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
3199 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
3200 NULL, // #71 (QUAKE)
3201 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
3202 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
3203 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
3204 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
3205 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
3206 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
3207 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
3208 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
3209 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
3210 VM_stof, // #81 float(string s) stof (FRIK_FILE)
3211 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
3212 NULL, // #83 (QUAKE)
3213 NULL, // #84 (QUAKE)
3214 NULL, // #85 (QUAKE)
3215 NULL, // #86 (QUAKE)
3216 NULL, // #87 (QUAKE)
3217 NULL, // #88 (QUAKE)
3218 NULL, // #89 (QUAKE)
3219 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
3220 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
3221 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
3222 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
3223 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
3224 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3225 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3226 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3227 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3228 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3229 // FrikaC and Telejano range #100-#199
3240 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3241 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3242 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3243 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3244 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3245 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3246 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3247 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3248 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3249 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3330 // FTEQW range #200-#299
3349 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3352 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3353 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3354 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3355 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3356 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3357 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3358 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3359 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3360 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3361 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3363 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3371 VM_SV_checkpvs, // #240 float(vector viewpos, entity viewee) checkpvs;
3394 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.
3395 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
3396 VM_SV_skel_get_numbones, // #265 float(float skel) skel_get_numbones = #265; // (DP_SKELETONOBJECTS) returns how many bones exist in the created skeleton
3397 VM_SV_skel_get_bonename, // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (DP_SKELETONOBJECTS) returns name of bone (as a tempstring)
3398 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)
3399 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
3400 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)
3401 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)
3402 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)
3403 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)
3404 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)
3405 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
3406 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)
3407 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
3408 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.
3431 // CSQC range #300-#399
3432 NULL, // #300 void() clearscene (EXT_CSQC)
3433 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3434 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3435 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3436 NULL, // #304 void() renderscene (EXT_CSQC)
3437 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3438 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3439 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3440 NULL, // #308 void() R_EndPolygon
3442 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3443 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3447 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3448 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3449 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3450 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3451 NULL, // #319 void(string name) freepic (EXT_CSQC)
3452 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3453 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3454 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3455 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3456 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3457 NULL, // #325 void(void) drawresetcliparea
3462 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3463 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3464 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3465 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3466 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3467 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3468 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3469 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3470 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3471 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3472 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3473 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3474 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3475 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3476 NULL, // #344 vector() getmousepos (EXT_CSQC)
3477 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3478 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3479 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3480 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3481 NULL, // #349 float() isdemo (EXT_CSQC)
3482 VM_isserver, // #350 float() isserver (EXT_CSQC)
3483 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3484 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3485 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3486 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3492 NULL, // #360 float() readbyte (EXT_CSQC)
3493 NULL, // #361 float() readchar (EXT_CSQC)
3494 NULL, // #362 float() readshort (EXT_CSQC)
3495 NULL, // #363 float() readlong (EXT_CSQC)
3496 NULL, // #364 float() readcoord (EXT_CSQC)
3497 NULL, // #365 float() readangle (EXT_CSQC)
3498 NULL, // #366 string() readstring (EXT_CSQC)
3499 NULL, // #367 float() readfloat (EXT_CSQC)
3532 // LordHavoc's range #400-#499
3533 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3534 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3535 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3536 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3537 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3538 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3539 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3540 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3541 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)
3542 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3543 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3544 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3545 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3546 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3547 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3548 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3549 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3550 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3551 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3552 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3553 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3554 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3555 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3556 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3557 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3558 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3559 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3560 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3561 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3562 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3563 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3564 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3565 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3566 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3567 VM_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3568 VM_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3569 VM_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3570 VM_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3571 VM_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3572 VM_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3573 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3574 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3575 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3576 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3577 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3578 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3579 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3580 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3581 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3582 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3583 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3584 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3585 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3586 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3587 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3588 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3589 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3590 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3592 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3593 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3594 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3595 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3596 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3597 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3598 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3599 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3600 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3601 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3602 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3604 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3605 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3606 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3607 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3608 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3609 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3610 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3611 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3612 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3613 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3614 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3615 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3616 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3617 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3618 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3619 VM_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3627 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3628 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3629 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3630 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3631 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3632 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3633 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3634 VM_SV_WritePicture, // #501
3636 VM_whichpack, // #503 string(string) whichpack = #503;
3643 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3644 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3645 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3646 VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3647 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3648 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3649 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3650 VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
3651 VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
3652 VM_gettime, // #519 float(float timer) gettime = #519; (DP_QC_GETTIME)
3662 VM_loadfromdata, // #529
3663 VM_loadfromfile, // #530
3664 VM_SV_setpause, // #531 void(float pause) setpause = #531;
3666 VM_getsoundtime, // #533 float(entity e, float channel) getsoundtime = #533; (DP_SND_GETSOUNDTIME)
3667 VM_soundlength, // #534 float(string sample) soundlength = #534; (DP_SND_GETSOUNDTIME)
3738 VM_callfunction, // #605
3739 VM_writetofile, // #606
3740 VM_isfunction, // #607
3746 VM_parseentitydata, // #613
3757 VM_SV_getextresponse, // #624 string getextresponse(void)
3760 VM_sprintf, // #627 string sprintf(string format, ...)
3761 VM_getsurfacenumtriangles, // #628 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACETRIANGLE)
3762 VM_getsurfacetriangle, // #629 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACETRIANGLE)
3766 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3768 void VM_SV_Cmd_Init(void)
3773 void VM_SV_Cmd_Reset(void)
3775 World_End(&sv.world);
3776 if(prog->funcoffsets.SV_Shutdown)
3778 func_t s = prog->funcoffsets.SV_Shutdown;
3779 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3780 PRVM_ExecuteProgram(s,"SV_Shutdown() required");