3 //============================================================================
6 cvar_t sv_aim = {CVAR_SAVE, "sv_aim", "2", "maximum cosine angle for quake's vertical autoaim, a value above 1 completely disables the autoaim, quake used 0.93"}; //"0.93"}; // LordHavoc: disabled autoaim by default
9 char *vm_sv_extensions =
14 "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 "
58 "DP_QC_FINDCHAINFLAGS "
59 "DP_QC_FINDCHAINFLOAT "
67 "DP_QC_MULTIPLETEMPSTRINGS "
69 "DP_QC_SINCOSSQRTPOW "
71 "DP_QC_STRINGBUFFERS "
72 "DP_QC_STRINGCOLORFUNCTIONS "
75 "DP_QC_TRACE_MOVETYPE_HITMODEL "
76 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
77 "DP_QC_UNLIMITEDTEMPSTRINGS "
78 "DP_QC_VECTORVECTORS "
84 "DP_SND_DIRECTIONLESSATTNNONE "
93 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
94 "DP_SV_DRAWONLYTOCLIENT "
97 "DP_SV_ENTITYCONTENTSTRANSITION "
98 "DP_SV_NODRAWTOCLIENT "
100 "DP_SV_PLAYERPHYSICS "
101 "DP_SV_PRECACHEANYTIME "
104 "DP_SV_ROTATINGBMODEL "
107 "DP_SV_WRITEUNTERMINATEDSTRING "
111 "DP_TE_EXPLOSIONRGB "
113 "DP_TE_PARTICLECUBE "
114 "DP_TE_PARTICLERAIN "
115 "DP_TE_PARTICLESNOW "
117 "DP_TE_QUADEFFECTS1 "
120 "DP_TE_STANDARDEFFECTBUILTINS "
121 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
124 //"EXT_CSQC " // not ready yet
126 "KRIMZON_SV_PARSECLIENTCOMMAND "
129 "NEXUIZ_PLAYERMODEL "
131 "PRYDON_CLIENTCURSOR "
132 "TENEBRAE_GFX_DLIGHTS "
140 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.
142 setorigin (entity, origin)
145 static void VM_SV_setorigin (void)
150 VM_SAFEPARMCOUNT(2, VM_setorigin);
152 e = PRVM_G_EDICT(OFS_PARM0);
153 if (e == prog->edicts)
155 VM_Warning("setorigin: can not modify world entity\n");
158 if (e->priv.server->free)
160 VM_Warning("setorigin: can not modify free entity\n");
163 org = PRVM_G_VECTOR(OFS_PARM1);
164 VectorCopy (org, e->fields.server->origin);
165 SV_LinkEdict (e, false);
169 void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
173 for (i=0 ; i<3 ; i++)
175 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
177 // set derived values
178 VectorCopy (min, e->fields.server->mins);
179 VectorCopy (max, e->fields.server->maxs);
180 VectorSubtract (max, min, e->fields.server->size);
182 SV_LinkEdict (e, false);
189 the size box is rotated by the current angle
190 LordHavoc: no it isn't...
192 setsize (entity, minvector, maxvector)
195 static void VM_SV_setsize (void)
200 VM_SAFEPARMCOUNT(3, VM_setsize);
202 e = PRVM_G_EDICT(OFS_PARM0);
203 if (e == prog->edicts)
205 VM_Warning("setsize: can not modify world entity\n");
208 if (e->priv.server->free)
210 VM_Warning("setsize: can not modify free entity\n");
213 min = PRVM_G_VECTOR(OFS_PARM1);
214 max = PRVM_G_VECTOR(OFS_PARM2);
215 SetMinMaxSize (e, min, max, false);
223 setmodel(entity, model)
226 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
227 static void VM_SV_setmodel (void)
233 VM_SAFEPARMCOUNT(2, VM_setmodel);
235 e = PRVM_G_EDICT(OFS_PARM0);
236 if (e == prog->edicts)
238 VM_Warning("setmodel: can not modify world entity\n");
241 if (e->priv.server->free)
243 VM_Warning("setmodel: can not modify free entity\n");
246 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
247 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
248 e->fields.server->modelindex = i;
254 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
255 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
257 SetMinMaxSize (e, quakemins, quakemaxs, true);
260 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
267 single print to a specific client
269 sprint(clientent, value)
272 static void VM_SV_sprint (void)
276 char string[VM_STRINGTEMP_LENGTH];
278 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
280 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
282 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
284 VM_Warning("tried to centerprint to a non-client\n");
288 client = svs.clients + entnum-1;
289 if (!client->netconnection)
292 VM_VarString(1, string, sizeof(string));
293 MSG_WriteChar(&client->netconnection->message,svc_print);
294 MSG_WriteString(&client->netconnection->message, string);
302 single print to a specific client
304 centerprint(clientent, value)
307 static void VM_SV_centerprint (void)
311 char string[VM_STRINGTEMP_LENGTH];
313 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
315 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
317 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
319 VM_Warning("tried to centerprint to a non-client\n");
323 client = svs.clients + entnum-1;
324 if (!client->netconnection)
327 VM_VarString(1, string, sizeof(string));
328 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
329 MSG_WriteString(&client->netconnection->message, string);
336 particle(origin, color, count)
339 static void VM_SV_particle (void)
345 VM_SAFEPARMCOUNT(4, VM_SV_particle);
347 org = PRVM_G_VECTOR(OFS_PARM0);
348 dir = PRVM_G_VECTOR(OFS_PARM1);
349 color = PRVM_G_FLOAT(OFS_PARM2);
350 count = PRVM_G_FLOAT(OFS_PARM3);
351 SV_StartParticle (org, dir, (int)color, (int)count);
361 static void VM_SV_ambientsound (void)
365 float vol, attenuation;
368 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
370 pos = PRVM_G_VECTOR (OFS_PARM0);
371 samp = PRVM_G_STRING(OFS_PARM1);
372 vol = PRVM_G_FLOAT(OFS_PARM2);
373 attenuation = PRVM_G_FLOAT(OFS_PARM3);
375 // check to see if samp was properly precached
376 soundnum = SV_SoundIndex(samp, 1);
384 // add an svc_spawnambient command to the level signon packet
387 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
389 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
391 MSG_WriteVector(&sv.signon, pos, sv.protocol);
394 MSG_WriteShort (&sv.signon, soundnum);
396 MSG_WriteByte (&sv.signon, soundnum);
398 MSG_WriteByte (&sv.signon, (int)(vol*255));
399 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
407 Each entity can have eight independant sound sources, like voice,
410 Channel 0 is an auto-allocate channel, the others override anything
411 already running on that entity/channel pair.
413 An attenuation of 0 will play full volume everywhere in the level.
414 Larger attenuations will drop off.
418 static void VM_SV_sound (void)
422 prvm_edict_t *entity;
426 VM_SAFEPARMCOUNT(5, VM_SV_sound);
428 entity = PRVM_G_EDICT(OFS_PARM0);
429 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
430 sample = PRVM_G_STRING(OFS_PARM2);
431 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
432 attenuation = PRVM_G_FLOAT(OFS_PARM4);
434 if (volume < 0 || volume > 255)
436 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
440 if (attenuation < 0 || attenuation > 4)
442 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
446 if (channel < 0 || channel > 7)
448 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
452 SV_StartSound (entity, channel, sample, volume, attenuation);
459 Used for use tracing and shot targeting
460 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
461 if the tryents flag is set.
463 traceline (vector1, vector2, movetype, ignore)
466 static void VM_SV_traceline (void)
473 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
475 prog->xfunction->builtinsprofile += 30;
477 v1 = PRVM_G_VECTOR(OFS_PARM0);
478 v2 = PRVM_G_VECTOR(OFS_PARM1);
479 move = (int)PRVM_G_FLOAT(OFS_PARM2);
480 ent = PRVM_G_EDICT(OFS_PARM3);
482 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]))
483 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));
485 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
487 VM_SetTraceGlobals(&trace);
495 Used for use tracing and shot targeting
496 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
497 if the tryents flag is set.
499 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
502 // LordHavoc: added this for my own use, VERY useful, similar to traceline
503 static void VM_SV_tracebox (void)
505 float *v1, *v2, *m1, *m2;
510 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
512 prog->xfunction->builtinsprofile += 30;
514 v1 = PRVM_G_VECTOR(OFS_PARM0);
515 m1 = PRVM_G_VECTOR(OFS_PARM1);
516 m2 = PRVM_G_VECTOR(OFS_PARM2);
517 v2 = PRVM_G_VECTOR(OFS_PARM3);
518 move = (int)PRVM_G_FLOAT(OFS_PARM4);
519 ent = PRVM_G_EDICT(OFS_PARM5);
521 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]))
522 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));
524 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
526 VM_SetTraceGlobals(&trace);
529 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
534 vec3_t original_origin;
535 vec3_t original_velocity;
536 vec3_t original_angles;
537 vec3_t original_avelocity;
541 VectorCopy(tossent->fields.server->origin , original_origin );
542 VectorCopy(tossent->fields.server->velocity , original_velocity );
543 VectorCopy(tossent->fields.server->angles , original_angles );
544 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
546 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
547 if (val != NULL && val->_float != 0)
548 gravity = val->_float;
551 gravity *= sv_gravity.value * 0.05;
553 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
555 SV_CheckVelocity (tossent);
556 tossent->fields.server->velocity[2] -= gravity;
557 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
558 VectorScale (tossent->fields.server->velocity, 0.05, move);
559 VectorAdd (tossent->fields.server->origin, move, end);
560 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
561 VectorCopy (trace.endpos, tossent->fields.server->origin);
563 if (trace.fraction < 1)
567 VectorCopy(original_origin , tossent->fields.server->origin );
568 VectorCopy(original_velocity , tossent->fields.server->velocity );
569 VectorCopy(original_angles , tossent->fields.server->angles );
570 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
575 static void VM_SV_tracetoss (void)
579 prvm_edict_t *ignore;
581 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
583 prog->xfunction->builtinsprofile += 600;
585 ent = PRVM_G_EDICT(OFS_PARM0);
586 if (ent == prog->edicts)
588 VM_Warning("tracetoss: can not use world entity\n");
591 ignore = PRVM_G_EDICT(OFS_PARM1);
593 trace = SV_Trace_Toss (ent, ignore);
595 VM_SetTraceGlobals(&trace);
598 //============================================================================
600 static int checkpvsbytes;
601 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
603 static int VM_SV_newcheckclient (int check)
609 // cycle to the next one
611 check = bound(1, check, svs.maxclients);
612 if (check == svs.maxclients)
620 prog->xfunction->builtinsprofile++;
622 if (i == svs.maxclients+1)
624 // look up the client's edict
625 ent = PRVM_EDICT_NUM(i);
626 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
627 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
629 // found a valid client (possibly the same one again)
633 // get the PVS for the entity
634 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
636 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
637 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
646 Returns a client (or object that has a client enemy) that would be a
649 If there is more than one valid option, they are cycled each frame
651 If (self.origin + self.viewofs) is not in the PVS of the current target,
652 it is not returned at all.
657 int c_invis, c_notvis;
658 static void VM_SV_checkclient (void)
660 prvm_edict_t *ent, *self;
663 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
665 // find a new check if on a new frame
666 if (sv.time - sv.lastchecktime >= 0.1)
668 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
669 sv.lastchecktime = sv.time;
672 // return check if it might be visible
673 ent = PRVM_EDICT_NUM(sv.lastcheck);
674 if (ent->priv.server->free || ent->fields.server->health <= 0)
676 VM_RETURN_EDICT(prog->edicts);
680 // if current entity can't possibly see the check entity, return 0
681 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
682 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
683 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
686 VM_RETURN_EDICT(prog->edicts);
690 // might be able to see it
692 VM_RETURN_EDICT(ent);
695 //============================================================================
702 Sends text over to the client's execution buffer
704 stuffcmd (clientent, value, ...)
707 static void VM_SV_stuffcmd (void)
711 char string[VM_STRINGTEMP_LENGTH];
713 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
715 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
716 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
718 VM_Warning("Can't stuffcmd to a non-client\n");
722 VM_VarString(1, string, sizeof(string));
725 host_client = svs.clients + entnum-1;
726 Host_ClientCommands ("%s", string);
734 Returns a chain of entities that have origins within a spherical area
736 findradius (origin, radius)
739 static void VM_SV_findradius (void)
741 prvm_edict_t *ent, *chain;
742 vec_t radius, radius2;
743 vec3_t org, eorg, mins, maxs;
746 prvm_edict_t *touchedicts[MAX_EDICTS];
748 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
750 chain = (prvm_edict_t *)prog->edicts;
752 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
753 radius = PRVM_G_FLOAT(OFS_PARM1);
754 radius2 = radius * radius;
756 mins[0] = org[0] - (radius + 1);
757 mins[1] = org[1] - (radius + 1);
758 mins[2] = org[2] - (radius + 1);
759 maxs[0] = org[0] + (radius + 1);
760 maxs[1] = org[1] + (radius + 1);
761 maxs[2] = org[2] + (radius + 1);
762 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
763 if (numtouchedicts > MAX_EDICTS)
765 // this never happens
766 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
767 numtouchedicts = MAX_EDICTS;
769 for (i = 0;i < numtouchedicts;i++)
771 ent = touchedicts[i];
772 prog->xfunction->builtinsprofile++;
773 // Quake did not return non-solid entities but darkplaces does
774 // (note: this is the reason you can't blow up fallen zombies)
775 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
777 // LordHavoc: compare against bounding box rather than center so it
778 // doesn't miss large objects, and use DotProduct instead of Length
779 // for a major speedup
780 VectorSubtract(org, ent->fields.server->origin, eorg);
781 if (sv_gameplayfix_findradiusdistancetobox.integer)
783 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
784 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
785 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
788 VectorMAMAM(1, eorg, 0.5f, ent->fields.server->mins, 0.5f, ent->fields.server->maxs, eorg);
789 if (DotProduct(eorg, eorg) < radius2)
791 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
796 VM_RETURN_EDICT(chain);
799 static void VM_SV_precache_sound (void)
801 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
802 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
803 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
806 static void VM_SV_precache_model (void)
808 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
809 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
810 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
817 float(float yaw, float dist[, settrace]) walkmove
820 static void VM_SV_walkmove (void)
829 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
831 // assume failure if it returns early
832 PRVM_G_FLOAT(OFS_RETURN) = 0;
834 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
835 if (ent == prog->edicts)
837 VM_Warning("walkmove: can not modify world entity\n");
840 if (ent->priv.server->free)
842 VM_Warning("walkmove: can not modify free entity\n");
845 yaw = PRVM_G_FLOAT(OFS_PARM0);
846 dist = PRVM_G_FLOAT(OFS_PARM1);
847 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
849 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
852 yaw = yaw*M_PI*2 / 360;
854 move[0] = cos(yaw)*dist;
855 move[1] = sin(yaw)*dist;
858 // save program state, because SV_movestep may call other progs
859 oldf = prog->xfunction;
860 oldself = prog->globals.server->self;
862 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
865 // restore program state
866 prog->xfunction = oldf;
867 prog->globals.server->self = oldself;
877 static void VM_SV_droptofloor (void)
883 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
885 // assume failure if it returns early
886 PRVM_G_FLOAT(OFS_RETURN) = 0;
888 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
889 if (ent == prog->edicts)
891 VM_Warning("droptofloor: can not modify world entity\n");
894 if (ent->priv.server->free)
896 VM_Warning("droptofloor: can not modify free entity\n");
900 VectorCopy (ent->fields.server->origin, end);
903 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
905 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
907 if (trace.fraction < 1)
908 VectorCopy (trace.endpos, ent->fields.server->origin);
909 SV_LinkEdict (ent, false);
910 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
911 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
912 PRVM_G_FLOAT(OFS_RETURN) = 1;
913 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
914 ent->priv.server->suspendedinairflag = true;
922 void(float style, string value) lightstyle
925 static void VM_SV_lightstyle (void)
932 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
934 style = (int)PRVM_G_FLOAT(OFS_PARM0);
935 val = PRVM_G_STRING(OFS_PARM1);
937 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
938 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
941 // change the string in sv
942 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
944 // send message to all clients on this server
945 if (sv.state != ss_active)
948 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
950 if (client->active && client->netconnection)
952 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
953 MSG_WriteChar (&client->netconnection->message,style);
954 MSG_WriteString (&client->netconnection->message, val);
964 static void VM_SV_checkbottom (void)
966 VM_SAFEPARMCOUNT(0, VM_SV_checkbottom);
967 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
975 static void VM_SV_pointcontents (void)
977 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
978 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
985 Pick a vector for the player to shoot along
986 vector aim(entity, missilespeed)
989 static void VM_SV_aim (void)
991 prvm_edict_t *ent, *check, *bestent;
992 vec3_t start, dir, end, bestdir;
995 float dist, bestdist;
998 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1000 // assume failure if it returns early
1001 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1002 // if sv_aim is so high it can't possibly accept anything, skip out early
1003 if (sv_aim.value >= 1)
1006 ent = PRVM_G_EDICT(OFS_PARM0);
1007 if (ent == prog->edicts)
1009 VM_Warning("aim: can not use world entity\n");
1012 if (ent->priv.server->free)
1014 VM_Warning("aim: can not use free entity\n");
1017 speed = PRVM_G_FLOAT(OFS_PARM1);
1019 VectorCopy (ent->fields.server->origin, start);
1022 // try sending a trace straight
1023 VectorCopy (prog->globals.server->v_forward, dir);
1024 VectorMA (start, 2048, dir, end);
1025 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1026 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1027 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1029 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1034 // try all possible entities
1035 VectorCopy (dir, bestdir);
1036 bestdist = sv_aim.value;
1039 check = PRVM_NEXT_EDICT(prog->edicts);
1040 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1042 prog->xfunction->builtinsprofile++;
1043 if (check->fields.server->takedamage != DAMAGE_AIM)
1047 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1048 continue; // don't aim at teammate
1049 for (j=0 ; j<3 ; j++)
1050 end[j] = check->fields.server->origin[j]
1051 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1052 VectorSubtract (end, start, dir);
1053 VectorNormalize (dir);
1054 dist = DotProduct (dir, prog->globals.server->v_forward);
1055 if (dist < bestdist)
1056 continue; // to far to turn
1057 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1058 if (tr.ent == check)
1059 { // can shoot at this one
1067 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1068 dist = DotProduct (dir, prog->globals.server->v_forward);
1069 VectorScale (prog->globals.server->v_forward, dist, end);
1071 VectorNormalize (end);
1072 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1076 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1081 ===============================================================================
1085 ===============================================================================
1088 #define MSG_BROADCAST 0 // unreliable to all
1089 #define MSG_ONE 1 // reliable to one (msg_entity)
1090 #define MSG_ALL 2 // reliable to all
1091 #define MSG_INIT 3 // write to the init string
1092 #define MSG_ENTITY 5
1094 sizebuf_t *WriteDest (void)
1099 extern sizebuf_t *sv2csqcbuf;
1101 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1105 return &sv.datagram;
1108 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1109 entnum = PRVM_NUM_FOR_EDICT(ent);
1110 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1112 VM_Warning ("WriteDest: tried to write to non-client\n");
1113 return &sv.reliable_datagram;
1116 return &svs.clients[entnum-1].netconnection->message;
1119 VM_Warning ("WriteDest: bad destination\n");
1121 return &sv.reliable_datagram;
1133 static void VM_SV_WriteByte (void)
1135 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1136 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1139 static void VM_SV_WriteChar (void)
1141 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1142 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1145 static void VM_SV_WriteShort (void)
1147 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1148 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1151 static void VM_SV_WriteLong (void)
1153 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1154 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1157 static void VM_SV_WriteAngle (void)
1159 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1160 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1163 static void VM_SV_WriteCoord (void)
1165 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1166 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1169 static void VM_SV_WriteString (void)
1171 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1172 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1175 static void VM_SV_WriteUnterminatedString (void)
1177 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1178 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1182 static void VM_SV_WriteEntity (void)
1184 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1185 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1188 //////////////////////////////////////////////////////////
1190 static void VM_SV_makestatic (void)
1195 VM_SAFEPARMCOUNT(1, VM_SV_makestatic);
1197 ent = PRVM_G_EDICT(OFS_PARM0);
1198 if (ent == prog->edicts)
1200 VM_Warning("makestatic: can not modify world entity\n");
1203 if (ent->priv.server->free)
1205 VM_Warning("makestatic: can not modify free entity\n");
1210 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1215 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1216 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1217 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1221 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1222 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1223 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1226 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1227 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1228 for (i=0 ; i<3 ; i++)
1230 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1231 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1234 // throw the entity away now
1238 //=============================================================================
1245 static void VM_SV_setspawnparms (void)
1251 VM_SAFEPARMCOUNT(0, VM_SV_setspawnparms);
1253 ent = PRVM_G_EDICT(OFS_PARM0);
1254 i = PRVM_NUM_FOR_EDICT(ent);
1255 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1257 Con_Print("tried to setspawnparms on a non-client\n");
1261 // copy spawn parms out of the client_t
1262 client = svs.clients + i-1;
1263 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1264 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1271 Returns a color vector indicating the lighting at the requested point.
1273 (Internal Operation note: actually measures the light beneath the point, just like
1274 the model lighting on the client)
1279 static void VM_SV_getlight (void)
1281 vec3_t ambientcolor, diffusecolor, diffusenormal;
1283 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1284 p = PRVM_G_VECTOR(OFS_PARM0);
1285 VectorClear(ambientcolor);
1286 VectorClear(diffusecolor);
1287 VectorClear(diffusenormal);
1288 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1289 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1290 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1295 unsigned char type; // 1/2/8 or other value if isn't used
1299 static autosentstat_t *vm_autosentstats = NULL; //[515]: it starts from 0, not 32
1300 static int vm_autosentstats_last;
1302 void VM_AutoSentStats_Clear (void)
1304 if(vm_autosentstats)
1306 Z_Free(vm_autosentstats);
1307 vm_autosentstats = NULL;
1308 vm_autosentstats_last = -1;
1312 //[515]: add check if even bigger ? "try to use two stats, cause it's too big" ?
1313 #define VM_SENDSTAT(a,b,c)\
1316 if((c)==(unsigned char)(c))\
1318 MSG_WriteByte((a), svc_updatestatubyte);\
1319 MSG_WriteByte((a), (b));\
1320 MSG_WriteByte((a), (c));\
1324 MSG_WriteByte((a), svc_updatestat);\
1325 MSG_WriteByte((a), (b));\
1326 MSG_WriteLong((a), (c));\
1330 void VM_SV_WriteAutoSentStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1342 if(!vm_autosentstats)
1345 send = (sv.protocol != PROTOCOL_QUAKE && sv.protocol != PROTOCOL_QUAKEDP && sv.protocol != PROTOCOL_NEHAHRAMOVIE && sv.protocol != PROTOCOL_DARKPLACES1 && sv.protocol != PROTOCOL_DARKPLACES2 && sv.protocol != PROTOCOL_DARKPLACES3 && sv.protocol != PROTOCOL_DARKPLACES4 && sv.protocol != PROTOCOL_DARKPLACES5);
1347 for(i=0; i<vm_autosentstats_last+1 ;i++)
1349 if(!vm_autosentstats[i].type)
1351 switch(vm_autosentstats[i].type)
1355 t = PRVM_E_STRING(ent, vm_autosentstats[i].fieldoffset);
1363 stats[i+32] = si[0];
1364 stats[i+33] = si[1];
1365 stats[i+34] = si[2];
1366 stats[i+35] = si[3];
1370 VM_SENDSTAT(msg, i+32, si[0]);
1371 VM_SENDSTAT(msg, i+33, si[1]);
1372 VM_SENDSTAT(msg, i+34, si[2]);
1373 VM_SENDSTAT(msg, i+35, si[3]);
1379 k.f = PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ?
1380 k.i = LittleLong (k.i);
1384 VM_SENDSTAT(msg, i+32, k.i);
1388 v = (int)PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ?
1392 VM_SENDSTAT(msg, i+32, v);
1400 // void(float index, float type, .void field) SV_AddStat = #232;
1401 // Set up an auto-sent player stat.
1402 // Client's get thier own fields sent to them. Index may not be less than 32.
1403 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1404 // 1: string (4 stats carrying a total of 16 charactures)
1405 // 2: float (one stat, float converted to an integer for transportation)
1406 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1407 static void VM_SV_AddStat (void)
1412 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1414 if(!vm_autosentstats)
1416 vm_autosentstats = (autosentstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(autosentstat_t));
1417 if(!vm_autosentstats)
1419 VM_Warning("PF_SV_AddStat: not enough memory\n");
1423 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1424 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1425 off = PRVM_G_INT (OFS_PARM2);
1430 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1433 if(i >= (MAX_CL_STATS-32))
1435 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1438 if(i > (MAX_CL_STATS-32-4) && type == 1)
1440 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1443 vm_autosentstats[i].type = type;
1444 vm_autosentstats[i].fieldoffset = off;
1445 if(vm_autosentstats_last < i)
1446 vm_autosentstats_last = i;
1453 copies data from one entity to another
1455 copyentity(src, dst)
1458 static void VM_SV_copyentity (void)
1460 prvm_edict_t *in, *out;
1461 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1462 in = PRVM_G_EDICT(OFS_PARM0);
1463 if (in == prog->edicts)
1465 VM_Warning("copyentity: can not read world entity\n");
1468 if (in->priv.server->free)
1470 VM_Warning("copyentity: can not read free entity\n");
1473 out = PRVM_G_EDICT(OFS_PARM1);
1474 if (out == prog->edicts)
1476 VM_Warning("copyentity: can not modify world entity\n");
1479 if (out->priv.server->free)
1481 VM_Warning("copyentity: can not modify free entity\n");
1484 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1485 SV_LinkEdict(out, false);
1493 sets the color of a client and broadcasts the update to all connected clients
1495 setcolor(clientent, value)
1498 static void VM_SV_setcolor (void)
1504 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1505 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1506 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1508 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1510 Con_Print("tried to setcolor a non-client\n");
1514 client = svs.clients + entnum-1;
1517 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1519 client->edict->fields.server->team = (i & 15) + 1;
1522 if (client->old_colors != client->colors)
1524 client->old_colors = client->colors;
1525 // send notification to all clients
1526 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1527 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1528 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1536 effect(origin, modelname, startframe, framecount, framerate)
1539 static void VM_SV_effect (void)
1543 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1544 s = PRVM_G_STRING(OFS_PARM1);
1547 VM_Warning("effect: no model specified\n");
1551 i = SV_ModelIndex(s, 1);
1554 VM_Warning("effect: model not precached\n");
1558 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1560 VM_Warning("effect: framecount < 1\n");
1564 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1566 VM_Warning("effect: framerate < 1\n");
1570 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));
1573 static void VM_SV_te_blood (void)
1575 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1576 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1578 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1579 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1581 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1582 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1583 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1585 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1586 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1587 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1589 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1592 static void VM_SV_te_bloodshower (void)
1594 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1595 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1597 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1598 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1600 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1601 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1602 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1604 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1605 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1606 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1608 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1610 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1613 static void VM_SV_te_explosionrgb (void)
1615 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1616 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1617 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1619 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1620 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1621 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1623 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1624 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1625 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1628 static void VM_SV_te_particlecube (void)
1630 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1631 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1633 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1634 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1636 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1637 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1638 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1640 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1641 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1642 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1644 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1645 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1646 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1648 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1650 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1651 // gravity true/false
1652 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1654 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1657 static void VM_SV_te_particlerain (void)
1659 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1660 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1662 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1663 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1665 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1666 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1667 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1671 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1673 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1674 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1675 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1677 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1679 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1682 static void VM_SV_te_particlesnow (void)
1684 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1685 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1687 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1688 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
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));
1707 static void VM_SV_te_spark (void)
1709 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1710 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1712 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1713 MSG_WriteByte(&sv.datagram, TE_SPARK);
1715 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1716 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1717 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1719 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1720 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1721 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1723 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1726 static void VM_SV_te_gunshotquad (void)
1728 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1729 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1730 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1732 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1733 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1734 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1737 static void VM_SV_te_spikequad (void)
1739 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1740 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1741 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1743 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1744 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1745 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1748 static void VM_SV_te_superspikequad (void)
1750 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1751 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1752 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1754 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1755 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1756 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1759 static void VM_SV_te_explosionquad (void)
1761 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1762 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1763 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1765 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1766 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1767 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1770 static void VM_SV_te_smallflash (void)
1772 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1773 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1774 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1776 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1777 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1778 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1781 static void VM_SV_te_customflash (void)
1783 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1784 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1786 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1787 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1790 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1791 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1793 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1795 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1797 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1798 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1799 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1802 static void VM_SV_te_gunshot (void)
1804 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1805 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1806 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
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);
1813 static void VM_SV_te_spike (void)
1815 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1816 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1817 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1819 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1820 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1821 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1824 static void VM_SV_te_superspike (void)
1826 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1827 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1828 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1830 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1831 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1835 static void VM_SV_te_explosion (void)
1837 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1838 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1839 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1841 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1842 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1843 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1846 static void VM_SV_te_tarexplosion (void)
1848 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1849 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1850 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1852 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1853 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1854 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1857 static void VM_SV_te_wizspike (void)
1859 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1860 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1861 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1863 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1864 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1865 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1868 static void VM_SV_te_knightspike (void)
1870 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1871 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1872 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1874 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1875 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1876 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1879 static void VM_SV_te_lavasplash (void)
1881 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1882 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1883 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1885 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1886 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1887 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1890 static void VM_SV_te_teleport (void)
1892 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1893 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1894 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1896 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1897 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1898 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1901 static void VM_SV_te_explosion2 (void)
1903 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1904 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1905 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1907 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1908 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1909 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1911 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1912 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1915 static void VM_SV_te_lightning1 (void)
1917 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1918 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1919 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1921 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1923 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1924 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1925 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1927 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1928 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1929 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1932 static void VM_SV_te_lightning2 (void)
1934 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1935 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1936 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1938 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1940 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1941 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1942 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1944 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1945 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1946 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1949 static void VM_SV_te_lightning3 (void)
1951 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1952 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1953 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1955 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1957 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1958 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1959 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1961 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1962 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1963 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1966 static void VM_SV_te_beam (void)
1968 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1969 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1970 MSG_WriteByte(&sv.datagram, TE_BEAM);
1972 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1974 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1976 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1978 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1979 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1980 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1983 static void VM_SV_te_plasmaburn (void)
1985 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
1986 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1987 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
1988 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1989 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1990 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1993 static void VM_SV_te_flamejet (void)
1995 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
1996 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1997 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
1999 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2000 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2001 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
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_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2010 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2013 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2015 bestdist = 1000000000;
2017 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2019 // clip original point to each triangle of the surface and find the
2020 // triangle that is closest
2021 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2022 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2023 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2024 TriangleNormal(v[0], v[1], v[2], facenormal);
2025 VectorNormalize(facenormal);
2026 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2027 VectorMA(p, offsetdist, facenormal, temp);
2028 for (j = 0, k = 2;j < 3;k = j, j++)
2030 VectorSubtract(v[k], v[j], edgenormal);
2031 CrossProduct(edgenormal, facenormal, sidenormal);
2032 VectorNormalize(sidenormal);
2033 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2035 VectorMA(temp, offsetdist, sidenormal, temp);
2037 dist = VectorDistance2(temp, p);
2038 if (bestdist > dist)
2041 VectorCopy(temp, out);
2046 static model_t *getmodel(prvm_edict_t *ed)
2049 if (!ed || ed->priv.server->free)
2051 modelindex = (int)ed->fields.server->modelindex;
2052 if (modelindex < 1 || modelindex >= MAX_MODELS)
2054 return sv.models[modelindex];
2057 static msurface_t *getsurface(model_t *model, int surfacenum)
2059 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2061 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2065 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2066 static void VM_SV_getsurfacenumpoints(void)
2069 msurface_t *surface;
2070 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2071 // return 0 if no such surface
2072 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2074 PRVM_G_FLOAT(OFS_RETURN) = 0;
2078 // note: this (incorrectly) assumes it is a simple polygon
2079 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2081 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2082 static void VM_SV_getsurfacepoint(void)
2086 msurface_t *surface;
2088 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2089 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2090 ed = PRVM_G_EDICT(OFS_PARM0);
2091 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2093 // note: this (incorrectly) assumes it is a simple polygon
2094 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2095 if (pointnum < 0 || pointnum >= surface->num_vertices)
2097 // FIXME: implement rotation/scaling
2098 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2100 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2101 static void VM_SV_getsurfacenormal(void)
2104 msurface_t *surface;
2106 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2107 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2108 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2110 // FIXME: implement rotation/scaling
2111 // note: this (incorrectly) assumes it is a simple polygon
2112 // note: this only returns the first triangle, so it doesn't work very
2113 // well for curved surfaces or arbitrary meshes
2114 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);
2115 VectorNormalize(normal);
2116 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2118 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2119 static void VM_SV_getsurfacetexture(void)
2122 msurface_t *surface;
2123 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2124 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2125 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2127 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2129 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2130 static void VM_SV_getsurfacenearpoint(void)
2132 int surfacenum, best;
2134 vec_t dist, bestdist;
2137 msurface_t *surface;
2139 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2140 PRVM_G_FLOAT(OFS_RETURN) = -1;
2141 ed = PRVM_G_EDICT(OFS_PARM0);
2142 point = PRVM_G_VECTOR(OFS_PARM1);
2144 if (!ed || ed->priv.server->free)
2146 model = getmodel(ed);
2147 if (!model || !model->num_surfaces)
2150 // FIXME: implement rotation/scaling
2151 VectorSubtract(point, ed->fields.server->origin, p);
2153 bestdist = 1000000000;
2154 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2156 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2157 // first see if the nearest point on the surface's box is closer than the previous match
2158 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2159 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2160 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2161 dist = VectorLength2(clipped);
2162 if (dist < bestdist)
2164 // it is, check the nearest point on the actual geometry
2165 clippointtosurface(model, surface, p, clipped);
2166 VectorSubtract(clipped, p, clipped);
2167 dist += VectorLength2(clipped);
2168 if (dist < bestdist)
2170 // that's closer too, store it as the best match
2176 PRVM_G_FLOAT(OFS_RETURN) = best;
2178 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2179 static void VM_SV_getsurfaceclippedpoint(void)
2183 msurface_t *surface;
2185 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2186 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2187 ed = PRVM_G_EDICT(OFS_PARM0);
2188 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2190 // FIXME: implement rotation/scaling
2191 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2192 clippointtosurface(model, surface, p, out);
2193 // FIXME: implement rotation/scaling
2194 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2197 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2198 //this function originally written by KrimZon, made shorter by LordHavoc
2199 static void VM_SV_clientcommand (void)
2201 client_t *temp_client;
2203 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2205 //find client for this entity
2206 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2207 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2209 Con_Print("PF_clientcommand: entity is not a client\n");
2213 temp_client = host_client;
2214 host_client = svs.clients + i;
2215 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2216 host_client = temp_client;
2219 //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)
2220 static void VM_SV_setattachment (void)
2222 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2223 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2224 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2228 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2230 if (e == prog->edicts)
2232 VM_Warning("setattachment: can not modify world entity\n");
2235 if (e->priv.server->free)
2237 VM_Warning("setattachment: can not modify free entity\n");
2241 if (tagentity == NULL)
2242 tagentity = prog->edicts;
2244 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2246 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2248 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2251 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2253 modelindex = (int)tagentity->fields.server->modelindex;
2254 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2256 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2258 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);
2261 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));
2265 /////////////////////////////////////////
2266 // DP_MD3_TAGINFO extension coded by VorteX
2268 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2273 i = (int)e->fields.server->modelindex;
2274 if (i < 1 || i >= MAX_MODELS)
2276 model = sv.models[i];
2278 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2281 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2283 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2287 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);
2289 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);
2292 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2298 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2299 && (model = sv.models[(int)ent->fields.server->modelindex])
2300 && model->animscenes)
2302 // if model has wrong frame, engine automatically switches to model first frame
2303 frame = (int)ent->fields.server->frame;
2304 if (frame < 0 || frame >= model->numframes)
2306 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2308 *out = identitymatrix;
2312 // Warnings/errors code:
2313 // 0 - normal (everything all-right)
2316 // 3 - null or non-precached model
2317 // 4 - no tags with requested index
2318 // 5 - runaway loop at attachment chain
2319 extern cvar_t cl_bob;
2320 extern cvar_t cl_bobcycle;
2321 extern cvar_t cl_bobup;
2322 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2326 int modelindex, attachloop;
2327 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2330 *out = identitymatrix; // warnings and errors return identical matrix
2332 if (ent == prog->edicts)
2334 if (ent->priv.server->free)
2337 modelindex = (int)ent->fields.server->modelindex;
2338 if (modelindex <= 0 || modelindex > MAX_MODELS)
2341 model = sv.models[modelindex];
2343 tagmatrix = identitymatrix;
2344 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2348 if (attachloop >= 256) // prevent runaway looping
2350 // apply transformation by child's tagindex on parent entity and then
2351 // by parent entity itself
2352 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2353 if (ret && attachloop == 0)
2355 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2356 SV_GetEntityMatrix(ent, &entitymatrix, false);
2357 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2358 // next iteration we process the parent entity
2359 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2361 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2362 ent = PRVM_EDICT_NUM(val->edict);
2369 // RENDER_VIEWMODEL magic
2370 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2372 Matrix4x4_Copy(&tagmatrix, out);
2373 ent = PRVM_EDICT_NUM(val->edict);
2375 SV_GetEntityMatrix(ent, &entitymatrix, true);
2376 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2379 // Cl_bob, ported from rendering code
2380 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2383 // LordHavoc: this code is *weird*, but not replacable (I think it
2384 // should be done in QC on the server, but oh well, quake is quake)
2385 // LordHavoc: figured out bobup: the time at which the sin is at 180
2386 // degrees (which allows lengthening or squishing the peak or valley)
2387 cycle = sv.time/cl_bobcycle.value;
2388 cycle -= (int)cycle;
2389 if (cycle < cl_bobup.value)
2390 cycle = sin(M_PI * cycle / cl_bobup.value);
2392 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2393 // bob is proportional to velocity in the xy plane
2394 // (don't count Z, or jumping messes it up)
2395 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;
2396 bob = bob*0.3 + bob*0.7*cycle;
2397 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2404 //float(entity ent, string tagname) gettagindex;
2406 static void VM_SV_gettagindex (void)
2409 const char *tag_name;
2410 int modelindex, tag_index;
2412 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2414 ent = PRVM_G_EDICT(OFS_PARM0);
2415 tag_name = PRVM_G_STRING(OFS_PARM1);
2417 if (ent == prog->edicts)
2419 VM_Warning("gettagindex: can't affect world entity\n");
2422 if (ent->priv.server->free)
2424 VM_Warning("gettagindex: can't affect free entity\n");
2428 modelindex = (int)ent->fields.server->modelindex;
2430 if (modelindex <= 0 || modelindex > MAX_MODELS)
2431 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2434 tag_index = SV_GetTagIndex(ent, tag_name);
2436 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2438 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2441 //vector(entity ent, float tagindex) gettaginfo;
2442 static void VM_SV_gettaginfo (void)
2446 matrix4x4_t tag_matrix;
2449 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2451 e = PRVM_G_EDICT(OFS_PARM0);
2452 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2454 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2455 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2460 VM_Warning("gettagindex: can't affect world entity\n");
2463 VM_Warning("gettagindex: can't affect free entity\n");
2466 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2469 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2472 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2477 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2478 static void VM_SV_dropclient (void)
2481 client_t *oldhostclient;
2482 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2483 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2484 if (clientnum < 0 || clientnum >= svs.maxclients)
2486 VM_Warning("dropclient: not a client\n");
2489 if (!svs.clients[clientnum].active)
2491 VM_Warning("dropclient: that client slot is not connected\n");
2494 oldhostclient = host_client;
2495 host_client = svs.clients + clientnum;
2496 SV_DropClient(false);
2497 host_client = oldhostclient;
2500 //entity() spawnclient (DP_SV_BOTCLIENT)
2501 static void VM_SV_spawnclient (void)
2505 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2506 prog->xfunction->builtinsprofile += 2;
2508 for (i = 0;i < svs.maxclients;i++)
2510 if (!svs.clients[i].active)
2512 prog->xfunction->builtinsprofile += 100;
2513 SV_ConnectClient (i, NULL);
2514 // this has to be set or else ClientDisconnect won't be called
2515 // we assume the qc will call ClientConnect...
2516 svs.clients[i].clientconnectcalled = true;
2517 ed = PRVM_EDICT_NUM(i + 1);
2521 VM_RETURN_EDICT(ed);
2524 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2525 static void VM_SV_clienttype (void)
2528 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2529 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2530 if (clientnum < 0 || clientnum >= svs.maxclients)
2531 PRVM_G_FLOAT(OFS_RETURN) = 3;
2532 else if (!svs.clients[clientnum].active)
2533 PRVM_G_FLOAT(OFS_RETURN) = 0;
2534 else if (svs.clients[clientnum].netconnection)
2535 PRVM_G_FLOAT(OFS_RETURN) = 1;
2537 PRVM_G_FLOAT(OFS_RETURN) = 2;
2544 string(string key) serverkey
2547 void VM_SV_serverkey(void)
2549 char string[VM_STRINGTEMP_LENGTH];
2550 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2551 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2552 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2555 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2556 static void VM_SV_setmodelindex (void)
2561 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2563 e = PRVM_G_EDICT(OFS_PARM0);
2564 if (e == prog->edicts)
2566 VM_Warning("setmodelindex: can not modify world entity\n");
2569 if (e->priv.server->free)
2571 VM_Warning("setmodelindex: can not modify free entity\n");
2574 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2575 if (i <= 0 || i > MAX_MODELS)
2577 VM_Warning("setmodelindex: invalid modelindex\n");
2580 if (!sv.model_precache[i][0])
2582 VM_Warning("setmodelindex: model not precached\n");
2586 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2587 e->fields.server->modelindex = i;
2593 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2594 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2596 SetMinMaxSize (e, quakemins, quakemaxs, true);
2599 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2602 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2603 static void VM_SV_modelnameforindex (void)
2606 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2608 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2610 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2611 if (i <= 0 || i > MAX_MODELS)
2613 VM_Warning("modelnameforindex: invalid modelindex\n");
2616 if (!sv.model_precache[i][0])
2618 VM_Warning("modelnameforindex: model not precached\n");
2622 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2625 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2626 static void VM_SV_particleeffectnum (void)
2629 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2630 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2633 PRVM_G_FLOAT(OFS_RETURN) = i;
2636 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2637 static void VM_SV_trailparticles (void)
2639 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2641 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2642 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2643 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2644 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2645 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2648 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2649 static void VM_SV_pointparticles (void)
2651 VM_SAFEPARMCOUNT(4, VM_SV_pointparticles);
2653 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2654 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM0));
2655 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1), sv.protocol);
2656 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2657 MSG_WriteShort(&sv.datagram, bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535));
2660 prvm_builtin_t vm_sv_builtins[] = {
2661 NULL, // #0 NULL function (not callable) (QUAKE)
2662 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2663 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2664 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2665 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2666 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2667 VM_break, // #6 void() break (QUAKE)
2668 VM_random, // #7 float() random (QUAKE)
2669 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2670 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2671 VM_error, // #10 void(string e) error (QUAKE)
2672 VM_objerror, // #11 void(string e) objerror (QUAKE)
2673 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2674 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2675 VM_spawn, // #14 entity() spawn (QUAKE)
2676 VM_remove, // #15 void(entity e) remove (QUAKE)
2677 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2678 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2679 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2680 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2681 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2682 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2683 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2684 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2685 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2686 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2687 VM_ftos, // #26 string(float f) ftos (QUAKE)
2688 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2689 VM_coredump, // #28 void() coredump (QUAKE)
2690 VM_traceon, // #29 void() traceon (QUAKE)
2691 VM_traceoff, // #30 void() traceoff (QUAKE)
2692 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2693 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2694 NULL, // #33 (QUAKE)
2695 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2696 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2697 VM_rint, // #36 float(float v) rint (QUAKE)
2698 VM_floor, // #37 float(float v) floor (QUAKE)
2699 VM_ceil, // #38 float(float v) ceil (QUAKE)
2700 NULL, // #39 (QUAKE)
2701 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2702 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2703 NULL, // #42 (QUAKE)
2704 VM_fabs, // #43 float(float f) fabs (QUAKE)
2705 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2706 VM_cvar, // #45 float(string s) cvar (QUAKE)
2707 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2708 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2709 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2710 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2711 NULL, // #50 (QUAKE)
2712 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2713 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2714 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2715 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2716 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2717 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2718 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2719 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2720 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2721 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2722 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2723 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2724 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2725 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2726 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2727 NULL, // #66 (QUAKE)
2728 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2729 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2730 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2731 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2732 NULL, // #71 (QUAKE)
2733 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2734 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2735 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2736 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2737 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2738 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2739 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2740 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2741 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2742 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2743 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2744 NULL, // #83 (QUAKE)
2745 NULL, // #84 (QUAKE)
2746 NULL, // #85 (QUAKE)
2747 NULL, // #86 (QUAKE)
2748 NULL, // #87 (QUAKE)
2749 NULL, // #88 (QUAKE)
2750 NULL, // #89 (QUAKE)
2751 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2752 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2753 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2754 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2755 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2756 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2757 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2758 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2759 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2760 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2761 // FrikaC and Telejano range #100-#199
2772 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2773 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2774 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2775 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2776 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2777 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2778 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2779 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2780 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2781 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2862 // FTEQW range #200-#299
2881 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2885 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2886 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2891 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2895 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2963 // CSQC range #300-#399
2964 NULL, // #300 void() clearscene (EXT_CSQC)
2965 NULL, // #301 void(float mask) addentities (EXT_CSQC)
2966 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
2967 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
2968 NULL, // #304 void() renderscene (EXT_CSQC)
2969 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2970 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2971 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2972 NULL, // #308 void() R_EndPolygon
2974 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
2975 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
2979 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
2980 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
2981 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
2982 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
2983 NULL, // #319 void(string name) freepic (EXT_CSQC)
2984 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
2985 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
2986 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
2987 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
2988 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
2989 NULL, // #325 void(void) drawresetcliparea
2994 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
2995 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
2996 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
2997 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2998 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2999 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3000 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3001 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3002 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3003 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3004 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3005 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3006 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3007 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3008 NULL, // #344 vector() getmousepos (EXT_CSQC)
3009 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3010 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3011 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3012 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3013 NULL, // #349 float() isdemo (EXT_CSQC)
3014 VM_isserver, // #350 float() isserver (EXT_CSQC)
3015 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3016 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3017 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3018 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3024 NULL, // #360 float() readbyte (EXT_CSQC)
3025 NULL, // #361 float() readchar (EXT_CSQC)
3026 NULL, // #362 float() readshort (EXT_CSQC)
3027 NULL, // #363 float() readlong (EXT_CSQC)
3028 NULL, // #364 float() readcoord (EXT_CSQC)
3029 NULL, // #365 float() readangle (EXT_CSQC)
3030 NULL, // #366 string() readstring (EXT_CSQC)
3031 NULL, // #367 float() readfloat (EXT_CSQC)
3064 // LordHavoc's range #400-#499
3065 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3066 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3067 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3068 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3069 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3070 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3071 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3072 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3073 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)
3074 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3075 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3076 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3077 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3078 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3079 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3080 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3081 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3082 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3083 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3084 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3085 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3086 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3087 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3088 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3089 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3090 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3091 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3092 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3093 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3094 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3095 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3096 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3097 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3098 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3099 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3100 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3101 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3102 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3103 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3104 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3105 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3106 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3107 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3108 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3109 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
3110 VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
3111 VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
3112 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
3113 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3114 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3115 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3116 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3117 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3118 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3119 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3120 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3121 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3122 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3124 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3125 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3126 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3127 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3128 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3129 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3130 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3131 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3132 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3133 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3134 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3136 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3137 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3138 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3139 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3140 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3141 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3142 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3143 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3167 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3169 void VM_SV_Cmd_Init(void)
3174 void VM_SV_Cmd_Reset(void)