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 customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1315 static int vm_customstats_last;
1317 void VM_CustomStats_Clear (void)
1321 Z_Free(vm_customstats);
1322 vm_customstats = NULL;
1323 vm_customstats_last = -1;
1327 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1335 for(i=0; i<vm_customstats_last+1 ;i++)
1337 if(!vm_customstats[i].type)
1339 switch(vm_customstats[i].type)
1341 //string as 16 bytes
1344 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1345 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1346 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1347 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1348 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1350 //float field sent as-is
1352 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1354 //integer value of float field
1356 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1364 // void(float index, float type, .void field) SV_AddStat = #232;
1365 // Set up an auto-sent player stat.
1366 // Client's get thier own fields sent to them. Index may not be less than 32.
1367 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1368 // 1: string (4 stats carrying a total of 16 charactures)
1369 // 2: float (one stat, float converted to an integer for transportation)
1370 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1371 static void VM_SV_AddStat (void)
1376 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1380 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1383 VM_Warning("PF_SV_AddStat: not enough memory\n");
1387 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1388 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1389 off = PRVM_G_INT (OFS_PARM2);
1394 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1397 if(i >= (MAX_CL_STATS-32))
1399 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1402 if(i > (MAX_CL_STATS-32-4) && type == 1)
1404 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1407 vm_customstats[i].type = type;
1408 vm_customstats[i].fieldoffset = off;
1409 if(vm_customstats_last < i)
1410 vm_customstats_last = i;
1417 copies data from one entity to another
1419 copyentity(src, dst)
1422 static void VM_SV_copyentity (void)
1424 prvm_edict_t *in, *out;
1425 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1426 in = PRVM_G_EDICT(OFS_PARM0);
1427 if (in == prog->edicts)
1429 VM_Warning("copyentity: can not read world entity\n");
1432 if (in->priv.server->free)
1434 VM_Warning("copyentity: can not read free entity\n");
1437 out = PRVM_G_EDICT(OFS_PARM1);
1438 if (out == prog->edicts)
1440 VM_Warning("copyentity: can not modify world entity\n");
1443 if (out->priv.server->free)
1445 VM_Warning("copyentity: can not modify free entity\n");
1448 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1449 SV_LinkEdict(out, false);
1457 sets the color of a client and broadcasts the update to all connected clients
1459 setcolor(clientent, value)
1462 static void VM_SV_setcolor (void)
1468 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1469 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1470 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1472 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1474 Con_Print("tried to setcolor a non-client\n");
1478 client = svs.clients + entnum-1;
1481 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1483 client->edict->fields.server->team = (i & 15) + 1;
1486 if (client->old_colors != client->colors)
1488 client->old_colors = client->colors;
1489 // send notification to all clients
1490 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1491 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1492 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1500 effect(origin, modelname, startframe, framecount, framerate)
1503 static void VM_SV_effect (void)
1507 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1508 s = PRVM_G_STRING(OFS_PARM1);
1511 VM_Warning("effect: no model specified\n");
1515 i = SV_ModelIndex(s, 1);
1518 VM_Warning("effect: model not precached\n");
1522 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1524 VM_Warning("effect: framecount < 1\n");
1528 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1530 VM_Warning("effect: framerate < 1\n");
1534 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));
1537 static void VM_SV_te_blood (void)
1539 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1540 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1542 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1543 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1545 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1546 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1547 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1549 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1550 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1551 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1553 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1554 SV_FlushBroadcastMessages();
1557 static void VM_SV_te_bloodshower (void)
1559 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1560 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1562 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1563 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1565 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1566 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1567 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1569 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1570 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1571 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1573 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1575 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1576 SV_FlushBroadcastMessages();
1579 static void VM_SV_te_explosionrgb (void)
1581 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1582 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1583 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1585 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1586 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1587 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1589 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1590 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1591 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1592 SV_FlushBroadcastMessages();
1595 static void VM_SV_te_particlecube (void)
1597 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1598 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1600 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1601 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1603 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1604 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1605 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1607 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1608 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1609 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1611 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1612 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1613 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1615 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1617 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1618 // gravity true/false
1619 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1621 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1622 SV_FlushBroadcastMessages();
1625 static void VM_SV_te_particlerain (void)
1627 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1628 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1630 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1631 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1633 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1634 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1635 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1637 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1638 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1639 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1641 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1642 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1643 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1645 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1647 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1648 SV_FlushBroadcastMessages();
1651 static void VM_SV_te_particlesnow (void)
1653 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1654 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1656 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1657 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1659 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1660 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1661 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1663 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1664 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1665 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1667 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1668 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1671 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1673 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1674 SV_FlushBroadcastMessages();
1677 static void VM_SV_te_spark (void)
1679 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1680 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1682 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1683 MSG_WriteByte(&sv.datagram, TE_SPARK);
1685 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1686 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1687 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1689 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1690 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1691 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1693 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1694 SV_FlushBroadcastMessages();
1697 static void VM_SV_te_gunshotquad (void)
1699 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1700 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1701 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
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);
1706 SV_FlushBroadcastMessages();
1709 static void VM_SV_te_spikequad (void)
1711 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1712 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1713 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1715 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1716 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1717 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1718 SV_FlushBroadcastMessages();
1721 static void VM_SV_te_superspikequad (void)
1723 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1724 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1725 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1727 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1728 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1729 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1730 SV_FlushBroadcastMessages();
1733 static void VM_SV_te_explosionquad (void)
1735 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1736 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1737 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1739 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1740 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1741 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1742 SV_FlushBroadcastMessages();
1745 static void VM_SV_te_smallflash (void)
1747 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1748 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1749 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1751 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1752 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1753 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1754 SV_FlushBroadcastMessages();
1757 static void VM_SV_te_customflash (void)
1759 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1760 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1762 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1763 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1765 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1766 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1767 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1769 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1771 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1773 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1774 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1775 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1776 SV_FlushBroadcastMessages();
1779 static void VM_SV_te_gunshot (void)
1781 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1782 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1783 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1785 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1786 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1787 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1788 SV_FlushBroadcastMessages();
1791 static void VM_SV_te_spike (void)
1793 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1794 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1795 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1797 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1798 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1799 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1800 SV_FlushBroadcastMessages();
1803 static void VM_SV_te_superspike (void)
1805 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1806 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1807 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1809 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1810 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1811 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1812 SV_FlushBroadcastMessages();
1815 static void VM_SV_te_explosion (void)
1817 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1818 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1819 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
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);
1824 SV_FlushBroadcastMessages();
1827 static void VM_SV_te_tarexplosion (void)
1829 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1830 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1831 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1833 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1834 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1835 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1836 SV_FlushBroadcastMessages();
1839 static void VM_SV_te_wizspike (void)
1841 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1842 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1843 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
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);
1848 SV_FlushBroadcastMessages();
1851 static void VM_SV_te_knightspike (void)
1853 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1854 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1855 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1857 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1858 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1859 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1860 SV_FlushBroadcastMessages();
1863 static void VM_SV_te_lavasplash (void)
1865 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1866 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1867 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1871 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1872 SV_FlushBroadcastMessages();
1875 static void VM_SV_te_teleport (void)
1877 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1878 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1879 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1881 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1882 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1883 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1884 SV_FlushBroadcastMessages();
1887 static void VM_SV_te_explosion2 (void)
1889 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1890 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1891 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1893 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1894 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1895 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1897 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1898 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1899 SV_FlushBroadcastMessages();
1902 static void VM_SV_te_lightning1 (void)
1904 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1905 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1906 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1908 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1910 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1911 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1912 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1914 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1915 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1916 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1917 SV_FlushBroadcastMessages();
1920 static void VM_SV_te_lightning2 (void)
1922 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1923 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1924 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1926 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1928 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1929 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1930 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1933 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1934 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1935 SV_FlushBroadcastMessages();
1938 static void VM_SV_te_lightning3 (void)
1940 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1941 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1942 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1944 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1946 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1947 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1948 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1950 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1951 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1952 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1953 SV_FlushBroadcastMessages();
1956 static void VM_SV_te_beam (void)
1958 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1959 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1960 MSG_WriteByte(&sv.datagram, TE_BEAM);
1962 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1964 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1965 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1966 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1968 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1969 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1970 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1971 SV_FlushBroadcastMessages();
1974 static void VM_SV_te_plasmaburn (void)
1976 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
1977 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1978 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
1979 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1980 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1981 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1982 SV_FlushBroadcastMessages();
1985 static void VM_SV_te_flamejet (void)
1987 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
1988 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1989 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
1991 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1992 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1993 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1996 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1997 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1999 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2000 SV_FlushBroadcastMessages();
2003 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2006 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2008 bestdist = 1000000000;
2010 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2012 // clip original point to each triangle of the surface and find the
2013 // triangle that is closest
2014 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2015 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2016 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2017 TriangleNormal(v[0], v[1], v[2], facenormal);
2018 VectorNormalize(facenormal);
2019 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2020 VectorMA(p, offsetdist, facenormal, temp);
2021 for (j = 0, k = 2;j < 3;k = j, j++)
2023 VectorSubtract(v[k], v[j], edgenormal);
2024 CrossProduct(edgenormal, facenormal, sidenormal);
2025 VectorNormalize(sidenormal);
2026 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2028 VectorMA(temp, offsetdist, sidenormal, temp);
2030 dist = VectorDistance2(temp, p);
2031 if (bestdist > dist)
2034 VectorCopy(temp, out);
2039 static model_t *getmodel(prvm_edict_t *ed)
2042 if (!ed || ed->priv.server->free)
2044 modelindex = (int)ed->fields.server->modelindex;
2045 if (modelindex < 1 || modelindex >= MAX_MODELS)
2047 return sv.models[modelindex];
2050 static msurface_t *getsurface(model_t *model, int surfacenum)
2052 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2054 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2058 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2059 static void VM_SV_getsurfacenumpoints(void)
2062 msurface_t *surface;
2063 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2064 // return 0 if no such surface
2065 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2067 PRVM_G_FLOAT(OFS_RETURN) = 0;
2071 // note: this (incorrectly) assumes it is a simple polygon
2072 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2074 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2075 static void VM_SV_getsurfacepoint(void)
2079 msurface_t *surface;
2081 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2082 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2083 ed = PRVM_G_EDICT(OFS_PARM0);
2084 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2086 // note: this (incorrectly) assumes it is a simple polygon
2087 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2088 if (pointnum < 0 || pointnum >= surface->num_vertices)
2090 // FIXME: implement rotation/scaling
2091 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2093 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2094 static void VM_SV_getsurfacenormal(void)
2097 msurface_t *surface;
2099 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2100 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2101 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2103 // FIXME: implement rotation/scaling
2104 // note: this (incorrectly) assumes it is a simple polygon
2105 // note: this only returns the first triangle, so it doesn't work very
2106 // well for curved surfaces or arbitrary meshes
2107 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);
2108 VectorNormalize(normal);
2109 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2111 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2112 static void VM_SV_getsurfacetexture(void)
2115 msurface_t *surface;
2116 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2117 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2118 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2120 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2122 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2123 static void VM_SV_getsurfacenearpoint(void)
2125 int surfacenum, best;
2127 vec_t dist, bestdist;
2130 msurface_t *surface;
2132 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2133 PRVM_G_FLOAT(OFS_RETURN) = -1;
2134 ed = PRVM_G_EDICT(OFS_PARM0);
2135 point = PRVM_G_VECTOR(OFS_PARM1);
2137 if (!ed || ed->priv.server->free)
2139 model = getmodel(ed);
2140 if (!model || !model->num_surfaces)
2143 // FIXME: implement rotation/scaling
2144 VectorSubtract(point, ed->fields.server->origin, p);
2146 bestdist = 1000000000;
2147 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2149 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2150 // first see if the nearest point on the surface's box is closer than the previous match
2151 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2152 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2153 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2154 dist = VectorLength2(clipped);
2155 if (dist < bestdist)
2157 // it is, check the nearest point on the actual geometry
2158 clippointtosurface(model, surface, p, clipped);
2159 VectorSubtract(clipped, p, clipped);
2160 dist += VectorLength2(clipped);
2161 if (dist < bestdist)
2163 // that's closer too, store it as the best match
2169 PRVM_G_FLOAT(OFS_RETURN) = best;
2171 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2172 static void VM_SV_getsurfaceclippedpoint(void)
2176 msurface_t *surface;
2178 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2179 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2180 ed = PRVM_G_EDICT(OFS_PARM0);
2181 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2183 // FIXME: implement rotation/scaling
2184 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2185 clippointtosurface(model, surface, p, out);
2186 // FIXME: implement rotation/scaling
2187 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2190 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2191 //this function originally written by KrimZon, made shorter by LordHavoc
2192 static void VM_SV_clientcommand (void)
2194 client_t *temp_client;
2196 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2198 //find client for this entity
2199 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2200 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2202 Con_Print("PF_clientcommand: entity is not a client\n");
2206 temp_client = host_client;
2207 host_client = svs.clients + i;
2208 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2209 host_client = temp_client;
2212 //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)
2213 static void VM_SV_setattachment (void)
2215 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2216 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2217 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2221 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2223 if (e == prog->edicts)
2225 VM_Warning("setattachment: can not modify world entity\n");
2228 if (e->priv.server->free)
2230 VM_Warning("setattachment: can not modify free entity\n");
2234 if (tagentity == NULL)
2235 tagentity = prog->edicts;
2237 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2239 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2241 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2244 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2246 modelindex = (int)tagentity->fields.server->modelindex;
2247 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2249 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2251 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);
2254 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));
2258 /////////////////////////////////////////
2259 // DP_MD3_TAGINFO extension coded by VorteX
2261 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2266 i = (int)e->fields.server->modelindex;
2267 if (i < 1 || i >= MAX_MODELS)
2269 model = sv.models[i];
2271 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2274 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2276 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2280 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);
2282 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);
2285 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2291 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2292 && (model = sv.models[(int)ent->fields.server->modelindex])
2293 && model->animscenes)
2295 // if model has wrong frame, engine automatically switches to model first frame
2296 frame = (int)ent->fields.server->frame;
2297 if (frame < 0 || frame >= model->numframes)
2299 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2301 *out = identitymatrix;
2305 // Warnings/errors code:
2306 // 0 - normal (everything all-right)
2309 // 3 - null or non-precached model
2310 // 4 - no tags with requested index
2311 // 5 - runaway loop at attachment chain
2312 extern cvar_t cl_bob;
2313 extern cvar_t cl_bobcycle;
2314 extern cvar_t cl_bobup;
2315 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2319 int modelindex, attachloop;
2320 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2323 *out = identitymatrix; // warnings and errors return identical matrix
2325 if (ent == prog->edicts)
2327 if (ent->priv.server->free)
2330 modelindex = (int)ent->fields.server->modelindex;
2331 if (modelindex <= 0 || modelindex > MAX_MODELS)
2334 model = sv.models[modelindex];
2336 tagmatrix = identitymatrix;
2337 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2341 if (attachloop >= 256) // prevent runaway looping
2343 // apply transformation by child's tagindex on parent entity and then
2344 // by parent entity itself
2345 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2346 if (ret && attachloop == 0)
2348 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2349 SV_GetEntityMatrix(ent, &entitymatrix, false);
2350 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2351 // next iteration we process the parent entity
2352 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2354 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2355 ent = PRVM_EDICT_NUM(val->edict);
2362 // RENDER_VIEWMODEL magic
2363 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2365 Matrix4x4_Copy(&tagmatrix, out);
2366 ent = PRVM_EDICT_NUM(val->edict);
2368 SV_GetEntityMatrix(ent, &entitymatrix, true);
2369 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2372 // Cl_bob, ported from rendering code
2373 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2376 // LordHavoc: this code is *weird*, but not replacable (I think it
2377 // should be done in QC on the server, but oh well, quake is quake)
2378 // LordHavoc: figured out bobup: the time at which the sin is at 180
2379 // degrees (which allows lengthening or squishing the peak or valley)
2380 cycle = sv.time/cl_bobcycle.value;
2381 cycle -= (int)cycle;
2382 if (cycle < cl_bobup.value)
2383 cycle = sin(M_PI * cycle / cl_bobup.value);
2385 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2386 // bob is proportional to velocity in the xy plane
2387 // (don't count Z, or jumping messes it up)
2388 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;
2389 bob = bob*0.3 + bob*0.7*cycle;
2390 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2397 //float(entity ent, string tagname) gettagindex;
2399 static void VM_SV_gettagindex (void)
2402 const char *tag_name;
2403 int modelindex, tag_index;
2405 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2407 ent = PRVM_G_EDICT(OFS_PARM0);
2408 tag_name = PRVM_G_STRING(OFS_PARM1);
2410 if (ent == prog->edicts)
2412 VM_Warning("gettagindex: can't affect world entity\n");
2415 if (ent->priv.server->free)
2417 VM_Warning("gettagindex: can't affect free entity\n");
2421 modelindex = (int)ent->fields.server->modelindex;
2423 if (modelindex <= 0 || modelindex > MAX_MODELS)
2424 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2427 tag_index = SV_GetTagIndex(ent, tag_name);
2429 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2431 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2434 //vector(entity ent, float tagindex) gettaginfo;
2435 static void VM_SV_gettaginfo (void)
2439 matrix4x4_t tag_matrix;
2442 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2444 e = PRVM_G_EDICT(OFS_PARM0);
2445 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2447 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2448 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2453 VM_Warning("gettagindex: can't affect world entity\n");
2456 VM_Warning("gettagindex: can't affect free entity\n");
2459 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2462 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2465 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2470 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2471 static void VM_SV_dropclient (void)
2474 client_t *oldhostclient;
2475 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2476 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2477 if (clientnum < 0 || clientnum >= svs.maxclients)
2479 VM_Warning("dropclient: not a client\n");
2482 if (!svs.clients[clientnum].active)
2484 VM_Warning("dropclient: that client slot is not connected\n");
2487 oldhostclient = host_client;
2488 host_client = svs.clients + clientnum;
2489 SV_DropClient(false);
2490 host_client = oldhostclient;
2493 //entity() spawnclient (DP_SV_BOTCLIENT)
2494 static void VM_SV_spawnclient (void)
2498 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2499 prog->xfunction->builtinsprofile += 2;
2501 for (i = 0;i < svs.maxclients;i++)
2503 if (!svs.clients[i].active)
2505 prog->xfunction->builtinsprofile += 100;
2506 SV_ConnectClient (i, NULL);
2507 // this has to be set or else ClientDisconnect won't be called
2508 // we assume the qc will call ClientConnect...
2509 svs.clients[i].clientconnectcalled = true;
2510 ed = PRVM_EDICT_NUM(i + 1);
2514 VM_RETURN_EDICT(ed);
2517 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2518 static void VM_SV_clienttype (void)
2521 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2522 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2523 if (clientnum < 0 || clientnum >= svs.maxclients)
2524 PRVM_G_FLOAT(OFS_RETURN) = 3;
2525 else if (!svs.clients[clientnum].active)
2526 PRVM_G_FLOAT(OFS_RETURN) = 0;
2527 else if (svs.clients[clientnum].netconnection)
2528 PRVM_G_FLOAT(OFS_RETURN) = 1;
2530 PRVM_G_FLOAT(OFS_RETURN) = 2;
2537 string(string key) serverkey
2540 void VM_SV_serverkey(void)
2542 char string[VM_STRINGTEMP_LENGTH];
2543 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2544 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2545 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2548 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2549 static void VM_SV_setmodelindex (void)
2554 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2556 e = PRVM_G_EDICT(OFS_PARM0);
2557 if (e == prog->edicts)
2559 VM_Warning("setmodelindex: can not modify world entity\n");
2562 if (e->priv.server->free)
2564 VM_Warning("setmodelindex: can not modify free entity\n");
2567 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2568 if (i <= 0 || i > MAX_MODELS)
2570 VM_Warning("setmodelindex: invalid modelindex\n");
2573 if (!sv.model_precache[i][0])
2575 VM_Warning("setmodelindex: model not precached\n");
2579 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2580 e->fields.server->modelindex = i;
2586 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2587 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2589 SetMinMaxSize (e, quakemins, quakemaxs, true);
2592 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2595 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2596 static void VM_SV_modelnameforindex (void)
2599 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2601 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2603 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2604 if (i <= 0 || i > MAX_MODELS)
2606 VM_Warning("modelnameforindex: invalid modelindex\n");
2609 if (!sv.model_precache[i][0])
2611 VM_Warning("modelnameforindex: model not precached\n");
2615 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2618 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2619 static void VM_SV_particleeffectnum (void)
2622 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2623 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2626 PRVM_G_FLOAT(OFS_RETURN) = i;
2629 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2630 static void VM_SV_trailparticles (void)
2632 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2634 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2635 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2636 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2637 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2638 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2639 SV_FlushBroadcastMessages();
2642 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2643 static void VM_SV_pointparticles (void)
2645 VM_SAFEPARMCOUNT(4, VM_SV_pointparticles);
2647 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2648 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM0));
2649 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1), sv.protocol);
2650 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2651 MSG_WriteShort(&sv.datagram, bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535));
2652 SV_FlushBroadcastMessages();
2655 prvm_builtin_t vm_sv_builtins[] = {
2656 NULL, // #0 NULL function (not callable) (QUAKE)
2657 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2658 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2659 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2660 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2661 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2662 VM_break, // #6 void() break (QUAKE)
2663 VM_random, // #7 float() random (QUAKE)
2664 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2665 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2666 VM_error, // #10 void(string e) error (QUAKE)
2667 VM_objerror, // #11 void(string e) objerror (QUAKE)
2668 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2669 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2670 VM_spawn, // #14 entity() spawn (QUAKE)
2671 VM_remove, // #15 void(entity e) remove (QUAKE)
2672 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2673 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2674 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2675 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2676 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2677 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2678 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2679 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2680 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2681 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2682 VM_ftos, // #26 string(float f) ftos (QUAKE)
2683 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2684 VM_coredump, // #28 void() coredump (QUAKE)
2685 VM_traceon, // #29 void() traceon (QUAKE)
2686 VM_traceoff, // #30 void() traceoff (QUAKE)
2687 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2688 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2689 NULL, // #33 (QUAKE)
2690 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2691 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2692 VM_rint, // #36 float(float v) rint (QUAKE)
2693 VM_floor, // #37 float(float v) floor (QUAKE)
2694 VM_ceil, // #38 float(float v) ceil (QUAKE)
2695 NULL, // #39 (QUAKE)
2696 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2697 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2698 NULL, // #42 (QUAKE)
2699 VM_fabs, // #43 float(float f) fabs (QUAKE)
2700 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2701 VM_cvar, // #45 float(string s) cvar (QUAKE)
2702 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2703 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2704 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2705 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2706 NULL, // #50 (QUAKE)
2707 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2708 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2709 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2710 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2711 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2712 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2713 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2714 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2715 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2716 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2717 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2718 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2719 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2720 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2721 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2722 NULL, // #66 (QUAKE)
2723 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2724 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2725 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2726 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2727 NULL, // #71 (QUAKE)
2728 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2729 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2730 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2731 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2732 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2733 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2734 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2735 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2736 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2737 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2738 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2739 NULL, // #83 (QUAKE)
2740 NULL, // #84 (QUAKE)
2741 NULL, // #85 (QUAKE)
2742 NULL, // #86 (QUAKE)
2743 NULL, // #87 (QUAKE)
2744 NULL, // #88 (QUAKE)
2745 NULL, // #89 (QUAKE)
2746 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2747 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2748 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2749 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2750 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2751 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2752 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2753 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2754 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2755 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2756 // FrikaC and Telejano range #100-#199
2767 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2768 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2769 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2770 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2771 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2772 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2773 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2774 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2775 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2776 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2857 // FTEQW range #200-#299
2876 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2880 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2881 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2886 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2890 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2958 // CSQC range #300-#399
2959 NULL, // #300 void() clearscene (EXT_CSQC)
2960 NULL, // #301 void(float mask) addentities (EXT_CSQC)
2961 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
2962 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
2963 NULL, // #304 void() renderscene (EXT_CSQC)
2964 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2965 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2966 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2967 NULL, // #308 void() R_EndPolygon
2969 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
2970 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
2974 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
2975 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
2976 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
2977 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
2978 NULL, // #319 void(string name) freepic (EXT_CSQC)
2979 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
2980 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
2981 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
2982 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
2983 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
2984 NULL, // #325 void(void) drawresetcliparea
2989 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
2990 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
2991 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
2992 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2993 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2994 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
2995 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2996 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
2997 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
2998 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
2999 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3000 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3001 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3002 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3003 NULL, // #344 vector() getmousepos (EXT_CSQC)
3004 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3005 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3006 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3007 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3008 NULL, // #349 float() isdemo (EXT_CSQC)
3009 VM_isserver, // #350 float() isserver (EXT_CSQC)
3010 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3011 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3012 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3013 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3019 NULL, // #360 float() readbyte (EXT_CSQC)
3020 NULL, // #361 float() readchar (EXT_CSQC)
3021 NULL, // #362 float() readshort (EXT_CSQC)
3022 NULL, // #363 float() readlong (EXT_CSQC)
3023 NULL, // #364 float() readcoord (EXT_CSQC)
3024 NULL, // #365 float() readangle (EXT_CSQC)
3025 NULL, // #366 string() readstring (EXT_CSQC)
3026 NULL, // #367 float() readfloat (EXT_CSQC)
3059 // LordHavoc's range #400-#499
3060 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3061 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3062 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3063 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3064 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3065 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3066 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3067 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3068 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)
3069 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3070 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3071 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3072 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3073 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3074 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3075 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3076 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3077 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3078 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3079 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3080 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3081 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3082 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3083 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3084 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3085 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3086 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3087 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3088 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3089 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3090 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3091 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3092 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3093 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3094 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3095 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3096 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3097 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3098 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3099 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3100 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3101 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3102 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3103 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3104 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
3105 VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
3106 VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
3107 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
3108 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3109 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3110 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3111 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3112 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3113 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3114 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3115 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3116 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3117 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3119 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3120 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3121 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3122 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3123 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3124 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3125 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3126 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3127 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3128 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3129 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3131 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3132 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3133 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3134 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3135 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3136 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3137 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3138 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3139 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3162 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3164 void VM_SV_Cmd_Init(void)
3169 void VM_SV_Cmd_Reset(void)