6 //============================================================================
11 char *vm_sv_extensions =
16 "DP_CON_ALIASPARAMETERS "
24 "DP_CSQC_ENTITYNOCULL "
25 "DP_CSQC_ENTITYTRANSPARENTSORTING_OFFSET "
26 "DP_CSQC_MULTIFRAME_INTERPOLATION "
27 "DP_CSQC_BOXPARTICLES "
28 "DP_CSQC_SPAWNPARTICLE "
29 "DP_CSQC_QUERYRENDERENTITY "
42 "DP_EF_RESTARTANIM_BIT "
47 "DP_ENT_CUSTOMCOLORMAP "
48 "DP_ENT_EXTERIORMODELTOCLIENT "
51 "DP_ENT_LOWPRECISION "
55 "DP_GFX_EXTERNALTEXTURES "
56 "DP_GFX_EXTERNALTEXTURES_PERMAP "
58 "DP_GFX_MODEL_INTERPOLATION "
59 "DP_GFX_QUAKE3MODELTAGS "
63 "DP_GFX_FONTS_FREETYPE "
65 "DP_FONT_VARIABLEWIDTH "
67 "DP_HALFLIFE_MAP_CVAR "
70 "DP_LIGHTSTYLE_STATICVALUE "
74 "DP_MOVETYPEBOUNCEMISSILE "
77 "DP_QC_ASINACOSATANATAN2TAN "
83 "DP_QC_CVAR_DEFSTRING "
84 "DP_QC_CVAR_DESCRIPTION "
91 "DP_QC_EXTRESPONSEPACKET "
93 "DP_QC_FINDCHAINFLAGS "
94 "DP_QC_FINDCHAINFLOAT "
95 "DP_QC_FINDCHAIN_TOFIELD "
101 "DP_QC_GETSURFACETRIANGLE "
102 "DP_QC_GETSURFACEPOINTATTRIBUTE "
104 "DP_QC_GETTAGINFO_BONEPROPERTIES "
106 "DP_QC_GETTIME_CDTRACK "
109 "DP_QC_MULTIPLETEMPSTRINGS "
110 "DP_QC_NUM_FOR_EDICT "
112 "DP_QC_SINCOSSQRTPOW "
115 "DP_QC_STRINGBUFFERS "
116 "DP_QC_STRINGBUFFERS_CVARLIST "
117 "DP_QC_STRINGCOLORFUNCTIONS "
118 "DP_QC_STRING_CASE_FUNCTIONS "
120 "DP_QC_TOKENIZEBYSEPARATOR "
121 "DP_QC_TOKENIZE_CONSOLE "
124 "DP_QC_TRACE_MOVETYPE_HITMODEL "
125 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
126 "DP_QC_UNLIMITEDTEMPSTRINGS "
129 "DP_QC_VECTOANGLES_WITH_ROLL "
130 "DP_QC_VECTORVECTORS "
137 "DP_SKELETONOBJECTS "
138 "DP_SND_DIRECTIONLESSATTNNONE "
143 "DP_SND_GETSOUNDTIME "
145 "DP_VIDEO_SUBTITLES "
149 "DP_SV_BOUNCEFACTOR "
150 "DP_SV_CLIENTCAMERA "
151 "DP_SV_CLIENTCOLORS "
154 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
155 "DP_SV_DISCARDABLEDEMO "
156 "DP_SV_DRAWONLYTOCLIENT "
159 "DP_SV_ENTITYCONTENTSTRANSITION "
160 "DP_SV_MODELFLAGS_AS_EFFECTS "
161 "DP_SV_MOVETYPESTEP_LANDEVENT "
163 "DP_SV_NODRAWTOCLIENT "
164 "DP_SV_ONENTITYNOSPAWNFUNCTION "
165 "DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
167 "DP_SV_PING_PACKETLOSS "
168 "DP_SV_PLAYERPHYSICS "
169 "DP_SV_POINTPARTICLES "
171 "DP_SV_PRECACHEANYTIME "
175 "DP_SV_ROTATINGBMODEL "
179 "DP_SV_SPAWNFUNC_PREFIX "
180 "DP_SV_WRITEPICTURE "
181 "DP_SV_WRITEUNTERMINATEDSTRING "
185 "DP_TE_EXPLOSIONRGB "
187 "DP_TE_PARTICLECUBE "
188 "DP_TE_PARTICLERAIN "
189 "DP_TE_PARTICLESNOW "
191 "DP_TE_QUADEFFECTS1 "
194 "DP_TE_STANDARDEFFECTBUILTINS "
195 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
199 "FTE_CSQC_SKELETONOBJECTS "
202 "KRIMZON_SV_PARSECLIENTCOMMAND "
205 "NEXUIZ_PLAYERMODEL "
207 "PRYDON_CLIENTCURSOR "
208 "TENEBRAE_GFX_DLIGHTS "
211 //"EXT_CSQC " // not ready yet
218 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.
220 setorigin (entity, origin)
223 static void VM_SV_setorigin (void)
228 VM_SAFEPARMCOUNT(2, VM_setorigin);
230 e = PRVM_G_EDICT(OFS_PARM0);
231 if (e == prog->edicts)
233 VM_Warning("setorigin: can not modify world entity\n");
236 if (e->priv.server->free)
238 VM_Warning("setorigin: can not modify free entity\n");
241 org = PRVM_G_VECTOR(OFS_PARM1);
242 VectorCopy (org, e->fields.server->origin);
246 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
247 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
251 for (i=0 ; i<3 ; i++)
253 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
255 // set derived values
256 VectorCopy (min, e->fields.server->mins);
257 VectorCopy (max, e->fields.server->maxs);
258 VectorSubtract (max, min, e->fields.server->size);
267 the size box is rotated by the current angle
268 LordHavoc: no it isn't...
270 setsize (entity, minvector, maxvector)
273 static void VM_SV_setsize (void)
278 VM_SAFEPARMCOUNT(3, VM_setsize);
280 e = PRVM_G_EDICT(OFS_PARM0);
281 if (e == prog->edicts)
283 VM_Warning("setsize: can not modify world entity\n");
286 if (e->priv.server->free)
288 VM_Warning("setsize: can not modify free entity\n");
291 min = PRVM_G_VECTOR(OFS_PARM1);
292 max = PRVM_G_VECTOR(OFS_PARM2);
293 SetMinMaxSize (e, min, max, false);
301 setmodel(entity, model)
304 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
305 static void VM_SV_setmodel (void)
311 VM_SAFEPARMCOUNT(2, VM_setmodel);
313 e = PRVM_G_EDICT(OFS_PARM0);
314 if (e == prog->edicts)
316 VM_Warning("setmodel: can not modify world entity\n");
319 if (e->priv.server->free)
321 VM_Warning("setmodel: can not modify free entity\n");
324 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
325 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
326 e->fields.server->modelindex = i;
328 mod = SV_GetModelByIndex(i);
332 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
333 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
335 SetMinMaxSize (e, quakemins, quakemaxs, true);
338 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
345 single print to a specific client
347 sprint(clientent, value)
350 static void VM_SV_sprint (void)
354 char string[VM_STRINGTEMP_LENGTH];
356 VM_VarString(1, string, sizeof(string));
358 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
360 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
361 // LordHavoc: div0 requested that sprintto world operate like print
368 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
370 VM_Warning("tried to centerprint to a non-client\n");
374 client = svs.clients + entnum-1;
375 if (!client->netconnection)
378 MSG_WriteChar(&client->netconnection->message,svc_print);
379 MSG_WriteString(&client->netconnection->message, string);
387 single print to a specific client
389 centerprint(clientent, value)
392 static void VM_SV_centerprint (void)
396 char string[VM_STRINGTEMP_LENGTH];
398 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
400 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
402 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
404 VM_Warning("tried to centerprint to a non-client\n");
408 client = svs.clients + entnum-1;
409 if (!client->netconnection)
412 VM_VarString(1, string, sizeof(string));
413 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
414 MSG_WriteString(&client->netconnection->message, string);
421 particle(origin, color, count)
424 static void VM_SV_particle (void)
430 VM_SAFEPARMCOUNT(4, VM_SV_particle);
432 org = PRVM_G_VECTOR(OFS_PARM0);
433 dir = PRVM_G_VECTOR(OFS_PARM1);
434 color = PRVM_G_FLOAT(OFS_PARM2);
435 count = PRVM_G_FLOAT(OFS_PARM3);
436 SV_StartParticle (org, dir, (int)color, (int)count);
446 static void VM_SV_ambientsound (void)
450 float vol, attenuation;
453 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
455 pos = PRVM_G_VECTOR (OFS_PARM0);
456 samp = PRVM_G_STRING(OFS_PARM1);
457 vol = PRVM_G_FLOAT(OFS_PARM2);
458 attenuation = PRVM_G_FLOAT(OFS_PARM3);
460 // check to see if samp was properly precached
461 soundnum = SV_SoundIndex(samp, 1);
469 // add an svc_spawnambient command to the level signon packet
472 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
474 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
476 MSG_WriteVector(&sv.signon, pos, sv.protocol);
478 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
479 MSG_WriteShort (&sv.signon, soundnum);
481 MSG_WriteByte (&sv.signon, soundnum);
483 MSG_WriteByte (&sv.signon, (int)(vol*255));
484 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
492 Each entity can have eight independant sound sources, like voice,
495 Channel 0 is an auto-allocate channel, the others override anything
496 already running on that entity/channel pair.
498 An attenuation of 0 will play full volume everywhere in the level.
499 Larger attenuations will drop off.
503 static void VM_SV_sound (void)
507 prvm_edict_t *entity;
511 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
513 entity = PRVM_G_EDICT(OFS_PARM0);
514 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
515 sample = PRVM_G_STRING(OFS_PARM2);
516 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
517 attenuation = PRVM_G_FLOAT(OFS_PARM4);
520 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
524 if (volume < 0 || volume > 255)
526 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
530 if (attenuation < 0 || attenuation > 4)
532 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
536 if (channel < 0 || channel > 7)
538 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
542 SV_StartSound (entity, channel, sample, volume, attenuation);
549 Follows the same logic as VM_SV_sound, except instead of
550 an entity, an origin for the sound is provided, and channel
551 is omitted (since no entity is being tracked).
555 static void VM_SV_pointsound(void)
562 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
564 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
565 sample = PRVM_G_STRING(OFS_PARM1);
566 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
567 attenuation = PRVM_G_FLOAT(OFS_PARM3);
569 if (volume < 0 || volume > 255)
571 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
575 if (attenuation < 0 || attenuation > 4)
577 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
581 SV_StartPointSound (org, sample, volume, attenuation);
588 Used for use tracing and shot targeting
589 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
590 if the tryents flag is set.
592 traceline (vector1, vector2, movetype, ignore)
595 static void VM_SV_traceline (void)
602 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
604 prog->xfunction->builtinsprofile += 30;
606 v1 = PRVM_G_VECTOR(OFS_PARM0);
607 v2 = PRVM_G_VECTOR(OFS_PARM1);
608 move = (int)PRVM_G_FLOAT(OFS_PARM2);
609 ent = PRVM_G_EDICT(OFS_PARM3);
611 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]))
612 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));
614 trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
616 VM_SetTraceGlobals(&trace);
624 Used for use tracing and shot targeting
625 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
626 if the tryents flag is set.
628 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
631 // LordHavoc: added this for my own use, VERY useful, similar to traceline
632 static void VM_SV_tracebox (void)
634 float *v1, *v2, *m1, *m2;
639 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
641 prog->xfunction->builtinsprofile += 30;
643 v1 = PRVM_G_VECTOR(OFS_PARM0);
644 m1 = PRVM_G_VECTOR(OFS_PARM1);
645 m2 = PRVM_G_VECTOR(OFS_PARM2);
646 v2 = PRVM_G_VECTOR(OFS_PARM3);
647 move = (int)PRVM_G_FLOAT(OFS_PARM4);
648 ent = PRVM_G_EDICT(OFS_PARM5);
650 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]))
651 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));
653 trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
655 VM_SetTraceGlobals(&trace);
658 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
663 vec3_t original_origin;
664 vec3_t original_velocity;
665 vec3_t original_angles;
666 vec3_t original_avelocity;
670 VectorCopy(tossent->fields.server->origin , original_origin );
671 VectorCopy(tossent->fields.server->velocity , original_velocity );
672 VectorCopy(tossent->fields.server->angles , original_angles );
673 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
675 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
676 if (val != NULL && val->_float != 0)
677 gravity = val->_float;
680 gravity *= sv_gravity.value * 0.025;
682 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
684 SV_CheckVelocity (tossent);
685 tossent->fields.server->velocity[2] -= gravity;
686 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
687 VectorScale (tossent->fields.server->velocity, 0.05, move);
688 VectorAdd (tossent->fields.server->origin, move, end);
689 trace = SV_TraceBox(tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
690 VectorCopy (trace.endpos, tossent->fields.server->origin);
691 tossent->fields.server->velocity[2] -= gravity;
693 if (trace.fraction < 1)
697 VectorCopy(original_origin , tossent->fields.server->origin );
698 VectorCopy(original_velocity , tossent->fields.server->velocity );
699 VectorCopy(original_angles , tossent->fields.server->angles );
700 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
705 static void VM_SV_tracetoss (void)
709 prvm_edict_t *ignore;
711 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
713 prog->xfunction->builtinsprofile += 600;
715 ent = PRVM_G_EDICT(OFS_PARM0);
716 if (ent == prog->edicts)
718 VM_Warning("tracetoss: can not use world entity\n");
721 ignore = PRVM_G_EDICT(OFS_PARM1);
723 trace = SV_Trace_Toss (ent, ignore);
725 VM_SetTraceGlobals(&trace);
728 //============================================================================
730 static int checkpvsbytes;
731 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
733 static int VM_SV_newcheckclient (int check)
739 // cycle to the next one
741 check = bound(1, check, svs.maxclients);
742 if (check == svs.maxclients)
750 prog->xfunction->builtinsprofile++;
752 if (i == svs.maxclients+1)
754 // look up the client's edict
755 ent = PRVM_EDICT_NUM(i);
756 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
757 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
759 // found a valid client (possibly the same one again)
763 // get the PVS for the entity
764 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
766 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
767 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
776 Returns a client (or object that has a client enemy) that would be a
779 If there is more than one valid option, they are cycled each frame
781 If (self.origin + self.viewofs) is not in the PVS of the current target,
782 it is not returned at all.
787 int c_invis, c_notvis;
788 static void VM_SV_checkclient (void)
790 prvm_edict_t *ent, *self;
793 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
795 // find a new check if on a new frame
796 if (sv.time - sv.lastchecktime >= 0.1)
798 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
799 sv.lastchecktime = sv.time;
802 // return check if it might be visible
803 ent = PRVM_EDICT_NUM(sv.lastcheck);
804 if (ent->priv.server->free || ent->fields.server->health <= 0)
806 VM_RETURN_EDICT(prog->edicts);
810 // if current entity can't possibly see the check entity, return 0
811 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
812 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
813 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
816 VM_RETURN_EDICT(prog->edicts);
820 // might be able to see it
822 VM_RETURN_EDICT(ent);
825 //============================================================================
831 Checks if an entity is in a point's PVS.
832 Should be fast but can be inexact.
834 float checkpvs(vector viewpos, entity viewee) = #240;
837 static void VM_SV_checkpvs (void)
840 prvm_edict_t *viewee;
845 unsigned char fatpvs[MAX_MAP_LEAFS/8];
848 VM_SAFEPARMCOUNT(2, VM_SV_checkpvs);
849 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos);
850 viewee = PRVM_G_EDICT(OFS_PARM1);
852 if(viewee->priv.server->free)
854 VM_Warning("checkpvs: can not check free entity\n");
855 PRVM_G_FLOAT(OFS_RETURN) = 4;
860 if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
862 // no PVS support on this worldmodel... darn
863 PRVM_G_FLOAT(OFS_RETURN) = 3;
866 pvs = sv.worldmodel->brush.GetPVS(sv.worldmodel, viewpos);
869 // viewpos isn't in any PVS... darn
870 PRVM_G_FLOAT(OFS_RETURN) = 2;
873 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
875 // using fat PVS like FTEQW does (slow)
876 if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
878 // no PVS support on this worldmodel... darn
879 PRVM_G_FLOAT(OFS_RETURN) = 3;
882 fatpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
885 // viewpos isn't in any PVS... darn
886 PRVM_G_FLOAT(OFS_RETURN) = 2;
889 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
898 Sends text over to the client's execution buffer
900 stuffcmd (clientent, value, ...)
903 static void VM_SV_stuffcmd (void)
907 char string[VM_STRINGTEMP_LENGTH];
909 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
911 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
912 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
914 VM_Warning("Can't stuffcmd to a non-client\n");
918 VM_VarString(1, string, sizeof(string));
921 host_client = svs.clients + entnum-1;
922 Host_ClientCommands ("%s", string);
930 Returns a chain of entities that have origins within a spherical area
932 findradius (origin, radius)
935 static void VM_SV_findradius (void)
937 prvm_edict_t *ent, *chain;
938 vec_t radius, radius2;
939 vec3_t org, eorg, mins, maxs;
942 static prvm_edict_t *touchedicts[MAX_EDICTS];
945 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findradius);
948 chainfield = PRVM_G_INT(OFS_PARM2);
950 chainfield = prog->fieldoffsets.chain;
952 PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
954 chain = (prvm_edict_t *)prog->edicts;
956 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
957 radius = PRVM_G_FLOAT(OFS_PARM1);
958 radius2 = radius * radius;
960 mins[0] = org[0] - (radius + 1);
961 mins[1] = org[1] - (radius + 1);
962 mins[2] = org[2] - (radius + 1);
963 maxs[0] = org[0] + (radius + 1);
964 maxs[1] = org[1] + (radius + 1);
965 maxs[2] = org[2] + (radius + 1);
966 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
967 if (numtouchedicts > MAX_EDICTS)
969 // this never happens
970 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
971 numtouchedicts = MAX_EDICTS;
973 for (i = 0;i < numtouchedicts;i++)
975 ent = touchedicts[i];
976 prog->xfunction->builtinsprofile++;
977 // Quake did not return non-solid entities but darkplaces does
978 // (note: this is the reason you can't blow up fallen zombies)
979 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
981 // LordHavoc: compare against bounding box rather than center so it
982 // doesn't miss large objects, and use DotProduct instead of Length
983 // for a major speedup
984 VectorSubtract(org, ent->fields.server->origin, eorg);
985 if (sv_gameplayfix_findradiusdistancetobox.integer)
987 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
988 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
989 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
992 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
993 if (DotProduct(eorg, eorg) < radius2)
995 PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
1000 VM_RETURN_EDICT(chain);
1003 static void VM_SV_precache_sound (void)
1005 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
1006 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
1009 static void VM_SV_precache_model (void)
1011 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
1012 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
1013 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
1020 float(float yaw, float dist[, settrace]) walkmove
1023 static void VM_SV_walkmove (void)
1032 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
1034 // assume failure if it returns early
1035 PRVM_G_FLOAT(OFS_RETURN) = 0;
1037 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1038 if (ent == prog->edicts)
1040 VM_Warning("walkmove: can not modify world entity\n");
1043 if (ent->priv.server->free)
1045 VM_Warning("walkmove: can not modify free entity\n");
1048 yaw = PRVM_G_FLOAT(OFS_PARM0);
1049 dist = PRVM_G_FLOAT(OFS_PARM1);
1050 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
1052 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1055 yaw = yaw*M_PI*2 / 360;
1057 move[0] = cos(yaw)*dist;
1058 move[1] = sin(yaw)*dist;
1061 // save program state, because SV_movestep may call other progs
1062 oldf = prog->xfunction;
1063 oldself = prog->globals.server->self;
1065 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
1068 // restore program state
1069 prog->xfunction = oldf;
1070 prog->globals.server->self = oldself;
1080 static void VM_SV_droptofloor (void)
1086 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
1088 // assume failure if it returns early
1089 PRVM_G_FLOAT(OFS_RETURN) = 0;
1091 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1092 if (ent == prog->edicts)
1094 VM_Warning("droptofloor: can not modify world entity\n");
1097 if (ent->priv.server->free)
1099 VM_Warning("droptofloor: can not modify free entity\n");
1103 VectorCopy (ent->fields.server->origin, end);
1106 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
1107 SV_UnstickEntity(ent);
1109 trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1110 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
1113 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]);
1114 VectorAdd(ent->fields.server->origin, offset, org);
1115 trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1116 VectorSubtract(trace.endpos, offset, trace.endpos);
1117 if (trace.startsolid)
1119 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]);
1120 SV_UnstickEntity(ent);
1122 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1123 ent->fields.server->groundentity = 0;
1124 PRVM_G_FLOAT(OFS_RETURN) = 1;
1126 else if (trace.fraction < 1)
1128 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]);
1129 VectorCopy (trace.endpos, ent->fields.server->origin);
1130 SV_UnstickEntity(ent);
1132 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1133 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1134 PRVM_G_FLOAT(OFS_RETURN) = 1;
1135 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1136 ent->priv.server->suspendedinairflag = true;
1141 if (trace.fraction != 1)
1143 if (trace.fraction < 1)
1144 VectorCopy (trace.endpos, ent->fields.server->origin);
1146 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1147 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1148 PRVM_G_FLOAT(OFS_RETURN) = 1;
1149 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1150 ent->priv.server->suspendedinairflag = true;
1159 void(float style, string value) lightstyle
1162 static void VM_SV_lightstyle (void)
1169 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1171 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1172 val = PRVM_G_STRING(OFS_PARM1);
1174 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1175 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1178 // change the string in sv
1179 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1181 // send message to all clients on this server
1182 if (sv.state != ss_active)
1185 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1187 if (client->active && client->netconnection)
1189 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1190 MSG_WriteChar (&client->netconnection->message,style);
1191 MSG_WriteString (&client->netconnection->message, val);
1201 static void VM_SV_checkbottom (void)
1203 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1204 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1212 static void VM_SV_pointcontents (void)
1214 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1215 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1222 Pick a vector for the player to shoot along
1223 vector aim(entity, missilespeed)
1226 static void VM_SV_aim (void)
1228 prvm_edict_t *ent, *check, *bestent;
1229 vec3_t start, dir, end, bestdir;
1232 float dist, bestdist;
1235 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1237 // assume failure if it returns early
1238 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1239 // if sv_aim is so high it can't possibly accept anything, skip out early
1240 if (sv_aim.value >= 1)
1243 ent = PRVM_G_EDICT(OFS_PARM0);
1244 if (ent == prog->edicts)
1246 VM_Warning("aim: can not use world entity\n");
1249 if (ent->priv.server->free)
1251 VM_Warning("aim: can not use free entity\n");
1254 //speed = PRVM_G_FLOAT(OFS_PARM1);
1256 VectorCopy (ent->fields.server->origin, start);
1259 // try sending a trace straight
1260 VectorCopy (prog->globals.server->v_forward, dir);
1261 VectorMA (start, 2048, dir, end);
1262 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1263 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1264 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1266 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1271 // try all possible entities
1272 VectorCopy (dir, bestdir);
1273 bestdist = sv_aim.value;
1276 check = PRVM_NEXT_EDICT(prog->edicts);
1277 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1279 prog->xfunction->builtinsprofile++;
1280 if (check->fields.server->takedamage != DAMAGE_AIM)
1284 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1285 continue; // don't aim at teammate
1286 for (j=0 ; j<3 ; j++)
1287 end[j] = check->fields.server->origin[j]
1288 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1289 VectorSubtract (end, start, dir);
1290 VectorNormalize (dir);
1291 dist = DotProduct (dir, prog->globals.server->v_forward);
1292 if (dist < bestdist)
1293 continue; // to far to turn
1294 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1295 if (tr.ent == check)
1296 { // can shoot at this one
1304 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1305 dist = DotProduct (dir, prog->globals.server->v_forward);
1306 VectorScale (prog->globals.server->v_forward, dist, end);
1308 VectorNormalize (end);
1309 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1313 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1318 ===============================================================================
1322 ===============================================================================
1325 #define MSG_BROADCAST 0 // unreliable to all
1326 #define MSG_ONE 1 // reliable to one (msg_entity)
1327 #define MSG_ALL 2 // reliable to all
1328 #define MSG_INIT 3 // write to the init string
1329 #define MSG_ENTITY 5
1331 sizebuf_t *WriteDest (void)
1337 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1341 return &sv.datagram;
1344 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1345 entnum = PRVM_NUM_FOR_EDICT(ent);
1346 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1348 VM_Warning ("WriteDest: tried to write to non-client\n");
1349 return &sv.reliable_datagram;
1352 return &svs.clients[entnum-1].netconnection->message;
1355 VM_Warning ("WriteDest: bad destination\n");
1357 return &sv.reliable_datagram;
1363 return sv.writeentitiestoclient_msg;
1369 static void VM_SV_WriteByte (void)
1371 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1372 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1375 static void VM_SV_WriteChar (void)
1377 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1378 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1381 static void VM_SV_WriteShort (void)
1383 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1384 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1387 static void VM_SV_WriteLong (void)
1389 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1390 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1393 static void VM_SV_WriteAngle (void)
1395 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1396 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1399 static void VM_SV_WriteCoord (void)
1401 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1402 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1405 static void VM_SV_WriteString (void)
1407 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1408 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1411 static void VM_SV_WriteUnterminatedString (void)
1413 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1414 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1418 static void VM_SV_WriteEntity (void)
1420 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1421 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1424 // writes a picture as at most size bytes of data
1426 // IMGNAME \0 SIZE(short) IMGDATA
1427 // if failed to read/compress:
1429 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1430 static void VM_SV_WritePicture (void)
1432 const char *imgname;
1436 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1438 imgname = PRVM_G_STRING(OFS_PARM1);
1439 size = (int) PRVM_G_FLOAT(OFS_PARM2);
1443 MSG_WriteString(WriteDest(), imgname);
1444 if(Image_Compress(imgname, size, &buf, &size))
1447 MSG_WriteShort(WriteDest(), size);
1448 SZ_Write(WriteDest(), (unsigned char *) buf, size);
1453 MSG_WriteShort(WriteDest(), 0);
1457 //////////////////////////////////////////////////////////
1459 static void VM_SV_makestatic (void)
1464 // allow 0 parameters due to an id1 qc bug in which this function is used
1465 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1466 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1468 if (prog->argc >= 1)
1469 ent = PRVM_G_EDICT(OFS_PARM0);
1471 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1472 if (ent == prog->edicts)
1474 VM_Warning("makestatic: can not modify world entity\n");
1477 if (ent->priv.server->free)
1479 VM_Warning("makestatic: can not modify free entity\n");
1484 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1489 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1490 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1491 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1493 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1495 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1496 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1497 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1501 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1502 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1503 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1506 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1507 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1508 for (i=0 ; i<3 ; i++)
1510 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1511 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1514 // throw the entity away now
1518 //=============================================================================
1525 static void VM_SV_setspawnparms (void)
1531 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1533 ent = PRVM_G_EDICT(OFS_PARM0);
1534 i = PRVM_NUM_FOR_EDICT(ent);
1535 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1537 Con_Print("tried to setspawnparms on a non-client\n");
1541 // copy spawn parms out of the client_t
1542 client = svs.clients + i-1;
1543 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1544 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1551 Returns a color vector indicating the lighting at the requested point.
1553 (Internal Operation note: actually measures the light beneath the point, just like
1554 the model lighting on the client)
1559 static void VM_SV_getlight (void)
1561 vec3_t ambientcolor, diffusecolor, diffusenormal;
1563 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1564 p = PRVM_G_VECTOR(OFS_PARM0);
1565 VectorClear(ambientcolor);
1566 VectorClear(diffusecolor);
1567 VectorClear(diffusenormal);
1568 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1569 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1570 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1575 unsigned char type; // 1/2/8 or other value if isn't used
1579 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1580 static int vm_customstats_last;
1582 void VM_CustomStats_Clear (void)
1586 Z_Free(vm_customstats);
1587 vm_customstats = NULL;
1588 vm_customstats_last = -1;
1592 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1600 for(i=0; i<vm_customstats_last+1 ;i++)
1602 if(!vm_customstats[i].type)
1604 switch(vm_customstats[i].type)
1606 //string as 16 bytes
1609 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1610 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1611 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1612 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1613 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1615 //float field sent as-is
1617 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1619 //integer value of float field
1621 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1629 // void(float index, float type, .void field) SV_AddStat = #232;
1630 // Set up an auto-sent player stat.
1631 // Client's get thier own fields sent to them. Index may not be less than 32.
1632 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1633 // 1: string (4 stats carrying a total of 16 charactures)
1634 // 2: float (one stat, float converted to an integer for transportation)
1635 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1636 static void VM_SV_AddStat (void)
1641 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1645 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1648 VM_Warning("PF_SV_AddStat: not enough memory\n");
1652 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1653 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1654 off = PRVM_G_INT (OFS_PARM2);
1659 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1662 if(i >= (MAX_CL_STATS-32))
1664 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1667 if(i > (MAX_CL_STATS-32-4) && type == 1)
1669 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1672 vm_customstats[i].type = type;
1673 vm_customstats[i].fieldoffset = off;
1674 if(vm_customstats_last < i)
1675 vm_customstats_last = i;
1682 copies data from one entity to another
1684 copyentity(src, dst)
1687 static void VM_SV_copyentity (void)
1689 prvm_edict_t *in, *out;
1690 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1691 in = PRVM_G_EDICT(OFS_PARM0);
1692 if (in == prog->edicts)
1694 VM_Warning("copyentity: can not read world entity\n");
1697 if (in->priv.server->free)
1699 VM_Warning("copyentity: can not read free entity\n");
1702 out = PRVM_G_EDICT(OFS_PARM1);
1703 if (out == prog->edicts)
1705 VM_Warning("copyentity: can not modify world entity\n");
1708 if (out->priv.server->free)
1710 VM_Warning("copyentity: can not modify free entity\n");
1713 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1722 sets the color of a client and broadcasts the update to all connected clients
1724 setcolor(clientent, value)
1727 static void VM_SV_setcolor (void)
1733 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1734 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1735 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1737 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1739 Con_Print("tried to setcolor a non-client\n");
1743 client = svs.clients + entnum-1;
1746 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1748 client->edict->fields.server->team = (i & 15) + 1;
1751 if (client->old_colors != client->colors)
1753 client->old_colors = client->colors;
1754 // send notification to all clients
1755 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1756 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1757 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1765 effect(origin, modelname, startframe, framecount, framerate)
1768 static void VM_SV_effect (void)
1772 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1773 s = PRVM_G_STRING(OFS_PARM1);
1776 VM_Warning("effect: no model specified\n");
1780 i = SV_ModelIndex(s, 1);
1783 VM_Warning("effect: model not precached\n");
1787 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1789 VM_Warning("effect: framecount < 1\n");
1793 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1795 VM_Warning("effect: framerate < 1\n");
1799 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));
1802 static void VM_SV_te_blood (void)
1804 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1805 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1807 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1808 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1810 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1811 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1812 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1814 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1815 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1816 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1818 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1819 SV_FlushBroadcastMessages();
1822 static void VM_SV_te_bloodshower (void)
1824 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1825 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1827 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1828 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1830 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1831 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1834 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1835 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1836 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1838 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1840 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1841 SV_FlushBroadcastMessages();
1844 static void VM_SV_te_explosionrgb (void)
1846 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1847 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1848 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1850 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1851 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1852 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1854 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1855 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1856 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1857 SV_FlushBroadcastMessages();
1860 static void VM_SV_te_particlecube (void)
1862 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1863 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1865 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1866 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1872 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1873 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1874 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1876 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1877 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1878 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1880 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1882 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1883 // gravity true/false
1884 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1886 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1887 SV_FlushBroadcastMessages();
1890 static void VM_SV_te_particlerain (void)
1892 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1893 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1895 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1896 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1898 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1899 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1902 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1903 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1904 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1906 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1907 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1908 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1910 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1912 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1913 SV_FlushBroadcastMessages();
1916 static void VM_SV_te_particlesnow (void)
1918 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1919 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1921 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1922 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1924 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1925 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1926 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1928 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1929 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1930 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1933 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1934 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1936 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1938 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1939 SV_FlushBroadcastMessages();
1942 static void VM_SV_te_spark (void)
1944 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1945 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1947 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1948 MSG_WriteByte(&sv.datagram, TE_SPARK);
1950 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1951 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1952 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1954 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1955 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1956 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1958 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1959 SV_FlushBroadcastMessages();
1962 static void VM_SV_te_gunshotquad (void)
1964 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1965 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1966 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1968 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1969 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1970 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1971 SV_FlushBroadcastMessages();
1974 static void VM_SV_te_spikequad (void)
1976 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1977 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1978 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1980 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1981 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1982 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1983 SV_FlushBroadcastMessages();
1986 static void VM_SV_te_superspikequad (void)
1988 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1989 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1990 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1992 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1993 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1994 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1995 SV_FlushBroadcastMessages();
1998 static void VM_SV_te_explosionquad (void)
2000 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
2001 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2002 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2004 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2005 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2006 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2007 SV_FlushBroadcastMessages();
2010 static void VM_SV_te_smallflash (void)
2012 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
2013 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2014 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2016 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2017 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2018 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2019 SV_FlushBroadcastMessages();
2022 static void VM_SV_te_customflash (void)
2024 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
2025 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2027 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2028 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2030 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2031 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2032 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2034 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2036 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
2038 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
2039 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
2040 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
2041 SV_FlushBroadcastMessages();
2044 static void VM_SV_te_gunshot (void)
2046 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
2047 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2048 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2050 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2051 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2052 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2053 SV_FlushBroadcastMessages();
2056 static void VM_SV_te_spike (void)
2058 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
2059 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2060 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2062 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2063 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2064 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2065 SV_FlushBroadcastMessages();
2068 static void VM_SV_te_superspike (void)
2070 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
2071 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2072 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2074 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2075 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2076 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2077 SV_FlushBroadcastMessages();
2080 static void VM_SV_te_explosion (void)
2082 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
2083 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2084 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2086 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2087 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2088 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2089 SV_FlushBroadcastMessages();
2092 static void VM_SV_te_tarexplosion (void)
2094 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
2095 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2096 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2098 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2099 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2100 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2101 SV_FlushBroadcastMessages();
2104 static void VM_SV_te_wizspike (void)
2106 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
2107 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2108 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2110 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2111 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2112 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2113 SV_FlushBroadcastMessages();
2116 static void VM_SV_te_knightspike (void)
2118 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2119 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2120 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2122 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2123 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2124 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2125 SV_FlushBroadcastMessages();
2128 static void VM_SV_te_lavasplash (void)
2130 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2131 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2132 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2134 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2135 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2136 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2137 SV_FlushBroadcastMessages();
2140 static void VM_SV_te_teleport (void)
2142 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2143 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2144 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2146 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2147 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2148 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2149 SV_FlushBroadcastMessages();
2152 static void VM_SV_te_explosion2 (void)
2154 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2155 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2156 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2158 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2159 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2160 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2162 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2163 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2164 SV_FlushBroadcastMessages();
2167 static void VM_SV_te_lightning1 (void)
2169 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2170 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2171 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2173 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2175 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2176 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2177 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2179 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2180 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2181 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2182 SV_FlushBroadcastMessages();
2185 static void VM_SV_te_lightning2 (void)
2187 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2188 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2189 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2191 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2193 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2194 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2195 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2197 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2198 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2199 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2200 SV_FlushBroadcastMessages();
2203 static void VM_SV_te_lightning3 (void)
2205 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2206 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2207 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2209 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2211 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2212 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2213 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2215 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2216 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2217 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2218 SV_FlushBroadcastMessages();
2221 static void VM_SV_te_beam (void)
2223 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2224 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2225 MSG_WriteByte(&sv.datagram, TE_BEAM);
2227 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2229 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2230 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2231 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2233 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2234 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2235 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2236 SV_FlushBroadcastMessages();
2239 static void VM_SV_te_plasmaburn (void)
2241 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2242 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2243 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2244 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2245 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2246 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2247 SV_FlushBroadcastMessages();
2250 static void VM_SV_te_flamejet (void)
2252 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2253 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2254 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2256 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2257 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2258 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2260 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2261 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2262 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2264 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2265 SV_FlushBroadcastMessages();
2268 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2269 //this function originally written by KrimZon, made shorter by LordHavoc
2270 static void VM_SV_clientcommand (void)
2272 client_t *temp_client;
2274 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2276 //find client for this entity
2277 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2278 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2280 Con_Print("PF_clientcommand: entity is not a client\n");
2284 temp_client = host_client;
2285 host_client = svs.clients + i;
2286 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2287 host_client = temp_client;
2290 //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)
2291 static void VM_SV_setattachment (void)
2293 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2294 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2295 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2298 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2300 if (e == prog->edicts)
2302 VM_Warning("setattachment: can not modify world entity\n");
2305 if (e->priv.server->free)
2307 VM_Warning("setattachment: can not modify free entity\n");
2311 if (tagentity == NULL)
2312 tagentity = prog->edicts;
2314 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2316 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2318 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2321 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2323 model = SV_GetModelFromEdict(tagentity);
2326 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2328 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);
2331 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));
2335 /////////////////////////////////////////
2336 // DP_MD3_TAGINFO extension coded by VorteX
2338 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2342 i = (int)e->fields.server->modelindex;
2343 if (i < 1 || i >= MAX_MODELS)
2346 return Mod_Alias_GetTagIndexForName(SV_GetModelByIndex(i), (int)e->fields.server->skin, tagname);
2349 int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
2356 Matrix4x4_CreateIdentity(tag_localmatrix);
2358 if (tagindex >= 0 && (model = SV_GetModelFromEdict(e)) && model->num_bones)
2360 r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, e->priv.server->frameblend, &e->priv.server->skeleton, tagindex - 1, parentindex, tagname, tag_localmatrix);
2371 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2375 float pitchsign = 1;
2378 val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
2379 if (val && val->_float != 0)
2380 scale = val->_float;
2383 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);
2386 pitchsign = SV_GetPitchSign(ent);
2387 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);
2391 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2394 if (tagindex >= 0 && (model = SV_GetModelFromEdict(ent)) && model->animscenes)
2396 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2397 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2398 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2399 return Mod_Alias_GetTagMatrix(model, ent->priv.server->frameblend, &ent->priv.server->skeleton, tagindex, out);
2401 *out = identitymatrix;
2405 // Warnings/errors code:
2406 // 0 - normal (everything all-right)
2409 // 3 - null or non-precached model
2410 // 4 - no tags with requested index
2411 // 5 - runaway loop at attachment chain
2412 extern cvar_t cl_bob;
2413 extern cvar_t cl_bobcycle;
2414 extern cvar_t cl_bobup;
2415 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2419 int modelindex, attachloop;
2420 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2423 *out = identitymatrix; // warnings and errors return identical matrix
2425 if (ent == prog->edicts)
2427 if (ent->priv.server->free)
2430 modelindex = (int)ent->fields.server->modelindex;
2431 if (modelindex <= 0 || modelindex >= MAX_MODELS)
2434 model = SV_GetModelByIndex(modelindex);
2436 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2437 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2438 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2440 tagmatrix = identitymatrix;
2441 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2445 if (attachloop >= 256) // prevent runaway looping
2447 // apply transformation by child's tagindex on parent entity and then
2448 // by parent entity itself
2449 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2450 if (ret && attachloop == 0)
2452 SV_GetEntityMatrix(ent, &entitymatrix, false);
2453 Matrix4x4_Concat(&tagmatrix, &attachmatrix, out);
2454 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2455 // next iteration we process the parent entity
2456 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2458 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2459 ent = PRVM_EDICT_NUM(val->edict);
2466 // RENDER_VIEWMODEL magic
2467 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2469 Matrix4x4_Copy(&tagmatrix, out);
2470 ent = PRVM_EDICT_NUM(val->edict);
2472 SV_GetEntityMatrix(ent, &entitymatrix, true);
2473 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2476 // Cl_bob, ported from rendering code
2477 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2480 // LordHavoc: this code is *weird*, but not replacable (I think it
2481 // should be done in QC on the server, but oh well, quake is quake)
2482 // LordHavoc: figured out bobup: the time at which the sin is at 180
2483 // degrees (which allows lengthening or squishing the peak or valley)
2484 cycle = sv.time/cl_bobcycle.value;
2485 cycle -= (int)cycle;
2486 if (cycle < cl_bobup.value)
2487 cycle = sin(M_PI * cycle / cl_bobup.value);
2489 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2490 // bob is proportional to velocity in the xy plane
2491 // (don't count Z, or jumping messes it up)
2492 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;
2493 bob = bob*0.3 + bob*0.7*cycle;
2494 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2501 //float(entity ent, string tagname) gettagindex;
2503 static void VM_SV_gettagindex (void)
2506 const char *tag_name;
2509 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2511 ent = PRVM_G_EDICT(OFS_PARM0);
2512 tag_name = PRVM_G_STRING(OFS_PARM1);
2514 if (ent == prog->edicts)
2516 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
2519 if (ent->priv.server->free)
2521 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
2526 if (!SV_GetModelFromEdict(ent))
2527 Con_DPrintf("VM_SV_gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2530 tag_index = SV_GetTagIndex(ent, tag_name);
2532 if(developer_extra.integer)
2533 Con_DPrintf("VM_SV_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2535 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2538 //vector(entity ent, float tagindex) gettaginfo;
2539 static void VM_SV_gettaginfo (void)
2543 matrix4x4_t tag_matrix;
2544 matrix4x4_t tag_localmatrix;
2546 const char *tagname;
2549 vec3_t fo, le, up, trans;
2550 const dp_model_t *model;
2552 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2554 e = PRVM_G_EDICT(OFS_PARM0);
2555 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2557 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2558 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, le, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2559 VectorScale(le, -1, prog->globals.server->v_right);
2560 model = SV_GetModelFromEdict(e);
2561 VM_GenerateFrameGroupBlend(e->priv.server->framegroupblend, e);
2562 VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model);
2563 VM_UpdateEdictSkeleton(e, model, e->priv.server->frameblend);
2564 SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
2565 Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
2567 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
2568 val->_float = parentindex;
2569 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
2570 val->string = tagname ? PRVM_SetTempString(tagname) : 0;
2571 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
2572 VectorCopy(trans, val->vector);
2573 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
2574 VectorCopy(fo, val->vector);
2575 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
2576 VectorScale(le, -1, val->vector);
2577 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
2578 VectorCopy(up, val->vector);
2583 VM_Warning("gettagindex: can't affect world entity\n");
2586 VM_Warning("gettagindex: can't affect free entity\n");
2589 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2592 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2595 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2600 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2601 static void VM_SV_dropclient (void)
2604 client_t *oldhostclient;
2605 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2606 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2607 if (clientnum < 0 || clientnum >= svs.maxclients)
2609 VM_Warning("dropclient: not a client\n");
2612 if (!svs.clients[clientnum].active)
2614 VM_Warning("dropclient: that client slot is not connected\n");
2617 oldhostclient = host_client;
2618 host_client = svs.clients + clientnum;
2619 SV_DropClient(false);
2620 host_client = oldhostclient;
2623 //entity() spawnclient (DP_SV_BOTCLIENT)
2624 static void VM_SV_spawnclient (void)
2628 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2629 prog->xfunction->builtinsprofile += 2;
2631 for (i = 0;i < svs.maxclients;i++)
2633 if (!svs.clients[i].active)
2635 prog->xfunction->builtinsprofile += 100;
2636 SV_ConnectClient (i, NULL);
2637 // this has to be set or else ClientDisconnect won't be called
2638 // we assume the qc will call ClientConnect...
2639 svs.clients[i].clientconnectcalled = true;
2640 ed = PRVM_EDICT_NUM(i + 1);
2644 VM_RETURN_EDICT(ed);
2647 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2648 static void VM_SV_clienttype (void)
2651 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2652 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2653 if (clientnum < 0 || clientnum >= svs.maxclients)
2654 PRVM_G_FLOAT(OFS_RETURN) = 3;
2655 else if (!svs.clients[clientnum].active)
2656 PRVM_G_FLOAT(OFS_RETURN) = 0;
2657 else if (svs.clients[clientnum].netconnection)
2658 PRVM_G_FLOAT(OFS_RETURN) = 1;
2660 PRVM_G_FLOAT(OFS_RETURN) = 2;
2667 string(string key) serverkey
2670 void VM_SV_serverkey(void)
2672 char string[VM_STRINGTEMP_LENGTH];
2673 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2674 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2675 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2678 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2679 static void VM_SV_setmodelindex (void)
2684 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2686 e = PRVM_G_EDICT(OFS_PARM0);
2687 if (e == prog->edicts)
2689 VM_Warning("setmodelindex: can not modify world entity\n");
2692 if (e->priv.server->free)
2694 VM_Warning("setmodelindex: can not modify free entity\n");
2697 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2698 if (i <= 0 || i >= MAX_MODELS)
2700 VM_Warning("setmodelindex: invalid modelindex\n");
2703 if (!sv.model_precache[i][0])
2705 VM_Warning("setmodelindex: model not precached\n");
2709 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2710 e->fields.server->modelindex = i;
2712 mod = SV_GetModelByIndex(i);
2716 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2717 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2719 SetMinMaxSize (e, quakemins, quakemaxs, true);
2722 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2725 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2726 static void VM_SV_modelnameforindex (void)
2729 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2731 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2733 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2734 if (i <= 0 || i >= MAX_MODELS)
2736 VM_Warning("modelnameforindex: invalid modelindex\n");
2739 if (!sv.model_precache[i][0])
2741 VM_Warning("modelnameforindex: model not precached\n");
2745 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2748 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2749 static void VM_SV_particleeffectnum (void)
2752 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2753 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2756 PRVM_G_FLOAT(OFS_RETURN) = i;
2759 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2760 static void VM_SV_trailparticles (void)
2762 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2764 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2767 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2768 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2769 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2770 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2771 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2772 SV_FlushBroadcastMessages();
2775 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2776 static void VM_SV_pointparticles (void)
2778 int effectnum, count;
2780 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2782 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2785 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2786 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2787 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2788 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2789 if (count == 1 && !VectorLength2(vel))
2792 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2793 MSG_WriteShort(&sv.datagram, effectnum);
2794 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2798 // 1+2+12+12+2=29 bytes
2799 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2800 MSG_WriteShort(&sv.datagram, effectnum);
2801 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2802 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2803 MSG_WriteShort(&sv.datagram, count);
2806 SV_FlushBroadcastMessages();
2809 //PF_setpause, // void(float pause) setpause = #531;
2810 static void VM_SV_setpause(void) {
2812 pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
2813 if (pauseValue != 0) { //pause the game
2815 sv.pausedstart = Sys_DoubleTime();
2816 } else { //disable pause, in case it was enabled
2817 if (sv.paused != 0) {
2822 // send notification to all clients
2823 MSG_WriteByte(&sv.reliable_datagram, svc_setpause);
2824 MSG_WriteByte(&sv.reliable_datagram, sv.paused);
2827 // #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.
2828 static void VM_SV_skel_create(void)
2830 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
2831 dp_model_t *model = SV_GetModelByIndex(modelindex);
2832 skeleton_t *skeleton;
2834 PRVM_G_FLOAT(OFS_RETURN) = 0;
2835 if (!model || !model->num_bones)
2837 for (i = 0;i < MAX_EDICTS;i++)
2838 if (!prog->skeletons[i])
2840 if (i == MAX_EDICTS)
2842 prog->skeletons[i] = skeleton = Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
2843 PRVM_G_FLOAT(OFS_RETURN) = i + 1;
2844 skeleton->model = model;
2845 skeleton->relativetransforms = (matrix4x4_t *)(skeleton+1);
2846 // initialize to identity matrices
2847 for (i = 0;i < skeleton->model->num_bones;i++)
2848 skeleton->relativetransforms[i] = identitymatrix;
2851 // #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
2852 static void VM_SV_skel_build(void)
2854 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2855 skeleton_t *skeleton;
2856 prvm_edict_t *ed = PRVM_G_EDICT(OFS_PARM1);
2857 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM2);
2858 float retainfrac = PRVM_G_FLOAT(OFS_PARM3);
2859 int firstbone = PRVM_G_FLOAT(OFS_PARM4) - 1;
2860 int lastbone = PRVM_G_FLOAT(OFS_PARM5) - 1;
2861 dp_model_t *model = SV_GetModelByIndex(modelindex);
2866 framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS];
2867 frameblend_t frameblend[MAX_FRAMEBLENDS];
2868 matrix4x4_t blendedmatrix;
2870 PRVM_G_FLOAT(OFS_RETURN) = 0;
2871 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2873 firstbone = max(0, firstbone);
2874 lastbone = min(lastbone, model->num_bones - 1);
2875 lastbone = min(lastbone, skeleton->model->num_bones - 1);
2876 VM_GenerateFrameGroupBlend(framegroupblend, ed);
2877 VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model);
2878 blendfrac = 1.0f - retainfrac;
2879 for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
2880 frameblend[numblends].lerp *= blendfrac;
2881 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
2883 memset(&blendedmatrix, 0, sizeof(blendedmatrix));
2884 Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac);
2885 for (blendindex = 0;blendindex < numblends;blendindex++)
2887 Matrix4x4_FromBonePose6s(&matrix, model->num_posescale, model->data_poses6s + 6 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
2888 Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp);
2890 skeleton->relativetransforms[bonenum] = blendedmatrix;
2892 PRVM_G_FLOAT(OFS_RETURN) = skeletonindex + 1;
2895 // #265 float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS) returns how many bones exist in the created skeleton
2896 static void VM_SV_skel_get_numbones(void)
2898 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2899 skeleton_t *skeleton;
2900 PRVM_G_FLOAT(OFS_RETURN) = 0;
2901 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2903 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->num_bones;
2906 // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) returns name of bone (as a tempstring)
2907 static void VM_SV_skel_get_bonename(void)
2909 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2910 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2911 skeleton_t *skeleton;
2912 PRVM_G_INT(OFS_RETURN) = 0;
2913 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2915 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2917 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(skeleton->model->data_bones[bonenum].name);
2920 // #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)
2921 static void VM_SV_skel_get_boneparent(void)
2923 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2924 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2925 skeleton_t *skeleton;
2926 PRVM_G_FLOAT(OFS_RETURN) = 0;
2927 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2929 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2931 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->data_bones[bonenum].parent + 1;
2934 // #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
2935 static void VM_SV_skel_find_bone(void)
2937 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2938 const char *tagname = PRVM_G_STRING(OFS_PARM1);
2939 skeleton_t *skeleton;
2940 PRVM_G_FLOAT(OFS_RETURN) = 0;
2941 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2943 PRVM_G_FLOAT(OFS_RETURN) = Mod_Alias_GetTagIndexForName(skeleton->model, 0, tagname) + 1;
2946 // #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)
2947 static void VM_SV_skel_get_bonerel(void)
2949 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2950 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2951 skeleton_t *skeleton;
2953 vec3_t forward, left, up, origin;
2954 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2955 VectorClear(prog->globals.client->v_forward);
2956 VectorClear(prog->globals.client->v_right);
2957 VectorClear(prog->globals.client->v_up);
2958 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2960 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2962 matrix = skeleton->relativetransforms[bonenum];
2963 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2964 VectorCopy(forward, prog->globals.client->v_forward);
2965 VectorNegate(left, prog->globals.client->v_right);
2966 VectorCopy(up, prog->globals.client->v_up);
2967 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
2970 // #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)
2971 static void VM_SV_skel_get_boneabs(void)
2973 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2974 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2975 skeleton_t *skeleton;
2978 vec3_t forward, left, up, origin;
2979 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2980 VectorClear(prog->globals.client->v_forward);
2981 VectorClear(prog->globals.client->v_right);
2982 VectorClear(prog->globals.client->v_up);
2983 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2985 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2987 matrix = skeleton->relativetransforms[bonenum];
2988 // convert to absolute
2989 while ((bonenum = skeleton->model->data_bones[bonenum].parent) >= 0)
2992 Matrix4x4_Concat(&matrix, &skeleton->relativetransforms[bonenum], &temp);
2994 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2995 VectorCopy(forward, prog->globals.client->v_forward);
2996 VectorNegate(left, prog->globals.client->v_right);
2997 VectorCopy(up, prog->globals.client->v_up);
2998 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
3001 // #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)
3002 static void VM_SV_skel_set_bone(void)
3004 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3005 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3006 vec3_t forward, left, up, origin;
3007 skeleton_t *skeleton;
3009 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3011 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3013 VectorCopy(prog->globals.client->v_forward, forward);
3014 VectorNegate(prog->globals.client->v_right, left);
3015 VectorCopy(prog->globals.client->v_up, up);
3016 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3017 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3018 skeleton->relativetransforms[bonenum] = matrix;
3021 // #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)
3022 static void VM_SV_skel_mul_bone(void)
3024 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3025 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3026 vec3_t forward, left, up, origin;
3027 skeleton_t *skeleton;
3030 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3032 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3034 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3035 VectorCopy(prog->globals.client->v_forward, forward);
3036 VectorNegate(prog->globals.client->v_right, left);
3037 VectorCopy(prog->globals.client->v_up, up);
3038 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3039 temp = skeleton->relativetransforms[bonenum];
3040 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3043 // #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)
3044 static void VM_SV_skel_mul_bones(void)
3046 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3047 int firstbone = PRVM_G_FLOAT(OFS_PARM1) - 1;
3048 int lastbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3050 vec3_t forward, left, up, origin;
3051 skeleton_t *skeleton;
3054 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3056 VectorCopy(PRVM_G_VECTOR(OFS_PARM3), origin);
3057 VectorCopy(prog->globals.client->v_forward, forward);
3058 VectorNegate(prog->globals.client->v_right, left);
3059 VectorCopy(prog->globals.client->v_up, up);
3060 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3061 firstbone = max(0, firstbone);
3062 lastbone = min(lastbone, skeleton->model->num_bones - 1);
3063 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3065 temp = skeleton->relativetransforms[bonenum];
3066 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3070 // #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
3071 static void VM_SV_skel_copybones(void)
3073 int skeletonindexdst = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3074 int skeletonindexsrc = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3075 int firstbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3076 int lastbone = PRVM_G_FLOAT(OFS_PARM3) - 1;
3078 skeleton_t *skeletondst;
3079 skeleton_t *skeletonsrc;
3080 if (skeletonindexdst < 0 || skeletonindexdst >= MAX_EDICTS || !(skeletondst = prog->skeletons[skeletonindexdst]))
3082 if (skeletonindexsrc < 0 || skeletonindexsrc >= MAX_EDICTS || !(skeletonsrc = prog->skeletons[skeletonindexsrc]))
3084 firstbone = max(0, firstbone);
3085 lastbone = min(lastbone, skeletondst->model->num_bones - 1);
3086 lastbone = min(lastbone, skeletonsrc->model->num_bones - 1);
3087 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3088 skeletondst->relativetransforms[bonenum] = skeletonsrc->relativetransforms[bonenum];
3091 // #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)
3092 static void VM_SV_skel_delete(void)
3094 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3095 skeleton_t *skeleton;
3096 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3099 prog->skeletons[skeletonindex] = NULL;
3102 // #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
3103 static void VM_SV_frameforname(void)
3105 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3106 dp_model_t *model = SV_GetModelByIndex(modelindex);
3107 const char *name = PRVM_G_STRING(OFS_PARM1);
3109 PRVM_G_FLOAT(OFS_RETURN) = -1;
3110 if (!model || !model->animscenes)
3112 for (i = 0;i < model->numframes;i++)
3114 if (!strcasecmp(model->animscenes[i].name, name))
3116 PRVM_G_FLOAT(OFS_RETURN) = i;
3122 // #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.
3123 static void VM_SV_frameduration(void)
3125 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3126 dp_model_t *model = SV_GetModelByIndex(modelindex);
3127 int framenum = (int)PRVM_G_FLOAT(OFS_PARM1);
3128 PRVM_G_FLOAT(OFS_RETURN) = 0;
3129 if (!model || !model->animscenes || framenum < 0 || framenum >= model->numframes)
3131 if (model->animscenes[framenum].framerate)
3132 PRVM_G_FLOAT(OFS_RETURN) = model->animscenes[framenum].framecount / model->animscenes[framenum].framerate;
3136 prvm_builtin_t vm_sv_builtins[] = {
3137 NULL, // #0 NULL function (not callable) (QUAKE)
3138 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
3139 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
3140 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
3141 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
3142 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
3143 VM_break, // #6 void() break (QUAKE)
3144 VM_random, // #7 float() random (QUAKE)
3145 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
3146 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
3147 VM_error, // #10 void(string e) error (QUAKE)
3148 VM_objerror, // #11 void(string e) objerror (QUAKE)
3149 VM_vlen, // #12 float(vector v) vlen (QUAKE)
3150 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
3151 VM_spawn, // #14 entity() spawn (QUAKE)
3152 VM_remove, // #15 void(entity e) remove (QUAKE)
3153 VM_SV_traceline, // #16 void(vector v1, vector v2, float tryents) traceline (QUAKE)
3154 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
3155 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
3156 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
3157 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
3158 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
3159 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
3160 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
3161 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
3162 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
3163 VM_ftos, // #26 string(float f) ftos (QUAKE)
3164 VM_vtos, // #27 string(vector v) vtos (QUAKE)
3165 VM_coredump, // #28 void() coredump (QUAKE)
3166 VM_traceon, // #29 void() traceon (QUAKE)
3167 VM_traceoff, // #30 void() traceoff (QUAKE)
3168 VM_eprint, // #31 void(entity e) eprint (QUAKE)
3169 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
3170 NULL, // #33 (QUAKE)
3171 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
3172 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
3173 VM_rint, // #36 float(float v) rint (QUAKE)
3174 VM_floor, // #37 float(float v) floor (QUAKE)
3175 VM_ceil, // #38 float(float v) ceil (QUAKE)
3176 NULL, // #39 (QUAKE)
3177 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
3178 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
3179 NULL, // #42 (QUAKE)
3180 VM_fabs, // #43 float(float f) fabs (QUAKE)
3181 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
3182 VM_cvar, // #45 float(string s) cvar (QUAKE)
3183 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
3184 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
3185 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
3186 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
3187 NULL, // #50 (QUAKE)
3188 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
3189 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
3190 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
3191 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
3192 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
3193 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
3194 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
3195 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
3196 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
3197 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
3198 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
3199 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
3200 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
3201 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
3202 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
3203 NULL, // #66 (QUAKE)
3204 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
3205 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
3206 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
3207 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
3208 NULL, // #71 (QUAKE)
3209 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
3210 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
3211 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
3212 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
3213 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
3214 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
3215 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
3216 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
3217 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
3218 VM_stof, // #81 float(string s) stof (FRIK_FILE)
3219 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
3220 NULL, // #83 (QUAKE)
3221 NULL, // #84 (QUAKE)
3222 NULL, // #85 (QUAKE)
3223 NULL, // #86 (QUAKE)
3224 NULL, // #87 (QUAKE)
3225 NULL, // #88 (QUAKE)
3226 NULL, // #89 (QUAKE)
3227 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
3228 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
3229 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
3230 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
3231 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
3232 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3233 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3234 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3235 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3236 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3237 // FrikaC and Telejano range #100-#199
3248 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3249 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3250 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3251 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3252 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3253 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3254 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3255 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3256 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3257 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3338 // FTEQW range #200-#299
3357 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3360 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3361 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3362 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3363 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3364 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3365 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3366 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3367 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3368 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3369 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3371 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3379 VM_SV_checkpvs, // #240 float(vector viewpos, entity viewee) checkpvs;
3402 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.
3403 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
3404 VM_SV_skel_get_numbones, // #265 float(float skel) skel_get_numbones = #265; // (DP_SKELETONOBJECTS) returns how many bones exist in the created skeleton
3405 VM_SV_skel_get_bonename, // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (DP_SKELETONOBJECTS) returns name of bone (as a tempstring)
3406 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)
3407 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
3408 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)
3409 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)
3410 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)
3411 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)
3412 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)
3413 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
3414 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)
3415 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
3416 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.
3439 // CSQC range #300-#399
3440 NULL, // #300 void() clearscene (EXT_CSQC)
3441 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3442 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3443 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3444 NULL, // #304 void() renderscene (EXT_CSQC)
3445 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3446 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3447 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3448 NULL, // #308 void() R_EndPolygon
3450 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3451 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3455 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3456 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3457 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3458 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3459 NULL, // #319 void(string name) freepic (EXT_CSQC)
3460 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3461 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3462 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3463 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3464 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3465 NULL, // #325 void(void) drawresetcliparea
3470 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3471 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3472 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3473 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3474 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3475 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3476 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3477 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3478 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3479 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3480 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3481 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3482 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3483 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3484 NULL, // #344 vector() getmousepos (EXT_CSQC)
3485 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3486 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3487 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3488 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3489 NULL, // #349 float() isdemo (EXT_CSQC)
3490 VM_isserver, // #350 float() isserver (EXT_CSQC)
3491 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3492 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3493 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3494 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3500 NULL, // #360 float() readbyte (EXT_CSQC)
3501 NULL, // #361 float() readchar (EXT_CSQC)
3502 NULL, // #362 float() readshort (EXT_CSQC)
3503 NULL, // #363 float() readlong (EXT_CSQC)
3504 NULL, // #364 float() readcoord (EXT_CSQC)
3505 NULL, // #365 float() readangle (EXT_CSQC)
3506 NULL, // #366 string() readstring (EXT_CSQC)
3507 NULL, // #367 float() readfloat (EXT_CSQC)
3540 // LordHavoc's range #400-#499
3541 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3542 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3543 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3544 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3545 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3546 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3547 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3548 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3549 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)
3550 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3551 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3552 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3553 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3554 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3555 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3556 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3557 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3558 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3559 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3560 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3561 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3562 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3563 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3564 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3565 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3566 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3567 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3568 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3569 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3570 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3571 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3572 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3573 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3574 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3575 VM_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3576 VM_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3577 VM_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3578 VM_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3579 VM_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3580 VM_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3581 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3582 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3583 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3584 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3585 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3586 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3587 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3588 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3589 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3590 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3591 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3592 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3593 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3594 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3595 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3596 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3597 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3598 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3600 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3601 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3602 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3603 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3604 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3605 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3606 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3607 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3608 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3609 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3610 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3612 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3613 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3614 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3615 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3616 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3617 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3618 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3619 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3620 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3621 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3622 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3623 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3624 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3625 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3626 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3627 VM_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3635 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3636 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3637 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3638 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3639 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3640 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3641 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3642 VM_SV_WritePicture, // #501
3644 VM_whichpack, // #503 string(string) whichpack = #503;
3651 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3652 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3653 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3654 VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3655 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3656 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3657 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3658 VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
3659 VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
3660 VM_gettime, // #519 float(float timer) gettime = #519; (DP_QC_GETTIME)
3670 VM_loadfromdata, // #529
3671 VM_loadfromfile, // #530
3672 VM_SV_setpause, // #531 void(float pause) setpause = #531;
3674 VM_getsoundtime, // #533 float(entity e, float channel) getsoundtime = #533; (DP_SND_GETSOUNDTIME)
3675 VM_soundlength, // #534 float(string sample) soundlength = #534; (DP_SND_GETSOUNDTIME)
3746 VM_callfunction, // #605
3747 VM_writetofile, // #606
3748 VM_isfunction, // #607
3754 VM_parseentitydata, // #613
3765 VM_SV_getextresponse, // #624 string getextresponse(void)
3768 VM_sprintf, // #627 string sprintf(string format, ...)
3769 VM_getsurfacenumtriangles, // #628 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACETRIANGLE)
3770 VM_getsurfacetriangle, // #629 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACETRIANGLE)
3774 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3776 void VM_SV_Cmd_Init(void)
3781 void VM_SV_Cmd_Reset(void)
3783 World_End(&sv.world);
3784 if(prog->funcoffsets.SV_Shutdown)
3786 func_t s = prog->funcoffsets.SV_Shutdown;
3787 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3788 PRVM_ExecuteProgram(s,"SV_Shutdown() required");