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);
411 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
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), false);
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);
1285 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1287 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1288 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1289 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1293 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1294 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1295 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1298 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1299 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1300 for (i=0 ; i<3 ; i++)
1302 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1303 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1306 // throw the entity away now
1310 //=============================================================================
1317 static void VM_SV_setspawnparms (void)
1323 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1325 ent = PRVM_G_EDICT(OFS_PARM0);
1326 i = PRVM_NUM_FOR_EDICT(ent);
1327 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1329 Con_Print("tried to setspawnparms on a non-client\n");
1333 // copy spawn parms out of the client_t
1334 client = svs.clients + i-1;
1335 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1336 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1343 Returns a color vector indicating the lighting at the requested point.
1345 (Internal Operation note: actually measures the light beneath the point, just like
1346 the model lighting on the client)
1351 static void VM_SV_getlight (void)
1353 vec3_t ambientcolor, diffusecolor, diffusenormal;
1355 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1356 p = PRVM_G_VECTOR(OFS_PARM0);
1357 VectorClear(ambientcolor);
1358 VectorClear(diffusecolor);
1359 VectorClear(diffusenormal);
1360 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1361 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1362 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1367 unsigned char type; // 1/2/8 or other value if isn't used
1371 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1372 static int vm_customstats_last;
1374 void VM_CustomStats_Clear (void)
1378 Z_Free(vm_customstats);
1379 vm_customstats = NULL;
1380 vm_customstats_last = -1;
1384 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1392 for(i=0; i<vm_customstats_last+1 ;i++)
1394 if(!vm_customstats[i].type)
1396 switch(vm_customstats[i].type)
1398 //string as 16 bytes
1401 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1402 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1403 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1404 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1405 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1407 //float field sent as-is
1409 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1411 //integer value of float field
1413 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1421 // void(float index, float type, .void field) SV_AddStat = #232;
1422 // Set up an auto-sent player stat.
1423 // Client's get thier own fields sent to them. Index may not be less than 32.
1424 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1425 // 1: string (4 stats carrying a total of 16 charactures)
1426 // 2: float (one stat, float converted to an integer for transportation)
1427 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1428 static void VM_SV_AddStat (void)
1433 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1437 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1440 VM_Warning("PF_SV_AddStat: not enough memory\n");
1444 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1445 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1446 off = PRVM_G_INT (OFS_PARM2);
1451 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1454 if(i >= (MAX_CL_STATS-32))
1456 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1459 if(i > (MAX_CL_STATS-32-4) && type == 1)
1461 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1464 vm_customstats[i].type = type;
1465 vm_customstats[i].fieldoffset = off;
1466 if(vm_customstats_last < i)
1467 vm_customstats_last = i;
1474 copies data from one entity to another
1476 copyentity(src, dst)
1479 static void VM_SV_copyentity (void)
1481 prvm_edict_t *in, *out;
1482 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1483 in = PRVM_G_EDICT(OFS_PARM0);
1484 if (in == prog->edicts)
1486 VM_Warning("copyentity: can not read world entity\n");
1489 if (in->priv.server->free)
1491 VM_Warning("copyentity: can not read free entity\n");
1494 out = PRVM_G_EDICT(OFS_PARM1);
1495 if (out == prog->edicts)
1497 VM_Warning("copyentity: can not modify world entity\n");
1500 if (out->priv.server->free)
1502 VM_Warning("copyentity: can not modify free entity\n");
1505 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1506 SV_LinkEdict(out, false);
1514 sets the color of a client and broadcasts the update to all connected clients
1516 setcolor(clientent, value)
1519 static void VM_SV_setcolor (void)
1525 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1526 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1527 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1529 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1531 Con_Print("tried to setcolor a non-client\n");
1535 client = svs.clients + entnum-1;
1538 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1540 client->edict->fields.server->team = (i & 15) + 1;
1543 if (client->old_colors != client->colors)
1545 client->old_colors = client->colors;
1546 // send notification to all clients
1547 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1548 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1549 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1557 effect(origin, modelname, startframe, framecount, framerate)
1560 static void VM_SV_effect (void)
1564 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1565 s = PRVM_G_STRING(OFS_PARM1);
1568 VM_Warning("effect: no model specified\n");
1572 i = SV_ModelIndex(s, 1);
1575 VM_Warning("effect: model not precached\n");
1579 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1581 VM_Warning("effect: framecount < 1\n");
1585 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1587 VM_Warning("effect: framerate < 1\n");
1591 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));
1594 static void VM_SV_te_blood (void)
1596 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1597 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1599 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1600 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1602 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1603 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1604 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1606 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1607 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1608 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1610 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1611 SV_FlushBroadcastMessages();
1614 static void VM_SV_te_bloodshower (void)
1616 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1617 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1619 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1620 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1622 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1623 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1624 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1626 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1627 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1628 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1630 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1632 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1633 SV_FlushBroadcastMessages();
1636 static void VM_SV_te_explosionrgb (void)
1638 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1639 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1640 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1642 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1643 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1644 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1646 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1647 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1648 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1649 SV_FlushBroadcastMessages();
1652 static void VM_SV_te_particlecube (void)
1654 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1655 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1657 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1658 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1660 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1661 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1662 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1664 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1665 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1666 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1668 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1672 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1674 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1675 // gravity true/false
1676 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1678 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1679 SV_FlushBroadcastMessages();
1682 static void VM_SV_te_particlerain (void)
1684 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1685 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1687 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1688 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1690 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1691 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1692 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1694 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1695 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1696 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1698 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1699 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1700 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1702 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1704 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1705 SV_FlushBroadcastMessages();
1708 static void VM_SV_te_particlesnow (void)
1710 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1711 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1713 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1714 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1716 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1717 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1718 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1720 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1721 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1722 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1724 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1725 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1726 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1728 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1730 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1731 SV_FlushBroadcastMessages();
1734 static void VM_SV_te_spark (void)
1736 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1737 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1739 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1740 MSG_WriteByte(&sv.datagram, TE_SPARK);
1742 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1743 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1744 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1746 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1747 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1748 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1750 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1751 SV_FlushBroadcastMessages();
1754 static void VM_SV_te_gunshotquad (void)
1756 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1757 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1758 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1760 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1761 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1762 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1763 SV_FlushBroadcastMessages();
1766 static void VM_SV_te_spikequad (void)
1768 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1769 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1770 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1772 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1773 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1774 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1775 SV_FlushBroadcastMessages();
1778 static void VM_SV_te_superspikequad (void)
1780 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1781 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1782 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1784 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1785 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1786 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1787 SV_FlushBroadcastMessages();
1790 static void VM_SV_te_explosionquad (void)
1792 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1793 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1794 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1796 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1797 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1798 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1799 SV_FlushBroadcastMessages();
1802 static void VM_SV_te_smallflash (void)
1804 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1805 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1806 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1808 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1809 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1810 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1811 SV_FlushBroadcastMessages();
1814 static void VM_SV_te_customflash (void)
1816 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1817 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1819 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1820 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1822 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1823 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1824 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1826 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1828 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1830 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1831 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1832 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1833 SV_FlushBroadcastMessages();
1836 static void VM_SV_te_gunshot (void)
1838 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1839 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1840 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1842 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1843 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1844 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1845 SV_FlushBroadcastMessages();
1848 static void VM_SV_te_spike (void)
1850 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1851 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1852 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1854 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1855 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1856 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1857 SV_FlushBroadcastMessages();
1860 static void VM_SV_te_superspike (void)
1862 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1863 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1864 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1866 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1867 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1869 SV_FlushBroadcastMessages();
1872 static void VM_SV_te_explosion (void)
1874 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1875 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1876 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1878 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1879 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1880 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1881 SV_FlushBroadcastMessages();
1884 static void VM_SV_te_tarexplosion (void)
1886 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1887 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1888 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1890 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1891 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1892 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1893 SV_FlushBroadcastMessages();
1896 static void VM_SV_te_wizspike (void)
1898 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1899 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1900 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1902 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1903 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1904 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1905 SV_FlushBroadcastMessages();
1908 static void VM_SV_te_knightspike (void)
1910 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1911 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1912 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1914 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1915 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1916 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1917 SV_FlushBroadcastMessages();
1920 static void VM_SV_te_lavasplash (void)
1922 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1923 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1924 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1926 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1927 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1928 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1929 SV_FlushBroadcastMessages();
1932 static void VM_SV_te_teleport (void)
1934 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1935 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1936 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1938 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1939 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1940 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1941 SV_FlushBroadcastMessages();
1944 static void VM_SV_te_explosion2 (void)
1946 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1947 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1948 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1950 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1951 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1952 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1954 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1955 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1956 SV_FlushBroadcastMessages();
1959 static void VM_SV_te_lightning1 (void)
1961 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1962 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1963 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1965 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1967 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1968 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1969 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1974 SV_FlushBroadcastMessages();
1977 static void VM_SV_te_lightning2 (void)
1979 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1980 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1981 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1983 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1985 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1986 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1987 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1989 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1990 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1991 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1992 SV_FlushBroadcastMessages();
1995 static void VM_SV_te_lightning3 (void)
1997 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1998 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1999 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2001 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2003 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2004 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2005 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2007 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2008 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2009 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2010 SV_FlushBroadcastMessages();
2013 static void VM_SV_te_beam (void)
2015 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2016 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2017 MSG_WriteByte(&sv.datagram, TE_BEAM);
2019 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2021 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2022 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2023 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2025 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2026 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2027 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2028 SV_FlushBroadcastMessages();
2031 static void VM_SV_te_plasmaburn (void)
2033 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2034 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2035 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2036 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2037 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2038 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2039 SV_FlushBroadcastMessages();
2042 static void VM_SV_te_flamejet (void)
2044 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2045 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2046 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2048 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2049 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2050 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2052 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2053 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2054 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2056 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2057 SV_FlushBroadcastMessages();
2060 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2063 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2065 bestdist = 1000000000;
2067 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2069 // clip original point to each triangle of the surface and find the
2070 // triangle that is closest
2071 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2072 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2073 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2074 TriangleNormal(v[0], v[1], v[2], facenormal);
2075 VectorNormalize(facenormal);
2076 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2077 VectorMA(p, offsetdist, facenormal, temp);
2078 for (j = 0, k = 2;j < 3;k = j, j++)
2080 VectorSubtract(v[k], v[j], edgenormal);
2081 CrossProduct(edgenormal, facenormal, sidenormal);
2082 VectorNormalize(sidenormal);
2083 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2085 VectorMA(temp, offsetdist, sidenormal, temp);
2087 dist = VectorDistance2(temp, p);
2088 if (bestdist > dist)
2091 VectorCopy(temp, out);
2096 static model_t *getmodel(prvm_edict_t *ed)
2099 if (!ed || ed->priv.server->free)
2101 modelindex = (int)ed->fields.server->modelindex;
2102 if (modelindex < 1 || modelindex >= MAX_MODELS)
2104 return sv.models[modelindex];
2107 static msurface_t *getsurface(model_t *model, int surfacenum)
2109 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2111 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2115 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2116 static void VM_SV_getsurfacenumpoints(void)
2119 msurface_t *surface;
2120 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2121 // return 0 if no such surface
2122 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2124 PRVM_G_FLOAT(OFS_RETURN) = 0;
2128 // note: this (incorrectly) assumes it is a simple polygon
2129 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2131 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2132 static void VM_SV_getsurfacepoint(void)
2136 msurface_t *surface;
2138 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2139 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2140 ed = PRVM_G_EDICT(OFS_PARM0);
2141 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2143 // note: this (incorrectly) assumes it is a simple polygon
2144 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2145 if (pointnum < 0 || pointnum >= surface->num_vertices)
2147 // FIXME: implement rotation/scaling
2148 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2150 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2151 static void VM_SV_getsurfacenormal(void)
2154 msurface_t *surface;
2156 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2157 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2158 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2160 // FIXME: implement rotation/scaling
2161 // note: this (incorrectly) assumes it is a simple polygon
2162 // note: this only returns the first triangle, so it doesn't work very
2163 // well for curved surfaces or arbitrary meshes
2164 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);
2165 VectorNormalize(normal);
2166 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2168 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2169 static void VM_SV_getsurfacetexture(void)
2172 msurface_t *surface;
2173 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2174 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2175 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2177 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2179 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2180 static void VM_SV_getsurfacenearpoint(void)
2182 int surfacenum, best;
2184 vec_t dist, bestdist;
2187 msurface_t *surface;
2189 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2190 PRVM_G_FLOAT(OFS_RETURN) = -1;
2191 ed = PRVM_G_EDICT(OFS_PARM0);
2192 point = PRVM_G_VECTOR(OFS_PARM1);
2194 if (!ed || ed->priv.server->free)
2196 model = getmodel(ed);
2197 if (!model || !model->num_surfaces)
2200 // FIXME: implement rotation/scaling
2201 VectorSubtract(point, ed->fields.server->origin, p);
2203 bestdist = 1000000000;
2204 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2206 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2207 // first see if the nearest point on the surface's box is closer than the previous match
2208 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2209 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2210 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2211 dist = VectorLength2(clipped);
2212 if (dist < bestdist)
2214 // it is, check the nearest point on the actual geometry
2215 clippointtosurface(model, surface, p, clipped);
2216 VectorSubtract(clipped, p, clipped);
2217 dist += VectorLength2(clipped);
2218 if (dist < bestdist)
2220 // that's closer too, store it as the best match
2226 PRVM_G_FLOAT(OFS_RETURN) = best;
2228 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2229 static void VM_SV_getsurfaceclippedpoint(void)
2233 msurface_t *surface;
2235 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2236 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2237 ed = PRVM_G_EDICT(OFS_PARM0);
2238 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2240 // FIXME: implement rotation/scaling
2241 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2242 clippointtosurface(model, surface, p, out);
2243 // FIXME: implement rotation/scaling
2244 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2247 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2248 //this function originally written by KrimZon, made shorter by LordHavoc
2249 static void VM_SV_clientcommand (void)
2251 client_t *temp_client;
2253 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2255 //find client for this entity
2256 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2257 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2259 Con_Print("PF_clientcommand: entity is not a client\n");
2263 temp_client = host_client;
2264 host_client = svs.clients + i;
2265 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2266 host_client = temp_client;
2269 //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)
2270 static void VM_SV_setattachment (void)
2272 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2273 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2274 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2278 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2280 if (e == prog->edicts)
2282 VM_Warning("setattachment: can not modify world entity\n");
2285 if (e->priv.server->free)
2287 VM_Warning("setattachment: can not modify free entity\n");
2291 if (tagentity == NULL)
2292 tagentity = prog->edicts;
2294 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2296 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2298 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2301 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2303 modelindex = (int)tagentity->fields.server->modelindex;
2304 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2306 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2308 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);
2311 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));
2315 /////////////////////////////////////////
2316 // DP_MD3_TAGINFO extension coded by VorteX
2318 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2323 i = (int)e->fields.server->modelindex;
2324 if (i < 1 || i >= MAX_MODELS)
2326 model = sv.models[i];
2328 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2331 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2333 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2337 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);
2339 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);
2342 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2348 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2349 && (model = sv.models[(int)ent->fields.server->modelindex])
2350 && model->animscenes)
2352 // if model has wrong frame, engine automatically switches to model first frame
2353 frame = (int)ent->fields.server->frame;
2354 if (frame < 0 || frame >= model->numframes)
2356 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2358 *out = identitymatrix;
2362 // Warnings/errors code:
2363 // 0 - normal (everything all-right)
2366 // 3 - null or non-precached model
2367 // 4 - no tags with requested index
2368 // 5 - runaway loop at attachment chain
2369 extern cvar_t cl_bob;
2370 extern cvar_t cl_bobcycle;
2371 extern cvar_t cl_bobup;
2372 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2376 int modelindex, attachloop;
2377 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2380 *out = identitymatrix; // warnings and errors return identical matrix
2382 if (ent == prog->edicts)
2384 if (ent->priv.server->free)
2387 modelindex = (int)ent->fields.server->modelindex;
2388 if (modelindex <= 0 || modelindex > MAX_MODELS)
2391 model = sv.models[modelindex];
2393 tagmatrix = identitymatrix;
2394 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2398 if (attachloop >= 256) // prevent runaway looping
2400 // apply transformation by child's tagindex on parent entity and then
2401 // by parent entity itself
2402 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2403 if (ret && attachloop == 0)
2405 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2406 SV_GetEntityMatrix(ent, &entitymatrix, false);
2407 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2408 // next iteration we process the parent entity
2409 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2411 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2412 ent = PRVM_EDICT_NUM(val->edict);
2419 // RENDER_VIEWMODEL magic
2420 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2422 Matrix4x4_Copy(&tagmatrix, out);
2423 ent = PRVM_EDICT_NUM(val->edict);
2425 SV_GetEntityMatrix(ent, &entitymatrix, true);
2426 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2429 // Cl_bob, ported from rendering code
2430 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2433 // LordHavoc: this code is *weird*, but not replacable (I think it
2434 // should be done in QC on the server, but oh well, quake is quake)
2435 // LordHavoc: figured out bobup: the time at which the sin is at 180
2436 // degrees (which allows lengthening or squishing the peak or valley)
2437 cycle = sv.time/cl_bobcycle.value;
2438 cycle -= (int)cycle;
2439 if (cycle < cl_bobup.value)
2440 cycle = sin(M_PI * cycle / cl_bobup.value);
2442 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2443 // bob is proportional to velocity in the xy plane
2444 // (don't count Z, or jumping messes it up)
2445 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;
2446 bob = bob*0.3 + bob*0.7*cycle;
2447 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2454 //float(entity ent, string tagname) gettagindex;
2456 static void VM_SV_gettagindex (void)
2459 const char *tag_name;
2460 int modelindex, tag_index;
2462 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2464 ent = PRVM_G_EDICT(OFS_PARM0);
2465 tag_name = PRVM_G_STRING(OFS_PARM1);
2467 if (ent == prog->edicts)
2469 VM_Warning("gettagindex: can't affect world entity\n");
2472 if (ent->priv.server->free)
2474 VM_Warning("gettagindex: can't affect free entity\n");
2478 modelindex = (int)ent->fields.server->modelindex;
2480 if (modelindex <= 0 || modelindex > MAX_MODELS)
2481 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2484 tag_index = SV_GetTagIndex(ent, tag_name);
2486 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2488 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2491 //vector(entity ent, float tagindex) gettaginfo;
2492 static void VM_SV_gettaginfo (void)
2496 matrix4x4_t tag_matrix;
2499 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2501 e = PRVM_G_EDICT(OFS_PARM0);
2502 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2504 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2505 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2510 VM_Warning("gettagindex: can't affect world entity\n");
2513 VM_Warning("gettagindex: can't affect free entity\n");
2516 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2519 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2522 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2527 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2528 static void VM_SV_dropclient (void)
2531 client_t *oldhostclient;
2532 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2533 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2534 if (clientnum < 0 || clientnum >= svs.maxclients)
2536 VM_Warning("dropclient: not a client\n");
2539 if (!svs.clients[clientnum].active)
2541 VM_Warning("dropclient: that client slot is not connected\n");
2544 oldhostclient = host_client;
2545 host_client = svs.clients + clientnum;
2546 SV_DropClient(false);
2547 host_client = oldhostclient;
2550 //entity() spawnclient (DP_SV_BOTCLIENT)
2551 static void VM_SV_spawnclient (void)
2555 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2556 prog->xfunction->builtinsprofile += 2;
2558 for (i = 0;i < svs.maxclients;i++)
2560 if (!svs.clients[i].active)
2562 prog->xfunction->builtinsprofile += 100;
2563 SV_ConnectClient (i, NULL);
2564 // this has to be set or else ClientDisconnect won't be called
2565 // we assume the qc will call ClientConnect...
2566 svs.clients[i].clientconnectcalled = true;
2567 ed = PRVM_EDICT_NUM(i + 1);
2571 VM_RETURN_EDICT(ed);
2574 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2575 static void VM_SV_clienttype (void)
2578 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2579 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2580 if (clientnum < 0 || clientnum >= svs.maxclients)
2581 PRVM_G_FLOAT(OFS_RETURN) = 3;
2582 else if (!svs.clients[clientnum].active)
2583 PRVM_G_FLOAT(OFS_RETURN) = 0;
2584 else if (svs.clients[clientnum].netconnection)
2585 PRVM_G_FLOAT(OFS_RETURN) = 1;
2587 PRVM_G_FLOAT(OFS_RETURN) = 2;
2594 string(string key) serverkey
2597 void VM_SV_serverkey(void)
2599 char string[VM_STRINGTEMP_LENGTH];
2600 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2601 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2602 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2605 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2606 static void VM_SV_setmodelindex (void)
2611 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2613 e = PRVM_G_EDICT(OFS_PARM0);
2614 if (e == prog->edicts)
2616 VM_Warning("setmodelindex: can not modify world entity\n");
2619 if (e->priv.server->free)
2621 VM_Warning("setmodelindex: can not modify free entity\n");
2624 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2625 if (i <= 0 || i > MAX_MODELS)
2627 VM_Warning("setmodelindex: invalid modelindex\n");
2630 if (!sv.model_precache[i][0])
2632 VM_Warning("setmodelindex: model not precached\n");
2636 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2637 e->fields.server->modelindex = i;
2643 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2644 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2646 SetMinMaxSize (e, quakemins, quakemaxs, true);
2649 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2652 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2653 static void VM_SV_modelnameforindex (void)
2656 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2658 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2660 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2661 if (i <= 0 || i > MAX_MODELS)
2663 VM_Warning("modelnameforindex: invalid modelindex\n");
2666 if (!sv.model_precache[i][0])
2668 VM_Warning("modelnameforindex: model not precached\n");
2672 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2675 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2676 static void VM_SV_particleeffectnum (void)
2679 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2680 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2683 PRVM_G_FLOAT(OFS_RETURN) = i;
2686 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2687 static void VM_SV_trailparticles (void)
2689 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2691 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2692 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2693 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2694 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2695 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2696 SV_FlushBroadcastMessages();
2699 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2700 static void VM_SV_pointparticles (void)
2702 int effectnum, count;
2704 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2705 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2706 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2707 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2708 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2709 if (count == 1 && !VectorLength2(vel))
2712 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2713 MSG_WriteShort(&sv.datagram, effectnum);
2714 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2718 // 1+2+12+12+2=29 bytes
2719 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2720 MSG_WriteShort(&sv.datagram, effectnum);
2721 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2722 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2723 MSG_WriteShort(&sv.datagram, count);
2726 SV_FlushBroadcastMessages();
2729 prvm_builtin_t vm_sv_builtins[] = {
2730 NULL, // #0 NULL function (not callable) (QUAKE)
2731 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2732 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2733 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2734 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2735 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2736 VM_break, // #6 void() break (QUAKE)
2737 VM_random, // #7 float() random (QUAKE)
2738 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2739 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2740 VM_error, // #10 void(string e) error (QUAKE)
2741 VM_objerror, // #11 void(string e) objerror (QUAKE)
2742 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2743 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2744 VM_spawn, // #14 entity() spawn (QUAKE)
2745 VM_remove, // #15 void(entity e) remove (QUAKE)
2746 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2747 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2748 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2749 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2750 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2751 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2752 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2753 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2754 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2755 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2756 VM_ftos, // #26 string(float f) ftos (QUAKE)
2757 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2758 VM_coredump, // #28 void() coredump (QUAKE)
2759 VM_traceon, // #29 void() traceon (QUAKE)
2760 VM_traceoff, // #30 void() traceoff (QUAKE)
2761 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2762 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2763 NULL, // #33 (QUAKE)
2764 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2765 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2766 VM_rint, // #36 float(float v) rint (QUAKE)
2767 VM_floor, // #37 float(float v) floor (QUAKE)
2768 VM_ceil, // #38 float(float v) ceil (QUAKE)
2769 NULL, // #39 (QUAKE)
2770 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2771 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2772 NULL, // #42 (QUAKE)
2773 VM_fabs, // #43 float(float f) fabs (QUAKE)
2774 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2775 VM_cvar, // #45 float(string s) cvar (QUAKE)
2776 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2777 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2778 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2779 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2780 NULL, // #50 (QUAKE)
2781 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2782 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2783 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2784 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2785 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2786 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2787 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2788 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2789 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2790 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2791 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2792 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2793 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2794 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2795 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2796 NULL, // #66 (QUAKE)
2797 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2798 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2799 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2800 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2801 NULL, // #71 (QUAKE)
2802 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2803 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2804 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2805 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2806 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2807 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2808 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2809 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2810 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2811 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2812 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2813 NULL, // #83 (QUAKE)
2814 NULL, // #84 (QUAKE)
2815 NULL, // #85 (QUAKE)
2816 NULL, // #86 (QUAKE)
2817 NULL, // #87 (QUAKE)
2818 NULL, // #88 (QUAKE)
2819 NULL, // #89 (QUAKE)
2820 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2821 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2822 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2823 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2824 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2825 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2826 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2827 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2828 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2829 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2830 // FrikaC and Telejano range #100-#199
2841 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2842 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2843 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2844 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2845 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2846 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2847 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2848 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2849 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2850 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2931 // FTEQW range #200-#299
2950 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2953 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
2954 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2955 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2956 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
2957 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
2958 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
2959 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
2960 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2961 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
2962 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
2964 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3032 // CSQC range #300-#399
3033 NULL, // #300 void() clearscene (EXT_CSQC)
3034 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3035 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3036 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3037 NULL, // #304 void() renderscene (EXT_CSQC)
3038 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3039 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3040 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3041 NULL, // #308 void() R_EndPolygon
3043 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3044 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3048 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3049 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3050 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3051 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3052 NULL, // #319 void(string name) freepic (EXT_CSQC)
3053 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3054 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3055 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3056 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3057 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3058 NULL, // #325 void(void) drawresetcliparea
3063 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3064 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3065 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3066 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3067 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3068 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3069 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3070 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3071 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3072 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3073 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3074 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3075 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3076 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3077 NULL, // #344 vector() getmousepos (EXT_CSQC)
3078 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3079 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3080 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3081 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3082 NULL, // #349 float() isdemo (EXT_CSQC)
3083 VM_isserver, // #350 float() isserver (EXT_CSQC)
3084 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3085 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3086 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3087 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3093 NULL, // #360 float() readbyte (EXT_CSQC)
3094 NULL, // #361 float() readchar (EXT_CSQC)
3095 NULL, // #362 float() readshort (EXT_CSQC)
3096 NULL, // #363 float() readlong (EXT_CSQC)
3097 NULL, // #364 float() readcoord (EXT_CSQC)
3098 NULL, // #365 float() readangle (EXT_CSQC)
3099 NULL, // #366 string() readstring (EXT_CSQC)
3100 NULL, // #367 float() readfloat (EXT_CSQC)
3133 // LordHavoc's range #400-#499
3134 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3135 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3136 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3137 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3138 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3139 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3140 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3141 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3142 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)
3143 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3144 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3145 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3146 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3147 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3148 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3149 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3150 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3151 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3152 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3153 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3154 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3155 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3156 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3157 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3158 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3159 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3160 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3161 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3162 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3163 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3164 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3165 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3166 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3167 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3168 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3169 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3170 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3171 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3172 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3173 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3174 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3175 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3176 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3177 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3178 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3179 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3180 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3181 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3182 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3183 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3184 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3185 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3186 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3187 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3188 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3189 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3190 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3191 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3193 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3194 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3195 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3196 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3197 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3198 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3199 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3200 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3201 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3202 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3203 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3205 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3206 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3207 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3208 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3209 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3210 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3211 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3212 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3213 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3214 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3215 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3216 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3217 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3236 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3238 void VM_SV_Cmd_Init(void)
3243 void VM_SV_Cmd_Reset(void)