3 //============================================================================
8 char *vm_sv_extensions =
13 "DP_CON_ALIASPARAMETERS "
30 "DP_ENT_CUSTOMCOLORMAP "
31 "DP_ENT_EXTERIORMODELTOCLIENT "
33 "DP_ENT_LOWPRECISION "
36 "DP_GFX_EXTERNALTEXTURES "
37 "DP_GFX_EXTERNALTEXTURES_PERMAP "
39 "DP_GFX_QUAKE3MODELTAGS "
43 "DP_HALFLIFE_MAP_CVAR "
49 "DP_MOVETYPEBOUNCEMISSILE "
51 "DP_QC_ASINACOSATANATAN2TAN "
54 "DP_QC_CVAR_DEFSTRING "
58 "DP_QC_FINDCHAINFLAGS "
59 "DP_QC_FINDCHAINFLOAT "
67 "DP_QC_MULTIPLETEMPSTRINGS "
69 "DP_QC_SINCOSSQRTPOW "
71 "DP_QC_STRING_CASE_FUNCTIONS "
72 "DP_QC_STRINGBUFFERS "
73 "DP_QC_STRINGCOLORFUNCTIONS "
74 "DP_QC_TOKENIZEBYSEPARATOR "
77 "DP_QC_TRACE_MOVETYPE_HITMODEL "
78 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
79 "DP_QC_UNLIMITEDTEMPSTRINGS "
80 "DP_QC_VECTORVECTORS "
86 "DP_SND_DIRECTIONLESSATTNNONE "
95 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
96 "DP_SV_DRAWONLYTOCLIENT "
99 "DP_SV_ENTITYCONTENTSTRANSITION "
100 "DP_SV_MODELFLAGS_AS_EFFECTS "
102 "DP_SV_NODRAWTOCLIENT "
104 "DP_SV_PLAYERPHYSICS "
105 "DP_SV_POINTPARTICLES "
106 "DP_SV_PRECACHEANYTIME "
109 "DP_SV_ROTATINGBMODEL "
112 "DP_SV_WRITEUNTERMINATEDSTRING "
116 "DP_TE_EXPLOSIONRGB "
118 "DP_TE_PARTICLECUBE "
119 "DP_TE_PARTICLERAIN "
120 "DP_TE_PARTICLESNOW "
122 "DP_TE_QUADEFFECTS1 "
125 "DP_TE_STANDARDEFFECTBUILTINS "
126 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
129 //"EXT_CSQC " // not ready yet
131 "KRIMZON_SV_PARSECLIENTCOMMAND "
134 "NEXUIZ_PLAYERMODEL "
136 "PRYDON_CLIENTCURSOR "
137 "TENEBRAE_GFX_DLIGHTS "
147 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.
149 setorigin (entity, origin)
152 static void VM_SV_setorigin (void)
157 VM_SAFEPARMCOUNT(2, VM_setorigin);
159 e = PRVM_G_EDICT(OFS_PARM0);
160 if (e == prog->edicts)
162 VM_Warning("setorigin: can not modify world entity\n");
165 if (e->priv.server->free)
167 VM_Warning("setorigin: can not modify free entity\n");
170 org = PRVM_G_VECTOR(OFS_PARM1);
171 VectorCopy (org, e->fields.server->origin);
172 SV_LinkEdict (e, false);
176 void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
180 for (i=0 ; i<3 ; i++)
182 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
184 // set derived values
185 VectorCopy (min, e->fields.server->mins);
186 VectorCopy (max, e->fields.server->maxs);
187 VectorSubtract (max, min, e->fields.server->size);
189 SV_LinkEdict (e, false);
196 the size box is rotated by the current angle
197 LordHavoc: no it isn't...
199 setsize (entity, minvector, maxvector)
202 static void VM_SV_setsize (void)
207 VM_SAFEPARMCOUNT(3, VM_setsize);
209 e = PRVM_G_EDICT(OFS_PARM0);
210 if (e == prog->edicts)
212 VM_Warning("setsize: can not modify world entity\n");
215 if (e->priv.server->free)
217 VM_Warning("setsize: can not modify free entity\n");
220 min = PRVM_G_VECTOR(OFS_PARM1);
221 max = PRVM_G_VECTOR(OFS_PARM2);
222 SetMinMaxSize (e, min, max, false);
230 setmodel(entity, model)
233 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
234 static void VM_SV_setmodel (void)
240 VM_SAFEPARMCOUNT(2, VM_setmodel);
242 e = PRVM_G_EDICT(OFS_PARM0);
243 if (e == prog->edicts)
245 VM_Warning("setmodel: can not modify world entity\n");
248 if (e->priv.server->free)
250 VM_Warning("setmodel: can not modify free entity\n");
253 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
254 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
255 e->fields.server->modelindex = i;
261 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
262 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
264 SetMinMaxSize (e, quakemins, quakemaxs, true);
267 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
274 single print to a specific client
276 sprint(clientent, value)
279 static void VM_SV_sprint (void)
283 char string[VM_STRINGTEMP_LENGTH];
285 VM_VarString(1, string, sizeof(string));
287 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
289 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
290 // LordHavoc: div0 requested that sprintto world operate like print
297 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
299 VM_Warning("tried to centerprint to a non-client\n");
303 client = svs.clients + entnum-1;
304 if (!client->netconnection)
307 MSG_WriteChar(&client->netconnection->message,svc_print);
308 MSG_WriteString(&client->netconnection->message, string);
316 single print to a specific client
318 centerprint(clientent, value)
321 static void VM_SV_centerprint (void)
325 char string[VM_STRINGTEMP_LENGTH];
327 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
329 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
331 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
333 VM_Warning("tried to centerprint to a non-client\n");
337 client = svs.clients + entnum-1;
338 if (!client->netconnection)
341 VM_VarString(1, string, sizeof(string));
342 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
343 MSG_WriteString(&client->netconnection->message, string);
350 particle(origin, color, count)
353 static void VM_SV_particle (void)
359 VM_SAFEPARMCOUNT(4, VM_SV_particle);
361 org = PRVM_G_VECTOR(OFS_PARM0);
362 dir = PRVM_G_VECTOR(OFS_PARM1);
363 color = PRVM_G_FLOAT(OFS_PARM2);
364 count = PRVM_G_FLOAT(OFS_PARM3);
365 SV_StartParticle (org, dir, (int)color, (int)count);
375 static void VM_SV_ambientsound (void)
379 float vol, attenuation;
382 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
384 pos = PRVM_G_VECTOR (OFS_PARM0);
385 samp = PRVM_G_STRING(OFS_PARM1);
386 vol = PRVM_G_FLOAT(OFS_PARM2);
387 attenuation = PRVM_G_FLOAT(OFS_PARM3);
389 // check to see if samp was properly precached
390 soundnum = SV_SoundIndex(samp, 1);
398 // add an svc_spawnambient command to the level signon packet
401 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
403 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
405 MSG_WriteVector(&sv.signon, pos, sv.protocol);
408 MSG_WriteShort (&sv.signon, soundnum);
410 MSG_WriteByte (&sv.signon, soundnum);
412 MSG_WriteByte (&sv.signon, (int)(vol*255));
413 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
421 Each entity can have eight independant sound sources, like voice,
424 Channel 0 is an auto-allocate channel, the others override anything
425 already running on that entity/channel pair.
427 An attenuation of 0 will play full volume everywhere in the level.
428 Larger attenuations will drop off.
432 static void VM_SV_sound (void)
436 prvm_edict_t *entity;
440 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
442 entity = PRVM_G_EDICT(OFS_PARM0);
443 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
444 sample = PRVM_G_STRING(OFS_PARM2);
445 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
446 attenuation = PRVM_G_FLOAT(OFS_PARM4);
449 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
453 if (volume < 0 || volume > 255)
455 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
459 if (attenuation < 0 || attenuation > 4)
461 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
465 if (channel < 0 || channel > 7)
467 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
471 SV_StartSound (entity, channel, sample, volume, attenuation);
478 Used for use tracing and shot targeting
479 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
480 if the tryents flag is set.
482 traceline (vector1, vector2, movetype, ignore)
485 static void VM_SV_traceline (void)
492 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
494 prog->xfunction->builtinsprofile += 30;
496 v1 = PRVM_G_VECTOR(OFS_PARM0);
497 v2 = PRVM_G_VECTOR(OFS_PARM1);
498 move = (int)PRVM_G_FLOAT(OFS_PARM2);
499 ent = PRVM_G_EDICT(OFS_PARM3);
501 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]))
502 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));
504 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
506 VM_SetTraceGlobals(&trace);
514 Used for use tracing and shot targeting
515 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
516 if the tryents flag is set.
518 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
521 // LordHavoc: added this for my own use, VERY useful, similar to traceline
522 static void VM_SV_tracebox (void)
524 float *v1, *v2, *m1, *m2;
529 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
531 prog->xfunction->builtinsprofile += 30;
533 v1 = PRVM_G_VECTOR(OFS_PARM0);
534 m1 = PRVM_G_VECTOR(OFS_PARM1);
535 m2 = PRVM_G_VECTOR(OFS_PARM2);
536 v2 = PRVM_G_VECTOR(OFS_PARM3);
537 move = (int)PRVM_G_FLOAT(OFS_PARM4);
538 ent = PRVM_G_EDICT(OFS_PARM5);
540 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]))
541 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));
543 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
545 VM_SetTraceGlobals(&trace);
548 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
553 vec3_t original_origin;
554 vec3_t original_velocity;
555 vec3_t original_angles;
556 vec3_t original_avelocity;
560 VectorCopy(tossent->fields.server->origin , original_origin );
561 VectorCopy(tossent->fields.server->velocity , original_velocity );
562 VectorCopy(tossent->fields.server->angles , original_angles );
563 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
565 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
566 if (val != NULL && val->_float != 0)
567 gravity = val->_float;
570 gravity *= sv_gravity.value * 0.05;
572 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
574 SV_CheckVelocity (tossent);
575 tossent->fields.server->velocity[2] -= gravity;
576 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
577 VectorScale (tossent->fields.server->velocity, 0.05, move);
578 VectorAdd (tossent->fields.server->origin, move, end);
579 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
580 VectorCopy (trace.endpos, tossent->fields.server->origin);
582 if (trace.fraction < 1)
586 VectorCopy(original_origin , tossent->fields.server->origin );
587 VectorCopy(original_velocity , tossent->fields.server->velocity );
588 VectorCopy(original_angles , tossent->fields.server->angles );
589 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
594 static void VM_SV_tracetoss (void)
598 prvm_edict_t *ignore;
600 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
602 prog->xfunction->builtinsprofile += 600;
604 ent = PRVM_G_EDICT(OFS_PARM0);
605 if (ent == prog->edicts)
607 VM_Warning("tracetoss: can not use world entity\n");
610 ignore = PRVM_G_EDICT(OFS_PARM1);
612 trace = SV_Trace_Toss (ent, ignore);
614 VM_SetTraceGlobals(&trace);
617 //============================================================================
619 static int checkpvsbytes;
620 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
622 static int VM_SV_newcheckclient (int check)
628 // cycle to the next one
630 check = bound(1, check, svs.maxclients);
631 if (check == svs.maxclients)
639 prog->xfunction->builtinsprofile++;
641 if (i == svs.maxclients+1)
643 // look up the client's edict
644 ent = PRVM_EDICT_NUM(i);
645 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
646 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
648 // found a valid client (possibly the same one again)
652 // get the PVS for the entity
653 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
655 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
656 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
665 Returns a client (or object that has a client enemy) that would be a
668 If there is more than one valid option, they are cycled each frame
670 If (self.origin + self.viewofs) is not in the PVS of the current target,
671 it is not returned at all.
676 int c_invis, c_notvis;
677 static void VM_SV_checkclient (void)
679 prvm_edict_t *ent, *self;
682 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
684 // find a new check if on a new frame
685 if (sv.time - sv.lastchecktime >= 0.1)
687 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
688 sv.lastchecktime = sv.time;
691 // return check if it might be visible
692 ent = PRVM_EDICT_NUM(sv.lastcheck);
693 if (ent->priv.server->free || ent->fields.server->health <= 0)
695 VM_RETURN_EDICT(prog->edicts);
699 // if current entity can't possibly see the check entity, return 0
700 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
701 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
702 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
705 VM_RETURN_EDICT(prog->edicts);
709 // might be able to see it
711 VM_RETURN_EDICT(ent);
714 //============================================================================
721 Sends text over to the client's execution buffer
723 stuffcmd (clientent, value, ...)
726 static void VM_SV_stuffcmd (void)
730 char string[VM_STRINGTEMP_LENGTH];
732 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
734 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
735 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
737 VM_Warning("Can't stuffcmd to a non-client\n");
741 VM_VarString(1, string, sizeof(string));
744 host_client = svs.clients + entnum-1;
745 Host_ClientCommands ("%s", string);
753 Returns a chain of entities that have origins within a spherical area
755 findradius (origin, radius)
758 static void VM_SV_findradius (void)
760 prvm_edict_t *ent, *chain;
761 vec_t radius, radius2;
762 vec3_t org, eorg, mins, maxs;
765 prvm_edict_t *touchedicts[MAX_EDICTS];
767 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
769 chain = (prvm_edict_t *)prog->edicts;
771 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
772 radius = PRVM_G_FLOAT(OFS_PARM1);
773 radius2 = radius * radius;
775 mins[0] = org[0] - (radius + 1);
776 mins[1] = org[1] - (radius + 1);
777 mins[2] = org[2] - (radius + 1);
778 maxs[0] = org[0] + (radius + 1);
779 maxs[1] = org[1] + (radius + 1);
780 maxs[2] = org[2] + (radius + 1);
781 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
782 if (numtouchedicts > MAX_EDICTS)
784 // this never happens
785 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
786 numtouchedicts = MAX_EDICTS;
788 for (i = 0;i < numtouchedicts;i++)
790 ent = touchedicts[i];
791 prog->xfunction->builtinsprofile++;
792 // Quake did not return non-solid entities but darkplaces does
793 // (note: this is the reason you can't blow up fallen zombies)
794 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
796 // LordHavoc: compare against bounding box rather than center so it
797 // doesn't miss large objects, and use DotProduct instead of Length
798 // for a major speedup
799 VectorSubtract(org, ent->fields.server->origin, eorg);
800 if (sv_gameplayfix_findradiusdistancetobox.integer)
802 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
803 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
804 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
807 VectorMAMAM(1, eorg, 0.5f, ent->fields.server->mins, 0.5f, ent->fields.server->maxs, eorg);
808 if (DotProduct(eorg, eorg) < radius2)
810 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
815 VM_RETURN_EDICT(chain);
818 static void VM_SV_precache_sound (void)
820 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
821 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
822 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
825 static void VM_SV_precache_model (void)
827 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
828 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
829 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
836 float(float yaw, float dist[, settrace]) walkmove
839 static void VM_SV_walkmove (void)
848 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
850 // assume failure if it returns early
851 PRVM_G_FLOAT(OFS_RETURN) = 0;
853 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
854 if (ent == prog->edicts)
856 VM_Warning("walkmove: can not modify world entity\n");
859 if (ent->priv.server->free)
861 VM_Warning("walkmove: can not modify free entity\n");
864 yaw = PRVM_G_FLOAT(OFS_PARM0);
865 dist = PRVM_G_FLOAT(OFS_PARM1);
866 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
868 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
871 yaw = yaw*M_PI*2 / 360;
873 move[0] = cos(yaw)*dist;
874 move[1] = sin(yaw)*dist;
877 // save program state, because SV_movestep may call other progs
878 oldf = prog->xfunction;
879 oldself = prog->globals.server->self;
881 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
884 // restore program state
885 prog->xfunction = oldf;
886 prog->globals.server->self = oldself;
896 static void VM_SV_droptofloor (void)
902 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
904 // assume failure if it returns early
905 PRVM_G_FLOAT(OFS_RETURN) = 0;
907 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
908 if (ent == prog->edicts)
910 VM_Warning("droptofloor: can not modify world entity\n");
913 if (ent->priv.server->free)
915 VM_Warning("droptofloor: can not modify free entity\n");
919 VectorCopy (ent->fields.server->origin, end);
922 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
924 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
926 if (trace.fraction < 1)
927 VectorCopy (trace.endpos, ent->fields.server->origin);
928 SV_LinkEdict (ent, false);
929 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
930 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
931 PRVM_G_FLOAT(OFS_RETURN) = 1;
932 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
933 ent->priv.server->suspendedinairflag = true;
941 void(float style, string value) lightstyle
944 static void VM_SV_lightstyle (void)
951 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
953 style = (int)PRVM_G_FLOAT(OFS_PARM0);
954 val = PRVM_G_STRING(OFS_PARM1);
956 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
957 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
960 // change the string in sv
961 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
963 // send message to all clients on this server
964 if (sv.state != ss_active)
967 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
969 if (client->active && client->netconnection)
971 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
972 MSG_WriteChar (&client->netconnection->message,style);
973 MSG_WriteString (&client->netconnection->message, val);
983 static void VM_SV_checkbottom (void)
985 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
986 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
994 static void VM_SV_pointcontents (void)
996 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
997 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1004 Pick a vector for the player to shoot along
1005 vector aim(entity, missilespeed)
1008 static void VM_SV_aim (void)
1010 prvm_edict_t *ent, *check, *bestent;
1011 vec3_t start, dir, end, bestdir;
1014 float dist, bestdist;
1017 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1019 // assume failure if it returns early
1020 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1021 // if sv_aim is so high it can't possibly accept anything, skip out early
1022 if (sv_aim.value >= 1)
1025 ent = PRVM_G_EDICT(OFS_PARM0);
1026 if (ent == prog->edicts)
1028 VM_Warning("aim: can not use world entity\n");
1031 if (ent->priv.server->free)
1033 VM_Warning("aim: can not use free entity\n");
1036 speed = PRVM_G_FLOAT(OFS_PARM1);
1038 VectorCopy (ent->fields.server->origin, start);
1041 // try sending a trace straight
1042 VectorCopy (prog->globals.server->v_forward, dir);
1043 VectorMA (start, 2048, dir, end);
1044 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1045 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1046 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1048 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1053 // try all possible entities
1054 VectorCopy (dir, bestdir);
1055 bestdist = sv_aim.value;
1058 check = PRVM_NEXT_EDICT(prog->edicts);
1059 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1061 prog->xfunction->builtinsprofile++;
1062 if (check->fields.server->takedamage != DAMAGE_AIM)
1066 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1067 continue; // don't aim at teammate
1068 for (j=0 ; j<3 ; j++)
1069 end[j] = check->fields.server->origin[j]
1070 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1071 VectorSubtract (end, start, dir);
1072 VectorNormalize (dir);
1073 dist = DotProduct (dir, prog->globals.server->v_forward);
1074 if (dist < bestdist)
1075 continue; // to far to turn
1076 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1077 if (tr.ent == check)
1078 { // can shoot at this one
1086 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1087 dist = DotProduct (dir, prog->globals.server->v_forward);
1088 VectorScale (prog->globals.server->v_forward, dist, end);
1090 VectorNormalize (end);
1091 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1095 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1100 ===============================================================================
1104 ===============================================================================
1107 #define MSG_BROADCAST 0 // unreliable to all
1108 #define MSG_ONE 1 // reliable to one (msg_entity)
1109 #define MSG_ALL 2 // reliable to all
1110 #define MSG_INIT 3 // write to the init string
1111 #define MSG_ENTITY 5
1113 sizebuf_t *WriteDest (void)
1119 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1123 return &sv.datagram;
1126 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1127 entnum = PRVM_NUM_FOR_EDICT(ent);
1128 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1130 VM_Warning ("WriteDest: tried to write to non-client\n");
1131 return &sv.reliable_datagram;
1134 return &svs.clients[entnum-1].netconnection->message;
1137 VM_Warning ("WriteDest: bad destination\n");
1139 return &sv.reliable_datagram;
1145 return sv.writeentitiestoclient_msg;
1151 static void VM_SV_WriteByte (void)
1153 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1154 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1157 static void VM_SV_WriteChar (void)
1159 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1160 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1163 static void VM_SV_WriteShort (void)
1165 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1166 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1169 static void VM_SV_WriteLong (void)
1171 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1172 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1175 static void VM_SV_WriteAngle (void)
1177 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1178 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1181 static void VM_SV_WriteCoord (void)
1183 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1184 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1187 static void VM_SV_WriteString (void)
1189 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1190 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1193 static void VM_SV_WriteUnterminatedString (void)
1195 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1196 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1200 static void VM_SV_WriteEntity (void)
1202 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1203 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1206 //////////////////////////////////////////////////////////
1208 static void VM_SV_makestatic (void)
1213 // allow 0 parameters due to an id1 qc bug in which this function is used
1214 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1215 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1217 if (prog->argc >= 1)
1218 ent = PRVM_G_EDICT(OFS_PARM0);
1220 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1221 if (ent == prog->edicts)
1223 VM_Warning("makestatic: can not modify world entity\n");
1226 if (ent->priv.server->free)
1228 VM_Warning("makestatic: can not modify free entity\n");
1233 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1238 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1239 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1240 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1244 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1245 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1246 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1249 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1250 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1251 for (i=0 ; i<3 ; i++)
1253 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1254 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1257 // throw the entity away now
1261 //=============================================================================
1268 static void VM_SV_setspawnparms (void)
1274 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1276 ent = PRVM_G_EDICT(OFS_PARM0);
1277 i = PRVM_NUM_FOR_EDICT(ent);
1278 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1280 Con_Print("tried to setspawnparms on a non-client\n");
1284 // copy spawn parms out of the client_t
1285 client = svs.clients + i-1;
1286 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1287 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1294 Returns a color vector indicating the lighting at the requested point.
1296 (Internal Operation note: actually measures the light beneath the point, just like
1297 the model lighting on the client)
1302 static void VM_SV_getlight (void)
1304 vec3_t ambientcolor, diffusecolor, diffusenormal;
1306 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1307 p = PRVM_G_VECTOR(OFS_PARM0);
1308 VectorClear(ambientcolor);
1309 VectorClear(diffusecolor);
1310 VectorClear(diffusenormal);
1311 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1312 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1313 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1318 unsigned char type; // 1/2/8 or other value if isn't used
1322 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1323 static int vm_customstats_last;
1325 void VM_CustomStats_Clear (void)
1329 Z_Free(vm_customstats);
1330 vm_customstats = NULL;
1331 vm_customstats_last = -1;
1335 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1343 for(i=0; i<vm_customstats_last+1 ;i++)
1345 if(!vm_customstats[i].type)
1347 switch(vm_customstats[i].type)
1349 //string as 16 bytes
1352 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1353 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1354 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1355 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1356 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1358 //float field sent as-is
1360 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1362 //integer value of float field
1364 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1372 // void(float index, float type, .void field) SV_AddStat = #232;
1373 // Set up an auto-sent player stat.
1374 // Client's get thier own fields sent to them. Index may not be less than 32.
1375 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1376 // 1: string (4 stats carrying a total of 16 charactures)
1377 // 2: float (one stat, float converted to an integer for transportation)
1378 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1379 static void VM_SV_AddStat (void)
1384 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1388 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1391 VM_Warning("PF_SV_AddStat: not enough memory\n");
1395 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1396 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1397 off = PRVM_G_INT (OFS_PARM2);
1402 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1405 if(i >= (MAX_CL_STATS-32))
1407 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1410 if(i > (MAX_CL_STATS-32-4) && type == 1)
1412 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1415 vm_customstats[i].type = type;
1416 vm_customstats[i].fieldoffset = off;
1417 if(vm_customstats_last < i)
1418 vm_customstats_last = i;
1425 copies data from one entity to another
1427 copyentity(src, dst)
1430 static void VM_SV_copyentity (void)
1432 prvm_edict_t *in, *out;
1433 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1434 in = PRVM_G_EDICT(OFS_PARM0);
1435 if (in == prog->edicts)
1437 VM_Warning("copyentity: can not read world entity\n");
1440 if (in->priv.server->free)
1442 VM_Warning("copyentity: can not read free entity\n");
1445 out = PRVM_G_EDICT(OFS_PARM1);
1446 if (out == prog->edicts)
1448 VM_Warning("copyentity: can not modify world entity\n");
1451 if (out->priv.server->free)
1453 VM_Warning("copyentity: can not modify free entity\n");
1456 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1457 SV_LinkEdict(out, false);
1465 sets the color of a client and broadcasts the update to all connected clients
1467 setcolor(clientent, value)
1470 static void VM_SV_setcolor (void)
1476 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1477 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1478 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1480 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1482 Con_Print("tried to setcolor a non-client\n");
1486 client = svs.clients + entnum-1;
1489 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1491 client->edict->fields.server->team = (i & 15) + 1;
1494 if (client->old_colors != client->colors)
1496 client->old_colors = client->colors;
1497 // send notification to all clients
1498 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1499 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1500 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1508 effect(origin, modelname, startframe, framecount, framerate)
1511 static void VM_SV_effect (void)
1515 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1516 s = PRVM_G_STRING(OFS_PARM1);
1519 VM_Warning("effect: no model specified\n");
1523 i = SV_ModelIndex(s, 1);
1526 VM_Warning("effect: model not precached\n");
1530 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1532 VM_Warning("effect: framecount < 1\n");
1536 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1538 VM_Warning("effect: framerate < 1\n");
1542 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));
1545 static void VM_SV_te_blood (void)
1547 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1548 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1550 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1551 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1553 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1554 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1555 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1557 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1558 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1559 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1561 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1562 SV_FlushBroadcastMessages();
1565 static void VM_SV_te_bloodshower (void)
1567 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1568 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1570 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1571 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1573 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1574 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1575 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1577 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1578 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1579 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1581 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1583 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1584 SV_FlushBroadcastMessages();
1587 static void VM_SV_te_explosionrgb (void)
1589 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1590 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1591 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1593 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1594 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1595 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1597 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1598 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1599 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1600 SV_FlushBroadcastMessages();
1603 static void VM_SV_te_particlecube (void)
1605 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1606 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1608 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1609 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1611 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1612 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1613 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1615 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1616 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1617 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1619 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1620 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1621 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1623 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1625 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1626 // gravity true/false
1627 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1629 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1630 SV_FlushBroadcastMessages();
1633 static void VM_SV_te_particlerain (void)
1635 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1636 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1638 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1639 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1641 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1642 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1643 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1645 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1646 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1647 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1649 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1650 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1651 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1653 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1655 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1656 SV_FlushBroadcastMessages();
1659 static void VM_SV_te_particlesnow (void)
1661 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1662 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1664 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1665 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1667 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1668 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1671 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1672 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1673 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1675 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1676 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1677 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1679 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1681 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1682 SV_FlushBroadcastMessages();
1685 static void VM_SV_te_spark (void)
1687 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1688 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1690 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1691 MSG_WriteByte(&sv.datagram, TE_SPARK);
1693 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1694 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1695 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1697 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1698 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1699 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1701 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1702 SV_FlushBroadcastMessages();
1705 static void VM_SV_te_gunshotquad (void)
1707 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1708 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1709 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1711 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1712 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1713 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1714 SV_FlushBroadcastMessages();
1717 static void VM_SV_te_spikequad (void)
1719 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1720 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1721 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1723 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1724 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1725 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1726 SV_FlushBroadcastMessages();
1729 static void VM_SV_te_superspikequad (void)
1731 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1732 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1733 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1735 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1736 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1737 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1738 SV_FlushBroadcastMessages();
1741 static void VM_SV_te_explosionquad (void)
1743 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1744 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1745 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
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);
1750 SV_FlushBroadcastMessages();
1753 static void VM_SV_te_smallflash (void)
1755 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1756 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1757 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1759 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1760 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1761 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1762 SV_FlushBroadcastMessages();
1765 static void VM_SV_te_customflash (void)
1767 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1768 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1770 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1771 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1773 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1774 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1775 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1777 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1779 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1781 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1782 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1783 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1784 SV_FlushBroadcastMessages();
1787 static void VM_SV_te_gunshot (void)
1789 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1790 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1791 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1793 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1794 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1795 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1796 SV_FlushBroadcastMessages();
1799 static void VM_SV_te_spike (void)
1801 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1802 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1803 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1805 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1806 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1807 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1808 SV_FlushBroadcastMessages();
1811 static void VM_SV_te_superspike (void)
1813 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1814 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1815 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1817 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1818 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1819 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1820 SV_FlushBroadcastMessages();
1823 static void VM_SV_te_explosion (void)
1825 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1826 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1827 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1829 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1830 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1831 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1832 SV_FlushBroadcastMessages();
1835 static void VM_SV_te_tarexplosion (void)
1837 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1838 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1839 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1841 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1842 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1843 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1844 SV_FlushBroadcastMessages();
1847 static void VM_SV_te_wizspike (void)
1849 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1850 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1851 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1853 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1854 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1855 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1856 SV_FlushBroadcastMessages();
1859 static void VM_SV_te_knightspike (void)
1861 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1862 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1863 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1865 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1866 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1867 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1868 SV_FlushBroadcastMessages();
1871 static void VM_SV_te_lavasplash (void)
1873 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1874 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1875 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1877 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1878 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1879 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1880 SV_FlushBroadcastMessages();
1883 static void VM_SV_te_teleport (void)
1885 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1886 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1887 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
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);
1892 SV_FlushBroadcastMessages();
1895 static void VM_SV_te_explosion2 (void)
1897 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1898 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1899 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1902 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1903 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1905 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1906 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1907 SV_FlushBroadcastMessages();
1910 static void VM_SV_te_lightning1 (void)
1912 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1913 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1914 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1916 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1918 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1919 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1920 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1922 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1923 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1924 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1925 SV_FlushBroadcastMessages();
1928 static void VM_SV_te_lightning2 (void)
1930 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1931 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1932 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1934 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1936 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1937 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1938 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1940 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1941 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1942 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1943 SV_FlushBroadcastMessages();
1946 static void VM_SV_te_lightning3 (void)
1948 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1949 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1950 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1952 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1954 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1955 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1956 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1958 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1959 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1960 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1961 SV_FlushBroadcastMessages();
1964 static void VM_SV_te_beam (void)
1966 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1967 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1968 MSG_WriteByte(&sv.datagram, TE_BEAM);
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);
1979 SV_FlushBroadcastMessages();
1982 static void VM_SV_te_plasmaburn (void)
1984 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
1985 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1986 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
1987 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1988 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1989 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1990 SV_FlushBroadcastMessages();
1993 static void VM_SV_te_flamejet (void)
1995 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
1996 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1997 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
1999 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2000 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2001 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2003 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2004 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2005 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2007 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2008 SV_FlushBroadcastMessages();
2011 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2014 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2016 bestdist = 1000000000;
2018 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2020 // clip original point to each triangle of the surface and find the
2021 // triangle that is closest
2022 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2023 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2024 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2025 TriangleNormal(v[0], v[1], v[2], facenormal);
2026 VectorNormalize(facenormal);
2027 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2028 VectorMA(p, offsetdist, facenormal, temp);
2029 for (j = 0, k = 2;j < 3;k = j, j++)
2031 VectorSubtract(v[k], v[j], edgenormal);
2032 CrossProduct(edgenormal, facenormal, sidenormal);
2033 VectorNormalize(sidenormal);
2034 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2036 VectorMA(temp, offsetdist, sidenormal, temp);
2038 dist = VectorDistance2(temp, p);
2039 if (bestdist > dist)
2042 VectorCopy(temp, out);
2047 static model_t *getmodel(prvm_edict_t *ed)
2050 if (!ed || ed->priv.server->free)
2052 modelindex = (int)ed->fields.server->modelindex;
2053 if (modelindex < 1 || modelindex >= MAX_MODELS)
2055 return sv.models[modelindex];
2058 static msurface_t *getsurface(model_t *model, int surfacenum)
2060 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2062 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2066 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2067 static void VM_SV_getsurfacenumpoints(void)
2070 msurface_t *surface;
2071 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2072 // return 0 if no such surface
2073 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2075 PRVM_G_FLOAT(OFS_RETURN) = 0;
2079 // note: this (incorrectly) assumes it is a simple polygon
2080 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2082 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2083 static void VM_SV_getsurfacepoint(void)
2087 msurface_t *surface;
2089 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2090 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2091 ed = PRVM_G_EDICT(OFS_PARM0);
2092 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2094 // note: this (incorrectly) assumes it is a simple polygon
2095 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2096 if (pointnum < 0 || pointnum >= surface->num_vertices)
2098 // FIXME: implement rotation/scaling
2099 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2101 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2102 static void VM_SV_getsurfacenormal(void)
2105 msurface_t *surface;
2107 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2108 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2109 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2111 // FIXME: implement rotation/scaling
2112 // note: this (incorrectly) assumes it is a simple polygon
2113 // note: this only returns the first triangle, so it doesn't work very
2114 // well for curved surfaces or arbitrary meshes
2115 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);
2116 VectorNormalize(normal);
2117 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2119 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2120 static void VM_SV_getsurfacetexture(void)
2123 msurface_t *surface;
2124 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2125 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2126 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2128 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2130 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2131 static void VM_SV_getsurfacenearpoint(void)
2133 int surfacenum, best;
2135 vec_t dist, bestdist;
2138 msurface_t *surface;
2140 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2141 PRVM_G_FLOAT(OFS_RETURN) = -1;
2142 ed = PRVM_G_EDICT(OFS_PARM0);
2143 point = PRVM_G_VECTOR(OFS_PARM1);
2145 if (!ed || ed->priv.server->free)
2147 model = getmodel(ed);
2148 if (!model || !model->num_surfaces)
2151 // FIXME: implement rotation/scaling
2152 VectorSubtract(point, ed->fields.server->origin, p);
2154 bestdist = 1000000000;
2155 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2157 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2158 // first see if the nearest point on the surface's box is closer than the previous match
2159 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2160 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2161 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2162 dist = VectorLength2(clipped);
2163 if (dist < bestdist)
2165 // it is, check the nearest point on the actual geometry
2166 clippointtosurface(model, surface, p, clipped);
2167 VectorSubtract(clipped, p, clipped);
2168 dist += VectorLength2(clipped);
2169 if (dist < bestdist)
2171 // that's closer too, store it as the best match
2177 PRVM_G_FLOAT(OFS_RETURN) = best;
2179 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2180 static void VM_SV_getsurfaceclippedpoint(void)
2184 msurface_t *surface;
2186 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2187 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2188 ed = PRVM_G_EDICT(OFS_PARM0);
2189 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2191 // FIXME: implement rotation/scaling
2192 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2193 clippointtosurface(model, surface, p, out);
2194 // FIXME: implement rotation/scaling
2195 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2198 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2199 //this function originally written by KrimZon, made shorter by LordHavoc
2200 static void VM_SV_clientcommand (void)
2202 client_t *temp_client;
2204 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2206 //find client for this entity
2207 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2208 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2210 Con_Print("PF_clientcommand: entity is not a client\n");
2214 temp_client = host_client;
2215 host_client = svs.clients + i;
2216 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2217 host_client = temp_client;
2220 //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)
2221 static void VM_SV_setattachment (void)
2223 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2224 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2225 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2229 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2231 if (e == prog->edicts)
2233 VM_Warning("setattachment: can not modify world entity\n");
2236 if (e->priv.server->free)
2238 VM_Warning("setattachment: can not modify free entity\n");
2242 if (tagentity == NULL)
2243 tagentity = prog->edicts;
2245 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2247 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2249 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2252 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2254 modelindex = (int)tagentity->fields.server->modelindex;
2255 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2257 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2259 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);
2262 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));
2266 /////////////////////////////////////////
2267 // DP_MD3_TAGINFO extension coded by VorteX
2269 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2274 i = (int)e->fields.server->modelindex;
2275 if (i < 1 || i >= MAX_MODELS)
2277 model = sv.models[i];
2279 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2282 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2284 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2288 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);
2290 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);
2293 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2299 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2300 && (model = sv.models[(int)ent->fields.server->modelindex])
2301 && model->animscenes)
2303 // if model has wrong frame, engine automatically switches to model first frame
2304 frame = (int)ent->fields.server->frame;
2305 if (frame < 0 || frame >= model->numframes)
2307 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2309 *out = identitymatrix;
2313 // Warnings/errors code:
2314 // 0 - normal (everything all-right)
2317 // 3 - null or non-precached model
2318 // 4 - no tags with requested index
2319 // 5 - runaway loop at attachment chain
2320 extern cvar_t cl_bob;
2321 extern cvar_t cl_bobcycle;
2322 extern cvar_t cl_bobup;
2323 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2327 int modelindex, attachloop;
2328 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2331 *out = identitymatrix; // warnings and errors return identical matrix
2333 if (ent == prog->edicts)
2335 if (ent->priv.server->free)
2338 modelindex = (int)ent->fields.server->modelindex;
2339 if (modelindex <= 0 || modelindex > MAX_MODELS)
2342 model = sv.models[modelindex];
2344 tagmatrix = identitymatrix;
2345 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2349 if (attachloop >= 256) // prevent runaway looping
2351 // apply transformation by child's tagindex on parent entity and then
2352 // by parent entity itself
2353 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2354 if (ret && attachloop == 0)
2356 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2357 SV_GetEntityMatrix(ent, &entitymatrix, false);
2358 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2359 // next iteration we process the parent entity
2360 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2362 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2363 ent = PRVM_EDICT_NUM(val->edict);
2370 // RENDER_VIEWMODEL magic
2371 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2373 Matrix4x4_Copy(&tagmatrix, out);
2374 ent = PRVM_EDICT_NUM(val->edict);
2376 SV_GetEntityMatrix(ent, &entitymatrix, true);
2377 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2380 // Cl_bob, ported from rendering code
2381 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2384 // LordHavoc: this code is *weird*, but not replacable (I think it
2385 // should be done in QC on the server, but oh well, quake is quake)
2386 // LordHavoc: figured out bobup: the time at which the sin is at 180
2387 // degrees (which allows lengthening or squishing the peak or valley)
2388 cycle = sv.time/cl_bobcycle.value;
2389 cycle -= (int)cycle;
2390 if (cycle < cl_bobup.value)
2391 cycle = sin(M_PI * cycle / cl_bobup.value);
2393 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2394 // bob is proportional to velocity in the xy plane
2395 // (don't count Z, or jumping messes it up)
2396 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;
2397 bob = bob*0.3 + bob*0.7*cycle;
2398 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2405 //float(entity ent, string tagname) gettagindex;
2407 static void VM_SV_gettagindex (void)
2410 const char *tag_name;
2411 int modelindex, tag_index;
2413 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2415 ent = PRVM_G_EDICT(OFS_PARM0);
2416 tag_name = PRVM_G_STRING(OFS_PARM1);
2418 if (ent == prog->edicts)
2420 VM_Warning("gettagindex: can't affect world entity\n");
2423 if (ent->priv.server->free)
2425 VM_Warning("gettagindex: can't affect free entity\n");
2429 modelindex = (int)ent->fields.server->modelindex;
2431 if (modelindex <= 0 || modelindex > MAX_MODELS)
2432 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2435 tag_index = SV_GetTagIndex(ent, tag_name);
2437 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2439 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2442 //vector(entity ent, float tagindex) gettaginfo;
2443 static void VM_SV_gettaginfo (void)
2447 matrix4x4_t tag_matrix;
2450 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2452 e = PRVM_G_EDICT(OFS_PARM0);
2453 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2455 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2456 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2461 VM_Warning("gettagindex: can't affect world entity\n");
2464 VM_Warning("gettagindex: can't affect free entity\n");
2467 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2470 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2473 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2478 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2479 static void VM_SV_dropclient (void)
2482 client_t *oldhostclient;
2483 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2484 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2485 if (clientnum < 0 || clientnum >= svs.maxclients)
2487 VM_Warning("dropclient: not a client\n");
2490 if (!svs.clients[clientnum].active)
2492 VM_Warning("dropclient: that client slot is not connected\n");
2495 oldhostclient = host_client;
2496 host_client = svs.clients + clientnum;
2497 SV_DropClient(false);
2498 host_client = oldhostclient;
2501 //entity() spawnclient (DP_SV_BOTCLIENT)
2502 static void VM_SV_spawnclient (void)
2506 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2507 prog->xfunction->builtinsprofile += 2;
2509 for (i = 0;i < svs.maxclients;i++)
2511 if (!svs.clients[i].active)
2513 prog->xfunction->builtinsprofile += 100;
2514 SV_ConnectClient (i, NULL);
2515 // this has to be set or else ClientDisconnect won't be called
2516 // we assume the qc will call ClientConnect...
2517 svs.clients[i].clientconnectcalled = true;
2518 ed = PRVM_EDICT_NUM(i + 1);
2522 VM_RETURN_EDICT(ed);
2525 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2526 static void VM_SV_clienttype (void)
2529 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2530 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2531 if (clientnum < 0 || clientnum >= svs.maxclients)
2532 PRVM_G_FLOAT(OFS_RETURN) = 3;
2533 else if (!svs.clients[clientnum].active)
2534 PRVM_G_FLOAT(OFS_RETURN) = 0;
2535 else if (svs.clients[clientnum].netconnection)
2536 PRVM_G_FLOAT(OFS_RETURN) = 1;
2538 PRVM_G_FLOAT(OFS_RETURN) = 2;
2545 string(string key) serverkey
2548 void VM_SV_serverkey(void)
2550 char string[VM_STRINGTEMP_LENGTH];
2551 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2552 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2553 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2556 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2557 static void VM_SV_setmodelindex (void)
2562 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2564 e = PRVM_G_EDICT(OFS_PARM0);
2565 if (e == prog->edicts)
2567 VM_Warning("setmodelindex: can not modify world entity\n");
2570 if (e->priv.server->free)
2572 VM_Warning("setmodelindex: can not modify free entity\n");
2575 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2576 if (i <= 0 || i > MAX_MODELS)
2578 VM_Warning("setmodelindex: invalid modelindex\n");
2581 if (!sv.model_precache[i][0])
2583 VM_Warning("setmodelindex: model not precached\n");
2587 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2588 e->fields.server->modelindex = i;
2594 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2595 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2597 SetMinMaxSize (e, quakemins, quakemaxs, true);
2600 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2603 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2604 static void VM_SV_modelnameforindex (void)
2607 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2609 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2611 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2612 if (i <= 0 || i > MAX_MODELS)
2614 VM_Warning("modelnameforindex: invalid modelindex\n");
2617 if (!sv.model_precache[i][0])
2619 VM_Warning("modelnameforindex: model not precached\n");
2623 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2626 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2627 static void VM_SV_particleeffectnum (void)
2630 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2631 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2634 PRVM_G_FLOAT(OFS_RETURN) = i;
2637 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2638 static void VM_SV_trailparticles (void)
2640 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2642 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2643 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2644 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2645 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2646 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2647 SV_FlushBroadcastMessages();
2650 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2651 static void VM_SV_pointparticles (void)
2653 int effectnum, count;
2655 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2656 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2657 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2658 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2659 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2660 if (count == 1 && !VectorLength2(vel))
2663 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2664 MSG_WriteShort(&sv.datagram, effectnum);
2665 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2669 // 1+2+12+12+2=29 bytes
2670 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2671 MSG_WriteShort(&sv.datagram, effectnum);
2672 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2673 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2674 MSG_WriteShort(&sv.datagram, count);
2677 SV_FlushBroadcastMessages();
2680 prvm_builtin_t vm_sv_builtins[] = {
2681 NULL, // #0 NULL function (not callable) (QUAKE)
2682 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2683 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2684 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2685 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2686 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2687 VM_break, // #6 void() break (QUAKE)
2688 VM_random, // #7 float() random (QUAKE)
2689 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2690 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2691 VM_error, // #10 void(string e) error (QUAKE)
2692 VM_objerror, // #11 void(string e) objerror (QUAKE)
2693 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2694 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2695 VM_spawn, // #14 entity() spawn (QUAKE)
2696 VM_remove, // #15 void(entity e) remove (QUAKE)
2697 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2698 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2699 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2700 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2701 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2702 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2703 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2704 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2705 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2706 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2707 VM_ftos, // #26 string(float f) ftos (QUAKE)
2708 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2709 VM_coredump, // #28 void() coredump (QUAKE)
2710 VM_traceon, // #29 void() traceon (QUAKE)
2711 VM_traceoff, // #30 void() traceoff (QUAKE)
2712 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2713 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2714 NULL, // #33 (QUAKE)
2715 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2716 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2717 VM_rint, // #36 float(float v) rint (QUAKE)
2718 VM_floor, // #37 float(float v) floor (QUAKE)
2719 VM_ceil, // #38 float(float v) ceil (QUAKE)
2720 NULL, // #39 (QUAKE)
2721 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2722 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2723 NULL, // #42 (QUAKE)
2724 VM_fabs, // #43 float(float f) fabs (QUAKE)
2725 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2726 VM_cvar, // #45 float(string s) cvar (QUAKE)
2727 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2728 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2729 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2730 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2731 NULL, // #50 (QUAKE)
2732 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2733 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2734 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2735 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2736 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2737 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2738 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2739 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2740 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2741 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2742 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2743 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2744 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2745 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2746 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2747 NULL, // #66 (QUAKE)
2748 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2749 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2750 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2751 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2752 NULL, // #71 (QUAKE)
2753 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2754 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2755 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2756 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2757 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2758 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2759 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2760 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2761 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2762 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2763 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2764 NULL, // #83 (QUAKE)
2765 NULL, // #84 (QUAKE)
2766 NULL, // #85 (QUAKE)
2767 NULL, // #86 (QUAKE)
2768 NULL, // #87 (QUAKE)
2769 NULL, // #88 (QUAKE)
2770 NULL, // #89 (QUAKE)
2771 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2772 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2773 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2774 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2775 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2776 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2777 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2778 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2779 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2780 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2781 // FrikaC and Telejano range #100-#199
2792 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2793 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2794 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2795 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2796 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2797 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2798 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2799 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2800 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2801 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2882 // FTEQW range #200-#299
2901 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2905 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2906 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2911 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2915 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2983 // CSQC range #300-#399
2984 NULL, // #300 void() clearscene (EXT_CSQC)
2985 NULL, // #301 void(float mask) addentities (EXT_CSQC)
2986 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
2987 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
2988 NULL, // #304 void() renderscene (EXT_CSQC)
2989 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2990 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2991 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2992 NULL, // #308 void() R_EndPolygon
2994 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
2995 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
2999 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3000 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3001 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3002 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3003 NULL, // #319 void(string name) freepic (EXT_CSQC)
3004 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3005 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3006 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3007 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3008 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3009 NULL, // #325 void(void) drawresetcliparea
3014 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3015 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3016 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3017 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3018 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3019 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3020 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3021 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3022 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3023 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3024 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3025 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3026 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3027 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3028 NULL, // #344 vector() getmousepos (EXT_CSQC)
3029 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3030 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3031 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3032 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3033 NULL, // #349 float() isdemo (EXT_CSQC)
3034 VM_isserver, // #350 float() isserver (EXT_CSQC)
3035 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3036 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3037 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3038 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3044 NULL, // #360 float() readbyte (EXT_CSQC)
3045 NULL, // #361 float() readchar (EXT_CSQC)
3046 NULL, // #362 float() readshort (EXT_CSQC)
3047 NULL, // #363 float() readlong (EXT_CSQC)
3048 NULL, // #364 float() readcoord (EXT_CSQC)
3049 NULL, // #365 float() readangle (EXT_CSQC)
3050 NULL, // #366 string() readstring (EXT_CSQC)
3051 NULL, // #367 float() readfloat (EXT_CSQC)
3084 // LordHavoc's range #400-#499
3085 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3086 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3087 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3088 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3089 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3090 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3091 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3092 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3093 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)
3094 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3095 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3096 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3097 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3098 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3099 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3100 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3101 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3102 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3103 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3104 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3105 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3106 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3107 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3108 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3109 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3110 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3111 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3112 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3113 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3114 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3115 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3116 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3117 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3118 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3119 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3120 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3121 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3122 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3123 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3124 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3125 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3126 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3127 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3128 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3129 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
3130 VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
3131 VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
3132 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
3133 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3134 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3135 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3136 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3137 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3138 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3139 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3140 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3141 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3142 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3144 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3145 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3146 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3147 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3148 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3149 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3150 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3151 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3152 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3153 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3154 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3156 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3157 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3158 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3159 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3160 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3161 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3162 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3163 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3164 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3165 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3166 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3167 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3187 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3189 void VM_SV_Cmd_Init(void)
3194 void VM_SV_Cmd_Reset(void)