3 //============================================================================
8 char *vm_sv_extensions =
13 "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 "
55 "DP_QC_CVAR_DEFSTRING "
59 "DP_QC_FINDCHAINFLAGS "
60 "DP_QC_FINDCHAINFLOAT "
68 "DP_QC_MULTIPLETEMPSTRINGS "
70 "DP_QC_SINCOSSQRTPOW "
72 "DP_QC_STRING_CASE_FUNCTIONS "
73 "DP_QC_STRINGBUFFERS "
74 "DP_QC_STRINGCOLORFUNCTIONS "
75 "DP_QC_TOKENIZEBYSEPARATOR "
78 "DP_QC_TRACE_MOVETYPE_HITMODEL "
79 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
80 "DP_QC_UNLIMITEDTEMPSTRINGS "
81 "DP_QC_VECTORVECTORS "
87 "DP_SND_DIRECTIONLESSATTNNONE "
96 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
97 "DP_SV_DRAWONLYTOCLIENT "
100 "DP_SV_ENTITYCONTENTSTRANSITION "
101 "DP_SV_MODELFLAGS_AS_EFFECTS "
103 "DP_SV_NODRAWTOCLIENT "
105 "DP_SV_PLAYERPHYSICS "
106 "DP_SV_POINTPARTICLES "
107 "DP_SV_PRECACHEANYTIME "
110 "DP_SV_ROTATINGBMODEL "
113 "DP_SV_WRITEUNTERMINATEDSTRING "
117 "DP_TE_EXPLOSIONRGB "
119 "DP_TE_PARTICLECUBE "
120 "DP_TE_PARTICLERAIN "
121 "DP_TE_PARTICLESNOW "
123 "DP_TE_QUADEFFECTS1 "
126 "DP_TE_STANDARDEFFECTBUILTINS "
127 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
130 //"EXT_CSQC " // not ready yet
132 "KRIMZON_SV_PARSECLIENTCOMMAND "
135 "NEXUIZ_PLAYERMODEL "
137 "PRYDON_CLIENTCURSOR "
138 "TENEBRAE_GFX_DLIGHTS "
148 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.
150 setorigin (entity, origin)
153 static void VM_SV_setorigin (void)
158 VM_SAFEPARMCOUNT(2, VM_setorigin);
160 e = PRVM_G_EDICT(OFS_PARM0);
161 if (e == prog->edicts)
163 VM_Warning("setorigin: can not modify world entity\n");
166 if (e->priv.server->free)
168 VM_Warning("setorigin: can not modify free entity\n");
171 org = PRVM_G_VECTOR(OFS_PARM1);
172 VectorCopy (org, e->fields.server->origin);
173 SV_LinkEdict (e, false);
177 void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
181 for (i=0 ; i<3 ; i++)
183 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
185 // set derived values
186 VectorCopy (min, e->fields.server->mins);
187 VectorCopy (max, e->fields.server->maxs);
188 VectorSubtract (max, min, e->fields.server->size);
190 SV_LinkEdict (e, false);
197 the size box is rotated by the current angle
198 LordHavoc: no it isn't...
200 setsize (entity, minvector, maxvector)
203 static void VM_SV_setsize (void)
208 VM_SAFEPARMCOUNT(3, VM_setsize);
210 e = PRVM_G_EDICT(OFS_PARM0);
211 if (e == prog->edicts)
213 VM_Warning("setsize: can not modify world entity\n");
216 if (e->priv.server->free)
218 VM_Warning("setsize: can not modify free entity\n");
221 min = PRVM_G_VECTOR(OFS_PARM1);
222 max = PRVM_G_VECTOR(OFS_PARM2);
223 SetMinMaxSize (e, min, max, false);
231 setmodel(entity, model)
234 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
235 static void VM_SV_setmodel (void)
241 VM_SAFEPARMCOUNT(2, VM_setmodel);
243 e = PRVM_G_EDICT(OFS_PARM0);
244 if (e == prog->edicts)
246 VM_Warning("setmodel: can not modify world entity\n");
249 if (e->priv.server->free)
251 VM_Warning("setmodel: can not modify free entity\n");
254 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
255 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
256 e->fields.server->modelindex = i;
262 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
263 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
265 SetMinMaxSize (e, quakemins, quakemaxs, true);
268 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
275 single print to a specific client
277 sprint(clientent, value)
280 static void VM_SV_sprint (void)
284 char string[VM_STRINGTEMP_LENGTH];
286 VM_VarString(1, string, sizeof(string));
288 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
290 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
291 // LordHavoc: div0 requested that sprintto world operate like print
298 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
300 VM_Warning("tried to centerprint to a non-client\n");
304 client = svs.clients + entnum-1;
305 if (!client->netconnection)
308 MSG_WriteChar(&client->netconnection->message,svc_print);
309 MSG_WriteString(&client->netconnection->message, string);
317 single print to a specific client
319 centerprint(clientent, value)
322 static void VM_SV_centerprint (void)
326 char string[VM_STRINGTEMP_LENGTH];
328 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
330 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
332 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
334 VM_Warning("tried to centerprint to a non-client\n");
338 client = svs.clients + entnum-1;
339 if (!client->netconnection)
342 VM_VarString(1, string, sizeof(string));
343 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
344 MSG_WriteString(&client->netconnection->message, string);
351 particle(origin, color, count)
354 static void VM_SV_particle (void)
360 VM_SAFEPARMCOUNT(4, VM_SV_particle);
362 org = PRVM_G_VECTOR(OFS_PARM0);
363 dir = PRVM_G_VECTOR(OFS_PARM1);
364 color = PRVM_G_FLOAT(OFS_PARM2);
365 count = PRVM_G_FLOAT(OFS_PARM3);
366 SV_StartParticle (org, dir, (int)color, (int)count);
376 static void VM_SV_ambientsound (void)
380 float vol, attenuation;
383 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
385 pos = PRVM_G_VECTOR (OFS_PARM0);
386 samp = PRVM_G_STRING(OFS_PARM1);
387 vol = PRVM_G_FLOAT(OFS_PARM2);
388 attenuation = PRVM_G_FLOAT(OFS_PARM3);
390 // check to see if samp was properly precached
391 soundnum = SV_SoundIndex(samp, 1);
399 // add an svc_spawnambient command to the level signon packet
402 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
404 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
406 MSG_WriteVector(&sv.signon, pos, sv.protocol);
409 MSG_WriteShort (&sv.signon, soundnum);
411 MSG_WriteByte (&sv.signon, soundnum);
413 MSG_WriteByte (&sv.signon, (int)(vol*255));
414 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
422 Each entity can have eight independant sound sources, like voice,
425 Channel 0 is an auto-allocate channel, the others override anything
426 already running on that entity/channel pair.
428 An attenuation of 0 will play full volume everywhere in the level.
429 Larger attenuations will drop off.
433 static void VM_SV_sound (void)
437 prvm_edict_t *entity;
441 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
443 entity = PRVM_G_EDICT(OFS_PARM0);
444 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
445 sample = PRVM_G_STRING(OFS_PARM2);
446 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
447 attenuation = PRVM_G_FLOAT(OFS_PARM4);
450 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
454 if (volume < 0 || volume > 255)
456 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
460 if (attenuation < 0 || attenuation > 4)
462 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
466 if (channel < 0 || channel > 7)
468 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
472 SV_StartSound (entity, channel, sample, volume, attenuation);
479 Used for use tracing and shot targeting
480 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
481 if the tryents flag is set.
483 traceline (vector1, vector2, movetype, ignore)
486 static void VM_SV_traceline (void)
493 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
495 prog->xfunction->builtinsprofile += 30;
497 v1 = PRVM_G_VECTOR(OFS_PARM0);
498 v2 = PRVM_G_VECTOR(OFS_PARM1);
499 move = (int)PRVM_G_FLOAT(OFS_PARM2);
500 ent = PRVM_G_EDICT(OFS_PARM3);
502 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]))
503 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));
505 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
507 VM_SetTraceGlobals(&trace);
515 Used for use tracing and shot targeting
516 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
517 if the tryents flag is set.
519 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
522 // LordHavoc: added this for my own use, VERY useful, similar to traceline
523 static void VM_SV_tracebox (void)
525 float *v1, *v2, *m1, *m2;
530 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
532 prog->xfunction->builtinsprofile += 30;
534 v1 = PRVM_G_VECTOR(OFS_PARM0);
535 m1 = PRVM_G_VECTOR(OFS_PARM1);
536 m2 = PRVM_G_VECTOR(OFS_PARM2);
537 v2 = PRVM_G_VECTOR(OFS_PARM3);
538 move = (int)PRVM_G_FLOAT(OFS_PARM4);
539 ent = PRVM_G_EDICT(OFS_PARM5);
541 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]))
542 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));
544 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
546 VM_SetTraceGlobals(&trace);
549 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
554 vec3_t original_origin;
555 vec3_t original_velocity;
556 vec3_t original_angles;
557 vec3_t original_avelocity;
561 VectorCopy(tossent->fields.server->origin , original_origin );
562 VectorCopy(tossent->fields.server->velocity , original_velocity );
563 VectorCopy(tossent->fields.server->angles , original_angles );
564 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
566 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
567 if (val != NULL && val->_float != 0)
568 gravity = val->_float;
571 gravity *= sv_gravity.value * 0.05;
573 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
575 SV_CheckVelocity (tossent);
576 tossent->fields.server->velocity[2] -= gravity;
577 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
578 VectorScale (tossent->fields.server->velocity, 0.05, move);
579 VectorAdd (tossent->fields.server->origin, move, end);
580 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
581 VectorCopy (trace.endpos, tossent->fields.server->origin);
583 if (trace.fraction < 1)
587 VectorCopy(original_origin , tossent->fields.server->origin );
588 VectorCopy(original_velocity , tossent->fields.server->velocity );
589 VectorCopy(original_angles , tossent->fields.server->angles );
590 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
595 static void VM_SV_tracetoss (void)
599 prvm_edict_t *ignore;
601 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
603 prog->xfunction->builtinsprofile += 600;
605 ent = PRVM_G_EDICT(OFS_PARM0);
606 if (ent == prog->edicts)
608 VM_Warning("tracetoss: can not use world entity\n");
611 ignore = PRVM_G_EDICT(OFS_PARM1);
613 trace = SV_Trace_Toss (ent, ignore);
615 VM_SetTraceGlobals(&trace);
618 //============================================================================
620 static int checkpvsbytes;
621 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
623 static int VM_SV_newcheckclient (int check)
629 // cycle to the next one
631 check = bound(1, check, svs.maxclients);
632 if (check == svs.maxclients)
640 prog->xfunction->builtinsprofile++;
642 if (i == svs.maxclients+1)
644 // look up the client's edict
645 ent = PRVM_EDICT_NUM(i);
646 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
647 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
649 // found a valid client (possibly the same one again)
653 // get the PVS for the entity
654 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
656 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
657 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
666 Returns a client (or object that has a client enemy) that would be a
669 If there is more than one valid option, they are cycled each frame
671 If (self.origin + self.viewofs) is not in the PVS of the current target,
672 it is not returned at all.
677 int c_invis, c_notvis;
678 static void VM_SV_checkclient (void)
680 prvm_edict_t *ent, *self;
683 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
685 // find a new check if on a new frame
686 if (sv.time - sv.lastchecktime >= 0.1)
688 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
689 sv.lastchecktime = sv.time;
692 // return check if it might be visible
693 ent = PRVM_EDICT_NUM(sv.lastcheck);
694 if (ent->priv.server->free || ent->fields.server->health <= 0)
696 VM_RETURN_EDICT(prog->edicts);
700 // if current entity can't possibly see the check entity, return 0
701 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
702 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
703 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
706 VM_RETURN_EDICT(prog->edicts);
710 // might be able to see it
712 VM_RETURN_EDICT(ent);
715 //============================================================================
722 Sends text over to the client's execution buffer
724 stuffcmd (clientent, value, ...)
727 static void VM_SV_stuffcmd (void)
731 char string[VM_STRINGTEMP_LENGTH];
733 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
735 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
736 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
738 VM_Warning("Can't stuffcmd to a non-client\n");
742 VM_VarString(1, string, sizeof(string));
745 host_client = svs.clients + entnum-1;
746 Host_ClientCommands ("%s", string);
754 Returns a chain of entities that have origins within a spherical area
756 findradius (origin, radius)
759 static void VM_SV_findradius (void)
761 prvm_edict_t *ent, *chain;
762 vec_t radius, radius2;
763 vec3_t org, eorg, mins, maxs;
766 prvm_edict_t *touchedicts[MAX_EDICTS];
768 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
770 chain = (prvm_edict_t *)prog->edicts;
772 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
773 radius = PRVM_G_FLOAT(OFS_PARM1);
774 radius2 = radius * radius;
776 mins[0] = org[0] - (radius + 1);
777 mins[1] = org[1] - (radius + 1);
778 mins[2] = org[2] - (radius + 1);
779 maxs[0] = org[0] + (radius + 1);
780 maxs[1] = org[1] + (radius + 1);
781 maxs[2] = org[2] + (radius + 1);
782 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
783 if (numtouchedicts > MAX_EDICTS)
785 // this never happens
786 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
787 numtouchedicts = MAX_EDICTS;
789 for (i = 0;i < numtouchedicts;i++)
791 ent = touchedicts[i];
792 prog->xfunction->builtinsprofile++;
793 // Quake did not return non-solid entities but darkplaces does
794 // (note: this is the reason you can't blow up fallen zombies)
795 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
797 // LordHavoc: compare against bounding box rather than center so it
798 // doesn't miss large objects, and use DotProduct instead of Length
799 // for a major speedup
800 VectorSubtract(org, ent->fields.server->origin, eorg);
801 if (sv_gameplayfix_findradiusdistancetobox.integer)
803 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
804 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
805 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
808 VectorMAMAM(1, eorg, 0.5f, ent->fields.server->mins, 0.5f, ent->fields.server->maxs, eorg);
809 if (DotProduct(eorg, eorg) < radius2)
811 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
816 VM_RETURN_EDICT(chain);
819 static void VM_SV_precache_sound (void)
821 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
822 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
823 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
826 static void VM_SV_precache_model (void)
828 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
829 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
830 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
837 float(float yaw, float dist[, settrace]) walkmove
840 static void VM_SV_walkmove (void)
849 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
851 // assume failure if it returns early
852 PRVM_G_FLOAT(OFS_RETURN) = 0;
854 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
855 if (ent == prog->edicts)
857 VM_Warning("walkmove: can not modify world entity\n");
860 if (ent->priv.server->free)
862 VM_Warning("walkmove: can not modify free entity\n");
865 yaw = PRVM_G_FLOAT(OFS_PARM0);
866 dist = PRVM_G_FLOAT(OFS_PARM1);
867 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
869 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
872 yaw = yaw*M_PI*2 / 360;
874 move[0] = cos(yaw)*dist;
875 move[1] = sin(yaw)*dist;
878 // save program state, because SV_movestep may call other progs
879 oldf = prog->xfunction;
880 oldself = prog->globals.server->self;
882 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
885 // restore program state
886 prog->xfunction = oldf;
887 prog->globals.server->self = oldself;
897 static void VM_SV_droptofloor (void)
903 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
905 // assume failure if it returns early
906 PRVM_G_FLOAT(OFS_RETURN) = 0;
908 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
909 if (ent == prog->edicts)
911 VM_Warning("droptofloor: can not modify world entity\n");
914 if (ent->priv.server->free)
916 VM_Warning("droptofloor: can not modify free entity\n");
920 VectorCopy (ent->fields.server->origin, end);
923 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
925 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
927 if (trace.fraction < 1)
928 VectorCopy (trace.endpos, ent->fields.server->origin);
929 SV_LinkEdict (ent, false);
930 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
931 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
932 PRVM_G_FLOAT(OFS_RETURN) = 1;
933 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
934 ent->priv.server->suspendedinairflag = true;
942 void(float style, string value) lightstyle
945 static void VM_SV_lightstyle (void)
952 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
954 style = (int)PRVM_G_FLOAT(OFS_PARM0);
955 val = PRVM_G_STRING(OFS_PARM1);
957 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
958 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
961 // change the string in sv
962 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
964 // send message to all clients on this server
965 if (sv.state != ss_active)
968 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
970 if (client->active && client->netconnection)
972 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
973 MSG_WriteChar (&client->netconnection->message,style);
974 MSG_WriteString (&client->netconnection->message, val);
984 static void VM_SV_checkbottom (void)
986 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
987 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
995 static void VM_SV_pointcontents (void)
997 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
998 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1005 Pick a vector for the player to shoot along
1006 vector aim(entity, missilespeed)
1009 static void VM_SV_aim (void)
1011 prvm_edict_t *ent, *check, *bestent;
1012 vec3_t start, dir, end, bestdir;
1015 float dist, bestdist;
1018 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1020 // assume failure if it returns early
1021 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1022 // if sv_aim is so high it can't possibly accept anything, skip out early
1023 if (sv_aim.value >= 1)
1026 ent = PRVM_G_EDICT(OFS_PARM0);
1027 if (ent == prog->edicts)
1029 VM_Warning("aim: can not use world entity\n");
1032 if (ent->priv.server->free)
1034 VM_Warning("aim: can not use free entity\n");
1037 speed = PRVM_G_FLOAT(OFS_PARM1);
1039 VectorCopy (ent->fields.server->origin, start);
1042 // try sending a trace straight
1043 VectorCopy (prog->globals.server->v_forward, dir);
1044 VectorMA (start, 2048, dir, end);
1045 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1046 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1047 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1049 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1054 // try all possible entities
1055 VectorCopy (dir, bestdir);
1056 bestdist = sv_aim.value;
1059 check = PRVM_NEXT_EDICT(prog->edicts);
1060 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1062 prog->xfunction->builtinsprofile++;
1063 if (check->fields.server->takedamage != DAMAGE_AIM)
1067 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1068 continue; // don't aim at teammate
1069 for (j=0 ; j<3 ; j++)
1070 end[j] = check->fields.server->origin[j]
1071 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1072 VectorSubtract (end, start, dir);
1073 VectorNormalize (dir);
1074 dist = DotProduct (dir, prog->globals.server->v_forward);
1075 if (dist < bestdist)
1076 continue; // to far to turn
1077 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1078 if (tr.ent == check)
1079 { // can shoot at this one
1087 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1088 dist = DotProduct (dir, prog->globals.server->v_forward);
1089 VectorScale (prog->globals.server->v_forward, dist, end);
1091 VectorNormalize (end);
1092 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1096 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1101 ===============================================================================
1105 ===============================================================================
1108 #define MSG_BROADCAST 0 // unreliable to all
1109 #define MSG_ONE 1 // reliable to one (msg_entity)
1110 #define MSG_ALL 2 // reliable to all
1111 #define MSG_INIT 3 // write to the init string
1112 #define MSG_ENTITY 5
1114 sizebuf_t *WriteDest (void)
1120 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1124 return &sv.datagram;
1127 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1128 entnum = PRVM_NUM_FOR_EDICT(ent);
1129 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1131 VM_Warning ("WriteDest: tried to write to non-client\n");
1132 return &sv.reliable_datagram;
1135 return &svs.clients[entnum-1].netconnection->message;
1138 VM_Warning ("WriteDest: bad destination\n");
1140 return &sv.reliable_datagram;
1146 return sv.writeentitiestoclient_msg;
1152 static void VM_SV_WriteByte (void)
1154 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1155 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1158 static void VM_SV_WriteChar (void)
1160 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1161 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1164 static void VM_SV_WriteShort (void)
1166 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1167 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1170 static void VM_SV_WriteLong (void)
1172 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1173 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1176 static void VM_SV_WriteAngle (void)
1178 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1179 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1182 static void VM_SV_WriteCoord (void)
1184 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1185 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1188 static void VM_SV_WriteString (void)
1190 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1191 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1194 static void VM_SV_WriteUnterminatedString (void)
1196 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1197 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1201 static void VM_SV_WriteEntity (void)
1203 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1204 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1207 //////////////////////////////////////////////////////////
1209 static void VM_SV_makestatic (void)
1214 // allow 0 parameters due to an id1 qc bug in which this function is used
1215 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1216 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1218 if (prog->argc >= 1)
1219 ent = PRVM_G_EDICT(OFS_PARM0);
1221 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1222 if (ent == prog->edicts)
1224 VM_Warning("makestatic: can not modify world entity\n");
1227 if (ent->priv.server->free)
1229 VM_Warning("makestatic: can not modify free entity\n");
1234 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1239 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1240 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1241 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1245 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1246 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1247 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1250 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1251 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1252 for (i=0 ; i<3 ; i++)
1254 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1255 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1258 // throw the entity away now
1262 //=============================================================================
1269 static void VM_SV_setspawnparms (void)
1275 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1277 ent = PRVM_G_EDICT(OFS_PARM0);
1278 i = PRVM_NUM_FOR_EDICT(ent);
1279 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1281 Con_Print("tried to setspawnparms on a non-client\n");
1285 // copy spawn parms out of the client_t
1286 client = svs.clients + i-1;
1287 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1288 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1295 Returns a color vector indicating the lighting at the requested point.
1297 (Internal Operation note: actually measures the light beneath the point, just like
1298 the model lighting on the client)
1303 static void VM_SV_getlight (void)
1305 vec3_t ambientcolor, diffusecolor, diffusenormal;
1307 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1308 p = PRVM_G_VECTOR(OFS_PARM0);
1309 VectorClear(ambientcolor);
1310 VectorClear(diffusecolor);
1311 VectorClear(diffusenormal);
1312 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1313 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1314 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1319 unsigned char type; // 1/2/8 or other value if isn't used
1323 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1324 static int vm_customstats_last;
1326 void VM_CustomStats_Clear (void)
1330 Z_Free(vm_customstats);
1331 vm_customstats = NULL;
1332 vm_customstats_last = -1;
1336 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1344 for(i=0; i<vm_customstats_last+1 ;i++)
1346 if(!vm_customstats[i].type)
1348 switch(vm_customstats[i].type)
1350 //string as 16 bytes
1353 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1354 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1355 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1356 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1357 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1359 //float field sent as-is
1361 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1363 //integer value of float field
1365 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1373 // void(float index, float type, .void field) SV_AddStat = #232;
1374 // Set up an auto-sent player stat.
1375 // Client's get thier own fields sent to them. Index may not be less than 32.
1376 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1377 // 1: string (4 stats carrying a total of 16 charactures)
1378 // 2: float (one stat, float converted to an integer for transportation)
1379 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1380 static void VM_SV_AddStat (void)
1385 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1389 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1392 VM_Warning("PF_SV_AddStat: not enough memory\n");
1396 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1397 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1398 off = PRVM_G_INT (OFS_PARM2);
1403 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1406 if(i >= (MAX_CL_STATS-32))
1408 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1411 if(i > (MAX_CL_STATS-32-4) && type == 1)
1413 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1416 vm_customstats[i].type = type;
1417 vm_customstats[i].fieldoffset = off;
1418 if(vm_customstats_last < i)
1419 vm_customstats_last = i;
1426 copies data from one entity to another
1428 copyentity(src, dst)
1431 static void VM_SV_copyentity (void)
1433 prvm_edict_t *in, *out;
1434 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1435 in = PRVM_G_EDICT(OFS_PARM0);
1436 if (in == prog->edicts)
1438 VM_Warning("copyentity: can not read world entity\n");
1441 if (in->priv.server->free)
1443 VM_Warning("copyentity: can not read free entity\n");
1446 out = PRVM_G_EDICT(OFS_PARM1);
1447 if (out == prog->edicts)
1449 VM_Warning("copyentity: can not modify world entity\n");
1452 if (out->priv.server->free)
1454 VM_Warning("copyentity: can not modify free entity\n");
1457 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1458 SV_LinkEdict(out, false);
1466 sets the color of a client and broadcasts the update to all connected clients
1468 setcolor(clientent, value)
1471 static void VM_SV_setcolor (void)
1477 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1478 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1479 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1481 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1483 Con_Print("tried to setcolor a non-client\n");
1487 client = svs.clients + entnum-1;
1490 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1492 client->edict->fields.server->team = (i & 15) + 1;
1495 if (client->old_colors != client->colors)
1497 client->old_colors = client->colors;
1498 // send notification to all clients
1499 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1500 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1501 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1509 effect(origin, modelname, startframe, framecount, framerate)
1512 static void VM_SV_effect (void)
1516 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1517 s = PRVM_G_STRING(OFS_PARM1);
1520 VM_Warning("effect: no model specified\n");
1524 i = SV_ModelIndex(s, 1);
1527 VM_Warning("effect: model not precached\n");
1531 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1533 VM_Warning("effect: framecount < 1\n");
1537 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1539 VM_Warning("effect: framerate < 1\n");
1543 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));
1546 static void VM_SV_te_blood (void)
1548 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1549 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1551 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1552 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1554 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1555 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1556 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1558 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1559 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1560 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1562 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1563 SV_FlushBroadcastMessages();
1566 static void VM_SV_te_bloodshower (void)
1568 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1569 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1571 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1572 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1574 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1575 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1576 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1578 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1579 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1580 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1582 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1584 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1585 SV_FlushBroadcastMessages();
1588 static void VM_SV_te_explosionrgb (void)
1590 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1591 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1592 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1594 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1595 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1596 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1598 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1599 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1600 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1601 SV_FlushBroadcastMessages();
1604 static void VM_SV_te_particlecube (void)
1606 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1607 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1609 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1610 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1612 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1613 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1614 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1616 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1617 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1618 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1620 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1621 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1622 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1624 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1626 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1627 // gravity true/false
1628 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1630 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1631 SV_FlushBroadcastMessages();
1634 static void VM_SV_te_particlerain (void)
1636 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1637 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1639 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1640 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1642 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1643 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1644 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1646 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1647 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1648 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1650 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1651 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1652 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1654 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1656 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1657 SV_FlushBroadcastMessages();
1660 static void VM_SV_te_particlesnow (void)
1662 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1663 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1665 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1666 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1668 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1672 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1673 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1674 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1676 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1677 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1678 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1680 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1682 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1683 SV_FlushBroadcastMessages();
1686 static void VM_SV_te_spark (void)
1688 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1689 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1691 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1692 MSG_WriteByte(&sv.datagram, TE_SPARK);
1694 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1695 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1696 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1698 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1699 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1700 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1702 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1703 SV_FlushBroadcastMessages();
1706 static void VM_SV_te_gunshotquad (void)
1708 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1709 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1710 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1712 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1713 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1714 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1715 SV_FlushBroadcastMessages();
1718 static void VM_SV_te_spikequad (void)
1720 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1721 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1722 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1724 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1725 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1726 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1727 SV_FlushBroadcastMessages();
1730 static void VM_SV_te_superspikequad (void)
1732 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1733 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1734 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1736 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1737 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1738 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1739 SV_FlushBroadcastMessages();
1742 static void VM_SV_te_explosionquad (void)
1744 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1745 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1746 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1748 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1749 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1750 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1751 SV_FlushBroadcastMessages();
1754 static void VM_SV_te_smallflash (void)
1756 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1757 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1758 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1760 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1761 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1762 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1763 SV_FlushBroadcastMessages();
1766 static void VM_SV_te_customflash (void)
1768 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1769 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1771 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1772 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1774 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1775 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1776 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1778 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1780 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1782 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1783 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1784 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1785 SV_FlushBroadcastMessages();
1788 static void VM_SV_te_gunshot (void)
1790 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1791 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1792 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1794 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1795 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1796 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1797 SV_FlushBroadcastMessages();
1800 static void VM_SV_te_spike (void)
1802 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1803 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1804 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1806 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1807 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1808 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1809 SV_FlushBroadcastMessages();
1812 static void VM_SV_te_superspike (void)
1814 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1815 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1816 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1818 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1819 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1820 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1821 SV_FlushBroadcastMessages();
1824 static void VM_SV_te_explosion (void)
1826 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1827 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1828 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1830 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1831 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1833 SV_FlushBroadcastMessages();
1836 static void VM_SV_te_tarexplosion (void)
1838 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1839 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1840 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1842 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1843 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1844 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1845 SV_FlushBroadcastMessages();
1848 static void VM_SV_te_wizspike (void)
1850 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1851 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1852 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1854 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1855 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1856 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1857 SV_FlushBroadcastMessages();
1860 static void VM_SV_te_knightspike (void)
1862 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1863 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1864 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1866 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1867 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1869 SV_FlushBroadcastMessages();
1872 static void VM_SV_te_lavasplash (void)
1874 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1875 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1876 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1878 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1879 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1880 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1881 SV_FlushBroadcastMessages();
1884 static void VM_SV_te_teleport (void)
1886 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1887 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1888 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1890 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1891 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1892 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1893 SV_FlushBroadcastMessages();
1896 static void VM_SV_te_explosion2 (void)
1898 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1899 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1900 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1902 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1903 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1904 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1906 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1907 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1908 SV_FlushBroadcastMessages();
1911 static void VM_SV_te_lightning1 (void)
1913 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1914 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1915 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1917 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1919 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1920 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1921 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1923 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1924 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1925 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1926 SV_FlushBroadcastMessages();
1929 static void VM_SV_te_lightning2 (void)
1931 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1932 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1933 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1935 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1937 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1938 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1939 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1941 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1942 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1943 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1944 SV_FlushBroadcastMessages();
1947 static void VM_SV_te_lightning3 (void)
1949 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1950 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1951 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1953 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1955 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1956 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1957 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1959 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1960 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1961 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1962 SV_FlushBroadcastMessages();
1965 static void VM_SV_te_beam (void)
1967 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1968 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1969 MSG_WriteByte(&sv.datagram, TE_BEAM);
1971 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1974 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1977 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1978 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1979 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1980 SV_FlushBroadcastMessages();
1983 static void VM_SV_te_plasmaburn (void)
1985 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
1986 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1987 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
1988 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1989 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1990 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1991 SV_FlushBroadcastMessages();
1994 static void VM_SV_te_flamejet (void)
1996 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
1997 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1998 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2000 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2001 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2002 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2004 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2005 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2006 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2008 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2009 SV_FlushBroadcastMessages();
2012 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2015 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2017 bestdist = 1000000000;
2019 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2021 // clip original point to each triangle of the surface and find the
2022 // triangle that is closest
2023 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2024 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2025 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2026 TriangleNormal(v[0], v[1], v[2], facenormal);
2027 VectorNormalize(facenormal);
2028 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2029 VectorMA(p, offsetdist, facenormal, temp);
2030 for (j = 0, k = 2;j < 3;k = j, j++)
2032 VectorSubtract(v[k], v[j], edgenormal);
2033 CrossProduct(edgenormal, facenormal, sidenormal);
2034 VectorNormalize(sidenormal);
2035 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2037 VectorMA(temp, offsetdist, sidenormal, temp);
2039 dist = VectorDistance2(temp, p);
2040 if (bestdist > dist)
2043 VectorCopy(temp, out);
2048 static model_t *getmodel(prvm_edict_t *ed)
2051 if (!ed || ed->priv.server->free)
2053 modelindex = (int)ed->fields.server->modelindex;
2054 if (modelindex < 1 || modelindex >= MAX_MODELS)
2056 return sv.models[modelindex];
2059 static msurface_t *getsurface(model_t *model, int surfacenum)
2061 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2063 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2067 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2068 static void VM_SV_getsurfacenumpoints(void)
2071 msurface_t *surface;
2072 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2073 // return 0 if no such surface
2074 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2076 PRVM_G_FLOAT(OFS_RETURN) = 0;
2080 // note: this (incorrectly) assumes it is a simple polygon
2081 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2083 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2084 static void VM_SV_getsurfacepoint(void)
2088 msurface_t *surface;
2090 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2091 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2092 ed = PRVM_G_EDICT(OFS_PARM0);
2093 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2095 // note: this (incorrectly) assumes it is a simple polygon
2096 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2097 if (pointnum < 0 || pointnum >= surface->num_vertices)
2099 // FIXME: implement rotation/scaling
2100 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2102 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2103 static void VM_SV_getsurfacenormal(void)
2106 msurface_t *surface;
2108 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2109 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2110 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2112 // FIXME: implement rotation/scaling
2113 // note: this (incorrectly) assumes it is a simple polygon
2114 // note: this only returns the first triangle, so it doesn't work very
2115 // well for curved surfaces or arbitrary meshes
2116 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);
2117 VectorNormalize(normal);
2118 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2120 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2121 static void VM_SV_getsurfacetexture(void)
2124 msurface_t *surface;
2125 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2126 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2127 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2129 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2131 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2132 static void VM_SV_getsurfacenearpoint(void)
2134 int surfacenum, best;
2136 vec_t dist, bestdist;
2139 msurface_t *surface;
2141 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2142 PRVM_G_FLOAT(OFS_RETURN) = -1;
2143 ed = PRVM_G_EDICT(OFS_PARM0);
2144 point = PRVM_G_VECTOR(OFS_PARM1);
2146 if (!ed || ed->priv.server->free)
2148 model = getmodel(ed);
2149 if (!model || !model->num_surfaces)
2152 // FIXME: implement rotation/scaling
2153 VectorSubtract(point, ed->fields.server->origin, p);
2155 bestdist = 1000000000;
2156 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2158 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2159 // first see if the nearest point on the surface's box is closer than the previous match
2160 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2161 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2162 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2163 dist = VectorLength2(clipped);
2164 if (dist < bestdist)
2166 // it is, check the nearest point on the actual geometry
2167 clippointtosurface(model, surface, p, clipped);
2168 VectorSubtract(clipped, p, clipped);
2169 dist += VectorLength2(clipped);
2170 if (dist < bestdist)
2172 // that's closer too, store it as the best match
2178 PRVM_G_FLOAT(OFS_RETURN) = best;
2180 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2181 static void VM_SV_getsurfaceclippedpoint(void)
2185 msurface_t *surface;
2187 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2188 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2189 ed = PRVM_G_EDICT(OFS_PARM0);
2190 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2192 // FIXME: implement rotation/scaling
2193 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2194 clippointtosurface(model, surface, p, out);
2195 // FIXME: implement rotation/scaling
2196 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2199 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2200 //this function originally written by KrimZon, made shorter by LordHavoc
2201 static void VM_SV_clientcommand (void)
2203 client_t *temp_client;
2205 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2207 //find client for this entity
2208 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2209 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2211 Con_Print("PF_clientcommand: entity is not a client\n");
2215 temp_client = host_client;
2216 host_client = svs.clients + i;
2217 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2218 host_client = temp_client;
2221 //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)
2222 static void VM_SV_setattachment (void)
2224 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2225 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2226 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2230 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2232 if (e == prog->edicts)
2234 VM_Warning("setattachment: can not modify world entity\n");
2237 if (e->priv.server->free)
2239 VM_Warning("setattachment: can not modify free entity\n");
2243 if (tagentity == NULL)
2244 tagentity = prog->edicts;
2246 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2248 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2250 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2253 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2255 modelindex = (int)tagentity->fields.server->modelindex;
2256 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2258 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2260 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);
2263 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));
2267 /////////////////////////////////////////
2268 // DP_MD3_TAGINFO extension coded by VorteX
2270 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2275 i = (int)e->fields.server->modelindex;
2276 if (i < 1 || i >= MAX_MODELS)
2278 model = sv.models[i];
2280 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2283 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2285 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2289 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);
2291 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);
2294 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2300 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2301 && (model = sv.models[(int)ent->fields.server->modelindex])
2302 && model->animscenes)
2304 // if model has wrong frame, engine automatically switches to model first frame
2305 frame = (int)ent->fields.server->frame;
2306 if (frame < 0 || frame >= model->numframes)
2308 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2310 *out = identitymatrix;
2314 // Warnings/errors code:
2315 // 0 - normal (everything all-right)
2318 // 3 - null or non-precached model
2319 // 4 - no tags with requested index
2320 // 5 - runaway loop at attachment chain
2321 extern cvar_t cl_bob;
2322 extern cvar_t cl_bobcycle;
2323 extern cvar_t cl_bobup;
2324 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2328 int modelindex, attachloop;
2329 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2332 *out = identitymatrix; // warnings and errors return identical matrix
2334 if (ent == prog->edicts)
2336 if (ent->priv.server->free)
2339 modelindex = (int)ent->fields.server->modelindex;
2340 if (modelindex <= 0 || modelindex > MAX_MODELS)
2343 model = sv.models[modelindex];
2345 tagmatrix = identitymatrix;
2346 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2350 if (attachloop >= 256) // prevent runaway looping
2352 // apply transformation by child's tagindex on parent entity and then
2353 // by parent entity itself
2354 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2355 if (ret && attachloop == 0)
2357 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2358 SV_GetEntityMatrix(ent, &entitymatrix, false);
2359 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2360 // next iteration we process the parent entity
2361 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2363 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2364 ent = PRVM_EDICT_NUM(val->edict);
2371 // RENDER_VIEWMODEL magic
2372 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2374 Matrix4x4_Copy(&tagmatrix, out);
2375 ent = PRVM_EDICT_NUM(val->edict);
2377 SV_GetEntityMatrix(ent, &entitymatrix, true);
2378 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2381 // Cl_bob, ported from rendering code
2382 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2385 // LordHavoc: this code is *weird*, but not replacable (I think it
2386 // should be done in QC on the server, but oh well, quake is quake)
2387 // LordHavoc: figured out bobup: the time at which the sin is at 180
2388 // degrees (which allows lengthening or squishing the peak or valley)
2389 cycle = sv.time/cl_bobcycle.value;
2390 cycle -= (int)cycle;
2391 if (cycle < cl_bobup.value)
2392 cycle = sin(M_PI * cycle / cl_bobup.value);
2394 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2395 // bob is proportional to velocity in the xy plane
2396 // (don't count Z, or jumping messes it up)
2397 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;
2398 bob = bob*0.3 + bob*0.7*cycle;
2399 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2406 //float(entity ent, string tagname) gettagindex;
2408 static void VM_SV_gettagindex (void)
2411 const char *tag_name;
2412 int modelindex, tag_index;
2414 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2416 ent = PRVM_G_EDICT(OFS_PARM0);
2417 tag_name = PRVM_G_STRING(OFS_PARM1);
2419 if (ent == prog->edicts)
2421 VM_Warning("gettagindex: can't affect world entity\n");
2424 if (ent->priv.server->free)
2426 VM_Warning("gettagindex: can't affect free entity\n");
2430 modelindex = (int)ent->fields.server->modelindex;
2432 if (modelindex <= 0 || modelindex > MAX_MODELS)
2433 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2436 tag_index = SV_GetTagIndex(ent, tag_name);
2438 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2440 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2443 //vector(entity ent, float tagindex) gettaginfo;
2444 static void VM_SV_gettaginfo (void)
2448 matrix4x4_t tag_matrix;
2451 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2453 e = PRVM_G_EDICT(OFS_PARM0);
2454 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2456 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2457 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2462 VM_Warning("gettagindex: can't affect world entity\n");
2465 VM_Warning("gettagindex: can't affect free entity\n");
2468 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2471 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2474 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2479 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2480 static void VM_SV_dropclient (void)
2483 client_t *oldhostclient;
2484 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2485 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2486 if (clientnum < 0 || clientnum >= svs.maxclients)
2488 VM_Warning("dropclient: not a client\n");
2491 if (!svs.clients[clientnum].active)
2493 VM_Warning("dropclient: that client slot is not connected\n");
2496 oldhostclient = host_client;
2497 host_client = svs.clients + clientnum;
2498 SV_DropClient(false);
2499 host_client = oldhostclient;
2502 //entity() spawnclient (DP_SV_BOTCLIENT)
2503 static void VM_SV_spawnclient (void)
2507 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2508 prog->xfunction->builtinsprofile += 2;
2510 for (i = 0;i < svs.maxclients;i++)
2512 if (!svs.clients[i].active)
2514 prog->xfunction->builtinsprofile += 100;
2515 SV_ConnectClient (i, NULL);
2516 // this has to be set or else ClientDisconnect won't be called
2517 // we assume the qc will call ClientConnect...
2518 svs.clients[i].clientconnectcalled = true;
2519 ed = PRVM_EDICT_NUM(i + 1);
2523 VM_RETURN_EDICT(ed);
2526 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2527 static void VM_SV_clienttype (void)
2530 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2531 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2532 if (clientnum < 0 || clientnum >= svs.maxclients)
2533 PRVM_G_FLOAT(OFS_RETURN) = 3;
2534 else if (!svs.clients[clientnum].active)
2535 PRVM_G_FLOAT(OFS_RETURN) = 0;
2536 else if (svs.clients[clientnum].netconnection)
2537 PRVM_G_FLOAT(OFS_RETURN) = 1;
2539 PRVM_G_FLOAT(OFS_RETURN) = 2;
2546 string(string key) serverkey
2549 void VM_SV_serverkey(void)
2551 char string[VM_STRINGTEMP_LENGTH];
2552 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2553 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2554 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2557 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2558 static void VM_SV_setmodelindex (void)
2563 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2565 e = PRVM_G_EDICT(OFS_PARM0);
2566 if (e == prog->edicts)
2568 VM_Warning("setmodelindex: can not modify world entity\n");
2571 if (e->priv.server->free)
2573 VM_Warning("setmodelindex: can not modify free entity\n");
2576 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2577 if (i <= 0 || i > MAX_MODELS)
2579 VM_Warning("setmodelindex: invalid modelindex\n");
2582 if (!sv.model_precache[i][0])
2584 VM_Warning("setmodelindex: model not precached\n");
2588 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2589 e->fields.server->modelindex = i;
2595 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2596 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2598 SetMinMaxSize (e, quakemins, quakemaxs, true);
2601 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2604 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2605 static void VM_SV_modelnameforindex (void)
2608 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2610 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2612 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2613 if (i <= 0 || i > MAX_MODELS)
2615 VM_Warning("modelnameforindex: invalid modelindex\n");
2618 if (!sv.model_precache[i][0])
2620 VM_Warning("modelnameforindex: model not precached\n");
2624 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2627 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2628 static void VM_SV_particleeffectnum (void)
2631 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2632 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2635 PRVM_G_FLOAT(OFS_RETURN) = i;
2638 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2639 static void VM_SV_trailparticles (void)
2641 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2643 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2644 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2645 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2646 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2647 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2648 SV_FlushBroadcastMessages();
2651 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2652 static void VM_SV_pointparticles (void)
2654 int effectnum, count;
2656 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2657 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2658 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2659 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2660 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2661 if (count == 1 && !VectorLength2(vel))
2664 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2665 MSG_WriteShort(&sv.datagram, effectnum);
2666 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2670 // 1+2+12+12+2=29 bytes
2671 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2672 MSG_WriteShort(&sv.datagram, effectnum);
2673 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2674 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2675 MSG_WriteShort(&sv.datagram, count);
2678 SV_FlushBroadcastMessages();
2681 prvm_builtin_t vm_sv_builtins[] = {
2682 NULL, // #0 NULL function (not callable) (QUAKE)
2683 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2684 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2685 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2686 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2687 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2688 VM_break, // #6 void() break (QUAKE)
2689 VM_random, // #7 float() random (QUAKE)
2690 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2691 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2692 VM_error, // #10 void(string e) error (QUAKE)
2693 VM_objerror, // #11 void(string e) objerror (QUAKE)
2694 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2695 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2696 VM_spawn, // #14 entity() spawn (QUAKE)
2697 VM_remove, // #15 void(entity e) remove (QUAKE)
2698 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2699 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2700 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2701 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2702 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2703 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2704 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2705 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2706 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2707 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2708 VM_ftos, // #26 string(float f) ftos (QUAKE)
2709 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2710 VM_coredump, // #28 void() coredump (QUAKE)
2711 VM_traceon, // #29 void() traceon (QUAKE)
2712 VM_traceoff, // #30 void() traceoff (QUAKE)
2713 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2714 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2715 NULL, // #33 (QUAKE)
2716 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2717 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2718 VM_rint, // #36 float(float v) rint (QUAKE)
2719 VM_floor, // #37 float(float v) floor (QUAKE)
2720 VM_ceil, // #38 float(float v) ceil (QUAKE)
2721 NULL, // #39 (QUAKE)
2722 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2723 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2724 NULL, // #42 (QUAKE)
2725 VM_fabs, // #43 float(float f) fabs (QUAKE)
2726 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2727 VM_cvar, // #45 float(string s) cvar (QUAKE)
2728 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2729 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2730 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2731 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2732 NULL, // #50 (QUAKE)
2733 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2734 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2735 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2736 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2737 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2738 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2739 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2740 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2741 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2742 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2743 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2744 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2745 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2746 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2747 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2748 NULL, // #66 (QUAKE)
2749 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2750 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2751 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2752 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2753 NULL, // #71 (QUAKE)
2754 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2755 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2756 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2757 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2758 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2759 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2760 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2761 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2762 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2763 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2764 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2765 NULL, // #83 (QUAKE)
2766 NULL, // #84 (QUAKE)
2767 NULL, // #85 (QUAKE)
2768 NULL, // #86 (QUAKE)
2769 NULL, // #87 (QUAKE)
2770 NULL, // #88 (QUAKE)
2771 NULL, // #89 (QUAKE)
2772 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2773 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2774 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2775 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2776 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2777 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2778 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2779 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2780 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2781 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2782 // FrikaC and Telejano range #100-#199
2793 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2794 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2795 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2796 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2797 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2798 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2799 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2800 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2801 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2802 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2883 // FTEQW range #200-#299
2902 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2906 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2907 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2912 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2916 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2984 // CSQC range #300-#399
2985 NULL, // #300 void() clearscene (EXT_CSQC)
2986 NULL, // #301 void(float mask) addentities (EXT_CSQC)
2987 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
2988 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
2989 NULL, // #304 void() renderscene (EXT_CSQC)
2990 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2991 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2992 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2993 NULL, // #308 void() R_EndPolygon
2995 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
2996 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3000 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3001 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3002 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3003 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3004 NULL, // #319 void(string name) freepic (EXT_CSQC)
3005 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3006 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3007 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3008 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3009 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3010 NULL, // #325 void(void) drawresetcliparea
3015 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3016 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3017 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3018 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3019 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3020 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3021 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3022 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3023 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3024 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3025 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3026 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3027 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3028 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3029 NULL, // #344 vector() getmousepos (EXT_CSQC)
3030 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3031 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3032 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3033 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3034 NULL, // #349 float() isdemo (EXT_CSQC)
3035 VM_isserver, // #350 float() isserver (EXT_CSQC)
3036 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3037 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3038 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3039 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3045 NULL, // #360 float() readbyte (EXT_CSQC)
3046 NULL, // #361 float() readchar (EXT_CSQC)
3047 NULL, // #362 float() readshort (EXT_CSQC)
3048 NULL, // #363 float() readlong (EXT_CSQC)
3049 NULL, // #364 float() readcoord (EXT_CSQC)
3050 NULL, // #365 float() readangle (EXT_CSQC)
3051 NULL, // #366 string() readstring (EXT_CSQC)
3052 NULL, // #367 float() readfloat (EXT_CSQC)
3085 // LordHavoc's range #400-#499
3086 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3087 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3088 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3089 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3090 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3091 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3092 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3093 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3094 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)
3095 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3096 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3097 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3098 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3099 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3100 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3101 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3102 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3103 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3104 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3105 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3106 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3107 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3108 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3109 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3110 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3111 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3112 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3113 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3114 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3115 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3116 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3117 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3118 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3119 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3120 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3121 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3122 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3123 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3124 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3125 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3126 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3127 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3128 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3129 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3130 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
3131 VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
3132 VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
3133 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
3134 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3135 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3136 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3137 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3138 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3139 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3140 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3141 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3142 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3143 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3145 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3146 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3147 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3148 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3149 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3150 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3151 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3152 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3153 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3154 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3155 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3157 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3158 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3159 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3160 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3161 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3162 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3163 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3164 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3165 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3166 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3167 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3168 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3188 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3190 void VM_SV_Cmd_Init(void)
3195 void VM_SV_Cmd_Reset(void)