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 "
143 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.
145 setorigin (entity, origin)
148 static void VM_SV_setorigin (void)
153 VM_SAFEPARMCOUNT(2, VM_setorigin);
155 e = PRVM_G_EDICT(OFS_PARM0);
156 if (e == prog->edicts)
158 VM_Warning("setorigin: can not modify world entity\n");
161 if (e->priv.server->free)
163 VM_Warning("setorigin: can not modify free entity\n");
166 org = PRVM_G_VECTOR(OFS_PARM1);
167 VectorCopy (org, e->fields.server->origin);
168 SV_LinkEdict (e, false);
172 void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
176 for (i=0 ; i<3 ; i++)
178 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
180 // set derived values
181 VectorCopy (min, e->fields.server->mins);
182 VectorCopy (max, e->fields.server->maxs);
183 VectorSubtract (max, min, e->fields.server->size);
185 SV_LinkEdict (e, false);
192 the size box is rotated by the current angle
193 LordHavoc: no it isn't...
195 setsize (entity, minvector, maxvector)
198 static void VM_SV_setsize (void)
203 VM_SAFEPARMCOUNT(3, VM_setsize);
205 e = PRVM_G_EDICT(OFS_PARM0);
206 if (e == prog->edicts)
208 VM_Warning("setsize: can not modify world entity\n");
211 if (e->priv.server->free)
213 VM_Warning("setsize: can not modify free entity\n");
216 min = PRVM_G_VECTOR(OFS_PARM1);
217 max = PRVM_G_VECTOR(OFS_PARM2);
218 SetMinMaxSize (e, min, max, false);
226 setmodel(entity, model)
229 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
230 static void VM_SV_setmodel (void)
236 VM_SAFEPARMCOUNT(2, VM_setmodel);
238 e = PRVM_G_EDICT(OFS_PARM0);
239 if (e == prog->edicts)
241 VM_Warning("setmodel: can not modify world entity\n");
244 if (e->priv.server->free)
246 VM_Warning("setmodel: can not modify free entity\n");
249 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
250 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
251 e->fields.server->modelindex = i;
257 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
258 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
260 SetMinMaxSize (e, quakemins, quakemaxs, true);
263 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
270 single print to a specific client
272 sprint(clientent, value)
275 static void VM_SV_sprint (void)
279 char string[VM_STRINGTEMP_LENGTH];
281 VM_VarString(1, string, sizeof(string));
283 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
285 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
286 // LordHavoc: div0 requested that sprintto world operate like print
293 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
295 VM_Warning("tried to centerprint to a non-client\n");
299 client = svs.clients + entnum-1;
300 if (!client->netconnection)
303 MSG_WriteChar(&client->netconnection->message,svc_print);
304 MSG_WriteString(&client->netconnection->message, string);
312 single print to a specific client
314 centerprint(clientent, value)
317 static void VM_SV_centerprint (void)
321 char string[VM_STRINGTEMP_LENGTH];
323 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
325 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
327 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
329 VM_Warning("tried to centerprint to a non-client\n");
333 client = svs.clients + entnum-1;
334 if (!client->netconnection)
337 VM_VarString(1, string, sizeof(string));
338 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
339 MSG_WriteString(&client->netconnection->message, string);
346 particle(origin, color, count)
349 static void VM_SV_particle (void)
355 VM_SAFEPARMCOUNT(4, VM_SV_particle);
357 org = PRVM_G_VECTOR(OFS_PARM0);
358 dir = PRVM_G_VECTOR(OFS_PARM1);
359 color = PRVM_G_FLOAT(OFS_PARM2);
360 count = PRVM_G_FLOAT(OFS_PARM3);
361 SV_StartParticle (org, dir, (int)color, (int)count);
371 static void VM_SV_ambientsound (void)
375 float vol, attenuation;
378 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
380 pos = PRVM_G_VECTOR (OFS_PARM0);
381 samp = PRVM_G_STRING(OFS_PARM1);
382 vol = PRVM_G_FLOAT(OFS_PARM2);
383 attenuation = PRVM_G_FLOAT(OFS_PARM3);
385 // check to see if samp was properly precached
386 soundnum = SV_SoundIndex(samp, 1);
394 // add an svc_spawnambient command to the level signon packet
397 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
399 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
401 MSG_WriteVector(&sv.signon, pos, sv.protocol);
404 MSG_WriteShort (&sv.signon, soundnum);
406 MSG_WriteByte (&sv.signon, soundnum);
408 MSG_WriteByte (&sv.signon, (int)(vol*255));
409 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
417 Each entity can have eight independant sound sources, like voice,
420 Channel 0 is an auto-allocate channel, the others override anything
421 already running on that entity/channel pair.
423 An attenuation of 0 will play full volume everywhere in the level.
424 Larger attenuations will drop off.
428 static void VM_SV_sound (void)
432 prvm_edict_t *entity;
436 VM_SAFEPARMCOUNT(5, VM_SV_sound);
438 entity = PRVM_G_EDICT(OFS_PARM0);
439 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
440 sample = PRVM_G_STRING(OFS_PARM2);
441 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
442 attenuation = PRVM_G_FLOAT(OFS_PARM4);
444 if (volume < 0 || volume > 255)
446 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
450 if (attenuation < 0 || attenuation > 4)
452 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
456 if (channel < 0 || channel > 7)
458 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
462 SV_StartSound (entity, channel, sample, volume, attenuation);
469 Used for use tracing and shot targeting
470 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
471 if the tryents flag is set.
473 traceline (vector1, vector2, movetype, ignore)
476 static void VM_SV_traceline (void)
483 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
485 prog->xfunction->builtinsprofile += 30;
487 v1 = PRVM_G_VECTOR(OFS_PARM0);
488 v2 = PRVM_G_VECTOR(OFS_PARM1);
489 move = (int)PRVM_G_FLOAT(OFS_PARM2);
490 ent = PRVM_G_EDICT(OFS_PARM3);
492 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]))
493 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));
495 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
497 VM_SetTraceGlobals(&trace);
505 Used for use tracing and shot targeting
506 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
507 if the tryents flag is set.
509 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
512 // LordHavoc: added this for my own use, VERY useful, similar to traceline
513 static void VM_SV_tracebox (void)
515 float *v1, *v2, *m1, *m2;
520 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
522 prog->xfunction->builtinsprofile += 30;
524 v1 = PRVM_G_VECTOR(OFS_PARM0);
525 m1 = PRVM_G_VECTOR(OFS_PARM1);
526 m2 = PRVM_G_VECTOR(OFS_PARM2);
527 v2 = PRVM_G_VECTOR(OFS_PARM3);
528 move = (int)PRVM_G_FLOAT(OFS_PARM4);
529 ent = PRVM_G_EDICT(OFS_PARM5);
531 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]))
532 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));
534 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
536 VM_SetTraceGlobals(&trace);
539 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
544 vec3_t original_origin;
545 vec3_t original_velocity;
546 vec3_t original_angles;
547 vec3_t original_avelocity;
551 VectorCopy(tossent->fields.server->origin , original_origin );
552 VectorCopy(tossent->fields.server->velocity , original_velocity );
553 VectorCopy(tossent->fields.server->angles , original_angles );
554 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
556 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
557 if (val != NULL && val->_float != 0)
558 gravity = val->_float;
561 gravity *= sv_gravity.value * 0.05;
563 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
565 SV_CheckVelocity (tossent);
566 tossent->fields.server->velocity[2] -= gravity;
567 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
568 VectorScale (tossent->fields.server->velocity, 0.05, move);
569 VectorAdd (tossent->fields.server->origin, move, end);
570 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
571 VectorCopy (trace.endpos, tossent->fields.server->origin);
573 if (trace.fraction < 1)
577 VectorCopy(original_origin , tossent->fields.server->origin );
578 VectorCopy(original_velocity , tossent->fields.server->velocity );
579 VectorCopy(original_angles , tossent->fields.server->angles );
580 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
585 static void VM_SV_tracetoss (void)
589 prvm_edict_t *ignore;
591 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
593 prog->xfunction->builtinsprofile += 600;
595 ent = PRVM_G_EDICT(OFS_PARM0);
596 if (ent == prog->edicts)
598 VM_Warning("tracetoss: can not use world entity\n");
601 ignore = PRVM_G_EDICT(OFS_PARM1);
603 trace = SV_Trace_Toss (ent, ignore);
605 VM_SetTraceGlobals(&trace);
608 //============================================================================
610 static int checkpvsbytes;
611 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
613 static int VM_SV_newcheckclient (int check)
619 // cycle to the next one
621 check = bound(1, check, svs.maxclients);
622 if (check == svs.maxclients)
630 prog->xfunction->builtinsprofile++;
632 if (i == svs.maxclients+1)
634 // look up the client's edict
635 ent = PRVM_EDICT_NUM(i);
636 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
637 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
639 // found a valid client (possibly the same one again)
643 // get the PVS for the entity
644 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
646 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
647 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
656 Returns a client (or object that has a client enemy) that would be a
659 If there is more than one valid option, they are cycled each frame
661 If (self.origin + self.viewofs) is not in the PVS of the current target,
662 it is not returned at all.
667 int c_invis, c_notvis;
668 static void VM_SV_checkclient (void)
670 prvm_edict_t *ent, *self;
673 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
675 // find a new check if on a new frame
676 if (sv.time - sv.lastchecktime >= 0.1)
678 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
679 sv.lastchecktime = sv.time;
682 // return check if it might be visible
683 ent = PRVM_EDICT_NUM(sv.lastcheck);
684 if (ent->priv.server->free || ent->fields.server->health <= 0)
686 VM_RETURN_EDICT(prog->edicts);
690 // if current entity can't possibly see the check entity, return 0
691 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
692 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
693 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
696 VM_RETURN_EDICT(prog->edicts);
700 // might be able to see it
702 VM_RETURN_EDICT(ent);
705 //============================================================================
712 Sends text over to the client's execution buffer
714 stuffcmd (clientent, value, ...)
717 static void VM_SV_stuffcmd (void)
721 char string[VM_STRINGTEMP_LENGTH];
723 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
725 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
726 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
728 VM_Warning("Can't stuffcmd to a non-client\n");
732 VM_VarString(1, string, sizeof(string));
735 host_client = svs.clients + entnum-1;
736 Host_ClientCommands ("%s", string);
744 Returns a chain of entities that have origins within a spherical area
746 findradius (origin, radius)
749 static void VM_SV_findradius (void)
751 prvm_edict_t *ent, *chain;
752 vec_t radius, radius2;
753 vec3_t org, eorg, mins, maxs;
756 prvm_edict_t *touchedicts[MAX_EDICTS];
758 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
760 chain = (prvm_edict_t *)prog->edicts;
762 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
763 radius = PRVM_G_FLOAT(OFS_PARM1);
764 radius2 = radius * radius;
766 mins[0] = org[0] - (radius + 1);
767 mins[1] = org[1] - (radius + 1);
768 mins[2] = org[2] - (radius + 1);
769 maxs[0] = org[0] + (radius + 1);
770 maxs[1] = org[1] + (radius + 1);
771 maxs[2] = org[2] + (radius + 1);
772 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
773 if (numtouchedicts > MAX_EDICTS)
775 // this never happens
776 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
777 numtouchedicts = MAX_EDICTS;
779 for (i = 0;i < numtouchedicts;i++)
781 ent = touchedicts[i];
782 prog->xfunction->builtinsprofile++;
783 // Quake did not return non-solid entities but darkplaces does
784 // (note: this is the reason you can't blow up fallen zombies)
785 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
787 // LordHavoc: compare against bounding box rather than center so it
788 // doesn't miss large objects, and use DotProduct instead of Length
789 // for a major speedup
790 VectorSubtract(org, ent->fields.server->origin, eorg);
791 if (sv_gameplayfix_findradiusdistancetobox.integer)
793 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
794 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
795 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
798 VectorMAMAM(1, eorg, 0.5f, ent->fields.server->mins, 0.5f, ent->fields.server->maxs, eorg);
799 if (DotProduct(eorg, eorg) < radius2)
801 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
806 VM_RETURN_EDICT(chain);
809 static void VM_SV_precache_sound (void)
811 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
812 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
813 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
816 static void VM_SV_precache_model (void)
818 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
819 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
820 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
827 float(float yaw, float dist[, settrace]) walkmove
830 static void VM_SV_walkmove (void)
839 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
841 // assume failure if it returns early
842 PRVM_G_FLOAT(OFS_RETURN) = 0;
844 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
845 if (ent == prog->edicts)
847 VM_Warning("walkmove: can not modify world entity\n");
850 if (ent->priv.server->free)
852 VM_Warning("walkmove: can not modify free entity\n");
855 yaw = PRVM_G_FLOAT(OFS_PARM0);
856 dist = PRVM_G_FLOAT(OFS_PARM1);
857 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
859 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
862 yaw = yaw*M_PI*2 / 360;
864 move[0] = cos(yaw)*dist;
865 move[1] = sin(yaw)*dist;
868 // save program state, because SV_movestep may call other progs
869 oldf = prog->xfunction;
870 oldself = prog->globals.server->self;
872 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
875 // restore program state
876 prog->xfunction = oldf;
877 prog->globals.server->self = oldself;
887 static void VM_SV_droptofloor (void)
893 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
895 // assume failure if it returns early
896 PRVM_G_FLOAT(OFS_RETURN) = 0;
898 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
899 if (ent == prog->edicts)
901 VM_Warning("droptofloor: can not modify world entity\n");
904 if (ent->priv.server->free)
906 VM_Warning("droptofloor: can not modify free entity\n");
910 VectorCopy (ent->fields.server->origin, end);
913 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
915 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
917 if (trace.fraction < 1)
918 VectorCopy (trace.endpos, ent->fields.server->origin);
919 SV_LinkEdict (ent, false);
920 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
921 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
922 PRVM_G_FLOAT(OFS_RETURN) = 1;
923 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
924 ent->priv.server->suspendedinairflag = true;
932 void(float style, string value) lightstyle
935 static void VM_SV_lightstyle (void)
942 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
944 style = (int)PRVM_G_FLOAT(OFS_PARM0);
945 val = PRVM_G_STRING(OFS_PARM1);
947 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
948 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
951 // change the string in sv
952 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
954 // send message to all clients on this server
955 if (sv.state != ss_active)
958 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
960 if (client->active && client->netconnection)
962 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
963 MSG_WriteChar (&client->netconnection->message,style);
964 MSG_WriteString (&client->netconnection->message, val);
974 static void VM_SV_checkbottom (void)
976 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
977 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
985 static void VM_SV_pointcontents (void)
987 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
988 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
995 Pick a vector for the player to shoot along
996 vector aim(entity, missilespeed)
999 static void VM_SV_aim (void)
1001 prvm_edict_t *ent, *check, *bestent;
1002 vec3_t start, dir, end, bestdir;
1005 float dist, bestdist;
1008 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1010 // assume failure if it returns early
1011 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1012 // if sv_aim is so high it can't possibly accept anything, skip out early
1013 if (sv_aim.value >= 1)
1016 ent = PRVM_G_EDICT(OFS_PARM0);
1017 if (ent == prog->edicts)
1019 VM_Warning("aim: can not use world entity\n");
1022 if (ent->priv.server->free)
1024 VM_Warning("aim: can not use free entity\n");
1027 speed = PRVM_G_FLOAT(OFS_PARM1);
1029 VectorCopy (ent->fields.server->origin, start);
1032 // try sending a trace straight
1033 VectorCopy (prog->globals.server->v_forward, dir);
1034 VectorMA (start, 2048, dir, end);
1035 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1036 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1037 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1039 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1044 // try all possible entities
1045 VectorCopy (dir, bestdir);
1046 bestdist = sv_aim.value;
1049 check = PRVM_NEXT_EDICT(prog->edicts);
1050 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1052 prog->xfunction->builtinsprofile++;
1053 if (check->fields.server->takedamage != DAMAGE_AIM)
1057 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1058 continue; // don't aim at teammate
1059 for (j=0 ; j<3 ; j++)
1060 end[j] = check->fields.server->origin[j]
1061 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1062 VectorSubtract (end, start, dir);
1063 VectorNormalize (dir);
1064 dist = DotProduct (dir, prog->globals.server->v_forward);
1065 if (dist < bestdist)
1066 continue; // to far to turn
1067 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1068 if (tr.ent == check)
1069 { // can shoot at this one
1077 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1078 dist = DotProduct (dir, prog->globals.server->v_forward);
1079 VectorScale (prog->globals.server->v_forward, dist, end);
1081 VectorNormalize (end);
1082 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1086 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1091 ===============================================================================
1095 ===============================================================================
1098 #define MSG_BROADCAST 0 // unreliable to all
1099 #define MSG_ONE 1 // reliable to one (msg_entity)
1100 #define MSG_ALL 2 // reliable to all
1101 #define MSG_INIT 3 // write to the init string
1102 #define MSG_ENTITY 5
1104 sizebuf_t *WriteDest (void)
1109 extern sizebuf_t *sv2csqcbuf;
1111 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1115 return &sv.datagram;
1118 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1119 entnum = PRVM_NUM_FOR_EDICT(ent);
1120 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1122 VM_Warning ("WriteDest: tried to write to non-client\n");
1123 return &sv.reliable_datagram;
1126 return &svs.clients[entnum-1].netconnection->message;
1129 VM_Warning ("WriteDest: bad destination\n");
1131 return &sv.reliable_datagram;
1143 static void VM_SV_WriteByte (void)
1145 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1146 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1149 static void VM_SV_WriteChar (void)
1151 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1152 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1155 static void VM_SV_WriteShort (void)
1157 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1158 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1161 static void VM_SV_WriteLong (void)
1163 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1164 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1167 static void VM_SV_WriteAngle (void)
1169 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1170 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1173 static void VM_SV_WriteCoord (void)
1175 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1176 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1179 static void VM_SV_WriteString (void)
1181 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1182 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1185 static void VM_SV_WriteUnterminatedString (void)
1187 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1188 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1192 static void VM_SV_WriteEntity (void)
1194 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1195 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1198 //////////////////////////////////////////////////////////
1200 static void VM_SV_makestatic (void)
1205 // allow 0 parameters due to an id1 qc bug in which this function is used
1206 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1207 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1209 if (prog->argc >= 1)
1210 ent = PRVM_G_EDICT(OFS_PARM0);
1212 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1213 if (ent == prog->edicts)
1215 VM_Warning("makestatic: can not modify world entity\n");
1218 if (ent->priv.server->free)
1220 VM_Warning("makestatic: can not modify free entity\n");
1225 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1230 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1231 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1232 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1236 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1237 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1238 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1241 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1242 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1243 for (i=0 ; i<3 ; i++)
1245 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1246 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1249 // throw the entity away now
1253 //=============================================================================
1260 static void VM_SV_setspawnparms (void)
1266 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1268 ent = PRVM_G_EDICT(OFS_PARM0);
1269 i = PRVM_NUM_FOR_EDICT(ent);
1270 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1272 Con_Print("tried to setspawnparms on a non-client\n");
1276 // copy spawn parms out of the client_t
1277 client = svs.clients + i-1;
1278 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1279 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1286 Returns a color vector indicating the lighting at the requested point.
1288 (Internal Operation note: actually measures the light beneath the point, just like
1289 the model lighting on the client)
1294 static void VM_SV_getlight (void)
1296 vec3_t ambientcolor, diffusecolor, diffusenormal;
1298 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1299 p = PRVM_G_VECTOR(OFS_PARM0);
1300 VectorClear(ambientcolor);
1301 VectorClear(diffusecolor);
1302 VectorClear(diffusenormal);
1303 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1304 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1305 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1310 unsigned char type; // 1/2/8 or other value if isn't used
1314 static autosentstat_t *vm_autosentstats = NULL; //[515]: it starts from 0, not 32
1315 static int vm_autosentstats_last;
1317 void VM_AutoSentStats_Clear (void)
1319 if(vm_autosentstats)
1321 Z_Free(vm_autosentstats);
1322 vm_autosentstats = NULL;
1323 vm_autosentstats_last = -1;
1327 //[515]: add check if even bigger ? "try to use two stats, cause it's too big" ?
1328 #define VM_SENDSTAT(a,b,c)\
1331 if((c)==(unsigned char)(c))\
1333 MSG_WriteByte((a), svc_updatestatubyte);\
1334 MSG_WriteByte((a), (b));\
1335 MSG_WriteByte((a), (c));\
1339 MSG_WriteByte((a), svc_updatestat);\
1340 MSG_WriteByte((a), (b));\
1341 MSG_WriteLong((a), (c));\
1345 void VM_SV_WriteAutoSentStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1357 if(!vm_autosentstats)
1360 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);
1362 for(i=0; i<vm_autosentstats_last+1 ;i++)
1364 if(!vm_autosentstats[i].type)
1366 switch(vm_autosentstats[i].type)
1370 t = PRVM_E_STRING(ent, vm_autosentstats[i].fieldoffset);
1378 stats[i+32] = si[0];
1379 stats[i+33] = si[1];
1380 stats[i+34] = si[2];
1381 stats[i+35] = si[3];
1385 VM_SENDSTAT(msg, i+32, si[0]);
1386 VM_SENDSTAT(msg, i+33, si[1]);
1387 VM_SENDSTAT(msg, i+34, si[2]);
1388 VM_SENDSTAT(msg, i+35, si[3]);
1394 k.f = PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ?
1395 k.i = LittleLong (k.i);
1399 VM_SENDSTAT(msg, i+32, k.i);
1403 v = (int)PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ?
1407 VM_SENDSTAT(msg, i+32, v);
1415 // void(float index, float type, .void field) SV_AddStat = #232;
1416 // Set up an auto-sent player stat.
1417 // Client's get thier own fields sent to them. Index may not be less than 32.
1418 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1419 // 1: string (4 stats carrying a total of 16 charactures)
1420 // 2: float (one stat, float converted to an integer for transportation)
1421 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1422 static void VM_SV_AddStat (void)
1427 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1429 if(!vm_autosentstats)
1431 vm_autosentstats = (autosentstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(autosentstat_t));
1432 if(!vm_autosentstats)
1434 VM_Warning("PF_SV_AddStat: not enough memory\n");
1438 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1439 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1440 off = PRVM_G_INT (OFS_PARM2);
1445 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1448 if(i >= (MAX_CL_STATS-32))
1450 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1453 if(i > (MAX_CL_STATS-32-4) && type == 1)
1455 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1458 vm_autosentstats[i].type = type;
1459 vm_autosentstats[i].fieldoffset = off;
1460 if(vm_autosentstats_last < i)
1461 vm_autosentstats_last = i;
1468 copies data from one entity to another
1470 copyentity(src, dst)
1473 static void VM_SV_copyentity (void)
1475 prvm_edict_t *in, *out;
1476 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1477 in = PRVM_G_EDICT(OFS_PARM0);
1478 if (in == prog->edicts)
1480 VM_Warning("copyentity: can not read world entity\n");
1483 if (in->priv.server->free)
1485 VM_Warning("copyentity: can not read free entity\n");
1488 out = PRVM_G_EDICT(OFS_PARM1);
1489 if (out == prog->edicts)
1491 VM_Warning("copyentity: can not modify world entity\n");
1494 if (out->priv.server->free)
1496 VM_Warning("copyentity: can not modify free entity\n");
1499 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1500 SV_LinkEdict(out, false);
1508 sets the color of a client and broadcasts the update to all connected clients
1510 setcolor(clientent, value)
1513 static void VM_SV_setcolor (void)
1519 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1520 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1521 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1523 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1525 Con_Print("tried to setcolor a non-client\n");
1529 client = svs.clients + entnum-1;
1532 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1534 client->edict->fields.server->team = (i & 15) + 1;
1537 if (client->old_colors != client->colors)
1539 client->old_colors = client->colors;
1540 // send notification to all clients
1541 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1542 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1543 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1551 effect(origin, modelname, startframe, framecount, framerate)
1554 static void VM_SV_effect (void)
1558 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1559 s = PRVM_G_STRING(OFS_PARM1);
1562 VM_Warning("effect: no model specified\n");
1566 i = SV_ModelIndex(s, 1);
1569 VM_Warning("effect: model not precached\n");
1573 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1575 VM_Warning("effect: framecount < 1\n");
1579 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1581 VM_Warning("effect: framerate < 1\n");
1585 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));
1588 static void VM_SV_te_blood (void)
1590 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1591 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1593 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1594 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1596 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1597 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1598 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1600 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1601 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1602 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1604 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1607 static void VM_SV_te_bloodshower (void)
1609 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1610 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1612 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1613 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1615 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1616 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1617 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1619 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1620 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1621 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1623 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1625 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1628 static void VM_SV_te_explosionrgb (void)
1630 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1631 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1632 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1634 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1635 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1636 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1638 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1639 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1640 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1643 static void VM_SV_te_particlecube (void)
1645 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1646 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1648 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1649 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1651 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1652 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1653 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1655 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1656 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1657 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1659 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1660 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1661 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1663 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1665 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1666 // gravity true/false
1667 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1672 static void VM_SV_te_particlerain (void)
1674 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1675 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1677 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1678 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1680 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1681 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1682 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1684 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1685 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1686 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1688 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1689 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1690 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1692 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1694 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1697 static void VM_SV_te_particlesnow (void)
1699 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1700 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1702 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1703 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1705 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1706 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1707 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1709 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1710 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1711 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1713 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1714 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1715 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1717 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1719 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1722 static void VM_SV_te_spark (void)
1724 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1725 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1727 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1728 MSG_WriteByte(&sv.datagram, TE_SPARK);
1730 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1731 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1732 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1734 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1735 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1736 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1738 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1741 static void VM_SV_te_gunshotquad (void)
1743 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1744 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1745 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1747 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1748 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1749 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1752 static void VM_SV_te_spikequad (void)
1754 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1755 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1756 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1758 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1759 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1760 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1763 static void VM_SV_te_superspikequad (void)
1765 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1766 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1767 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1769 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1770 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1771 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1774 static void VM_SV_te_explosionquad (void)
1776 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1777 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1778 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1780 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1781 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1782 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1785 static void VM_SV_te_smallflash (void)
1787 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1788 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1789 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1791 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1792 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1793 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1796 static void VM_SV_te_customflash (void)
1798 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1799 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1801 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1802 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1804 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1805 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1806 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1808 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1810 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1812 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1813 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1814 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1817 static void VM_SV_te_gunshot (void)
1819 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1820 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1821 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1823 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1824 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1825 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1828 static void VM_SV_te_spike (void)
1830 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1831 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1832 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1834 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1835 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1836 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1839 static void VM_SV_te_superspike (void)
1841 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1842 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1843 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1845 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1846 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1847 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1850 static void VM_SV_te_explosion (void)
1852 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1853 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1854 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1856 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1857 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1858 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1861 static void VM_SV_te_tarexplosion (void)
1863 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1864 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1865 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1867 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1872 static void VM_SV_te_wizspike (void)
1874 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1875 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1876 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1878 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1879 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1880 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1883 static void VM_SV_te_knightspike (void)
1885 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1886 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1887 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1889 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1890 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1891 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1894 static void VM_SV_te_lavasplash (void)
1896 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1897 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1898 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1902 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1905 static void VM_SV_te_teleport (void)
1907 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1908 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1909 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1911 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1912 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1913 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1916 static void VM_SV_te_explosion2 (void)
1918 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1919 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1920 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1922 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1923 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1924 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1926 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1927 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1930 static void VM_SV_te_lightning1 (void)
1932 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1933 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1934 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1936 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1938 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1939 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1940 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1942 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1943 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1944 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1947 static void VM_SV_te_lightning2 (void)
1949 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1950 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1951 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1953 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1955 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1956 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1957 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1959 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1960 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1961 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1964 static void VM_SV_te_lightning3 (void)
1966 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1967 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1968 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1970 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1974 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1976 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1977 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1978 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1981 static void VM_SV_te_beam (void)
1983 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1984 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1985 MSG_WriteByte(&sv.datagram, TE_BEAM);
1987 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1989 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1990 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1991 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1993 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1994 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1998 static void VM_SV_te_plasmaburn (void)
2000 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2001 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2002 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2003 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2004 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2005 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2008 static void VM_SV_te_flamejet (void)
2010 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2011 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2012 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2014 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2015 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2016 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2018 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2019 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2020 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2022 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2025 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2028 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2030 bestdist = 1000000000;
2032 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2034 // clip original point to each triangle of the surface and find the
2035 // triangle that is closest
2036 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2037 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2038 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2039 TriangleNormal(v[0], v[1], v[2], facenormal);
2040 VectorNormalize(facenormal);
2041 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2042 VectorMA(p, offsetdist, facenormal, temp);
2043 for (j = 0, k = 2;j < 3;k = j, j++)
2045 VectorSubtract(v[k], v[j], edgenormal);
2046 CrossProduct(edgenormal, facenormal, sidenormal);
2047 VectorNormalize(sidenormal);
2048 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2050 VectorMA(temp, offsetdist, sidenormal, temp);
2052 dist = VectorDistance2(temp, p);
2053 if (bestdist > dist)
2056 VectorCopy(temp, out);
2061 static model_t *getmodel(prvm_edict_t *ed)
2064 if (!ed || ed->priv.server->free)
2066 modelindex = (int)ed->fields.server->modelindex;
2067 if (modelindex < 1 || modelindex >= MAX_MODELS)
2069 return sv.models[modelindex];
2072 static msurface_t *getsurface(model_t *model, int surfacenum)
2074 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2076 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2080 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2081 static void VM_SV_getsurfacenumpoints(void)
2084 msurface_t *surface;
2085 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2086 // return 0 if no such surface
2087 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2089 PRVM_G_FLOAT(OFS_RETURN) = 0;
2093 // note: this (incorrectly) assumes it is a simple polygon
2094 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2096 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2097 static void VM_SV_getsurfacepoint(void)
2101 msurface_t *surface;
2103 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2104 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2105 ed = PRVM_G_EDICT(OFS_PARM0);
2106 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2108 // note: this (incorrectly) assumes it is a simple polygon
2109 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2110 if (pointnum < 0 || pointnum >= surface->num_vertices)
2112 // FIXME: implement rotation/scaling
2113 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2115 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2116 static void VM_SV_getsurfacenormal(void)
2119 msurface_t *surface;
2121 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2122 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2123 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2125 // FIXME: implement rotation/scaling
2126 // note: this (incorrectly) assumes it is a simple polygon
2127 // note: this only returns the first triangle, so it doesn't work very
2128 // well for curved surfaces or arbitrary meshes
2129 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);
2130 VectorNormalize(normal);
2131 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2133 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2134 static void VM_SV_getsurfacetexture(void)
2137 msurface_t *surface;
2138 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2139 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2140 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2142 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2144 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2145 static void VM_SV_getsurfacenearpoint(void)
2147 int surfacenum, best;
2149 vec_t dist, bestdist;
2152 msurface_t *surface;
2154 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2155 PRVM_G_FLOAT(OFS_RETURN) = -1;
2156 ed = PRVM_G_EDICT(OFS_PARM0);
2157 point = PRVM_G_VECTOR(OFS_PARM1);
2159 if (!ed || ed->priv.server->free)
2161 model = getmodel(ed);
2162 if (!model || !model->num_surfaces)
2165 // FIXME: implement rotation/scaling
2166 VectorSubtract(point, ed->fields.server->origin, p);
2168 bestdist = 1000000000;
2169 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2171 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2172 // first see if the nearest point on the surface's box is closer than the previous match
2173 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2174 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2175 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2176 dist = VectorLength2(clipped);
2177 if (dist < bestdist)
2179 // it is, check the nearest point on the actual geometry
2180 clippointtosurface(model, surface, p, clipped);
2181 VectorSubtract(clipped, p, clipped);
2182 dist += VectorLength2(clipped);
2183 if (dist < bestdist)
2185 // that's closer too, store it as the best match
2191 PRVM_G_FLOAT(OFS_RETURN) = best;
2193 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2194 static void VM_SV_getsurfaceclippedpoint(void)
2198 msurface_t *surface;
2200 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2201 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2202 ed = PRVM_G_EDICT(OFS_PARM0);
2203 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2205 // FIXME: implement rotation/scaling
2206 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2207 clippointtosurface(model, surface, p, out);
2208 // FIXME: implement rotation/scaling
2209 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2212 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2213 //this function originally written by KrimZon, made shorter by LordHavoc
2214 static void VM_SV_clientcommand (void)
2216 client_t *temp_client;
2218 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2220 //find client for this entity
2221 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2222 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2224 Con_Print("PF_clientcommand: entity is not a client\n");
2228 temp_client = host_client;
2229 host_client = svs.clients + i;
2230 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2231 host_client = temp_client;
2234 //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)
2235 static void VM_SV_setattachment (void)
2237 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2238 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2239 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2243 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2245 if (e == prog->edicts)
2247 VM_Warning("setattachment: can not modify world entity\n");
2250 if (e->priv.server->free)
2252 VM_Warning("setattachment: can not modify free entity\n");
2256 if (tagentity == NULL)
2257 tagentity = prog->edicts;
2259 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2261 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2263 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2266 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2268 modelindex = (int)tagentity->fields.server->modelindex;
2269 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2271 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2273 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);
2276 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));
2280 /////////////////////////////////////////
2281 // DP_MD3_TAGINFO extension coded by VorteX
2283 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2288 i = (int)e->fields.server->modelindex;
2289 if (i < 1 || i >= MAX_MODELS)
2291 model = sv.models[i];
2293 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2296 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2298 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2302 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);
2304 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);
2307 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2313 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2314 && (model = sv.models[(int)ent->fields.server->modelindex])
2315 && model->animscenes)
2317 // if model has wrong frame, engine automatically switches to model first frame
2318 frame = (int)ent->fields.server->frame;
2319 if (frame < 0 || frame >= model->numframes)
2321 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2323 *out = identitymatrix;
2327 // Warnings/errors code:
2328 // 0 - normal (everything all-right)
2331 // 3 - null or non-precached model
2332 // 4 - no tags with requested index
2333 // 5 - runaway loop at attachment chain
2334 extern cvar_t cl_bob;
2335 extern cvar_t cl_bobcycle;
2336 extern cvar_t cl_bobup;
2337 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2341 int modelindex, attachloop;
2342 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2345 *out = identitymatrix; // warnings and errors return identical matrix
2347 if (ent == prog->edicts)
2349 if (ent->priv.server->free)
2352 modelindex = (int)ent->fields.server->modelindex;
2353 if (modelindex <= 0 || modelindex > MAX_MODELS)
2356 model = sv.models[modelindex];
2358 tagmatrix = identitymatrix;
2359 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2363 if (attachloop >= 256) // prevent runaway looping
2365 // apply transformation by child's tagindex on parent entity and then
2366 // by parent entity itself
2367 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2368 if (ret && attachloop == 0)
2370 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2371 SV_GetEntityMatrix(ent, &entitymatrix, false);
2372 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2373 // next iteration we process the parent entity
2374 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2376 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2377 ent = PRVM_EDICT_NUM(val->edict);
2384 // RENDER_VIEWMODEL magic
2385 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2387 Matrix4x4_Copy(&tagmatrix, out);
2388 ent = PRVM_EDICT_NUM(val->edict);
2390 SV_GetEntityMatrix(ent, &entitymatrix, true);
2391 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2394 // Cl_bob, ported from rendering code
2395 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2398 // LordHavoc: this code is *weird*, but not replacable (I think it
2399 // should be done in QC on the server, but oh well, quake is quake)
2400 // LordHavoc: figured out bobup: the time at which the sin is at 180
2401 // degrees (which allows lengthening or squishing the peak or valley)
2402 cycle = sv.time/cl_bobcycle.value;
2403 cycle -= (int)cycle;
2404 if (cycle < cl_bobup.value)
2405 cycle = sin(M_PI * cycle / cl_bobup.value);
2407 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2408 // bob is proportional to velocity in the xy plane
2409 // (don't count Z, or jumping messes it up)
2410 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;
2411 bob = bob*0.3 + bob*0.7*cycle;
2412 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2419 //float(entity ent, string tagname) gettagindex;
2421 static void VM_SV_gettagindex (void)
2424 const char *tag_name;
2425 int modelindex, tag_index;
2427 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2429 ent = PRVM_G_EDICT(OFS_PARM0);
2430 tag_name = PRVM_G_STRING(OFS_PARM1);
2432 if (ent == prog->edicts)
2434 VM_Warning("gettagindex: can't affect world entity\n");
2437 if (ent->priv.server->free)
2439 VM_Warning("gettagindex: can't affect free entity\n");
2443 modelindex = (int)ent->fields.server->modelindex;
2445 if (modelindex <= 0 || modelindex > MAX_MODELS)
2446 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2449 tag_index = SV_GetTagIndex(ent, tag_name);
2451 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2453 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2456 //vector(entity ent, float tagindex) gettaginfo;
2457 static void VM_SV_gettaginfo (void)
2461 matrix4x4_t tag_matrix;
2464 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2466 e = PRVM_G_EDICT(OFS_PARM0);
2467 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2469 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2470 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2475 VM_Warning("gettagindex: can't affect world entity\n");
2478 VM_Warning("gettagindex: can't affect free entity\n");
2481 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2484 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2487 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2492 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2493 static void VM_SV_dropclient (void)
2496 client_t *oldhostclient;
2497 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2498 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2499 if (clientnum < 0 || clientnum >= svs.maxclients)
2501 VM_Warning("dropclient: not a client\n");
2504 if (!svs.clients[clientnum].active)
2506 VM_Warning("dropclient: that client slot is not connected\n");
2509 oldhostclient = host_client;
2510 host_client = svs.clients + clientnum;
2511 SV_DropClient(false);
2512 host_client = oldhostclient;
2515 //entity() spawnclient (DP_SV_BOTCLIENT)
2516 static void VM_SV_spawnclient (void)
2520 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2521 prog->xfunction->builtinsprofile += 2;
2523 for (i = 0;i < svs.maxclients;i++)
2525 if (!svs.clients[i].active)
2527 prog->xfunction->builtinsprofile += 100;
2528 SV_ConnectClient (i, NULL);
2529 // this has to be set or else ClientDisconnect won't be called
2530 // we assume the qc will call ClientConnect...
2531 svs.clients[i].clientconnectcalled = true;
2532 ed = PRVM_EDICT_NUM(i + 1);
2536 VM_RETURN_EDICT(ed);
2539 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2540 static void VM_SV_clienttype (void)
2543 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2544 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2545 if (clientnum < 0 || clientnum >= svs.maxclients)
2546 PRVM_G_FLOAT(OFS_RETURN) = 3;
2547 else if (!svs.clients[clientnum].active)
2548 PRVM_G_FLOAT(OFS_RETURN) = 0;
2549 else if (svs.clients[clientnum].netconnection)
2550 PRVM_G_FLOAT(OFS_RETURN) = 1;
2552 PRVM_G_FLOAT(OFS_RETURN) = 2;
2559 string(string key) serverkey
2562 void VM_SV_serverkey(void)
2564 char string[VM_STRINGTEMP_LENGTH];
2565 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2566 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2567 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2570 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2571 static void VM_SV_setmodelindex (void)
2576 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2578 e = PRVM_G_EDICT(OFS_PARM0);
2579 if (e == prog->edicts)
2581 VM_Warning("setmodelindex: can not modify world entity\n");
2584 if (e->priv.server->free)
2586 VM_Warning("setmodelindex: can not modify free entity\n");
2589 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2590 if (i <= 0 || i > MAX_MODELS)
2592 VM_Warning("setmodelindex: invalid modelindex\n");
2595 if (!sv.model_precache[i][0])
2597 VM_Warning("setmodelindex: model not precached\n");
2601 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2602 e->fields.server->modelindex = i;
2608 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2609 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2611 SetMinMaxSize (e, quakemins, quakemaxs, true);
2614 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2617 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2618 static void VM_SV_modelnameforindex (void)
2621 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2623 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2625 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2626 if (i <= 0 || i > MAX_MODELS)
2628 VM_Warning("modelnameforindex: invalid modelindex\n");
2631 if (!sv.model_precache[i][0])
2633 VM_Warning("modelnameforindex: model not precached\n");
2637 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2640 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2641 static void VM_SV_particleeffectnum (void)
2644 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2645 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2648 PRVM_G_FLOAT(OFS_RETURN) = i;
2651 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2652 static void VM_SV_trailparticles (void)
2654 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2656 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2657 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2658 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2659 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2660 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2663 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2664 static void VM_SV_pointparticles (void)
2666 VM_SAFEPARMCOUNT(4, VM_SV_pointparticles);
2668 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2669 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM0));
2670 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1), sv.protocol);
2671 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2672 MSG_WriteShort(&sv.datagram, bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535));
2675 prvm_builtin_t vm_sv_builtins[] = {
2676 NULL, // #0 NULL function (not callable) (QUAKE)
2677 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2678 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2679 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2680 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2681 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2682 VM_break, // #6 void() break (QUAKE)
2683 VM_random, // #7 float() random (QUAKE)
2684 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2685 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2686 VM_error, // #10 void(string e) error (QUAKE)
2687 VM_objerror, // #11 void(string e) objerror (QUAKE)
2688 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2689 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2690 VM_spawn, // #14 entity() spawn (QUAKE)
2691 VM_remove, // #15 void(entity e) remove (QUAKE)
2692 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2693 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2694 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2695 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2696 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2697 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2698 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2699 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2700 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2701 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2702 VM_ftos, // #26 string(float f) ftos (QUAKE)
2703 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2704 VM_coredump, // #28 void() coredump (QUAKE)
2705 VM_traceon, // #29 void() traceon (QUAKE)
2706 VM_traceoff, // #30 void() traceoff (QUAKE)
2707 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2708 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2709 NULL, // #33 (QUAKE)
2710 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2711 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2712 VM_rint, // #36 float(float v) rint (QUAKE)
2713 VM_floor, // #37 float(float v) floor (QUAKE)
2714 VM_ceil, // #38 float(float v) ceil (QUAKE)
2715 NULL, // #39 (QUAKE)
2716 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2717 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2718 NULL, // #42 (QUAKE)
2719 VM_fabs, // #43 float(float f) fabs (QUAKE)
2720 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2721 VM_cvar, // #45 float(string s) cvar (QUAKE)
2722 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2723 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2724 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2725 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2726 NULL, // #50 (QUAKE)
2727 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2728 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2729 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2730 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2731 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2732 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2733 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2734 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2735 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2736 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2737 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2738 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2739 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2740 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2741 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2742 NULL, // #66 (QUAKE)
2743 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2744 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2745 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2746 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2747 NULL, // #71 (QUAKE)
2748 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2749 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2750 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2751 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2752 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2753 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2754 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2755 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2756 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2757 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2758 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2759 NULL, // #83 (QUAKE)
2760 NULL, // #84 (QUAKE)
2761 NULL, // #85 (QUAKE)
2762 NULL, // #86 (QUAKE)
2763 NULL, // #87 (QUAKE)
2764 NULL, // #88 (QUAKE)
2765 NULL, // #89 (QUAKE)
2766 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2767 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2768 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2769 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2770 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2771 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2772 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2773 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2774 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2775 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2776 // FrikaC and Telejano range #100-#199
2787 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2788 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2789 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2790 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2791 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2792 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2793 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2794 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2795 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2796 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2877 // FTEQW range #200-#299
2896 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2900 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2901 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2906 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2910 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2978 // CSQC range #300-#399
2979 NULL, // #300 void() clearscene (EXT_CSQC)
2980 NULL, // #301 void(float mask) addentities (EXT_CSQC)
2981 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
2982 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
2983 NULL, // #304 void() renderscene (EXT_CSQC)
2984 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2985 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2986 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2987 NULL, // #308 void() R_EndPolygon
2989 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
2990 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
2994 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
2995 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
2996 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
2997 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
2998 NULL, // #319 void(string name) freepic (EXT_CSQC)
2999 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3000 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3001 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3002 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3003 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3004 NULL, // #325 void(void) drawresetcliparea
3009 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3010 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3011 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3012 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3013 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3014 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3015 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3016 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3017 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3018 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3019 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3020 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3021 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3022 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3023 NULL, // #344 vector() getmousepos (EXT_CSQC)
3024 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3025 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3026 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3027 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3028 NULL, // #349 float() isdemo (EXT_CSQC)
3029 VM_isserver, // #350 float() isserver (EXT_CSQC)
3030 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3031 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3032 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3033 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3039 NULL, // #360 float() readbyte (EXT_CSQC)
3040 NULL, // #361 float() readchar (EXT_CSQC)
3041 NULL, // #362 float() readshort (EXT_CSQC)
3042 NULL, // #363 float() readlong (EXT_CSQC)
3043 NULL, // #364 float() readcoord (EXT_CSQC)
3044 NULL, // #365 float() readangle (EXT_CSQC)
3045 NULL, // #366 string() readstring (EXT_CSQC)
3046 NULL, // #367 float() readfloat (EXT_CSQC)
3079 // LordHavoc's range #400-#499
3080 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3081 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3082 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3083 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3084 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3085 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3086 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3087 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3088 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)
3089 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3090 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3091 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3092 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3093 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3094 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3095 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3096 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3097 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3098 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3099 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3100 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3101 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3102 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3103 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3104 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3105 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3106 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3107 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3108 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3109 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3110 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3111 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3112 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3113 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3114 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3115 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3116 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3117 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3118 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3119 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3120 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3121 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3122 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3123 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3124 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
3125 VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
3126 VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
3127 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
3128 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3129 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3130 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3131 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3132 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3133 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3134 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3135 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3136 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3137 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3139 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3140 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3141 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3142 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3143 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3144 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3145 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3146 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3147 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3148 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3149 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3151 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3152 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3153 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3154 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3155 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3156 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3157 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3158 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3159 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3182 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3184 void VM_SV_Cmd_Init(void)
3189 void VM_SV_Cmd_Reset(void)