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 "
170 "DP_SV_POINTPARTICLES "
172 "DP_SV_PRECACHEANYTIME "
176 "DP_SV_ROTATINGBMODEL "
180 "DP_SV_SPAWNFUNC_PREFIX "
181 "DP_SV_WRITEPICTURE "
182 "DP_SV_WRITEUNTERMINATEDSTRING "
186 "DP_TE_EXPLOSIONRGB "
188 "DP_TE_PARTICLECUBE "
189 "DP_TE_PARTICLERAIN "
190 "DP_TE_PARTICLESNOW "
192 "DP_TE_QUADEFFECTS1 "
195 "DP_TE_STANDARDEFFECTBUILTINS "
196 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
200 "FTE_CSQC_SKELETONOBJECTS "
203 "KRIMZON_SV_PARSECLIENTCOMMAND "
206 "NEXUIZ_PLAYERMODEL "
208 "PRYDON_CLIENTCURSOR "
209 "TENEBRAE_GFX_DLIGHTS "
212 //"EXT_CSQC " // not ready yet
219 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.
221 setorigin (entity, origin)
224 static void VM_SV_setorigin (void)
229 VM_SAFEPARMCOUNT(2, VM_setorigin);
231 e = PRVM_G_EDICT(OFS_PARM0);
232 if (e == prog->edicts)
234 VM_Warning("setorigin: can not modify world entity\n");
237 if (e->priv.server->free)
239 VM_Warning("setorigin: can not modify free entity\n");
242 org = PRVM_G_VECTOR(OFS_PARM1);
243 VectorCopy (org, e->fields.server->origin);
247 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
248 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
252 for (i=0 ; i<3 ; i++)
254 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
256 // set derived values
257 VectorCopy (min, e->fields.server->mins);
258 VectorCopy (max, e->fields.server->maxs);
259 VectorSubtract (max, min, e->fields.server->size);
268 the size box is rotated by the current angle
269 LordHavoc: no it isn't...
271 setsize (entity, minvector, maxvector)
274 static void VM_SV_setsize (void)
279 VM_SAFEPARMCOUNT(3, VM_setsize);
281 e = PRVM_G_EDICT(OFS_PARM0);
282 if (e == prog->edicts)
284 VM_Warning("setsize: can not modify world entity\n");
287 if (e->priv.server->free)
289 VM_Warning("setsize: can not modify free entity\n");
292 min = PRVM_G_VECTOR(OFS_PARM1);
293 max = PRVM_G_VECTOR(OFS_PARM2);
294 SetMinMaxSize (e, min, max, false);
302 setmodel(entity, model)
305 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
306 static void VM_SV_setmodel (void)
312 VM_SAFEPARMCOUNT(2, VM_setmodel);
314 e = PRVM_G_EDICT(OFS_PARM0);
315 if (e == prog->edicts)
317 VM_Warning("setmodel: can not modify world entity\n");
320 if (e->priv.server->free)
322 VM_Warning("setmodel: can not modify free entity\n");
325 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
326 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
327 e->fields.server->modelindex = i;
329 mod = SV_GetModelByIndex(i);
333 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
334 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
336 SetMinMaxSize (e, quakemins, quakemaxs, true);
339 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
346 single print to a specific client
348 sprint(clientent, value)
351 static void VM_SV_sprint (void)
355 char string[VM_STRINGTEMP_LENGTH];
357 VM_VarString(1, string, sizeof(string));
359 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
361 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
362 // LordHavoc: div0 requested that sprintto world operate like print
369 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
371 VM_Warning("tried to centerprint to a non-client\n");
375 client = svs.clients + entnum-1;
376 if (!client->netconnection)
379 MSG_WriteChar(&client->netconnection->message,svc_print);
380 MSG_WriteString(&client->netconnection->message, string);
388 single print to a specific client
390 centerprint(clientent, value)
393 static void VM_SV_centerprint (void)
397 char string[VM_STRINGTEMP_LENGTH];
399 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
401 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
403 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
405 VM_Warning("tried to centerprint to a non-client\n");
409 client = svs.clients + entnum-1;
410 if (!client->netconnection)
413 VM_VarString(1, string, sizeof(string));
414 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
415 MSG_WriteString(&client->netconnection->message, string);
422 particle(origin, color, count)
425 static void VM_SV_particle (void)
431 VM_SAFEPARMCOUNT(4, VM_SV_particle);
433 org = PRVM_G_VECTOR(OFS_PARM0);
434 dir = PRVM_G_VECTOR(OFS_PARM1);
435 color = PRVM_G_FLOAT(OFS_PARM2);
436 count = PRVM_G_FLOAT(OFS_PARM3);
437 SV_StartParticle (org, dir, (int)color, (int)count);
447 static void VM_SV_ambientsound (void)
451 float vol, attenuation;
454 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
456 pos = PRVM_G_VECTOR (OFS_PARM0);
457 samp = PRVM_G_STRING(OFS_PARM1);
458 vol = PRVM_G_FLOAT(OFS_PARM2);
459 attenuation = PRVM_G_FLOAT(OFS_PARM3);
461 // check to see if samp was properly precached
462 soundnum = SV_SoundIndex(samp, 1);
470 // add an svc_spawnambient command to the level signon packet
473 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
475 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
477 MSG_WriteVector(&sv.signon, pos, sv.protocol);
479 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
480 MSG_WriteShort (&sv.signon, soundnum);
482 MSG_WriteByte (&sv.signon, soundnum);
484 MSG_WriteByte (&sv.signon, (int)(vol*255));
485 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
493 Each entity can have eight independant sound sources, like voice,
496 Channel 0 is an auto-allocate channel, the others override anything
497 already running on that entity/channel pair.
499 An attenuation of 0 will play full volume everywhere in the level.
500 Larger attenuations will drop off.
504 static void VM_SV_sound (void)
508 prvm_edict_t *entity;
512 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
514 entity = PRVM_G_EDICT(OFS_PARM0);
515 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
516 sample = PRVM_G_STRING(OFS_PARM2);
517 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
518 attenuation = PRVM_G_FLOAT(OFS_PARM4);
521 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
525 if (volume < 0 || volume > 255)
527 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
531 if (attenuation < 0 || attenuation > 4)
533 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
537 if (channel < 0 || channel > 7)
539 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
543 SV_StartSound (entity, channel, sample, volume, attenuation);
550 Follows the same logic as VM_SV_sound, except instead of
551 an entity, an origin for the sound is provided, and channel
552 is omitted (since no entity is being tracked).
556 static void VM_SV_pointsound(void)
563 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
565 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
566 sample = PRVM_G_STRING(OFS_PARM1);
567 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
568 attenuation = PRVM_G_FLOAT(OFS_PARM3);
570 if (volume < 0 || volume > 255)
572 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
576 if (attenuation < 0 || attenuation > 4)
578 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
582 SV_StartPointSound (org, sample, volume, attenuation);
589 Used for use tracing and shot targeting
590 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
591 if the tryents flag is set.
593 traceline (vector1, vector2, movetype, ignore)
596 static void VM_SV_traceline (void)
603 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
605 prog->xfunction->builtinsprofile += 30;
607 v1 = PRVM_G_VECTOR(OFS_PARM0);
608 v2 = PRVM_G_VECTOR(OFS_PARM1);
609 move = (int)PRVM_G_FLOAT(OFS_PARM2);
610 ent = PRVM_G_EDICT(OFS_PARM3);
612 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]))
613 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));
615 trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
617 VM_SetTraceGlobals(&trace);
625 Used for use tracing and shot targeting
626 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
627 if the tryents flag is set.
629 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
632 // LordHavoc: added this for my own use, VERY useful, similar to traceline
633 static void VM_SV_tracebox (void)
635 float *v1, *v2, *m1, *m2;
640 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
642 prog->xfunction->builtinsprofile += 30;
644 v1 = PRVM_G_VECTOR(OFS_PARM0);
645 m1 = PRVM_G_VECTOR(OFS_PARM1);
646 m2 = PRVM_G_VECTOR(OFS_PARM2);
647 v2 = PRVM_G_VECTOR(OFS_PARM3);
648 move = (int)PRVM_G_FLOAT(OFS_PARM4);
649 ent = PRVM_G_EDICT(OFS_PARM5);
651 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]))
652 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));
654 trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
656 VM_SetTraceGlobals(&trace);
659 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
664 vec3_t original_origin;
665 vec3_t original_velocity;
666 vec3_t original_angles;
667 vec3_t original_avelocity;
671 VectorCopy(tossent->fields.server->origin , original_origin );
672 VectorCopy(tossent->fields.server->velocity , original_velocity );
673 VectorCopy(tossent->fields.server->angles , original_angles );
674 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
676 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
677 if (val != NULL && val->_float != 0)
678 gravity = val->_float;
681 gravity *= sv_gravity.value * 0.025;
683 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
685 SV_CheckVelocity (tossent);
686 tossent->fields.server->velocity[2] -= gravity;
687 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
688 VectorScale (tossent->fields.server->velocity, 0.05, move);
689 VectorAdd (tossent->fields.server->origin, move, end);
690 trace = SV_TraceBox(tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
691 VectorCopy (trace.endpos, tossent->fields.server->origin);
692 tossent->fields.server->velocity[2] -= gravity;
694 if (trace.fraction < 1)
698 VectorCopy(original_origin , tossent->fields.server->origin );
699 VectorCopy(original_velocity , tossent->fields.server->velocity );
700 VectorCopy(original_angles , tossent->fields.server->angles );
701 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
706 static void VM_SV_tracetoss (void)
710 prvm_edict_t *ignore;
712 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
714 prog->xfunction->builtinsprofile += 600;
716 ent = PRVM_G_EDICT(OFS_PARM0);
717 if (ent == prog->edicts)
719 VM_Warning("tracetoss: can not use world entity\n");
722 ignore = PRVM_G_EDICT(OFS_PARM1);
724 trace = SV_Trace_Toss (ent, ignore);
726 VM_SetTraceGlobals(&trace);
729 //============================================================================
731 static int checkpvsbytes;
732 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
734 static int VM_SV_newcheckclient (int check)
740 // cycle to the next one
742 check = bound(1, check, svs.maxclients);
743 if (check == svs.maxclients)
751 prog->xfunction->builtinsprofile++;
753 if (i == svs.maxclients+1)
755 // look up the client's edict
756 ent = PRVM_EDICT_NUM(i);
757 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
758 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
760 // found a valid client (possibly the same one again)
764 // get the PVS for the entity
765 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
767 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
768 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
777 Returns a client (or object that has a client enemy) that would be a
780 If there is more than one valid option, they are cycled each frame
782 If (self.origin + self.viewofs) is not in the PVS of the current target,
783 it is not returned at all.
788 int c_invis, c_notvis;
789 static void VM_SV_checkclient (void)
791 prvm_edict_t *ent, *self;
794 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
796 // find a new check if on a new frame
797 if (sv.time - sv.lastchecktime >= 0.1)
799 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
800 sv.lastchecktime = sv.time;
803 // return check if it might be visible
804 ent = PRVM_EDICT_NUM(sv.lastcheck);
805 if (ent->priv.server->free || ent->fields.server->health <= 0)
807 VM_RETURN_EDICT(prog->edicts);
811 // if current entity can't possibly see the check entity, return 0
812 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
813 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
814 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
817 VM_RETURN_EDICT(prog->edicts);
821 // might be able to see it
823 VM_RETURN_EDICT(ent);
826 //============================================================================
832 Checks if an entity is in a point's PVS.
833 Should be fast but can be inexact.
835 float checkpvs(vector viewpos, entity viewee) = #240;
838 static void VM_SV_checkpvs (void)
841 prvm_edict_t *viewee;
846 unsigned char fatpvs[MAX_MAP_LEAFS/8];
849 VM_SAFEPARMCOUNT(2, VM_SV_checkpvs);
850 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos);
851 viewee = PRVM_G_EDICT(OFS_PARM1);
853 if(viewee->priv.server->free)
855 VM_Warning("checkpvs: can not check free entity\n");
856 PRVM_G_FLOAT(OFS_RETURN) = 4;
861 if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
863 // no PVS support on this worldmodel... darn
864 PRVM_G_FLOAT(OFS_RETURN) = 3;
867 pvs = sv.worldmodel->brush.GetPVS(sv.worldmodel, viewpos);
870 // viewpos isn't in any PVS... darn
871 PRVM_G_FLOAT(OFS_RETURN) = 2;
874 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
876 // using fat PVS like FTEQW does (slow)
877 if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
879 // no PVS support on this worldmodel... darn
880 PRVM_G_FLOAT(OFS_RETURN) = 3;
883 fatpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
886 // viewpos isn't in any PVS... darn
887 PRVM_G_FLOAT(OFS_RETURN) = 2;
890 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
899 Sends text over to the client's execution buffer
901 stuffcmd (clientent, value, ...)
904 static void VM_SV_stuffcmd (void)
908 char string[VM_STRINGTEMP_LENGTH];
910 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
912 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
913 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
915 VM_Warning("Can't stuffcmd to a non-client\n");
919 VM_VarString(1, string, sizeof(string));
922 host_client = svs.clients + entnum-1;
923 Host_ClientCommands ("%s", string);
931 Returns a chain of entities that have origins within a spherical area
933 findradius (origin, radius)
936 static void VM_SV_findradius (void)
938 prvm_edict_t *ent, *chain;
939 vec_t radius, radius2;
940 vec3_t org, eorg, mins, maxs;
943 static prvm_edict_t *touchedicts[MAX_EDICTS];
946 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findradius);
949 chainfield = PRVM_G_INT(OFS_PARM2);
951 chainfield = prog->fieldoffsets.chain;
953 PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
955 chain = (prvm_edict_t *)prog->edicts;
957 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
958 radius = PRVM_G_FLOAT(OFS_PARM1);
959 radius2 = radius * radius;
961 mins[0] = org[0] - (radius + 1);
962 mins[1] = org[1] - (radius + 1);
963 mins[2] = org[2] - (radius + 1);
964 maxs[0] = org[0] + (radius + 1);
965 maxs[1] = org[1] + (radius + 1);
966 maxs[2] = org[2] + (radius + 1);
967 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
968 if (numtouchedicts > MAX_EDICTS)
970 // this never happens
971 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
972 numtouchedicts = MAX_EDICTS;
974 for (i = 0;i < numtouchedicts;i++)
976 ent = touchedicts[i];
977 prog->xfunction->builtinsprofile++;
978 // Quake did not return non-solid entities but darkplaces does
979 // (note: this is the reason you can't blow up fallen zombies)
980 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
982 // LordHavoc: compare against bounding box rather than center so it
983 // doesn't miss large objects, and use DotProduct instead of Length
984 // for a major speedup
985 VectorSubtract(org, ent->fields.server->origin, eorg);
986 if (sv_gameplayfix_findradiusdistancetobox.integer)
988 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
989 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
990 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
993 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
994 if (DotProduct(eorg, eorg) < radius2)
996 PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
1001 VM_RETURN_EDICT(chain);
1004 static void VM_SV_precache_sound (void)
1006 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
1007 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
1010 static void VM_SV_precache_model (void)
1012 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
1013 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
1014 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
1021 float(float yaw, float dist[, settrace]) walkmove
1024 static void VM_SV_walkmove (void)
1033 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
1035 // assume failure if it returns early
1036 PRVM_G_FLOAT(OFS_RETURN) = 0;
1038 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1039 if (ent == prog->edicts)
1041 VM_Warning("walkmove: can not modify world entity\n");
1044 if (ent->priv.server->free)
1046 VM_Warning("walkmove: can not modify free entity\n");
1049 yaw = PRVM_G_FLOAT(OFS_PARM0);
1050 dist = PRVM_G_FLOAT(OFS_PARM1);
1051 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
1053 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1056 yaw = yaw*M_PI*2 / 360;
1058 move[0] = cos(yaw)*dist;
1059 move[1] = sin(yaw)*dist;
1062 // save program state, because SV_movestep may call other progs
1063 oldf = prog->xfunction;
1064 oldself = prog->globals.server->self;
1066 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
1069 // restore program state
1070 prog->xfunction = oldf;
1071 prog->globals.server->self = oldself;
1081 static void VM_SV_droptofloor (void)
1087 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
1089 // assume failure if it returns early
1090 PRVM_G_FLOAT(OFS_RETURN) = 0;
1092 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1093 if (ent == prog->edicts)
1095 VM_Warning("droptofloor: can not modify world entity\n");
1098 if (ent->priv.server->free)
1100 VM_Warning("droptofloor: can not modify free entity\n");
1104 VectorCopy (ent->fields.server->origin, end);
1107 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
1108 SV_UnstickEntity(ent);
1110 trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1111 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
1114 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]);
1115 VectorAdd(ent->fields.server->origin, offset, org);
1116 trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1117 VectorSubtract(trace.endpos, offset, trace.endpos);
1118 if (trace.startsolid)
1120 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]);
1121 SV_UnstickEntity(ent);
1123 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1124 ent->fields.server->groundentity = 0;
1125 PRVM_G_FLOAT(OFS_RETURN) = 1;
1127 else if (trace.fraction < 1)
1129 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]);
1130 VectorCopy (trace.endpos, ent->fields.server->origin);
1131 SV_UnstickEntity(ent);
1133 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1134 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1135 PRVM_G_FLOAT(OFS_RETURN) = 1;
1136 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1137 ent->priv.server->suspendedinairflag = true;
1142 if (trace.fraction != 1)
1144 if (trace.fraction < 1)
1145 VectorCopy (trace.endpos, ent->fields.server->origin);
1147 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1148 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1149 PRVM_G_FLOAT(OFS_RETURN) = 1;
1150 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1151 ent->priv.server->suspendedinairflag = true;
1160 void(float style, string value) lightstyle
1163 static void VM_SV_lightstyle (void)
1170 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1172 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1173 val = PRVM_G_STRING(OFS_PARM1);
1175 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1176 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1179 // change the string in sv
1180 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1182 // send message to all clients on this server
1183 if (sv.state != ss_active)
1186 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1188 if (client->active && client->netconnection)
1190 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1191 MSG_WriteChar (&client->netconnection->message,style);
1192 MSG_WriteString (&client->netconnection->message, val);
1202 static void VM_SV_checkbottom (void)
1204 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1205 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1213 static void VM_SV_pointcontents (void)
1215 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1216 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1223 Pick a vector for the player to shoot along
1224 vector aim(entity, missilespeed)
1227 static void VM_SV_aim (void)
1229 prvm_edict_t *ent, *check, *bestent;
1230 vec3_t start, dir, end, bestdir;
1233 float dist, bestdist;
1236 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1238 // assume failure if it returns early
1239 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1240 // if sv_aim is so high it can't possibly accept anything, skip out early
1241 if (sv_aim.value >= 1)
1244 ent = PRVM_G_EDICT(OFS_PARM0);
1245 if (ent == prog->edicts)
1247 VM_Warning("aim: can not use world entity\n");
1250 if (ent->priv.server->free)
1252 VM_Warning("aim: can not use free entity\n");
1255 //speed = PRVM_G_FLOAT(OFS_PARM1);
1257 VectorCopy (ent->fields.server->origin, start);
1260 // try sending a trace straight
1261 VectorCopy (prog->globals.server->v_forward, dir);
1262 VectorMA (start, 2048, dir, end);
1263 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1264 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1265 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1267 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1272 // try all possible entities
1273 VectorCopy (dir, bestdir);
1274 bestdist = sv_aim.value;
1277 check = PRVM_NEXT_EDICT(prog->edicts);
1278 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1280 prog->xfunction->builtinsprofile++;
1281 if (check->fields.server->takedamage != DAMAGE_AIM)
1285 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1286 continue; // don't aim at teammate
1287 for (j=0 ; j<3 ; j++)
1288 end[j] = check->fields.server->origin[j]
1289 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1290 VectorSubtract (end, start, dir);
1291 VectorNormalize (dir);
1292 dist = DotProduct (dir, prog->globals.server->v_forward);
1293 if (dist < bestdist)
1294 continue; // to far to turn
1295 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1296 if (tr.ent == check)
1297 { // can shoot at this one
1305 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1306 dist = DotProduct (dir, prog->globals.server->v_forward);
1307 VectorScale (prog->globals.server->v_forward, dist, end);
1309 VectorNormalize (end);
1310 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1314 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1319 ===============================================================================
1323 ===============================================================================
1326 #define MSG_BROADCAST 0 // unreliable to all
1327 #define MSG_ONE 1 // reliable to one (msg_entity)
1328 #define MSG_ALL 2 // reliable to all
1329 #define MSG_INIT 3 // write to the init string
1330 #define MSG_ENTITY 5
1332 sizebuf_t *WriteDest (void)
1338 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1342 return &sv.datagram;
1345 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1346 entnum = PRVM_NUM_FOR_EDICT(ent);
1347 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1349 VM_Warning ("WriteDest: tried to write to non-client\n");
1350 return &sv.reliable_datagram;
1353 return &svs.clients[entnum-1].netconnection->message;
1356 VM_Warning ("WriteDest: bad destination\n");
1358 return &sv.reliable_datagram;
1364 return sv.writeentitiestoclient_msg;
1370 static void VM_SV_WriteByte (void)
1372 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1373 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1376 static void VM_SV_WriteChar (void)
1378 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1379 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1382 static void VM_SV_WriteShort (void)
1384 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1385 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1388 static void VM_SV_WriteLong (void)
1390 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1391 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1394 static void VM_SV_WriteAngle (void)
1396 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1397 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1400 static void VM_SV_WriteCoord (void)
1402 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1403 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1406 static void VM_SV_WriteString (void)
1408 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1409 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1412 static void VM_SV_WriteUnterminatedString (void)
1414 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1415 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1419 static void VM_SV_WriteEntity (void)
1421 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1422 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1425 // writes a picture as at most size bytes of data
1427 // IMGNAME \0 SIZE(short) IMGDATA
1428 // if failed to read/compress:
1430 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1431 static void VM_SV_WritePicture (void)
1433 const char *imgname;
1437 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1439 imgname = PRVM_G_STRING(OFS_PARM1);
1440 size = (int) PRVM_G_FLOAT(OFS_PARM2);
1444 MSG_WriteString(WriteDest(), imgname);
1445 if(Image_Compress(imgname, size, &buf, &size))
1448 MSG_WriteShort(WriteDest(), size);
1449 SZ_Write(WriteDest(), (unsigned char *) buf, size);
1454 MSG_WriteShort(WriteDest(), 0);
1458 //////////////////////////////////////////////////////////
1460 static void VM_SV_makestatic (void)
1465 // allow 0 parameters due to an id1 qc bug in which this function is used
1466 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1467 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1469 if (prog->argc >= 1)
1470 ent = PRVM_G_EDICT(OFS_PARM0);
1472 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1473 if (ent == prog->edicts)
1475 VM_Warning("makestatic: can not modify world entity\n");
1478 if (ent->priv.server->free)
1480 VM_Warning("makestatic: can not modify free entity\n");
1485 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1490 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1491 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1492 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1494 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1496 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1497 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1498 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1502 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1503 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1504 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1507 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1508 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1509 for (i=0 ; i<3 ; i++)
1511 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1512 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1515 // throw the entity away now
1519 //=============================================================================
1526 static void VM_SV_setspawnparms (void)
1532 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1534 ent = PRVM_G_EDICT(OFS_PARM0);
1535 i = PRVM_NUM_FOR_EDICT(ent);
1536 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1538 Con_Print("tried to setspawnparms on a non-client\n");
1542 // copy spawn parms out of the client_t
1543 client = svs.clients + i-1;
1544 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1545 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1552 Returns a color vector indicating the lighting at the requested point.
1554 (Internal Operation note: actually measures the light beneath the point, just like
1555 the model lighting on the client)
1560 static void VM_SV_getlight (void)
1562 vec3_t ambientcolor, diffusecolor, diffusenormal;
1564 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1565 p = PRVM_G_VECTOR(OFS_PARM0);
1566 VectorClear(ambientcolor);
1567 VectorClear(diffusecolor);
1568 VectorClear(diffusenormal);
1569 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1570 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1571 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1576 unsigned char type; // 1/2/8 or other value if isn't used
1580 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1581 static int vm_customstats_last;
1583 void VM_CustomStats_Clear (void)
1587 Z_Free(vm_customstats);
1588 vm_customstats = NULL;
1589 vm_customstats_last = -1;
1593 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1601 for(i=0; i<vm_customstats_last+1 ;i++)
1603 if(!vm_customstats[i].type)
1605 switch(vm_customstats[i].type)
1607 //string as 16 bytes
1610 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1611 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1612 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1613 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1614 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1616 //float field sent as-is
1618 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1620 //integer value of float field
1622 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1630 // void(float index, float type, .void field) SV_AddStat = #232;
1631 // Set up an auto-sent player stat.
1632 // Client's get thier own fields sent to them. Index may not be less than 32.
1633 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1634 // 1: string (4 stats carrying a total of 16 charactures)
1635 // 2: float (one stat, float converted to an integer for transportation)
1636 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1637 static void VM_SV_AddStat (void)
1642 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1646 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1649 VM_Warning("PF_SV_AddStat: not enough memory\n");
1653 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1654 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1655 off = PRVM_G_INT (OFS_PARM2);
1660 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1663 if(i >= (MAX_CL_STATS-32))
1665 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1668 if(i > (MAX_CL_STATS-32-4) && type == 1)
1670 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1673 vm_customstats[i].type = type;
1674 vm_customstats[i].fieldoffset = off;
1675 if(vm_customstats_last < i)
1676 vm_customstats_last = i;
1683 copies data from one entity to another
1685 copyentity(src, dst)
1688 static void VM_SV_copyentity (void)
1690 prvm_edict_t *in, *out;
1691 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1692 in = PRVM_G_EDICT(OFS_PARM0);
1693 if (in == prog->edicts)
1695 VM_Warning("copyentity: can not read world entity\n");
1698 if (in->priv.server->free)
1700 VM_Warning("copyentity: can not read free entity\n");
1703 out = PRVM_G_EDICT(OFS_PARM1);
1704 if (out == prog->edicts)
1706 VM_Warning("copyentity: can not modify world entity\n");
1709 if (out->priv.server->free)
1711 VM_Warning("copyentity: can not modify free entity\n");
1714 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1723 sets the color of a client and broadcasts the update to all connected clients
1725 setcolor(clientent, value)
1728 static void VM_SV_setcolor (void)
1734 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1735 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1736 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1738 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1740 Con_Print("tried to setcolor a non-client\n");
1744 client = svs.clients + entnum-1;
1747 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1749 client->edict->fields.server->team = (i & 15) + 1;
1752 if (client->old_colors != client->colors)
1754 client->old_colors = client->colors;
1755 // send notification to all clients
1756 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1757 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1758 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1766 effect(origin, modelname, startframe, framecount, framerate)
1769 static void VM_SV_effect (void)
1773 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1774 s = PRVM_G_STRING(OFS_PARM1);
1777 VM_Warning("effect: no model specified\n");
1781 i = SV_ModelIndex(s, 1);
1784 VM_Warning("effect: model not precached\n");
1788 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1790 VM_Warning("effect: framecount < 1\n");
1794 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1796 VM_Warning("effect: framerate < 1\n");
1800 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));
1803 static void VM_SV_te_blood (void)
1805 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1806 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1808 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1809 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1811 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1812 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1815 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1816 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1817 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1819 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1820 SV_FlushBroadcastMessages();
1823 static void VM_SV_te_bloodshower (void)
1825 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1826 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1828 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1829 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1831 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1833 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1835 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1836 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1837 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1839 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1841 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1842 SV_FlushBroadcastMessages();
1845 static void VM_SV_te_explosionrgb (void)
1847 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1848 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1849 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1851 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1852 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1853 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1855 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1856 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1857 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1858 SV_FlushBroadcastMessages();
1861 static void VM_SV_te_particlecube (void)
1863 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1864 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1866 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1867 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1871 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1873 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1874 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1875 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1877 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1878 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1879 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1881 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1883 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1884 // gravity true/false
1885 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1887 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1888 SV_FlushBroadcastMessages();
1891 static void VM_SV_te_particlerain (void)
1893 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1894 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1896 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1897 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1899 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1903 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1904 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1905 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1907 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1908 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1909 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1911 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1913 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1914 SV_FlushBroadcastMessages();
1917 static void VM_SV_te_particlesnow (void)
1919 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1920 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1922 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1923 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1925 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1926 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1927 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1929 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1930 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1931 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1933 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1934 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1935 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1937 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1939 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1940 SV_FlushBroadcastMessages();
1943 static void VM_SV_te_spark (void)
1945 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1946 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1948 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1949 MSG_WriteByte(&sv.datagram, TE_SPARK);
1951 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1952 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1953 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1955 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1956 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1957 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1959 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1960 SV_FlushBroadcastMessages();
1963 static void VM_SV_te_gunshotquad (void)
1965 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1966 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1967 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1969 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1970 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1972 SV_FlushBroadcastMessages();
1975 static void VM_SV_te_spikequad (void)
1977 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1978 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1979 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1981 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1982 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1983 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1984 SV_FlushBroadcastMessages();
1987 static void VM_SV_te_superspikequad (void)
1989 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1990 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1991 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1993 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1994 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1996 SV_FlushBroadcastMessages();
1999 static void VM_SV_te_explosionquad (void)
2001 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
2002 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2003 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2005 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2006 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2007 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2008 SV_FlushBroadcastMessages();
2011 static void VM_SV_te_smallflash (void)
2013 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
2014 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2015 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2017 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2018 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2019 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2020 SV_FlushBroadcastMessages();
2023 static void VM_SV_te_customflash (void)
2025 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
2026 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2028 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2029 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2031 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2032 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2033 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2035 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2037 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
2039 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
2040 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
2041 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
2042 SV_FlushBroadcastMessages();
2045 static void VM_SV_te_gunshot (void)
2047 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
2048 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2049 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2051 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2052 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2053 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2054 SV_FlushBroadcastMessages();
2057 static void VM_SV_te_spike (void)
2059 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
2060 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2061 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2063 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2064 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2065 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2066 SV_FlushBroadcastMessages();
2069 static void VM_SV_te_superspike (void)
2071 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
2072 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2073 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2075 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2076 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2077 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2078 SV_FlushBroadcastMessages();
2081 static void VM_SV_te_explosion (void)
2083 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
2084 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2085 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2087 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2088 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2089 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2090 SV_FlushBroadcastMessages();
2093 static void VM_SV_te_tarexplosion (void)
2095 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
2096 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2097 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2099 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2100 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2101 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2102 SV_FlushBroadcastMessages();
2105 static void VM_SV_te_wizspike (void)
2107 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
2108 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2109 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2111 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2112 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2113 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2114 SV_FlushBroadcastMessages();
2117 static void VM_SV_te_knightspike (void)
2119 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2120 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2121 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2123 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2124 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2125 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2126 SV_FlushBroadcastMessages();
2129 static void VM_SV_te_lavasplash (void)
2131 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2132 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2133 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2135 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2136 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2137 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2138 SV_FlushBroadcastMessages();
2141 static void VM_SV_te_teleport (void)
2143 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2144 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2145 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2147 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2148 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2149 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2150 SV_FlushBroadcastMessages();
2153 static void VM_SV_te_explosion2 (void)
2155 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2156 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2157 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2159 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2160 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2161 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2163 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2164 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2165 SV_FlushBroadcastMessages();
2168 static void VM_SV_te_lightning1 (void)
2170 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2171 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2172 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2174 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2176 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2177 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2178 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2180 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2181 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2182 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2183 SV_FlushBroadcastMessages();
2186 static void VM_SV_te_lightning2 (void)
2188 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2189 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2190 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2192 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2194 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2195 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2196 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2198 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2199 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2200 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2201 SV_FlushBroadcastMessages();
2204 static void VM_SV_te_lightning3 (void)
2206 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2207 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2208 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2210 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2212 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2213 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2214 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2216 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2217 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2218 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2219 SV_FlushBroadcastMessages();
2222 static void VM_SV_te_beam (void)
2224 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2225 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2226 MSG_WriteByte(&sv.datagram, TE_BEAM);
2228 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2230 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2231 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2232 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2234 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2235 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2236 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2237 SV_FlushBroadcastMessages();
2240 static void VM_SV_te_plasmaburn (void)
2242 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2243 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2244 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2245 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2246 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2247 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2248 SV_FlushBroadcastMessages();
2251 static void VM_SV_te_flamejet (void)
2253 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2254 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2255 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2257 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2258 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2259 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2261 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2262 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2263 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2265 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2266 SV_FlushBroadcastMessages();
2269 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2270 //this function originally written by KrimZon, made shorter by LordHavoc
2271 static void VM_SV_clientcommand (void)
2273 client_t *temp_client;
2275 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2277 //find client for this entity
2278 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2279 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2281 Con_Print("PF_clientcommand: entity is not a client\n");
2285 temp_client = host_client;
2286 host_client = svs.clients + i;
2287 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2288 host_client = temp_client;
2291 //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)
2292 static void VM_SV_setattachment (void)
2294 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2295 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2296 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2299 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2301 if (e == prog->edicts)
2303 VM_Warning("setattachment: can not modify world entity\n");
2306 if (e->priv.server->free)
2308 VM_Warning("setattachment: can not modify free entity\n");
2312 if (tagentity == NULL)
2313 tagentity = prog->edicts;
2315 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2317 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2319 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2322 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2324 model = SV_GetModelFromEdict(tagentity);
2327 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2329 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);
2332 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));
2336 /////////////////////////////////////////
2337 // DP_MD3_TAGINFO extension coded by VorteX
2339 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2343 i = (int)e->fields.server->modelindex;
2344 if (i < 1 || i >= MAX_MODELS)
2347 return Mod_Alias_GetTagIndexForName(SV_GetModelByIndex(i), (int)e->fields.server->skin, tagname);
2350 int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
2357 Matrix4x4_CreateIdentity(tag_localmatrix);
2359 if (tagindex >= 0 && (model = SV_GetModelFromEdict(e)) && model->num_bones)
2361 r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, e->priv.server->frameblend, &e->priv.server->skeleton, tagindex - 1, parentindex, tagname, tag_localmatrix);
2372 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2376 float pitchsign = 1;
2379 val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
2380 if (val && val->_float != 0)
2381 scale = val->_float;
2384 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);
2387 pitchsign = SV_GetPitchSign(ent);
2388 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);
2392 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2395 if (tagindex >= 0 && (model = SV_GetModelFromEdict(ent)) && model->animscenes)
2397 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2398 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2399 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2400 return Mod_Alias_GetTagMatrix(model, ent->priv.server->frameblend, &ent->priv.server->skeleton, tagindex, out);
2402 *out = identitymatrix;
2406 // Warnings/errors code:
2407 // 0 - normal (everything all-right)
2410 // 3 - null or non-precached model
2411 // 4 - no tags with requested index
2412 // 5 - runaway loop at attachment chain
2413 extern cvar_t cl_bob;
2414 extern cvar_t cl_bobcycle;
2415 extern cvar_t cl_bobup;
2416 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2420 int modelindex, attachloop;
2421 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2424 *out = identitymatrix; // warnings and errors return identical matrix
2426 if (ent == prog->edicts)
2428 if (ent->priv.server->free)
2431 modelindex = (int)ent->fields.server->modelindex;
2432 if (modelindex <= 0 || modelindex >= MAX_MODELS)
2435 model = SV_GetModelByIndex(modelindex);
2437 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2438 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2439 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2441 tagmatrix = identitymatrix;
2442 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2446 if (attachloop >= 256) // prevent runaway looping
2448 // apply transformation by child's tagindex on parent entity and then
2449 // by parent entity itself
2450 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2451 if (ret && attachloop == 0)
2453 SV_GetEntityMatrix(ent, &entitymatrix, false);
2454 Matrix4x4_Concat(&tagmatrix, &attachmatrix, out);
2455 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2456 // next iteration we process the parent entity
2457 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2459 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2460 ent = PRVM_EDICT_NUM(val->edict);
2467 // RENDER_VIEWMODEL magic
2468 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2470 Matrix4x4_Copy(&tagmatrix, out);
2471 ent = PRVM_EDICT_NUM(val->edict);
2473 SV_GetEntityMatrix(ent, &entitymatrix, true);
2474 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2477 // Cl_bob, ported from rendering code
2478 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2481 // LordHavoc: this code is *weird*, but not replacable (I think it
2482 // should be done in QC on the server, but oh well, quake is quake)
2483 // LordHavoc: figured out bobup: the time at which the sin is at 180
2484 // degrees (which allows lengthening or squishing the peak or valley)
2485 cycle = sv.time/cl_bobcycle.value;
2486 cycle -= (int)cycle;
2487 if (cycle < cl_bobup.value)
2488 cycle = sin(M_PI * cycle / cl_bobup.value);
2490 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2491 // bob is proportional to velocity in the xy plane
2492 // (don't count Z, or jumping messes it up)
2493 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;
2494 bob = bob*0.3 + bob*0.7*cycle;
2495 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2502 //float(entity ent, string tagname) gettagindex;
2504 static void VM_SV_gettagindex (void)
2507 const char *tag_name;
2510 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2512 ent = PRVM_G_EDICT(OFS_PARM0);
2513 tag_name = PRVM_G_STRING(OFS_PARM1);
2515 if (ent == prog->edicts)
2517 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
2520 if (ent->priv.server->free)
2522 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
2527 if (!SV_GetModelFromEdict(ent))
2528 Con_DPrintf("VM_SV_gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2531 tag_index = SV_GetTagIndex(ent, tag_name);
2533 if(developer_extra.integer)
2534 Con_DPrintf("VM_SV_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2536 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2539 //vector(entity ent, float tagindex) gettaginfo;
2540 static void VM_SV_gettaginfo (void)
2544 matrix4x4_t tag_matrix;
2545 matrix4x4_t tag_localmatrix;
2547 const char *tagname;
2550 vec3_t fo, le, up, trans;
2551 const dp_model_t *model;
2553 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2555 e = PRVM_G_EDICT(OFS_PARM0);
2556 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2558 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2559 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, le, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2560 VectorScale(le, -1, prog->globals.server->v_right);
2561 model = SV_GetModelFromEdict(e);
2562 VM_GenerateFrameGroupBlend(e->priv.server->framegroupblend, e);
2563 VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model);
2564 VM_UpdateEdictSkeleton(e, model, e->priv.server->frameblend);
2565 SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
2566 Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
2568 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
2569 val->_float = parentindex;
2570 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
2571 val->string = tagname ? PRVM_SetTempString(tagname) : 0;
2572 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
2573 VectorCopy(trans, val->vector);
2574 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
2575 VectorCopy(fo, val->vector);
2576 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
2577 VectorScale(le, -1, val->vector);
2578 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
2579 VectorCopy(up, val->vector);
2584 VM_Warning("gettagindex: can't affect world entity\n");
2587 VM_Warning("gettagindex: can't affect free entity\n");
2590 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2593 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2596 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2601 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2602 static void VM_SV_dropclient (void)
2605 client_t *oldhostclient;
2606 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2607 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2608 if (clientnum < 0 || clientnum >= svs.maxclients)
2610 VM_Warning("dropclient: not a client\n");
2613 if (!svs.clients[clientnum].active)
2615 VM_Warning("dropclient: that client slot is not connected\n");
2618 oldhostclient = host_client;
2619 host_client = svs.clients + clientnum;
2620 SV_DropClient(false);
2621 host_client = oldhostclient;
2624 //entity() spawnclient (DP_SV_BOTCLIENT)
2625 static void VM_SV_spawnclient (void)
2629 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2630 prog->xfunction->builtinsprofile += 2;
2632 for (i = 0;i < svs.maxclients;i++)
2634 if (!svs.clients[i].active)
2636 prog->xfunction->builtinsprofile += 100;
2637 SV_ConnectClient (i, NULL);
2638 // this has to be set or else ClientDisconnect won't be called
2639 // we assume the qc will call ClientConnect...
2640 svs.clients[i].clientconnectcalled = true;
2641 ed = PRVM_EDICT_NUM(i + 1);
2645 VM_RETURN_EDICT(ed);
2648 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2649 static void VM_SV_clienttype (void)
2652 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2653 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2654 if (clientnum < 0 || clientnum >= svs.maxclients)
2655 PRVM_G_FLOAT(OFS_RETURN) = 3;
2656 else if (!svs.clients[clientnum].active)
2657 PRVM_G_FLOAT(OFS_RETURN) = 0;
2658 else if (svs.clients[clientnum].netconnection)
2659 PRVM_G_FLOAT(OFS_RETURN) = 1;
2661 PRVM_G_FLOAT(OFS_RETURN) = 2;
2668 string(string key) serverkey
2671 void VM_SV_serverkey(void)
2673 char string[VM_STRINGTEMP_LENGTH];
2674 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2675 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2676 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2679 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2680 static void VM_SV_setmodelindex (void)
2685 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2687 e = PRVM_G_EDICT(OFS_PARM0);
2688 if (e == prog->edicts)
2690 VM_Warning("setmodelindex: can not modify world entity\n");
2693 if (e->priv.server->free)
2695 VM_Warning("setmodelindex: can not modify free entity\n");
2698 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2699 if (i <= 0 || i >= MAX_MODELS)
2701 VM_Warning("setmodelindex: invalid modelindex\n");
2704 if (!sv.model_precache[i][0])
2706 VM_Warning("setmodelindex: model not precached\n");
2710 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2711 e->fields.server->modelindex = i;
2713 mod = SV_GetModelByIndex(i);
2717 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2718 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2720 SetMinMaxSize (e, quakemins, quakemaxs, true);
2723 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2726 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2727 static void VM_SV_modelnameforindex (void)
2730 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2732 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2734 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2735 if (i <= 0 || i >= MAX_MODELS)
2737 VM_Warning("modelnameforindex: invalid modelindex\n");
2740 if (!sv.model_precache[i][0])
2742 VM_Warning("modelnameforindex: model not precached\n");
2746 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2749 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2750 static void VM_SV_particleeffectnum (void)
2753 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2754 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2757 PRVM_G_FLOAT(OFS_RETURN) = i;
2760 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2761 static void VM_SV_trailparticles (void)
2763 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2765 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2768 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2769 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2770 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2771 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2772 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2773 SV_FlushBroadcastMessages();
2776 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2777 static void VM_SV_pointparticles (void)
2779 int effectnum, count;
2781 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2783 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2786 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2787 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2788 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2789 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2790 if (count == 1 && !VectorLength2(vel))
2793 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2794 MSG_WriteShort(&sv.datagram, effectnum);
2795 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2799 // 1+2+12+12+2=29 bytes
2800 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2801 MSG_WriteShort(&sv.datagram, effectnum);
2802 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2803 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2804 MSG_WriteShort(&sv.datagram, count);
2807 SV_FlushBroadcastMessages();
2810 //PF_setpause, // void(float pause) setpause = #531;
2811 static void VM_SV_setpause(void) {
2813 pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
2814 if (pauseValue != 0) { //pause the game
2816 sv.pausedstart = Sys_DoubleTime();
2817 } else { //disable pause, in case it was enabled
2818 if (sv.paused != 0) {
2823 // send notification to all clients
2824 MSG_WriteByte(&sv.reliable_datagram, svc_setpause);
2825 MSG_WriteByte(&sv.reliable_datagram, sv.paused);
2828 // #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.
2829 static void VM_SV_skel_create(void)
2831 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
2832 dp_model_t *model = SV_GetModelByIndex(modelindex);
2833 skeleton_t *skeleton;
2835 PRVM_G_FLOAT(OFS_RETURN) = 0;
2836 if (!model || !model->num_bones)
2838 for (i = 0;i < MAX_EDICTS;i++)
2839 if (!prog->skeletons[i])
2841 if (i == MAX_EDICTS)
2843 prog->skeletons[i] = skeleton = (skeleton_t *)Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
2844 PRVM_G_FLOAT(OFS_RETURN) = i + 1;
2845 skeleton->model = model;
2846 skeleton->relativetransforms = (matrix4x4_t *)(skeleton+1);
2847 // initialize to identity matrices
2848 for (i = 0;i < skeleton->model->num_bones;i++)
2849 skeleton->relativetransforms[i] = identitymatrix;
2852 // #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
2853 static void VM_SV_skel_build(void)
2855 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2856 skeleton_t *skeleton;
2857 prvm_edict_t *ed = PRVM_G_EDICT(OFS_PARM1);
2858 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM2);
2859 float retainfrac = PRVM_G_FLOAT(OFS_PARM3);
2860 int firstbone = PRVM_G_FLOAT(OFS_PARM4) - 1;
2861 int lastbone = PRVM_G_FLOAT(OFS_PARM5) - 1;
2862 dp_model_t *model = SV_GetModelByIndex(modelindex);
2867 framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS];
2868 frameblend_t frameblend[MAX_FRAMEBLENDS];
2869 matrix4x4_t blendedmatrix;
2871 PRVM_G_FLOAT(OFS_RETURN) = 0;
2872 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2874 firstbone = max(0, firstbone);
2875 lastbone = min(lastbone, model->num_bones - 1);
2876 lastbone = min(lastbone, skeleton->model->num_bones - 1);
2877 VM_GenerateFrameGroupBlend(framegroupblend, ed);
2878 VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model);
2879 blendfrac = 1.0f - retainfrac;
2880 for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
2881 frameblend[numblends].lerp *= blendfrac;
2882 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
2884 memset(&blendedmatrix, 0, sizeof(blendedmatrix));
2885 Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac);
2886 for (blendindex = 0;blendindex < numblends;blendindex++)
2888 Matrix4x4_FromBonePose6s(&matrix, model->num_posescale, model->data_poses6s + 6 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
2889 Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp);
2891 skeleton->relativetransforms[bonenum] = blendedmatrix;
2893 PRVM_G_FLOAT(OFS_RETURN) = skeletonindex + 1;
2896 // #265 float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS) returns how many bones exist in the created skeleton
2897 static void VM_SV_skel_get_numbones(void)
2899 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2900 skeleton_t *skeleton;
2901 PRVM_G_FLOAT(OFS_RETURN) = 0;
2902 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2904 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->num_bones;
2907 // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) returns name of bone (as a tempstring)
2908 static void VM_SV_skel_get_bonename(void)
2910 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2911 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2912 skeleton_t *skeleton;
2913 PRVM_G_INT(OFS_RETURN) = 0;
2914 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2916 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2918 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(skeleton->model->data_bones[bonenum].name);
2921 // #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)
2922 static void VM_SV_skel_get_boneparent(void)
2924 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2925 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2926 skeleton_t *skeleton;
2927 PRVM_G_FLOAT(OFS_RETURN) = 0;
2928 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2930 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2932 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->data_bones[bonenum].parent + 1;
2935 // #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
2936 static void VM_SV_skel_find_bone(void)
2938 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2939 const char *tagname = PRVM_G_STRING(OFS_PARM1);
2940 skeleton_t *skeleton;
2941 PRVM_G_FLOAT(OFS_RETURN) = 0;
2942 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2944 PRVM_G_FLOAT(OFS_RETURN) = Mod_Alias_GetTagIndexForName(skeleton->model, 0, tagname) + 1;
2947 // #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)
2948 static void VM_SV_skel_get_bonerel(void)
2950 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2951 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2952 skeleton_t *skeleton;
2954 vec3_t forward, left, up, origin;
2955 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2956 VectorClear(prog->globals.client->v_forward);
2957 VectorClear(prog->globals.client->v_right);
2958 VectorClear(prog->globals.client->v_up);
2959 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2961 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2963 matrix = skeleton->relativetransforms[bonenum];
2964 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2965 VectorCopy(forward, prog->globals.client->v_forward);
2966 VectorNegate(left, prog->globals.client->v_right);
2967 VectorCopy(up, prog->globals.client->v_up);
2968 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
2971 // #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)
2972 static void VM_SV_skel_get_boneabs(void)
2974 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2975 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2976 skeleton_t *skeleton;
2979 vec3_t forward, left, up, origin;
2980 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2981 VectorClear(prog->globals.client->v_forward);
2982 VectorClear(prog->globals.client->v_right);
2983 VectorClear(prog->globals.client->v_up);
2984 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2986 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2988 matrix = skeleton->relativetransforms[bonenum];
2989 // convert to absolute
2990 while ((bonenum = skeleton->model->data_bones[bonenum].parent) >= 0)
2993 Matrix4x4_Concat(&matrix, &skeleton->relativetransforms[bonenum], &temp);
2995 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2996 VectorCopy(forward, prog->globals.client->v_forward);
2997 VectorNegate(left, prog->globals.client->v_right);
2998 VectorCopy(up, prog->globals.client->v_up);
2999 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
3002 // #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)
3003 static void VM_SV_skel_set_bone(void)
3005 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3006 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3007 vec3_t forward, left, up, origin;
3008 skeleton_t *skeleton;
3010 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3012 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3014 VectorCopy(prog->globals.client->v_forward, forward);
3015 VectorNegate(prog->globals.client->v_right, left);
3016 VectorCopy(prog->globals.client->v_up, up);
3017 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3018 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3019 skeleton->relativetransforms[bonenum] = matrix;
3022 // #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)
3023 static void VM_SV_skel_mul_bone(void)
3025 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3026 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3027 vec3_t forward, left, up, origin;
3028 skeleton_t *skeleton;
3031 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3033 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3035 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3036 VectorCopy(prog->globals.client->v_forward, forward);
3037 VectorNegate(prog->globals.client->v_right, left);
3038 VectorCopy(prog->globals.client->v_up, up);
3039 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3040 temp = skeleton->relativetransforms[bonenum];
3041 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3044 // #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)
3045 static void VM_SV_skel_mul_bones(void)
3047 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3048 int firstbone = PRVM_G_FLOAT(OFS_PARM1) - 1;
3049 int lastbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3051 vec3_t forward, left, up, origin;
3052 skeleton_t *skeleton;
3055 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3057 VectorCopy(PRVM_G_VECTOR(OFS_PARM3), origin);
3058 VectorCopy(prog->globals.client->v_forward, forward);
3059 VectorNegate(prog->globals.client->v_right, left);
3060 VectorCopy(prog->globals.client->v_up, up);
3061 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3062 firstbone = max(0, firstbone);
3063 lastbone = min(lastbone, skeleton->model->num_bones - 1);
3064 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3066 temp = skeleton->relativetransforms[bonenum];
3067 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3071 // #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
3072 static void VM_SV_skel_copybones(void)
3074 int skeletonindexdst = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3075 int skeletonindexsrc = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3076 int firstbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3077 int lastbone = PRVM_G_FLOAT(OFS_PARM3) - 1;
3079 skeleton_t *skeletondst;
3080 skeleton_t *skeletonsrc;
3081 if (skeletonindexdst < 0 || skeletonindexdst >= MAX_EDICTS || !(skeletondst = prog->skeletons[skeletonindexdst]))
3083 if (skeletonindexsrc < 0 || skeletonindexsrc >= MAX_EDICTS || !(skeletonsrc = prog->skeletons[skeletonindexsrc]))
3085 firstbone = max(0, firstbone);
3086 lastbone = min(lastbone, skeletondst->model->num_bones - 1);
3087 lastbone = min(lastbone, skeletonsrc->model->num_bones - 1);
3088 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3089 skeletondst->relativetransforms[bonenum] = skeletonsrc->relativetransforms[bonenum];
3092 // #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)
3093 static void VM_SV_skel_delete(void)
3095 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3096 skeleton_t *skeleton;
3097 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3100 prog->skeletons[skeletonindex] = NULL;
3103 // #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
3104 static void VM_SV_frameforname(void)
3106 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3107 dp_model_t *model = SV_GetModelByIndex(modelindex);
3108 const char *name = PRVM_G_STRING(OFS_PARM1);
3110 PRVM_G_FLOAT(OFS_RETURN) = -1;
3111 if (!model || !model->animscenes)
3113 for (i = 0;i < model->numframes;i++)
3115 if (!strcasecmp(model->animscenes[i].name, name))
3117 PRVM_G_FLOAT(OFS_RETURN) = i;
3123 // #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.
3124 static void VM_SV_frameduration(void)
3126 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3127 dp_model_t *model = SV_GetModelByIndex(modelindex);
3128 int framenum = (int)PRVM_G_FLOAT(OFS_PARM1);
3129 PRVM_G_FLOAT(OFS_RETURN) = 0;
3130 if (!model || !model->animscenes || framenum < 0 || framenum >= model->numframes)
3132 if (model->animscenes[framenum].framerate)
3133 PRVM_G_FLOAT(OFS_RETURN) = model->animscenes[framenum].framecount / model->animscenes[framenum].framerate;
3137 prvm_builtin_t vm_sv_builtins[] = {
3138 NULL, // #0 NULL function (not callable) (QUAKE)
3139 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
3140 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
3141 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
3142 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
3143 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
3144 VM_break, // #6 void() break (QUAKE)
3145 VM_random, // #7 float() random (QUAKE)
3146 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
3147 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
3148 VM_error, // #10 void(string e) error (QUAKE)
3149 VM_objerror, // #11 void(string e) objerror (QUAKE)
3150 VM_vlen, // #12 float(vector v) vlen (QUAKE)
3151 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
3152 VM_spawn, // #14 entity() spawn (QUAKE)
3153 VM_remove, // #15 void(entity e) remove (QUAKE)
3154 VM_SV_traceline, // #16 void(vector v1, vector v2, float tryents) traceline (QUAKE)
3155 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
3156 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
3157 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
3158 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
3159 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
3160 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
3161 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
3162 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
3163 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
3164 VM_ftos, // #26 string(float f) ftos (QUAKE)
3165 VM_vtos, // #27 string(vector v) vtos (QUAKE)
3166 VM_coredump, // #28 void() coredump (QUAKE)
3167 VM_traceon, // #29 void() traceon (QUAKE)
3168 VM_traceoff, // #30 void() traceoff (QUAKE)
3169 VM_eprint, // #31 void(entity e) eprint (QUAKE)
3170 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
3171 NULL, // #33 (QUAKE)
3172 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
3173 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
3174 VM_rint, // #36 float(float v) rint (QUAKE)
3175 VM_floor, // #37 float(float v) floor (QUAKE)
3176 VM_ceil, // #38 float(float v) ceil (QUAKE)
3177 NULL, // #39 (QUAKE)
3178 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
3179 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
3180 NULL, // #42 (QUAKE)
3181 VM_fabs, // #43 float(float f) fabs (QUAKE)
3182 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
3183 VM_cvar, // #45 float(string s) cvar (QUAKE)
3184 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
3185 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
3186 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
3187 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
3188 NULL, // #50 (QUAKE)
3189 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
3190 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
3191 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
3192 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
3193 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
3194 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
3195 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
3196 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
3197 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
3198 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
3199 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
3200 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
3201 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
3202 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
3203 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
3204 NULL, // #66 (QUAKE)
3205 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
3206 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
3207 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
3208 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
3209 NULL, // #71 (QUAKE)
3210 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
3211 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
3212 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
3213 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
3214 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
3215 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
3216 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
3217 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
3218 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
3219 VM_stof, // #81 float(string s) stof (FRIK_FILE)
3220 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
3221 NULL, // #83 (QUAKE)
3222 NULL, // #84 (QUAKE)
3223 NULL, // #85 (QUAKE)
3224 NULL, // #86 (QUAKE)
3225 NULL, // #87 (QUAKE)
3226 NULL, // #88 (QUAKE)
3227 NULL, // #89 (QUAKE)
3228 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
3229 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
3230 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
3231 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
3232 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
3233 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3234 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3235 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3236 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3237 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3238 // FrikaC and Telejano range #100-#199
3249 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3250 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3251 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3252 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3253 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3254 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3255 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3256 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3257 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3258 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3339 // FTEQW range #200-#299
3358 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3361 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3362 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3363 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3364 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3365 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3366 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3367 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3368 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3369 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3370 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3372 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3380 VM_SV_checkpvs, // #240 float(vector viewpos, entity viewee) checkpvs;
3403 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.
3404 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
3405 VM_SV_skel_get_numbones, // #265 float(float skel) skel_get_numbones = #265; // (DP_SKELETONOBJECTS) returns how many bones exist in the created skeleton
3406 VM_SV_skel_get_bonename, // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (DP_SKELETONOBJECTS) returns name of bone (as a tempstring)
3407 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)
3408 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
3409 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)
3410 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)
3411 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)
3412 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)
3413 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)
3414 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
3415 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)
3416 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
3417 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.
3440 // CSQC range #300-#399
3441 NULL, // #300 void() clearscene (EXT_CSQC)
3442 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3443 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3444 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3445 NULL, // #304 void() renderscene (EXT_CSQC)
3446 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3447 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3448 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3449 NULL, // #308 void() R_EndPolygon
3451 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3452 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3456 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3457 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3458 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3459 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3460 NULL, // #319 void(string name) freepic (EXT_CSQC)
3461 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3462 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3463 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3464 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3465 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3466 NULL, // #325 void(void) drawresetcliparea
3471 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3472 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3473 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3474 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3475 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3476 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3477 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3478 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3479 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3480 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3481 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3482 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3483 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3484 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3485 NULL, // #344 vector() getmousepos (EXT_CSQC)
3486 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3487 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3488 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3489 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3490 NULL, // #349 float() isdemo (EXT_CSQC)
3491 VM_isserver, // #350 float() isserver (EXT_CSQC)
3492 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3493 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3494 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3495 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3501 NULL, // #360 float() readbyte (EXT_CSQC)
3502 NULL, // #361 float() readchar (EXT_CSQC)
3503 NULL, // #362 float() readshort (EXT_CSQC)
3504 NULL, // #363 float() readlong (EXT_CSQC)
3505 NULL, // #364 float() readcoord (EXT_CSQC)
3506 NULL, // #365 float() readangle (EXT_CSQC)
3507 NULL, // #366 string() readstring (EXT_CSQC)
3508 NULL, // #367 float() readfloat (EXT_CSQC)
3541 // LordHavoc's range #400-#499
3542 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3543 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3544 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3545 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3546 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3547 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3548 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3549 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3550 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)
3551 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3552 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3553 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3554 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3555 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3556 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3557 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3558 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3559 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3560 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3561 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3562 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3563 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3564 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3565 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3566 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3567 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3568 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3569 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3570 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3571 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3572 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3573 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3574 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3575 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3576 VM_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3577 VM_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3578 VM_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3579 VM_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3580 VM_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3581 VM_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3582 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3583 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3584 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3585 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3586 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3587 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3588 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3589 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3590 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3591 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3592 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3593 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3594 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3595 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3596 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3597 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3598 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3599 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3601 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3602 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3603 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3604 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3605 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3606 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3607 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3608 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3609 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3610 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3611 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3613 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3614 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3615 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3616 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3617 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3618 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3619 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3620 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3621 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3622 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3623 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3624 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3625 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3626 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3627 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3628 VM_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3636 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3637 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3638 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3639 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3640 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3641 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3642 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3643 VM_SV_WritePicture, // #501
3645 VM_whichpack, // #503 string(string) whichpack = #503;
3652 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3653 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3654 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3655 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)
3656 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3657 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3658 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3659 VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
3660 VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
3661 VM_gettime, // #519 float(float timer) gettime = #519; (DP_QC_GETTIME)
3671 VM_loadfromdata, // #529
3672 VM_loadfromfile, // #530
3673 VM_SV_setpause, // #531 void(float pause) setpause = #531;
3675 VM_getsoundtime, // #533 float(entity e, float channel) getsoundtime = #533; (DP_SND_GETSOUNDTIME)
3676 VM_soundlength, // #534 float(string sample) soundlength = #534; (DP_SND_GETSOUNDTIME)
3747 VM_callfunction, // #605
3748 VM_writetofile, // #606
3749 VM_isfunction, // #607
3755 VM_parseentitydata, // #613
3766 VM_SV_getextresponse, // #624 string getextresponse(void)
3769 VM_sprintf, // #627 string sprintf(string format, ...)
3770 VM_getsurfacenumtriangles, // #628 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACETRIANGLE)
3771 VM_getsurfacetriangle, // #629 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACETRIANGLE)
3775 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3777 void VM_SV_Cmd_Init(void)
3782 void VM_SV_Cmd_Reset(void)
3784 World_End(&sv.world);
3785 if(prog->funcoffsets.SV_Shutdown)
3787 func_t s = prog->funcoffsets.SV_Shutdown;
3788 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3789 PRVM_ExecuteProgram(s,"SV_Shutdown() required");