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(1, 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 // allow 0 parameters due to an id1 qc bug in which this function is used
1196 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1197 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1199 if (prog->argc >= 1)
1200 ent = PRVM_G_EDICT(OFS_PARM0);
1202 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1203 if (ent == prog->edicts)
1205 VM_Warning("makestatic: can not modify world entity\n");
1208 if (ent->priv.server->free)
1210 VM_Warning("makestatic: can not modify free entity\n");
1215 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1220 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1221 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1222 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1226 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1227 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1228 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1231 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1232 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1233 for (i=0 ; i<3 ; i++)
1235 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1236 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1239 // throw the entity away now
1243 //=============================================================================
1250 static void VM_SV_setspawnparms (void)
1256 VM_SAFEPARMCOUNT(0, VM_SV_setspawnparms);
1258 ent = PRVM_G_EDICT(OFS_PARM0);
1259 i = PRVM_NUM_FOR_EDICT(ent);
1260 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1262 Con_Print("tried to setspawnparms on a non-client\n");
1266 // copy spawn parms out of the client_t
1267 client = svs.clients + i-1;
1268 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1269 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1276 Returns a color vector indicating the lighting at the requested point.
1278 (Internal Operation note: actually measures the light beneath the point, just like
1279 the model lighting on the client)
1284 static void VM_SV_getlight (void)
1286 vec3_t ambientcolor, diffusecolor, diffusenormal;
1288 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1289 p = PRVM_G_VECTOR(OFS_PARM0);
1290 VectorClear(ambientcolor);
1291 VectorClear(diffusecolor);
1292 VectorClear(diffusenormal);
1293 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1294 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1295 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1300 unsigned char type; // 1/2/8 or other value if isn't used
1304 static autosentstat_t *vm_autosentstats = NULL; //[515]: it starts from 0, not 32
1305 static int vm_autosentstats_last;
1307 void VM_AutoSentStats_Clear (void)
1309 if(vm_autosentstats)
1311 Z_Free(vm_autosentstats);
1312 vm_autosentstats = NULL;
1313 vm_autosentstats_last = -1;
1317 //[515]: add check if even bigger ? "try to use two stats, cause it's too big" ?
1318 #define VM_SENDSTAT(a,b,c)\
1321 if((c)==(unsigned char)(c))\
1323 MSG_WriteByte((a), svc_updatestatubyte);\
1324 MSG_WriteByte((a), (b));\
1325 MSG_WriteByte((a), (c));\
1329 MSG_WriteByte((a), svc_updatestat);\
1330 MSG_WriteByte((a), (b));\
1331 MSG_WriteLong((a), (c));\
1335 void VM_SV_WriteAutoSentStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1347 if(!vm_autosentstats)
1350 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);
1352 for(i=0; i<vm_autosentstats_last+1 ;i++)
1354 if(!vm_autosentstats[i].type)
1356 switch(vm_autosentstats[i].type)
1360 t = PRVM_E_STRING(ent, vm_autosentstats[i].fieldoffset);
1368 stats[i+32] = si[0];
1369 stats[i+33] = si[1];
1370 stats[i+34] = si[2];
1371 stats[i+35] = si[3];
1375 VM_SENDSTAT(msg, i+32, si[0]);
1376 VM_SENDSTAT(msg, i+33, si[1]);
1377 VM_SENDSTAT(msg, i+34, si[2]);
1378 VM_SENDSTAT(msg, i+35, si[3]);
1384 k.f = PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ?
1385 k.i = LittleLong (k.i);
1389 VM_SENDSTAT(msg, i+32, k.i);
1393 v = (int)PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ?
1397 VM_SENDSTAT(msg, i+32, v);
1405 // void(float index, float type, .void field) SV_AddStat = #232;
1406 // Set up an auto-sent player stat.
1407 // Client's get thier own fields sent to them. Index may not be less than 32.
1408 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1409 // 1: string (4 stats carrying a total of 16 charactures)
1410 // 2: float (one stat, float converted to an integer for transportation)
1411 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1412 static void VM_SV_AddStat (void)
1417 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1419 if(!vm_autosentstats)
1421 vm_autosentstats = (autosentstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(autosentstat_t));
1422 if(!vm_autosentstats)
1424 VM_Warning("PF_SV_AddStat: not enough memory\n");
1428 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1429 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1430 off = PRVM_G_INT (OFS_PARM2);
1435 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1438 if(i >= (MAX_CL_STATS-32))
1440 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1443 if(i > (MAX_CL_STATS-32-4) && type == 1)
1445 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1448 vm_autosentstats[i].type = type;
1449 vm_autosentstats[i].fieldoffset = off;
1450 if(vm_autosentstats_last < i)
1451 vm_autosentstats_last = i;
1458 copies data from one entity to another
1460 copyentity(src, dst)
1463 static void VM_SV_copyentity (void)
1465 prvm_edict_t *in, *out;
1466 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1467 in = PRVM_G_EDICT(OFS_PARM0);
1468 if (in == prog->edicts)
1470 VM_Warning("copyentity: can not read world entity\n");
1473 if (in->priv.server->free)
1475 VM_Warning("copyentity: can not read free entity\n");
1478 out = PRVM_G_EDICT(OFS_PARM1);
1479 if (out == prog->edicts)
1481 VM_Warning("copyentity: can not modify world entity\n");
1484 if (out->priv.server->free)
1486 VM_Warning("copyentity: can not modify free entity\n");
1489 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1490 SV_LinkEdict(out, false);
1498 sets the color of a client and broadcasts the update to all connected clients
1500 setcolor(clientent, value)
1503 static void VM_SV_setcolor (void)
1509 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1510 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1511 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1513 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1515 Con_Print("tried to setcolor a non-client\n");
1519 client = svs.clients + entnum-1;
1522 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1524 client->edict->fields.server->team = (i & 15) + 1;
1527 if (client->old_colors != client->colors)
1529 client->old_colors = client->colors;
1530 // send notification to all clients
1531 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1532 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1533 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1541 effect(origin, modelname, startframe, framecount, framerate)
1544 static void VM_SV_effect (void)
1548 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1549 s = PRVM_G_STRING(OFS_PARM1);
1552 VM_Warning("effect: no model specified\n");
1556 i = SV_ModelIndex(s, 1);
1559 VM_Warning("effect: model not precached\n");
1563 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1565 VM_Warning("effect: framecount < 1\n");
1569 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1571 VM_Warning("effect: framerate < 1\n");
1575 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));
1578 static void VM_SV_te_blood (void)
1580 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1581 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1583 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1584 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1586 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1587 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1588 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1590 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1591 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1592 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1594 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1597 static void VM_SV_te_bloodshower (void)
1599 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1600 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1602 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1603 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1605 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1606 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1607 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1609 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1610 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1611 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1613 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1615 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1618 static void VM_SV_te_explosionrgb (void)
1620 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1621 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1622 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1624 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1625 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1626 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1628 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1629 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1630 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1633 static void VM_SV_te_particlecube (void)
1635 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1636 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1638 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1639 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1641 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1642 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1643 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1645 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1646 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1647 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1649 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1650 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1651 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1653 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1655 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1656 // gravity true/false
1657 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1659 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1662 static void VM_SV_te_particlerain (void)
1664 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1665 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1667 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1668 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1671 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1672 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1674 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1675 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1676 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1678 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1679 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1680 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1682 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1684 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1687 static void VM_SV_te_particlesnow (void)
1689 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1690 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1692 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1693 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1695 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1696 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1697 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1699 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1700 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1701 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1703 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1704 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1705 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1707 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1709 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1712 static void VM_SV_te_spark (void)
1714 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1715 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1717 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1718 MSG_WriteByte(&sv.datagram, TE_SPARK);
1720 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1721 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1722 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1724 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1725 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1726 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1728 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1731 static void VM_SV_te_gunshotquad (void)
1733 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1734 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1735 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1737 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1738 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1739 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1742 static void VM_SV_te_spikequad (void)
1744 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1745 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1746 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1748 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1749 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1750 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1753 static void VM_SV_te_superspikequad (void)
1755 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1756 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1757 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1759 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1760 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1761 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1764 static void VM_SV_te_explosionquad (void)
1766 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1767 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1768 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1770 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1771 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1772 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1775 static void VM_SV_te_smallflash (void)
1777 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1778 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1779 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1781 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1782 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1783 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1786 static void VM_SV_te_customflash (void)
1788 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1789 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1791 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1792 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1794 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1795 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1796 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1798 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1800 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1802 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1803 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1804 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1807 static void VM_SV_te_gunshot (void)
1809 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1810 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1811 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1814 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1815 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1818 static void VM_SV_te_spike (void)
1820 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1821 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1822 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1824 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1825 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1826 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1829 static void VM_SV_te_superspike (void)
1831 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1832 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1833 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1835 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1836 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1837 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1840 static void VM_SV_te_explosion (void)
1842 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1843 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1844 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1846 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1847 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1848 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1851 static void VM_SV_te_tarexplosion (void)
1853 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1854 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1855 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1857 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1858 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1859 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1862 static void VM_SV_te_wizspike (void)
1864 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1865 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1866 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1873 static void VM_SV_te_knightspike (void)
1875 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1876 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1877 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1879 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1880 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1881 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1884 static void VM_SV_te_lavasplash (void)
1886 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1887 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1888 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
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);
1895 static void VM_SV_te_teleport (void)
1897 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1898 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1899 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1902 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1903 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1906 static void VM_SV_te_explosion2 (void)
1908 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1909 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1910 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1912 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1913 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1914 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1916 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1917 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1920 static void VM_SV_te_lightning1 (void)
1922 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1923 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1924 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1926 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1928 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1929 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1930 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1933 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1934 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1937 static void VM_SV_te_lightning2 (void)
1939 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1940 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1941 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1943 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1945 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1946 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1947 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1949 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1950 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1951 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1954 static void VM_SV_te_lightning3 (void)
1956 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1957 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1958 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1960 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1962 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1963 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1964 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1966 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1967 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1968 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1971 static void VM_SV_te_beam (void)
1973 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1974 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1975 MSG_WriteByte(&sv.datagram, TE_BEAM);
1977 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1979 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1980 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1981 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1983 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1984 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1985 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1988 static void VM_SV_te_plasmaburn (void)
1990 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
1991 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1992 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
1993 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1994 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1998 static void VM_SV_te_flamejet (void)
2000 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2001 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2002 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2004 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2005 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2006 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2008 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2009 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2010 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2012 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2015 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2018 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2020 bestdist = 1000000000;
2022 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2024 // clip original point to each triangle of the surface and find the
2025 // triangle that is closest
2026 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2027 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2028 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2029 TriangleNormal(v[0], v[1], v[2], facenormal);
2030 VectorNormalize(facenormal);
2031 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2032 VectorMA(p, offsetdist, facenormal, temp);
2033 for (j = 0, k = 2;j < 3;k = j, j++)
2035 VectorSubtract(v[k], v[j], edgenormal);
2036 CrossProduct(edgenormal, facenormal, sidenormal);
2037 VectorNormalize(sidenormal);
2038 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2040 VectorMA(temp, offsetdist, sidenormal, temp);
2042 dist = VectorDistance2(temp, p);
2043 if (bestdist > dist)
2046 VectorCopy(temp, out);
2051 static model_t *getmodel(prvm_edict_t *ed)
2054 if (!ed || ed->priv.server->free)
2056 modelindex = (int)ed->fields.server->modelindex;
2057 if (modelindex < 1 || modelindex >= MAX_MODELS)
2059 return sv.models[modelindex];
2062 static msurface_t *getsurface(model_t *model, int surfacenum)
2064 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2066 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2070 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2071 static void VM_SV_getsurfacenumpoints(void)
2074 msurface_t *surface;
2075 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2076 // return 0 if no such surface
2077 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2079 PRVM_G_FLOAT(OFS_RETURN) = 0;
2083 // note: this (incorrectly) assumes it is a simple polygon
2084 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2086 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2087 static void VM_SV_getsurfacepoint(void)
2091 msurface_t *surface;
2093 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2094 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2095 ed = PRVM_G_EDICT(OFS_PARM0);
2096 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2098 // note: this (incorrectly) assumes it is a simple polygon
2099 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2100 if (pointnum < 0 || pointnum >= surface->num_vertices)
2102 // FIXME: implement rotation/scaling
2103 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2105 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2106 static void VM_SV_getsurfacenormal(void)
2109 msurface_t *surface;
2111 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2112 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2113 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2115 // FIXME: implement rotation/scaling
2116 // note: this (incorrectly) assumes it is a simple polygon
2117 // note: this only returns the first triangle, so it doesn't work very
2118 // well for curved surfaces or arbitrary meshes
2119 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);
2120 VectorNormalize(normal);
2121 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2123 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2124 static void VM_SV_getsurfacetexture(void)
2127 msurface_t *surface;
2128 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2129 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2130 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2132 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2134 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2135 static void VM_SV_getsurfacenearpoint(void)
2137 int surfacenum, best;
2139 vec_t dist, bestdist;
2142 msurface_t *surface;
2144 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2145 PRVM_G_FLOAT(OFS_RETURN) = -1;
2146 ed = PRVM_G_EDICT(OFS_PARM0);
2147 point = PRVM_G_VECTOR(OFS_PARM1);
2149 if (!ed || ed->priv.server->free)
2151 model = getmodel(ed);
2152 if (!model || !model->num_surfaces)
2155 // FIXME: implement rotation/scaling
2156 VectorSubtract(point, ed->fields.server->origin, p);
2158 bestdist = 1000000000;
2159 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2161 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2162 // first see if the nearest point on the surface's box is closer than the previous match
2163 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2164 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2165 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2166 dist = VectorLength2(clipped);
2167 if (dist < bestdist)
2169 // it is, check the nearest point on the actual geometry
2170 clippointtosurface(model, surface, p, clipped);
2171 VectorSubtract(clipped, p, clipped);
2172 dist += VectorLength2(clipped);
2173 if (dist < bestdist)
2175 // that's closer too, store it as the best match
2181 PRVM_G_FLOAT(OFS_RETURN) = best;
2183 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2184 static void VM_SV_getsurfaceclippedpoint(void)
2188 msurface_t *surface;
2190 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2191 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2192 ed = PRVM_G_EDICT(OFS_PARM0);
2193 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2195 // FIXME: implement rotation/scaling
2196 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2197 clippointtosurface(model, surface, p, out);
2198 // FIXME: implement rotation/scaling
2199 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2202 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2203 //this function originally written by KrimZon, made shorter by LordHavoc
2204 static void VM_SV_clientcommand (void)
2206 client_t *temp_client;
2208 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2210 //find client for this entity
2211 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2212 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2214 Con_Print("PF_clientcommand: entity is not a client\n");
2218 temp_client = host_client;
2219 host_client = svs.clients + i;
2220 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2221 host_client = temp_client;
2224 //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)
2225 static void VM_SV_setattachment (void)
2227 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2228 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2229 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2233 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2235 if (e == prog->edicts)
2237 VM_Warning("setattachment: can not modify world entity\n");
2240 if (e->priv.server->free)
2242 VM_Warning("setattachment: can not modify free entity\n");
2246 if (tagentity == NULL)
2247 tagentity = prog->edicts;
2249 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2251 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2253 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2256 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2258 modelindex = (int)tagentity->fields.server->modelindex;
2259 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2261 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2263 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);
2266 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));
2270 /////////////////////////////////////////
2271 // DP_MD3_TAGINFO extension coded by VorteX
2273 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2278 i = (int)e->fields.server->modelindex;
2279 if (i < 1 || i >= MAX_MODELS)
2281 model = sv.models[i];
2283 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2286 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2288 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2292 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);
2294 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);
2297 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2303 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2304 && (model = sv.models[(int)ent->fields.server->modelindex])
2305 && model->animscenes)
2307 // if model has wrong frame, engine automatically switches to model first frame
2308 frame = (int)ent->fields.server->frame;
2309 if (frame < 0 || frame >= model->numframes)
2311 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2313 *out = identitymatrix;
2317 // Warnings/errors code:
2318 // 0 - normal (everything all-right)
2321 // 3 - null or non-precached model
2322 // 4 - no tags with requested index
2323 // 5 - runaway loop at attachment chain
2324 extern cvar_t cl_bob;
2325 extern cvar_t cl_bobcycle;
2326 extern cvar_t cl_bobup;
2327 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2331 int modelindex, attachloop;
2332 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2335 *out = identitymatrix; // warnings and errors return identical matrix
2337 if (ent == prog->edicts)
2339 if (ent->priv.server->free)
2342 modelindex = (int)ent->fields.server->modelindex;
2343 if (modelindex <= 0 || modelindex > MAX_MODELS)
2346 model = sv.models[modelindex];
2348 tagmatrix = identitymatrix;
2349 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2353 if (attachloop >= 256) // prevent runaway looping
2355 // apply transformation by child's tagindex on parent entity and then
2356 // by parent entity itself
2357 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2358 if (ret && attachloop == 0)
2360 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2361 SV_GetEntityMatrix(ent, &entitymatrix, false);
2362 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2363 // next iteration we process the parent entity
2364 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2366 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2367 ent = PRVM_EDICT_NUM(val->edict);
2374 // RENDER_VIEWMODEL magic
2375 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2377 Matrix4x4_Copy(&tagmatrix, out);
2378 ent = PRVM_EDICT_NUM(val->edict);
2380 SV_GetEntityMatrix(ent, &entitymatrix, true);
2381 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2384 // Cl_bob, ported from rendering code
2385 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2388 // LordHavoc: this code is *weird*, but not replacable (I think it
2389 // should be done in QC on the server, but oh well, quake is quake)
2390 // LordHavoc: figured out bobup: the time at which the sin is at 180
2391 // degrees (which allows lengthening or squishing the peak or valley)
2392 cycle = sv.time/cl_bobcycle.value;
2393 cycle -= (int)cycle;
2394 if (cycle < cl_bobup.value)
2395 cycle = sin(M_PI * cycle / cl_bobup.value);
2397 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2398 // bob is proportional to velocity in the xy plane
2399 // (don't count Z, or jumping messes it up)
2400 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;
2401 bob = bob*0.3 + bob*0.7*cycle;
2402 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2409 //float(entity ent, string tagname) gettagindex;
2411 static void VM_SV_gettagindex (void)
2414 const char *tag_name;
2415 int modelindex, tag_index;
2417 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2419 ent = PRVM_G_EDICT(OFS_PARM0);
2420 tag_name = PRVM_G_STRING(OFS_PARM1);
2422 if (ent == prog->edicts)
2424 VM_Warning("gettagindex: can't affect world entity\n");
2427 if (ent->priv.server->free)
2429 VM_Warning("gettagindex: can't affect free entity\n");
2433 modelindex = (int)ent->fields.server->modelindex;
2435 if (modelindex <= 0 || modelindex > MAX_MODELS)
2436 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2439 tag_index = SV_GetTagIndex(ent, tag_name);
2441 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2443 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2446 //vector(entity ent, float tagindex) gettaginfo;
2447 static void VM_SV_gettaginfo (void)
2451 matrix4x4_t tag_matrix;
2454 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2456 e = PRVM_G_EDICT(OFS_PARM0);
2457 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2459 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2460 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2465 VM_Warning("gettagindex: can't affect world entity\n");
2468 VM_Warning("gettagindex: can't affect free entity\n");
2471 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2474 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2477 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2482 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2483 static void VM_SV_dropclient (void)
2486 client_t *oldhostclient;
2487 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2488 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2489 if (clientnum < 0 || clientnum >= svs.maxclients)
2491 VM_Warning("dropclient: not a client\n");
2494 if (!svs.clients[clientnum].active)
2496 VM_Warning("dropclient: that client slot is not connected\n");
2499 oldhostclient = host_client;
2500 host_client = svs.clients + clientnum;
2501 SV_DropClient(false);
2502 host_client = oldhostclient;
2505 //entity() spawnclient (DP_SV_BOTCLIENT)
2506 static void VM_SV_spawnclient (void)
2510 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2511 prog->xfunction->builtinsprofile += 2;
2513 for (i = 0;i < svs.maxclients;i++)
2515 if (!svs.clients[i].active)
2517 prog->xfunction->builtinsprofile += 100;
2518 SV_ConnectClient (i, NULL);
2519 // this has to be set or else ClientDisconnect won't be called
2520 // we assume the qc will call ClientConnect...
2521 svs.clients[i].clientconnectcalled = true;
2522 ed = PRVM_EDICT_NUM(i + 1);
2526 VM_RETURN_EDICT(ed);
2529 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2530 static void VM_SV_clienttype (void)
2533 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2534 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2535 if (clientnum < 0 || clientnum >= svs.maxclients)
2536 PRVM_G_FLOAT(OFS_RETURN) = 3;
2537 else if (!svs.clients[clientnum].active)
2538 PRVM_G_FLOAT(OFS_RETURN) = 0;
2539 else if (svs.clients[clientnum].netconnection)
2540 PRVM_G_FLOAT(OFS_RETURN) = 1;
2542 PRVM_G_FLOAT(OFS_RETURN) = 2;
2549 string(string key) serverkey
2552 void VM_SV_serverkey(void)
2554 char string[VM_STRINGTEMP_LENGTH];
2555 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2556 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2557 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2560 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2561 static void VM_SV_setmodelindex (void)
2566 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2568 e = PRVM_G_EDICT(OFS_PARM0);
2569 if (e == prog->edicts)
2571 VM_Warning("setmodelindex: can not modify world entity\n");
2574 if (e->priv.server->free)
2576 VM_Warning("setmodelindex: can not modify free entity\n");
2579 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2580 if (i <= 0 || i > MAX_MODELS)
2582 VM_Warning("setmodelindex: invalid modelindex\n");
2585 if (!sv.model_precache[i][0])
2587 VM_Warning("setmodelindex: model not precached\n");
2591 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2592 e->fields.server->modelindex = i;
2598 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2599 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2601 SetMinMaxSize (e, quakemins, quakemaxs, true);
2604 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2607 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2608 static void VM_SV_modelnameforindex (void)
2611 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2613 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2615 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2616 if (i <= 0 || i > MAX_MODELS)
2618 VM_Warning("modelnameforindex: invalid modelindex\n");
2621 if (!sv.model_precache[i][0])
2623 VM_Warning("modelnameforindex: model not precached\n");
2627 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2630 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2631 static void VM_SV_particleeffectnum (void)
2634 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2635 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2638 PRVM_G_FLOAT(OFS_RETURN) = i;
2641 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2642 static void VM_SV_trailparticles (void)
2644 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2646 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2647 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2648 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2649 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2650 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2653 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2654 static void VM_SV_pointparticles (void)
2656 VM_SAFEPARMCOUNT(4, VM_SV_pointparticles);
2658 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2659 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM0));
2660 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1), sv.protocol);
2661 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2662 MSG_WriteShort(&sv.datagram, bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535));
2665 prvm_builtin_t vm_sv_builtins[] = {
2666 NULL, // #0 NULL function (not callable) (QUAKE)
2667 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2668 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2669 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2670 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2671 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2672 VM_break, // #6 void() break (QUAKE)
2673 VM_random, // #7 float() random (QUAKE)
2674 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2675 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2676 VM_error, // #10 void(string e) error (QUAKE)
2677 VM_objerror, // #11 void(string e) objerror (QUAKE)
2678 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2679 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2680 VM_spawn, // #14 entity() spawn (QUAKE)
2681 VM_remove, // #15 void(entity e) remove (QUAKE)
2682 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2683 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2684 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2685 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2686 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2687 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2688 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2689 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2690 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2691 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2692 VM_ftos, // #26 string(float f) ftos (QUAKE)
2693 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2694 VM_coredump, // #28 void() coredump (QUAKE)
2695 VM_traceon, // #29 void() traceon (QUAKE)
2696 VM_traceoff, // #30 void() traceoff (QUAKE)
2697 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2698 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2699 NULL, // #33 (QUAKE)
2700 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2701 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2702 VM_rint, // #36 float(float v) rint (QUAKE)
2703 VM_floor, // #37 float(float v) floor (QUAKE)
2704 VM_ceil, // #38 float(float v) ceil (QUAKE)
2705 NULL, // #39 (QUAKE)
2706 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2707 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2708 NULL, // #42 (QUAKE)
2709 VM_fabs, // #43 float(float f) fabs (QUAKE)
2710 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2711 VM_cvar, // #45 float(string s) cvar (QUAKE)
2712 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2713 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2714 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2715 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2716 NULL, // #50 (QUAKE)
2717 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2718 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2719 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2720 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2721 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2722 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2723 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2724 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2725 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2726 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2727 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2728 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2729 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2730 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2731 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2732 NULL, // #66 (QUAKE)
2733 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2734 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2735 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2736 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2737 NULL, // #71 (QUAKE)
2738 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2739 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2740 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2741 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2742 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2743 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2744 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2745 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2746 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2747 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2748 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2749 NULL, // #83 (QUAKE)
2750 NULL, // #84 (QUAKE)
2751 NULL, // #85 (QUAKE)
2752 NULL, // #86 (QUAKE)
2753 NULL, // #87 (QUAKE)
2754 NULL, // #88 (QUAKE)
2755 NULL, // #89 (QUAKE)
2756 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2757 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2758 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2759 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2760 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2761 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2762 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2763 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2764 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2765 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2766 // FrikaC and Telejano range #100-#199
2777 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2778 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2779 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2780 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2781 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2782 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2783 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2784 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2785 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2786 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2867 // FTEQW range #200-#299
2886 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2890 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2891 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2896 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2900 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2968 // CSQC range #300-#399
2969 NULL, // #300 void() clearscene (EXT_CSQC)
2970 NULL, // #301 void(float mask) addentities (EXT_CSQC)
2971 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
2972 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
2973 NULL, // #304 void() renderscene (EXT_CSQC)
2974 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2975 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2976 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2977 NULL, // #308 void() R_EndPolygon
2979 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
2980 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
2984 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
2985 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
2986 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
2987 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
2988 NULL, // #319 void(string name) freepic (EXT_CSQC)
2989 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
2990 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
2991 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
2992 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
2993 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
2994 NULL, // #325 void(void) drawresetcliparea
2999 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3000 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3001 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3002 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3003 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3004 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3005 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3006 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3007 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3008 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3009 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3010 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3011 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3012 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3013 NULL, // #344 vector() getmousepos (EXT_CSQC)
3014 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3015 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3016 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3017 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3018 NULL, // #349 float() isdemo (EXT_CSQC)
3019 VM_isserver, // #350 float() isserver (EXT_CSQC)
3020 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3021 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3022 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3023 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3029 NULL, // #360 float() readbyte (EXT_CSQC)
3030 NULL, // #361 float() readchar (EXT_CSQC)
3031 NULL, // #362 float() readshort (EXT_CSQC)
3032 NULL, // #363 float() readlong (EXT_CSQC)
3033 NULL, // #364 float() readcoord (EXT_CSQC)
3034 NULL, // #365 float() readangle (EXT_CSQC)
3035 NULL, // #366 string() readstring (EXT_CSQC)
3036 NULL, // #367 float() readfloat (EXT_CSQC)
3069 // LordHavoc's range #400-#499
3070 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3071 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3072 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3073 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3074 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3075 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3076 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3077 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3078 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)
3079 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3080 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3081 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3082 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3083 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3084 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3085 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3086 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3087 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3088 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3089 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3090 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3091 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3092 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3093 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3094 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3095 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3096 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3097 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3098 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3099 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3100 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3101 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3102 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3103 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3104 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3105 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3106 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3107 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3108 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3109 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3110 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3111 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3112 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3113 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3114 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
3115 VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
3116 VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
3117 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
3118 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3119 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3120 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3121 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3122 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3123 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3124 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3125 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3126 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3127 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3129 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3130 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3131 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3132 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3133 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3134 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3135 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3136 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3137 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3138 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3139 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3141 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3142 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3143 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3144 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3145 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3146 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3147 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3148 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3172 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3174 void VM_SV_Cmd_Init(void)
3179 void VM_SV_Cmd_Reset(void)