3 //============================================================================
8 char *vm_sv_extensions =
13 "DP_CON_ALIASPARAMETERS "
31 "DP_ENT_CUSTOMCOLORMAP "
32 "DP_ENT_EXTERIORMODELTOCLIENT "
34 "DP_ENT_LOWPRECISION "
37 "DP_GFX_EXTERNALTEXTURES "
38 "DP_GFX_EXTERNALTEXTURES_PERMAP "
40 "DP_GFX_QUAKE3MODELTAGS "
44 "DP_HALFLIFE_MAP_CVAR "
50 "DP_MOVETYPEBOUNCEMISSILE "
52 "DP_QC_ASINACOSATANATAN2TAN "
55 "DP_QC_CVAR_DEFSTRING "
59 "DP_QC_FINDCHAINFLAGS "
60 "DP_QC_FINDCHAINFLOAT "
68 "DP_QC_MULTIPLETEMPSTRINGS "
70 "DP_QC_SINCOSSQRTPOW "
72 "DP_QC_STRING_CASE_FUNCTIONS "
73 "DP_QC_STRINGBUFFERS "
74 "DP_QC_STRINGCOLORFUNCTIONS "
75 "DP_QC_TOKENIZEBYSEPARATOR "
78 "DP_QC_TRACE_MOVETYPE_HITMODEL "
79 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
80 "DP_QC_UNLIMITEDTEMPSTRINGS "
81 "DP_QC_VECTORVECTORS "
87 "DP_SND_DIRECTIONLESSATTNNONE "
96 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
97 "DP_SV_DRAWONLYTOCLIENT "
100 "DP_SV_ENTITYCONTENTSTRANSITION "
101 "DP_SV_ONENTITYNOSPAWNFUNCTION "
102 "DP_SV_MODELFLAGS_AS_EFFECTS "
104 "DP_SV_NODRAWTOCLIENT "
106 "DP_SV_PLAYERPHYSICS "
107 "DP_SV_POINTPARTICLES "
109 "DP_SV_PRECACHEANYTIME "
112 "DP_SV_ROTATINGBMODEL "
115 "DP_SV_WRITEUNTERMINATEDSTRING "
119 "DP_TE_EXPLOSIONRGB "
121 "DP_TE_PARTICLECUBE "
122 "DP_TE_PARTICLERAIN "
123 "DP_TE_PARTICLESNOW "
125 "DP_TE_QUADEFFECTS1 "
128 "DP_TE_STANDARDEFFECTBUILTINS "
129 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
132 //"EXT_CSQC " // not ready yet
134 "KRIMZON_SV_PARSECLIENTCOMMAND "
137 "NEXUIZ_PLAYERMODEL "
139 "PRYDON_CLIENTCURSOR "
140 "TENEBRAE_GFX_DLIGHTS "
151 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.
153 setorigin (entity, origin)
156 static void VM_SV_setorigin (void)
161 VM_SAFEPARMCOUNT(2, VM_setorigin);
163 e = PRVM_G_EDICT(OFS_PARM0);
164 if (e == prog->edicts)
166 VM_Warning("setorigin: can not modify world entity\n");
169 if (e->priv.server->free)
171 VM_Warning("setorigin: can not modify free entity\n");
174 org = PRVM_G_VECTOR(OFS_PARM1);
175 VectorCopy (org, e->fields.server->origin);
176 SV_LinkEdict (e, false);
180 void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
184 for (i=0 ; i<3 ; i++)
186 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
188 // set derived values
189 VectorCopy (min, e->fields.server->mins);
190 VectorCopy (max, e->fields.server->maxs);
191 VectorSubtract (max, min, e->fields.server->size);
193 SV_LinkEdict (e, false);
200 the size box is rotated by the current angle
201 LordHavoc: no it isn't...
203 setsize (entity, minvector, maxvector)
206 static void VM_SV_setsize (void)
211 VM_SAFEPARMCOUNT(3, VM_setsize);
213 e = PRVM_G_EDICT(OFS_PARM0);
214 if (e == prog->edicts)
216 VM_Warning("setsize: can not modify world entity\n");
219 if (e->priv.server->free)
221 VM_Warning("setsize: can not modify free entity\n");
224 min = PRVM_G_VECTOR(OFS_PARM1);
225 max = PRVM_G_VECTOR(OFS_PARM2);
226 SetMinMaxSize (e, min, max, false);
234 setmodel(entity, model)
237 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
238 static void VM_SV_setmodel (void)
244 VM_SAFEPARMCOUNT(2, VM_setmodel);
246 e = PRVM_G_EDICT(OFS_PARM0);
247 if (e == prog->edicts)
249 VM_Warning("setmodel: can not modify world entity\n");
252 if (e->priv.server->free)
254 VM_Warning("setmodel: can not modify free entity\n");
257 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
258 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
259 e->fields.server->modelindex = i;
265 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
266 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
268 SetMinMaxSize (e, quakemins, quakemaxs, true);
271 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
278 single print to a specific client
280 sprint(clientent, value)
283 static void VM_SV_sprint (void)
287 char string[VM_STRINGTEMP_LENGTH];
289 VM_VarString(1, string, sizeof(string));
291 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
293 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
294 // LordHavoc: div0 requested that sprintto world operate like print
301 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
303 VM_Warning("tried to centerprint to a non-client\n");
307 client = svs.clients + entnum-1;
308 if (!client->netconnection)
311 MSG_WriteChar(&client->netconnection->message,svc_print);
312 MSG_WriteString(&client->netconnection->message, string);
320 single print to a specific client
322 centerprint(clientent, value)
325 static void VM_SV_centerprint (void)
329 char string[VM_STRINGTEMP_LENGTH];
331 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
333 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
335 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
337 VM_Warning("tried to centerprint to a non-client\n");
341 client = svs.clients + entnum-1;
342 if (!client->netconnection)
345 VM_VarString(1, string, sizeof(string));
346 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
347 MSG_WriteString(&client->netconnection->message, string);
354 particle(origin, color, count)
357 static void VM_SV_particle (void)
363 VM_SAFEPARMCOUNT(4, VM_SV_particle);
365 org = PRVM_G_VECTOR(OFS_PARM0);
366 dir = PRVM_G_VECTOR(OFS_PARM1);
367 color = PRVM_G_FLOAT(OFS_PARM2);
368 count = PRVM_G_FLOAT(OFS_PARM3);
369 SV_StartParticle (org, dir, (int)color, (int)count);
379 static void VM_SV_ambientsound (void)
383 float vol, attenuation;
386 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
388 pos = PRVM_G_VECTOR (OFS_PARM0);
389 samp = PRVM_G_STRING(OFS_PARM1);
390 vol = PRVM_G_FLOAT(OFS_PARM2);
391 attenuation = PRVM_G_FLOAT(OFS_PARM3);
393 // check to see if samp was properly precached
394 soundnum = SV_SoundIndex(samp, 1);
402 // add an svc_spawnambient command to the level signon packet
405 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
407 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
409 MSG_WriteVector(&sv.signon, pos, sv.protocol);
412 MSG_WriteShort (&sv.signon, soundnum);
414 MSG_WriteByte (&sv.signon, soundnum);
416 MSG_WriteByte (&sv.signon, (int)(vol*255));
417 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
425 Each entity can have eight independant sound sources, like voice,
428 Channel 0 is an auto-allocate channel, the others override anything
429 already running on that entity/channel pair.
431 An attenuation of 0 will play full volume everywhere in the level.
432 Larger attenuations will drop off.
436 static void VM_SV_sound (void)
440 prvm_edict_t *entity;
444 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
446 entity = PRVM_G_EDICT(OFS_PARM0);
447 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
448 sample = PRVM_G_STRING(OFS_PARM2);
449 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
450 attenuation = PRVM_G_FLOAT(OFS_PARM4);
453 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
457 if (volume < 0 || volume > 255)
459 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
463 if (attenuation < 0 || attenuation > 4)
465 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
469 if (channel < 0 || channel > 7)
471 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
475 SV_StartSound (entity, channel, sample, volume, attenuation);
482 Follows the same logic as VM_SV_sound, except instead of
483 an entity, an origin for the sound is provided, and channel
484 is omitted (since no entity is being tracked).
488 static void VM_SV_pointsound(void)
495 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
497 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
498 sample = PRVM_G_STRING(OFS_PARM1);
499 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
500 attenuation = PRVM_G_FLOAT(OFS_PARM3);
502 if (volume < 0 || volume > 255)
504 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
508 if (attenuation < 0 || attenuation > 4)
510 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
514 SV_StartPointSound (org, sample, volume, attenuation);
521 Used for use tracing and shot targeting
522 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
523 if the tryents flag is set.
525 traceline (vector1, vector2, movetype, ignore)
528 static void VM_SV_traceline (void)
535 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
537 prog->xfunction->builtinsprofile += 30;
539 v1 = PRVM_G_VECTOR(OFS_PARM0);
540 v2 = PRVM_G_VECTOR(OFS_PARM1);
541 move = (int)PRVM_G_FLOAT(OFS_PARM2);
542 ent = PRVM_G_EDICT(OFS_PARM3);
544 if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
545 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));
547 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
549 VM_SetTraceGlobals(&trace);
557 Used for use tracing and shot targeting
558 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
559 if the tryents flag is set.
561 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
564 // LordHavoc: added this for my own use, VERY useful, similar to traceline
565 static void VM_SV_tracebox (void)
567 float *v1, *v2, *m1, *m2;
572 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
574 prog->xfunction->builtinsprofile += 30;
576 v1 = PRVM_G_VECTOR(OFS_PARM0);
577 m1 = PRVM_G_VECTOR(OFS_PARM1);
578 m2 = PRVM_G_VECTOR(OFS_PARM2);
579 v2 = PRVM_G_VECTOR(OFS_PARM3);
580 move = (int)PRVM_G_FLOAT(OFS_PARM4);
581 ent = PRVM_G_EDICT(OFS_PARM5);
583 if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
584 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));
586 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
588 VM_SetTraceGlobals(&trace);
591 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
596 vec3_t original_origin;
597 vec3_t original_velocity;
598 vec3_t original_angles;
599 vec3_t original_avelocity;
603 VectorCopy(tossent->fields.server->origin , original_origin );
604 VectorCopy(tossent->fields.server->velocity , original_velocity );
605 VectorCopy(tossent->fields.server->angles , original_angles );
606 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
608 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
609 if (val != NULL && val->_float != 0)
610 gravity = val->_float;
613 gravity *= sv_gravity.value * 0.05;
615 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
617 SV_CheckVelocity (tossent);
618 tossent->fields.server->velocity[2] -= gravity;
619 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
620 VectorScale (tossent->fields.server->velocity, 0.05, move);
621 VectorAdd (tossent->fields.server->origin, move, end);
622 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
623 VectorCopy (trace.endpos, tossent->fields.server->origin);
625 if (trace.fraction < 1)
629 VectorCopy(original_origin , tossent->fields.server->origin );
630 VectorCopy(original_velocity , tossent->fields.server->velocity );
631 VectorCopy(original_angles , tossent->fields.server->angles );
632 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
637 static void VM_SV_tracetoss (void)
641 prvm_edict_t *ignore;
643 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
645 prog->xfunction->builtinsprofile += 600;
647 ent = PRVM_G_EDICT(OFS_PARM0);
648 if (ent == prog->edicts)
650 VM_Warning("tracetoss: can not use world entity\n");
653 ignore = PRVM_G_EDICT(OFS_PARM1);
655 trace = SV_Trace_Toss (ent, ignore);
657 VM_SetTraceGlobals(&trace);
660 //============================================================================
662 static int checkpvsbytes;
663 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
665 static int VM_SV_newcheckclient (int check)
671 // cycle to the next one
673 check = bound(1, check, svs.maxclients);
674 if (check == svs.maxclients)
682 prog->xfunction->builtinsprofile++;
684 if (i == svs.maxclients+1)
686 // look up the client's edict
687 ent = PRVM_EDICT_NUM(i);
688 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
689 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
691 // found a valid client (possibly the same one again)
695 // get the PVS for the entity
696 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
698 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
699 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
708 Returns a client (or object that has a client enemy) that would be a
711 If there is more than one valid option, they are cycled each frame
713 If (self.origin + self.viewofs) is not in the PVS of the current target,
714 it is not returned at all.
719 int c_invis, c_notvis;
720 static void VM_SV_checkclient (void)
722 prvm_edict_t *ent, *self;
725 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
727 // find a new check if on a new frame
728 if (sv.time - sv.lastchecktime >= 0.1)
730 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
731 sv.lastchecktime = sv.time;
734 // return check if it might be visible
735 ent = PRVM_EDICT_NUM(sv.lastcheck);
736 if (ent->priv.server->free || ent->fields.server->health <= 0)
738 VM_RETURN_EDICT(prog->edicts);
742 // if current entity can't possibly see the check entity, return 0
743 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
744 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
745 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
748 VM_RETURN_EDICT(prog->edicts);
752 // might be able to see it
754 VM_RETURN_EDICT(ent);
757 //============================================================================
764 Sends text over to the client's execution buffer
766 stuffcmd (clientent, value, ...)
769 static void VM_SV_stuffcmd (void)
773 char string[VM_STRINGTEMP_LENGTH];
775 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
777 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
778 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
780 VM_Warning("Can't stuffcmd to a non-client\n");
784 VM_VarString(1, string, sizeof(string));
787 host_client = svs.clients + entnum-1;
788 Host_ClientCommands ("%s", string);
796 Returns a chain of entities that have origins within a spherical area
798 findradius (origin, radius)
801 static void VM_SV_findradius (void)
803 prvm_edict_t *ent, *chain;
804 vec_t radius, radius2;
805 vec3_t org, eorg, mins, maxs;
808 prvm_edict_t *touchedicts[MAX_EDICTS];
810 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
812 chain = (prvm_edict_t *)prog->edicts;
814 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
815 radius = PRVM_G_FLOAT(OFS_PARM1);
816 radius2 = radius * radius;
818 mins[0] = org[0] - (radius + 1);
819 mins[1] = org[1] - (radius + 1);
820 mins[2] = org[2] - (radius + 1);
821 maxs[0] = org[0] + (radius + 1);
822 maxs[1] = org[1] + (radius + 1);
823 maxs[2] = org[2] + (radius + 1);
824 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
825 if (numtouchedicts > MAX_EDICTS)
827 // this never happens
828 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
829 numtouchedicts = MAX_EDICTS;
831 for (i = 0;i < numtouchedicts;i++)
833 ent = touchedicts[i];
834 prog->xfunction->builtinsprofile++;
835 // Quake did not return non-solid entities but darkplaces does
836 // (note: this is the reason you can't blow up fallen zombies)
837 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
839 // LordHavoc: compare against bounding box rather than center so it
840 // doesn't miss large objects, and use DotProduct instead of Length
841 // for a major speedup
842 VectorSubtract(org, ent->fields.server->origin, eorg);
843 if (sv_gameplayfix_findradiusdistancetobox.integer)
845 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
846 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
847 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
850 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
851 if (DotProduct(eorg, eorg) < radius2)
853 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
858 VM_RETURN_EDICT(chain);
861 static void VM_SV_precache_sound (void)
863 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
864 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
865 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
868 static void VM_SV_precache_model (void)
870 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
871 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
872 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
879 float(float yaw, float dist[, settrace]) walkmove
882 static void VM_SV_walkmove (void)
891 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
893 // assume failure if it returns early
894 PRVM_G_FLOAT(OFS_RETURN) = 0;
896 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
897 if (ent == prog->edicts)
899 VM_Warning("walkmove: can not modify world entity\n");
902 if (ent->priv.server->free)
904 VM_Warning("walkmove: can not modify free entity\n");
907 yaw = PRVM_G_FLOAT(OFS_PARM0);
908 dist = PRVM_G_FLOAT(OFS_PARM1);
909 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
911 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
914 yaw = yaw*M_PI*2 / 360;
916 move[0] = cos(yaw)*dist;
917 move[1] = sin(yaw)*dist;
920 // save program state, because SV_movestep may call other progs
921 oldf = prog->xfunction;
922 oldself = prog->globals.server->self;
924 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
927 // restore program state
928 prog->xfunction = oldf;
929 prog->globals.server->self = oldself;
939 static void VM_SV_droptofloor (void)
945 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
947 // assume failure if it returns early
948 PRVM_G_FLOAT(OFS_RETURN) = 0;
950 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
951 if (ent == prog->edicts)
953 VM_Warning("droptofloor: can not modify world entity\n");
956 if (ent->priv.server->free)
958 VM_Warning("droptofloor: can not modify free entity\n");
962 VectorCopy (ent->fields.server->origin, end);
965 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
967 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
969 if (trace.fraction < 1)
970 VectorCopy (trace.endpos, ent->fields.server->origin);
971 SV_LinkEdict (ent, false);
972 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
973 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
974 PRVM_G_FLOAT(OFS_RETURN) = 1;
975 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
976 ent->priv.server->suspendedinairflag = true;
984 void(float style, string value) lightstyle
987 static void VM_SV_lightstyle (void)
994 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
996 style = (int)PRVM_G_FLOAT(OFS_PARM0);
997 val = PRVM_G_STRING(OFS_PARM1);
999 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1000 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1003 // change the string in sv
1004 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1006 // send message to all clients on this server
1007 if (sv.state != ss_active)
1010 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1012 if (client->active && client->netconnection)
1014 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1015 MSG_WriteChar (&client->netconnection->message,style);
1016 MSG_WriteString (&client->netconnection->message, val);
1026 static void VM_SV_checkbottom (void)
1028 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1029 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1037 static void VM_SV_pointcontents (void)
1039 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1040 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1047 Pick a vector for the player to shoot along
1048 vector aim(entity, missilespeed)
1051 static void VM_SV_aim (void)
1053 prvm_edict_t *ent, *check, *bestent;
1054 vec3_t start, dir, end, bestdir;
1057 float dist, bestdist;
1060 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1062 // assume failure if it returns early
1063 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1064 // if sv_aim is so high it can't possibly accept anything, skip out early
1065 if (sv_aim.value >= 1)
1068 ent = PRVM_G_EDICT(OFS_PARM0);
1069 if (ent == prog->edicts)
1071 VM_Warning("aim: can not use world entity\n");
1074 if (ent->priv.server->free)
1076 VM_Warning("aim: can not use free entity\n");
1079 speed = PRVM_G_FLOAT(OFS_PARM1);
1081 VectorCopy (ent->fields.server->origin, start);
1084 // try sending a trace straight
1085 VectorCopy (prog->globals.server->v_forward, dir);
1086 VectorMA (start, 2048, dir, end);
1087 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1088 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1089 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1091 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1096 // try all possible entities
1097 VectorCopy (dir, bestdir);
1098 bestdist = sv_aim.value;
1101 check = PRVM_NEXT_EDICT(prog->edicts);
1102 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1104 prog->xfunction->builtinsprofile++;
1105 if (check->fields.server->takedamage != DAMAGE_AIM)
1109 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1110 continue; // don't aim at teammate
1111 for (j=0 ; j<3 ; j++)
1112 end[j] = check->fields.server->origin[j]
1113 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1114 VectorSubtract (end, start, dir);
1115 VectorNormalize (dir);
1116 dist = DotProduct (dir, prog->globals.server->v_forward);
1117 if (dist < bestdist)
1118 continue; // to far to turn
1119 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1120 if (tr.ent == check)
1121 { // can shoot at this one
1129 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1130 dist = DotProduct (dir, prog->globals.server->v_forward);
1131 VectorScale (prog->globals.server->v_forward, dist, end);
1133 VectorNormalize (end);
1134 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1138 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1143 ===============================================================================
1147 ===============================================================================
1150 #define MSG_BROADCAST 0 // unreliable to all
1151 #define MSG_ONE 1 // reliable to one (msg_entity)
1152 #define MSG_ALL 2 // reliable to all
1153 #define MSG_INIT 3 // write to the init string
1154 #define MSG_ENTITY 5
1156 sizebuf_t *WriteDest (void)
1162 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1166 return &sv.datagram;
1169 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1170 entnum = PRVM_NUM_FOR_EDICT(ent);
1171 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1173 VM_Warning ("WriteDest: tried to write to non-client\n");
1174 return &sv.reliable_datagram;
1177 return &svs.clients[entnum-1].netconnection->message;
1180 VM_Warning ("WriteDest: bad destination\n");
1182 return &sv.reliable_datagram;
1188 return sv.writeentitiestoclient_msg;
1194 static void VM_SV_WriteByte (void)
1196 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1197 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1200 static void VM_SV_WriteChar (void)
1202 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1203 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1206 static void VM_SV_WriteShort (void)
1208 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1209 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1212 static void VM_SV_WriteLong (void)
1214 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1215 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1218 static void VM_SV_WriteAngle (void)
1220 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1221 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1224 static void VM_SV_WriteCoord (void)
1226 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1227 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1230 static void VM_SV_WriteString (void)
1232 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1233 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1236 static void VM_SV_WriteUnterminatedString (void)
1238 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1239 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1243 static void VM_SV_WriteEntity (void)
1245 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1246 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1249 //////////////////////////////////////////////////////////
1251 static void VM_SV_makestatic (void)
1256 // allow 0 parameters due to an id1 qc bug in which this function is used
1257 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1258 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1260 if (prog->argc >= 1)
1261 ent = PRVM_G_EDICT(OFS_PARM0);
1263 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1264 if (ent == prog->edicts)
1266 VM_Warning("makestatic: can not modify world entity\n");
1269 if (ent->priv.server->free)
1271 VM_Warning("makestatic: can not modify free entity\n");
1276 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1281 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1282 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1283 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1287 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1288 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1289 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1292 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1293 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1294 for (i=0 ; i<3 ; i++)
1296 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1297 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1300 // throw the entity away now
1304 //=============================================================================
1311 static void VM_SV_setspawnparms (void)
1317 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1319 ent = PRVM_G_EDICT(OFS_PARM0);
1320 i = PRVM_NUM_FOR_EDICT(ent);
1321 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1323 Con_Print("tried to setspawnparms on a non-client\n");
1327 // copy spawn parms out of the client_t
1328 client = svs.clients + i-1;
1329 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1330 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1337 Returns a color vector indicating the lighting at the requested point.
1339 (Internal Operation note: actually measures the light beneath the point, just like
1340 the model lighting on the client)
1345 static void VM_SV_getlight (void)
1347 vec3_t ambientcolor, diffusecolor, diffusenormal;
1349 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1350 p = PRVM_G_VECTOR(OFS_PARM0);
1351 VectorClear(ambientcolor);
1352 VectorClear(diffusecolor);
1353 VectorClear(diffusenormal);
1354 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1355 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1356 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1361 unsigned char type; // 1/2/8 or other value if isn't used
1365 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1366 static int vm_customstats_last;
1368 void VM_CustomStats_Clear (void)
1372 Z_Free(vm_customstats);
1373 vm_customstats = NULL;
1374 vm_customstats_last = -1;
1378 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1386 for(i=0; i<vm_customstats_last+1 ;i++)
1388 if(!vm_customstats[i].type)
1390 switch(vm_customstats[i].type)
1392 //string as 16 bytes
1395 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1396 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1397 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1398 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1399 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1401 //float field sent as-is
1403 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1405 //integer value of float field
1407 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1415 // void(float index, float type, .void field) SV_AddStat = #232;
1416 // Set up an auto-sent player stat.
1417 // Client's get thier own fields sent to them. Index may not be less than 32.
1418 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1419 // 1: string (4 stats carrying a total of 16 charactures)
1420 // 2: float (one stat, float converted to an integer for transportation)
1421 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1422 static void VM_SV_AddStat (void)
1427 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1431 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1434 VM_Warning("PF_SV_AddStat: not enough memory\n");
1438 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1439 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1440 off = PRVM_G_INT (OFS_PARM2);
1445 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1448 if(i >= (MAX_CL_STATS-32))
1450 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1453 if(i > (MAX_CL_STATS-32-4) && type == 1)
1455 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1458 vm_customstats[i].type = type;
1459 vm_customstats[i].fieldoffset = off;
1460 if(vm_customstats_last < i)
1461 vm_customstats_last = i;
1468 copies data from one entity to another
1470 copyentity(src, dst)
1473 static void VM_SV_copyentity (void)
1475 prvm_edict_t *in, *out;
1476 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1477 in = PRVM_G_EDICT(OFS_PARM0);
1478 if (in == prog->edicts)
1480 VM_Warning("copyentity: can not read world entity\n");
1483 if (in->priv.server->free)
1485 VM_Warning("copyentity: can not read free entity\n");
1488 out = PRVM_G_EDICT(OFS_PARM1);
1489 if (out == prog->edicts)
1491 VM_Warning("copyentity: can not modify world entity\n");
1494 if (out->priv.server->free)
1496 VM_Warning("copyentity: can not modify free entity\n");
1499 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1500 SV_LinkEdict(out, false);
1508 sets the color of a client and broadcasts the update to all connected clients
1510 setcolor(clientent, value)
1513 static void VM_SV_setcolor (void)
1519 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1520 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1521 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1523 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1525 Con_Print("tried to setcolor a non-client\n");
1529 client = svs.clients + entnum-1;
1532 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1534 client->edict->fields.server->team = (i & 15) + 1;
1537 if (client->old_colors != client->colors)
1539 client->old_colors = client->colors;
1540 // send notification to all clients
1541 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1542 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1543 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1551 effect(origin, modelname, startframe, framecount, framerate)
1554 static void VM_SV_effect (void)
1558 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1559 s = PRVM_G_STRING(OFS_PARM1);
1562 VM_Warning("effect: no model specified\n");
1566 i = SV_ModelIndex(s, 1);
1569 VM_Warning("effect: model not precached\n");
1573 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1575 VM_Warning("effect: framecount < 1\n");
1579 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1581 VM_Warning("effect: framerate < 1\n");
1585 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));
1588 static void VM_SV_te_blood (void)
1590 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1591 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1593 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1594 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1596 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1597 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1598 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1600 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1601 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1602 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1604 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1605 SV_FlushBroadcastMessages();
1608 static void VM_SV_te_bloodshower (void)
1610 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1611 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1613 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1614 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1616 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1617 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1618 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1620 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1621 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1622 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1624 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1626 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1627 SV_FlushBroadcastMessages();
1630 static void VM_SV_te_explosionrgb (void)
1632 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1633 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1634 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1636 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1637 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1638 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1640 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1641 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1642 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1643 SV_FlushBroadcastMessages();
1646 static void VM_SV_te_particlecube (void)
1648 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1649 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1651 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1652 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1654 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1655 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1656 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1658 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1659 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1660 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1662 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1663 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1664 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1666 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1668 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1669 // gravity true/false
1670 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1672 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1673 SV_FlushBroadcastMessages();
1676 static void VM_SV_te_particlerain (void)
1678 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1679 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1681 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1682 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1684 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1685 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1686 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1688 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1689 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1690 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1692 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1693 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1694 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1696 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1698 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1699 SV_FlushBroadcastMessages();
1702 static void VM_SV_te_particlesnow (void)
1704 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1705 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1707 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1708 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1710 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1711 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1712 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1714 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1715 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1716 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1718 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1719 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1720 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1722 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1724 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1725 SV_FlushBroadcastMessages();
1728 static void VM_SV_te_spark (void)
1730 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1731 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1733 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1734 MSG_WriteByte(&sv.datagram, TE_SPARK);
1736 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1737 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1738 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1740 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1741 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1742 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1744 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1745 SV_FlushBroadcastMessages();
1748 static void VM_SV_te_gunshotquad (void)
1750 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1751 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1752 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1754 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1755 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1756 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1757 SV_FlushBroadcastMessages();
1760 static void VM_SV_te_spikequad (void)
1762 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1763 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1764 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1766 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1767 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1768 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1769 SV_FlushBroadcastMessages();
1772 static void VM_SV_te_superspikequad (void)
1774 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1775 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1776 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1778 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1779 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1780 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1781 SV_FlushBroadcastMessages();
1784 static void VM_SV_te_explosionquad (void)
1786 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1787 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1788 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1790 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1791 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1792 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1793 SV_FlushBroadcastMessages();
1796 static void VM_SV_te_smallflash (void)
1798 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1799 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1800 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1802 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1803 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1804 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1805 SV_FlushBroadcastMessages();
1808 static void VM_SV_te_customflash (void)
1810 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1811 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1813 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1814 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1816 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1817 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1818 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1820 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1822 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1824 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1825 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1826 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1827 SV_FlushBroadcastMessages();
1830 static void VM_SV_te_gunshot (void)
1832 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1833 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1834 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1836 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1837 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1838 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1839 SV_FlushBroadcastMessages();
1842 static void VM_SV_te_spike (void)
1844 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1845 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1846 MSG_WriteByte(&sv.datagram, TE_SPIKE);
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);
1851 SV_FlushBroadcastMessages();
1854 static void VM_SV_te_superspike (void)
1856 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1857 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1858 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1860 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1861 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1862 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1863 SV_FlushBroadcastMessages();
1866 static void VM_SV_te_explosion (void)
1868 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1869 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1870 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1872 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1873 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1874 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1875 SV_FlushBroadcastMessages();
1878 static void VM_SV_te_tarexplosion (void)
1880 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1881 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1882 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1884 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1885 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1886 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1887 SV_FlushBroadcastMessages();
1890 static void VM_SV_te_wizspike (void)
1892 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1893 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1894 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
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);
1899 SV_FlushBroadcastMessages();
1902 static void VM_SV_te_knightspike (void)
1904 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1905 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1906 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1908 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1909 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1910 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1911 SV_FlushBroadcastMessages();
1914 static void VM_SV_te_lavasplash (void)
1916 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1917 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1918 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1920 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1921 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1922 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1923 SV_FlushBroadcastMessages();
1926 static void VM_SV_te_teleport (void)
1928 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1929 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1930 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1933 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1934 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1935 SV_FlushBroadcastMessages();
1938 static void VM_SV_te_explosion2 (void)
1940 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1941 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1942 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1944 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1945 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1946 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1948 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1949 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1950 SV_FlushBroadcastMessages();
1953 static void VM_SV_te_lightning1 (void)
1955 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1956 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1957 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1959 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1961 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1962 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1963 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1965 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1966 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1967 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1968 SV_FlushBroadcastMessages();
1971 static void VM_SV_te_lightning2 (void)
1973 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1974 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1975 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1977 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1979 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1980 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1981 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1983 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1984 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1985 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1986 SV_FlushBroadcastMessages();
1989 static void VM_SV_te_lightning3 (void)
1991 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1992 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1993 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1995 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1997 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1998 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1999 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2001 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2002 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2003 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2004 SV_FlushBroadcastMessages();
2007 static void VM_SV_te_beam (void)
2009 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2010 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2011 MSG_WriteByte(&sv.datagram, TE_BEAM);
2013 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2015 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2016 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2017 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2019 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2020 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2021 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2022 SV_FlushBroadcastMessages();
2025 static void VM_SV_te_plasmaburn (void)
2027 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2028 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2029 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2030 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2031 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2032 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2033 SV_FlushBroadcastMessages();
2036 static void VM_SV_te_flamejet (void)
2038 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2039 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2040 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2042 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2043 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2044 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2046 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2047 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2048 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2050 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2051 SV_FlushBroadcastMessages();
2054 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2057 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2059 bestdist = 1000000000;
2061 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2063 // clip original point to each triangle of the surface and find the
2064 // triangle that is closest
2065 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2066 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2067 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2068 TriangleNormal(v[0], v[1], v[2], facenormal);
2069 VectorNormalize(facenormal);
2070 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2071 VectorMA(p, offsetdist, facenormal, temp);
2072 for (j = 0, k = 2;j < 3;k = j, j++)
2074 VectorSubtract(v[k], v[j], edgenormal);
2075 CrossProduct(edgenormal, facenormal, sidenormal);
2076 VectorNormalize(sidenormal);
2077 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2079 VectorMA(temp, offsetdist, sidenormal, temp);
2081 dist = VectorDistance2(temp, p);
2082 if (bestdist > dist)
2085 VectorCopy(temp, out);
2090 static model_t *getmodel(prvm_edict_t *ed)
2093 if (!ed || ed->priv.server->free)
2095 modelindex = (int)ed->fields.server->modelindex;
2096 if (modelindex < 1 || modelindex >= MAX_MODELS)
2098 return sv.models[modelindex];
2101 static msurface_t *getsurface(model_t *model, int surfacenum)
2103 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2105 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2109 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2110 static void VM_SV_getsurfacenumpoints(void)
2113 msurface_t *surface;
2114 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2115 // return 0 if no such surface
2116 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2118 PRVM_G_FLOAT(OFS_RETURN) = 0;
2122 // note: this (incorrectly) assumes it is a simple polygon
2123 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2125 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2126 static void VM_SV_getsurfacepoint(void)
2130 msurface_t *surface;
2132 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2133 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2134 ed = PRVM_G_EDICT(OFS_PARM0);
2135 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2137 // note: this (incorrectly) assumes it is a simple polygon
2138 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2139 if (pointnum < 0 || pointnum >= surface->num_vertices)
2141 // FIXME: implement rotation/scaling
2142 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2144 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2145 static void VM_SV_getsurfacenormal(void)
2148 msurface_t *surface;
2150 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2151 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2152 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2154 // FIXME: implement rotation/scaling
2155 // note: this (incorrectly) assumes it is a simple polygon
2156 // note: this only returns the first triangle, so it doesn't work very
2157 // well for curved surfaces or arbitrary meshes
2158 TriangleNormal((model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex), (model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex) + 3, (model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex) + 6, normal);
2159 VectorNormalize(normal);
2160 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2162 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2163 static void VM_SV_getsurfacetexture(void)
2166 msurface_t *surface;
2167 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2168 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2169 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2171 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2173 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2174 static void VM_SV_getsurfacenearpoint(void)
2176 int surfacenum, best;
2178 vec_t dist, bestdist;
2181 msurface_t *surface;
2183 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2184 PRVM_G_FLOAT(OFS_RETURN) = -1;
2185 ed = PRVM_G_EDICT(OFS_PARM0);
2186 point = PRVM_G_VECTOR(OFS_PARM1);
2188 if (!ed || ed->priv.server->free)
2190 model = getmodel(ed);
2191 if (!model || !model->num_surfaces)
2194 // FIXME: implement rotation/scaling
2195 VectorSubtract(point, ed->fields.server->origin, p);
2197 bestdist = 1000000000;
2198 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2200 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2201 // first see if the nearest point on the surface's box is closer than the previous match
2202 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2203 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2204 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2205 dist = VectorLength2(clipped);
2206 if (dist < bestdist)
2208 // it is, check the nearest point on the actual geometry
2209 clippointtosurface(model, surface, p, clipped);
2210 VectorSubtract(clipped, p, clipped);
2211 dist += VectorLength2(clipped);
2212 if (dist < bestdist)
2214 // that's closer too, store it as the best match
2220 PRVM_G_FLOAT(OFS_RETURN) = best;
2222 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2223 static void VM_SV_getsurfaceclippedpoint(void)
2227 msurface_t *surface;
2229 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2230 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2231 ed = PRVM_G_EDICT(OFS_PARM0);
2232 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2234 // FIXME: implement rotation/scaling
2235 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2236 clippointtosurface(model, surface, p, out);
2237 // FIXME: implement rotation/scaling
2238 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2241 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2242 //this function originally written by KrimZon, made shorter by LordHavoc
2243 static void VM_SV_clientcommand (void)
2245 client_t *temp_client;
2247 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2249 //find client for this entity
2250 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2251 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2253 Con_Print("PF_clientcommand: entity is not a client\n");
2257 temp_client = host_client;
2258 host_client = svs.clients + i;
2259 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2260 host_client = temp_client;
2263 //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)
2264 static void VM_SV_setattachment (void)
2266 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2267 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2268 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2272 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2274 if (e == prog->edicts)
2276 VM_Warning("setattachment: can not modify world entity\n");
2279 if (e->priv.server->free)
2281 VM_Warning("setattachment: can not modify free entity\n");
2285 if (tagentity == NULL)
2286 tagentity = prog->edicts;
2288 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2290 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2292 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2295 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2297 modelindex = (int)tagentity->fields.server->modelindex;
2298 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2300 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2302 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);
2305 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));
2309 /////////////////////////////////////////
2310 // DP_MD3_TAGINFO extension coded by VorteX
2312 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2317 i = (int)e->fields.server->modelindex;
2318 if (i < 1 || i >= MAX_MODELS)
2320 model = sv.models[i];
2322 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2325 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2327 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2331 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);
2333 Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], -ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], scale * cl_viewmodel_scale.value);
2336 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2342 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2343 && (model = sv.models[(int)ent->fields.server->modelindex])
2344 && model->animscenes)
2346 // if model has wrong frame, engine automatically switches to model first frame
2347 frame = (int)ent->fields.server->frame;
2348 if (frame < 0 || frame >= model->numframes)
2350 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2352 *out = identitymatrix;
2356 // Warnings/errors code:
2357 // 0 - normal (everything all-right)
2360 // 3 - null or non-precached model
2361 // 4 - no tags with requested index
2362 // 5 - runaway loop at attachment chain
2363 extern cvar_t cl_bob;
2364 extern cvar_t cl_bobcycle;
2365 extern cvar_t cl_bobup;
2366 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2370 int modelindex, attachloop;
2371 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2374 *out = identitymatrix; // warnings and errors return identical matrix
2376 if (ent == prog->edicts)
2378 if (ent->priv.server->free)
2381 modelindex = (int)ent->fields.server->modelindex;
2382 if (modelindex <= 0 || modelindex > MAX_MODELS)
2385 model = sv.models[modelindex];
2387 tagmatrix = identitymatrix;
2388 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2392 if (attachloop >= 256) // prevent runaway looping
2394 // apply transformation by child's tagindex on parent entity and then
2395 // by parent entity itself
2396 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2397 if (ret && attachloop == 0)
2399 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2400 SV_GetEntityMatrix(ent, &entitymatrix, false);
2401 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2402 // next iteration we process the parent entity
2403 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2405 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2406 ent = PRVM_EDICT_NUM(val->edict);
2413 // RENDER_VIEWMODEL magic
2414 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2416 Matrix4x4_Copy(&tagmatrix, out);
2417 ent = PRVM_EDICT_NUM(val->edict);
2419 SV_GetEntityMatrix(ent, &entitymatrix, true);
2420 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2423 // Cl_bob, ported from rendering code
2424 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2427 // LordHavoc: this code is *weird*, but not replacable (I think it
2428 // should be done in QC on the server, but oh well, quake is quake)
2429 // LordHavoc: figured out bobup: the time at which the sin is at 180
2430 // degrees (which allows lengthening or squishing the peak or valley)
2431 cycle = sv.time/cl_bobcycle.value;
2432 cycle -= (int)cycle;
2433 if (cycle < cl_bobup.value)
2434 cycle = sin(M_PI * cycle / cl_bobup.value);
2436 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2437 // bob is proportional to velocity in the xy plane
2438 // (don't count Z, or jumping messes it up)
2439 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;
2440 bob = bob*0.3 + bob*0.7*cycle;
2441 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2448 //float(entity ent, string tagname) gettagindex;
2450 static void VM_SV_gettagindex (void)
2453 const char *tag_name;
2454 int modelindex, tag_index;
2456 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2458 ent = PRVM_G_EDICT(OFS_PARM0);
2459 tag_name = PRVM_G_STRING(OFS_PARM1);
2461 if (ent == prog->edicts)
2463 VM_Warning("gettagindex: can't affect world entity\n");
2466 if (ent->priv.server->free)
2468 VM_Warning("gettagindex: can't affect free entity\n");
2472 modelindex = (int)ent->fields.server->modelindex;
2474 if (modelindex <= 0 || modelindex > MAX_MODELS)
2475 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2478 tag_index = SV_GetTagIndex(ent, tag_name);
2480 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2482 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2485 //vector(entity ent, float tagindex) gettaginfo;
2486 static void VM_SV_gettaginfo (void)
2490 matrix4x4_t tag_matrix;
2493 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2495 e = PRVM_G_EDICT(OFS_PARM0);
2496 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2498 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2499 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2504 VM_Warning("gettagindex: can't affect world entity\n");
2507 VM_Warning("gettagindex: can't affect free entity\n");
2510 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2513 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2516 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2521 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2522 static void VM_SV_dropclient (void)
2525 client_t *oldhostclient;
2526 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2527 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2528 if (clientnum < 0 || clientnum >= svs.maxclients)
2530 VM_Warning("dropclient: not a client\n");
2533 if (!svs.clients[clientnum].active)
2535 VM_Warning("dropclient: that client slot is not connected\n");
2538 oldhostclient = host_client;
2539 host_client = svs.clients + clientnum;
2540 SV_DropClient(false);
2541 host_client = oldhostclient;
2544 //entity() spawnclient (DP_SV_BOTCLIENT)
2545 static void VM_SV_spawnclient (void)
2549 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2550 prog->xfunction->builtinsprofile += 2;
2552 for (i = 0;i < svs.maxclients;i++)
2554 if (!svs.clients[i].active)
2556 prog->xfunction->builtinsprofile += 100;
2557 SV_ConnectClient (i, NULL);
2558 // this has to be set or else ClientDisconnect won't be called
2559 // we assume the qc will call ClientConnect...
2560 svs.clients[i].clientconnectcalled = true;
2561 ed = PRVM_EDICT_NUM(i + 1);
2565 VM_RETURN_EDICT(ed);
2568 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2569 static void VM_SV_clienttype (void)
2572 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2573 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2574 if (clientnum < 0 || clientnum >= svs.maxclients)
2575 PRVM_G_FLOAT(OFS_RETURN) = 3;
2576 else if (!svs.clients[clientnum].active)
2577 PRVM_G_FLOAT(OFS_RETURN) = 0;
2578 else if (svs.clients[clientnum].netconnection)
2579 PRVM_G_FLOAT(OFS_RETURN) = 1;
2581 PRVM_G_FLOAT(OFS_RETURN) = 2;
2588 string(string key) serverkey
2591 void VM_SV_serverkey(void)
2593 char string[VM_STRINGTEMP_LENGTH];
2594 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2595 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2596 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2599 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2600 static void VM_SV_setmodelindex (void)
2605 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2607 e = PRVM_G_EDICT(OFS_PARM0);
2608 if (e == prog->edicts)
2610 VM_Warning("setmodelindex: can not modify world entity\n");
2613 if (e->priv.server->free)
2615 VM_Warning("setmodelindex: can not modify free entity\n");
2618 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2619 if (i <= 0 || i > MAX_MODELS)
2621 VM_Warning("setmodelindex: invalid modelindex\n");
2624 if (!sv.model_precache[i][0])
2626 VM_Warning("setmodelindex: model not precached\n");
2630 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2631 e->fields.server->modelindex = i;
2637 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2638 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2640 SetMinMaxSize (e, quakemins, quakemaxs, true);
2643 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2646 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2647 static void VM_SV_modelnameforindex (void)
2650 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2652 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2654 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2655 if (i <= 0 || i > MAX_MODELS)
2657 VM_Warning("modelnameforindex: invalid modelindex\n");
2660 if (!sv.model_precache[i][0])
2662 VM_Warning("modelnameforindex: model not precached\n");
2666 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2669 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2670 static void VM_SV_particleeffectnum (void)
2673 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2674 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2677 PRVM_G_FLOAT(OFS_RETURN) = i;
2680 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2681 static void VM_SV_trailparticles (void)
2683 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2685 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2686 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2687 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2688 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2689 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2690 SV_FlushBroadcastMessages();
2693 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2694 static void VM_SV_pointparticles (void)
2696 int effectnum, count;
2698 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2699 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2700 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2701 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2702 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2703 if (count == 1 && !VectorLength2(vel))
2706 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2707 MSG_WriteShort(&sv.datagram, effectnum);
2708 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2712 // 1+2+12+12+2=29 bytes
2713 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2714 MSG_WriteShort(&sv.datagram, effectnum);
2715 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2716 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2717 MSG_WriteShort(&sv.datagram, count);
2720 SV_FlushBroadcastMessages();
2723 prvm_builtin_t vm_sv_builtins[] = {
2724 NULL, // #0 NULL function (not callable) (QUAKE)
2725 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2726 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2727 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2728 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2729 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2730 VM_break, // #6 void() break (QUAKE)
2731 VM_random, // #7 float() random (QUAKE)
2732 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2733 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2734 VM_error, // #10 void(string e) error (QUAKE)
2735 VM_objerror, // #11 void(string e) objerror (QUAKE)
2736 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2737 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2738 VM_spawn, // #14 entity() spawn (QUAKE)
2739 VM_remove, // #15 void(entity e) remove (QUAKE)
2740 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2741 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2742 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2743 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2744 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2745 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2746 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2747 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2748 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2749 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2750 VM_ftos, // #26 string(float f) ftos (QUAKE)
2751 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2752 VM_coredump, // #28 void() coredump (QUAKE)
2753 VM_traceon, // #29 void() traceon (QUAKE)
2754 VM_traceoff, // #30 void() traceoff (QUAKE)
2755 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2756 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2757 NULL, // #33 (QUAKE)
2758 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2759 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2760 VM_rint, // #36 float(float v) rint (QUAKE)
2761 VM_floor, // #37 float(float v) floor (QUAKE)
2762 VM_ceil, // #38 float(float v) ceil (QUAKE)
2763 NULL, // #39 (QUAKE)
2764 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2765 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2766 NULL, // #42 (QUAKE)
2767 VM_fabs, // #43 float(float f) fabs (QUAKE)
2768 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2769 VM_cvar, // #45 float(string s) cvar (QUAKE)
2770 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2771 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2772 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2773 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2774 NULL, // #50 (QUAKE)
2775 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2776 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2777 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2778 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2779 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2780 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2781 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2782 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2783 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2784 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2785 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2786 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2787 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2788 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2789 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2790 NULL, // #66 (QUAKE)
2791 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2792 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2793 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2794 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2795 NULL, // #71 (QUAKE)
2796 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2797 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2798 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2799 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2800 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2801 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2802 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2803 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2804 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2805 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2806 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2807 NULL, // #83 (QUAKE)
2808 NULL, // #84 (QUAKE)
2809 NULL, // #85 (QUAKE)
2810 NULL, // #86 (QUAKE)
2811 NULL, // #87 (QUAKE)
2812 NULL, // #88 (QUAKE)
2813 NULL, // #89 (QUAKE)
2814 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2815 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2816 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2817 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2818 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2819 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2820 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2821 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2822 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2823 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2824 // FrikaC and Telejano range #100-#199
2835 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2836 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2837 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2838 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2839 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2840 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2841 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2842 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2843 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2844 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2925 // FTEQW range #200-#299
2944 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2947 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
2948 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2949 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2950 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
2951 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
2952 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
2953 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
2954 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2955 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
2956 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
2958 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3026 // CSQC range #300-#399
3027 NULL, // #300 void() clearscene (EXT_CSQC)
3028 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3029 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3030 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3031 NULL, // #304 void() renderscene (EXT_CSQC)
3032 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3033 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3034 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3035 NULL, // #308 void() R_EndPolygon
3037 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3038 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3042 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3043 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3044 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3045 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3046 NULL, // #319 void(string name) freepic (EXT_CSQC)
3047 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3048 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3049 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3050 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3051 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3052 NULL, // #325 void(void) drawresetcliparea
3057 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3058 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3059 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3060 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3061 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3062 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3063 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3064 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3065 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3066 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3067 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3068 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3069 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3070 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3071 NULL, // #344 vector() getmousepos (EXT_CSQC)
3072 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3073 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3074 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3075 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3076 NULL, // #349 float() isdemo (EXT_CSQC)
3077 VM_isserver, // #350 float() isserver (EXT_CSQC)
3078 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3079 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3080 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3081 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3087 NULL, // #360 float() readbyte (EXT_CSQC)
3088 NULL, // #361 float() readchar (EXT_CSQC)
3089 NULL, // #362 float() readshort (EXT_CSQC)
3090 NULL, // #363 float() readlong (EXT_CSQC)
3091 NULL, // #364 float() readcoord (EXT_CSQC)
3092 NULL, // #365 float() readangle (EXT_CSQC)
3093 NULL, // #366 string() readstring (EXT_CSQC)
3094 NULL, // #367 float() readfloat (EXT_CSQC)
3127 // LordHavoc's range #400-#499
3128 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3129 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3130 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3131 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3132 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3133 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3134 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3135 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3136 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)
3137 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3138 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3139 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3140 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3141 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3142 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3143 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3144 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3145 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3146 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3147 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3148 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3149 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3150 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3151 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3152 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3153 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3154 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3155 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3156 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3157 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3158 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3159 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3160 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3161 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3162 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3163 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3164 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3165 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3166 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3167 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3168 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3169 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3170 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3171 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3172 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3173 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3174 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3175 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3176 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3177 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3178 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3179 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3180 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3181 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3182 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3183 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3184 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3185 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3187 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3188 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3189 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3190 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3191 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3192 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3193 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3194 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3195 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3196 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3197 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3199 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3200 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3201 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3202 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3203 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3204 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3205 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3206 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3207 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3208 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3209 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3210 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3211 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3230 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3232 void VM_SV_Cmd_Init(void)
3237 void VM_SV_Cmd_Reset(void)