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"};
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_VarString(1, string, sizeof(string));
280 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
282 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
283 // LordHavoc: div0 requested that sprintto world operate like print
290 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
292 VM_Warning("tried to centerprint to a non-client\n");
296 client = svs.clients + entnum-1;
297 if (!client->netconnection)
300 MSG_WriteChar(&client->netconnection->message,svc_print);
301 MSG_WriteString(&client->netconnection->message, string);
309 single print to a specific client
311 centerprint(clientent, value)
314 static void VM_SV_centerprint (void)
318 char string[VM_STRINGTEMP_LENGTH];
320 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
322 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
324 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
326 VM_Warning("tried to centerprint to a non-client\n");
330 client = svs.clients + entnum-1;
331 if (!client->netconnection)
334 VM_VarString(1, string, sizeof(string));
335 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
336 MSG_WriteString(&client->netconnection->message, string);
343 particle(origin, color, count)
346 static void VM_SV_particle (void)
352 VM_SAFEPARMCOUNT(4, VM_SV_particle);
354 org = PRVM_G_VECTOR(OFS_PARM0);
355 dir = PRVM_G_VECTOR(OFS_PARM1);
356 color = PRVM_G_FLOAT(OFS_PARM2);
357 count = PRVM_G_FLOAT(OFS_PARM3);
358 SV_StartParticle (org, dir, (int)color, (int)count);
368 static void VM_SV_ambientsound (void)
372 float vol, attenuation;
375 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
377 pos = PRVM_G_VECTOR (OFS_PARM0);
378 samp = PRVM_G_STRING(OFS_PARM1);
379 vol = PRVM_G_FLOAT(OFS_PARM2);
380 attenuation = PRVM_G_FLOAT(OFS_PARM3);
382 // check to see if samp was properly precached
383 soundnum = SV_SoundIndex(samp, 1);
391 // add an svc_spawnambient command to the level signon packet
394 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
396 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
398 MSG_WriteVector(&sv.signon, pos, sv.protocol);
401 MSG_WriteShort (&sv.signon, soundnum);
403 MSG_WriteByte (&sv.signon, soundnum);
405 MSG_WriteByte (&sv.signon, (int)(vol*255));
406 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
414 Each entity can have eight independant sound sources, like voice,
417 Channel 0 is an auto-allocate channel, the others override anything
418 already running on that entity/channel pair.
420 An attenuation of 0 will play full volume everywhere in the level.
421 Larger attenuations will drop off.
425 static void VM_SV_sound (void)
429 prvm_edict_t *entity;
433 VM_SAFEPARMCOUNT(5, VM_SV_sound);
435 entity = PRVM_G_EDICT(OFS_PARM0);
436 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
437 sample = PRVM_G_STRING(OFS_PARM2);
438 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
439 attenuation = PRVM_G_FLOAT(OFS_PARM4);
441 if (volume < 0 || volume > 255)
443 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
447 if (attenuation < 0 || attenuation > 4)
449 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
453 if (channel < 0 || channel > 7)
455 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
459 SV_StartSound (entity, channel, sample, volume, attenuation);
466 Used for use tracing and shot targeting
467 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
468 if the tryents flag is set.
470 traceline (vector1, vector2, movetype, ignore)
473 static void VM_SV_traceline (void)
480 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
482 prog->xfunction->builtinsprofile += 30;
484 v1 = PRVM_G_VECTOR(OFS_PARM0);
485 v2 = PRVM_G_VECTOR(OFS_PARM1);
486 move = (int)PRVM_G_FLOAT(OFS_PARM2);
487 ent = PRVM_G_EDICT(OFS_PARM3);
489 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]))
490 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));
492 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
494 VM_SetTraceGlobals(&trace);
502 Used for use tracing and shot targeting
503 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
504 if the tryents flag is set.
506 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
509 // LordHavoc: added this for my own use, VERY useful, similar to traceline
510 static void VM_SV_tracebox (void)
512 float *v1, *v2, *m1, *m2;
517 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
519 prog->xfunction->builtinsprofile += 30;
521 v1 = PRVM_G_VECTOR(OFS_PARM0);
522 m1 = PRVM_G_VECTOR(OFS_PARM1);
523 m2 = PRVM_G_VECTOR(OFS_PARM2);
524 v2 = PRVM_G_VECTOR(OFS_PARM3);
525 move = (int)PRVM_G_FLOAT(OFS_PARM4);
526 ent = PRVM_G_EDICT(OFS_PARM5);
528 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]))
529 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));
531 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
533 VM_SetTraceGlobals(&trace);
536 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
541 vec3_t original_origin;
542 vec3_t original_velocity;
543 vec3_t original_angles;
544 vec3_t original_avelocity;
548 VectorCopy(tossent->fields.server->origin , original_origin );
549 VectorCopy(tossent->fields.server->velocity , original_velocity );
550 VectorCopy(tossent->fields.server->angles , original_angles );
551 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
553 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
554 if (val != NULL && val->_float != 0)
555 gravity = val->_float;
558 gravity *= sv_gravity.value * 0.05;
560 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
562 SV_CheckVelocity (tossent);
563 tossent->fields.server->velocity[2] -= gravity;
564 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
565 VectorScale (tossent->fields.server->velocity, 0.05, move);
566 VectorAdd (tossent->fields.server->origin, move, end);
567 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
568 VectorCopy (trace.endpos, tossent->fields.server->origin);
570 if (trace.fraction < 1)
574 VectorCopy(original_origin , tossent->fields.server->origin );
575 VectorCopy(original_velocity , tossent->fields.server->velocity );
576 VectorCopy(original_angles , tossent->fields.server->angles );
577 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
582 static void VM_SV_tracetoss (void)
586 prvm_edict_t *ignore;
588 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
590 prog->xfunction->builtinsprofile += 600;
592 ent = PRVM_G_EDICT(OFS_PARM0);
593 if (ent == prog->edicts)
595 VM_Warning("tracetoss: can not use world entity\n");
598 ignore = PRVM_G_EDICT(OFS_PARM1);
600 trace = SV_Trace_Toss (ent, ignore);
602 VM_SetTraceGlobals(&trace);
605 //============================================================================
607 static int checkpvsbytes;
608 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
610 static int VM_SV_newcheckclient (int check)
616 // cycle to the next one
618 check = bound(1, check, svs.maxclients);
619 if (check == svs.maxclients)
627 prog->xfunction->builtinsprofile++;
629 if (i == svs.maxclients+1)
631 // look up the client's edict
632 ent = PRVM_EDICT_NUM(i);
633 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
634 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
636 // found a valid client (possibly the same one again)
640 // get the PVS for the entity
641 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
643 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
644 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
653 Returns a client (or object that has a client enemy) that would be a
656 If there is more than one valid option, they are cycled each frame
658 If (self.origin + self.viewofs) is not in the PVS of the current target,
659 it is not returned at all.
664 int c_invis, c_notvis;
665 static void VM_SV_checkclient (void)
667 prvm_edict_t *ent, *self;
670 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
672 // find a new check if on a new frame
673 if (sv.time - sv.lastchecktime >= 0.1)
675 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
676 sv.lastchecktime = sv.time;
679 // return check if it might be visible
680 ent = PRVM_EDICT_NUM(sv.lastcheck);
681 if (ent->priv.server->free || ent->fields.server->health <= 0)
683 VM_RETURN_EDICT(prog->edicts);
687 // if current entity can't possibly see the check entity, return 0
688 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
689 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
690 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
693 VM_RETURN_EDICT(prog->edicts);
697 // might be able to see it
699 VM_RETURN_EDICT(ent);
702 //============================================================================
709 Sends text over to the client's execution buffer
711 stuffcmd (clientent, value, ...)
714 static void VM_SV_stuffcmd (void)
718 char string[VM_STRINGTEMP_LENGTH];
720 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
722 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
723 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
725 VM_Warning("Can't stuffcmd to a non-client\n");
729 VM_VarString(1, string, sizeof(string));
732 host_client = svs.clients + entnum-1;
733 Host_ClientCommands ("%s", string);
741 Returns a chain of entities that have origins within a spherical area
743 findradius (origin, radius)
746 static void VM_SV_findradius (void)
748 prvm_edict_t *ent, *chain;
749 vec_t radius, radius2;
750 vec3_t org, eorg, mins, maxs;
753 prvm_edict_t *touchedicts[MAX_EDICTS];
755 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
757 chain = (prvm_edict_t *)prog->edicts;
759 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
760 radius = PRVM_G_FLOAT(OFS_PARM1);
761 radius2 = radius * radius;
763 mins[0] = org[0] - (radius + 1);
764 mins[1] = org[1] - (radius + 1);
765 mins[2] = org[2] - (radius + 1);
766 maxs[0] = org[0] + (radius + 1);
767 maxs[1] = org[1] + (radius + 1);
768 maxs[2] = org[2] + (radius + 1);
769 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
770 if (numtouchedicts > MAX_EDICTS)
772 // this never happens
773 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
774 numtouchedicts = MAX_EDICTS;
776 for (i = 0;i < numtouchedicts;i++)
778 ent = touchedicts[i];
779 prog->xfunction->builtinsprofile++;
780 // Quake did not return non-solid entities but darkplaces does
781 // (note: this is the reason you can't blow up fallen zombies)
782 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
784 // LordHavoc: compare against bounding box rather than center so it
785 // doesn't miss large objects, and use DotProduct instead of Length
786 // for a major speedup
787 VectorSubtract(org, ent->fields.server->origin, eorg);
788 if (sv_gameplayfix_findradiusdistancetobox.integer)
790 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
791 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
792 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
795 VectorMAMAM(1, eorg, 0.5f, ent->fields.server->mins, 0.5f, ent->fields.server->maxs, eorg);
796 if (DotProduct(eorg, eorg) < radius2)
798 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
803 VM_RETURN_EDICT(chain);
806 static void VM_SV_precache_sound (void)
808 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
809 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
810 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
813 static void VM_SV_precache_model (void)
815 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
816 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
817 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
824 float(float yaw, float dist[, settrace]) walkmove
827 static void VM_SV_walkmove (void)
836 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
838 // assume failure if it returns early
839 PRVM_G_FLOAT(OFS_RETURN) = 0;
841 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
842 if (ent == prog->edicts)
844 VM_Warning("walkmove: can not modify world entity\n");
847 if (ent->priv.server->free)
849 VM_Warning("walkmove: can not modify free entity\n");
852 yaw = PRVM_G_FLOAT(OFS_PARM0);
853 dist = PRVM_G_FLOAT(OFS_PARM1);
854 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
856 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
859 yaw = yaw*M_PI*2 / 360;
861 move[0] = cos(yaw)*dist;
862 move[1] = sin(yaw)*dist;
865 // save program state, because SV_movestep may call other progs
866 oldf = prog->xfunction;
867 oldself = prog->globals.server->self;
869 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
872 // restore program state
873 prog->xfunction = oldf;
874 prog->globals.server->self = oldself;
884 static void VM_SV_droptofloor (void)
890 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
892 // assume failure if it returns early
893 PRVM_G_FLOAT(OFS_RETURN) = 0;
895 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
896 if (ent == prog->edicts)
898 VM_Warning("droptofloor: can not modify world entity\n");
901 if (ent->priv.server->free)
903 VM_Warning("droptofloor: can not modify free entity\n");
907 VectorCopy (ent->fields.server->origin, end);
910 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
912 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
914 if (trace.fraction < 1)
915 VectorCopy (trace.endpos, ent->fields.server->origin);
916 SV_LinkEdict (ent, false);
917 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
918 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
919 PRVM_G_FLOAT(OFS_RETURN) = 1;
920 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
921 ent->priv.server->suspendedinairflag = true;
929 void(float style, string value) lightstyle
932 static void VM_SV_lightstyle (void)
939 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
941 style = (int)PRVM_G_FLOAT(OFS_PARM0);
942 val = PRVM_G_STRING(OFS_PARM1);
944 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
945 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
948 // change the string in sv
949 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
951 // send message to all clients on this server
952 if (sv.state != ss_active)
955 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
957 if (client->active && client->netconnection)
959 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
960 MSG_WriteChar (&client->netconnection->message,style);
961 MSG_WriteString (&client->netconnection->message, val);
971 static void VM_SV_checkbottom (void)
973 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
974 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
982 static void VM_SV_pointcontents (void)
984 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
985 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
992 Pick a vector for the player to shoot along
993 vector aim(entity, missilespeed)
996 static void VM_SV_aim (void)
998 prvm_edict_t *ent, *check, *bestent;
999 vec3_t start, dir, end, bestdir;
1002 float dist, bestdist;
1005 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1007 // assume failure if it returns early
1008 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1009 // if sv_aim is so high it can't possibly accept anything, skip out early
1010 if (sv_aim.value >= 1)
1013 ent = PRVM_G_EDICT(OFS_PARM0);
1014 if (ent == prog->edicts)
1016 VM_Warning("aim: can not use world entity\n");
1019 if (ent->priv.server->free)
1021 VM_Warning("aim: can not use free entity\n");
1024 speed = PRVM_G_FLOAT(OFS_PARM1);
1026 VectorCopy (ent->fields.server->origin, start);
1029 // try sending a trace straight
1030 VectorCopy (prog->globals.server->v_forward, dir);
1031 VectorMA (start, 2048, dir, end);
1032 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1033 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1034 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1036 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1041 // try all possible entities
1042 VectorCopy (dir, bestdir);
1043 bestdist = sv_aim.value;
1046 check = PRVM_NEXT_EDICT(prog->edicts);
1047 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1049 prog->xfunction->builtinsprofile++;
1050 if (check->fields.server->takedamage != DAMAGE_AIM)
1054 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1055 continue; // don't aim at teammate
1056 for (j=0 ; j<3 ; j++)
1057 end[j] = check->fields.server->origin[j]
1058 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1059 VectorSubtract (end, start, dir);
1060 VectorNormalize (dir);
1061 dist = DotProduct (dir, prog->globals.server->v_forward);
1062 if (dist < bestdist)
1063 continue; // to far to turn
1064 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1065 if (tr.ent == check)
1066 { // can shoot at this one
1074 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1075 dist = DotProduct (dir, prog->globals.server->v_forward);
1076 VectorScale (prog->globals.server->v_forward, dist, end);
1078 VectorNormalize (end);
1079 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1083 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1088 ===============================================================================
1092 ===============================================================================
1095 #define MSG_BROADCAST 0 // unreliable to all
1096 #define MSG_ONE 1 // reliable to one (msg_entity)
1097 #define MSG_ALL 2 // reliable to all
1098 #define MSG_INIT 3 // write to the init string
1099 #define MSG_ENTITY 5
1101 sizebuf_t *WriteDest (void)
1106 extern sizebuf_t *sv2csqcbuf;
1108 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1112 return &sv.datagram;
1115 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1116 entnum = PRVM_NUM_FOR_EDICT(ent);
1117 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1119 VM_Warning ("WriteDest: tried to write to non-client\n");
1120 return &sv.reliable_datagram;
1123 return &svs.clients[entnum-1].netconnection->message;
1126 VM_Warning ("WriteDest: bad destination\n");
1128 return &sv.reliable_datagram;
1140 static void VM_SV_WriteByte (void)
1142 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1143 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1146 static void VM_SV_WriteChar (void)
1148 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1149 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1152 static void VM_SV_WriteShort (void)
1154 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1155 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1158 static void VM_SV_WriteLong (void)
1160 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1161 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1164 static void VM_SV_WriteAngle (void)
1166 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1167 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1170 static void VM_SV_WriteCoord (void)
1172 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1173 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1176 static void VM_SV_WriteString (void)
1178 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1179 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1182 static void VM_SV_WriteUnterminatedString (void)
1184 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1185 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1189 static void VM_SV_WriteEntity (void)
1191 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1192 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1195 //////////////////////////////////////////////////////////
1197 static void VM_SV_makestatic (void)
1202 // allow 0 parameters due to an id1 qc bug in which this function is used
1203 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1204 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1206 if (prog->argc >= 1)
1207 ent = PRVM_G_EDICT(OFS_PARM0);
1209 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1210 if (ent == prog->edicts)
1212 VM_Warning("makestatic: can not modify world entity\n");
1215 if (ent->priv.server->free)
1217 VM_Warning("makestatic: can not modify free entity\n");
1222 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1227 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1228 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1229 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1233 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1234 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1235 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1238 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1239 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1240 for (i=0 ; i<3 ; i++)
1242 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1243 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1246 // throw the entity away now
1250 //=============================================================================
1257 static void VM_SV_setspawnparms (void)
1263 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1265 ent = PRVM_G_EDICT(OFS_PARM0);
1266 i = PRVM_NUM_FOR_EDICT(ent);
1267 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1269 Con_Print("tried to setspawnparms on a non-client\n");
1273 // copy spawn parms out of the client_t
1274 client = svs.clients + i-1;
1275 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1276 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1283 Returns a color vector indicating the lighting at the requested point.
1285 (Internal Operation note: actually measures the light beneath the point, just like
1286 the model lighting on the client)
1291 static void VM_SV_getlight (void)
1293 vec3_t ambientcolor, diffusecolor, diffusenormal;
1295 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1296 p = PRVM_G_VECTOR(OFS_PARM0);
1297 VectorClear(ambientcolor);
1298 VectorClear(diffusecolor);
1299 VectorClear(diffusenormal);
1300 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1301 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1302 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1307 unsigned char type; // 1/2/8 or other value if isn't used
1311 static autosentstat_t *vm_autosentstats = NULL; //[515]: it starts from 0, not 32
1312 static int vm_autosentstats_last;
1314 void VM_AutoSentStats_Clear (void)
1316 if(vm_autosentstats)
1318 Z_Free(vm_autosentstats);
1319 vm_autosentstats = NULL;
1320 vm_autosentstats_last = -1;
1324 //[515]: add check if even bigger ? "try to use two stats, cause it's too big" ?
1325 #define VM_SENDSTAT(a,b,c)\
1328 if((c)==(unsigned char)(c))\
1330 MSG_WriteByte((a), svc_updatestatubyte);\
1331 MSG_WriteByte((a), (b));\
1332 MSG_WriteByte((a), (c));\
1336 MSG_WriteByte((a), svc_updatestat);\
1337 MSG_WriteByte((a), (b));\
1338 MSG_WriteLong((a), (c));\
1342 void VM_SV_WriteAutoSentStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1354 if(!vm_autosentstats)
1357 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);
1359 for(i=0; i<vm_autosentstats_last+1 ;i++)
1361 if(!vm_autosentstats[i].type)
1363 switch(vm_autosentstats[i].type)
1367 t = PRVM_E_STRING(ent, vm_autosentstats[i].fieldoffset);
1375 stats[i+32] = si[0];
1376 stats[i+33] = si[1];
1377 stats[i+34] = si[2];
1378 stats[i+35] = si[3];
1382 VM_SENDSTAT(msg, i+32, si[0]);
1383 VM_SENDSTAT(msg, i+33, si[1]);
1384 VM_SENDSTAT(msg, i+34, si[2]);
1385 VM_SENDSTAT(msg, i+35, si[3]);
1391 k.f = PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ?
1392 k.i = LittleLong (k.i);
1396 VM_SENDSTAT(msg, i+32, k.i);
1400 v = (int)PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ?
1404 VM_SENDSTAT(msg, i+32, v);
1412 // void(float index, float type, .void field) SV_AddStat = #232;
1413 // Set up an auto-sent player stat.
1414 // Client's get thier own fields sent to them. Index may not be less than 32.
1415 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1416 // 1: string (4 stats carrying a total of 16 charactures)
1417 // 2: float (one stat, float converted to an integer for transportation)
1418 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1419 static void VM_SV_AddStat (void)
1424 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1426 if(!vm_autosentstats)
1428 vm_autosentstats = (autosentstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(autosentstat_t));
1429 if(!vm_autosentstats)
1431 VM_Warning("PF_SV_AddStat: not enough memory\n");
1435 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1436 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1437 off = PRVM_G_INT (OFS_PARM2);
1442 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1445 if(i >= (MAX_CL_STATS-32))
1447 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1450 if(i > (MAX_CL_STATS-32-4) && type == 1)
1452 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1455 vm_autosentstats[i].type = type;
1456 vm_autosentstats[i].fieldoffset = off;
1457 if(vm_autosentstats_last < i)
1458 vm_autosentstats_last = i;
1465 copies data from one entity to another
1467 copyentity(src, dst)
1470 static void VM_SV_copyentity (void)
1472 prvm_edict_t *in, *out;
1473 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1474 in = PRVM_G_EDICT(OFS_PARM0);
1475 if (in == prog->edicts)
1477 VM_Warning("copyentity: can not read world entity\n");
1480 if (in->priv.server->free)
1482 VM_Warning("copyentity: can not read free entity\n");
1485 out = PRVM_G_EDICT(OFS_PARM1);
1486 if (out == prog->edicts)
1488 VM_Warning("copyentity: can not modify world entity\n");
1491 if (out->priv.server->free)
1493 VM_Warning("copyentity: can not modify free entity\n");
1496 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1497 SV_LinkEdict(out, false);
1505 sets the color of a client and broadcasts the update to all connected clients
1507 setcolor(clientent, value)
1510 static void VM_SV_setcolor (void)
1516 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1517 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1518 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1520 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1522 Con_Print("tried to setcolor a non-client\n");
1526 client = svs.clients + entnum-1;
1529 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1531 client->edict->fields.server->team = (i & 15) + 1;
1534 if (client->old_colors != client->colors)
1536 client->old_colors = client->colors;
1537 // send notification to all clients
1538 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1539 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1540 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1548 effect(origin, modelname, startframe, framecount, framerate)
1551 static void VM_SV_effect (void)
1555 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1556 s = PRVM_G_STRING(OFS_PARM1);
1559 VM_Warning("effect: no model specified\n");
1563 i = SV_ModelIndex(s, 1);
1566 VM_Warning("effect: model not precached\n");
1570 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1572 VM_Warning("effect: framecount < 1\n");
1576 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1578 VM_Warning("effect: framerate < 1\n");
1582 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));
1585 static void VM_SV_te_blood (void)
1587 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1588 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1590 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1591 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1593 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1594 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1595 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1597 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1598 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1599 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1601 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1604 static void VM_SV_te_bloodshower (void)
1606 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1607 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1609 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1610 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1612 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1613 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1614 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1616 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1617 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1618 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1620 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1622 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1625 static void VM_SV_te_explosionrgb (void)
1627 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1628 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1629 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1631 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1632 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1633 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1635 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1636 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1637 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1640 static void VM_SV_te_particlecube (void)
1642 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1643 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1645 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1646 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1648 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1649 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1650 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1652 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1653 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1654 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1656 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1657 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1658 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1660 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1662 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1663 // gravity true/false
1664 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1666 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1669 static void VM_SV_te_particlerain (void)
1671 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1672 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1674 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1675 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1677 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1678 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1679 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1681 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1682 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1683 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1685 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1686 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1687 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1689 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1691 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1694 static void VM_SV_te_particlesnow (void)
1696 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1697 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1699 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1700 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1702 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1703 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1704 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1706 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1707 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1708 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1710 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1711 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1712 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1714 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1716 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1719 static void VM_SV_te_spark (void)
1721 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1722 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1724 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1725 MSG_WriteByte(&sv.datagram, TE_SPARK);
1727 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1728 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1729 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1731 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1732 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1733 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1735 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1738 static void VM_SV_te_gunshotquad (void)
1740 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1741 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1742 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1744 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1745 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1746 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1749 static void VM_SV_te_spikequad (void)
1751 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1752 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1753 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1755 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1756 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1757 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1760 static void VM_SV_te_superspikequad (void)
1762 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1763 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1764 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1766 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1767 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1768 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1771 static void VM_SV_te_explosionquad (void)
1773 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1774 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1775 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1777 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1778 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1779 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1782 static void VM_SV_te_smallflash (void)
1784 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1785 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1786 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1788 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1790 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1793 static void VM_SV_te_customflash (void)
1795 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1796 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1798 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1799 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1801 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1802 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1803 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1805 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1807 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1809 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1810 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1811 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1814 static void VM_SV_te_gunshot (void)
1816 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1817 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1818 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1820 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1821 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1822 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1825 static void VM_SV_te_spike (void)
1827 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1828 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1829 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1831 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1833 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1836 static void VM_SV_te_superspike (void)
1838 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1839 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1840 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1842 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1843 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1844 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1847 static void VM_SV_te_explosion (void)
1849 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1850 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1851 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1853 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1854 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1855 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1858 static void VM_SV_te_tarexplosion (void)
1860 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1861 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1862 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1864 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1865 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1866 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1869 static void VM_SV_te_wizspike (void)
1871 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1872 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1873 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1875 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1876 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1877 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1880 static void VM_SV_te_knightspike (void)
1882 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1883 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1884 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1886 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1887 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1888 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1891 static void VM_SV_te_lavasplash (void)
1893 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1894 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1895 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1897 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1898 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1899 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1902 static void VM_SV_te_teleport (void)
1904 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1905 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1906 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1908 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1909 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1910 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1913 static void VM_SV_te_explosion2 (void)
1915 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1916 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1917 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1919 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1920 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1921 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1923 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1924 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1927 static void VM_SV_te_lightning1 (void)
1929 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1930 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1931 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1933 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1935 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1936 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1937 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1939 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1940 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1941 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1944 static void VM_SV_te_lightning2 (void)
1946 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1947 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1948 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1950 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1952 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1953 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1954 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1956 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1957 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1958 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1961 static void VM_SV_te_lightning3 (void)
1963 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1964 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1965 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1967 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1969 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1970 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1974 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1978 static void VM_SV_te_beam (void)
1980 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1981 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1982 MSG_WriteByte(&sv.datagram, TE_BEAM);
1984 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1986 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1987 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1988 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1990 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1991 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1992 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1995 static void VM_SV_te_plasmaburn (void)
1997 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
1998 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1999 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2000 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2001 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2002 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2005 static void VM_SV_te_flamejet (void)
2007 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2008 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2009 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2011 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2012 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2013 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2015 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2016 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2017 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2019 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2022 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2025 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2027 bestdist = 1000000000;
2029 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2031 // clip original point to each triangle of the surface and find the
2032 // triangle that is closest
2033 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2034 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2035 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2036 TriangleNormal(v[0], v[1], v[2], facenormal);
2037 VectorNormalize(facenormal);
2038 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2039 VectorMA(p, offsetdist, facenormal, temp);
2040 for (j = 0, k = 2;j < 3;k = j, j++)
2042 VectorSubtract(v[k], v[j], edgenormal);
2043 CrossProduct(edgenormal, facenormal, sidenormal);
2044 VectorNormalize(sidenormal);
2045 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2047 VectorMA(temp, offsetdist, sidenormal, temp);
2049 dist = VectorDistance2(temp, p);
2050 if (bestdist > dist)
2053 VectorCopy(temp, out);
2058 static model_t *getmodel(prvm_edict_t *ed)
2061 if (!ed || ed->priv.server->free)
2063 modelindex = (int)ed->fields.server->modelindex;
2064 if (modelindex < 1 || modelindex >= MAX_MODELS)
2066 return sv.models[modelindex];
2069 static msurface_t *getsurface(model_t *model, int surfacenum)
2071 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2073 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2077 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2078 static void VM_SV_getsurfacenumpoints(void)
2081 msurface_t *surface;
2082 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2083 // return 0 if no such surface
2084 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2086 PRVM_G_FLOAT(OFS_RETURN) = 0;
2090 // note: this (incorrectly) assumes it is a simple polygon
2091 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2093 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2094 static void VM_SV_getsurfacepoint(void)
2098 msurface_t *surface;
2100 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2101 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2102 ed = PRVM_G_EDICT(OFS_PARM0);
2103 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2105 // note: this (incorrectly) assumes it is a simple polygon
2106 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2107 if (pointnum < 0 || pointnum >= surface->num_vertices)
2109 // FIXME: implement rotation/scaling
2110 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2112 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2113 static void VM_SV_getsurfacenormal(void)
2116 msurface_t *surface;
2118 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2119 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2120 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2122 // FIXME: implement rotation/scaling
2123 // note: this (incorrectly) assumes it is a simple polygon
2124 // note: this only returns the first triangle, so it doesn't work very
2125 // well for curved surfaces or arbitrary meshes
2126 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);
2127 VectorNormalize(normal);
2128 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2130 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2131 static void VM_SV_getsurfacetexture(void)
2134 msurface_t *surface;
2135 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2136 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2137 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2139 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2141 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2142 static void VM_SV_getsurfacenearpoint(void)
2144 int surfacenum, best;
2146 vec_t dist, bestdist;
2149 msurface_t *surface;
2151 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2152 PRVM_G_FLOAT(OFS_RETURN) = -1;
2153 ed = PRVM_G_EDICT(OFS_PARM0);
2154 point = PRVM_G_VECTOR(OFS_PARM1);
2156 if (!ed || ed->priv.server->free)
2158 model = getmodel(ed);
2159 if (!model || !model->num_surfaces)
2162 // FIXME: implement rotation/scaling
2163 VectorSubtract(point, ed->fields.server->origin, p);
2165 bestdist = 1000000000;
2166 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2168 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2169 // first see if the nearest point on the surface's box is closer than the previous match
2170 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2171 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2172 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2173 dist = VectorLength2(clipped);
2174 if (dist < bestdist)
2176 // it is, check the nearest point on the actual geometry
2177 clippointtosurface(model, surface, p, clipped);
2178 VectorSubtract(clipped, p, clipped);
2179 dist += VectorLength2(clipped);
2180 if (dist < bestdist)
2182 // that's closer too, store it as the best match
2188 PRVM_G_FLOAT(OFS_RETURN) = best;
2190 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2191 static void VM_SV_getsurfaceclippedpoint(void)
2195 msurface_t *surface;
2197 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2198 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2199 ed = PRVM_G_EDICT(OFS_PARM0);
2200 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2202 // FIXME: implement rotation/scaling
2203 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2204 clippointtosurface(model, surface, p, out);
2205 // FIXME: implement rotation/scaling
2206 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2209 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2210 //this function originally written by KrimZon, made shorter by LordHavoc
2211 static void VM_SV_clientcommand (void)
2213 client_t *temp_client;
2215 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2217 //find client for this entity
2218 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2219 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2221 Con_Print("PF_clientcommand: entity is not a client\n");
2225 temp_client = host_client;
2226 host_client = svs.clients + i;
2227 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2228 host_client = temp_client;
2231 //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)
2232 static void VM_SV_setattachment (void)
2234 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2235 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2236 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2240 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2242 if (e == prog->edicts)
2244 VM_Warning("setattachment: can not modify world entity\n");
2247 if (e->priv.server->free)
2249 VM_Warning("setattachment: can not modify free entity\n");
2253 if (tagentity == NULL)
2254 tagentity = prog->edicts;
2256 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2258 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2260 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2263 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2265 modelindex = (int)tagentity->fields.server->modelindex;
2266 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2268 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2270 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);
2273 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));
2277 /////////////////////////////////////////
2278 // DP_MD3_TAGINFO extension coded by VorteX
2280 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2285 i = (int)e->fields.server->modelindex;
2286 if (i < 1 || i >= MAX_MODELS)
2288 model = sv.models[i];
2290 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2293 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2295 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2299 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);
2301 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);
2304 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2310 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2311 && (model = sv.models[(int)ent->fields.server->modelindex])
2312 && model->animscenes)
2314 // if model has wrong frame, engine automatically switches to model first frame
2315 frame = (int)ent->fields.server->frame;
2316 if (frame < 0 || frame >= model->numframes)
2318 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2320 *out = identitymatrix;
2324 // Warnings/errors code:
2325 // 0 - normal (everything all-right)
2328 // 3 - null or non-precached model
2329 // 4 - no tags with requested index
2330 // 5 - runaway loop at attachment chain
2331 extern cvar_t cl_bob;
2332 extern cvar_t cl_bobcycle;
2333 extern cvar_t cl_bobup;
2334 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2338 int modelindex, attachloop;
2339 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2342 *out = identitymatrix; // warnings and errors return identical matrix
2344 if (ent == prog->edicts)
2346 if (ent->priv.server->free)
2349 modelindex = (int)ent->fields.server->modelindex;
2350 if (modelindex <= 0 || modelindex > MAX_MODELS)
2353 model = sv.models[modelindex];
2355 tagmatrix = identitymatrix;
2356 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2360 if (attachloop >= 256) // prevent runaway looping
2362 // apply transformation by child's tagindex on parent entity and then
2363 // by parent entity itself
2364 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2365 if (ret && attachloop == 0)
2367 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2368 SV_GetEntityMatrix(ent, &entitymatrix, false);
2369 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2370 // next iteration we process the parent entity
2371 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2373 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2374 ent = PRVM_EDICT_NUM(val->edict);
2381 // RENDER_VIEWMODEL magic
2382 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2384 Matrix4x4_Copy(&tagmatrix, out);
2385 ent = PRVM_EDICT_NUM(val->edict);
2387 SV_GetEntityMatrix(ent, &entitymatrix, true);
2388 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2391 // Cl_bob, ported from rendering code
2392 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2395 // LordHavoc: this code is *weird*, but not replacable (I think it
2396 // should be done in QC on the server, but oh well, quake is quake)
2397 // LordHavoc: figured out bobup: the time at which the sin is at 180
2398 // degrees (which allows lengthening or squishing the peak or valley)
2399 cycle = sv.time/cl_bobcycle.value;
2400 cycle -= (int)cycle;
2401 if (cycle < cl_bobup.value)
2402 cycle = sin(M_PI * cycle / cl_bobup.value);
2404 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2405 // bob is proportional to velocity in the xy plane
2406 // (don't count Z, or jumping messes it up)
2407 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;
2408 bob = bob*0.3 + bob*0.7*cycle;
2409 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2416 //float(entity ent, string tagname) gettagindex;
2418 static void VM_SV_gettagindex (void)
2421 const char *tag_name;
2422 int modelindex, tag_index;
2424 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2426 ent = PRVM_G_EDICT(OFS_PARM0);
2427 tag_name = PRVM_G_STRING(OFS_PARM1);
2429 if (ent == prog->edicts)
2431 VM_Warning("gettagindex: can't affect world entity\n");
2434 if (ent->priv.server->free)
2436 VM_Warning("gettagindex: can't affect free entity\n");
2440 modelindex = (int)ent->fields.server->modelindex;
2442 if (modelindex <= 0 || modelindex > MAX_MODELS)
2443 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2446 tag_index = SV_GetTagIndex(ent, tag_name);
2448 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2450 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2453 //vector(entity ent, float tagindex) gettaginfo;
2454 static void VM_SV_gettaginfo (void)
2458 matrix4x4_t tag_matrix;
2461 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2463 e = PRVM_G_EDICT(OFS_PARM0);
2464 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2466 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2467 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2472 VM_Warning("gettagindex: can't affect world entity\n");
2475 VM_Warning("gettagindex: can't affect free entity\n");
2478 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2481 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2484 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2489 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2490 static void VM_SV_dropclient (void)
2493 client_t *oldhostclient;
2494 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2495 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2496 if (clientnum < 0 || clientnum >= svs.maxclients)
2498 VM_Warning("dropclient: not a client\n");
2501 if (!svs.clients[clientnum].active)
2503 VM_Warning("dropclient: that client slot is not connected\n");
2506 oldhostclient = host_client;
2507 host_client = svs.clients + clientnum;
2508 SV_DropClient(false);
2509 host_client = oldhostclient;
2512 //entity() spawnclient (DP_SV_BOTCLIENT)
2513 static void VM_SV_spawnclient (void)
2517 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2518 prog->xfunction->builtinsprofile += 2;
2520 for (i = 0;i < svs.maxclients;i++)
2522 if (!svs.clients[i].active)
2524 prog->xfunction->builtinsprofile += 100;
2525 SV_ConnectClient (i, NULL);
2526 // this has to be set or else ClientDisconnect won't be called
2527 // we assume the qc will call ClientConnect...
2528 svs.clients[i].clientconnectcalled = true;
2529 ed = PRVM_EDICT_NUM(i + 1);
2533 VM_RETURN_EDICT(ed);
2536 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2537 static void VM_SV_clienttype (void)
2540 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2541 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2542 if (clientnum < 0 || clientnum >= svs.maxclients)
2543 PRVM_G_FLOAT(OFS_RETURN) = 3;
2544 else if (!svs.clients[clientnum].active)
2545 PRVM_G_FLOAT(OFS_RETURN) = 0;
2546 else if (svs.clients[clientnum].netconnection)
2547 PRVM_G_FLOAT(OFS_RETURN) = 1;
2549 PRVM_G_FLOAT(OFS_RETURN) = 2;
2556 string(string key) serverkey
2559 void VM_SV_serverkey(void)
2561 char string[VM_STRINGTEMP_LENGTH];
2562 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2563 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2564 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2567 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2568 static void VM_SV_setmodelindex (void)
2573 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2575 e = PRVM_G_EDICT(OFS_PARM0);
2576 if (e == prog->edicts)
2578 VM_Warning("setmodelindex: can not modify world entity\n");
2581 if (e->priv.server->free)
2583 VM_Warning("setmodelindex: can not modify free entity\n");
2586 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2587 if (i <= 0 || i > MAX_MODELS)
2589 VM_Warning("setmodelindex: invalid modelindex\n");
2592 if (!sv.model_precache[i][0])
2594 VM_Warning("setmodelindex: model not precached\n");
2598 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2599 e->fields.server->modelindex = i;
2605 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2606 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2608 SetMinMaxSize (e, quakemins, quakemaxs, true);
2611 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2614 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2615 static void VM_SV_modelnameforindex (void)
2618 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2620 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2622 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2623 if (i <= 0 || i > MAX_MODELS)
2625 VM_Warning("modelnameforindex: invalid modelindex\n");
2628 if (!sv.model_precache[i][0])
2630 VM_Warning("modelnameforindex: model not precached\n");
2634 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2637 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2638 static void VM_SV_particleeffectnum (void)
2641 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2642 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2645 PRVM_G_FLOAT(OFS_RETURN) = i;
2648 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2649 static void VM_SV_trailparticles (void)
2651 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2653 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2654 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2655 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2656 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2657 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2660 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2661 static void VM_SV_pointparticles (void)
2663 VM_SAFEPARMCOUNT(4, VM_SV_pointparticles);
2665 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2666 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM0));
2667 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1), sv.protocol);
2668 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2669 MSG_WriteShort(&sv.datagram, bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535));
2672 prvm_builtin_t vm_sv_builtins[] = {
2673 NULL, // #0 NULL function (not callable) (QUAKE)
2674 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2675 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2676 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2677 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2678 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2679 VM_break, // #6 void() break (QUAKE)
2680 VM_random, // #7 float() random (QUAKE)
2681 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2682 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2683 VM_error, // #10 void(string e) error (QUAKE)
2684 VM_objerror, // #11 void(string e) objerror (QUAKE)
2685 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2686 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2687 VM_spawn, // #14 entity() spawn (QUAKE)
2688 VM_remove, // #15 void(entity e) remove (QUAKE)
2689 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2690 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2691 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2692 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2693 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2694 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2695 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2696 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2697 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2698 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2699 VM_ftos, // #26 string(float f) ftos (QUAKE)
2700 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2701 VM_coredump, // #28 void() coredump (QUAKE)
2702 VM_traceon, // #29 void() traceon (QUAKE)
2703 VM_traceoff, // #30 void() traceoff (QUAKE)
2704 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2705 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2706 NULL, // #33 (QUAKE)
2707 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2708 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2709 VM_rint, // #36 float(float v) rint (QUAKE)
2710 VM_floor, // #37 float(float v) floor (QUAKE)
2711 VM_ceil, // #38 float(float v) ceil (QUAKE)
2712 NULL, // #39 (QUAKE)
2713 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2714 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2715 NULL, // #42 (QUAKE)
2716 VM_fabs, // #43 float(float f) fabs (QUAKE)
2717 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2718 VM_cvar, // #45 float(string s) cvar (QUAKE)
2719 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2720 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2721 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2722 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2723 NULL, // #50 (QUAKE)
2724 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2725 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2726 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2727 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2728 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2729 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2730 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2731 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2732 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2733 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2734 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2735 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2736 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2737 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2738 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2739 NULL, // #66 (QUAKE)
2740 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2741 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2742 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2743 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2744 NULL, // #71 (QUAKE)
2745 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2746 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2747 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2748 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2749 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2750 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2751 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2752 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2753 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2754 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2755 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2756 NULL, // #83 (QUAKE)
2757 NULL, // #84 (QUAKE)
2758 NULL, // #85 (QUAKE)
2759 NULL, // #86 (QUAKE)
2760 NULL, // #87 (QUAKE)
2761 NULL, // #88 (QUAKE)
2762 NULL, // #89 (QUAKE)
2763 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2764 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2765 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2766 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2767 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2768 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2769 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2770 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2771 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2772 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2773 // FrikaC and Telejano range #100-#199
2784 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2785 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2786 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2787 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2788 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2789 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2790 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2791 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2792 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2793 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2874 // FTEQW range #200-#299
2893 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2897 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2898 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2903 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2907 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2975 // CSQC range #300-#399
2976 NULL, // #300 void() clearscene (EXT_CSQC)
2977 NULL, // #301 void(float mask) addentities (EXT_CSQC)
2978 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
2979 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
2980 NULL, // #304 void() renderscene (EXT_CSQC)
2981 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2982 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2983 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2984 NULL, // #308 void() R_EndPolygon
2986 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
2987 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
2991 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
2992 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
2993 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
2994 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
2995 NULL, // #319 void(string name) freepic (EXT_CSQC)
2996 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
2997 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
2998 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
2999 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3000 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3001 NULL, // #325 void(void) drawresetcliparea
3006 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3007 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3008 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3009 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3010 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3011 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3012 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3013 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3014 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3015 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3016 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3017 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3018 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3019 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3020 NULL, // #344 vector() getmousepos (EXT_CSQC)
3021 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3022 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3023 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3024 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3025 NULL, // #349 float() isdemo (EXT_CSQC)
3026 VM_isserver, // #350 float() isserver (EXT_CSQC)
3027 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3028 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3029 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3030 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3036 NULL, // #360 float() readbyte (EXT_CSQC)
3037 NULL, // #361 float() readchar (EXT_CSQC)
3038 NULL, // #362 float() readshort (EXT_CSQC)
3039 NULL, // #363 float() readlong (EXT_CSQC)
3040 NULL, // #364 float() readcoord (EXT_CSQC)
3041 NULL, // #365 float() readangle (EXT_CSQC)
3042 NULL, // #366 string() readstring (EXT_CSQC)
3043 NULL, // #367 float() readfloat (EXT_CSQC)
3076 // LordHavoc's range #400-#499
3077 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3078 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3079 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3080 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3081 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3082 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3083 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3084 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3085 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)
3086 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3087 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3088 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3089 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3090 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3091 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3092 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3093 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3094 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3095 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3096 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3097 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3098 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3099 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3100 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3101 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3102 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3103 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3104 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3105 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3106 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3107 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3108 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3109 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3110 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3111 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3112 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3113 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3114 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3115 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3116 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3117 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3118 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3119 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3120 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3121 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
3122 VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
3123 VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
3124 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
3125 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3126 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3127 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3128 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3129 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3130 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3131 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3132 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3133 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3134 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3136 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3137 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3138 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3139 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3140 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3141 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3142 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3143 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3144 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3145 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3146 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3148 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3149 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3150 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3151 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3152 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3153 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3154 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3155 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3179 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3181 void VM_SV_Cmd_Init(void)
3186 void VM_SV_Cmd_Reset(void)