6 //============================================================================
11 char *vm_sv_extensions =
16 "DP_CON_ALIASPARAMETERS "
22 "DP_CSQC_ENTITYNOCULL "
23 "DP_CSQC_ENTITYTRANSPARENTSORTING_OFFSET "
24 "DP_CSQC_MULTIFRAME_INTERPOLATION "
25 "DP_CSQC_BOXPARTICLES "
26 "DP_CSQC_SPAWNPARTICLE "
27 "DP_CSQC_QUERYRENDERENTITY "
40 "DP_EF_RESTARTANIM_BIT "
45 "DP_ENT_CUSTOMCOLORMAP "
46 "DP_ENT_EXTERIORMODELTOCLIENT "
49 "DP_ENT_LOWPRECISION "
53 "DP_GFX_EXTERNALTEXTURES "
54 "DP_GFX_EXTERNALTEXTURES_PERMAP "
56 "DP_GFX_MODEL_INTERPOLATION "
57 "DP_GFX_QUAKE3MODELTAGS "
61 "DP_GFX_FONTS_FREETYPE "
63 "DP_FONT_VARIABLEWIDTH "
65 "DP_HALFLIFE_MAP_CVAR "
68 "DP_LIGHTSTYLE_STATICVALUE "
72 "DP_MOVETYPEBOUNCEMISSILE "
75 "DP_QC_ASINACOSATANATAN2TAN "
81 "DP_QC_CVAR_DEFSTRING "
82 "DP_QC_CVAR_DESCRIPTION "
89 "DP_QC_EXTRESPONSEPACKET "
91 "DP_QC_FINDCHAINFLAGS "
92 "DP_QC_FINDCHAINFLOAT "
93 "DP_QC_FINDCHAIN_TOFIELD "
99 "DP_QC_GETSURFACETRIANGLE "
100 "DP_QC_GETSURFACEPOINTATTRIBUTE "
102 "DP_QC_GETTAGINFO_BONEPROPERTIES "
104 "DP_QC_GETTIME_CDTRACK "
107 "DP_QC_MULTIPLETEMPSTRINGS "
108 "DP_QC_NUM_FOR_EDICT "
110 "DP_QC_SINCOSSQRTPOW "
113 "DP_QC_STRINGBUFFERS "
114 "DP_QC_STRINGBUFFERS_CVARLIST "
115 "DP_QC_STRINGCOLORFUNCTIONS "
116 "DP_QC_STRING_CASE_FUNCTIONS "
118 "DP_QC_TOKENIZEBYSEPARATOR "
119 "DP_QC_TOKENIZE_CONSOLE "
122 "DP_QC_TRACE_MOVETYPE_HITMODEL "
123 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
124 "DP_QC_UNLIMITEDTEMPSTRINGS "
127 "DP_QC_VECTOANGLES_WITH_ROLL "
128 "DP_QC_VECTORVECTORS "
135 "DP_SKELETONOBJECTS "
136 "DP_SND_DIRECTIONLESSATTNNONE "
141 "DP_SND_GETSOUNDTIME "
143 "DP_VIDEO_SUBTITLES "
147 "DP_SV_BOUNCEFACTOR "
148 "DP_SV_CLIENTCAMERA "
149 "DP_SV_CLIENTCOLORS "
152 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
153 "DP_SV_DISCARDABLEDEMO "
154 "DP_SV_DRAWONLYTOCLIENT "
157 "DP_SV_ENTITYCONTENTSTRANSITION "
158 "DP_SV_MODELFLAGS_AS_EFFECTS "
159 "DP_SV_MOVETYPESTEP_LANDEVENT "
161 "DP_SV_NODRAWTOCLIENT "
162 "DP_SV_ONENTITYNOSPAWNFUNCTION "
163 "DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
165 "DP_SV_PING_PACKETLOSS "
166 "DP_SV_PLAYERPHYSICS "
167 "DP_SV_POINTPARTICLES "
169 "DP_SV_PRECACHEANYTIME "
173 "DP_SV_ROTATINGBMODEL "
177 "DP_SV_SPAWNFUNC_PREFIX "
178 "DP_SV_WRITEPICTURE "
179 "DP_SV_WRITEUNTERMINATEDSTRING "
183 "DP_TE_EXPLOSIONRGB "
185 "DP_TE_PARTICLECUBE "
186 "DP_TE_PARTICLERAIN "
187 "DP_TE_PARTICLESNOW "
189 "DP_TE_QUADEFFECTS1 "
192 "DP_TE_STANDARDEFFECTBUILTINS "
193 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
197 "FTE_CSQC_SKELETONOBJECTS "
200 "KRIMZON_SV_PARSECLIENTCOMMAND "
203 "NEXUIZ_PLAYERMODEL "
205 "PRYDON_CLIENTCURSOR "
206 "TENEBRAE_GFX_DLIGHTS "
209 //"EXT_CSQC " // not ready yet
216 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.
218 setorigin (entity, origin)
221 static void VM_SV_setorigin (void)
226 VM_SAFEPARMCOUNT(2, VM_setorigin);
228 e = PRVM_G_EDICT(OFS_PARM0);
229 if (e == prog->edicts)
231 VM_Warning("setorigin: can not modify world entity\n");
234 if (e->priv.server->free)
236 VM_Warning("setorigin: can not modify free entity\n");
239 org = PRVM_G_VECTOR(OFS_PARM1);
240 VectorCopy (org, e->fields.server->origin);
244 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
245 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
249 for (i=0 ; i<3 ; i++)
251 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
253 // set derived values
254 VectorCopy (min, e->fields.server->mins);
255 VectorCopy (max, e->fields.server->maxs);
256 VectorSubtract (max, min, e->fields.server->size);
265 the size box is rotated by the current angle
266 LordHavoc: no it isn't...
268 setsize (entity, minvector, maxvector)
271 static void VM_SV_setsize (void)
276 VM_SAFEPARMCOUNT(3, VM_setsize);
278 e = PRVM_G_EDICT(OFS_PARM0);
279 if (e == prog->edicts)
281 VM_Warning("setsize: can not modify world entity\n");
284 if (e->priv.server->free)
286 VM_Warning("setsize: can not modify free entity\n");
289 min = PRVM_G_VECTOR(OFS_PARM1);
290 max = PRVM_G_VECTOR(OFS_PARM2);
291 SetMinMaxSize (e, min, max, false);
299 setmodel(entity, model)
302 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
303 static void VM_SV_setmodel (void)
309 VM_SAFEPARMCOUNT(2, VM_setmodel);
311 e = PRVM_G_EDICT(OFS_PARM0);
312 if (e == prog->edicts)
314 VM_Warning("setmodel: can not modify world entity\n");
317 if (e->priv.server->free)
319 VM_Warning("setmodel: can not modify free entity\n");
322 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
323 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
324 e->fields.server->modelindex = i;
326 mod = SV_GetModelByIndex(i);
330 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
331 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
333 SetMinMaxSize (e, quakemins, quakemaxs, true);
336 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
343 single print to a specific client
345 sprint(clientent, value)
348 static void VM_SV_sprint (void)
352 char string[VM_STRINGTEMP_LENGTH];
354 VM_VarString(1, string, sizeof(string));
356 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
358 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
359 // LordHavoc: div0 requested that sprintto world operate like print
366 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
368 VM_Warning("tried to centerprint to a non-client\n");
372 client = svs.clients + entnum-1;
373 if (!client->netconnection)
376 MSG_WriteChar(&client->netconnection->message,svc_print);
377 MSG_WriteString(&client->netconnection->message, string);
385 single print to a specific client
387 centerprint(clientent, value)
390 static void VM_SV_centerprint (void)
394 char string[VM_STRINGTEMP_LENGTH];
396 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
398 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
400 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
402 VM_Warning("tried to centerprint to a non-client\n");
406 client = svs.clients + entnum-1;
407 if (!client->netconnection)
410 VM_VarString(1, string, sizeof(string));
411 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
412 MSG_WriteString(&client->netconnection->message, string);
419 particle(origin, color, count)
422 static void VM_SV_particle (void)
428 VM_SAFEPARMCOUNT(4, VM_SV_particle);
430 org = PRVM_G_VECTOR(OFS_PARM0);
431 dir = PRVM_G_VECTOR(OFS_PARM1);
432 color = PRVM_G_FLOAT(OFS_PARM2);
433 count = PRVM_G_FLOAT(OFS_PARM3);
434 SV_StartParticle (org, dir, (int)color, (int)count);
444 static void VM_SV_ambientsound (void)
448 float vol, attenuation;
451 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
453 pos = PRVM_G_VECTOR (OFS_PARM0);
454 samp = PRVM_G_STRING(OFS_PARM1);
455 vol = PRVM_G_FLOAT(OFS_PARM2);
456 attenuation = PRVM_G_FLOAT(OFS_PARM3);
458 // check to see if samp was properly precached
459 soundnum = SV_SoundIndex(samp, 1);
467 // add an svc_spawnambient command to the level signon packet
470 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
472 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
474 MSG_WriteVector(&sv.signon, pos, sv.protocol);
476 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
477 MSG_WriteShort (&sv.signon, soundnum);
479 MSG_WriteByte (&sv.signon, soundnum);
481 MSG_WriteByte (&sv.signon, (int)(vol*255));
482 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
490 Each entity can have eight independant sound sources, like voice,
493 Channel 0 is an auto-allocate channel, the others override anything
494 already running on that entity/channel pair.
496 An attenuation of 0 will play full volume everywhere in the level.
497 Larger attenuations will drop off.
501 static void VM_SV_sound (void)
505 prvm_edict_t *entity;
509 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
511 entity = PRVM_G_EDICT(OFS_PARM0);
512 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
513 sample = PRVM_G_STRING(OFS_PARM2);
514 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
515 attenuation = PRVM_G_FLOAT(OFS_PARM4);
518 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
522 if (volume < 0 || volume > 255)
524 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
528 if (attenuation < 0 || attenuation > 4)
530 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
534 if (channel < 0 || channel > 7)
536 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
540 SV_StartSound (entity, channel, sample, volume, attenuation);
547 Follows the same logic as VM_SV_sound, except instead of
548 an entity, an origin for the sound is provided, and channel
549 is omitted (since no entity is being tracked).
553 static void VM_SV_pointsound(void)
560 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
562 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
563 sample = PRVM_G_STRING(OFS_PARM1);
564 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
565 attenuation = PRVM_G_FLOAT(OFS_PARM3);
567 if (volume < 0 || volume > 255)
569 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
573 if (attenuation < 0 || attenuation > 4)
575 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
579 SV_StartPointSound (org, sample, volume, attenuation);
586 Used for use tracing and shot targeting
587 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
588 if the tryents flag is set.
590 traceline (vector1, vector2, movetype, ignore)
593 static void VM_SV_traceline (void)
600 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
602 prog->xfunction->builtinsprofile += 30;
604 v1 = PRVM_G_VECTOR(OFS_PARM0);
605 v2 = PRVM_G_VECTOR(OFS_PARM1);
606 move = (int)PRVM_G_FLOAT(OFS_PARM2);
607 ent = PRVM_G_EDICT(OFS_PARM3);
609 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]))
610 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));
612 trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
614 VM_SetTraceGlobals(&trace);
622 Used for use tracing and shot targeting
623 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
624 if the tryents flag is set.
626 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
629 // LordHavoc: added this for my own use, VERY useful, similar to traceline
630 static void VM_SV_tracebox (void)
632 float *v1, *v2, *m1, *m2;
637 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
639 prog->xfunction->builtinsprofile += 30;
641 v1 = PRVM_G_VECTOR(OFS_PARM0);
642 m1 = PRVM_G_VECTOR(OFS_PARM1);
643 m2 = PRVM_G_VECTOR(OFS_PARM2);
644 v2 = PRVM_G_VECTOR(OFS_PARM3);
645 move = (int)PRVM_G_FLOAT(OFS_PARM4);
646 ent = PRVM_G_EDICT(OFS_PARM5);
648 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]))
649 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));
651 trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
653 VM_SetTraceGlobals(&trace);
656 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
661 vec3_t original_origin;
662 vec3_t original_velocity;
663 vec3_t original_angles;
664 vec3_t original_avelocity;
668 VectorCopy(tossent->fields.server->origin , original_origin );
669 VectorCopy(tossent->fields.server->velocity , original_velocity );
670 VectorCopy(tossent->fields.server->angles , original_angles );
671 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
673 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
674 if (val != NULL && val->_float != 0)
675 gravity = val->_float;
678 gravity *= sv_gravity.value * 0.025;
680 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
682 SV_CheckVelocity (tossent);
683 tossent->fields.server->velocity[2] -= gravity;
684 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
685 VectorScale (tossent->fields.server->velocity, 0.05, move);
686 VectorAdd (tossent->fields.server->origin, move, end);
687 trace = SV_TraceBox(tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
688 VectorCopy (trace.endpos, tossent->fields.server->origin);
689 tossent->fields.server->velocity[2] -= gravity;
691 if (trace.fraction < 1)
695 VectorCopy(original_origin , tossent->fields.server->origin );
696 VectorCopy(original_velocity , tossent->fields.server->velocity );
697 VectorCopy(original_angles , tossent->fields.server->angles );
698 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
703 static void VM_SV_tracetoss (void)
707 prvm_edict_t *ignore;
709 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
711 prog->xfunction->builtinsprofile += 600;
713 ent = PRVM_G_EDICT(OFS_PARM0);
714 if (ent == prog->edicts)
716 VM_Warning("tracetoss: can not use world entity\n");
719 ignore = PRVM_G_EDICT(OFS_PARM1);
721 trace = SV_Trace_Toss (ent, ignore);
723 VM_SetTraceGlobals(&trace);
726 //============================================================================
728 static int checkpvsbytes;
729 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
731 static int VM_SV_newcheckclient (int check)
737 // cycle to the next one
739 check = bound(1, check, svs.maxclients);
740 if (check == svs.maxclients)
748 prog->xfunction->builtinsprofile++;
750 if (i == svs.maxclients+1)
752 // look up the client's edict
753 ent = PRVM_EDICT_NUM(i);
754 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
755 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
757 // found a valid client (possibly the same one again)
761 // get the PVS for the entity
762 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
764 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
765 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
774 Returns a client (or object that has a client enemy) that would be a
777 If there is more than one valid option, they are cycled each frame
779 If (self.origin + self.viewofs) is not in the PVS of the current target,
780 it is not returned at all.
785 int c_invis, c_notvis;
786 static void VM_SV_checkclient (void)
788 prvm_edict_t *ent, *self;
791 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
793 // find a new check if on a new frame
794 if (sv.time - sv.lastchecktime >= 0.1)
796 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
797 sv.lastchecktime = sv.time;
800 // return check if it might be visible
801 ent = PRVM_EDICT_NUM(sv.lastcheck);
802 if (ent->priv.server->free || ent->fields.server->health <= 0)
804 VM_RETURN_EDICT(prog->edicts);
808 // if current entity can't possibly see the check entity, return 0
809 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
810 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
811 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
814 VM_RETURN_EDICT(prog->edicts);
818 // might be able to see it
820 VM_RETURN_EDICT(ent);
823 //============================================================================
829 Checks if an entity is in a point's PVS.
830 Should be fast but can be inexact.
832 float checkpvs(vector viewpos, entity viewee) = #240;
835 static void VM_SV_checkpvs (void)
838 prvm_edict_t *viewee;
843 unsigned char fatpvs[MAX_MAP_LEAFS/8];
846 VM_SAFEPARMCOUNT(2, VM_SV_checkpvs);
847 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos);
848 viewee = PRVM_G_EDICT(OFS_PARM1);
850 if(viewee->priv.server->free)
852 VM_Warning("checkpvs: can not check free entity\n");
853 PRVM_G_FLOAT(OFS_RETURN) = 4;
858 if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
860 // no PVS support on this worldmodel... darn
861 PRVM_G_FLOAT(OFS_RETURN) = 3;
864 pvs = sv.worldmodel->brush.GetPVS(sv.worldmodel, viewpos);
867 // viewpos isn't in any PVS... darn
868 PRVM_G_FLOAT(OFS_RETURN) = 2;
871 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
873 // using fat PVS like FTEQW does (slow)
874 if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
876 // no PVS support on this worldmodel... darn
877 PRVM_G_FLOAT(OFS_RETURN) = 3;
880 fatpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
883 // viewpos isn't in any PVS... darn
884 PRVM_G_FLOAT(OFS_RETURN) = 2;
887 PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, viewee->fields.server->absmin, viewee->fields.server->absmax);
896 Sends text over to the client's execution buffer
898 stuffcmd (clientent, value, ...)
901 static void VM_SV_stuffcmd (void)
905 char string[VM_STRINGTEMP_LENGTH];
907 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
909 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
910 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
912 VM_Warning("Can't stuffcmd to a non-client\n");
916 VM_VarString(1, string, sizeof(string));
919 host_client = svs.clients + entnum-1;
920 Host_ClientCommands ("%s", string);
928 Returns a chain of entities that have origins within a spherical area
930 findradius (origin, radius)
933 static void VM_SV_findradius (void)
935 prvm_edict_t *ent, *chain;
936 vec_t radius, radius2;
937 vec3_t org, eorg, mins, maxs;
940 static prvm_edict_t *touchedicts[MAX_EDICTS];
943 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_findradius);
946 chainfield = PRVM_G_INT(OFS_PARM2);
948 chainfield = prog->fieldoffsets.chain;
950 PRVM_ERROR("VM_findchain: %s doesnt have the specified chain field !", PRVM_NAME);
952 chain = (prvm_edict_t *)prog->edicts;
954 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
955 radius = PRVM_G_FLOAT(OFS_PARM1);
956 radius2 = radius * radius;
958 mins[0] = org[0] - (radius + 1);
959 mins[1] = org[1] - (radius + 1);
960 mins[2] = org[2] - (radius + 1);
961 maxs[0] = org[0] + (radius + 1);
962 maxs[1] = org[1] + (radius + 1);
963 maxs[2] = org[2] + (radius + 1);
964 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
965 if (numtouchedicts > MAX_EDICTS)
967 // this never happens
968 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
969 numtouchedicts = MAX_EDICTS;
971 for (i = 0;i < numtouchedicts;i++)
973 ent = touchedicts[i];
974 prog->xfunction->builtinsprofile++;
975 // Quake did not return non-solid entities but darkplaces does
976 // (note: this is the reason you can't blow up fallen zombies)
977 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
979 // LordHavoc: compare against bounding box rather than center so it
980 // doesn't miss large objects, and use DotProduct instead of Length
981 // for a major speedup
982 VectorSubtract(org, ent->fields.server->origin, eorg);
983 if (sv_gameplayfix_findradiusdistancetobox.integer)
985 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
986 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
987 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
990 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
991 if (DotProduct(eorg, eorg) < radius2)
993 PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
998 VM_RETURN_EDICT(chain);
1001 static void VM_SV_precache_sound (void)
1003 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
1004 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
1007 static void VM_SV_precache_model (void)
1009 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
1010 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
1011 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
1018 float(float yaw, float dist[, settrace]) walkmove
1021 static void VM_SV_walkmove (void)
1030 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
1032 // assume failure if it returns early
1033 PRVM_G_FLOAT(OFS_RETURN) = 0;
1035 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1036 if (ent == prog->edicts)
1038 VM_Warning("walkmove: can not modify world entity\n");
1041 if (ent->priv.server->free)
1043 VM_Warning("walkmove: can not modify free entity\n");
1046 yaw = PRVM_G_FLOAT(OFS_PARM0);
1047 dist = PRVM_G_FLOAT(OFS_PARM1);
1048 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
1050 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1053 yaw = yaw*M_PI*2 / 360;
1055 move[0] = cos(yaw)*dist;
1056 move[1] = sin(yaw)*dist;
1059 // save program state, because SV_movestep may call other progs
1060 oldf = prog->xfunction;
1061 oldself = prog->globals.server->self;
1063 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
1066 // restore program state
1067 prog->xfunction = oldf;
1068 prog->globals.server->self = oldself;
1078 static void VM_SV_droptofloor (void)
1084 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
1086 // assume failure if it returns early
1087 PRVM_G_FLOAT(OFS_RETURN) = 0;
1089 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1090 if (ent == prog->edicts)
1092 VM_Warning("droptofloor: can not modify world entity\n");
1095 if (ent->priv.server->free)
1097 VM_Warning("droptofloor: can not modify free entity\n");
1101 VectorCopy (ent->fields.server->origin, end);
1104 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
1105 SV_UnstickEntity(ent);
1107 trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1108 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
1111 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]);
1112 VectorAdd(ent->fields.server->origin, offset, org);
1113 trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1114 VectorSubtract(trace.endpos, offset, trace.endpos);
1115 if (trace.startsolid)
1117 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]);
1118 SV_UnstickEntity(ent);
1120 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1121 ent->fields.server->groundentity = 0;
1122 PRVM_G_FLOAT(OFS_RETURN) = 1;
1124 else if (trace.fraction < 1)
1126 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]);
1127 VectorCopy (trace.endpos, ent->fields.server->origin);
1128 SV_UnstickEntity(ent);
1130 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1131 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1132 PRVM_G_FLOAT(OFS_RETURN) = 1;
1133 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1134 ent->priv.server->suspendedinairflag = true;
1139 if (trace.fraction != 1)
1141 if (trace.fraction < 1)
1142 VectorCopy (trace.endpos, ent->fields.server->origin);
1144 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1145 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1146 PRVM_G_FLOAT(OFS_RETURN) = 1;
1147 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1148 ent->priv.server->suspendedinairflag = true;
1157 void(float style, string value) lightstyle
1160 static void VM_SV_lightstyle (void)
1167 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1169 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1170 val = PRVM_G_STRING(OFS_PARM1);
1172 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1173 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1176 // change the string in sv
1177 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1179 // send message to all clients on this server
1180 if (sv.state != ss_active)
1183 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1185 if (client->active && client->netconnection)
1187 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1188 MSG_WriteChar (&client->netconnection->message,style);
1189 MSG_WriteString (&client->netconnection->message, val);
1199 static void VM_SV_checkbottom (void)
1201 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1202 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1210 static void VM_SV_pointcontents (void)
1212 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1213 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1220 Pick a vector for the player to shoot along
1221 vector aim(entity, missilespeed)
1224 static void VM_SV_aim (void)
1226 prvm_edict_t *ent, *check, *bestent;
1227 vec3_t start, dir, end, bestdir;
1230 float dist, bestdist;
1233 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1235 // assume failure if it returns early
1236 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1237 // if sv_aim is so high it can't possibly accept anything, skip out early
1238 if (sv_aim.value >= 1)
1241 ent = PRVM_G_EDICT(OFS_PARM0);
1242 if (ent == prog->edicts)
1244 VM_Warning("aim: can not use world entity\n");
1247 if (ent->priv.server->free)
1249 VM_Warning("aim: can not use free entity\n");
1252 //speed = PRVM_G_FLOAT(OFS_PARM1);
1254 VectorCopy (ent->fields.server->origin, start);
1257 // try sending a trace straight
1258 VectorCopy (prog->globals.server->v_forward, dir);
1259 VectorMA (start, 2048, dir, end);
1260 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1261 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1262 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1264 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1269 // try all possible entities
1270 VectorCopy (dir, bestdir);
1271 bestdist = sv_aim.value;
1274 check = PRVM_NEXT_EDICT(prog->edicts);
1275 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1277 prog->xfunction->builtinsprofile++;
1278 if (check->fields.server->takedamage != DAMAGE_AIM)
1282 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1283 continue; // don't aim at teammate
1284 for (j=0 ; j<3 ; j++)
1285 end[j] = check->fields.server->origin[j]
1286 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1287 VectorSubtract (end, start, dir);
1288 VectorNormalize (dir);
1289 dist = DotProduct (dir, prog->globals.server->v_forward);
1290 if (dist < bestdist)
1291 continue; // to far to turn
1292 tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1293 if (tr.ent == check)
1294 { // can shoot at this one
1302 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1303 dist = DotProduct (dir, prog->globals.server->v_forward);
1304 VectorScale (prog->globals.server->v_forward, dist, end);
1306 VectorNormalize (end);
1307 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1311 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1316 ===============================================================================
1320 ===============================================================================
1323 #define MSG_BROADCAST 0 // unreliable to all
1324 #define MSG_ONE 1 // reliable to one (msg_entity)
1325 #define MSG_ALL 2 // reliable to all
1326 #define MSG_INIT 3 // write to the init string
1327 #define MSG_ENTITY 5
1329 sizebuf_t *WriteDest (void)
1335 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1339 return &sv.datagram;
1342 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1343 entnum = PRVM_NUM_FOR_EDICT(ent);
1344 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1346 VM_Warning ("WriteDest: tried to write to non-client\n");
1347 return &sv.reliable_datagram;
1350 return &svs.clients[entnum-1].netconnection->message;
1353 VM_Warning ("WriteDest: bad destination\n");
1355 return &sv.reliable_datagram;
1361 return sv.writeentitiestoclient_msg;
1367 static void VM_SV_WriteByte (void)
1369 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1370 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1373 static void VM_SV_WriteChar (void)
1375 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1376 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1379 static void VM_SV_WriteShort (void)
1381 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1382 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1385 static void VM_SV_WriteLong (void)
1387 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1388 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1391 static void VM_SV_WriteAngle (void)
1393 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1394 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1397 static void VM_SV_WriteCoord (void)
1399 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1400 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1403 static void VM_SV_WriteString (void)
1405 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1406 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1409 static void VM_SV_WriteUnterminatedString (void)
1411 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1412 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1416 static void VM_SV_WriteEntity (void)
1418 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1419 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1422 // writes a picture as at most size bytes of data
1424 // IMGNAME \0 SIZE(short) IMGDATA
1425 // if failed to read/compress:
1427 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1428 static void VM_SV_WritePicture (void)
1430 const char *imgname;
1434 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1436 imgname = PRVM_G_STRING(OFS_PARM1);
1437 size = (int) PRVM_G_FLOAT(OFS_PARM2);
1441 MSG_WriteString(WriteDest(), imgname);
1442 if(Image_Compress(imgname, size, &buf, &size))
1445 MSG_WriteShort(WriteDest(), size);
1446 SZ_Write(WriteDest(), (unsigned char *) buf, size);
1451 MSG_WriteShort(WriteDest(), 0);
1455 //////////////////////////////////////////////////////////
1457 static void VM_SV_makestatic (void)
1462 // allow 0 parameters due to an id1 qc bug in which this function is used
1463 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1464 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1466 if (prog->argc >= 1)
1467 ent = PRVM_G_EDICT(OFS_PARM0);
1469 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1470 if (ent == prog->edicts)
1472 VM_Warning("makestatic: can not modify world entity\n");
1475 if (ent->priv.server->free)
1477 VM_Warning("makestatic: can not modify free entity\n");
1482 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1487 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1488 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1489 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1491 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1493 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1494 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1495 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1499 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1500 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1501 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1504 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1505 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1506 for (i=0 ; i<3 ; i++)
1508 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1509 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1512 // throw the entity away now
1516 //=============================================================================
1523 static void VM_SV_setspawnparms (void)
1529 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1531 ent = PRVM_G_EDICT(OFS_PARM0);
1532 i = PRVM_NUM_FOR_EDICT(ent);
1533 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1535 Con_Print("tried to setspawnparms on a non-client\n");
1539 // copy spawn parms out of the client_t
1540 client = svs.clients + i-1;
1541 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1542 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1549 Returns a color vector indicating the lighting at the requested point.
1551 (Internal Operation note: actually measures the light beneath the point, just like
1552 the model lighting on the client)
1557 static void VM_SV_getlight (void)
1559 vec3_t ambientcolor, diffusecolor, diffusenormal;
1561 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1562 p = PRVM_G_VECTOR(OFS_PARM0);
1563 VectorClear(ambientcolor);
1564 VectorClear(diffusecolor);
1565 VectorClear(diffusenormal);
1566 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1567 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1568 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1573 unsigned char type; // 1/2/8 or other value if isn't used
1577 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1578 static int vm_customstats_last;
1580 void VM_CustomStats_Clear (void)
1584 Z_Free(vm_customstats);
1585 vm_customstats = NULL;
1586 vm_customstats_last = -1;
1590 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1598 for(i=0; i<vm_customstats_last+1 ;i++)
1600 if(!vm_customstats[i].type)
1602 switch(vm_customstats[i].type)
1604 //string as 16 bytes
1607 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1608 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1609 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1610 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1611 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1613 //float field sent as-is
1615 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1617 //integer value of float field
1619 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1627 // void(float index, float type, .void field) SV_AddStat = #232;
1628 // Set up an auto-sent player stat.
1629 // Client's get thier own fields sent to them. Index may not be less than 32.
1630 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1631 // 1: string (4 stats carrying a total of 16 charactures)
1632 // 2: float (one stat, float converted to an integer for transportation)
1633 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1634 static void VM_SV_AddStat (void)
1639 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1643 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1646 VM_Warning("PF_SV_AddStat: not enough memory\n");
1650 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1651 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1652 off = PRVM_G_INT (OFS_PARM2);
1657 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1660 if(i >= (MAX_CL_STATS-32))
1662 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1665 if(i > (MAX_CL_STATS-32-4) && type == 1)
1667 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1670 vm_customstats[i].type = type;
1671 vm_customstats[i].fieldoffset = off;
1672 if(vm_customstats_last < i)
1673 vm_customstats_last = i;
1680 copies data from one entity to another
1682 copyentity(src, dst)
1685 static void VM_SV_copyentity (void)
1687 prvm_edict_t *in, *out;
1688 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1689 in = PRVM_G_EDICT(OFS_PARM0);
1690 if (in == prog->edicts)
1692 VM_Warning("copyentity: can not read world entity\n");
1695 if (in->priv.server->free)
1697 VM_Warning("copyentity: can not read free entity\n");
1700 out = PRVM_G_EDICT(OFS_PARM1);
1701 if (out == prog->edicts)
1703 VM_Warning("copyentity: can not modify world entity\n");
1706 if (out->priv.server->free)
1708 VM_Warning("copyentity: can not modify free entity\n");
1711 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1720 sets the color of a client and broadcasts the update to all connected clients
1722 setcolor(clientent, value)
1725 static void VM_SV_setcolor (void)
1731 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1732 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1733 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1735 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1737 Con_Print("tried to setcolor a non-client\n");
1741 client = svs.clients + entnum-1;
1744 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1746 client->edict->fields.server->team = (i & 15) + 1;
1749 if (client->old_colors != client->colors)
1751 client->old_colors = client->colors;
1752 // send notification to all clients
1753 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1754 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1755 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1763 effect(origin, modelname, startframe, framecount, framerate)
1766 static void VM_SV_effect (void)
1770 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1771 s = PRVM_G_STRING(OFS_PARM1);
1774 VM_Warning("effect: no model specified\n");
1778 i = SV_ModelIndex(s, 1);
1781 VM_Warning("effect: model not precached\n");
1785 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1787 VM_Warning("effect: framecount < 1\n");
1791 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1793 VM_Warning("effect: framerate < 1\n");
1797 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));
1800 static void VM_SV_te_blood (void)
1802 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1803 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1805 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1806 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1808 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1809 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1810 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1812 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1813 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1814 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1816 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1817 SV_FlushBroadcastMessages();
1820 static void VM_SV_te_bloodshower (void)
1822 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1823 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1825 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1826 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1828 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1829 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1830 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1833 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1834 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1836 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1838 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1839 SV_FlushBroadcastMessages();
1842 static void VM_SV_te_explosionrgb (void)
1844 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1845 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1846 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1848 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1849 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1850 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1852 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1853 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1854 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1855 SV_FlushBroadcastMessages();
1858 static void VM_SV_te_particlecube (void)
1860 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1861 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1863 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1864 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1866 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1867 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1871 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1872 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1874 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1875 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1876 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1878 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1880 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1881 // gravity true/false
1882 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1884 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1885 SV_FlushBroadcastMessages();
1888 static void VM_SV_te_particlerain (void)
1890 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1891 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1893 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1894 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1896 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1897 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1898 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1902 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1904 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1905 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1906 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1908 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1910 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1911 SV_FlushBroadcastMessages();
1914 static void VM_SV_te_particlesnow (void)
1916 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1917 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1919 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1920 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1922 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1923 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1924 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1926 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1927 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1928 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1930 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1931 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1934 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1936 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1937 SV_FlushBroadcastMessages();
1940 static void VM_SV_te_spark (void)
1942 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1943 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1945 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1946 MSG_WriteByte(&sv.datagram, TE_SPARK);
1948 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1949 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1950 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1952 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1953 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1954 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1956 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1957 SV_FlushBroadcastMessages();
1960 static void VM_SV_te_gunshotquad (void)
1962 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1963 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1964 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1966 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1967 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1968 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1969 SV_FlushBroadcastMessages();
1972 static void VM_SV_te_spikequad (void)
1974 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1975 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1976 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1978 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1979 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1980 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1981 SV_FlushBroadcastMessages();
1984 static void VM_SV_te_superspikequad (void)
1986 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1987 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1988 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1990 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1991 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1992 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1993 SV_FlushBroadcastMessages();
1996 static void VM_SV_te_explosionquad (void)
1998 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1999 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2000 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2002 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2003 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2004 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2005 SV_FlushBroadcastMessages();
2008 static void VM_SV_te_smallflash (void)
2010 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
2011 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2012 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2014 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2015 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2016 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2017 SV_FlushBroadcastMessages();
2020 static void VM_SV_te_customflash (void)
2022 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
2023 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2025 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2026 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2028 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2029 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2030 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2032 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2034 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
2036 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
2037 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
2038 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
2039 SV_FlushBroadcastMessages();
2042 static void VM_SV_te_gunshot (void)
2044 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
2045 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2046 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2048 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2049 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2050 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2051 SV_FlushBroadcastMessages();
2054 static void VM_SV_te_spike (void)
2056 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
2057 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2058 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2060 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2061 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2062 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2063 SV_FlushBroadcastMessages();
2066 static void VM_SV_te_superspike (void)
2068 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
2069 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2070 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2072 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2073 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2074 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2075 SV_FlushBroadcastMessages();
2078 static void VM_SV_te_explosion (void)
2080 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
2081 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2082 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2084 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2085 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2086 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2087 SV_FlushBroadcastMessages();
2090 static void VM_SV_te_tarexplosion (void)
2092 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
2093 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2094 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2096 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2097 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2098 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2099 SV_FlushBroadcastMessages();
2102 static void VM_SV_te_wizspike (void)
2104 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
2105 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2106 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2108 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2109 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2110 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2111 SV_FlushBroadcastMessages();
2114 static void VM_SV_te_knightspike (void)
2116 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2117 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2118 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2120 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2121 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2122 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2123 SV_FlushBroadcastMessages();
2126 static void VM_SV_te_lavasplash (void)
2128 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2129 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2130 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2132 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2133 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2134 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2135 SV_FlushBroadcastMessages();
2138 static void VM_SV_te_teleport (void)
2140 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2141 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2142 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2144 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2145 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2146 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2147 SV_FlushBroadcastMessages();
2150 static void VM_SV_te_explosion2 (void)
2152 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2153 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2154 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2156 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2157 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2158 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2160 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2161 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2162 SV_FlushBroadcastMessages();
2165 static void VM_SV_te_lightning1 (void)
2167 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2168 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2169 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2171 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2173 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2174 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2175 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2177 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2178 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2179 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2180 SV_FlushBroadcastMessages();
2183 static void VM_SV_te_lightning2 (void)
2185 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2186 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2187 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2189 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2191 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2192 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2193 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2195 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2196 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2197 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2198 SV_FlushBroadcastMessages();
2201 static void VM_SV_te_lightning3 (void)
2203 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2204 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2205 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2207 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2209 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2210 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2211 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2213 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2214 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2215 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2216 SV_FlushBroadcastMessages();
2219 static void VM_SV_te_beam (void)
2221 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2222 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2223 MSG_WriteByte(&sv.datagram, TE_BEAM);
2225 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2227 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2228 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2229 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2231 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2232 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2233 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2234 SV_FlushBroadcastMessages();
2237 static void VM_SV_te_plasmaburn (void)
2239 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2240 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2241 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2242 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2243 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2244 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2245 SV_FlushBroadcastMessages();
2248 static void VM_SV_te_flamejet (void)
2250 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2251 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2252 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2254 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2255 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2256 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2258 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2259 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2260 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2262 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2263 SV_FlushBroadcastMessages();
2266 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2267 //this function originally written by KrimZon, made shorter by LordHavoc
2268 static void VM_SV_clientcommand (void)
2270 client_t *temp_client;
2272 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2274 //find client for this entity
2275 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2276 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2278 Con_Print("PF_clientcommand: entity is not a client\n");
2282 temp_client = host_client;
2283 host_client = svs.clients + i;
2284 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2285 host_client = temp_client;
2288 //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)
2289 static void VM_SV_setattachment (void)
2291 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2292 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2293 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2296 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2298 if (e == prog->edicts)
2300 VM_Warning("setattachment: can not modify world entity\n");
2303 if (e->priv.server->free)
2305 VM_Warning("setattachment: can not modify free entity\n");
2309 if (tagentity == NULL)
2310 tagentity = prog->edicts;
2312 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2314 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2316 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2319 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2321 model = SV_GetModelFromEdict(tagentity);
2324 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2326 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);
2329 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));
2333 /////////////////////////////////////////
2334 // DP_MD3_TAGINFO extension coded by VorteX
2336 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2340 i = (int)e->fields.server->modelindex;
2341 if (i < 1 || i >= MAX_MODELS)
2344 return Mod_Alias_GetTagIndexForName(SV_GetModelByIndex(i), (int)e->fields.server->skin, tagname);
2347 int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
2354 Matrix4x4_CreateIdentity(tag_localmatrix);
2356 if (tagindex >= 0 && (model = SV_GetModelFromEdict(e)) && model->num_bones)
2358 r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, e->priv.server->frameblend, &e->priv.server->skeleton, tagindex - 1, parentindex, tagname, tag_localmatrix);
2369 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2373 float pitchsign = 1;
2376 val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
2377 if (val && val->_float != 0)
2378 scale = val->_float;
2381 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);
2384 pitchsign = SV_GetPitchSign(ent);
2385 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);
2389 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2392 if (tagindex >= 0 && (model = SV_GetModelFromEdict(ent)) && model->animscenes)
2394 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2395 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2396 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2397 return Mod_Alias_GetTagMatrix(model, ent->priv.server->frameblend, &ent->priv.server->skeleton, tagindex, out);
2399 *out = identitymatrix;
2403 // Warnings/errors code:
2404 // 0 - normal (everything all-right)
2407 // 3 - null or non-precached model
2408 // 4 - no tags with requested index
2409 // 5 - runaway loop at attachment chain
2410 extern cvar_t cl_bob;
2411 extern cvar_t cl_bobcycle;
2412 extern cvar_t cl_bobup;
2413 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2417 int modelindex, attachloop;
2418 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2421 *out = identitymatrix; // warnings and errors return identical matrix
2423 if (ent == prog->edicts)
2425 if (ent->priv.server->free)
2428 modelindex = (int)ent->fields.server->modelindex;
2429 if (modelindex <= 0 || modelindex >= MAX_MODELS)
2432 model = SV_GetModelByIndex(modelindex);
2434 VM_GenerateFrameGroupBlend(ent->priv.server->framegroupblend, ent);
2435 VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
2436 VM_UpdateEdictSkeleton(ent, model, ent->priv.server->frameblend);
2438 tagmatrix = identitymatrix;
2439 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2443 if (attachloop >= 256) // prevent runaway looping
2445 // apply transformation by child's tagindex on parent entity and then
2446 // by parent entity itself
2447 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2448 if (ret && attachloop == 0)
2450 SV_GetEntityMatrix(ent, &entitymatrix, false);
2451 Matrix4x4_Concat(&tagmatrix, &attachmatrix, out);
2452 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2453 // next iteration we process the parent entity
2454 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2456 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2457 ent = PRVM_EDICT_NUM(val->edict);
2464 // RENDER_VIEWMODEL magic
2465 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2467 Matrix4x4_Copy(&tagmatrix, out);
2468 ent = PRVM_EDICT_NUM(val->edict);
2470 SV_GetEntityMatrix(ent, &entitymatrix, true);
2471 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2474 // Cl_bob, ported from rendering code
2475 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2478 // LordHavoc: this code is *weird*, but not replacable (I think it
2479 // should be done in QC on the server, but oh well, quake is quake)
2480 // LordHavoc: figured out bobup: the time at which the sin is at 180
2481 // degrees (which allows lengthening or squishing the peak or valley)
2482 cycle = sv.time/cl_bobcycle.value;
2483 cycle -= (int)cycle;
2484 if (cycle < cl_bobup.value)
2485 cycle = sin(M_PI * cycle / cl_bobup.value);
2487 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2488 // bob is proportional to velocity in the xy plane
2489 // (don't count Z, or jumping messes it up)
2490 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;
2491 bob = bob*0.3 + bob*0.7*cycle;
2492 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2499 //float(entity ent, string tagname) gettagindex;
2501 static void VM_SV_gettagindex (void)
2504 const char *tag_name;
2507 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2509 ent = PRVM_G_EDICT(OFS_PARM0);
2510 tag_name = PRVM_G_STRING(OFS_PARM1);
2512 if (ent == prog->edicts)
2514 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
2517 if (ent->priv.server->free)
2519 VM_Warning("VM_SV_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
2524 if (!SV_GetModelFromEdict(ent))
2525 Con_DPrintf("VM_SV_gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2528 tag_index = SV_GetTagIndex(ent, tag_name);
2530 if(developer_extra.integer)
2531 Con_DPrintf("VM_SV_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2533 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2536 //vector(entity ent, float tagindex) gettaginfo;
2537 static void VM_SV_gettaginfo (void)
2541 matrix4x4_t tag_matrix;
2542 matrix4x4_t tag_localmatrix;
2544 const char *tagname;
2547 vec3_t fo, le, up, trans;
2548 const dp_model_t *model;
2550 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2552 e = PRVM_G_EDICT(OFS_PARM0);
2553 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2555 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2556 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, le, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2557 VectorScale(le, -1, prog->globals.server->v_right);
2558 model = SV_GetModelFromEdict(e);
2559 VM_GenerateFrameGroupBlend(e->priv.server->framegroupblend, e);
2560 VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model);
2561 VM_UpdateEdictSkeleton(e, model, e->priv.server->frameblend);
2562 SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
2563 Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
2565 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
2566 val->_float = parentindex;
2567 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
2568 val->string = tagname ? PRVM_SetTempString(tagname) : 0;
2569 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
2570 VectorCopy(trans, val->vector);
2571 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
2572 VectorCopy(fo, val->vector);
2573 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
2574 VectorScale(le, -1, val->vector);
2575 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
2576 VectorCopy(up, val->vector);
2581 VM_Warning("gettagindex: can't affect world entity\n");
2584 VM_Warning("gettagindex: can't affect free entity\n");
2587 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2590 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2593 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2598 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2599 static void VM_SV_dropclient (void)
2602 client_t *oldhostclient;
2603 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2604 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2605 if (clientnum < 0 || clientnum >= svs.maxclients)
2607 VM_Warning("dropclient: not a client\n");
2610 if (!svs.clients[clientnum].active)
2612 VM_Warning("dropclient: that client slot is not connected\n");
2615 oldhostclient = host_client;
2616 host_client = svs.clients + clientnum;
2617 SV_DropClient(false);
2618 host_client = oldhostclient;
2621 //entity() spawnclient (DP_SV_BOTCLIENT)
2622 static void VM_SV_spawnclient (void)
2626 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2627 prog->xfunction->builtinsprofile += 2;
2629 for (i = 0;i < svs.maxclients;i++)
2631 if (!svs.clients[i].active)
2633 prog->xfunction->builtinsprofile += 100;
2634 SV_ConnectClient (i, NULL);
2635 // this has to be set or else ClientDisconnect won't be called
2636 // we assume the qc will call ClientConnect...
2637 svs.clients[i].clientconnectcalled = true;
2638 ed = PRVM_EDICT_NUM(i + 1);
2642 VM_RETURN_EDICT(ed);
2645 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2646 static void VM_SV_clienttype (void)
2649 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2650 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2651 if (clientnum < 0 || clientnum >= svs.maxclients)
2652 PRVM_G_FLOAT(OFS_RETURN) = 3;
2653 else if (!svs.clients[clientnum].active)
2654 PRVM_G_FLOAT(OFS_RETURN) = 0;
2655 else if (svs.clients[clientnum].netconnection)
2656 PRVM_G_FLOAT(OFS_RETURN) = 1;
2658 PRVM_G_FLOAT(OFS_RETURN) = 2;
2665 string(string key) serverkey
2668 void VM_SV_serverkey(void)
2670 char string[VM_STRINGTEMP_LENGTH];
2671 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2672 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2673 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2676 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2677 static void VM_SV_setmodelindex (void)
2682 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2684 e = PRVM_G_EDICT(OFS_PARM0);
2685 if (e == prog->edicts)
2687 VM_Warning("setmodelindex: can not modify world entity\n");
2690 if (e->priv.server->free)
2692 VM_Warning("setmodelindex: can not modify free entity\n");
2695 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2696 if (i <= 0 || i >= MAX_MODELS)
2698 VM_Warning("setmodelindex: invalid modelindex\n");
2701 if (!sv.model_precache[i][0])
2703 VM_Warning("setmodelindex: model not precached\n");
2707 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2708 e->fields.server->modelindex = i;
2710 mod = SV_GetModelByIndex(i);
2714 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2715 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2717 SetMinMaxSize (e, quakemins, quakemaxs, true);
2720 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2723 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2724 static void VM_SV_modelnameforindex (void)
2727 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2729 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2731 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2732 if (i <= 0 || i >= MAX_MODELS)
2734 VM_Warning("modelnameforindex: invalid modelindex\n");
2737 if (!sv.model_precache[i][0])
2739 VM_Warning("modelnameforindex: model not precached\n");
2743 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2746 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2747 static void VM_SV_particleeffectnum (void)
2750 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2751 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2754 PRVM_G_FLOAT(OFS_RETURN) = i;
2757 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2758 static void VM_SV_trailparticles (void)
2760 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2762 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2765 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2766 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2767 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2768 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2769 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2770 SV_FlushBroadcastMessages();
2773 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2774 static void VM_SV_pointparticles (void)
2776 int effectnum, count;
2778 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2780 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2783 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2784 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2785 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2786 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2787 if (count == 1 && !VectorLength2(vel))
2790 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2791 MSG_WriteShort(&sv.datagram, effectnum);
2792 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2796 // 1+2+12+12+2=29 bytes
2797 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2798 MSG_WriteShort(&sv.datagram, effectnum);
2799 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2800 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2801 MSG_WriteShort(&sv.datagram, count);
2804 SV_FlushBroadcastMessages();
2807 //PF_setpause, // void(float pause) setpause = #531;
2808 static void VM_SV_setpause(void) {
2810 pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
2811 if (pauseValue != 0) { //pause the game
2813 sv.pausedstart = Sys_DoubleTime();
2814 } else { //disable pause, in case it was enabled
2815 if (sv.paused != 0) {
2820 // send notification to all clients
2821 MSG_WriteByte(&sv.reliable_datagram, svc_setpause);
2822 MSG_WriteByte(&sv.reliable_datagram, sv.paused);
2825 // #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.
2826 static void VM_SV_skel_create(void)
2828 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
2829 dp_model_t *model = SV_GetModelByIndex(modelindex);
2830 skeleton_t *skeleton;
2832 PRVM_G_FLOAT(OFS_RETURN) = 0;
2833 if (!model || !model->num_bones)
2835 for (i = 0;i < MAX_EDICTS;i++)
2836 if (!prog->skeletons[i])
2838 if (i == MAX_EDICTS)
2840 prog->skeletons[i] = skeleton = Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
2841 PRVM_G_FLOAT(OFS_RETURN) = i + 1;
2842 skeleton->model = model;
2843 skeleton->relativetransforms = (matrix4x4_t *)(skeleton+1);
2844 // initialize to identity matrices
2845 for (i = 0;i < skeleton->model->num_bones;i++)
2846 skeleton->relativetransforms[i] = identitymatrix;
2849 // #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
2850 static void VM_SV_skel_build(void)
2852 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2853 skeleton_t *skeleton;
2854 prvm_edict_t *ed = PRVM_G_EDICT(OFS_PARM1);
2855 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM2);
2856 float retainfrac = PRVM_G_FLOAT(OFS_PARM3);
2857 int firstbone = PRVM_G_FLOAT(OFS_PARM4) - 1;
2858 int lastbone = PRVM_G_FLOAT(OFS_PARM5) - 1;
2859 dp_model_t *model = SV_GetModelByIndex(modelindex);
2864 framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS];
2865 frameblend_t frameblend[MAX_FRAMEBLENDS];
2866 matrix4x4_t blendedmatrix;
2868 PRVM_G_FLOAT(OFS_RETURN) = 0;
2869 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2871 firstbone = max(0, firstbone);
2872 lastbone = min(lastbone, model->num_bones - 1);
2873 lastbone = min(lastbone, skeleton->model->num_bones - 1);
2874 VM_GenerateFrameGroupBlend(framegroupblend, ed);
2875 VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model);
2876 blendfrac = 1.0f - retainfrac;
2877 for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
2878 frameblend[numblends].lerp *= blendfrac;
2879 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
2881 memset(&blendedmatrix, 0, sizeof(blendedmatrix));
2882 Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac);
2883 for (blendindex = 0;blendindex < numblends;blendindex++)
2885 Matrix4x4_FromBonePose6s(&matrix, model->num_posescale, model->data_poses6s + 6 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
2886 Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp);
2888 skeleton->relativetransforms[bonenum] = blendedmatrix;
2890 PRVM_G_FLOAT(OFS_RETURN) = skeletonindex + 1;
2893 // #265 float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS) returns how many bones exist in the created skeleton
2894 static void VM_SV_skel_get_numbones(void)
2896 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2897 skeleton_t *skeleton;
2898 PRVM_G_FLOAT(OFS_RETURN) = 0;
2899 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2901 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->num_bones;
2904 // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) returns name of bone (as a tempstring)
2905 static void VM_SV_skel_get_bonename(void)
2907 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2908 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2909 skeleton_t *skeleton;
2910 PRVM_G_INT(OFS_RETURN) = 0;
2911 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2913 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2915 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(skeleton->model->data_bones[bonenum].name);
2918 // #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)
2919 static void VM_SV_skel_get_boneparent(void)
2921 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2922 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2923 skeleton_t *skeleton;
2924 PRVM_G_FLOAT(OFS_RETURN) = 0;
2925 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2927 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2929 PRVM_G_FLOAT(OFS_RETURN) = skeleton->model->data_bones[bonenum].parent + 1;
2932 // #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
2933 static void VM_SV_skel_find_bone(void)
2935 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2936 const char *tagname = PRVM_G_STRING(OFS_PARM1);
2937 skeleton_t *skeleton;
2938 PRVM_G_FLOAT(OFS_RETURN) = 0;
2939 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2941 PRVM_G_FLOAT(OFS_RETURN) = Mod_Alias_GetTagIndexForName(skeleton->model, 0, tagname) + 1;
2944 // #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)
2945 static void VM_SV_skel_get_bonerel(void)
2947 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2948 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2949 skeleton_t *skeleton;
2951 vec3_t forward, left, up, origin;
2952 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2953 VectorClear(prog->globals.client->v_forward);
2954 VectorClear(prog->globals.client->v_right);
2955 VectorClear(prog->globals.client->v_up);
2956 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2958 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2960 matrix = skeleton->relativetransforms[bonenum];
2961 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2962 VectorCopy(forward, prog->globals.client->v_forward);
2963 VectorNegate(left, prog->globals.client->v_right);
2964 VectorCopy(up, prog->globals.client->v_up);
2965 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
2968 // #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)
2969 static void VM_SV_skel_get_boneabs(void)
2971 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
2972 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
2973 skeleton_t *skeleton;
2976 vec3_t forward, left, up, origin;
2977 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2978 VectorClear(prog->globals.client->v_forward);
2979 VectorClear(prog->globals.client->v_right);
2980 VectorClear(prog->globals.client->v_up);
2981 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
2983 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
2985 matrix = skeleton->relativetransforms[bonenum];
2986 // convert to absolute
2987 while ((bonenum = skeleton->model->data_bones[bonenum].parent) >= 0)
2990 Matrix4x4_Concat(&matrix, &skeleton->relativetransforms[bonenum], &temp);
2992 Matrix4x4_ToVectors(&matrix, forward, left, up, origin);
2993 VectorCopy(forward, prog->globals.client->v_forward);
2994 VectorNegate(left, prog->globals.client->v_right);
2995 VectorCopy(up, prog->globals.client->v_up);
2996 VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
2999 // #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)
3000 static void VM_SV_skel_set_bone(void)
3002 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3003 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3004 vec3_t forward, left, up, origin;
3005 skeleton_t *skeleton;
3007 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3009 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3011 VectorCopy(prog->globals.client->v_forward, forward);
3012 VectorNegate(prog->globals.client->v_right, left);
3013 VectorCopy(prog->globals.client->v_up, up);
3014 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3015 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3016 skeleton->relativetransforms[bonenum] = matrix;
3019 // #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)
3020 static void VM_SV_skel_mul_bone(void)
3022 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3023 int bonenum = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3024 vec3_t forward, left, up, origin;
3025 skeleton_t *skeleton;
3028 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3030 if (bonenum < 0 || bonenum >= skeleton->model->num_bones)
3032 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin);
3033 VectorCopy(prog->globals.client->v_forward, forward);
3034 VectorNegate(prog->globals.client->v_right, left);
3035 VectorCopy(prog->globals.client->v_up, up);
3036 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3037 temp = skeleton->relativetransforms[bonenum];
3038 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3041 // #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)
3042 static void VM_SV_skel_mul_bones(void)
3044 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3045 int firstbone = PRVM_G_FLOAT(OFS_PARM1) - 1;
3046 int lastbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3048 vec3_t forward, left, up, origin;
3049 skeleton_t *skeleton;
3052 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3054 VectorCopy(PRVM_G_VECTOR(OFS_PARM3), origin);
3055 VectorCopy(prog->globals.client->v_forward, forward);
3056 VectorNegate(prog->globals.client->v_right, left);
3057 VectorCopy(prog->globals.client->v_up, up);
3058 Matrix4x4_FromVectors(&matrix, forward, left, up, origin);
3059 firstbone = max(0, firstbone);
3060 lastbone = min(lastbone, skeleton->model->num_bones - 1);
3061 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3063 temp = skeleton->relativetransforms[bonenum];
3064 Matrix4x4_Concat(&skeleton->relativetransforms[bonenum], &matrix, &temp);
3068 // #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
3069 static void VM_SV_skel_copybones(void)
3071 int skeletonindexdst = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3072 int skeletonindexsrc = (int)PRVM_G_FLOAT(OFS_PARM1) - 1;
3073 int firstbone = PRVM_G_FLOAT(OFS_PARM2) - 1;
3074 int lastbone = PRVM_G_FLOAT(OFS_PARM3) - 1;
3076 skeleton_t *skeletondst;
3077 skeleton_t *skeletonsrc;
3078 if (skeletonindexdst < 0 || skeletonindexdst >= MAX_EDICTS || !(skeletondst = prog->skeletons[skeletonindexdst]))
3080 if (skeletonindexsrc < 0 || skeletonindexsrc >= MAX_EDICTS || !(skeletonsrc = prog->skeletons[skeletonindexsrc]))
3082 firstbone = max(0, firstbone);
3083 lastbone = min(lastbone, skeletondst->model->num_bones - 1);
3084 lastbone = min(lastbone, skeletonsrc->model->num_bones - 1);
3085 for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
3086 skeletondst->relativetransforms[bonenum] = skeletonsrc->relativetransforms[bonenum];
3089 // #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)
3090 static void VM_SV_skel_delete(void)
3092 int skeletonindex = (int)PRVM_G_FLOAT(OFS_PARM0) - 1;
3093 skeleton_t *skeleton;
3094 if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
3097 prog->skeletons[skeletonindex] = NULL;
3100 // #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
3101 static void VM_SV_frameforname(void)
3103 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3104 dp_model_t *model = SV_GetModelByIndex(modelindex);
3105 const char *name = PRVM_G_STRING(OFS_PARM1);
3107 PRVM_G_FLOAT(OFS_RETURN) = -1;
3108 if (!model || !model->animscenes)
3110 for (i = 0;i < model->numframes;i++)
3112 if (!strcasecmp(model->animscenes[i].name, name))
3114 PRVM_G_FLOAT(OFS_RETURN) = i;
3120 // #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.
3121 static void VM_SV_frameduration(void)
3123 int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
3124 dp_model_t *model = SV_GetModelByIndex(modelindex);
3125 int framenum = (int)PRVM_G_FLOAT(OFS_PARM1);
3126 PRVM_G_FLOAT(OFS_RETURN) = 0;
3127 if (!model || !model->animscenes || framenum < 0 || framenum >= model->numframes)
3129 if (model->animscenes[framenum].framerate)
3130 PRVM_G_FLOAT(OFS_RETURN) = model->animscenes[framenum].framecount / model->animscenes[framenum].framerate;
3134 prvm_builtin_t vm_sv_builtins[] = {
3135 NULL, // #0 NULL function (not callable) (QUAKE)
3136 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
3137 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
3138 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
3139 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
3140 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
3141 VM_break, // #6 void() break (QUAKE)
3142 VM_random, // #7 float() random (QUAKE)
3143 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
3144 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
3145 VM_error, // #10 void(string e) error (QUAKE)
3146 VM_objerror, // #11 void(string e) objerror (QUAKE)
3147 VM_vlen, // #12 float(vector v) vlen (QUAKE)
3148 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
3149 VM_spawn, // #14 entity() spawn (QUAKE)
3150 VM_remove, // #15 void(entity e) remove (QUAKE)
3151 VM_SV_traceline, // #16 void(vector v1, vector v2, float tryents) traceline (QUAKE)
3152 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
3153 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
3154 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
3155 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
3156 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
3157 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
3158 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
3159 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
3160 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
3161 VM_ftos, // #26 string(float f) ftos (QUAKE)
3162 VM_vtos, // #27 string(vector v) vtos (QUAKE)
3163 VM_coredump, // #28 void() coredump (QUAKE)
3164 VM_traceon, // #29 void() traceon (QUAKE)
3165 VM_traceoff, // #30 void() traceoff (QUAKE)
3166 VM_eprint, // #31 void(entity e) eprint (QUAKE)
3167 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
3168 NULL, // #33 (QUAKE)
3169 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
3170 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
3171 VM_rint, // #36 float(float v) rint (QUAKE)
3172 VM_floor, // #37 float(float v) floor (QUAKE)
3173 VM_ceil, // #38 float(float v) ceil (QUAKE)
3174 NULL, // #39 (QUAKE)
3175 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
3176 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
3177 NULL, // #42 (QUAKE)
3178 VM_fabs, // #43 float(float f) fabs (QUAKE)
3179 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
3180 VM_cvar, // #45 float(string s) cvar (QUAKE)
3181 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
3182 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
3183 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
3184 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
3185 NULL, // #50 (QUAKE)
3186 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
3187 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
3188 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
3189 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
3190 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
3191 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
3192 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
3193 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
3194 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
3195 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
3196 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
3197 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
3198 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
3199 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
3200 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
3201 NULL, // #66 (QUAKE)
3202 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
3203 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
3204 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
3205 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
3206 NULL, // #71 (QUAKE)
3207 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
3208 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
3209 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
3210 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
3211 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
3212 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
3213 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
3214 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
3215 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
3216 VM_stof, // #81 float(string s) stof (FRIK_FILE)
3217 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
3218 NULL, // #83 (QUAKE)
3219 NULL, // #84 (QUAKE)
3220 NULL, // #85 (QUAKE)
3221 NULL, // #86 (QUAKE)
3222 NULL, // #87 (QUAKE)
3223 NULL, // #88 (QUAKE)
3224 NULL, // #89 (QUAKE)
3225 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
3226 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
3227 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
3228 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
3229 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
3230 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3231 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3232 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3233 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3234 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3235 // FrikaC and Telejano range #100-#199
3246 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3247 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3248 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3249 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3250 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3251 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3252 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3253 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3254 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3255 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3336 // FTEQW range #200-#299
3355 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3358 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3359 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3360 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3361 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3362 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3363 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3364 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3365 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3366 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3367 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3369 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3377 VM_SV_checkpvs, // #240 float(vector viewpos, entity viewee) checkpvs;
3400 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.
3401 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
3402 VM_SV_skel_get_numbones, // #265 float(float skel) skel_get_numbones = #265; // (DP_SKELETONOBJECTS) returns how many bones exist in the created skeleton
3403 VM_SV_skel_get_bonename, // #266 string(float skel, float bonenum) skel_get_bonename = #266; // (DP_SKELETONOBJECTS) returns name of bone (as a tempstring)
3404 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)
3405 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
3406 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)
3407 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)
3408 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)
3409 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)
3410 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)
3411 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
3412 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)
3413 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
3414 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.
3437 // CSQC range #300-#399
3438 NULL, // #300 void() clearscene (EXT_CSQC)
3439 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3440 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3441 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3442 NULL, // #304 void() renderscene (EXT_CSQC)
3443 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3444 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3445 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3446 NULL, // #308 void() R_EndPolygon
3448 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3449 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3453 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3454 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3455 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3456 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3457 NULL, // #319 void(string name) freepic (EXT_CSQC)
3458 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3459 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3460 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3461 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3462 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3463 NULL, // #325 void(void) drawresetcliparea
3468 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3469 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3470 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3471 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3472 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3473 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3474 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3475 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3476 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3477 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3478 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3479 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3480 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3481 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3482 NULL, // #344 vector() getmousepos (EXT_CSQC)
3483 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3484 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3485 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3486 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3487 NULL, // #349 float() isdemo (EXT_CSQC)
3488 VM_isserver, // #350 float() isserver (EXT_CSQC)
3489 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3490 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3491 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3492 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3498 NULL, // #360 float() readbyte (EXT_CSQC)
3499 NULL, // #361 float() readchar (EXT_CSQC)
3500 NULL, // #362 float() readshort (EXT_CSQC)
3501 NULL, // #363 float() readlong (EXT_CSQC)
3502 NULL, // #364 float() readcoord (EXT_CSQC)
3503 NULL, // #365 float() readangle (EXT_CSQC)
3504 NULL, // #366 string() readstring (EXT_CSQC)
3505 NULL, // #367 float() readfloat (EXT_CSQC)
3538 // LordHavoc's range #400-#499
3539 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3540 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3541 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3542 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3543 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3544 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3545 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3546 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3547 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)
3548 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3549 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3550 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3551 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3552 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3553 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3554 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3555 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3556 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3557 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3558 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3559 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3560 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3561 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3562 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3563 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3564 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3565 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3566 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3567 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3568 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3569 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3570 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3571 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3572 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3573 VM_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3574 VM_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3575 VM_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3576 VM_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3577 VM_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3578 VM_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3579 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3580 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3581 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3582 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3583 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3584 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3585 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3586 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3587 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3588 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3589 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3590 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3591 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3592 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3593 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3594 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3595 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3596 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3598 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3599 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3600 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3601 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3602 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3603 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3604 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3605 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3606 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3607 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3608 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3610 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3611 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3612 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3613 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3614 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3615 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3616 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3617 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3618 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3619 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3620 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3621 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3622 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3623 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3624 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3625 VM_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3633 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3634 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3635 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3636 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3637 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3638 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3639 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3640 VM_SV_WritePicture, // #501
3642 VM_whichpack, // #503 string(string) whichpack = #503;
3649 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3650 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3651 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3652 VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3653 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3654 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3655 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3656 VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
3657 VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
3658 VM_gettime, // #519 float(float timer) gettime = #519; (DP_QC_GETTIME)
3668 VM_loadfromdata, // #529
3669 VM_loadfromfile, // #530
3670 VM_SV_setpause, // #531 void(float pause) setpause = #531;
3672 VM_getsoundtime, // #533 float(entity e, float channel) getsoundtime = #533; (DP_SND_GETSOUNDTIME)
3673 VM_soundlength, // #534 float(string sample) soundlength = #534; (DP_SND_GETSOUNDTIME)
3744 VM_callfunction, // #605
3745 VM_writetofile, // #606
3746 VM_isfunction, // #607
3752 VM_parseentitydata, // #613
3763 VM_SV_getextresponse, // #624 string getextresponse(void)
3766 VM_sprintf, // #627 string sprintf(string format, ...)
3767 VM_getsurfacenumtriangles, // #628 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACETRIANGLE)
3768 VM_getsurfacetriangle, // #629 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACETRIANGLE)
3772 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3774 void VM_SV_Cmd_Init(void)
3779 void VM_SV_Cmd_Reset(void)
3781 World_End(&sv.world);
3782 if(prog->funcoffsets.SV_Shutdown)
3784 func_t s = prog->funcoffsets.SV_Shutdown;
3785 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3786 PRVM_ExecuteProgram(s,"SV_Shutdown() required");