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 "
73 "DP_QC_TOKENIZEBYSEPARATOR "
76 "DP_QC_TRACE_MOVETYPE_HITMODEL "
77 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
78 "DP_QC_UNLIMITEDTEMPSTRINGS "
79 "DP_QC_VECTORVECTORS "
85 "DP_SND_DIRECTIONLESSATTNNONE "
94 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
95 "DP_SV_DRAWONLYTOCLIENT "
98 "DP_SV_ENTITYCONTENTSTRANSITION "
99 "DP_SV_NODRAWTOCLIENT "
101 "DP_SV_PLAYERPHYSICS "
102 "DP_SV_PRECACHEANYTIME "
105 "DP_SV_ROTATINGBMODEL "
108 "DP_SV_WRITEUNTERMINATEDSTRING "
112 "DP_TE_EXPLOSIONRGB "
114 "DP_TE_PARTICLECUBE "
115 "DP_TE_PARTICLERAIN "
116 "DP_TE_PARTICLESNOW "
118 "DP_TE_QUADEFFECTS1 "
121 "DP_TE_STANDARDEFFECTBUILTINS "
122 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
125 //"EXT_CSQC " // not ready yet
127 "KRIMZON_SV_PARSECLIENTCOMMAND "
130 "NEXUIZ_PLAYERMODEL "
132 "PRYDON_CLIENTCURSOR "
133 "TENEBRAE_GFX_DLIGHTS "
141 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.
143 setorigin (entity, origin)
146 static void VM_SV_setorigin (void)
151 VM_SAFEPARMCOUNT(2, VM_setorigin);
153 e = PRVM_G_EDICT(OFS_PARM0);
154 if (e == prog->edicts)
156 VM_Warning("setorigin: can not modify world entity\n");
159 if (e->priv.server->free)
161 VM_Warning("setorigin: can not modify free entity\n");
164 org = PRVM_G_VECTOR(OFS_PARM1);
165 VectorCopy (org, e->fields.server->origin);
166 SV_LinkEdict (e, false);
170 void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
174 for (i=0 ; i<3 ; i++)
176 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
178 // set derived values
179 VectorCopy (min, e->fields.server->mins);
180 VectorCopy (max, e->fields.server->maxs);
181 VectorSubtract (max, min, e->fields.server->size);
183 SV_LinkEdict (e, false);
190 the size box is rotated by the current angle
191 LordHavoc: no it isn't...
193 setsize (entity, minvector, maxvector)
196 static void VM_SV_setsize (void)
201 VM_SAFEPARMCOUNT(3, VM_setsize);
203 e = PRVM_G_EDICT(OFS_PARM0);
204 if (e == prog->edicts)
206 VM_Warning("setsize: can not modify world entity\n");
209 if (e->priv.server->free)
211 VM_Warning("setsize: can not modify free entity\n");
214 min = PRVM_G_VECTOR(OFS_PARM1);
215 max = PRVM_G_VECTOR(OFS_PARM2);
216 SetMinMaxSize (e, min, max, false);
224 setmodel(entity, model)
227 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
228 static void VM_SV_setmodel (void)
234 VM_SAFEPARMCOUNT(2, VM_setmodel);
236 e = PRVM_G_EDICT(OFS_PARM0);
237 if (e == prog->edicts)
239 VM_Warning("setmodel: can not modify world entity\n");
242 if (e->priv.server->free)
244 VM_Warning("setmodel: can not modify free entity\n");
247 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
248 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
249 e->fields.server->modelindex = i;
255 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
256 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
258 SetMinMaxSize (e, quakemins, quakemaxs, true);
261 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
268 single print to a specific client
270 sprint(clientent, value)
273 static void VM_SV_sprint (void)
277 char string[VM_STRINGTEMP_LENGTH];
279 VM_VarString(1, string, sizeof(string));
281 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
283 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
284 // LordHavoc: div0 requested that sprintto world operate like print
291 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
293 VM_Warning("tried to centerprint to a non-client\n");
297 client = svs.clients + entnum-1;
298 if (!client->netconnection)
301 MSG_WriteChar(&client->netconnection->message,svc_print);
302 MSG_WriteString(&client->netconnection->message, string);
310 single print to a specific client
312 centerprint(clientent, value)
315 static void VM_SV_centerprint (void)
319 char string[VM_STRINGTEMP_LENGTH];
321 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
323 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
325 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
327 VM_Warning("tried to centerprint to a non-client\n");
331 client = svs.clients + entnum-1;
332 if (!client->netconnection)
335 VM_VarString(1, string, sizeof(string));
336 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
337 MSG_WriteString(&client->netconnection->message, string);
344 particle(origin, color, count)
347 static void VM_SV_particle (void)
353 VM_SAFEPARMCOUNT(4, VM_SV_particle);
355 org = PRVM_G_VECTOR(OFS_PARM0);
356 dir = PRVM_G_VECTOR(OFS_PARM1);
357 color = PRVM_G_FLOAT(OFS_PARM2);
358 count = PRVM_G_FLOAT(OFS_PARM3);
359 SV_StartParticle (org, dir, (int)color, (int)count);
369 static void VM_SV_ambientsound (void)
373 float vol, attenuation;
376 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
378 pos = PRVM_G_VECTOR (OFS_PARM0);
379 samp = PRVM_G_STRING(OFS_PARM1);
380 vol = PRVM_G_FLOAT(OFS_PARM2);
381 attenuation = PRVM_G_FLOAT(OFS_PARM3);
383 // check to see if samp was properly precached
384 soundnum = SV_SoundIndex(samp, 1);
392 // add an svc_spawnambient command to the level signon packet
395 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
397 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
399 MSG_WriteVector(&sv.signon, pos, sv.protocol);
402 MSG_WriteShort (&sv.signon, soundnum);
404 MSG_WriteByte (&sv.signon, soundnum);
406 MSG_WriteByte (&sv.signon, (int)(vol*255));
407 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
415 Each entity can have eight independant sound sources, like voice,
418 Channel 0 is an auto-allocate channel, the others override anything
419 already running on that entity/channel pair.
421 An attenuation of 0 will play full volume everywhere in the level.
422 Larger attenuations will drop off.
426 static void VM_SV_sound (void)
430 prvm_edict_t *entity;
434 VM_SAFEPARMCOUNT(5, VM_SV_sound);
436 entity = PRVM_G_EDICT(OFS_PARM0);
437 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
438 sample = PRVM_G_STRING(OFS_PARM2);
439 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
440 attenuation = PRVM_G_FLOAT(OFS_PARM4);
442 if (volume < 0 || volume > 255)
444 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
448 if (attenuation < 0 || attenuation > 4)
450 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
454 if (channel < 0 || channel > 7)
456 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
460 SV_StartSound (entity, channel, sample, volume, attenuation);
467 Used for use tracing and shot targeting
468 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
469 if the tryents flag is set.
471 traceline (vector1, vector2, movetype, ignore)
474 static void VM_SV_traceline (void)
481 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
483 prog->xfunction->builtinsprofile += 30;
485 v1 = PRVM_G_VECTOR(OFS_PARM0);
486 v2 = PRVM_G_VECTOR(OFS_PARM1);
487 move = (int)PRVM_G_FLOAT(OFS_PARM2);
488 ent = PRVM_G_EDICT(OFS_PARM3);
490 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]))
491 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));
493 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
495 VM_SetTraceGlobals(&trace);
503 Used for use tracing and shot targeting
504 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
505 if the tryents flag is set.
507 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
510 // LordHavoc: added this for my own use, VERY useful, similar to traceline
511 static void VM_SV_tracebox (void)
513 float *v1, *v2, *m1, *m2;
518 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
520 prog->xfunction->builtinsprofile += 30;
522 v1 = PRVM_G_VECTOR(OFS_PARM0);
523 m1 = PRVM_G_VECTOR(OFS_PARM1);
524 m2 = PRVM_G_VECTOR(OFS_PARM2);
525 v2 = PRVM_G_VECTOR(OFS_PARM3);
526 move = (int)PRVM_G_FLOAT(OFS_PARM4);
527 ent = PRVM_G_EDICT(OFS_PARM5);
529 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]))
530 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));
532 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
534 VM_SetTraceGlobals(&trace);
537 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
542 vec3_t original_origin;
543 vec3_t original_velocity;
544 vec3_t original_angles;
545 vec3_t original_avelocity;
549 VectorCopy(tossent->fields.server->origin , original_origin );
550 VectorCopy(tossent->fields.server->velocity , original_velocity );
551 VectorCopy(tossent->fields.server->angles , original_angles );
552 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
554 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
555 if (val != NULL && val->_float != 0)
556 gravity = val->_float;
559 gravity *= sv_gravity.value * 0.05;
561 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
563 SV_CheckVelocity (tossent);
564 tossent->fields.server->velocity[2] -= gravity;
565 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
566 VectorScale (tossent->fields.server->velocity, 0.05, move);
567 VectorAdd (tossent->fields.server->origin, move, end);
568 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
569 VectorCopy (trace.endpos, tossent->fields.server->origin);
571 if (trace.fraction < 1)
575 VectorCopy(original_origin , tossent->fields.server->origin );
576 VectorCopy(original_velocity , tossent->fields.server->velocity );
577 VectorCopy(original_angles , tossent->fields.server->angles );
578 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
583 static void VM_SV_tracetoss (void)
587 prvm_edict_t *ignore;
589 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
591 prog->xfunction->builtinsprofile += 600;
593 ent = PRVM_G_EDICT(OFS_PARM0);
594 if (ent == prog->edicts)
596 VM_Warning("tracetoss: can not use world entity\n");
599 ignore = PRVM_G_EDICT(OFS_PARM1);
601 trace = SV_Trace_Toss (ent, ignore);
603 VM_SetTraceGlobals(&trace);
606 //============================================================================
608 static int checkpvsbytes;
609 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
611 static int VM_SV_newcheckclient (int check)
617 // cycle to the next one
619 check = bound(1, check, svs.maxclients);
620 if (check == svs.maxclients)
628 prog->xfunction->builtinsprofile++;
630 if (i == svs.maxclients+1)
632 // look up the client's edict
633 ent = PRVM_EDICT_NUM(i);
634 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
635 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
637 // found a valid client (possibly the same one again)
641 // get the PVS for the entity
642 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
644 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
645 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
654 Returns a client (or object that has a client enemy) that would be a
657 If there is more than one valid option, they are cycled each frame
659 If (self.origin + self.viewofs) is not in the PVS of the current target,
660 it is not returned at all.
665 int c_invis, c_notvis;
666 static void VM_SV_checkclient (void)
668 prvm_edict_t *ent, *self;
671 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
673 // find a new check if on a new frame
674 if (sv.time - sv.lastchecktime >= 0.1)
676 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
677 sv.lastchecktime = sv.time;
680 // return check if it might be visible
681 ent = PRVM_EDICT_NUM(sv.lastcheck);
682 if (ent->priv.server->free || ent->fields.server->health <= 0)
684 VM_RETURN_EDICT(prog->edicts);
688 // if current entity can't possibly see the check entity, return 0
689 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
690 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
691 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
694 VM_RETURN_EDICT(prog->edicts);
698 // might be able to see it
700 VM_RETURN_EDICT(ent);
703 //============================================================================
710 Sends text over to the client's execution buffer
712 stuffcmd (clientent, value, ...)
715 static void VM_SV_stuffcmd (void)
719 char string[VM_STRINGTEMP_LENGTH];
721 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
723 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
724 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
726 VM_Warning("Can't stuffcmd to a non-client\n");
730 VM_VarString(1, string, sizeof(string));
733 host_client = svs.clients + entnum-1;
734 Host_ClientCommands ("%s", string);
742 Returns a chain of entities that have origins within a spherical area
744 findradius (origin, radius)
747 static void VM_SV_findradius (void)
749 prvm_edict_t *ent, *chain;
750 vec_t radius, radius2;
751 vec3_t org, eorg, mins, maxs;
754 prvm_edict_t *touchedicts[MAX_EDICTS];
756 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
758 chain = (prvm_edict_t *)prog->edicts;
760 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
761 radius = PRVM_G_FLOAT(OFS_PARM1);
762 radius2 = radius * radius;
764 mins[0] = org[0] - (radius + 1);
765 mins[1] = org[1] - (radius + 1);
766 mins[2] = org[2] - (radius + 1);
767 maxs[0] = org[0] + (radius + 1);
768 maxs[1] = org[1] + (radius + 1);
769 maxs[2] = org[2] + (radius + 1);
770 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
771 if (numtouchedicts > MAX_EDICTS)
773 // this never happens
774 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
775 numtouchedicts = MAX_EDICTS;
777 for (i = 0;i < numtouchedicts;i++)
779 ent = touchedicts[i];
780 prog->xfunction->builtinsprofile++;
781 // Quake did not return non-solid entities but darkplaces does
782 // (note: this is the reason you can't blow up fallen zombies)
783 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
785 // LordHavoc: compare against bounding box rather than center so it
786 // doesn't miss large objects, and use DotProduct instead of Length
787 // for a major speedup
788 VectorSubtract(org, ent->fields.server->origin, eorg);
789 if (sv_gameplayfix_findradiusdistancetobox.integer)
791 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
792 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
793 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
796 VectorMAMAM(1, eorg, 0.5f, ent->fields.server->mins, 0.5f, ent->fields.server->maxs, eorg);
797 if (DotProduct(eorg, eorg) < radius2)
799 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
804 VM_RETURN_EDICT(chain);
807 static void VM_SV_precache_sound (void)
809 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
810 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
811 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
814 static void VM_SV_precache_model (void)
816 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
817 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
818 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
825 float(float yaw, float dist[, settrace]) walkmove
828 static void VM_SV_walkmove (void)
837 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
839 // assume failure if it returns early
840 PRVM_G_FLOAT(OFS_RETURN) = 0;
842 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
843 if (ent == prog->edicts)
845 VM_Warning("walkmove: can not modify world entity\n");
848 if (ent->priv.server->free)
850 VM_Warning("walkmove: can not modify free entity\n");
853 yaw = PRVM_G_FLOAT(OFS_PARM0);
854 dist = PRVM_G_FLOAT(OFS_PARM1);
855 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
857 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
860 yaw = yaw*M_PI*2 / 360;
862 move[0] = cos(yaw)*dist;
863 move[1] = sin(yaw)*dist;
866 // save program state, because SV_movestep may call other progs
867 oldf = prog->xfunction;
868 oldself = prog->globals.server->self;
870 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
873 // restore program state
874 prog->xfunction = oldf;
875 prog->globals.server->self = oldself;
885 static void VM_SV_droptofloor (void)
891 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
893 // assume failure if it returns early
894 PRVM_G_FLOAT(OFS_RETURN) = 0;
896 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
897 if (ent == prog->edicts)
899 VM_Warning("droptofloor: can not modify world entity\n");
902 if (ent->priv.server->free)
904 VM_Warning("droptofloor: can not modify free entity\n");
908 VectorCopy (ent->fields.server->origin, end);
911 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
913 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
915 if (trace.fraction < 1)
916 VectorCopy (trace.endpos, ent->fields.server->origin);
917 SV_LinkEdict (ent, false);
918 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
919 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
920 PRVM_G_FLOAT(OFS_RETURN) = 1;
921 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
922 ent->priv.server->suspendedinairflag = true;
930 void(float style, string value) lightstyle
933 static void VM_SV_lightstyle (void)
940 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
942 style = (int)PRVM_G_FLOAT(OFS_PARM0);
943 val = PRVM_G_STRING(OFS_PARM1);
945 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
946 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
949 // change the string in sv
950 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
952 // send message to all clients on this server
953 if (sv.state != ss_active)
956 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
958 if (client->active && client->netconnection)
960 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
961 MSG_WriteChar (&client->netconnection->message,style);
962 MSG_WriteString (&client->netconnection->message, val);
972 static void VM_SV_checkbottom (void)
974 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
975 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
983 static void VM_SV_pointcontents (void)
985 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
986 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
993 Pick a vector for the player to shoot along
994 vector aim(entity, missilespeed)
997 static void VM_SV_aim (void)
999 prvm_edict_t *ent, *check, *bestent;
1000 vec3_t start, dir, end, bestdir;
1003 float dist, bestdist;
1006 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1008 // assume failure if it returns early
1009 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1010 // if sv_aim is so high it can't possibly accept anything, skip out early
1011 if (sv_aim.value >= 1)
1014 ent = PRVM_G_EDICT(OFS_PARM0);
1015 if (ent == prog->edicts)
1017 VM_Warning("aim: can not use world entity\n");
1020 if (ent->priv.server->free)
1022 VM_Warning("aim: can not use free entity\n");
1025 speed = PRVM_G_FLOAT(OFS_PARM1);
1027 VectorCopy (ent->fields.server->origin, start);
1030 // try sending a trace straight
1031 VectorCopy (prog->globals.server->v_forward, dir);
1032 VectorMA (start, 2048, dir, end);
1033 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1034 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1035 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1037 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1042 // try all possible entities
1043 VectorCopy (dir, bestdir);
1044 bestdist = sv_aim.value;
1047 check = PRVM_NEXT_EDICT(prog->edicts);
1048 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1050 prog->xfunction->builtinsprofile++;
1051 if (check->fields.server->takedamage != DAMAGE_AIM)
1055 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1056 continue; // don't aim at teammate
1057 for (j=0 ; j<3 ; j++)
1058 end[j] = check->fields.server->origin[j]
1059 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1060 VectorSubtract (end, start, dir);
1061 VectorNormalize (dir);
1062 dist = DotProduct (dir, prog->globals.server->v_forward);
1063 if (dist < bestdist)
1064 continue; // to far to turn
1065 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1066 if (tr.ent == check)
1067 { // can shoot at this one
1075 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1076 dist = DotProduct (dir, prog->globals.server->v_forward);
1077 VectorScale (prog->globals.server->v_forward, dist, end);
1079 VectorNormalize (end);
1080 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1084 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1089 ===============================================================================
1093 ===============================================================================
1096 #define MSG_BROADCAST 0 // unreliable to all
1097 #define MSG_ONE 1 // reliable to one (msg_entity)
1098 #define MSG_ALL 2 // reliable to all
1099 #define MSG_INIT 3 // write to the init string
1100 #define MSG_ENTITY 5
1102 sizebuf_t *WriteDest (void)
1107 extern sizebuf_t *sv2csqcbuf;
1109 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1113 return &sv.datagram;
1116 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1117 entnum = PRVM_NUM_FOR_EDICT(ent);
1118 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1120 VM_Warning ("WriteDest: tried to write to non-client\n");
1121 return &sv.reliable_datagram;
1124 return &svs.clients[entnum-1].netconnection->message;
1127 VM_Warning ("WriteDest: bad destination\n");
1129 return &sv.reliable_datagram;
1141 static void VM_SV_WriteByte (void)
1143 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1144 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1147 static void VM_SV_WriteChar (void)
1149 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1150 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1153 static void VM_SV_WriteShort (void)
1155 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1156 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1159 static void VM_SV_WriteLong (void)
1161 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1162 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1165 static void VM_SV_WriteAngle (void)
1167 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1168 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1171 static void VM_SV_WriteCoord (void)
1173 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1174 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1177 static void VM_SV_WriteString (void)
1179 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1180 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1183 static void VM_SV_WriteUnterminatedString (void)
1185 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1186 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1190 static void VM_SV_WriteEntity (void)
1192 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1193 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1196 //////////////////////////////////////////////////////////
1198 static void VM_SV_makestatic (void)
1203 // allow 0 parameters due to an id1 qc bug in which this function is used
1204 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1205 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1207 if (prog->argc >= 1)
1208 ent = PRVM_G_EDICT(OFS_PARM0);
1210 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1211 if (ent == prog->edicts)
1213 VM_Warning("makestatic: can not modify world entity\n");
1216 if (ent->priv.server->free)
1218 VM_Warning("makestatic: can not modify free entity\n");
1223 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1228 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1229 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1230 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1234 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1235 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1236 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1239 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1240 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1241 for (i=0 ; i<3 ; i++)
1243 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1244 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1247 // throw the entity away now
1251 //=============================================================================
1258 static void VM_SV_setspawnparms (void)
1264 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1266 ent = PRVM_G_EDICT(OFS_PARM0);
1267 i = PRVM_NUM_FOR_EDICT(ent);
1268 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1270 Con_Print("tried to setspawnparms on a non-client\n");
1274 // copy spawn parms out of the client_t
1275 client = svs.clients + i-1;
1276 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1277 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1284 Returns a color vector indicating the lighting at the requested point.
1286 (Internal Operation note: actually measures the light beneath the point, just like
1287 the model lighting on the client)
1292 static void VM_SV_getlight (void)
1294 vec3_t ambientcolor, diffusecolor, diffusenormal;
1296 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1297 p = PRVM_G_VECTOR(OFS_PARM0);
1298 VectorClear(ambientcolor);
1299 VectorClear(diffusecolor);
1300 VectorClear(diffusenormal);
1301 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1302 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1303 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1308 unsigned char type; // 1/2/8 or other value if isn't used
1312 static autosentstat_t *vm_autosentstats = NULL; //[515]: it starts from 0, not 32
1313 static int vm_autosentstats_last;
1315 void VM_AutoSentStats_Clear (void)
1317 if(vm_autosentstats)
1319 Z_Free(vm_autosentstats);
1320 vm_autosentstats = NULL;
1321 vm_autosentstats_last = -1;
1325 //[515]: add check if even bigger ? "try to use two stats, cause it's too big" ?
1326 #define VM_SENDSTAT(a,b,c)\
1329 if((c)==(unsigned char)(c))\
1331 MSG_WriteByte((a), svc_updatestatubyte);\
1332 MSG_WriteByte((a), (b));\
1333 MSG_WriteByte((a), (c));\
1337 MSG_WriteByte((a), svc_updatestat);\
1338 MSG_WriteByte((a), (b));\
1339 MSG_WriteLong((a), (c));\
1343 void VM_SV_WriteAutoSentStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1355 if(!vm_autosentstats)
1358 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);
1360 for(i=0; i<vm_autosentstats_last+1 ;i++)
1362 if(!vm_autosentstats[i].type)
1364 switch(vm_autosentstats[i].type)
1368 t = PRVM_E_STRING(ent, vm_autosentstats[i].fieldoffset);
1376 stats[i+32] = si[0];
1377 stats[i+33] = si[1];
1378 stats[i+34] = si[2];
1379 stats[i+35] = si[3];
1383 VM_SENDSTAT(msg, i+32, si[0]);
1384 VM_SENDSTAT(msg, i+33, si[1]);
1385 VM_SENDSTAT(msg, i+34, si[2]);
1386 VM_SENDSTAT(msg, i+35, si[3]);
1392 k.f = PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ?
1393 k.i = LittleLong (k.i);
1397 VM_SENDSTAT(msg, i+32, k.i);
1401 v = (int)PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ?
1405 VM_SENDSTAT(msg, i+32, v);
1413 // void(float index, float type, .void field) SV_AddStat = #232;
1414 // Set up an auto-sent player stat.
1415 // Client's get thier own fields sent to them. Index may not be less than 32.
1416 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1417 // 1: string (4 stats carrying a total of 16 charactures)
1418 // 2: float (one stat, float converted to an integer for transportation)
1419 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1420 static void VM_SV_AddStat (void)
1425 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1427 if(!vm_autosentstats)
1429 vm_autosentstats = (autosentstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(autosentstat_t));
1430 if(!vm_autosentstats)
1432 VM_Warning("PF_SV_AddStat: not enough memory\n");
1436 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1437 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1438 off = PRVM_G_INT (OFS_PARM2);
1443 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1446 if(i >= (MAX_CL_STATS-32))
1448 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1451 if(i > (MAX_CL_STATS-32-4) && type == 1)
1453 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1456 vm_autosentstats[i].type = type;
1457 vm_autosentstats[i].fieldoffset = off;
1458 if(vm_autosentstats_last < i)
1459 vm_autosentstats_last = i;
1466 copies data from one entity to another
1468 copyentity(src, dst)
1471 static void VM_SV_copyentity (void)
1473 prvm_edict_t *in, *out;
1474 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1475 in = PRVM_G_EDICT(OFS_PARM0);
1476 if (in == prog->edicts)
1478 VM_Warning("copyentity: can not read world entity\n");
1481 if (in->priv.server->free)
1483 VM_Warning("copyentity: can not read free entity\n");
1486 out = PRVM_G_EDICT(OFS_PARM1);
1487 if (out == prog->edicts)
1489 VM_Warning("copyentity: can not modify world entity\n");
1492 if (out->priv.server->free)
1494 VM_Warning("copyentity: can not modify free entity\n");
1497 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1498 SV_LinkEdict(out, false);
1506 sets the color of a client and broadcasts the update to all connected clients
1508 setcolor(clientent, value)
1511 static void VM_SV_setcolor (void)
1517 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1518 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1519 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1521 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1523 Con_Print("tried to setcolor a non-client\n");
1527 client = svs.clients + entnum-1;
1530 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1532 client->edict->fields.server->team = (i & 15) + 1;
1535 if (client->old_colors != client->colors)
1537 client->old_colors = client->colors;
1538 // send notification to all clients
1539 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1540 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1541 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1549 effect(origin, modelname, startframe, framecount, framerate)
1552 static void VM_SV_effect (void)
1556 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1557 s = PRVM_G_STRING(OFS_PARM1);
1560 VM_Warning("effect: no model specified\n");
1564 i = SV_ModelIndex(s, 1);
1567 VM_Warning("effect: model not precached\n");
1571 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1573 VM_Warning("effect: framecount < 1\n");
1577 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1579 VM_Warning("effect: framerate < 1\n");
1583 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));
1586 static void VM_SV_te_blood (void)
1588 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1589 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1591 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1592 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1594 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1595 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1596 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1598 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1599 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1600 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1602 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1605 static void VM_SV_te_bloodshower (void)
1607 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1608 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1610 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1611 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1613 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1614 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1615 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1617 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1618 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1619 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1621 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1623 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1626 static void VM_SV_te_explosionrgb (void)
1628 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1629 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1630 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1632 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1633 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1634 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1636 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1637 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1638 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1641 static void VM_SV_te_particlecube (void)
1643 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1644 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1646 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1647 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1649 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1650 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1651 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1653 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1654 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1655 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1657 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1658 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1659 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1661 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1663 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1664 // gravity true/false
1665 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1667 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1670 static void VM_SV_te_particlerain (void)
1672 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1673 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1675 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1676 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1678 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1679 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1680 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1682 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1683 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1684 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1686 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1687 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1688 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1690 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1692 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1695 static void VM_SV_te_particlesnow (void)
1697 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1698 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1700 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1701 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1703 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1704 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1705 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1707 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1708 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1709 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1711 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1712 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1713 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1715 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1717 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1720 static void VM_SV_te_spark (void)
1722 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1723 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1725 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1726 MSG_WriteByte(&sv.datagram, TE_SPARK);
1728 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1729 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1730 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1732 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1733 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1734 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1736 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1739 static void VM_SV_te_gunshotquad (void)
1741 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1742 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1743 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1745 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1746 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1747 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1750 static void VM_SV_te_spikequad (void)
1752 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1753 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1754 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1756 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1757 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1758 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1761 static void VM_SV_te_superspikequad (void)
1763 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1764 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1765 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1767 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1768 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1769 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1772 static void VM_SV_te_explosionquad (void)
1774 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1775 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1776 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1778 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1779 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1780 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1783 static void VM_SV_te_smallflash (void)
1785 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1786 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1787 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1790 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1791 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1794 static void VM_SV_te_customflash (void)
1796 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1797 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1799 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1800 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1802 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1803 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1804 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1806 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1808 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1810 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1811 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1812 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1815 static void VM_SV_te_gunshot (void)
1817 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1818 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1819 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1821 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1822 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1823 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1826 static void VM_SV_te_spike (void)
1828 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1829 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1830 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1833 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1834 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1837 static void VM_SV_te_superspike (void)
1839 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1840 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1841 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1843 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1844 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1845 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1848 static void VM_SV_te_explosion (void)
1850 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1851 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1852 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1854 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1855 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1856 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1859 static void VM_SV_te_tarexplosion (void)
1861 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1862 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1863 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1865 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1866 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1867 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1870 static void VM_SV_te_wizspike (void)
1872 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1873 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1874 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1876 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1877 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1878 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1881 static void VM_SV_te_knightspike (void)
1883 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1884 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1885 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1887 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1888 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1889 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1892 static void VM_SV_te_lavasplash (void)
1894 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1895 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1896 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1898 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1899 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1903 static void VM_SV_te_teleport (void)
1905 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1906 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1907 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1909 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1910 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1911 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1914 static void VM_SV_te_explosion2 (void)
1916 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1917 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1918 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1920 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1921 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1922 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1924 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1925 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1928 static void VM_SV_te_lightning1 (void)
1930 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1931 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1932 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1934 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1936 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1937 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1938 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1940 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1941 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1942 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1945 static void VM_SV_te_lightning2 (void)
1947 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1948 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1949 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1951 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1953 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1954 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1955 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1957 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1958 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1959 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1962 static void VM_SV_te_lightning3 (void)
1964 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1965 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1966 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1968 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1970 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1974 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1976 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1979 static void VM_SV_te_beam (void)
1981 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1982 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1983 MSG_WriteByte(&sv.datagram, TE_BEAM);
1985 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1987 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1988 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1989 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1991 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1992 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1993 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1996 static void VM_SV_te_plasmaburn (void)
1998 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
1999 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2000 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2001 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2002 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2003 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2006 static void VM_SV_te_flamejet (void)
2008 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2009 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2010 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2012 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2013 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2014 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2016 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2017 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2018 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2020 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2023 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2026 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2028 bestdist = 1000000000;
2030 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2032 // clip original point to each triangle of the surface and find the
2033 // triangle that is closest
2034 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2035 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2036 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2037 TriangleNormal(v[0], v[1], v[2], facenormal);
2038 VectorNormalize(facenormal);
2039 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2040 VectorMA(p, offsetdist, facenormal, temp);
2041 for (j = 0, k = 2;j < 3;k = j, j++)
2043 VectorSubtract(v[k], v[j], edgenormal);
2044 CrossProduct(edgenormal, facenormal, sidenormal);
2045 VectorNormalize(sidenormal);
2046 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2048 VectorMA(temp, offsetdist, sidenormal, temp);
2050 dist = VectorDistance2(temp, p);
2051 if (bestdist > dist)
2054 VectorCopy(temp, out);
2059 static model_t *getmodel(prvm_edict_t *ed)
2062 if (!ed || ed->priv.server->free)
2064 modelindex = (int)ed->fields.server->modelindex;
2065 if (modelindex < 1 || modelindex >= MAX_MODELS)
2067 return sv.models[modelindex];
2070 static msurface_t *getsurface(model_t *model, int surfacenum)
2072 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2074 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2078 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2079 static void VM_SV_getsurfacenumpoints(void)
2082 msurface_t *surface;
2083 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2084 // return 0 if no such surface
2085 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2087 PRVM_G_FLOAT(OFS_RETURN) = 0;
2091 // note: this (incorrectly) assumes it is a simple polygon
2092 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2094 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2095 static void VM_SV_getsurfacepoint(void)
2099 msurface_t *surface;
2101 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2102 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2103 ed = PRVM_G_EDICT(OFS_PARM0);
2104 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2106 // note: this (incorrectly) assumes it is a simple polygon
2107 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2108 if (pointnum < 0 || pointnum >= surface->num_vertices)
2110 // FIXME: implement rotation/scaling
2111 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2113 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2114 static void VM_SV_getsurfacenormal(void)
2117 msurface_t *surface;
2119 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2120 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2121 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2123 // FIXME: implement rotation/scaling
2124 // note: this (incorrectly) assumes it is a simple polygon
2125 // note: this only returns the first triangle, so it doesn't work very
2126 // well for curved surfaces or arbitrary meshes
2127 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);
2128 VectorNormalize(normal);
2129 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2131 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2132 static void VM_SV_getsurfacetexture(void)
2135 msurface_t *surface;
2136 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2137 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2138 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2140 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2142 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2143 static void VM_SV_getsurfacenearpoint(void)
2145 int surfacenum, best;
2147 vec_t dist, bestdist;
2150 msurface_t *surface;
2152 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2153 PRVM_G_FLOAT(OFS_RETURN) = -1;
2154 ed = PRVM_G_EDICT(OFS_PARM0);
2155 point = PRVM_G_VECTOR(OFS_PARM1);
2157 if (!ed || ed->priv.server->free)
2159 model = getmodel(ed);
2160 if (!model || !model->num_surfaces)
2163 // FIXME: implement rotation/scaling
2164 VectorSubtract(point, ed->fields.server->origin, p);
2166 bestdist = 1000000000;
2167 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2169 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2170 // first see if the nearest point on the surface's box is closer than the previous match
2171 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2172 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2173 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2174 dist = VectorLength2(clipped);
2175 if (dist < bestdist)
2177 // it is, check the nearest point on the actual geometry
2178 clippointtosurface(model, surface, p, clipped);
2179 VectorSubtract(clipped, p, clipped);
2180 dist += VectorLength2(clipped);
2181 if (dist < bestdist)
2183 // that's closer too, store it as the best match
2189 PRVM_G_FLOAT(OFS_RETURN) = best;
2191 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2192 static void VM_SV_getsurfaceclippedpoint(void)
2196 msurface_t *surface;
2198 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2199 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2200 ed = PRVM_G_EDICT(OFS_PARM0);
2201 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2203 // FIXME: implement rotation/scaling
2204 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2205 clippointtosurface(model, surface, p, out);
2206 // FIXME: implement rotation/scaling
2207 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2210 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2211 //this function originally written by KrimZon, made shorter by LordHavoc
2212 static void VM_SV_clientcommand (void)
2214 client_t *temp_client;
2216 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2218 //find client for this entity
2219 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2220 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2222 Con_Print("PF_clientcommand: entity is not a client\n");
2226 temp_client = host_client;
2227 host_client = svs.clients + i;
2228 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2229 host_client = temp_client;
2232 //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)
2233 static void VM_SV_setattachment (void)
2235 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2236 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2237 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2241 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2243 if (e == prog->edicts)
2245 VM_Warning("setattachment: can not modify world entity\n");
2248 if (e->priv.server->free)
2250 VM_Warning("setattachment: can not modify free entity\n");
2254 if (tagentity == NULL)
2255 tagentity = prog->edicts;
2257 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2259 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2261 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2264 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2266 modelindex = (int)tagentity->fields.server->modelindex;
2267 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2269 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2271 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);
2274 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));
2278 /////////////////////////////////////////
2279 // DP_MD3_TAGINFO extension coded by VorteX
2281 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2286 i = (int)e->fields.server->modelindex;
2287 if (i < 1 || i >= MAX_MODELS)
2289 model = sv.models[i];
2291 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2294 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2296 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2300 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);
2302 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);
2305 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2311 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2312 && (model = sv.models[(int)ent->fields.server->modelindex])
2313 && model->animscenes)
2315 // if model has wrong frame, engine automatically switches to model first frame
2316 frame = (int)ent->fields.server->frame;
2317 if (frame < 0 || frame >= model->numframes)
2319 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2321 *out = identitymatrix;
2325 // Warnings/errors code:
2326 // 0 - normal (everything all-right)
2329 // 3 - null or non-precached model
2330 // 4 - no tags with requested index
2331 // 5 - runaway loop at attachment chain
2332 extern cvar_t cl_bob;
2333 extern cvar_t cl_bobcycle;
2334 extern cvar_t cl_bobup;
2335 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2339 int modelindex, attachloop;
2340 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2343 *out = identitymatrix; // warnings and errors return identical matrix
2345 if (ent == prog->edicts)
2347 if (ent->priv.server->free)
2350 modelindex = (int)ent->fields.server->modelindex;
2351 if (modelindex <= 0 || modelindex > MAX_MODELS)
2354 model = sv.models[modelindex];
2356 tagmatrix = identitymatrix;
2357 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2361 if (attachloop >= 256) // prevent runaway looping
2363 // apply transformation by child's tagindex on parent entity and then
2364 // by parent entity itself
2365 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2366 if (ret && attachloop == 0)
2368 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2369 SV_GetEntityMatrix(ent, &entitymatrix, false);
2370 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2371 // next iteration we process the parent entity
2372 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2374 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2375 ent = PRVM_EDICT_NUM(val->edict);
2382 // RENDER_VIEWMODEL magic
2383 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2385 Matrix4x4_Copy(&tagmatrix, out);
2386 ent = PRVM_EDICT_NUM(val->edict);
2388 SV_GetEntityMatrix(ent, &entitymatrix, true);
2389 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2392 // Cl_bob, ported from rendering code
2393 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2396 // LordHavoc: this code is *weird*, but not replacable (I think it
2397 // should be done in QC on the server, but oh well, quake is quake)
2398 // LordHavoc: figured out bobup: the time at which the sin is at 180
2399 // degrees (which allows lengthening or squishing the peak or valley)
2400 cycle = sv.time/cl_bobcycle.value;
2401 cycle -= (int)cycle;
2402 if (cycle < cl_bobup.value)
2403 cycle = sin(M_PI * cycle / cl_bobup.value);
2405 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2406 // bob is proportional to velocity in the xy plane
2407 // (don't count Z, or jumping messes it up)
2408 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;
2409 bob = bob*0.3 + bob*0.7*cycle;
2410 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2417 //float(entity ent, string tagname) gettagindex;
2419 static void VM_SV_gettagindex (void)
2422 const char *tag_name;
2423 int modelindex, tag_index;
2425 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2427 ent = PRVM_G_EDICT(OFS_PARM0);
2428 tag_name = PRVM_G_STRING(OFS_PARM1);
2430 if (ent == prog->edicts)
2432 VM_Warning("gettagindex: can't affect world entity\n");
2435 if (ent->priv.server->free)
2437 VM_Warning("gettagindex: can't affect free entity\n");
2441 modelindex = (int)ent->fields.server->modelindex;
2443 if (modelindex <= 0 || modelindex > MAX_MODELS)
2444 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2447 tag_index = SV_GetTagIndex(ent, tag_name);
2449 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2451 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2454 //vector(entity ent, float tagindex) gettaginfo;
2455 static void VM_SV_gettaginfo (void)
2459 matrix4x4_t tag_matrix;
2462 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2464 e = PRVM_G_EDICT(OFS_PARM0);
2465 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2467 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2468 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2473 VM_Warning("gettagindex: can't affect world entity\n");
2476 VM_Warning("gettagindex: can't affect free entity\n");
2479 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2482 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2485 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2490 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2491 static void VM_SV_dropclient (void)
2494 client_t *oldhostclient;
2495 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2496 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2497 if (clientnum < 0 || clientnum >= svs.maxclients)
2499 VM_Warning("dropclient: not a client\n");
2502 if (!svs.clients[clientnum].active)
2504 VM_Warning("dropclient: that client slot is not connected\n");
2507 oldhostclient = host_client;
2508 host_client = svs.clients + clientnum;
2509 SV_DropClient(false);
2510 host_client = oldhostclient;
2513 //entity() spawnclient (DP_SV_BOTCLIENT)
2514 static void VM_SV_spawnclient (void)
2518 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2519 prog->xfunction->builtinsprofile += 2;
2521 for (i = 0;i < svs.maxclients;i++)
2523 if (!svs.clients[i].active)
2525 prog->xfunction->builtinsprofile += 100;
2526 SV_ConnectClient (i, NULL);
2527 // this has to be set or else ClientDisconnect won't be called
2528 // we assume the qc will call ClientConnect...
2529 svs.clients[i].clientconnectcalled = true;
2530 ed = PRVM_EDICT_NUM(i + 1);
2534 VM_RETURN_EDICT(ed);
2537 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2538 static void VM_SV_clienttype (void)
2541 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2542 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2543 if (clientnum < 0 || clientnum >= svs.maxclients)
2544 PRVM_G_FLOAT(OFS_RETURN) = 3;
2545 else if (!svs.clients[clientnum].active)
2546 PRVM_G_FLOAT(OFS_RETURN) = 0;
2547 else if (svs.clients[clientnum].netconnection)
2548 PRVM_G_FLOAT(OFS_RETURN) = 1;
2550 PRVM_G_FLOAT(OFS_RETURN) = 2;
2557 string(string key) serverkey
2560 void VM_SV_serverkey(void)
2562 char string[VM_STRINGTEMP_LENGTH];
2563 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2564 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2565 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2568 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2569 static void VM_SV_setmodelindex (void)
2574 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2576 e = PRVM_G_EDICT(OFS_PARM0);
2577 if (e == prog->edicts)
2579 VM_Warning("setmodelindex: can not modify world entity\n");
2582 if (e->priv.server->free)
2584 VM_Warning("setmodelindex: can not modify free entity\n");
2587 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2588 if (i <= 0 || i > MAX_MODELS)
2590 VM_Warning("setmodelindex: invalid modelindex\n");
2593 if (!sv.model_precache[i][0])
2595 VM_Warning("setmodelindex: model not precached\n");
2599 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2600 e->fields.server->modelindex = i;
2606 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2607 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2609 SetMinMaxSize (e, quakemins, quakemaxs, true);
2612 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2615 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2616 static void VM_SV_modelnameforindex (void)
2619 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2621 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2623 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2624 if (i <= 0 || i > MAX_MODELS)
2626 VM_Warning("modelnameforindex: invalid modelindex\n");
2629 if (!sv.model_precache[i][0])
2631 VM_Warning("modelnameforindex: model not precached\n");
2635 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2638 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2639 static void VM_SV_particleeffectnum (void)
2642 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2643 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2646 PRVM_G_FLOAT(OFS_RETURN) = i;
2649 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2650 static void VM_SV_trailparticles (void)
2652 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2654 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2655 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2656 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2657 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2658 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2661 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2662 static void VM_SV_pointparticles (void)
2664 VM_SAFEPARMCOUNT(4, VM_SV_pointparticles);
2666 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2667 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM0));
2668 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1), sv.protocol);
2669 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2670 MSG_WriteShort(&sv.datagram, bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535));
2673 prvm_builtin_t vm_sv_builtins[] = {
2674 NULL, // #0 NULL function (not callable) (QUAKE)
2675 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2676 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2677 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2678 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2679 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2680 VM_break, // #6 void() break (QUAKE)
2681 VM_random, // #7 float() random (QUAKE)
2682 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2683 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2684 VM_error, // #10 void(string e) error (QUAKE)
2685 VM_objerror, // #11 void(string e) objerror (QUAKE)
2686 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2687 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2688 VM_spawn, // #14 entity() spawn (QUAKE)
2689 VM_remove, // #15 void(entity e) remove (QUAKE)
2690 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2691 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2692 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2693 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2694 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2695 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2696 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2697 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2698 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2699 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2700 VM_ftos, // #26 string(float f) ftos (QUAKE)
2701 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2702 VM_coredump, // #28 void() coredump (QUAKE)
2703 VM_traceon, // #29 void() traceon (QUAKE)
2704 VM_traceoff, // #30 void() traceoff (QUAKE)
2705 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2706 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2707 NULL, // #33 (QUAKE)
2708 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2709 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2710 VM_rint, // #36 float(float v) rint (QUAKE)
2711 VM_floor, // #37 float(float v) floor (QUAKE)
2712 VM_ceil, // #38 float(float v) ceil (QUAKE)
2713 NULL, // #39 (QUAKE)
2714 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2715 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2716 NULL, // #42 (QUAKE)
2717 VM_fabs, // #43 float(float f) fabs (QUAKE)
2718 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2719 VM_cvar, // #45 float(string s) cvar (QUAKE)
2720 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2721 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2722 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2723 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2724 NULL, // #50 (QUAKE)
2725 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2726 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2727 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2728 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2729 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2730 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2731 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2732 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2733 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2734 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2735 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2736 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2737 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2738 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2739 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2740 NULL, // #66 (QUAKE)
2741 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2742 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2743 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2744 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2745 NULL, // #71 (QUAKE)
2746 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2747 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2748 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2749 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2750 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2751 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2752 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2753 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2754 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2755 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2756 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2757 NULL, // #83 (QUAKE)
2758 NULL, // #84 (QUAKE)
2759 NULL, // #85 (QUAKE)
2760 NULL, // #86 (QUAKE)
2761 NULL, // #87 (QUAKE)
2762 NULL, // #88 (QUAKE)
2763 NULL, // #89 (QUAKE)
2764 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2765 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2766 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2767 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2768 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2769 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2770 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2771 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2772 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2773 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2774 // FrikaC and Telejano range #100-#199
2785 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2786 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2787 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2788 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2789 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2790 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2791 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2792 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2793 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2794 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2875 // FTEQW range #200-#299
2894 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2898 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2899 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2904 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2908 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2976 // CSQC range #300-#399
2977 NULL, // #300 void() clearscene (EXT_CSQC)
2978 NULL, // #301 void(float mask) addentities (EXT_CSQC)
2979 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
2980 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
2981 NULL, // #304 void() renderscene (EXT_CSQC)
2982 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2983 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2984 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2985 NULL, // #308 void() R_EndPolygon
2987 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
2988 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
2992 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
2993 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
2994 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
2995 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
2996 NULL, // #319 void(string name) freepic (EXT_CSQC)
2997 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
2998 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
2999 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3000 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3001 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3002 NULL, // #325 void(void) drawresetcliparea
3007 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3008 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3009 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3010 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3011 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3012 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3013 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3014 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3015 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3016 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3017 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3018 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3019 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3020 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3021 NULL, // #344 vector() getmousepos (EXT_CSQC)
3022 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3023 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3024 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3025 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3026 NULL, // #349 float() isdemo (EXT_CSQC)
3027 VM_isserver, // #350 float() isserver (EXT_CSQC)
3028 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3029 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3030 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3031 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3037 NULL, // #360 float() readbyte (EXT_CSQC)
3038 NULL, // #361 float() readchar (EXT_CSQC)
3039 NULL, // #362 float() readshort (EXT_CSQC)
3040 NULL, // #363 float() readlong (EXT_CSQC)
3041 NULL, // #364 float() readcoord (EXT_CSQC)
3042 NULL, // #365 float() readangle (EXT_CSQC)
3043 NULL, // #366 string() readstring (EXT_CSQC)
3044 NULL, // #367 float() readfloat (EXT_CSQC)
3077 // LordHavoc's range #400-#499
3078 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3079 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3080 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3081 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3082 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3083 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3084 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3085 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3086 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)
3087 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3088 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3089 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3090 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3091 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3092 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3093 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3094 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3095 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3096 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3097 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3098 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3099 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3100 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3101 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3102 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3103 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3104 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3105 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3106 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3107 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3108 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3109 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3110 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3111 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3112 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3113 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3114 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3115 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3116 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3117 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3118 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3119 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3120 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3121 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3122 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
3123 VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
3124 VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
3125 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
3126 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3127 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3128 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3129 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3130 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3131 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3132 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3133 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3134 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3135 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3137 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3138 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3139 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3140 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3141 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3142 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3143 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3144 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3145 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3146 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3147 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3149 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3150 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3151 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3152 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3153 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3154 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3155 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3156 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3157 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3180 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3182 void VM_SV_Cmd_Init(void)
3187 void VM_SV_Cmd_Reset(void)