3 //============================================================================
6 cvar_t sv_aim = {CVAR_SAVE, "sv_aim", "2", "maximum cosine angle for quake's vertical autoaim, a value above 1 completely disables the autoaim, quake used 0.93"};
9 char *vm_sv_extensions =
14 "DP_CON_ALIASPARAMETERS "
31 "DP_ENT_CUSTOMCOLORMAP "
32 "DP_ENT_EXTERIORMODELTOCLIENT "
34 "DP_ENT_LOWPRECISION "
37 "DP_GFX_EXTERNALTEXTURES "
38 "DP_GFX_EXTERNALTEXTURES_PERMAP "
40 "DP_GFX_QUAKE3MODELTAGS "
44 "DP_HALFLIFE_MAP_CVAR "
50 "DP_MOVETYPEBOUNCEMISSILE "
52 "DP_QC_ASINACOSATANATAN2TAN "
58 "DP_QC_FINDCHAINFLAGS "
59 "DP_QC_FINDCHAINFLOAT "
67 "DP_QC_MULTIPLETEMPSTRINGS "
69 "DP_QC_SINCOSSQRTPOW "
71 "DP_QC_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_PRECACHEANYTIME "
108 "DP_SV_ROTATINGBMODEL "
111 "DP_SV_WRITEUNTERMINATEDSTRING "
115 "DP_TE_EXPLOSIONRGB "
117 "DP_TE_PARTICLECUBE "
118 "DP_TE_PARTICLERAIN "
119 "DP_TE_PARTICLESNOW "
121 "DP_TE_QUADEFFECTS1 "
124 "DP_TE_STANDARDEFFECTBUILTINS "
125 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
128 //"EXT_CSQC " // not ready yet
130 "KRIMZON_SV_PARSECLIENTCOMMAND "
133 "NEXUIZ_PLAYERMODEL "
135 "PRYDON_CLIENTCURSOR "
136 "TENEBRAE_GFX_DLIGHTS "
146 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.
148 setorigin (entity, origin)
151 static void VM_SV_setorigin (void)
156 VM_SAFEPARMCOUNT(2, VM_setorigin);
158 e = PRVM_G_EDICT(OFS_PARM0);
159 if (e == prog->edicts)
161 VM_Warning("setorigin: can not modify world entity\n");
164 if (e->priv.server->free)
166 VM_Warning("setorigin: can not modify free entity\n");
169 org = PRVM_G_VECTOR(OFS_PARM1);
170 VectorCopy (org, e->fields.server->origin);
171 SV_LinkEdict (e, false);
175 void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
179 for (i=0 ; i<3 ; i++)
181 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
183 // set derived values
184 VectorCopy (min, e->fields.server->mins);
185 VectorCopy (max, e->fields.server->maxs);
186 VectorSubtract (max, min, e->fields.server->size);
188 SV_LinkEdict (e, false);
195 the size box is rotated by the current angle
196 LordHavoc: no it isn't...
198 setsize (entity, minvector, maxvector)
201 static void VM_SV_setsize (void)
206 VM_SAFEPARMCOUNT(3, VM_setsize);
208 e = PRVM_G_EDICT(OFS_PARM0);
209 if (e == prog->edicts)
211 VM_Warning("setsize: can not modify world entity\n");
214 if (e->priv.server->free)
216 VM_Warning("setsize: can not modify free entity\n");
219 min = PRVM_G_VECTOR(OFS_PARM1);
220 max = PRVM_G_VECTOR(OFS_PARM2);
221 SetMinMaxSize (e, min, max, false);
229 setmodel(entity, model)
232 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
233 static void VM_SV_setmodel (void)
239 VM_SAFEPARMCOUNT(2, VM_setmodel);
241 e = PRVM_G_EDICT(OFS_PARM0);
242 if (e == prog->edicts)
244 VM_Warning("setmodel: can not modify world entity\n");
247 if (e->priv.server->free)
249 VM_Warning("setmodel: can not modify free entity\n");
252 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
253 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
254 e->fields.server->modelindex = i;
260 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
261 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
263 SetMinMaxSize (e, quakemins, quakemaxs, true);
266 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
273 single print to a specific client
275 sprint(clientent, value)
278 static void VM_SV_sprint (void)
282 char string[VM_STRINGTEMP_LENGTH];
284 VM_VarString(1, string, sizeof(string));
286 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
288 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
289 // LordHavoc: div0 requested that sprintto world operate like print
296 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
298 VM_Warning("tried to centerprint to a non-client\n");
302 client = svs.clients + entnum-1;
303 if (!client->netconnection)
306 MSG_WriteChar(&client->netconnection->message,svc_print);
307 MSG_WriteString(&client->netconnection->message, string);
315 single print to a specific client
317 centerprint(clientent, value)
320 static void VM_SV_centerprint (void)
324 char string[VM_STRINGTEMP_LENGTH];
326 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
328 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
330 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
332 VM_Warning("tried to centerprint to a non-client\n");
336 client = svs.clients + entnum-1;
337 if (!client->netconnection)
340 VM_VarString(1, string, sizeof(string));
341 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
342 MSG_WriteString(&client->netconnection->message, string);
349 particle(origin, color, count)
352 static void VM_SV_particle (void)
358 VM_SAFEPARMCOUNT(4, VM_SV_particle);
360 org = PRVM_G_VECTOR(OFS_PARM0);
361 dir = PRVM_G_VECTOR(OFS_PARM1);
362 color = PRVM_G_FLOAT(OFS_PARM2);
363 count = PRVM_G_FLOAT(OFS_PARM3);
364 SV_StartParticle (org, dir, (int)color, (int)count);
374 static void VM_SV_ambientsound (void)
378 float vol, attenuation;
381 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
383 pos = PRVM_G_VECTOR (OFS_PARM0);
384 samp = PRVM_G_STRING(OFS_PARM1);
385 vol = PRVM_G_FLOAT(OFS_PARM2);
386 attenuation = PRVM_G_FLOAT(OFS_PARM3);
388 // check to see if samp was properly precached
389 soundnum = SV_SoundIndex(samp, 1);
397 // add an svc_spawnambient command to the level signon packet
400 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
402 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
404 MSG_WriteVector(&sv.signon, pos, sv.protocol);
407 MSG_WriteShort (&sv.signon, soundnum);
409 MSG_WriteByte (&sv.signon, soundnum);
411 MSG_WriteByte (&sv.signon, (int)(vol*255));
412 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
420 Each entity can have eight independant sound sources, like voice,
423 Channel 0 is an auto-allocate channel, the others override anything
424 already running on that entity/channel pair.
426 An attenuation of 0 will play full volume everywhere in the level.
427 Larger attenuations will drop off.
431 static void VM_SV_sound (void)
435 prvm_edict_t *entity;
439 VM_SAFEPARMCOUNT(5, VM_SV_sound);
441 entity = PRVM_G_EDICT(OFS_PARM0);
442 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
443 sample = PRVM_G_STRING(OFS_PARM2);
444 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
445 attenuation = PRVM_G_FLOAT(OFS_PARM4);
447 if (volume < 0 || volume > 255)
449 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
453 if (attenuation < 0 || attenuation > 4)
455 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
459 if (channel < 0 || channel > 7)
461 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
465 SV_StartSound (entity, channel, sample, volume, attenuation);
472 Used for use tracing and shot targeting
473 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
474 if the tryents flag is set.
476 traceline (vector1, vector2, movetype, ignore)
479 static void VM_SV_traceline (void)
486 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
488 prog->xfunction->builtinsprofile += 30;
490 v1 = PRVM_G_VECTOR(OFS_PARM0);
491 v2 = PRVM_G_VECTOR(OFS_PARM1);
492 move = (int)PRVM_G_FLOAT(OFS_PARM2);
493 ent = PRVM_G_EDICT(OFS_PARM3);
495 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]))
496 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));
498 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
500 VM_SetTraceGlobals(&trace);
508 Used for use tracing and shot targeting
509 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
510 if the tryents flag is set.
512 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
515 // LordHavoc: added this for my own use, VERY useful, similar to traceline
516 static void VM_SV_tracebox (void)
518 float *v1, *v2, *m1, *m2;
523 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
525 prog->xfunction->builtinsprofile += 30;
527 v1 = PRVM_G_VECTOR(OFS_PARM0);
528 m1 = PRVM_G_VECTOR(OFS_PARM1);
529 m2 = PRVM_G_VECTOR(OFS_PARM2);
530 v2 = PRVM_G_VECTOR(OFS_PARM3);
531 move = (int)PRVM_G_FLOAT(OFS_PARM4);
532 ent = PRVM_G_EDICT(OFS_PARM5);
534 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]))
535 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));
537 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
539 VM_SetTraceGlobals(&trace);
542 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
547 vec3_t original_origin;
548 vec3_t original_velocity;
549 vec3_t original_angles;
550 vec3_t original_avelocity;
554 VectorCopy(tossent->fields.server->origin , original_origin );
555 VectorCopy(tossent->fields.server->velocity , original_velocity );
556 VectorCopy(tossent->fields.server->angles , original_angles );
557 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
559 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
560 if (val != NULL && val->_float != 0)
561 gravity = val->_float;
564 gravity *= sv_gravity.value * 0.05;
566 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
568 SV_CheckVelocity (tossent);
569 tossent->fields.server->velocity[2] -= gravity;
570 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
571 VectorScale (tossent->fields.server->velocity, 0.05, move);
572 VectorAdd (tossent->fields.server->origin, move, end);
573 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
574 VectorCopy (trace.endpos, tossent->fields.server->origin);
576 if (trace.fraction < 1)
580 VectorCopy(original_origin , tossent->fields.server->origin );
581 VectorCopy(original_velocity , tossent->fields.server->velocity );
582 VectorCopy(original_angles , tossent->fields.server->angles );
583 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
588 static void VM_SV_tracetoss (void)
592 prvm_edict_t *ignore;
594 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
596 prog->xfunction->builtinsprofile += 600;
598 ent = PRVM_G_EDICT(OFS_PARM0);
599 if (ent == prog->edicts)
601 VM_Warning("tracetoss: can not use world entity\n");
604 ignore = PRVM_G_EDICT(OFS_PARM1);
606 trace = SV_Trace_Toss (ent, ignore);
608 VM_SetTraceGlobals(&trace);
611 //============================================================================
613 static int checkpvsbytes;
614 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
616 static int VM_SV_newcheckclient (int check)
622 // cycle to the next one
624 check = bound(1, check, svs.maxclients);
625 if (check == svs.maxclients)
633 prog->xfunction->builtinsprofile++;
635 if (i == svs.maxclients+1)
637 // look up the client's edict
638 ent = PRVM_EDICT_NUM(i);
639 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
640 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
642 // found a valid client (possibly the same one again)
646 // get the PVS for the entity
647 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
649 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
650 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
659 Returns a client (or object that has a client enemy) that would be a
662 If there is more than one valid option, they are cycled each frame
664 If (self.origin + self.viewofs) is not in the PVS of the current target,
665 it is not returned at all.
670 int c_invis, c_notvis;
671 static void VM_SV_checkclient (void)
673 prvm_edict_t *ent, *self;
676 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
678 // find a new check if on a new frame
679 if (sv.time - sv.lastchecktime >= 0.1)
681 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
682 sv.lastchecktime = sv.time;
685 // return check if it might be visible
686 ent = PRVM_EDICT_NUM(sv.lastcheck);
687 if (ent->priv.server->free || ent->fields.server->health <= 0)
689 VM_RETURN_EDICT(prog->edicts);
693 // if current entity can't possibly see the check entity, return 0
694 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
695 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
696 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
699 VM_RETURN_EDICT(prog->edicts);
703 // might be able to see it
705 VM_RETURN_EDICT(ent);
708 //============================================================================
715 Sends text over to the client's execution buffer
717 stuffcmd (clientent, value, ...)
720 static void VM_SV_stuffcmd (void)
724 char string[VM_STRINGTEMP_LENGTH];
726 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
728 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
729 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
731 VM_Warning("Can't stuffcmd to a non-client\n");
735 VM_VarString(1, string, sizeof(string));
738 host_client = svs.clients + entnum-1;
739 Host_ClientCommands ("%s", string);
747 Returns a chain of entities that have origins within a spherical area
749 findradius (origin, radius)
752 static void VM_SV_findradius (void)
754 prvm_edict_t *ent, *chain;
755 vec_t radius, radius2;
756 vec3_t org, eorg, mins, maxs;
759 prvm_edict_t *touchedicts[MAX_EDICTS];
761 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
763 chain = (prvm_edict_t *)prog->edicts;
765 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
766 radius = PRVM_G_FLOAT(OFS_PARM1);
767 radius2 = radius * radius;
769 mins[0] = org[0] - (radius + 1);
770 mins[1] = org[1] - (radius + 1);
771 mins[2] = org[2] - (radius + 1);
772 maxs[0] = org[0] + (radius + 1);
773 maxs[1] = org[1] + (radius + 1);
774 maxs[2] = org[2] + (radius + 1);
775 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
776 if (numtouchedicts > MAX_EDICTS)
778 // this never happens
779 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
780 numtouchedicts = MAX_EDICTS;
782 for (i = 0;i < numtouchedicts;i++)
784 ent = touchedicts[i];
785 prog->xfunction->builtinsprofile++;
786 // Quake did not return non-solid entities but darkplaces does
787 // (note: this is the reason you can't blow up fallen zombies)
788 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
790 // LordHavoc: compare against bounding box rather than center so it
791 // doesn't miss large objects, and use DotProduct instead of Length
792 // for a major speedup
793 VectorSubtract(org, ent->fields.server->origin, eorg);
794 if (sv_gameplayfix_findradiusdistancetobox.integer)
796 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
797 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
798 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
801 VectorMAMAM(1, eorg, 0.5f, ent->fields.server->mins, 0.5f, ent->fields.server->maxs, eorg);
802 if (DotProduct(eorg, eorg) < radius2)
804 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
809 VM_RETURN_EDICT(chain);
812 static void VM_SV_precache_sound (void)
814 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
815 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
816 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
819 static void VM_SV_precache_model (void)
821 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
822 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
823 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
830 float(float yaw, float dist[, settrace]) walkmove
833 static void VM_SV_walkmove (void)
842 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
844 // assume failure if it returns early
845 PRVM_G_FLOAT(OFS_RETURN) = 0;
847 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
848 if (ent == prog->edicts)
850 VM_Warning("walkmove: can not modify world entity\n");
853 if (ent->priv.server->free)
855 VM_Warning("walkmove: can not modify free entity\n");
858 yaw = PRVM_G_FLOAT(OFS_PARM0);
859 dist = PRVM_G_FLOAT(OFS_PARM1);
860 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
862 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
865 yaw = yaw*M_PI*2 / 360;
867 move[0] = cos(yaw)*dist;
868 move[1] = sin(yaw)*dist;
871 // save program state, because SV_movestep may call other progs
872 oldf = prog->xfunction;
873 oldself = prog->globals.server->self;
875 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
878 // restore program state
879 prog->xfunction = oldf;
880 prog->globals.server->self = oldself;
890 static void VM_SV_droptofloor (void)
896 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
898 // assume failure if it returns early
899 PRVM_G_FLOAT(OFS_RETURN) = 0;
901 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
902 if (ent == prog->edicts)
904 VM_Warning("droptofloor: can not modify world entity\n");
907 if (ent->priv.server->free)
909 VM_Warning("droptofloor: can not modify free entity\n");
913 VectorCopy (ent->fields.server->origin, end);
916 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
918 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
920 if (trace.fraction < 1)
921 VectorCopy (trace.endpos, ent->fields.server->origin);
922 SV_LinkEdict (ent, false);
923 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
924 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
925 PRVM_G_FLOAT(OFS_RETURN) = 1;
926 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
927 ent->priv.server->suspendedinairflag = true;
935 void(float style, string value) lightstyle
938 static void VM_SV_lightstyle (void)
945 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
947 style = (int)PRVM_G_FLOAT(OFS_PARM0);
948 val = PRVM_G_STRING(OFS_PARM1);
950 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
951 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
954 // change the string in sv
955 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
957 // send message to all clients on this server
958 if (sv.state != ss_active)
961 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
963 if (client->active && client->netconnection)
965 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
966 MSG_WriteChar (&client->netconnection->message,style);
967 MSG_WriteString (&client->netconnection->message, val);
977 static void VM_SV_checkbottom (void)
979 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
980 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
988 static void VM_SV_pointcontents (void)
990 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
991 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
998 Pick a vector for the player to shoot along
999 vector aim(entity, missilespeed)
1002 static void VM_SV_aim (void)
1004 prvm_edict_t *ent, *check, *bestent;
1005 vec3_t start, dir, end, bestdir;
1008 float dist, bestdist;
1011 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1013 // assume failure if it returns early
1014 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1015 // if sv_aim is so high it can't possibly accept anything, skip out early
1016 if (sv_aim.value >= 1)
1019 ent = PRVM_G_EDICT(OFS_PARM0);
1020 if (ent == prog->edicts)
1022 VM_Warning("aim: can not use world entity\n");
1025 if (ent->priv.server->free)
1027 VM_Warning("aim: can not use free entity\n");
1030 speed = PRVM_G_FLOAT(OFS_PARM1);
1032 VectorCopy (ent->fields.server->origin, start);
1035 // try sending a trace straight
1036 VectorCopy (prog->globals.server->v_forward, dir);
1037 VectorMA (start, 2048, dir, end);
1038 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1039 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1040 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1042 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1047 // try all possible entities
1048 VectorCopy (dir, bestdir);
1049 bestdist = sv_aim.value;
1052 check = PRVM_NEXT_EDICT(prog->edicts);
1053 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1055 prog->xfunction->builtinsprofile++;
1056 if (check->fields.server->takedamage != DAMAGE_AIM)
1060 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1061 continue; // don't aim at teammate
1062 for (j=0 ; j<3 ; j++)
1063 end[j] = check->fields.server->origin[j]
1064 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1065 VectorSubtract (end, start, dir);
1066 VectorNormalize (dir);
1067 dist = DotProduct (dir, prog->globals.server->v_forward);
1068 if (dist < bestdist)
1069 continue; // to far to turn
1070 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1071 if (tr.ent == check)
1072 { // can shoot at this one
1080 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1081 dist = DotProduct (dir, prog->globals.server->v_forward);
1082 VectorScale (prog->globals.server->v_forward, dist, end);
1084 VectorNormalize (end);
1085 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1089 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1094 ===============================================================================
1098 ===============================================================================
1101 #define MSG_BROADCAST 0 // unreliable to all
1102 #define MSG_ONE 1 // reliable to one (msg_entity)
1103 #define MSG_ALL 2 // reliable to all
1104 #define MSG_INIT 3 // write to the init string
1105 #define MSG_ENTITY 5
1107 sizebuf_t *WriteDest (void)
1112 extern sizebuf_t *sv2csqcbuf;
1114 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1118 return &sv.datagram;
1121 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1122 entnum = PRVM_NUM_FOR_EDICT(ent);
1123 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1125 VM_Warning ("WriteDest: tried to write to non-client\n");
1126 return &sv.reliable_datagram;
1129 return &svs.clients[entnum-1].netconnection->message;
1132 VM_Warning ("WriteDest: bad destination\n");
1134 return &sv.reliable_datagram;
1146 static void VM_SV_WriteByte (void)
1148 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1149 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1152 static void VM_SV_WriteChar (void)
1154 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1155 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1158 static void VM_SV_WriteShort (void)
1160 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1161 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1164 static void VM_SV_WriteLong (void)
1166 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1167 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1170 static void VM_SV_WriteAngle (void)
1172 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1173 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1176 static void VM_SV_WriteCoord (void)
1178 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1179 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1182 static void VM_SV_WriteString (void)
1184 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1185 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1188 static void VM_SV_WriteUnterminatedString (void)
1190 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1191 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1195 static void VM_SV_WriteEntity (void)
1197 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1198 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1201 //////////////////////////////////////////////////////////
1203 static void VM_SV_makestatic (void)
1208 // allow 0 parameters due to an id1 qc bug in which this function is used
1209 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1210 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1212 if (prog->argc >= 1)
1213 ent = PRVM_G_EDICT(OFS_PARM0);
1215 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1216 if (ent == prog->edicts)
1218 VM_Warning("makestatic: can not modify world entity\n");
1221 if (ent->priv.server->free)
1223 VM_Warning("makestatic: can not modify free entity\n");
1228 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1233 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1234 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1235 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1239 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1240 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1241 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1244 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1245 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1246 for (i=0 ; i<3 ; i++)
1248 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1249 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1252 // throw the entity away now
1256 //=============================================================================
1263 static void VM_SV_setspawnparms (void)
1269 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1271 ent = PRVM_G_EDICT(OFS_PARM0);
1272 i = PRVM_NUM_FOR_EDICT(ent);
1273 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1275 Con_Print("tried to setspawnparms on a non-client\n");
1279 // copy spawn parms out of the client_t
1280 client = svs.clients + i-1;
1281 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1282 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1289 Returns a color vector indicating the lighting at the requested point.
1291 (Internal Operation note: actually measures the light beneath the point, just like
1292 the model lighting on the client)
1297 static void VM_SV_getlight (void)
1299 vec3_t ambientcolor, diffusecolor, diffusenormal;
1301 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1302 p = PRVM_G_VECTOR(OFS_PARM0);
1303 VectorClear(ambientcolor);
1304 VectorClear(diffusecolor);
1305 VectorClear(diffusenormal);
1306 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1307 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1308 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1313 unsigned char type; // 1/2/8 or other value if isn't used
1317 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1318 static int vm_customstats_last;
1320 void VM_CustomStats_Clear (void)
1324 Z_Free(vm_customstats);
1325 vm_customstats = NULL;
1326 vm_customstats_last = -1;
1330 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1338 for(i=0; i<vm_customstats_last+1 ;i++)
1340 if(!vm_customstats[i].type)
1342 switch(vm_customstats[i].type)
1344 //string as 16 bytes
1347 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1348 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1349 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1350 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1351 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1353 //float field sent as-is
1355 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1357 //integer value of float field
1359 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1367 // void(float index, float type, .void field) SV_AddStat = #232;
1368 // Set up an auto-sent player stat.
1369 // Client's get thier own fields sent to them. Index may not be less than 32.
1370 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1371 // 1: string (4 stats carrying a total of 16 charactures)
1372 // 2: float (one stat, float converted to an integer for transportation)
1373 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1374 static void VM_SV_AddStat (void)
1379 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1383 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1386 VM_Warning("PF_SV_AddStat: not enough memory\n");
1390 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1391 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1392 off = PRVM_G_INT (OFS_PARM2);
1397 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1400 if(i >= (MAX_CL_STATS-32))
1402 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1405 if(i > (MAX_CL_STATS-32-4) && type == 1)
1407 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1410 vm_customstats[i].type = type;
1411 vm_customstats[i].fieldoffset = off;
1412 if(vm_customstats_last < i)
1413 vm_customstats_last = i;
1420 copies data from one entity to another
1422 copyentity(src, dst)
1425 static void VM_SV_copyentity (void)
1427 prvm_edict_t *in, *out;
1428 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1429 in = PRVM_G_EDICT(OFS_PARM0);
1430 if (in == prog->edicts)
1432 VM_Warning("copyentity: can not read world entity\n");
1435 if (in->priv.server->free)
1437 VM_Warning("copyentity: can not read free entity\n");
1440 out = PRVM_G_EDICT(OFS_PARM1);
1441 if (out == prog->edicts)
1443 VM_Warning("copyentity: can not modify world entity\n");
1446 if (out->priv.server->free)
1448 VM_Warning("copyentity: can not modify free entity\n");
1451 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1452 SV_LinkEdict(out, false);
1460 sets the color of a client and broadcasts the update to all connected clients
1462 setcolor(clientent, value)
1465 static void VM_SV_setcolor (void)
1471 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1472 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1473 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1475 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1477 Con_Print("tried to setcolor a non-client\n");
1481 client = svs.clients + entnum-1;
1484 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1486 client->edict->fields.server->team = (i & 15) + 1;
1489 if (client->old_colors != client->colors)
1491 client->old_colors = client->colors;
1492 // send notification to all clients
1493 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1494 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1495 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1503 effect(origin, modelname, startframe, framecount, framerate)
1506 static void VM_SV_effect (void)
1510 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1511 s = PRVM_G_STRING(OFS_PARM1);
1514 VM_Warning("effect: no model specified\n");
1518 i = SV_ModelIndex(s, 1);
1521 VM_Warning("effect: model not precached\n");
1525 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1527 VM_Warning("effect: framecount < 1\n");
1531 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1533 VM_Warning("effect: framerate < 1\n");
1537 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));
1540 static void VM_SV_te_blood (void)
1542 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1543 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1545 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1546 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1548 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1549 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1550 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1552 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1553 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1554 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1556 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1557 SV_FlushBroadcastMessages();
1560 static void VM_SV_te_bloodshower (void)
1562 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1563 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1565 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1566 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1568 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1569 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1570 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1572 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1573 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1574 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1576 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1578 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1579 SV_FlushBroadcastMessages();
1582 static void VM_SV_te_explosionrgb (void)
1584 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1585 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1586 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1588 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1589 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1590 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1592 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1593 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1594 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1595 SV_FlushBroadcastMessages();
1598 static void VM_SV_te_particlecube (void)
1600 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1601 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1603 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1604 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1606 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1607 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1608 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1610 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1611 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1612 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1614 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1615 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1616 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1618 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1620 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1621 // gravity true/false
1622 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1624 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1625 SV_FlushBroadcastMessages();
1628 static void VM_SV_te_particlerain (void)
1630 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1631 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1633 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1634 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1636 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1637 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1638 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1640 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1641 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1642 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1644 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1645 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1646 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1648 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1650 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1651 SV_FlushBroadcastMessages();
1654 static void VM_SV_te_particlesnow (void)
1656 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1657 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1659 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1660 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1662 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1663 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1664 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1666 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1667 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1668 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1671 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1672 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1674 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1676 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1677 SV_FlushBroadcastMessages();
1680 static void VM_SV_te_spark (void)
1682 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1683 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1685 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1686 MSG_WriteByte(&sv.datagram, TE_SPARK);
1688 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1689 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1690 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1692 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1693 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1694 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1696 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1697 SV_FlushBroadcastMessages();
1700 static void VM_SV_te_gunshotquad (void)
1702 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1703 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1704 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1706 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1707 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1708 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1709 SV_FlushBroadcastMessages();
1712 static void VM_SV_te_spikequad (void)
1714 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1715 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1716 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1718 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1719 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1720 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1721 SV_FlushBroadcastMessages();
1724 static void VM_SV_te_superspikequad (void)
1726 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1727 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1728 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1730 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1731 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1732 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1733 SV_FlushBroadcastMessages();
1736 static void VM_SV_te_explosionquad (void)
1738 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1739 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1740 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1742 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1743 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1744 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1745 SV_FlushBroadcastMessages();
1748 static void VM_SV_te_smallflash (void)
1750 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1751 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1752 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1754 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1755 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1756 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1757 SV_FlushBroadcastMessages();
1760 static void VM_SV_te_customflash (void)
1762 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1763 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1765 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1766 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1768 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1769 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1770 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1772 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1774 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1776 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1777 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1778 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1779 SV_FlushBroadcastMessages();
1782 static void VM_SV_te_gunshot (void)
1784 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1785 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1786 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1788 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1790 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1791 SV_FlushBroadcastMessages();
1794 static void VM_SV_te_spike (void)
1796 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1797 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1798 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1800 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1801 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1802 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1803 SV_FlushBroadcastMessages();
1806 static void VM_SV_te_superspike (void)
1808 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1809 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1810 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1812 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1814 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1815 SV_FlushBroadcastMessages();
1818 static void VM_SV_te_explosion (void)
1820 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1821 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1822 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1824 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1825 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1826 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1827 SV_FlushBroadcastMessages();
1830 static void VM_SV_te_tarexplosion (void)
1832 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1833 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1834 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1836 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1837 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1838 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1839 SV_FlushBroadcastMessages();
1842 static void VM_SV_te_wizspike (void)
1844 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1845 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1846 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1848 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1849 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1850 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1851 SV_FlushBroadcastMessages();
1854 static void VM_SV_te_knightspike (void)
1856 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1857 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1858 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1860 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1861 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1862 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1863 SV_FlushBroadcastMessages();
1866 static void VM_SV_te_lavasplash (void)
1868 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1869 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1870 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1872 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1873 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1874 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1875 SV_FlushBroadcastMessages();
1878 static void VM_SV_te_teleport (void)
1880 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1881 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1882 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1884 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1885 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1886 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1887 SV_FlushBroadcastMessages();
1890 static void VM_SV_te_explosion2 (void)
1892 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1893 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1894 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1896 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1897 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1898 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1900 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1901 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1902 SV_FlushBroadcastMessages();
1905 static void VM_SV_te_lightning1 (void)
1907 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1908 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1909 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1911 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1913 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1914 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1915 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1917 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1918 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1919 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1920 SV_FlushBroadcastMessages();
1923 static void VM_SV_te_lightning2 (void)
1925 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1926 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1927 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1929 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1931 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1933 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1935 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1936 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1937 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1938 SV_FlushBroadcastMessages();
1941 static void VM_SV_te_lightning3 (void)
1943 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1944 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1945 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1947 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1949 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1950 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1951 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1953 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1954 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1955 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1956 SV_FlushBroadcastMessages();
1959 static void VM_SV_te_beam (void)
1961 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1962 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1963 MSG_WriteByte(&sv.datagram, TE_BEAM);
1965 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1967 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1968 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1969 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1974 SV_FlushBroadcastMessages();
1977 static void VM_SV_te_plasmaburn (void)
1979 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
1980 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1981 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
1982 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1983 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1984 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1985 SV_FlushBroadcastMessages();
1988 static void VM_SV_te_flamejet (void)
1990 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
1991 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1992 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
1994 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1996 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1998 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1999 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2000 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2002 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2003 SV_FlushBroadcastMessages();
2006 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2009 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2011 bestdist = 1000000000;
2013 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2015 // clip original point to each triangle of the surface and find the
2016 // triangle that is closest
2017 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2018 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2019 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2020 TriangleNormal(v[0], v[1], v[2], facenormal);
2021 VectorNormalize(facenormal);
2022 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2023 VectorMA(p, offsetdist, facenormal, temp);
2024 for (j = 0, k = 2;j < 3;k = j, j++)
2026 VectorSubtract(v[k], v[j], edgenormal);
2027 CrossProduct(edgenormal, facenormal, sidenormal);
2028 VectorNormalize(sidenormal);
2029 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2031 VectorMA(temp, offsetdist, sidenormal, temp);
2033 dist = VectorDistance2(temp, p);
2034 if (bestdist > dist)
2037 VectorCopy(temp, out);
2042 static model_t *getmodel(prvm_edict_t *ed)
2045 if (!ed || ed->priv.server->free)
2047 modelindex = (int)ed->fields.server->modelindex;
2048 if (modelindex < 1 || modelindex >= MAX_MODELS)
2050 return sv.models[modelindex];
2053 static msurface_t *getsurface(model_t *model, int surfacenum)
2055 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2057 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2061 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2062 static void VM_SV_getsurfacenumpoints(void)
2065 msurface_t *surface;
2066 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2067 // return 0 if no such surface
2068 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2070 PRVM_G_FLOAT(OFS_RETURN) = 0;
2074 // note: this (incorrectly) assumes it is a simple polygon
2075 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2077 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2078 static void VM_SV_getsurfacepoint(void)
2082 msurface_t *surface;
2084 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2085 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2086 ed = PRVM_G_EDICT(OFS_PARM0);
2087 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2089 // note: this (incorrectly) assumes it is a simple polygon
2090 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2091 if (pointnum < 0 || pointnum >= surface->num_vertices)
2093 // FIXME: implement rotation/scaling
2094 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2096 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2097 static void VM_SV_getsurfacenormal(void)
2100 msurface_t *surface;
2102 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2103 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2104 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2106 // FIXME: implement rotation/scaling
2107 // note: this (incorrectly) assumes it is a simple polygon
2108 // note: this only returns the first triangle, so it doesn't work very
2109 // well for curved surfaces or arbitrary meshes
2110 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);
2111 VectorNormalize(normal);
2112 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2114 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2115 static void VM_SV_getsurfacetexture(void)
2118 msurface_t *surface;
2119 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2120 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2121 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2123 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2125 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2126 static void VM_SV_getsurfacenearpoint(void)
2128 int surfacenum, best;
2130 vec_t dist, bestdist;
2133 msurface_t *surface;
2135 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2136 PRVM_G_FLOAT(OFS_RETURN) = -1;
2137 ed = PRVM_G_EDICT(OFS_PARM0);
2138 point = PRVM_G_VECTOR(OFS_PARM1);
2140 if (!ed || ed->priv.server->free)
2142 model = getmodel(ed);
2143 if (!model || !model->num_surfaces)
2146 // FIXME: implement rotation/scaling
2147 VectorSubtract(point, ed->fields.server->origin, p);
2149 bestdist = 1000000000;
2150 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2152 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2153 // first see if the nearest point on the surface's box is closer than the previous match
2154 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2155 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2156 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2157 dist = VectorLength2(clipped);
2158 if (dist < bestdist)
2160 // it is, check the nearest point on the actual geometry
2161 clippointtosurface(model, surface, p, clipped);
2162 VectorSubtract(clipped, p, clipped);
2163 dist += VectorLength2(clipped);
2164 if (dist < bestdist)
2166 // that's closer too, store it as the best match
2172 PRVM_G_FLOAT(OFS_RETURN) = best;
2174 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2175 static void VM_SV_getsurfaceclippedpoint(void)
2179 msurface_t *surface;
2181 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2182 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2183 ed = PRVM_G_EDICT(OFS_PARM0);
2184 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2186 // FIXME: implement rotation/scaling
2187 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2188 clippointtosurface(model, surface, p, out);
2189 // FIXME: implement rotation/scaling
2190 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2193 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2194 //this function originally written by KrimZon, made shorter by LordHavoc
2195 static void VM_SV_clientcommand (void)
2197 client_t *temp_client;
2199 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2201 //find client for this entity
2202 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2203 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2205 Con_Print("PF_clientcommand: entity is not a client\n");
2209 temp_client = host_client;
2210 host_client = svs.clients + i;
2211 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2212 host_client = temp_client;
2215 //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)
2216 static void VM_SV_setattachment (void)
2218 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2219 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2220 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2224 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2226 if (e == prog->edicts)
2228 VM_Warning("setattachment: can not modify world entity\n");
2231 if (e->priv.server->free)
2233 VM_Warning("setattachment: can not modify free entity\n");
2237 if (tagentity == NULL)
2238 tagentity = prog->edicts;
2240 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2242 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2244 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2247 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2249 modelindex = (int)tagentity->fields.server->modelindex;
2250 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2252 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2254 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);
2257 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));
2261 /////////////////////////////////////////
2262 // DP_MD3_TAGINFO extension coded by VorteX
2264 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2269 i = (int)e->fields.server->modelindex;
2270 if (i < 1 || i >= MAX_MODELS)
2272 model = sv.models[i];
2274 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2277 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2279 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2283 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);
2285 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);
2288 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2294 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2295 && (model = sv.models[(int)ent->fields.server->modelindex])
2296 && model->animscenes)
2298 // if model has wrong frame, engine automatically switches to model first frame
2299 frame = (int)ent->fields.server->frame;
2300 if (frame < 0 || frame >= model->numframes)
2302 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2304 *out = identitymatrix;
2308 // Warnings/errors code:
2309 // 0 - normal (everything all-right)
2312 // 3 - null or non-precached model
2313 // 4 - no tags with requested index
2314 // 5 - runaway loop at attachment chain
2315 extern cvar_t cl_bob;
2316 extern cvar_t cl_bobcycle;
2317 extern cvar_t cl_bobup;
2318 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2322 int modelindex, attachloop;
2323 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2326 *out = identitymatrix; // warnings and errors return identical matrix
2328 if (ent == prog->edicts)
2330 if (ent->priv.server->free)
2333 modelindex = (int)ent->fields.server->modelindex;
2334 if (modelindex <= 0 || modelindex > MAX_MODELS)
2337 model = sv.models[modelindex];
2339 tagmatrix = identitymatrix;
2340 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2344 if (attachloop >= 256) // prevent runaway looping
2346 // apply transformation by child's tagindex on parent entity and then
2347 // by parent entity itself
2348 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2349 if (ret && attachloop == 0)
2351 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2352 SV_GetEntityMatrix(ent, &entitymatrix, false);
2353 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2354 // next iteration we process the parent entity
2355 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2357 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2358 ent = PRVM_EDICT_NUM(val->edict);
2365 // RENDER_VIEWMODEL magic
2366 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2368 Matrix4x4_Copy(&tagmatrix, out);
2369 ent = PRVM_EDICT_NUM(val->edict);
2371 SV_GetEntityMatrix(ent, &entitymatrix, true);
2372 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2375 // Cl_bob, ported from rendering code
2376 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2379 // LordHavoc: this code is *weird*, but not replacable (I think it
2380 // should be done in QC on the server, but oh well, quake is quake)
2381 // LordHavoc: figured out bobup: the time at which the sin is at 180
2382 // degrees (which allows lengthening or squishing the peak or valley)
2383 cycle = sv.time/cl_bobcycle.value;
2384 cycle -= (int)cycle;
2385 if (cycle < cl_bobup.value)
2386 cycle = sin(M_PI * cycle / cl_bobup.value);
2388 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2389 // bob is proportional to velocity in the xy plane
2390 // (don't count Z, or jumping messes it up)
2391 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;
2392 bob = bob*0.3 + bob*0.7*cycle;
2393 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2400 //float(entity ent, string tagname) gettagindex;
2402 static void VM_SV_gettagindex (void)
2405 const char *tag_name;
2406 int modelindex, tag_index;
2408 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2410 ent = PRVM_G_EDICT(OFS_PARM0);
2411 tag_name = PRVM_G_STRING(OFS_PARM1);
2413 if (ent == prog->edicts)
2415 VM_Warning("gettagindex: can't affect world entity\n");
2418 if (ent->priv.server->free)
2420 VM_Warning("gettagindex: can't affect free entity\n");
2424 modelindex = (int)ent->fields.server->modelindex;
2426 if (modelindex <= 0 || modelindex > MAX_MODELS)
2427 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2430 tag_index = SV_GetTagIndex(ent, tag_name);
2432 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2434 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2437 //vector(entity ent, float tagindex) gettaginfo;
2438 static void VM_SV_gettaginfo (void)
2442 matrix4x4_t tag_matrix;
2445 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2447 e = PRVM_G_EDICT(OFS_PARM0);
2448 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2450 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2451 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2456 VM_Warning("gettagindex: can't affect world entity\n");
2459 VM_Warning("gettagindex: can't affect free entity\n");
2462 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2465 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2468 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2473 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2474 static void VM_SV_dropclient (void)
2477 client_t *oldhostclient;
2478 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2479 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2480 if (clientnum < 0 || clientnum >= svs.maxclients)
2482 VM_Warning("dropclient: not a client\n");
2485 if (!svs.clients[clientnum].active)
2487 VM_Warning("dropclient: that client slot is not connected\n");
2490 oldhostclient = host_client;
2491 host_client = svs.clients + clientnum;
2492 SV_DropClient(false);
2493 host_client = oldhostclient;
2496 //entity() spawnclient (DP_SV_BOTCLIENT)
2497 static void VM_SV_spawnclient (void)
2501 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2502 prog->xfunction->builtinsprofile += 2;
2504 for (i = 0;i < svs.maxclients;i++)
2506 if (!svs.clients[i].active)
2508 prog->xfunction->builtinsprofile += 100;
2509 SV_ConnectClient (i, NULL);
2510 // this has to be set or else ClientDisconnect won't be called
2511 // we assume the qc will call ClientConnect...
2512 svs.clients[i].clientconnectcalled = true;
2513 ed = PRVM_EDICT_NUM(i + 1);
2517 VM_RETURN_EDICT(ed);
2520 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2521 static void VM_SV_clienttype (void)
2524 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2525 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2526 if (clientnum < 0 || clientnum >= svs.maxclients)
2527 PRVM_G_FLOAT(OFS_RETURN) = 3;
2528 else if (!svs.clients[clientnum].active)
2529 PRVM_G_FLOAT(OFS_RETURN) = 0;
2530 else if (svs.clients[clientnum].netconnection)
2531 PRVM_G_FLOAT(OFS_RETURN) = 1;
2533 PRVM_G_FLOAT(OFS_RETURN) = 2;
2540 string(string key) serverkey
2543 void VM_SV_serverkey(void)
2545 char string[VM_STRINGTEMP_LENGTH];
2546 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2547 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2548 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2551 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2552 static void VM_SV_setmodelindex (void)
2557 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2559 e = PRVM_G_EDICT(OFS_PARM0);
2560 if (e == prog->edicts)
2562 VM_Warning("setmodelindex: can not modify world entity\n");
2565 if (e->priv.server->free)
2567 VM_Warning("setmodelindex: can not modify free entity\n");
2570 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2571 if (i <= 0 || i > MAX_MODELS)
2573 VM_Warning("setmodelindex: invalid modelindex\n");
2576 if (!sv.model_precache[i][0])
2578 VM_Warning("setmodelindex: model not precached\n");
2582 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2583 e->fields.server->modelindex = i;
2589 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2590 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2592 SetMinMaxSize (e, quakemins, quakemaxs, true);
2595 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2598 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2599 static void VM_SV_modelnameforindex (void)
2602 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2604 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2606 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2607 if (i <= 0 || i > MAX_MODELS)
2609 VM_Warning("modelnameforindex: invalid modelindex\n");
2612 if (!sv.model_precache[i][0])
2614 VM_Warning("modelnameforindex: model not precached\n");
2618 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2621 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2622 static void VM_SV_particleeffectnum (void)
2625 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2626 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2629 PRVM_G_FLOAT(OFS_RETURN) = i;
2632 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2633 static void VM_SV_trailparticles (void)
2635 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2637 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2638 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2639 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2640 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2641 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2642 SV_FlushBroadcastMessages();
2645 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2646 static void VM_SV_pointparticles (void)
2648 VM_SAFEPARMCOUNT(4, VM_SV_pointparticles);
2650 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2651 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM0));
2652 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1), sv.protocol);
2653 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2654 MSG_WriteShort(&sv.datagram, bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535));
2655 SV_FlushBroadcastMessages();
2658 prvm_builtin_t vm_sv_builtins[] = {
2659 NULL, // #0 NULL function (not callable) (QUAKE)
2660 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2661 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2662 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2663 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2664 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2665 VM_break, // #6 void() break (QUAKE)
2666 VM_random, // #7 float() random (QUAKE)
2667 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2668 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2669 VM_error, // #10 void(string e) error (QUAKE)
2670 VM_objerror, // #11 void(string e) objerror (QUAKE)
2671 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2672 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2673 VM_spawn, // #14 entity() spawn (QUAKE)
2674 VM_remove, // #15 void(entity e) remove (QUAKE)
2675 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2676 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2677 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2678 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2679 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2680 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2681 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2682 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2683 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2684 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2685 VM_ftos, // #26 string(float f) ftos (QUAKE)
2686 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2687 VM_coredump, // #28 void() coredump (QUAKE)
2688 VM_traceon, // #29 void() traceon (QUAKE)
2689 VM_traceoff, // #30 void() traceoff (QUAKE)
2690 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2691 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2692 NULL, // #33 (QUAKE)
2693 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2694 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2695 VM_rint, // #36 float(float v) rint (QUAKE)
2696 VM_floor, // #37 float(float v) floor (QUAKE)
2697 VM_ceil, // #38 float(float v) ceil (QUAKE)
2698 NULL, // #39 (QUAKE)
2699 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2700 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2701 NULL, // #42 (QUAKE)
2702 VM_fabs, // #43 float(float f) fabs (QUAKE)
2703 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2704 VM_cvar, // #45 float(string s) cvar (QUAKE)
2705 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2706 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2707 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2708 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2709 NULL, // #50 (QUAKE)
2710 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2711 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2712 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2713 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2714 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2715 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2716 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2717 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2718 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2719 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2720 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2721 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2722 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2723 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2724 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2725 NULL, // #66 (QUAKE)
2726 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2727 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2728 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2729 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2730 NULL, // #71 (QUAKE)
2731 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2732 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2733 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2734 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2735 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2736 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2737 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2738 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2739 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2740 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2741 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2742 NULL, // #83 (QUAKE)
2743 NULL, // #84 (QUAKE)
2744 NULL, // #85 (QUAKE)
2745 NULL, // #86 (QUAKE)
2746 NULL, // #87 (QUAKE)
2747 NULL, // #88 (QUAKE)
2748 NULL, // #89 (QUAKE)
2749 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2750 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2751 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2752 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2753 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2754 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2755 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2756 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2757 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2758 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2759 // FrikaC and Telejano range #100-#199
2770 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2771 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2772 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2773 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2774 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2775 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2776 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2777 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2778 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2779 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2860 // FTEQW range #200-#299
2879 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2883 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2884 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2889 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2893 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2961 // CSQC range #300-#399
2962 NULL, // #300 void() clearscene (EXT_CSQC)
2963 NULL, // #301 void(float mask) addentities (EXT_CSQC)
2964 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
2965 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
2966 NULL, // #304 void() renderscene (EXT_CSQC)
2967 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2968 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2969 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2970 NULL, // #308 void() R_EndPolygon
2972 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
2973 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
2977 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
2978 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
2979 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
2980 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
2981 NULL, // #319 void(string name) freepic (EXT_CSQC)
2982 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
2983 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
2984 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
2985 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
2986 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
2987 NULL, // #325 void(void) drawresetcliparea
2992 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
2993 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
2994 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
2995 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2996 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2997 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
2998 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2999 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3000 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3001 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3002 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3003 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3004 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3005 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3006 NULL, // #344 vector() getmousepos (EXT_CSQC)
3007 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3008 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3009 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3010 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3011 NULL, // #349 float() isdemo (EXT_CSQC)
3012 VM_isserver, // #350 float() isserver (EXT_CSQC)
3013 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3014 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3015 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3016 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3022 NULL, // #360 float() readbyte (EXT_CSQC)
3023 NULL, // #361 float() readchar (EXT_CSQC)
3024 NULL, // #362 float() readshort (EXT_CSQC)
3025 NULL, // #363 float() readlong (EXT_CSQC)
3026 NULL, // #364 float() readcoord (EXT_CSQC)
3027 NULL, // #365 float() readangle (EXT_CSQC)
3028 NULL, // #366 string() readstring (EXT_CSQC)
3029 NULL, // #367 float() readfloat (EXT_CSQC)
3062 // LordHavoc's range #400-#499
3063 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3064 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3065 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3066 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3067 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3068 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3069 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3070 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3071 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)
3072 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3073 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3074 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3075 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3076 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3077 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3078 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3079 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3080 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3081 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3082 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3083 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3084 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3085 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3086 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3087 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3088 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3089 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3090 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3091 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3092 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3093 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3094 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3095 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3096 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3097 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3098 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3099 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3100 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3101 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3102 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3103 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3104 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3105 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3106 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3107 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
3108 VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
3109 VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
3110 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
3111 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3112 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3113 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3114 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3115 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3116 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3117 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3118 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3119 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3120 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3122 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3123 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3124 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3125 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3126 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3127 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3128 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3129 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3130 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3131 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3132 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3134 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3135 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3136 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3137 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3138 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3139 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3140 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3141 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3142 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3143 VM_strtolower, // #480 string(string s) VM_strtolower : DRESK - Return string as lowercase
3144 VM_strtoupper, // #481 string(string s) VM_strtoupper : DRESK - Return string as uppercase
3165 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3167 void VM_SV_Cmd_Init(void)
3172 void VM_SV_Cmd_Reset(void)