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 "
30 "DP_CSQC_ROTATEMOVES "
43 "DP_EF_RESTARTANIM_BIT "
48 "DP_ENT_CUSTOMCOLORMAP "
49 "DP_ENT_EXTERIORMODELTOCLIENT "
52 "DP_ENT_LOWPRECISION "
56 "DP_GFX_EXTERNALTEXTURES "
57 "DP_GFX_EXTERNALTEXTURES_PERMAP "
59 "DP_GFX_MODEL_INTERPOLATION "
60 "DP_GFX_QUAKE3MODELTAGS "
64 "DP_GFX_FONTS_FREETYPE "
66 "DP_FONT_VARIABLEWIDTH "
68 "DP_HALFLIFE_MAP_CVAR "
71 "DP_LIGHTSTYLE_STATICVALUE "
75 "DP_MOVETYPEBOUNCEMISSILE "
78 "DP_QC_ASINACOSATANATAN2TAN "
84 "DP_QC_CVAR_DEFSTRING "
85 "DP_QC_CVAR_DESCRIPTION "
92 "DP_QC_EXTRESPONSEPACKET "
94 "DP_QC_FINDCHAINFLAGS "
95 "DP_QC_FINDCHAINFLOAT "
96 "DP_QC_FINDCHAIN_TOFIELD "
102 "DP_QC_GETSURFACETRIANGLE "
103 "DP_QC_GETSURFACEPOINTATTRIBUTE "
105 "DP_QC_GETTAGINFO_BONEPROPERTIES "
107 "DP_QC_GETTIME_CDTRACK "
110 "DP_QC_MULTIPLETEMPSTRINGS "
111 "DP_QC_NUM_FOR_EDICT "
113 "DP_QC_SINCOSSQRTPOW "
116 "DP_QC_STRINGBUFFERS "
117 "DP_QC_STRINGBUFFERS_CVARLIST "
118 "DP_QC_STRINGCOLORFUNCTIONS "
119 "DP_QC_STRING_CASE_FUNCTIONS "
121 "DP_QC_TOKENIZEBYSEPARATOR "
122 "DP_QC_TOKENIZE_CONSOLE "
125 "DP_QC_TRACE_MOVETYPE_HITMODEL "
126 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
127 "DP_QC_UNLIMITEDTEMPSTRINGS "
131 "DP_QC_VECTOANGLES_WITH_ROLL "
132 "DP_QC_VECTORVECTORS "
139 "DP_SKELETONOBJECTS "
140 "DP_SND_DIRECTIONLESSATTNNONE "
145 "DP_SND_GETSOUNDTIME "
147 "DP_VIDEO_SUBTITLES "
151 "DP_SV_BOUNCEFACTOR "
152 "DP_SV_CLIENTCAMERA "
153 "DP_SV_CLIENTCOLORS "
156 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
157 "DP_SV_DISCARDABLEDEMO "
158 "DP_SV_DRAWONLYTOCLIENT "
161 "DP_SV_ENTITYCONTENTSTRANSITION "
162 "DP_SV_MODELFLAGS_AS_EFFECTS "
163 "DP_SV_MOVETYPESTEP_LANDEVENT "
165 "DP_SV_NODRAWTOCLIENT "
166 "DP_SV_ONENTITYNOSPAWNFUNCTION "
167 "DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
169 "DP_SV_PING_PACKETLOSS "
170 "DP_SV_PLAYERPHYSICS "
172 "DP_SV_POINTPARTICLES "
174 "DP_SV_PRECACHEANYTIME "
178 "DP_SV_ROTATINGBMODEL "
182 "DP_SV_SPAWNFUNC_PREFIX "
183 "DP_SV_WRITEPICTURE "
184 "DP_SV_WRITEUNTERMINATEDSTRING "
188 "DP_TE_EXPLOSIONRGB "
190 "DP_TE_PARTICLECUBE "
191 "DP_TE_PARTICLERAIN "
192 "DP_TE_PARTICLESNOW "
194 "DP_TE_QUADEFFECTS1 "
197 "DP_TE_STANDARDEFFECTBUILTINS "
198 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
202 "FTE_CSQC_SKELETONOBJECTS "
205 "KRIMZON_SV_PARSECLIENTCOMMAND "
208 "NEXUIZ_PLAYERMODEL "
210 "PRYDON_CLIENTCURSOR "
211 "TENEBRAE_GFX_DLIGHTS "
214 //"EXT_CSQC " // not ready yet
221 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.
223 setorigin (entity, origin)
226 static void VM_SV_setorigin (void)
231 VM_SAFEPARMCOUNT(2, VM_setorigin);
233 e = PRVM_G_EDICT(OFS_PARM0);
234 if (e == prog->edicts)
236 VM_Warning("setorigin: can not modify world entity\n");
239 if (e->priv.server->free)
241 VM_Warning("setorigin: can not modify free entity\n");
244 org = PRVM_G_VECTOR(OFS_PARM1);
245 VectorCopy (org, e->fields.server->origin);
249 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
250 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
254 for (i=0 ; i<3 ; i++)
256 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
258 // set derived values
259 VectorCopy (min, e->fields.server->mins);
260 VectorCopy (max, e->fields.server->maxs);
261 VectorSubtract (max, min, e->fields.server->size);
270 the size box is rotated by the current angle
271 LordHavoc: no it isn't...
273 setsize (entity, minvector, maxvector)
276 static void VM_SV_setsize (void)
281 VM_SAFEPARMCOUNT(3, VM_setsize);
283 e = PRVM_G_EDICT(OFS_PARM0);
284 if (e == prog->edicts)
286 VM_Warning("setsize: can not modify world entity\n");
289 if (e->priv.server->free)
291 VM_Warning("setsize: can not modify free entity\n");
294 min = PRVM_G_VECTOR(OFS_PARM1);
295 max = PRVM_G_VECTOR(OFS_PARM2);
296 SetMinMaxSize (e, min, max, false);
304 setmodel(entity, model)
307 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
308 static void VM_SV_setmodel (void)
314 VM_SAFEPARMCOUNT(2, VM_setmodel);
316 e = PRVM_G_EDICT(OFS_PARM0);
317 if (e == prog->edicts)
319 VM_Warning("setmodel: can not modify world entity\n");
322 if (e->priv.server->free)
324 VM_Warning("setmodel: can not modify free entity\n");
327 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
328 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
329 e->fields.server->modelindex = i;
331 mod = SV_GetModelByIndex(i);
335 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
336 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
338 SetMinMaxSize (e, quakemins, quakemaxs, true);
341 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
348 single print to a specific client
350 sprint(clientent, value)
353 static void VM_SV_sprint (void)
357 char string[VM_STRINGTEMP_LENGTH];
359 VM_VarString(1, string, sizeof(string));
361 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
363 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
364 // LordHavoc: div0 requested that sprintto world operate like print
371 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
373 VM_Warning("tried to centerprint to a non-client\n");
377 client = svs.clients + entnum-1;
378 if (!client->netconnection)
381 MSG_WriteChar(&client->netconnection->message,svc_print);
382 MSG_WriteString(&client->netconnection->message, string);
390 single print to a specific client
392 centerprint(clientent, value)
395 static void VM_SV_centerprint (void)
399 char string[VM_STRINGTEMP_LENGTH];
401 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
403 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
405 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
407 VM_Warning("tried to centerprint to a non-client\n");
411 client = svs.clients + entnum-1;
412 if (!client->netconnection)
415 VM_VarString(1, string, sizeof(string));
416 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
417 MSG_WriteString(&client->netconnection->message, string);
424 particle(origin, color, count)
427 static void VM_SV_particle (void)
433 VM_SAFEPARMCOUNT(4, VM_SV_particle);
435 org = PRVM_G_VECTOR(OFS_PARM0);
436 dir = PRVM_G_VECTOR(OFS_PARM1);
437 color = PRVM_G_FLOAT(OFS_PARM2);
438 count = PRVM_G_FLOAT(OFS_PARM3);
439 SV_StartParticle (org, dir, (int)color, (int)count);
449 static void VM_SV_ambientsound (void)
453 float vol, attenuation;
456 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
458 pos = PRVM_G_VECTOR (OFS_PARM0);
459 samp = PRVM_G_STRING(OFS_PARM1);
460 vol = PRVM_G_FLOAT(OFS_PARM2);
461 attenuation = PRVM_G_FLOAT(OFS_PARM3);
463 // check to see if samp was properly precached
464 soundnum = SV_SoundIndex(samp, 1);
472 // add an svc_spawnambient command to the level signon packet
475 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
477 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
479 MSG_WriteVector(&sv.signon, pos, sv.protocol);
481 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
482 MSG_WriteShort (&sv.signon, soundnum);
484 MSG_WriteByte (&sv.signon, soundnum);
486 MSG_WriteByte (&sv.signon, (int)(vol*255));
487 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
495 Each entity can have eight independant sound sources, like voice,
498 Channel 0 is an auto-allocate channel, the others override anything
499 already running on that entity/channel pair.
501 An attenuation of 0 will play full volume everywhere in the level.
502 Larger attenuations will drop off.
506 static void VM_SV_sound (void)
510 prvm_edict_t *entity;
514 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
516 entity = PRVM_G_EDICT(OFS_PARM0);
517 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
518 sample = PRVM_G_STRING(OFS_PARM2);
519 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
520 attenuation = PRVM_G_FLOAT(OFS_PARM4);
523 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
527 if (volume < 0 || volume > 255)
529 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
533 if (attenuation < 0 || attenuation > 4)
535 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
539 if (channel < 0 || channel > 7)
541 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
545 SV_StartSound (entity, channel, sample, volume, attenuation);
552 Follows the same logic as VM_SV_sound, except instead of
553 an entity, an origin for the sound is provided, and channel
554 is omitted (since no entity is being tracked).
558 static void VM_SV_pointsound(void)
565 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
567 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
568 sample = PRVM_G_STRING(OFS_PARM1);
569 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
570 attenuation = PRVM_G_FLOAT(OFS_PARM3);
572 if (volume < 0 || volume > 255)
574 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
578 if (attenuation < 0 || attenuation > 4)
580 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
584 SV_StartPointSound (org, sample, volume, attenuation);
591 Used for use tracing and shot targeting
592 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
593 if the tryents flag is set.
595 traceline (vector1, vector2, movetype, ignore)
598 static void VM_SV_traceline (void)
605 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
607 prog->xfunction->builtinsprofile += 30;
609 v1 = PRVM_G_VECTOR(OFS_PARM0);
610 v2 = PRVM_G_VECTOR(OFS_PARM1);
611 move = (int)PRVM_G_FLOAT(OFS_PARM2);
612 ent = PRVM_G_EDICT(OFS_PARM3);
614 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]))
615 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));
617 trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
619 VM_SetTraceGlobals(&trace);
627 Used for use tracing and shot targeting
628 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
629 if the tryents flag is set.
631 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
634 // LordHavoc: added this for my own use, VERY useful, similar to traceline
635 static void VM_SV_tracebox (void)
637 float *v1, *v2, *m1, *m2;
642 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
644 prog->xfunction->builtinsprofile += 30;
646 v1 = PRVM_G_VECTOR(OFS_PARM0);
647 m1 = PRVM_G_VECTOR(OFS_PARM1);
648 m2 = PRVM_G_VECTOR(OFS_PARM2);
649 v2 = PRVM_G_VECTOR(OFS_PARM3);
650 move = (int)PRVM_G_FLOAT(OFS_PARM4);
651 ent = PRVM_G_EDICT(OFS_PARM5);
653 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]))
654 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));
656 trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
658 VM_SetTraceGlobals(&trace);
661 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
666 vec3_t original_origin;
667 vec3_t original_velocity;
668 vec3_t original_angles;
669 vec3_t original_avelocity;
673 VectorCopy(tossent->fields.server->origin , original_origin );
674 VectorCopy(tossent->fields.server->velocity , original_velocity );
675 VectorCopy(tossent->fields.server->angles , original_angles );
676 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
678 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
679 if (val != NULL && val->_float != 0)
680 gravity = val->_float;
683 gravity *= sv_gravity.value * 0.025;
685 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
687 SV_CheckVelocity (tossent);
688 tossent->fields.server->velocity[2] -= gravity;
689 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
690 VectorScale (tossent->fields.server->velocity, 0.05, move);
691 VectorAdd (tossent->fields.server->origin, move, end);
692 trace = SV_TraceBox(tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
693 VectorCopy (trace.endpos, tossent->fields.server->origin);
694 tossent->fields.server->velocity[2] -= gravity;
696 if (trace.fraction < 1)
700 VectorCopy(original_origin , tossent->fields.server->origin );
701 VectorCopy(original_velocity , tossent->fields.server->velocity );
702 VectorCopy(original_angles , tossent->fields.server->angles );
703 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
708 static void VM_SV_tracetoss (void)
712 prvm_edict_t *ignore;
714 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
716 prog->xfunction->builtinsprofile += 600;
718 ent = PRVM_G_EDICT(OFS_PARM0);
719 if (ent == prog->edicts)
721 VM_Warning("tracetoss: can not use world entity\n");
724 ignore = PRVM_G_EDICT(OFS_PARM1);
726 trace = SV_Trace_Toss (ent, ignore);
728 VM_SetTraceGlobals(&trace);
731 //============================================================================
733 static int checkpvsbytes;
734 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
736 static int VM_SV_newcheckclient (int check)
742 // cycle to the next one
744 check = bound(1, check, svs.maxclients);
745 if (check == svs.maxclients)
753 prog->xfunction->builtinsprofile++;
755 if (i == svs.maxclients+1)
757 // look up the client's edict
758 ent = PRVM_EDICT_NUM(i);
759 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
760 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
762 // found a valid client (possibly the same one again)
766 // get the PVS for the entity
767 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
769 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
770 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
779 Returns a client (or object that has a client enemy) that would be a
782 If there is more than one valid option, they are cycled each frame
784 If (self.origin + self.viewofs) is not in the PVS of the current target,
785 it is not returned at all.
790 int c_invis, c_notvis;
791 static void VM_SV_checkclient (void)
793 prvm_edict_t *ent, *self;
796 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
798 // find a new check if on a new frame
799 if (sv.time - sv.lastchecktime >= 0.1)
801 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
802 sv.lastchecktime = sv.time;
805 // return check if it might be visible
806 ent = PRVM_EDICT_NUM(sv.lastcheck);
807 if (ent->priv.server->free || ent->fields.server->health <= 0)
809 VM_RETURN_EDICT(prog->edicts);
813 // if current entity can't possibly see the check entity, return 0
814 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
815 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
816 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
819 VM_RETURN_EDICT(prog->edicts);
823 // might be able to see it
825 VM_RETURN_EDICT(ent);
828 //============================================================================
834 Checks if an entity is in a point's PVS.
835 Should be fast but can be inexact.
837 float checkpvs(vector viewpos, entity viewee) = #240;
840 static void VM_SV_checkpvs (void)
843 prvm_edict_t *viewee;
848 unsigned char fatpvs[MAX_MAP_LEAFS/8];
851 VM_SAFEPARMCOUNT(2, VM_SV_checkpvs);
852 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos);
853 viewee = PRVM_G_EDICT(OFS_PARM1);
855 if(viewee->priv.server->free)
857 VM_Warning("checkpvs: can not check free entity\n");
858 PRVM_G_FLOAT(OFS_RETURN) = 4;
863 if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
865 // no PVS support on this worldmodel... darn
866 PRVM_G_FLOAT(OFS_RETURN) = 3;
869 pvs = sv.worldmodel->brush.GetPVS(sv.worldmodel, viewpos);
872 // viewpos isn't in any PVS... darn
873 PRVM_G_FLOAT(OFS_RETURN) = 2;
876 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
878 // using fat PVS like FTEQW does (slow)
879 if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
881 // no PVS support on this worldmodel... darn
882 PRVM_G_FLOAT(OFS_RETURN) = 3;
885 fatpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
888 // viewpos isn't in any PVS... darn
889 PRVM_G_FLOAT(OFS_RETURN) = 2;
892 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
901 Sends text over to the client's execution buffer
903 stuffcmd (clientent, value, ...)
906 static void VM_SV_stuffcmd (void)
910 char string[VM_STRINGTEMP_LENGTH];
912 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
914 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
915 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
917 VM_Warning("Can't stuffcmd to a non-client\n");
921 VM_VarString(1, string, sizeof(string));
924 host_client = svs.clients + entnum-1;
925 Host_ClientCommands ("%s", string);
933 Returns a chain of entities that have origins within a spherical area
935 findradius (origin, radius)
938 static void VM_SV_findradius (void)
940 prvm_edict_t *ent, *chain;
941 vec_t radius, radius2;
942 vec3_t org, eorg, mins, maxs;
945 static prvm_edict_t *touchedicts[MAX_EDICTS];
948 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findradius);
951 chainfield = PRVM_G_INT(OFS_PARM2);
953 chainfield = prog->fieldoffsets.chain;
955 PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
957 chain = (prvm_edict_t *)prog->edicts;
959 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
960 radius = PRVM_G_FLOAT(OFS_PARM1);
961 radius2 = radius * radius;
963 mins[0] = org[0] - (radius + 1);
964 mins[1] = org[1] - (radius + 1);
965 mins[2] = org[2] - (radius + 1);
966 maxs[0] = org[0] + (radius + 1);
967 maxs[1] = org[1] + (radius + 1);
968 maxs[2] = org[2] + (radius + 1);
969 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
970 if (numtouchedicts > MAX_EDICTS)
972 // this never happens
973 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
974 numtouchedicts = MAX_EDICTS;
976 for (i = 0;i < numtouchedicts;i++)
978 ent = touchedicts[i];
979 prog->xfunction->builtinsprofile++;
980 // Quake did not return non-solid entities but darkplaces does
981 // (note: this is the reason you can't blow up fallen zombies)
982 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
984 // LordHavoc: compare against bounding box rather than center so it
985 // doesn't miss large objects, and use DotProduct instead of Length
986 // for a major speedup
987 VectorSubtract(org, ent->fields.server->origin, eorg);
988 if (sv_gameplayfix_findradiusdistancetobox.integer)
990 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
991 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
992 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
995 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
996 if (DotProduct(eorg, eorg) < radius2)
998 PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
1003 VM_RETURN_EDICT(chain);
1006 static void VM_SV_precache_sound (void)
1008 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
1009 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
1012 static void VM_SV_precache_model (void)
1014 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
1015 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
1016 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
1023 float(float yaw, float dist[, settrace]) walkmove
1026 static void VM_SV_walkmove (void)
1035 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
1037 // assume failure if it returns early
1038 PRVM_G_FLOAT(OFS_RETURN) = 0;
1040 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1041 if (ent == prog->edicts)
1043 VM_Warning("walkmove: can not modify world entity\n");
1046 if (ent->priv.server->free)
1048 VM_Warning("walkmove: can not modify free entity\n");
1051 yaw = PRVM_G_FLOAT(OFS_PARM0);
1052 dist = PRVM_G_FLOAT(OFS_PARM1);
1053 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
1055 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1058 yaw = yaw*M_PI*2 / 360;
1060 move[0] = cos(yaw)*dist;
1061 move[1] = sin(yaw)*dist;
1064 // save program state, because SV_movestep may call other progs
1065 oldf = prog->xfunction;
1066 oldself = prog->globals.server->self;
1068 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
1071 // restore program state
1072 prog->xfunction = oldf;
1073 prog->globals.server->self = oldself;
1083 static void VM_SV_droptofloor (void)
1089 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
1091 // assume failure if it returns early
1092 PRVM_G_FLOAT(OFS_RETURN) = 0;
1094 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1095 if (ent == prog->edicts)
1097 VM_Warning("droptofloor: can not modify world entity\n");
1100 if (ent->priv.server->free)
1102 VM_Warning("droptofloor: can not modify free entity\n");
1106 VectorCopy (ent->fields.server->origin, end);
1109 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
1110 SV_UnstickEntity(ent);
1112 trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1113 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
1116 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]);
1117 VectorAdd(ent->fields.server->origin, offset, org);
1118 trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1119 VectorSubtract(trace.endpos, offset, trace.endpos);
1120 if (trace.startsolid)
1122 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]);
1123 SV_UnstickEntity(ent);
1125 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1126 ent->fields.server->groundentity = 0;
1127 PRVM_G_FLOAT(OFS_RETURN) = 1;
1129 else if (trace.fraction < 1)
1131 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]);
1132 VectorCopy (trace.endpos, ent->fields.server->origin);
1133 SV_UnstickEntity(ent);
1135 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1136 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1137 PRVM_G_FLOAT(OFS_RETURN) = 1;
1138 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1139 ent->priv.server->suspendedinairflag = true;
1144 if (trace.fraction != 1)
1146 if (trace.fraction < 1)
1147 VectorCopy (trace.endpos, ent->fields.server->origin);
1149 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1150 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1151 PRVM_G_FLOAT(OFS_RETURN) = 1;
1152 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1153 ent->priv.server->suspendedinairflag = true;
1162 void(float style, string value) lightstyle
1165 static void VM_SV_lightstyle (void)
1172 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1174 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1175 val = PRVM_G_STRING(OFS_PARM1);
1177 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1178 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1181 // change the string in sv
1182 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1184 // send message to all clients on this server
1185 if (sv.state != ss_active)
1188 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1190 if (client->active && client->netconnection)
1192 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1193 MSG_WriteChar (&client->netconnection->message,style);
1194 MSG_WriteString (&client->netconnection->message, val);
1204 static void VM_SV_checkbottom (void)
1206 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1207 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1215 static void VM_SV_pointcontents (void)
1217 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1218 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1225 Pick a vector for the player to shoot along
1226 vector aim(entity, missilespeed)
1229 static void VM_SV_aim (void)
1231 prvm_edict_t *ent, *check, *bestent;
1232 vec3_t start, dir, end, bestdir;
1235 float dist, bestdist;
1238 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1240 // assume failure if it returns early
1241 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1242 // if sv_aim is so high it can't possibly accept anything, skip out early
1243 if (sv_aim.value >= 1)
1246 ent = PRVM_G_EDICT(OFS_PARM0);
1247 if (ent == prog->edicts)
1249 VM_Warning("aim: can not use world entity\n");
1252 if (ent->priv.server->free)
1254 VM_Warning("aim: can not use free entity\n");
1257 //speed = PRVM_G_FLOAT(OFS_PARM1);
1259 VectorCopy (ent->fields.server->origin, start);
1262 // try sending a trace straight
1263 VectorCopy (prog->globals.server->v_forward, dir);
1264 VectorMA (start, 2048, dir, end);
1265 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1266 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1267 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1269 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1274 // try all possible entities
1275 VectorCopy (dir, bestdir);
1276 bestdist = sv_aim.value;
1279 check = PRVM_NEXT_EDICT(prog->edicts);
1280 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1282 prog->xfunction->builtinsprofile++;
1283 if (check->fields.server->takedamage != DAMAGE_AIM)
1287 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1288 continue; // don't aim at teammate
1289 for (j=0 ; j<3 ; j++)
1290 end[j] = check->fields.server->origin[j]
1291 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1292 VectorSubtract (end, start, dir);
1293 VectorNormalize (dir);
1294 dist = DotProduct (dir, prog->globals.server->v_forward);
1295 if (dist < bestdist)
1296 continue; // to far to turn
1297 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1298 if (tr.ent == check)
1299 { // can shoot at this one
1307 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1308 dist = DotProduct (dir, prog->globals.server->v_forward);
1309 VectorScale (prog->globals.server->v_forward, dist, end);
1311 VectorNormalize (end);
1312 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1316 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1321 ===============================================================================
1325 ===============================================================================
1328 #define MSG_BROADCAST 0 // unreliable to all
1329 #define MSG_ONE 1 // reliable to one (msg_entity)
1330 #define MSG_ALL 2 // reliable to all
1331 #define MSG_INIT 3 // write to the init string
1332 #define MSG_ENTITY 5
1334 sizebuf_t *WriteDest (void)
1340 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1344 return &sv.datagram;
1347 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1348 entnum = PRVM_NUM_FOR_EDICT(ent);
1349 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1351 VM_Warning ("WriteDest: tried to write to non-client\n");
1352 return &sv.reliable_datagram;
1355 return &svs.clients[entnum-1].netconnection->message;
1358 VM_Warning ("WriteDest: bad destination\n");
1360 return &sv.reliable_datagram;
1366 return sv.writeentitiestoclient_msg;
1372 static void VM_SV_WriteByte (void)
1374 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1375 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1378 static void VM_SV_WriteChar (void)
1380 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1381 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1384 static void VM_SV_WriteShort (void)
1386 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1387 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1390 static void VM_SV_WriteLong (void)
1392 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1393 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1396 static void VM_SV_WriteAngle (void)
1398 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1399 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1402 static void VM_SV_WriteCoord (void)
1404 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1405 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1408 static void VM_SV_WriteString (void)
1410 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1411 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1414 static void VM_SV_WriteUnterminatedString (void)
1416 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1417 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1421 static void VM_SV_WriteEntity (void)
1423 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1424 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1427 // writes a picture as at most size bytes of data
1429 // IMGNAME \0 SIZE(short) IMGDATA
1430 // if failed to read/compress:
1432 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1433 static void VM_SV_WritePicture (void)
1435 const char *imgname;
1439 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1441 imgname = PRVM_G_STRING(OFS_PARM1);
1442 size = (int) PRVM_G_FLOAT(OFS_PARM2);
1446 MSG_WriteString(WriteDest(), imgname);
1447 if(Image_Compress(imgname, size, &buf, &size))
1450 MSG_WriteShort(WriteDest(), size);
1451 SZ_Write(WriteDest(), (unsigned char *) buf, size);
1456 MSG_WriteShort(WriteDest(), 0);
1460 //////////////////////////////////////////////////////////
1462 static void VM_SV_makestatic (void)
1467 // allow 0 parameters due to an id1 qc bug in which this function is used
1468 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1469 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1471 if (prog->argc >= 1)
1472 ent = PRVM_G_EDICT(OFS_PARM0);
1474 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1475 if (ent == prog->edicts)
1477 VM_Warning("makestatic: can not modify world entity\n");
1480 if (ent->priv.server->free)
1482 VM_Warning("makestatic: can not modify free entity\n");
1487 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1492 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1493 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1494 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1496 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1498 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1499 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1500 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1504 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1505 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1506 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1509 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1510 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1511 for (i=0 ; i<3 ; i++)
1513 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1514 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1517 // throw the entity away now
1521 //=============================================================================
1528 static void VM_SV_setspawnparms (void)
1534 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1536 ent = PRVM_G_EDICT(OFS_PARM0);
1537 i = PRVM_NUM_FOR_EDICT(ent);
1538 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1540 Con_Print("tried to setspawnparms on a non-client\n");
1544 // copy spawn parms out of the client_t
1545 client = svs.clients + i-1;
1546 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1547 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1554 Returns a color vector indicating the lighting at the requested point.
1556 (Internal Operation note: actually measures the light beneath the point, just like
1557 the model lighting on the client)
1562 static void VM_SV_getlight (void)
1564 vec3_t ambientcolor, diffusecolor, diffusenormal;
1566 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1567 p = PRVM_G_VECTOR(OFS_PARM0);
1568 VectorClear(ambientcolor);
1569 VectorClear(diffusecolor);
1570 VectorClear(diffusenormal);
1571 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1572 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1573 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1578 unsigned char type; // 1/2/8 or other value if isn't used
1582 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1583 static int vm_customstats_last;
1585 void VM_CustomStats_Clear (void)
1589 Z_Free(vm_customstats);
1590 vm_customstats = NULL;
1591 vm_customstats_last = -1;
1595 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1603 for(i=0; i<vm_customstats_last+1 ;i++)
1605 if(!vm_customstats[i].type)
1607 switch(vm_customstats[i].type)
1609 //string as 16 bytes
1612 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1613 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1614 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1615 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1616 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1618 //float field sent as-is
1620 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1622 //integer value of float field
1624 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1632 // void(float index, float type, .void field) SV_AddStat = #232;
1633 // Set up an auto-sent player stat.
1634 // Client's get thier own fields sent to them. Index may not be less than 32.
1635 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1636 // 1: string (4 stats carrying a total of 16 charactures)
1637 // 2: float (one stat, float converted to an integer for transportation)
1638 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1639 static void VM_SV_AddStat (void)
1644 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1648 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1651 VM_Warning("PF_SV_AddStat: not enough memory\n");
1655 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1656 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1657 off = PRVM_G_INT (OFS_PARM2);
1662 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1665 if(i >= (MAX_CL_STATS-32))
1667 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1670 if(i > (MAX_CL_STATS-32-4) && type == 1)
1672 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1675 vm_customstats[i].type = type;
1676 vm_customstats[i].fieldoffset = off;
1677 if(vm_customstats_last < i)
1678 vm_customstats_last = i;
1685 copies data from one entity to another
1687 copyentity(src, dst)
1690 static void VM_SV_copyentity (void)
1692 prvm_edict_t *in, *out;
1693 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1694 in = PRVM_G_EDICT(OFS_PARM0);
1695 if (in == prog->edicts)
1697 VM_Warning("copyentity: can not read world entity\n");
1700 if (in->priv.server->free)
1702 VM_Warning("copyentity: can not read free entity\n");
1705 out = PRVM_G_EDICT(OFS_PARM1);
1706 if (out == prog->edicts)
1708 VM_Warning("copyentity: can not modify world entity\n");
1711 if (out->priv.server->free)
1713 VM_Warning("copyentity: can not modify free entity\n");
1716 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1725 sets the color of a client and broadcasts the update to all connected clients
1727 setcolor(clientent, value)
1730 static void VM_SV_setcolor (void)
1736 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1737 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1738 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1740 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1742 Con_Print("tried to setcolor a non-client\n");
1746 client = svs.clients + entnum-1;
1749 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1751 client->edict->fields.server->team = (i & 15) + 1;
1754 if (client->old_colors != client->colors)
1756 client->old_colors = client->colors;
1757 // send notification to all clients
1758 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1759 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1760 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1768 effect(origin, modelname, startframe, framecount, framerate)
1771 static void VM_SV_effect (void)
1775 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1776 s = PRVM_G_STRING(OFS_PARM1);
1779 VM_Warning("effect: no model specified\n");
1783 i = SV_ModelIndex(s, 1);
1786 VM_Warning("effect: model not precached\n");
1790 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1792 VM_Warning("effect: framecount < 1\n");
1796 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1798 VM_Warning("effect: framerate < 1\n");
1802 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));
1805 static void VM_SV_te_blood (void)
1807 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1808 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1810 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1811 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1814 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1815 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1817 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1818 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1819 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1821 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1822 SV_FlushBroadcastMessages();
1825 static void VM_SV_te_bloodshower (void)
1827 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1828 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1830 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1831 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1833 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1834 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1835 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1837 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1838 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1839 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1841 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1843 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1844 SV_FlushBroadcastMessages();
1847 static void VM_SV_te_explosionrgb (void)
1849 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1850 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1851 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1853 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1854 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1855 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1857 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1858 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1859 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1860 SV_FlushBroadcastMessages();
1863 static void VM_SV_te_particlecube (void)
1865 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1866 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1868 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1869 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1871 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1872 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1873 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1875 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1876 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1877 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1879 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1880 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1881 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1883 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1885 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1886 // gravity true/false
1887 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1889 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1890 SV_FlushBroadcastMessages();
1893 static void VM_SV_te_particlerain (void)
1895 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1896 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1898 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1899 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1902 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1903 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1905 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1906 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1907 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1909 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1910 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1911 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1913 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1915 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1916 SV_FlushBroadcastMessages();
1919 static void VM_SV_te_particlesnow (void)
1921 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1922 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1924 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1925 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1927 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1928 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1929 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1931 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1933 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1935 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1936 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1937 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1939 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1941 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1942 SV_FlushBroadcastMessages();
1945 static void VM_SV_te_spark (void)
1947 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1948 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1950 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1951 MSG_WriteByte(&sv.datagram, TE_SPARK);
1953 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1954 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1955 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1957 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1958 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1959 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1961 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1962 SV_FlushBroadcastMessages();
1965 static void VM_SV_te_gunshotquad (void)
1967 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1968 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1969 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1974 SV_FlushBroadcastMessages();
1977 static void VM_SV_te_spikequad (void)
1979 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1980 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1981 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1983 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1984 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1985 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1986 SV_FlushBroadcastMessages();
1989 static void VM_SV_te_superspikequad (void)
1991 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1992 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1993 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1996 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1997 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1998 SV_FlushBroadcastMessages();
2001 static void VM_SV_te_explosionquad (void)
2003 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
2004 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2005 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2007 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2008 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2009 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2010 SV_FlushBroadcastMessages();
2013 static void VM_SV_te_smallflash (void)
2015 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
2016 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2017 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2019 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2020 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2021 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2022 SV_FlushBroadcastMessages();
2025 static void VM_SV_te_customflash (void)
2027 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
2028 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2030 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2031 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2033 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2034 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2035 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2037 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2039 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
2041 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
2042 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
2043 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
2044 SV_FlushBroadcastMessages();
2047 static void VM_SV_te_gunshot (void)
2049 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
2050 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2051 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2053 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2054 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2055 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2056 SV_FlushBroadcastMessages();
2059 static void VM_SV_te_spike (void)
2061 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
2062 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2063 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2065 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2066 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2067 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2068 SV_FlushBroadcastMessages();
2071 static void VM_SV_te_superspike (void)
2073 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
2074 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2075 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2077 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2078 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2079 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2080 SV_FlushBroadcastMessages();
2083 static void VM_SV_te_explosion (void)
2085 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
2086 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2087 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2089 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2090 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2091 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2092 SV_FlushBroadcastMessages();
2095 static void VM_SV_te_tarexplosion (void)
2097 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
2098 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2099 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2101 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2102 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2103 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2104 SV_FlushBroadcastMessages();
2107 static void VM_SV_te_wizspike (void)
2109 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
2110 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2111 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2113 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2114 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2115 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2116 SV_FlushBroadcastMessages();
2119 static void VM_SV_te_knightspike (void)
2121 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2122 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2123 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2125 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2126 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2127 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2128 SV_FlushBroadcastMessages();
2131 static void VM_SV_te_lavasplash (void)
2133 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2134 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2135 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2137 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2138 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2139 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2140 SV_FlushBroadcastMessages();
2143 static void VM_SV_te_teleport (void)
2145 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2146 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2147 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2149 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2150 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2151 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2152 SV_FlushBroadcastMessages();
2155 static void VM_SV_te_explosion2 (void)
2157 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2158 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2159 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2161 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2162 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2163 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2165 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2166 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2167 SV_FlushBroadcastMessages();
2170 static void VM_SV_te_lightning1 (void)
2172 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2173 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2174 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2176 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2178 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2179 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2180 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2182 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2183 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2184 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2185 SV_FlushBroadcastMessages();
2188 static void VM_SV_te_lightning2 (void)
2190 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2191 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2192 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2194 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2196 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2197 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2198 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2200 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2201 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2202 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2203 SV_FlushBroadcastMessages();
2206 static void VM_SV_te_lightning3 (void)
2208 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2209 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2210 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2212 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2214 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2215 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2216 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2218 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2219 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2220 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2221 SV_FlushBroadcastMessages();
2224 static void VM_SV_te_beam (void)
2226 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2227 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2228 MSG_WriteByte(&sv.datagram, TE_BEAM);
2230 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2232 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2233 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2234 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2236 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2237 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2238 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2239 SV_FlushBroadcastMessages();
2242 static void VM_SV_te_plasmaburn (void)
2244 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2245 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2246 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2247 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2248 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2249 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2250 SV_FlushBroadcastMessages();
2253 static void VM_SV_te_flamejet (void)
2255 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2256 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2257 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2259 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2260 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2261 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2263 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2264 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2265 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2267 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2268 SV_FlushBroadcastMessages();
2271 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2272 //this function originally written by KrimZon, made shorter by LordHavoc
2273 static void VM_SV_clientcommand (void)
2275 client_t *temp_client;
2277 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2279 //find client for this entity
2280 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2281 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2283 Con_Print("PF_clientcommand: entity is not a client\n");
2287 temp_client = host_client;
2288 host_client = svs.clients + i;
2289 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2290 host_client = temp_client;
2293 //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)
2294 static void VM_SV_setattachment (void)
2296 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2297 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2298 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2301 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2303 if (e == prog->edicts)
2305 VM_Warning("setattachment: can not modify world entity\n");
2308 if (e->priv.server->free)
2310 VM_Warning("setattachment: can not modify free entity\n");
2314 if (tagentity == NULL)
2315 tagentity = prog->edicts;
2317 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2319 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2321 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2324 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2326 model = SV_GetModelFromEdict(tagentity);
2329 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2331 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);
2334 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));
2338 /////////////////////////////////////////
2339 // DP_MD3_TAGINFO extension coded by VorteX
2341 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2345 i = (int)e->fields.server->modelindex;
2346 if (i < 1 || i >= MAX_MODELS)
2349 return Mod_Alias_GetTagIndexForName(SV_GetModelByIndex(i), (int)e->fields.server->skin, tagname);
2352 int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
2359 Matrix4x4_CreateIdentity(tag_localmatrix);
2361 if (tagindex >= 0 && (model = SV_GetModelFromEdict(e)) && model->num_bones)
2363 r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, e->priv.server->frameblend, &e->priv.server->skeleton, tagindex - 1, parentindex, tagname, tag_localmatrix);
2374 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2378 float pitchsign = 1;
2381 val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
2382 if (val && val->_float != 0)
2383 scale = val->_float;
2386 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);
2389 pitchsign = SV_GetPitchSign(ent);
2390 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);
2394 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2397 if (tagindex >= 0 && (model = SV_GetModelFromEdict(ent)) && model->animscenes)
2399 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2400 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2401 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2402 return Mod_Alias_GetTagMatrix(model, ent->priv.server->frameblend, &ent->priv.server->skeleton, tagindex, out);
2404 *out = identitymatrix;
2408 // Warnings/errors code:
2409 // 0 - normal (everything all-right)
2412 // 3 - null or non-precached model
2413 // 4 - no tags with requested index
2414 // 5 - runaway loop at attachment chain
2415 extern cvar_t cl_bob;
2416 extern cvar_t cl_bobcycle;
2417 extern cvar_t cl_bobup;
2418 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2422 int modelindex, attachloop;
2423 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2426 *out = identitymatrix; // warnings and errors return identical matrix
2428 if (ent == prog->edicts)
2430 if (ent->priv.server->free)
2433 modelindex = (int)ent->fields.server->modelindex;
2434 if (modelindex <= 0 || modelindex >= MAX_MODELS)
2437 model = SV_GetModelByIndex(modelindex);
2439 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2440 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2441 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2443 tagmatrix = identitymatrix;
2444 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2448 if (attachloop >= 256) // prevent runaway looping
2450 // apply transformation by child's tagindex on parent entity and then
2451 // by parent entity itself
2452 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2453 if (ret && attachloop == 0)
2455 SV_GetEntityMatrix(ent, &entitymatrix, false);
2456 Matrix4x4_Concat(&tagmatrix, &attachmatrix, out);
2457 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2458 // next iteration we process the parent entity
2459 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2461 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2462 ent = PRVM_EDICT_NUM(val->edict);
2469 // RENDER_VIEWMODEL magic
2470 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2472 Matrix4x4_Copy(&tagmatrix, out);
2473 ent = PRVM_EDICT_NUM(val->edict);
2475 SV_GetEntityMatrix(ent, &entitymatrix, true);
2476 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2479 // Cl_bob, ported from rendering code
2480 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2483 // LordHavoc: this code is *weird*, but not replacable (I think it
2484 // should be done in QC on the server, but oh well, quake is quake)
2485 // LordHavoc: figured out bobup: the time at which the sin is at 180
2486 // degrees (which allows lengthening or squishing the peak or valley)
2487 cycle = sv.time/cl_bobcycle.value;
2488 cycle -= (int)cycle;
2489 if (cycle < cl_bobup.value)
2490 cycle = sin(M_PI * cycle / cl_bobup.value);
2492 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2493 // bob is proportional to velocity in the xy plane
2494 // (don't count Z, or jumping messes it up)
2495 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;
2496 bob = bob*0.3 + bob*0.7*cycle;
2497 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2504 //float(entity ent, string tagname) gettagindex;
2506 static void VM_SV_gettagindex (void)
2509 const char *tag_name;
2512 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2514 ent = PRVM_G_EDICT(OFS_PARM0);
2515 tag_name = PRVM_G_STRING(OFS_PARM1);
2517 if (ent == prog->edicts)
2519 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
2522 if (ent->priv.server->free)
2524 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
2529 if (!SV_GetModelFromEdict(ent))
2530 Con_DPrintf("VM_SV_gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2533 tag_index = SV_GetTagIndex(ent, tag_name);
2535 if(developer_extra.integer)
2536 Con_DPrintf("VM_SV_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2538 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2541 //vector(entity ent, float tagindex) gettaginfo;
2542 static void VM_SV_gettaginfo (void)
2546 matrix4x4_t tag_matrix;
2547 matrix4x4_t tag_localmatrix;
2549 const char *tagname;
2552 vec3_t fo, le, up, trans;
2553 const dp_model_t *model;
2555 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2557 e = PRVM_G_EDICT(OFS_PARM0);
2558 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2560 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2561 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, le, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2562 VectorScale(le, -1, prog->globals.server->v_right);
2563 model = SV_GetModelFromEdict(e);
2564 VM_GenerateFrameGroupBlend(e->priv.server->framegroupblend, e);
2565 VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model);
2566 VM_UpdateEdictSkeleton(e, model, e->priv.server->frameblend);
2567 SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
2568 Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
2570 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
2571 val->_float = parentindex;
2572 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
2573 val->string = tagname ? PRVM_SetTempString(tagname) : 0;
2574 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
2575 VectorCopy(trans, val->vector);
2576 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
2577 VectorCopy(fo, val->vector);
2578 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
2579 VectorScale(le, -1, val->vector);
2580 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
2581 VectorCopy(up, val->vector);
2586 VM_Warning("gettagindex: can't affect world entity\n");
2589 VM_Warning("gettagindex: can't affect free entity\n");
2592 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2595 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2598 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2603 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2604 static void VM_SV_dropclient (void)
2607 client_t *oldhostclient;
2608 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2609 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2610 if (clientnum < 0 || clientnum >= svs.maxclients)
2612 VM_Warning("dropclient: not a client\n");
2615 if (!svs.clients[clientnum].active)
2617 VM_Warning("dropclient: that client slot is not connected\n");
2620 oldhostclient = host_client;
2621 host_client = svs.clients + clientnum;
2622 SV_DropClient(false);
2623 host_client = oldhostclient;
2626 //entity() spawnclient (DP_SV_BOTCLIENT)
2627 static void VM_SV_spawnclient (void)
2631 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2632 prog->xfunction->builtinsprofile += 2;
2634 for (i = 0;i < svs.maxclients;i++)
2636 if (!svs.clients[i].active)
2638 prog->xfunction->builtinsprofile += 100;
2639 SV_ConnectClient (i, NULL);
2640 // this has to be set or else ClientDisconnect won't be called
2641 // we assume the qc will call ClientConnect...
2642 svs.clients[i].clientconnectcalled = true;
2643 ed = PRVM_EDICT_NUM(i + 1);
2647 VM_RETURN_EDICT(ed);
2650 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2651 static void VM_SV_clienttype (void)
2654 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2655 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2656 if (clientnum < 0 || clientnum >= svs.maxclients)
2657 PRVM_G_FLOAT(OFS_RETURN) = 3;
2658 else if (!svs.clients[clientnum].active)
2659 PRVM_G_FLOAT(OFS_RETURN) = 0;
2660 else if (svs.clients[clientnum].netconnection)
2661 PRVM_G_FLOAT(OFS_RETURN) = 1;
2663 PRVM_G_FLOAT(OFS_RETURN) = 2;
2670 string(string key) serverkey
2673 void VM_SV_serverkey(void)
2675 char string[VM_STRINGTEMP_LENGTH];
2676 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2677 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2678 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2681 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2682 static void VM_SV_setmodelindex (void)
2687 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2689 e = PRVM_G_EDICT(OFS_PARM0);
2690 if (e == prog->edicts)
2692 VM_Warning("setmodelindex: can not modify world entity\n");
2695 if (e->priv.server->free)
2697 VM_Warning("setmodelindex: can not modify free entity\n");
2700 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2701 if (i <= 0 || i >= MAX_MODELS)
2703 VM_Warning("setmodelindex: invalid modelindex\n");
2706 if (!sv.model_precache[i][0])
2708 VM_Warning("setmodelindex: model not precached\n");
2712 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2713 e->fields.server->modelindex = i;
2715 mod = SV_GetModelByIndex(i);
2719 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2720 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2722 SetMinMaxSize (e, quakemins, quakemaxs, true);
2725 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2728 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2729 static void VM_SV_modelnameforindex (void)
2732 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2734 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2736 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2737 if (i <= 0 || i >= MAX_MODELS)
2739 VM_Warning("modelnameforindex: invalid modelindex\n");
2742 if (!sv.model_precache[i][0])
2744 VM_Warning("modelnameforindex: model not precached\n");
2748 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2751 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2752 static void VM_SV_particleeffectnum (void)
2755 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2756 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2759 PRVM_G_FLOAT(OFS_RETURN) = i;
2762 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2763 static void VM_SV_trailparticles (void)
2765 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2767 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2770 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2771 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2772 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2773 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2774 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2775 SV_FlushBroadcastMessages();
2778 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2779 static void VM_SV_pointparticles (void)
2781 int effectnum, count;
2783 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2785 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2788 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2789 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2790 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2791 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2792 if (count == 1 && !VectorLength2(vel))
2795 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2796 MSG_WriteShort(&sv.datagram, effectnum);
2797 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2801 // 1+2+12+12+2=29 bytes
2802 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2803 MSG_WriteShort(&sv.datagram, effectnum);
2804 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2805 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2806 MSG_WriteShort(&sv.datagram, count);
2809 SV_FlushBroadcastMessages();
2812 //PF_setpause, // void(float pause) setpause = #531;
2813 static void VM_SV_setpause(void) {
2815 pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
2816 if (pauseValue != 0) { //pause the game
2818 sv.pausedstart = Sys_DoubleTime();
2819 } else { //disable pause, in case it was enabled
2820 if (sv.paused != 0) {
2825 // send notification to all clients
2826 MSG_WriteByte(&sv.reliable_datagram, svc_setpause);
2827 MSG_WriteByte(&sv.reliable_datagram, sv.paused);
2830 // #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.
2831 static void VM_SV_skel_create(void)
2833 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
2834 dp_model_t *model = SV_GetModelByIndex(modelindex);
2835 skeleton_t *skeleton;
2837 PRVM_G_FLOAT(OFS_RETURN) = 0;
2838 if (!model || !model->num_bones)
2840 for (i = 0;i < MAX_EDICTS;i++)
2841 if (!prog->skeletons[i])
2843 if (i == MAX_EDICTS)
2845 prog->skeletons[i] = skeleton = (skeleton_t *)Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
2846 PRVM_G_FLOAT(OFS_RETURN) = i + 1;
2847 skeleton->model = model;
2848 skeleton->relativetransforms = (matrix4x4_t *)(skeleton+1);
2849 // initialize to identity matrices
2850 for (i = 0;i < skeleton->model->num_bones;i++)
2851 skeleton->relativetransforms[i] = identitymatrix;
2854 // #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
2855 static void VM_SV_skel_build(void)
2857 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2858 skeleton_t *skeleton;
2859 prvm_edict_t *ed = PRVM_G_EDICT(OFS_PARM1);
2860 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM2);
2861 float retainfrac = PRVM_G_FLOAT(OFS_PARM3);
2862 int firstbone = PRVM_G_FLOAT(OFS_PARM4) - 1;
2863 int lastbone = PRVM_G_FLOAT(OFS_PARM5) - 1;
2864 dp_model_t *model = SV_GetModelByIndex(modelindex);
2869 framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS];
2870 frameblend_t frameblend[MAX_FRAMEBLENDS];
2871 matrix4x4_t blendedmatrix;
2873 PRVM_G_FLOAT(OFS_RETURN) = 0;
2874 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2876 firstbone = max(0, firstbone);
2877 lastbone = min(lastbone, model->num_bones - 1);
2878 lastbone = min(lastbone, skeleton->model->num_bones - 1);
2879 VM_GenerateFrameGroupBlend(framegroupblend, ed);
2880 VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model);
2881 blendfrac = 1.0f - retainfrac;
2882 for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
2883 frameblend[numblends].lerp *= blendfrac;
2884 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
2886 memset(&blendedmatrix, 0, sizeof(blendedmatrix));
2887 Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac);
2888 for (blendindex = 0;blendindex < numblends;blendindex++)
2890 Matrix4x4_FromBonePose6s(&matrix, model->num_posescale, model->data_poses6s + 6 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
2891 Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp);
2893 skeleton->relativetransforms[bonenum] = blendedmatrix;
2895 PRVM_G_FLOAT(OFS_RETURN) = skeletonindex + 1;
2898 // #265 float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS) returns how many bones exist in the created skeleton
2899 static void VM_SV_skel_get_numbones(void)
2901 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2902 skeleton_t *skeleton;
2903 PRVM_G_FLOAT(OFS_RETURN) = 0;
2904 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2906 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->num_bones;
2909 // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) returns name of bone (as a tempstring)
2910 static void VM_SV_skel_get_bonename(void)
2912 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2913 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2914 skeleton_t *skeleton;
2915 PRVM_G_INT(OFS_RETURN) = 0;
2916 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2918 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2920 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(skeleton->model->data_bones[bonenum].name);
2923 // #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)
2924 static void VM_SV_skel_get_boneparent(void)
2926 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2927 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2928 skeleton_t *skeleton;
2929 PRVM_G_FLOAT(OFS_RETURN) = 0;
2930 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2932 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2934 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->data_bones[bonenum].parent + 1;
2937 // #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
2938 static void VM_SV_skel_find_bone(void)
2940 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2941 const char *tagname = PRVM_G_STRING(OFS_PARM1);
2942 skeleton_t *skeleton;
2943 PRVM_G_FLOAT(OFS_RETURN) = 0;
2944 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2946 PRVM_G_FLOAT(OFS_RETURN) = Mod_Alias_GetTagIndexForName(skeleton->model, 0, tagname) + 1;
2949 // #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)
2950 static void VM_SV_skel_get_bonerel(void)
2952 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2953 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2954 skeleton_t *skeleton;
2956 vec3_t forward, left, up, origin;
2957 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2958 VectorClear(prog->globals.client->v_forward);
2959 VectorClear(prog->globals.client->v_right);
2960 VectorClear(prog->globals.client->v_up);
2961 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2963 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2965 matrix = skeleton->relativetransforms[bonenum];
2966 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2967 VectorCopy(forward, prog->globals.client->v_forward);
2968 VectorNegate(left, prog->globals.client->v_right);
2969 VectorCopy(up, prog->globals.client->v_up);
2970 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
2973 // #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)
2974 static void VM_SV_skel_get_boneabs(void)
2976 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2977 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2978 skeleton_t *skeleton;
2981 vec3_t forward, left, up, origin;
2982 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2983 VectorClear(prog->globals.client->v_forward);
2984 VectorClear(prog->globals.client->v_right);
2985 VectorClear(prog->globals.client->v_up);
2986 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2988 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2990 matrix = skeleton->relativetransforms[bonenum];
2991 // convert to absolute
2992 while ((bonenum = skeleton->model->data_bones[bonenum].parent) >= 0)
2995 Matrix4x4_Concat(&matrix, &skeleton->relativetransforms[bonenum], &temp);
2997 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2998 VectorCopy(forward, prog->globals.client->v_forward);
2999 VectorNegate(left, prog->globals.client->v_right);
3000 VectorCopy(up, prog->globals.client->v_up);
3001 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
3004 // #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)
3005 static void VM_SV_skel_set_bone(void)
3007 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3008 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3009 vec3_t forward, left, up, origin;
3010 skeleton_t *skeleton;
3012 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3014 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3016 VectorCopy(prog->globals.client->v_forward, forward);
3017 VectorNegate(prog->globals.client->v_right, left);
3018 VectorCopy(prog->globals.client->v_up, up);
3019 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3020 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3021 skeleton->relativetransforms[bonenum] = matrix;
3024 // #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)
3025 static void VM_SV_skel_mul_bone(void)
3027 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3028 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3029 vec3_t forward, left, up, origin;
3030 skeleton_t *skeleton;
3033 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3035 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3037 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3038 VectorCopy(prog->globals.client->v_forward, forward);
3039 VectorNegate(prog->globals.client->v_right, left);
3040 VectorCopy(prog->globals.client->v_up, up);
3041 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3042 temp = skeleton->relativetransforms[bonenum];
3043 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3046 // #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)
3047 static void VM_SV_skel_mul_bones(void)
3049 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3050 int firstbone = PRVM_G_FLOAT(OFS_PARM1) - 1;
3051 int lastbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3053 vec3_t forward, left, up, origin;
3054 skeleton_t *skeleton;
3057 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3059 VectorCopy(PRVM_G_VECTOR(OFS_PARM3), origin);
3060 VectorCopy(prog->globals.client->v_forward, forward);
3061 VectorNegate(prog->globals.client->v_right, left);
3062 VectorCopy(prog->globals.client->v_up, up);
3063 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3064 firstbone = max(0, firstbone);
3065 lastbone = min(lastbone, skeleton->model->num_bones - 1);
3066 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3068 temp = skeleton->relativetransforms[bonenum];
3069 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3073 // #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
3074 static void VM_SV_skel_copybones(void)
3076 int skeletonindexdst = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3077 int skeletonindexsrc = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3078 int firstbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3079 int lastbone = PRVM_G_FLOAT(OFS_PARM3) - 1;
3081 skeleton_t *skeletondst;
3082 skeleton_t *skeletonsrc;
3083 if (skeletonindexdst < 0 || skeletonindexdst >= MAX_EDICTS || !(skeletondst = prog->skeletons[skeletonindexdst]))
3085 if (skeletonindexsrc < 0 || skeletonindexsrc >= MAX_EDICTS || !(skeletonsrc = prog->skeletons[skeletonindexsrc]))
3087 firstbone = max(0, firstbone);
3088 lastbone = min(lastbone, skeletondst->model->num_bones - 1);
3089 lastbone = min(lastbone, skeletonsrc->model->num_bones - 1);
3090 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3091 skeletondst->relativetransforms[bonenum] = skeletonsrc->relativetransforms[bonenum];
3094 // #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)
3095 static void VM_SV_skel_delete(void)
3097 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3098 skeleton_t *skeleton;
3099 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3102 prog->skeletons[skeletonindex] = NULL;
3105 // #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
3106 static void VM_SV_frameforname(void)
3108 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3109 dp_model_t *model = SV_GetModelByIndex(modelindex);
3110 const char *name = PRVM_G_STRING(OFS_PARM1);
3112 PRVM_G_FLOAT(OFS_RETURN) = -1;
3113 if (!model || !model->animscenes)
3115 for (i = 0;i < model->numframes;i++)
3117 if (!strcasecmp(model->animscenes[i].name, name))
3119 PRVM_G_FLOAT(OFS_RETURN) = i;
3125 // #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.
3126 static void VM_SV_frameduration(void)
3128 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3129 dp_model_t *model = SV_GetModelByIndex(modelindex);
3130 int framenum = (int)PRVM_G_FLOAT(OFS_PARM1);
3131 PRVM_G_FLOAT(OFS_RETURN) = 0;
3132 if (!model || !model->animscenes || framenum < 0 || framenum >= model->numframes)
3134 if (model->animscenes[framenum].framerate)
3135 PRVM_G_FLOAT(OFS_RETURN) = model->animscenes[framenum].framecount / model->animscenes[framenum].framerate;
3139 prvm_builtin_t vm_sv_builtins[] = {
3140 NULL, // #0 NULL function (not callable) (QUAKE)
3141 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
3142 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
3143 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
3144 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
3145 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
3146 VM_break, // #6 void() break (QUAKE)
3147 VM_random, // #7 float() random (QUAKE)
3148 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
3149 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
3150 VM_error, // #10 void(string e) error (QUAKE)
3151 VM_objerror, // #11 void(string e) objerror (QUAKE)
3152 VM_vlen, // #12 float(vector v) vlen (QUAKE)
3153 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
3154 VM_spawn, // #14 entity() spawn (QUAKE)
3155 VM_remove, // #15 void(entity e) remove (QUAKE)
3156 VM_SV_traceline, // #16 void(vector v1, vector v2, float tryents) traceline (QUAKE)
3157 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
3158 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
3159 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
3160 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
3161 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
3162 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
3163 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
3164 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
3165 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
3166 VM_ftos, // #26 string(float f) ftos (QUAKE)
3167 VM_vtos, // #27 string(vector v) vtos (QUAKE)
3168 VM_coredump, // #28 void() coredump (QUAKE)
3169 VM_traceon, // #29 void() traceon (QUAKE)
3170 VM_traceoff, // #30 void() traceoff (QUAKE)
3171 VM_eprint, // #31 void(entity e) eprint (QUAKE)
3172 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
3173 NULL, // #33 (QUAKE)
3174 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
3175 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
3176 VM_rint, // #36 float(float v) rint (QUAKE)
3177 VM_floor, // #37 float(float v) floor (QUAKE)
3178 VM_ceil, // #38 float(float v) ceil (QUAKE)
3179 NULL, // #39 (QUAKE)
3180 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
3181 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
3182 NULL, // #42 (QUAKE)
3183 VM_fabs, // #43 float(float f) fabs (QUAKE)
3184 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
3185 VM_cvar, // #45 float(string s) cvar (QUAKE)
3186 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
3187 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
3188 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
3189 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
3190 NULL, // #50 (QUAKE)
3191 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
3192 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
3193 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
3194 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
3195 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
3196 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
3197 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
3198 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
3199 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
3200 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
3201 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
3202 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
3203 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
3204 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
3205 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
3206 NULL, // #66 (QUAKE)
3207 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
3208 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
3209 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
3210 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
3211 NULL, // #71 (QUAKE)
3212 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
3213 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
3214 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
3215 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
3216 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
3217 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
3218 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
3219 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
3220 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
3221 VM_stof, // #81 float(string s) stof (FRIK_FILE)
3222 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
3223 NULL, // #83 (QUAKE)
3224 NULL, // #84 (QUAKE)
3225 NULL, // #85 (QUAKE)
3226 NULL, // #86 (QUAKE)
3227 NULL, // #87 (QUAKE)
3228 NULL, // #88 (QUAKE)
3229 NULL, // #89 (QUAKE)
3230 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
3231 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
3232 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
3233 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
3234 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
3235 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3236 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3237 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3238 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3239 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3240 // FrikaC and Telejano range #100-#199
3251 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3252 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3253 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3254 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3255 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3256 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3257 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3258 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3259 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3260 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3341 // FTEQW range #200-#299
3360 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3363 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3364 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3365 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3366 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3367 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3368 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3369 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3370 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3371 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3372 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3374 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3382 VM_SV_checkpvs, // #240 float(vector viewpos, entity viewee) checkpvs;
3405 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.
3406 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
3407 VM_SV_skel_get_numbones, // #265 float(float skel) skel_get_numbones = #265; // (DP_SKELETONOBJECTS) returns how many bones exist in the created skeleton
3408 VM_SV_skel_get_bonename, // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (DP_SKELETONOBJECTS) returns name of bone (as a tempstring)
3409 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)
3410 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
3411 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)
3412 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)
3413 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)
3414 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)
3415 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)
3416 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
3417 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)
3418 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
3419 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.
3442 // CSQC range #300-#399
3443 NULL, // #300 void() clearscene (EXT_CSQC)
3444 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3445 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3446 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3447 NULL, // #304 void() renderscene (EXT_CSQC)
3448 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3449 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3450 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3451 NULL, // #308 void() R_EndPolygon
3453 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3454 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3458 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3459 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3460 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3461 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3462 NULL, // #319 void(string name) freepic (EXT_CSQC)
3463 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3464 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3465 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3466 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3467 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3468 NULL, // #325 void(void) drawresetcliparea
3473 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3474 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3475 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3476 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3477 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3478 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3479 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3480 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3481 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3482 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3483 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3484 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3485 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3486 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3487 NULL, // #344 vector() getmousepos (EXT_CSQC)
3488 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3489 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3490 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3491 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3492 NULL, // #349 float() isdemo (EXT_CSQC)
3493 VM_isserver, // #350 float() isserver (EXT_CSQC)
3494 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3495 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3496 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3497 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3503 NULL, // #360 float() readbyte (EXT_CSQC)
3504 NULL, // #361 float() readchar (EXT_CSQC)
3505 NULL, // #362 float() readshort (EXT_CSQC)
3506 NULL, // #363 float() readlong (EXT_CSQC)
3507 NULL, // #364 float() readcoord (EXT_CSQC)
3508 NULL, // #365 float() readangle (EXT_CSQC)
3509 NULL, // #366 string() readstring (EXT_CSQC)
3510 NULL, // #367 float() readfloat (EXT_CSQC)
3543 // LordHavoc's range #400-#499
3544 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3545 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3546 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3547 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3548 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3549 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3550 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3551 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3552 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)
3553 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3554 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3555 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3556 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3557 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3558 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3559 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3560 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3561 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3562 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3563 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3564 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3565 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3566 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3567 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3568 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3569 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3570 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3571 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3572 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3573 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3574 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3575 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3576 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3577 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3578 VM_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3579 VM_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3580 VM_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3581 VM_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3582 VM_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3583 VM_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3584 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3585 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3586 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3587 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3588 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3589 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3590 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3591 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3592 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3593 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3594 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3595 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3596 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3597 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3598 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3599 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3600 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3601 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3603 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3604 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3605 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3606 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3607 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3608 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3609 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3610 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3611 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3612 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3613 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3615 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3616 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3617 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3618 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3619 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3620 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3621 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3622 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3623 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3624 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3625 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3626 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3627 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3628 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3629 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3630 VM_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3638 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3639 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3640 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3641 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3642 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3643 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3644 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3645 VM_SV_WritePicture, // #501
3647 VM_whichpack, // #503 string(string) whichpack = #503;
3654 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3655 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3656 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3657 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)
3658 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3659 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3660 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3661 VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
3662 VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
3663 VM_gettime, // #519 float(float timer) gettime = #519; (DP_QC_GETTIME)
3673 VM_loadfromdata, // #529
3674 VM_loadfromfile, // #530
3675 VM_SV_setpause, // #531 void(float pause) setpause = #531;
3677 VM_getsoundtime, // #533 float(entity e, float channel) getsoundtime = #533; (DP_SND_GETSOUNDTIME)
3678 VM_soundlength, // #534 float(string sample) soundlength = #534; (DP_SND_GETSOUNDTIME)
3684 VM_physics_enable, // #540 void(entity e, float physics_enabled) physics_enable = #540; (DP_PHYSICS_ODE)
3685 VM_physics_addforce, // #541 void(entity e, vector force, vector relative_ofs) physics_addforce = #541; (DP_PHYSICS_ODE)
3686 VM_physics_addtorque, // #542 void(entity e, vector torque) physics_addtorque = #542; (DP_PHYSICS_ODE)
3749 VM_callfunction, // #605
3750 VM_writetofile, // #606
3751 VM_isfunction, // #607
3757 VM_parseentitydata, // #613
3768 VM_SV_getextresponse, // #624 string getextresponse(void)
3771 VM_sprintf, // #627 string sprintf(string format, ...)
3772 VM_getsurfacenumtriangles, // #628 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACETRIANGLE)
3773 VM_getsurfacetriangle, // #629 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACETRIANGLE)
3777 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3779 void VM_SV_Cmd_Init(void)
3784 void VM_SV_Cmd_Reset(void)
3786 World_End(&sv.world);
3787 if(prog->funcoffsets.SV_Shutdown)
3789 func_t s = prog->funcoffsets.SV_Shutdown;
3790 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3791 PRVM_ExecuteProgram(s,"SV_Shutdown() required");