6 //============================================================================
11 const 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 "
130 "DP_QC_VECTOANGLES_WITH_ROLL "
131 "DP_QC_VECTORVECTORS "
138 "DP_SKELETONOBJECTS "
139 "DP_SND_DIRECTIONLESSATTNNONE "
144 "DP_SND_GETSOUNDTIME "
146 "DP_VIDEO_SUBTITLES "
150 "DP_SV_BOUNCEFACTOR "
151 "DP_SV_CLIENTCAMERA "
152 "DP_SV_CLIENTCOLORS "
155 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
156 "DP_SV_DISCARDABLEDEMO "
157 "DP_SV_DRAWONLYTOCLIENT "
160 "DP_SV_ENTITYCONTENTSTRANSITION "
161 "DP_SV_MODELFLAGS_AS_EFFECTS "
162 "DP_SV_MOVETYPESTEP_LANDEVENT "
164 "DP_SV_NODRAWTOCLIENT "
165 "DP_SV_ONENTITYNOSPAWNFUNCTION "
166 "DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
168 "DP_SV_PING_PACKETLOSS "
169 "DP_SV_PLAYERPHYSICS "
171 "DP_SV_POINTPARTICLES "
173 "DP_SV_PRECACHEANYTIME "
177 "DP_SV_ROTATINGBMODEL "
181 "DP_SV_SPAWNFUNC_PREFIX "
182 "DP_SV_WRITEPICTURE "
183 "DP_SV_WRITEUNTERMINATEDSTRING "
187 "DP_TE_EXPLOSIONRGB "
189 "DP_TE_PARTICLECUBE "
190 "DP_TE_PARTICLERAIN "
191 "DP_TE_PARTICLESNOW "
193 "DP_TE_QUADEFFECTS1 "
196 "DP_TE_STANDARDEFFECTBUILTINS "
197 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
201 "FTE_CSQC_SKELETONOBJECTS "
204 "KRIMZON_SV_PARSECLIENTCOMMAND "
207 "NEXUIZ_PLAYERMODEL "
209 "PRYDON_CLIENTCURSOR "
210 "TENEBRAE_GFX_DLIGHTS "
213 //"EXT_CSQC " // not ready yet
220 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.
222 setorigin (entity, origin)
225 static void VM_SV_setorigin (void)
230 VM_SAFEPARMCOUNT(2, VM_setorigin);
232 e = PRVM_G_EDICT(OFS_PARM0);
233 if (e == prog->edicts)
235 VM_Warning("setorigin: can not modify world entity\n");
238 if (e->priv.server->free)
240 VM_Warning("setorigin: can not modify free entity\n");
243 org = PRVM_G_VECTOR(OFS_PARM1);
244 VectorCopy (org, e->fields.server->origin);
248 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
249 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
253 for (i=0 ; i<3 ; i++)
255 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
257 // set derived values
258 VectorCopy (min, e->fields.server->mins);
259 VectorCopy (max, e->fields.server->maxs);
260 VectorSubtract (max, min, e->fields.server->size);
269 the size box is rotated by the current angle
270 LordHavoc: no it isn't...
272 setsize (entity, minvector, maxvector)
275 static void VM_SV_setsize (void)
280 VM_SAFEPARMCOUNT(3, VM_setsize);
282 e = PRVM_G_EDICT(OFS_PARM0);
283 if (e == prog->edicts)
285 VM_Warning("setsize: can not modify world entity\n");
288 if (e->priv.server->free)
290 VM_Warning("setsize: can not modify free entity\n");
293 min = PRVM_G_VECTOR(OFS_PARM1);
294 max = PRVM_G_VECTOR(OFS_PARM2);
295 SetMinMaxSize (e, min, max, false);
303 setmodel(entity, model)
306 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
307 static void VM_SV_setmodel (void)
313 VM_SAFEPARMCOUNT(2, VM_setmodel);
315 e = PRVM_G_EDICT(OFS_PARM0);
316 if (e == prog->edicts)
318 VM_Warning("setmodel: can not modify world entity\n");
321 if (e->priv.server->free)
323 VM_Warning("setmodel: can not modify free entity\n");
326 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
327 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
328 e->fields.server->modelindex = i;
330 mod = SV_GetModelByIndex(i);
334 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
335 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
337 SetMinMaxSize (e, quakemins, quakemaxs, true);
340 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
347 single print to a specific client
349 sprint(clientent, value)
352 static void VM_SV_sprint (void)
356 char string[VM_STRINGTEMP_LENGTH];
358 VM_VarString(1, string, sizeof(string));
360 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
362 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
363 // LordHavoc: div0 requested that sprintto world operate like print
370 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
372 VM_Warning("tried to centerprint to a non-client\n");
376 client = svs.clients + entnum-1;
377 if (!client->netconnection)
380 MSG_WriteChar(&client->netconnection->message,svc_print);
381 MSG_WriteString(&client->netconnection->message, string);
389 single print to a specific client
391 centerprint(clientent, value)
394 static void VM_SV_centerprint (void)
398 char string[VM_STRINGTEMP_LENGTH];
400 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
402 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
404 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
406 VM_Warning("tried to centerprint to a non-client\n");
410 client = svs.clients + entnum-1;
411 if (!client->netconnection)
414 VM_VarString(1, string, sizeof(string));
415 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
416 MSG_WriteString(&client->netconnection->message, string);
423 particle(origin, color, count)
426 static void VM_SV_particle (void)
432 VM_SAFEPARMCOUNT(4, VM_SV_particle);
434 org = PRVM_G_VECTOR(OFS_PARM0);
435 dir = PRVM_G_VECTOR(OFS_PARM1);
436 color = PRVM_G_FLOAT(OFS_PARM2);
437 count = PRVM_G_FLOAT(OFS_PARM3);
438 SV_StartParticle (org, dir, (int)color, (int)count);
448 static void VM_SV_ambientsound (void)
452 float vol, attenuation;
455 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
457 pos = PRVM_G_VECTOR (OFS_PARM0);
458 samp = PRVM_G_STRING(OFS_PARM1);
459 vol = PRVM_G_FLOAT(OFS_PARM2);
460 attenuation = PRVM_G_FLOAT(OFS_PARM3);
462 // check to see if samp was properly precached
463 soundnum = SV_SoundIndex(samp, 1);
471 // add an svc_spawnambient command to the level signon packet
474 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
476 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
478 MSG_WriteVector(&sv.signon, pos, sv.protocol);
480 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
481 MSG_WriteShort (&sv.signon, soundnum);
483 MSG_WriteByte (&sv.signon, soundnum);
485 MSG_WriteByte (&sv.signon, (int)(vol*255));
486 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
494 Each entity can have eight independant sound sources, like voice,
497 Channel 0 is an auto-allocate channel, the others override anything
498 already running on that entity/channel pair.
500 An attenuation of 0 will play full volume everywhere in the level.
501 Larger attenuations will drop off.
505 static void VM_SV_sound (void)
509 prvm_edict_t *entity;
513 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
515 entity = PRVM_G_EDICT(OFS_PARM0);
516 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
517 sample = PRVM_G_STRING(OFS_PARM2);
518 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
519 attenuation = PRVM_G_FLOAT(OFS_PARM4);
522 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
526 if (volume < 0 || volume > 255)
528 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
532 if (attenuation < 0 || attenuation > 4)
534 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
538 if (channel < 0 || channel > 7)
540 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
544 SV_StartSound (entity, channel, sample, volume, attenuation);
551 Follows the same logic as VM_SV_sound, except instead of
552 an entity, an origin for the sound is provided, and channel
553 is omitted (since no entity is being tracked).
557 static void VM_SV_pointsound(void)
564 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
566 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
567 sample = PRVM_G_STRING(OFS_PARM1);
568 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
569 attenuation = PRVM_G_FLOAT(OFS_PARM3);
571 if (volume < 0 || volume > 255)
573 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
577 if (attenuation < 0 || attenuation > 4)
579 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
583 SV_StartPointSound (org, sample, volume, attenuation);
590 Used for use tracing and shot targeting
591 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
592 if the tryents flag is set.
594 traceline (vector1, vector2, movetype, ignore)
597 static void VM_SV_traceline (void)
604 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
606 prog->xfunction->builtinsprofile += 30;
608 v1 = PRVM_G_VECTOR(OFS_PARM0);
609 v2 = PRVM_G_VECTOR(OFS_PARM1);
610 move = (int)PRVM_G_FLOAT(OFS_PARM2);
611 ent = PRVM_G_EDICT(OFS_PARM3);
613 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]))
614 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));
616 trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
618 VM_SetTraceGlobals(&trace);
626 Used for use tracing and shot targeting
627 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
628 if the tryents flag is set.
630 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
633 // LordHavoc: added this for my own use, VERY useful, similar to traceline
634 static void VM_SV_tracebox (void)
636 float *v1, *v2, *m1, *m2;
641 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
643 prog->xfunction->builtinsprofile += 30;
645 v1 = PRVM_G_VECTOR(OFS_PARM0);
646 m1 = PRVM_G_VECTOR(OFS_PARM1);
647 m2 = PRVM_G_VECTOR(OFS_PARM2);
648 v2 = PRVM_G_VECTOR(OFS_PARM3);
649 move = (int)PRVM_G_FLOAT(OFS_PARM4);
650 ent = PRVM_G_EDICT(OFS_PARM5);
652 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]))
653 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));
655 trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
657 VM_SetTraceGlobals(&trace);
660 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
665 vec3_t original_origin;
666 vec3_t original_velocity;
667 vec3_t original_angles;
668 vec3_t original_avelocity;
672 VectorCopy(tossent->fields.server->origin , original_origin );
673 VectorCopy(tossent->fields.server->velocity , original_velocity );
674 VectorCopy(tossent->fields.server->angles , original_angles );
675 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
677 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
678 if (val != NULL && val->_float != 0)
679 gravity = val->_float;
682 gravity *= sv_gravity.value * 0.025;
684 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
686 SV_CheckVelocity (tossent);
687 tossent->fields.server->velocity[2] -= gravity;
688 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
689 VectorScale (tossent->fields.server->velocity, 0.05, move);
690 VectorAdd (tossent->fields.server->origin, move, end);
691 trace = SV_TraceBox(tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
692 VectorCopy (trace.endpos, tossent->fields.server->origin);
693 tossent->fields.server->velocity[2] -= gravity;
695 if (trace.fraction < 1)
699 VectorCopy(original_origin , tossent->fields.server->origin );
700 VectorCopy(original_velocity , tossent->fields.server->velocity );
701 VectorCopy(original_angles , tossent->fields.server->angles );
702 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
707 static void VM_SV_tracetoss (void)
711 prvm_edict_t *ignore;
713 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
715 prog->xfunction->builtinsprofile += 600;
717 ent = PRVM_G_EDICT(OFS_PARM0);
718 if (ent == prog->edicts)
720 VM_Warning("tracetoss: can not use world entity\n");
723 ignore = PRVM_G_EDICT(OFS_PARM1);
725 trace = SV_Trace_Toss (ent, ignore);
727 VM_SetTraceGlobals(&trace);
730 //============================================================================
732 static int checkpvsbytes;
733 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
735 static int VM_SV_newcheckclient (int check)
741 // cycle to the next one
743 check = bound(1, check, svs.maxclients);
744 if (check == svs.maxclients)
752 prog->xfunction->builtinsprofile++;
754 if (i == svs.maxclients+1)
756 // look up the client's edict
757 ent = PRVM_EDICT_NUM(i);
758 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
759 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
761 // found a valid client (possibly the same one again)
765 // get the PVS for the entity
766 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
768 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
769 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
778 Returns a client (or object that has a client enemy) that would be a
781 If there is more than one valid option, they are cycled each frame
783 If (self.origin + self.viewofs) is not in the PVS of the current target,
784 it is not returned at all.
789 int c_invis, c_notvis;
790 static void VM_SV_checkclient (void)
792 prvm_edict_t *ent, *self;
795 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
797 // find a new check if on a new frame
798 if (sv.time - sv.lastchecktime >= 0.1)
800 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
801 sv.lastchecktime = sv.time;
804 // return check if it might be visible
805 ent = PRVM_EDICT_NUM(sv.lastcheck);
806 if (ent->priv.server->free || ent->fields.server->health <= 0)
808 VM_RETURN_EDICT(prog->edicts);
812 // if current entity can't possibly see the check entity, return 0
813 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
814 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
815 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
818 VM_RETURN_EDICT(prog->edicts);
822 // might be able to see it
824 VM_RETURN_EDICT(ent);
827 //============================================================================
833 Checks if an entity is in a point's PVS.
834 Should be fast but can be inexact.
836 float checkpvs(vector viewpos, entity viewee) = #240;
839 static void VM_SV_checkpvs (void)
842 prvm_edict_t *viewee;
847 unsigned char fatpvs[MAX_MAP_LEAFS/8];
850 VM_SAFEPARMCOUNT(2, VM_SV_checkpvs);
851 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos);
852 viewee = PRVM_G_EDICT(OFS_PARM1);
854 if(viewee->priv.server->free)
856 VM_Warning("checkpvs: can not check free entity\n");
857 PRVM_G_FLOAT(OFS_RETURN) = 4;
862 if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
864 // no PVS support on this worldmodel... darn
865 PRVM_G_FLOAT(OFS_RETURN) = 3;
868 pvs = sv.worldmodel->brush.GetPVS(sv.worldmodel, viewpos);
871 // viewpos isn't in any PVS... darn
872 PRVM_G_FLOAT(OFS_RETURN) = 2;
875 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
877 // using fat PVS like FTEQW does (slow)
878 if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
880 // no PVS support on this worldmodel... darn
881 PRVM_G_FLOAT(OFS_RETURN) = 3;
884 fatpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
887 // viewpos isn't in any PVS... darn
888 PRVM_G_FLOAT(OFS_RETURN) = 2;
891 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
900 Sends text over to the client's execution buffer
902 stuffcmd (clientent, value, ...)
905 static void VM_SV_stuffcmd (void)
909 char string[VM_STRINGTEMP_LENGTH];
911 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
913 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
914 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
916 VM_Warning("Can't stuffcmd to a non-client\n");
920 VM_VarString(1, string, sizeof(string));
923 host_client = svs.clients + entnum-1;
924 Host_ClientCommands ("%s", string);
932 Returns a chain of entities that have origins within a spherical area
934 findradius (origin, radius)
937 static void VM_SV_findradius (void)
939 prvm_edict_t *ent, *chain;
940 vec_t radius, radius2;
941 vec3_t org, eorg, mins, maxs;
944 static prvm_edict_t *touchedicts[MAX_EDICTS];
947 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findradius);
950 chainfield = PRVM_G_INT(OFS_PARM2);
952 chainfield = prog->fieldoffsets.chain;
954 PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
956 chain = (prvm_edict_t *)prog->edicts;
958 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
959 radius = PRVM_G_FLOAT(OFS_PARM1);
960 radius2 = radius * radius;
962 mins[0] = org[0] - (radius + 1);
963 mins[1] = org[1] - (radius + 1);
964 mins[2] = org[2] - (radius + 1);
965 maxs[0] = org[0] + (radius + 1);
966 maxs[1] = org[1] + (radius + 1);
967 maxs[2] = org[2] + (radius + 1);
968 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
969 if (numtouchedicts > MAX_EDICTS)
971 // this never happens
972 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
973 numtouchedicts = MAX_EDICTS;
975 for (i = 0;i < numtouchedicts;i++)
977 ent = touchedicts[i];
978 prog->xfunction->builtinsprofile++;
979 // Quake did not return non-solid entities but darkplaces does
980 // (note: this is the reason you can't blow up fallen zombies)
981 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
983 // LordHavoc: compare against bounding box rather than center so it
984 // doesn't miss large objects, and use DotProduct instead of Length
985 // for a major speedup
986 VectorSubtract(org, ent->fields.server->origin, eorg);
987 if (sv_gameplayfix_findradiusdistancetobox.integer)
989 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
990 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
991 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
994 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
995 if (DotProduct(eorg, eorg) < radius2)
997 PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
1002 VM_RETURN_EDICT(chain);
1005 static void VM_SV_precache_sound (void)
1007 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
1008 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
1011 static void VM_SV_precache_model (void)
1013 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
1014 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
1015 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
1022 float(float yaw, float dist[, settrace]) walkmove
1025 static void VM_SV_walkmove (void)
1034 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
1036 // assume failure if it returns early
1037 PRVM_G_FLOAT(OFS_RETURN) = 0;
1039 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1040 if (ent == prog->edicts)
1042 VM_Warning("walkmove: can not modify world entity\n");
1045 if (ent->priv.server->free)
1047 VM_Warning("walkmove: can not modify free entity\n");
1050 yaw = PRVM_G_FLOAT(OFS_PARM0);
1051 dist = PRVM_G_FLOAT(OFS_PARM1);
1052 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
1054 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1057 yaw = yaw*M_PI*2 / 360;
1059 move[0] = cos(yaw)*dist;
1060 move[1] = sin(yaw)*dist;
1063 // save program state, because SV_movestep may call other progs
1064 oldf = prog->xfunction;
1065 oldself = prog->globals.server->self;
1067 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
1070 // restore program state
1071 prog->xfunction = oldf;
1072 prog->globals.server->self = oldself;
1082 static void VM_SV_droptofloor (void)
1088 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
1090 // assume failure if it returns early
1091 PRVM_G_FLOAT(OFS_RETURN) = 0;
1093 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1094 if (ent == prog->edicts)
1096 VM_Warning("droptofloor: can not modify world entity\n");
1099 if (ent->priv.server->free)
1101 VM_Warning("droptofloor: can not modify free entity\n");
1105 VectorCopy (ent->fields.server->origin, end);
1108 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
1109 SV_UnstickEntity(ent);
1111 trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1112 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
1115 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]);
1116 VectorAdd(ent->fields.server->origin, offset, org);
1117 trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1118 VectorSubtract(trace.endpos, offset, trace.endpos);
1119 if (trace.startsolid)
1121 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]);
1122 SV_UnstickEntity(ent);
1124 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1125 ent->fields.server->groundentity = 0;
1126 PRVM_G_FLOAT(OFS_RETURN) = 1;
1128 else if (trace.fraction < 1)
1130 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]);
1131 VectorCopy (trace.endpos, ent->fields.server->origin);
1132 SV_UnstickEntity(ent);
1134 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1135 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1136 PRVM_G_FLOAT(OFS_RETURN) = 1;
1137 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1138 ent->priv.server->suspendedinairflag = true;
1143 if (trace.fraction != 1)
1145 if (trace.fraction < 1)
1146 VectorCopy (trace.endpos, ent->fields.server->origin);
1148 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1149 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1150 PRVM_G_FLOAT(OFS_RETURN) = 1;
1151 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1152 ent->priv.server->suspendedinairflag = true;
1161 void(float style, string value) lightstyle
1164 static void VM_SV_lightstyle (void)
1171 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1173 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1174 val = PRVM_G_STRING(OFS_PARM1);
1176 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1177 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1180 // change the string in sv
1181 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1183 // send message to all clients on this server
1184 if (sv.state != ss_active)
1187 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1189 if (client->active && client->netconnection)
1191 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1192 MSG_WriteChar (&client->netconnection->message,style);
1193 MSG_WriteString (&client->netconnection->message, val);
1203 static void VM_SV_checkbottom (void)
1205 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1206 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1214 static void VM_SV_pointcontents (void)
1216 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1217 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1224 Pick a vector for the player to shoot along
1225 vector aim(entity, missilespeed)
1228 static void VM_SV_aim (void)
1230 prvm_edict_t *ent, *check, *bestent;
1231 vec3_t start, dir, end, bestdir;
1234 float dist, bestdist;
1237 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1239 // assume failure if it returns early
1240 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1241 // if sv_aim is so high it can't possibly accept anything, skip out early
1242 if (sv_aim.value >= 1)
1245 ent = PRVM_G_EDICT(OFS_PARM0);
1246 if (ent == prog->edicts)
1248 VM_Warning("aim: can not use world entity\n");
1251 if (ent->priv.server->free)
1253 VM_Warning("aim: can not use free entity\n");
1256 //speed = PRVM_G_FLOAT(OFS_PARM1);
1258 VectorCopy (ent->fields.server->origin, start);
1261 // try sending a trace straight
1262 VectorCopy (prog->globals.server->v_forward, dir);
1263 VectorMA (start, 2048, dir, end);
1264 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1265 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1266 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1268 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1273 // try all possible entities
1274 VectorCopy (dir, bestdir);
1275 bestdist = sv_aim.value;
1278 check = PRVM_NEXT_EDICT(prog->edicts);
1279 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1281 prog->xfunction->builtinsprofile++;
1282 if (check->fields.server->takedamage != DAMAGE_AIM)
1286 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1287 continue; // don't aim at teammate
1288 for (j=0 ; j<3 ; j++)
1289 end[j] = check->fields.server->origin[j]
1290 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1291 VectorSubtract (end, start, dir);
1292 VectorNormalize (dir);
1293 dist = DotProduct (dir, prog->globals.server->v_forward);
1294 if (dist < bestdist)
1295 continue; // to far to turn
1296 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1297 if (tr.ent == check)
1298 { // can shoot at this one
1306 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1307 dist = DotProduct (dir, prog->globals.server->v_forward);
1308 VectorScale (prog->globals.server->v_forward, dist, end);
1310 VectorNormalize (end);
1311 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1315 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1320 ===============================================================================
1324 ===============================================================================
1327 #define MSG_BROADCAST 0 // unreliable to all
1328 #define MSG_ONE 1 // reliable to one (msg_entity)
1329 #define MSG_ALL 2 // reliable to all
1330 #define MSG_INIT 3 // write to the init string
1331 #define MSG_ENTITY 5
1333 sizebuf_t *WriteDest (void)
1339 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1343 return &sv.datagram;
1346 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1347 entnum = PRVM_NUM_FOR_EDICT(ent);
1348 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1350 VM_Warning ("WriteDest: tried to write to non-client\n");
1351 return &sv.reliable_datagram;
1354 return &svs.clients[entnum-1].netconnection->message;
1357 VM_Warning ("WriteDest: bad destination\n");
1359 return &sv.reliable_datagram;
1365 return sv.writeentitiestoclient_msg;
1371 static void VM_SV_WriteByte (void)
1373 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1374 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1377 static void VM_SV_WriteChar (void)
1379 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1380 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1383 static void VM_SV_WriteShort (void)
1385 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1386 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1389 static void VM_SV_WriteLong (void)
1391 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1392 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1395 static void VM_SV_WriteAngle (void)
1397 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1398 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1401 static void VM_SV_WriteCoord (void)
1403 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1404 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1407 static void VM_SV_WriteString (void)
1409 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1410 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1413 static void VM_SV_WriteUnterminatedString (void)
1415 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1416 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1420 static void VM_SV_WriteEntity (void)
1422 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1423 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1426 // writes a picture as at most size bytes of data
1428 // IMGNAME \0 SIZE(short) IMGDATA
1429 // if failed to read/compress:
1431 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1432 static void VM_SV_WritePicture (void)
1434 const char *imgname;
1438 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1440 imgname = PRVM_G_STRING(OFS_PARM1);
1441 size = (int) PRVM_G_FLOAT(OFS_PARM2);
1445 MSG_WriteString(WriteDest(), imgname);
1446 if(Image_Compress(imgname, size, &buf, &size))
1449 MSG_WriteShort(WriteDest(), size);
1450 SZ_Write(WriteDest(), (unsigned char *) buf, size);
1455 MSG_WriteShort(WriteDest(), 0);
1459 //////////////////////////////////////////////////////////
1461 static void VM_SV_makestatic (void)
1466 // allow 0 parameters due to an id1 qc bug in which this function is used
1467 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1468 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1470 if (prog->argc >= 1)
1471 ent = PRVM_G_EDICT(OFS_PARM0);
1473 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1474 if (ent == prog->edicts)
1476 VM_Warning("makestatic: can not modify world entity\n");
1479 if (ent->priv.server->free)
1481 VM_Warning("makestatic: can not modify free entity\n");
1486 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1491 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1492 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1493 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1495 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1497 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1498 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1499 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1503 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1504 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1505 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1508 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1509 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1510 for (i=0 ; i<3 ; i++)
1512 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1513 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1516 // throw the entity away now
1520 //=============================================================================
1527 static void VM_SV_setspawnparms (void)
1533 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1535 ent = PRVM_G_EDICT(OFS_PARM0);
1536 i = PRVM_NUM_FOR_EDICT(ent);
1537 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1539 Con_Print("tried to setspawnparms on a non-client\n");
1543 // copy spawn parms out of the client_t
1544 client = svs.clients + i-1;
1545 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1546 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1553 Returns a color vector indicating the lighting at the requested point.
1555 (Internal Operation note: actually measures the light beneath the point, just like
1556 the model lighting on the client)
1561 static void VM_SV_getlight (void)
1563 vec3_t ambientcolor, diffusecolor, diffusenormal;
1565 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1566 p = PRVM_G_VECTOR(OFS_PARM0);
1567 VectorClear(ambientcolor);
1568 VectorClear(diffusecolor);
1569 VectorClear(diffusenormal);
1570 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1571 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1572 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1577 unsigned char type; // 1/2/8 or other value if isn't used
1581 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1582 static int vm_customstats_last;
1584 void VM_CustomStats_Clear (void)
1588 Z_Free(vm_customstats);
1589 vm_customstats = NULL;
1590 vm_customstats_last = -1;
1594 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1602 for(i=0; i<vm_customstats_last+1 ;i++)
1604 if(!vm_customstats[i].type)
1606 switch(vm_customstats[i].type)
1608 //string as 16 bytes
1611 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1612 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1613 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1614 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1615 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1617 //float field sent as-is
1619 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1621 //integer value of float field
1623 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1631 // void(float index, float type, .void field) SV_AddStat = #232;
1632 // Set up an auto-sent player stat.
1633 // Client's get thier own fields sent to them. Index may not be less than 32.
1634 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1635 // 1: string (4 stats carrying a total of 16 charactures)
1636 // 2: float (one stat, float converted to an integer for transportation)
1637 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1638 static void VM_SV_AddStat (void)
1643 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1647 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1650 VM_Warning("PF_SV_AddStat: not enough memory\n");
1654 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1655 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1656 off = PRVM_G_INT (OFS_PARM2);
1661 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1664 if(i >= (MAX_CL_STATS-32))
1666 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1669 if(i > (MAX_CL_STATS-32-4) && type == 1)
1671 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1674 vm_customstats[i].type = type;
1675 vm_customstats[i].fieldoffset = off;
1676 if(vm_customstats_last < i)
1677 vm_customstats_last = i;
1684 copies data from one entity to another
1686 copyentity(src, dst)
1689 static void VM_SV_copyentity (void)
1691 prvm_edict_t *in, *out;
1692 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1693 in = PRVM_G_EDICT(OFS_PARM0);
1694 if (in == prog->edicts)
1696 VM_Warning("copyentity: can not read world entity\n");
1699 if (in->priv.server->free)
1701 VM_Warning("copyentity: can not read free entity\n");
1704 out = PRVM_G_EDICT(OFS_PARM1);
1705 if (out == prog->edicts)
1707 VM_Warning("copyentity: can not modify world entity\n");
1710 if (out->priv.server->free)
1712 VM_Warning("copyentity: can not modify free entity\n");
1715 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1724 sets the color of a client and broadcasts the update to all connected clients
1726 setcolor(clientent, value)
1729 static void VM_SV_setcolor (void)
1735 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1736 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1737 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1739 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1741 Con_Print("tried to setcolor a non-client\n");
1745 client = svs.clients + entnum-1;
1748 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1750 client->edict->fields.server->team = (i & 15) + 1;
1753 if (client->old_colors != client->colors)
1755 client->old_colors = client->colors;
1756 // send notification to all clients
1757 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1758 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1759 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1767 effect(origin, modelname, startframe, framecount, framerate)
1770 static void VM_SV_effect (void)
1774 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1775 s = PRVM_G_STRING(OFS_PARM1);
1778 VM_Warning("effect: no model specified\n");
1782 i = SV_ModelIndex(s, 1);
1785 VM_Warning("effect: model not precached\n");
1789 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1791 VM_Warning("effect: framecount < 1\n");
1795 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1797 VM_Warning("effect: framerate < 1\n");
1801 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));
1804 static void VM_SV_te_blood (void)
1806 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1807 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1809 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1810 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1812 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1814 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1816 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1817 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1818 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1820 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1821 SV_FlushBroadcastMessages();
1824 static void VM_SV_te_bloodshower (void)
1826 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1827 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1829 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1830 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1833 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1834 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1836 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1837 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1838 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1840 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1842 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1843 SV_FlushBroadcastMessages();
1846 static void VM_SV_te_explosionrgb (void)
1848 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1849 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1850 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1852 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1853 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1854 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1856 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1857 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1858 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1859 SV_FlushBroadcastMessages();
1862 static void VM_SV_te_particlecube (void)
1864 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1865 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1867 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1868 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1871 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1872 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1874 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1875 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1876 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1878 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1879 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1880 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1882 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1884 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1885 // gravity true/false
1886 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1888 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1889 SV_FlushBroadcastMessages();
1892 static void VM_SV_te_particlerain (void)
1894 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1895 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1897 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1898 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1902 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1904 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1905 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1906 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1908 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1909 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1910 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1912 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1914 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1915 SV_FlushBroadcastMessages();
1918 static void VM_SV_te_particlesnow (void)
1920 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1921 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1923 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1924 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1926 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1927 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1928 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1930 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1931 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1934 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1935 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1936 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1938 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1940 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1941 SV_FlushBroadcastMessages();
1944 static void VM_SV_te_spark (void)
1946 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1947 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1949 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1950 MSG_WriteByte(&sv.datagram, TE_SPARK);
1952 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1953 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1954 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1956 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1957 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1958 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1960 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1961 SV_FlushBroadcastMessages();
1964 static void VM_SV_te_gunshotquad (void)
1966 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1967 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1968 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1970 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1973 SV_FlushBroadcastMessages();
1976 static void VM_SV_te_spikequad (void)
1978 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1979 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1980 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1982 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1983 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1984 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1985 SV_FlushBroadcastMessages();
1988 static void VM_SV_te_superspikequad (void)
1990 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1991 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1992 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1994 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1996 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1997 SV_FlushBroadcastMessages();
2000 static void VM_SV_te_explosionquad (void)
2002 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
2003 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2004 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2006 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2007 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2008 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2009 SV_FlushBroadcastMessages();
2012 static void VM_SV_te_smallflash (void)
2014 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
2015 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2016 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2018 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2019 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2020 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2021 SV_FlushBroadcastMessages();
2024 static void VM_SV_te_customflash (void)
2026 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
2027 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2029 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2030 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2032 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2033 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2034 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2036 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2038 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
2040 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
2041 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
2042 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
2043 SV_FlushBroadcastMessages();
2046 static void VM_SV_te_gunshot (void)
2048 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
2049 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2050 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2052 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2053 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2054 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2055 SV_FlushBroadcastMessages();
2058 static void VM_SV_te_spike (void)
2060 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
2061 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2062 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2064 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2065 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2066 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2067 SV_FlushBroadcastMessages();
2070 static void VM_SV_te_superspike (void)
2072 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
2073 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2074 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2076 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2077 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2078 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2079 SV_FlushBroadcastMessages();
2082 static void VM_SV_te_explosion (void)
2084 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
2085 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2086 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2088 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2089 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2090 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2091 SV_FlushBroadcastMessages();
2094 static void VM_SV_te_tarexplosion (void)
2096 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
2097 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2098 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2100 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2101 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2102 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2103 SV_FlushBroadcastMessages();
2106 static void VM_SV_te_wizspike (void)
2108 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
2109 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2110 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2112 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2113 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2114 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2115 SV_FlushBroadcastMessages();
2118 static void VM_SV_te_knightspike (void)
2120 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2121 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2122 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2124 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2125 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2126 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2127 SV_FlushBroadcastMessages();
2130 static void VM_SV_te_lavasplash (void)
2132 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2133 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2134 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2136 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2137 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2138 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2139 SV_FlushBroadcastMessages();
2142 static void VM_SV_te_teleport (void)
2144 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2145 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2146 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2148 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2149 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2150 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2151 SV_FlushBroadcastMessages();
2154 static void VM_SV_te_explosion2 (void)
2156 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2157 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2158 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2160 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2161 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2162 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2164 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2165 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2166 SV_FlushBroadcastMessages();
2169 static void VM_SV_te_lightning1 (void)
2171 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2172 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2173 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2175 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2177 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2178 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2179 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2181 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2182 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2183 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2184 SV_FlushBroadcastMessages();
2187 static void VM_SV_te_lightning2 (void)
2189 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2190 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2191 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2193 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2195 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2196 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2197 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2199 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2200 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2201 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2202 SV_FlushBroadcastMessages();
2205 static void VM_SV_te_lightning3 (void)
2207 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2208 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2209 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2211 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2213 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2214 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2215 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2217 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2218 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2219 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2220 SV_FlushBroadcastMessages();
2223 static void VM_SV_te_beam (void)
2225 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2226 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2227 MSG_WriteByte(&sv.datagram, TE_BEAM);
2229 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2231 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2232 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2233 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2235 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2236 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2237 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2238 SV_FlushBroadcastMessages();
2241 static void VM_SV_te_plasmaburn (void)
2243 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2244 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2245 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2246 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2247 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2248 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2249 SV_FlushBroadcastMessages();
2252 static void VM_SV_te_flamejet (void)
2254 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2255 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2256 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2258 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2259 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2260 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2262 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2263 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2264 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2266 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2267 SV_FlushBroadcastMessages();
2270 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2271 //this function originally written by KrimZon, made shorter by LordHavoc
2272 static void VM_SV_clientcommand (void)
2274 client_t *temp_client;
2276 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2278 //find client for this entity
2279 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2280 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2282 Con_Print("PF_clientcommand: entity is not a client\n");
2286 temp_client = host_client;
2287 host_client = svs.clients + i;
2288 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2289 host_client = temp_client;
2292 //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)
2293 static void VM_SV_setattachment (void)
2295 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2296 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2297 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2300 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2302 if (e == prog->edicts)
2304 VM_Warning("setattachment: can not modify world entity\n");
2307 if (e->priv.server->free)
2309 VM_Warning("setattachment: can not modify free entity\n");
2313 if (tagentity == NULL)
2314 tagentity = prog->edicts;
2316 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2318 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2320 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2323 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2325 model = SV_GetModelFromEdict(tagentity);
2328 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2330 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);
2333 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));
2337 /////////////////////////////////////////
2338 // DP_MD3_TAGINFO extension coded by VorteX
2340 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2344 i = (int)e->fields.server->modelindex;
2345 if (i < 1 || i >= MAX_MODELS)
2348 return Mod_Alias_GetTagIndexForName(SV_GetModelByIndex(i), (int)e->fields.server->skin, tagname);
2351 int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
2358 Matrix4x4_CreateIdentity(tag_localmatrix);
2360 if (tagindex >= 0 && (model = SV_GetModelFromEdict(e)) && model->num_bones)
2362 r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, e->priv.server->frameblend, &e->priv.server->skeleton, tagindex - 1, parentindex, tagname, tag_localmatrix);
2373 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2377 float pitchsign = 1;
2380 val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
2381 if (val && val->_float != 0)
2382 scale = val->_float;
2385 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);
2388 pitchsign = SV_GetPitchSign(ent);
2389 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);
2393 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2396 if (tagindex >= 0 && (model = SV_GetModelFromEdict(ent)) && model->animscenes)
2398 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2399 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2400 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2401 return Mod_Alias_GetTagMatrix(model, ent->priv.server->frameblend, &ent->priv.server->skeleton, tagindex, out);
2403 *out = identitymatrix;
2407 // Warnings/errors code:
2408 // 0 - normal (everything all-right)
2411 // 3 - null or non-precached model
2412 // 4 - no tags with requested index
2413 // 5 - runaway loop at attachment chain
2414 extern cvar_t cl_bob;
2415 extern cvar_t cl_bobcycle;
2416 extern cvar_t cl_bobup;
2417 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2421 int modelindex, attachloop;
2422 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2425 *out = identitymatrix; // warnings and errors return identical matrix
2427 if (ent == prog->edicts)
2429 if (ent->priv.server->free)
2432 modelindex = (int)ent->fields.server->modelindex;
2433 if (modelindex <= 0 || modelindex >= MAX_MODELS)
2436 model = SV_GetModelByIndex(modelindex);
2438 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2439 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2440 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2442 tagmatrix = identitymatrix;
2443 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2447 if (attachloop >= 256) // prevent runaway looping
2449 // apply transformation by child's tagindex on parent entity and then
2450 // by parent entity itself
2451 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2452 if (ret && attachloop == 0)
2454 SV_GetEntityMatrix(ent, &entitymatrix, false);
2455 Matrix4x4_Concat(&tagmatrix, &attachmatrix, out);
2456 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2457 // next iteration we process the parent entity
2458 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2460 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2461 ent = PRVM_EDICT_NUM(val->edict);
2468 // RENDER_VIEWMODEL magic
2469 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2471 Matrix4x4_Copy(&tagmatrix, out);
2472 ent = PRVM_EDICT_NUM(val->edict);
2474 SV_GetEntityMatrix(ent, &entitymatrix, true);
2475 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2478 // Cl_bob, ported from rendering code
2479 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2482 // LordHavoc: this code is *weird*, but not replacable (I think it
2483 // should be done in QC on the server, but oh well, quake is quake)
2484 // LordHavoc: figured out bobup: the time at which the sin is at 180
2485 // degrees (which allows lengthening or squishing the peak or valley)
2486 cycle = sv.time/cl_bobcycle.value;
2487 cycle -= (int)cycle;
2488 if (cycle < cl_bobup.value)
2489 cycle = sin(M_PI * cycle / cl_bobup.value);
2491 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2492 // bob is proportional to velocity in the xy plane
2493 // (don't count Z, or jumping messes it up)
2494 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;
2495 bob = bob*0.3 + bob*0.7*cycle;
2496 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2503 //float(entity ent, string tagname) gettagindex;
2505 static void VM_SV_gettagindex (void)
2508 const char *tag_name;
2511 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2513 ent = PRVM_G_EDICT(OFS_PARM0);
2514 tag_name = PRVM_G_STRING(OFS_PARM1);
2516 if (ent == prog->edicts)
2518 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
2521 if (ent->priv.server->free)
2523 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
2528 if (!SV_GetModelFromEdict(ent))
2529 Con_DPrintf("VM_SV_gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2532 tag_index = SV_GetTagIndex(ent, tag_name);
2534 if(developer_extra.integer)
2535 Con_DPrintf("VM_SV_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2537 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2540 //vector(entity ent, float tagindex) gettaginfo;
2541 static void VM_SV_gettaginfo (void)
2545 matrix4x4_t tag_matrix;
2546 matrix4x4_t tag_localmatrix;
2548 const char *tagname;
2551 vec3_t fo, le, up, trans;
2552 const dp_model_t *model;
2554 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2556 e = PRVM_G_EDICT(OFS_PARM0);
2557 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2559 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2560 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, le, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2561 VectorScale(le, -1, prog->globals.server->v_right);
2562 model = SV_GetModelFromEdict(e);
2563 VM_GenerateFrameGroupBlend(e->priv.server->framegroupblend, e);
2564 VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model);
2565 VM_UpdateEdictSkeleton(e, model, e->priv.server->frameblend);
2566 SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
2567 Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
2569 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
2570 val->_float = parentindex;
2571 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
2572 val->string = tagname ? PRVM_SetTempString(tagname) : 0;
2573 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
2574 VectorCopy(trans, val->vector);
2575 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
2576 VectorCopy(fo, val->vector);
2577 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
2578 VectorScale(le, -1, val->vector);
2579 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
2580 VectorCopy(up, val->vector);
2585 VM_Warning("gettagindex: can't affect world entity\n");
2588 VM_Warning("gettagindex: can't affect free entity\n");
2591 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2594 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2597 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2602 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2603 static void VM_SV_dropclient (void)
2606 client_t *oldhostclient;
2607 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2608 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2609 if (clientnum < 0 || clientnum >= svs.maxclients)
2611 VM_Warning("dropclient: not a client\n");
2614 if (!svs.clients[clientnum].active)
2616 VM_Warning("dropclient: that client slot is not connected\n");
2619 oldhostclient = host_client;
2620 host_client = svs.clients + clientnum;
2621 SV_DropClient(false);
2622 host_client = oldhostclient;
2625 //entity() spawnclient (DP_SV_BOTCLIENT)
2626 static void VM_SV_spawnclient (void)
2630 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2631 prog->xfunction->builtinsprofile += 2;
2633 for (i = 0;i < svs.maxclients;i++)
2635 if (!svs.clients[i].active)
2637 prog->xfunction->builtinsprofile += 100;
2638 SV_ConnectClient (i, NULL);
2639 // this has to be set or else ClientDisconnect won't be called
2640 // we assume the qc will call ClientConnect...
2641 svs.clients[i].clientconnectcalled = true;
2642 ed = PRVM_EDICT_NUM(i + 1);
2646 VM_RETURN_EDICT(ed);
2649 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2650 static void VM_SV_clienttype (void)
2653 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2654 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2655 if (clientnum < 0 || clientnum >= svs.maxclients)
2656 PRVM_G_FLOAT(OFS_RETURN) = 3;
2657 else if (!svs.clients[clientnum].active)
2658 PRVM_G_FLOAT(OFS_RETURN) = 0;
2659 else if (svs.clients[clientnum].netconnection)
2660 PRVM_G_FLOAT(OFS_RETURN) = 1;
2662 PRVM_G_FLOAT(OFS_RETURN) = 2;
2669 string(string key) serverkey
2672 void VM_SV_serverkey(void)
2674 char string[VM_STRINGTEMP_LENGTH];
2675 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2676 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2677 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2680 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2681 static void VM_SV_setmodelindex (void)
2686 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2688 e = PRVM_G_EDICT(OFS_PARM0);
2689 if (e == prog->edicts)
2691 VM_Warning("setmodelindex: can not modify world entity\n");
2694 if (e->priv.server->free)
2696 VM_Warning("setmodelindex: can not modify free entity\n");
2699 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2700 if (i <= 0 || i >= MAX_MODELS)
2702 VM_Warning("setmodelindex: invalid modelindex\n");
2705 if (!sv.model_precache[i][0])
2707 VM_Warning("setmodelindex: model not precached\n");
2711 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2712 e->fields.server->modelindex = i;
2714 mod = SV_GetModelByIndex(i);
2718 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2719 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2721 SetMinMaxSize (e, quakemins, quakemaxs, true);
2724 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2727 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2728 static void VM_SV_modelnameforindex (void)
2731 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2733 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2735 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2736 if (i <= 0 || i >= MAX_MODELS)
2738 VM_Warning("modelnameforindex: invalid modelindex\n");
2741 if (!sv.model_precache[i][0])
2743 VM_Warning("modelnameforindex: model not precached\n");
2747 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2750 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2751 static void VM_SV_particleeffectnum (void)
2754 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2755 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2758 PRVM_G_FLOAT(OFS_RETURN) = i;
2761 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2762 static void VM_SV_trailparticles (void)
2764 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2766 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2769 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2770 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2771 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2772 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2773 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2774 SV_FlushBroadcastMessages();
2777 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2778 static void VM_SV_pointparticles (void)
2780 int effectnum, count;
2782 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2784 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2787 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2788 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2789 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2790 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2791 if (count == 1 && !VectorLength2(vel))
2794 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2795 MSG_WriteShort(&sv.datagram, effectnum);
2796 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2800 // 1+2+12+12+2=29 bytes
2801 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2802 MSG_WriteShort(&sv.datagram, effectnum);
2803 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2804 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2805 MSG_WriteShort(&sv.datagram, count);
2808 SV_FlushBroadcastMessages();
2811 //PF_setpause, // void(float pause) setpause = #531;
2812 static void VM_SV_setpause(void) {
2814 pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
2815 if (pauseValue != 0) { //pause the game
2817 sv.pausedstart = Sys_DoubleTime();
2818 } else { //disable pause, in case it was enabled
2819 if (sv.paused != 0) {
2824 // send notification to all clients
2825 MSG_WriteByte(&sv.reliable_datagram, svc_setpause);
2826 MSG_WriteByte(&sv.reliable_datagram, sv.paused);
2829 // #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.
2830 static void VM_SV_skel_create(void)
2832 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
2833 dp_model_t *model = SV_GetModelByIndex(modelindex);
2834 skeleton_t *skeleton;
2836 PRVM_G_FLOAT(OFS_RETURN) = 0;
2837 if (!model || !model->num_bones)
2839 for (i = 0;i < MAX_EDICTS;i++)
2840 if (!prog->skeletons[i])
2842 if (i == MAX_EDICTS)
2844 prog->skeletons[i] = skeleton = (skeleton_t *)Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
2845 PRVM_G_FLOAT(OFS_RETURN) = i + 1;
2846 skeleton->model = model;
2847 skeleton->relativetransforms = (matrix4x4_t *)(skeleton+1);
2848 // initialize to identity matrices
2849 for (i = 0;i < skeleton->model->num_bones;i++)
2850 skeleton->relativetransforms[i] = identitymatrix;
2853 // #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
2854 static void VM_SV_skel_build(void)
2856 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2857 skeleton_t *skeleton;
2858 prvm_edict_t *ed = PRVM_G_EDICT(OFS_PARM1);
2859 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM2);
2860 float retainfrac = PRVM_G_FLOAT(OFS_PARM3);
2861 int firstbone = PRVM_G_FLOAT(OFS_PARM4) - 1;
2862 int lastbone = PRVM_G_FLOAT(OFS_PARM5) - 1;
2863 dp_model_t *model = SV_GetModelByIndex(modelindex);
2868 framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS];
2869 frameblend_t frameblend[MAX_FRAMEBLENDS];
2870 matrix4x4_t blendedmatrix;
2872 PRVM_G_FLOAT(OFS_RETURN) = 0;
2873 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2875 firstbone = max(0, firstbone);
2876 lastbone = min(lastbone, model->num_bones - 1);
2877 lastbone = min(lastbone, skeleton->model->num_bones - 1);
2878 VM_GenerateFrameGroupBlend(framegroupblend, ed);
2879 VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model);
2880 blendfrac = 1.0f - retainfrac;
2881 for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
2882 frameblend[numblends].lerp *= blendfrac;
2883 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
2885 memset(&blendedmatrix, 0, sizeof(blendedmatrix));
2886 Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac);
2887 for (blendindex = 0;blendindex < numblends;blendindex++)
2889 Matrix4x4_FromBonePose6s(&matrix, model->num_posescale, model->data_poses6s + 6 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
2890 Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp);
2892 skeleton->relativetransforms[bonenum] = blendedmatrix;
2894 PRVM_G_FLOAT(OFS_RETURN) = skeletonindex + 1;
2897 // #265 float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS) returns how many bones exist in the created skeleton
2898 static void VM_SV_skel_get_numbones(void)
2900 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2901 skeleton_t *skeleton;
2902 PRVM_G_FLOAT(OFS_RETURN) = 0;
2903 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2905 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->num_bones;
2908 // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) returns name of bone (as a tempstring)
2909 static void VM_SV_skel_get_bonename(void)
2911 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2912 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2913 skeleton_t *skeleton;
2914 PRVM_G_INT(OFS_RETURN) = 0;
2915 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2917 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2919 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(skeleton->model->data_bones[bonenum].name);
2922 // #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)
2923 static void VM_SV_skel_get_boneparent(void)
2925 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2926 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2927 skeleton_t *skeleton;
2928 PRVM_G_FLOAT(OFS_RETURN) = 0;
2929 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2931 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2933 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->data_bones[bonenum].parent + 1;
2936 // #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
2937 static void VM_SV_skel_find_bone(void)
2939 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2940 const char *tagname = PRVM_G_STRING(OFS_PARM1);
2941 skeleton_t *skeleton;
2942 PRVM_G_FLOAT(OFS_RETURN) = 0;
2943 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2945 PRVM_G_FLOAT(OFS_RETURN) = Mod_Alias_GetTagIndexForName(skeleton->model, 0, tagname) + 1;
2948 // #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)
2949 static void VM_SV_skel_get_bonerel(void)
2951 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2952 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2953 skeleton_t *skeleton;
2955 vec3_t forward, left, up, origin;
2956 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2957 VectorClear(prog->globals.client->v_forward);
2958 VectorClear(prog->globals.client->v_right);
2959 VectorClear(prog->globals.client->v_up);
2960 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2962 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2964 matrix = skeleton->relativetransforms[bonenum];
2965 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2966 VectorCopy(forward, prog->globals.client->v_forward);
2967 VectorNegate(left, prog->globals.client->v_right);
2968 VectorCopy(up, prog->globals.client->v_up);
2969 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
2972 // #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)
2973 static void VM_SV_skel_get_boneabs(void)
2975 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2976 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2977 skeleton_t *skeleton;
2980 vec3_t forward, left, up, origin;
2981 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2982 VectorClear(prog->globals.client->v_forward);
2983 VectorClear(prog->globals.client->v_right);
2984 VectorClear(prog->globals.client->v_up);
2985 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2987 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2989 matrix = skeleton->relativetransforms[bonenum];
2990 // convert to absolute
2991 while ((bonenum = skeleton->model->data_bones[bonenum].parent) >= 0)
2994 Matrix4x4_Concat(&matrix, &skeleton->relativetransforms[bonenum], &temp);
2996 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2997 VectorCopy(forward, prog->globals.client->v_forward);
2998 VectorNegate(left, prog->globals.client->v_right);
2999 VectorCopy(up, prog->globals.client->v_up);
3000 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
3003 // #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)
3004 static void VM_SV_skel_set_bone(void)
3006 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3007 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3008 vec3_t forward, left, up, origin;
3009 skeleton_t *skeleton;
3011 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3013 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3015 VectorCopy(prog->globals.client->v_forward, forward);
3016 VectorNegate(prog->globals.client->v_right, left);
3017 VectorCopy(prog->globals.client->v_up, up);
3018 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3019 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3020 skeleton->relativetransforms[bonenum] = matrix;
3023 // #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)
3024 static void VM_SV_skel_mul_bone(void)
3026 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3027 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3028 vec3_t forward, left, up, origin;
3029 skeleton_t *skeleton;
3032 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3034 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3036 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3037 VectorCopy(prog->globals.client->v_forward, forward);
3038 VectorNegate(prog->globals.client->v_right, left);
3039 VectorCopy(prog->globals.client->v_up, up);
3040 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3041 temp = skeleton->relativetransforms[bonenum];
3042 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3045 // #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)
3046 static void VM_SV_skel_mul_bones(void)
3048 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3049 int firstbone = PRVM_G_FLOAT(OFS_PARM1) - 1;
3050 int lastbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3052 vec3_t forward, left, up, origin;
3053 skeleton_t *skeleton;
3056 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3058 VectorCopy(PRVM_G_VECTOR(OFS_PARM3), origin);
3059 VectorCopy(prog->globals.client->v_forward, forward);
3060 VectorNegate(prog->globals.client->v_right, left);
3061 VectorCopy(prog->globals.client->v_up, up);
3062 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3063 firstbone = max(0, firstbone);
3064 lastbone = min(lastbone, skeleton->model->num_bones - 1);
3065 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3067 temp = skeleton->relativetransforms[bonenum];
3068 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3072 // #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
3073 static void VM_SV_skel_copybones(void)
3075 int skeletonindexdst = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3076 int skeletonindexsrc = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3077 int firstbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3078 int lastbone = PRVM_G_FLOAT(OFS_PARM3) - 1;
3080 skeleton_t *skeletondst;
3081 skeleton_t *skeletonsrc;
3082 if (skeletonindexdst < 0 || skeletonindexdst >= MAX_EDICTS || !(skeletondst = prog->skeletons[skeletonindexdst]))
3084 if (skeletonindexsrc < 0 || skeletonindexsrc >= MAX_EDICTS || !(skeletonsrc = prog->skeletons[skeletonindexsrc]))
3086 firstbone = max(0, firstbone);
3087 lastbone = min(lastbone, skeletondst->model->num_bones - 1);
3088 lastbone = min(lastbone, skeletonsrc->model->num_bones - 1);
3089 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3090 skeletondst->relativetransforms[bonenum] = skeletonsrc->relativetransforms[bonenum];
3093 // #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)
3094 static void VM_SV_skel_delete(void)
3096 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3097 skeleton_t *skeleton;
3098 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3101 prog->skeletons[skeletonindex] = NULL;
3104 // #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
3105 static void VM_SV_frameforname(void)
3107 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3108 dp_model_t *model = SV_GetModelByIndex(modelindex);
3109 const char *name = PRVM_G_STRING(OFS_PARM1);
3111 PRVM_G_FLOAT(OFS_RETURN) = -1;
3112 if (!model || !model->animscenes)
3114 for (i = 0;i < model->numframes;i++)
3116 if (!strcasecmp(model->animscenes[i].name, name))
3118 PRVM_G_FLOAT(OFS_RETURN) = i;
3124 // #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.
3125 static void VM_SV_frameduration(void)
3127 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3128 dp_model_t *model = SV_GetModelByIndex(modelindex);
3129 int framenum = (int)PRVM_G_FLOAT(OFS_PARM1);
3130 PRVM_G_FLOAT(OFS_RETURN) = 0;
3131 if (!model || !model->animscenes || framenum < 0 || framenum >= model->numframes)
3133 if (model->animscenes[framenum].framerate)
3134 PRVM_G_FLOAT(OFS_RETURN) = model->animscenes[framenum].framecount / model->animscenes[framenum].framerate;
3138 prvm_builtin_t vm_sv_builtins[] = {
3139 NULL, // #0 NULL function (not callable) (QUAKE)
3140 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
3141 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
3142 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
3143 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
3144 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
3145 VM_break, // #6 void() break (QUAKE)
3146 VM_random, // #7 float() random (QUAKE)
3147 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
3148 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
3149 VM_error, // #10 void(string e) error (QUAKE)
3150 VM_objerror, // #11 void(string e) objerror (QUAKE)
3151 VM_vlen, // #12 float(vector v) vlen (QUAKE)
3152 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
3153 VM_spawn, // #14 entity() spawn (QUAKE)
3154 VM_remove, // #15 void(entity e) remove (QUAKE)
3155 VM_SV_traceline, // #16 void(vector v1, vector v2, float tryents) traceline (QUAKE)
3156 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
3157 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
3158 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
3159 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
3160 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
3161 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
3162 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
3163 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
3164 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
3165 VM_ftos, // #26 string(float f) ftos (QUAKE)
3166 VM_vtos, // #27 string(vector v) vtos (QUAKE)
3167 VM_coredump, // #28 void() coredump (QUAKE)
3168 VM_traceon, // #29 void() traceon (QUAKE)
3169 VM_traceoff, // #30 void() traceoff (QUAKE)
3170 VM_eprint, // #31 void(entity e) eprint (QUAKE)
3171 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
3172 NULL, // #33 (QUAKE)
3173 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
3174 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
3175 VM_rint, // #36 float(float v) rint (QUAKE)
3176 VM_floor, // #37 float(float v) floor (QUAKE)
3177 VM_ceil, // #38 float(float v) ceil (QUAKE)
3178 NULL, // #39 (QUAKE)
3179 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
3180 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
3181 NULL, // #42 (QUAKE)
3182 VM_fabs, // #43 float(float f) fabs (QUAKE)
3183 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
3184 VM_cvar, // #45 float(string s) cvar (QUAKE)
3185 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
3186 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
3187 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
3188 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
3189 NULL, // #50 (QUAKE)
3190 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
3191 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
3192 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
3193 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
3194 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
3195 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
3196 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
3197 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
3198 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
3199 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
3200 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
3201 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
3202 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
3203 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
3204 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
3205 NULL, // #66 (QUAKE)
3206 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
3207 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
3208 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
3209 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
3210 NULL, // #71 (QUAKE)
3211 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
3212 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
3213 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
3214 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
3215 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
3216 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
3217 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
3218 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
3219 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
3220 VM_stof, // #81 float(string s) stof (FRIK_FILE)
3221 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
3222 NULL, // #83 (QUAKE)
3223 NULL, // #84 (QUAKE)
3224 NULL, // #85 (QUAKE)
3225 NULL, // #86 (QUAKE)
3226 NULL, // #87 (QUAKE)
3227 NULL, // #88 (QUAKE)
3228 NULL, // #89 (QUAKE)
3229 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
3230 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
3231 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
3232 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
3233 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
3234 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3235 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3236 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3237 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3238 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3239 // FrikaC and Telejano range #100-#199
3250 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3251 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3252 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3253 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3254 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3255 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3256 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3257 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3258 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3259 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3340 // FTEQW range #200-#299
3359 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3362 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3363 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3364 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3365 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3366 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3367 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3368 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3369 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3370 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3371 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3373 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3381 VM_SV_checkpvs, // #240 float(vector viewpos, entity viewee) checkpvs;
3404 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.
3405 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
3406 VM_SV_skel_get_numbones, // #265 float(float skel) skel_get_numbones = #265; // (DP_SKELETONOBJECTS) returns how many bones exist in the created skeleton
3407 VM_SV_skel_get_bonename, // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (DP_SKELETONOBJECTS) returns name of bone (as a tempstring)
3408 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)
3409 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
3410 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)
3411 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)
3412 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)
3413 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)
3414 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)
3415 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
3416 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)
3417 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
3418 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.
3441 // CSQC range #300-#399
3442 NULL, // #300 void() clearscene (EXT_CSQC)
3443 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3444 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3445 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3446 NULL, // #304 void() renderscene (EXT_CSQC)
3447 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3448 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3449 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3450 NULL, // #308 void() R_EndPolygon
3452 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3453 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3457 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3458 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3459 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3460 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3461 NULL, // #319 void(string name) freepic (EXT_CSQC)
3462 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3463 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3464 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3465 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3466 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3467 NULL, // #325 void(void) drawresetcliparea
3472 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3473 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3474 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3475 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3476 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3477 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3478 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3479 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3480 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3481 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3482 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3483 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3484 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3485 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3486 NULL, // #344 vector() getmousepos (EXT_CSQC)
3487 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3488 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3489 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3490 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3491 NULL, // #349 float() isdemo (EXT_CSQC)
3492 VM_isserver, // #350 float() isserver (EXT_CSQC)
3493 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3494 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3495 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3496 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3502 NULL, // #360 float() readbyte (EXT_CSQC)
3503 NULL, // #361 float() readchar (EXT_CSQC)
3504 NULL, // #362 float() readshort (EXT_CSQC)
3505 NULL, // #363 float() readlong (EXT_CSQC)
3506 NULL, // #364 float() readcoord (EXT_CSQC)
3507 NULL, // #365 float() readangle (EXT_CSQC)
3508 NULL, // #366 string() readstring (EXT_CSQC)
3509 NULL, // #367 float() readfloat (EXT_CSQC)
3542 // LordHavoc's range #400-#499
3543 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3544 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3545 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3546 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3547 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3548 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3549 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3550 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3551 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)
3552 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3553 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3554 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3555 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3556 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3557 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3558 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3559 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3560 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3561 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3562 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3563 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3564 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3565 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3566 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3567 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3568 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3569 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3570 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3571 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3572 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3573 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3574 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3575 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3576 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3577 VM_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3578 VM_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3579 VM_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3580 VM_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3581 VM_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3582 VM_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3583 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3584 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3585 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3586 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3587 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3588 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3589 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3590 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3591 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3592 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3593 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3594 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3595 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3596 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3597 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3598 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3599 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3600 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3602 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3603 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3604 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3605 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3606 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3607 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3608 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3609 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3610 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3611 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3612 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3614 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3615 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3616 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3617 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3618 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3619 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3620 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3621 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3622 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3623 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3624 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3625 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3626 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3627 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3628 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3629 VM_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3637 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3638 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3639 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3640 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3641 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3642 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3643 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3644 VM_SV_WritePicture, // #501
3646 VM_whichpack, // #503 string(string) whichpack = #503;
3653 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3654 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3655 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3656 VM_uri_get, // #513 float(string uri, float id, [string post_contenttype, string post_delim, [float buf]]) uri_get = #513; (DP_QC_URI_GET, DP_QC_URI_POST)
3657 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3658 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3659 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3660 VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
3661 VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
3662 VM_gettime, // #519 float(float timer) gettime = #519; (DP_QC_GETTIME)
3672 VM_loadfromdata, // #529
3673 VM_loadfromfile, // #530
3674 VM_SV_setpause, // #531 void(float pause) setpause = #531;
3676 VM_getsoundtime, // #533 float(entity e, float channel) getsoundtime = #533; (DP_SND_GETSOUNDTIME)
3677 VM_soundlength, // #534 float(string sample) soundlength = #534; (DP_SND_GETSOUNDTIME)
3683 VM_physics_enable, // #540 void(entity e, float physics_enabled) physics_enable = #540; (DP_PHYSICS_ODE)
3684 VM_physics_addforce, // #541 void(entity e, vector force, vector relative_ofs) physics_addforce = #541; (DP_PHYSICS_ODE)
3685 VM_physics_addtorque, // #542 void(entity e, vector torque) physics_addtorque = #542; (DP_PHYSICS_ODE)
3748 VM_callfunction, // #605
3749 VM_writetofile, // #606
3750 VM_isfunction, // #607
3756 VM_parseentitydata, // #613
3767 VM_SV_getextresponse, // #624 string getextresponse(void)
3770 VM_sprintf, // #627 string sprintf(string format, ...)
3771 VM_getsurfacenumtriangles, // #628 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACETRIANGLE)
3772 VM_getsurfacetriangle, // #629 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACETRIANGLE)
3776 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3778 void VM_SV_Cmd_Init(void)
3783 void VM_SV_Cmd_Reset(void)
3785 World_End(&sv.world);
3786 if(prog->funcoffsets.SV_Shutdown)
3788 func_t s = prog->funcoffsets.SV_Shutdown;
3789 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3790 PRVM_ExecuteProgram(s,"SV_Shutdown() required");