3 //============================================================================
8 char *vm_sv_extensions =
13 "DP_CON_ALIASPARAMETERS "
30 "DP_ENT_CUSTOMCOLORMAP "
31 "DP_ENT_EXTERIORMODELTOCLIENT "
33 "DP_ENT_LOWPRECISION "
36 "DP_GFX_EXTERNALTEXTURES "
37 "DP_GFX_EXTERNALTEXTURES_PERMAP "
39 "DP_GFX_QUAKE3MODELTAGS "
43 "DP_HALFLIFE_MAP_CVAR "
49 "DP_MOVETYPEBOUNCEMISSILE "
51 "DP_QC_ASINACOSATANATAN2TAN "
57 "DP_QC_FINDCHAINFLAGS "
58 "DP_QC_FINDCHAINFLOAT "
66 "DP_QC_MULTIPLETEMPSTRINGS "
68 "DP_QC_SINCOSSQRTPOW "
70 "DP_QC_STRING_CASE_FUNCTIONS "
71 "DP_QC_STRINGBUFFERS "
72 "DP_QC_STRINGCOLORFUNCTIONS "
73 "DP_QC_TOKENIZEBYSEPARATOR "
76 "DP_QC_TRACE_MOVETYPE_HITMODEL "
77 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
78 "DP_QC_UNLIMITEDTEMPSTRINGS "
79 "DP_QC_VECTORVECTORS "
85 "DP_SND_DIRECTIONLESSATTNNONE "
94 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
95 "DP_SV_DRAWONLYTOCLIENT "
98 "DP_SV_ENTITYCONTENTSTRANSITION "
99 "DP_SV_MODELFLAGS_AS_EFFECTS "
101 "DP_SV_NODRAWTOCLIENT "
103 "DP_SV_PLAYERPHYSICS "
104 "DP_SV_PRECACHEANYTIME "
107 "DP_SV_ROTATINGBMODEL "
110 "DP_SV_WRITEUNTERMINATEDSTRING "
114 "DP_TE_EXPLOSIONRGB "
116 "DP_TE_PARTICLECUBE "
117 "DP_TE_PARTICLERAIN "
118 "DP_TE_PARTICLESNOW "
120 "DP_TE_QUADEFFECTS1 "
123 "DP_TE_STANDARDEFFECTBUILTINS "
124 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
127 //"EXT_CSQC " // not ready yet
129 "KRIMZON_SV_PARSECLIENTCOMMAND "
132 "NEXUIZ_PLAYERMODEL "
134 "PRYDON_CLIENTCURSOR "
135 "TENEBRAE_GFX_DLIGHTS "
145 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.
147 setorigin (entity, origin)
150 static void VM_SV_setorigin (void)
155 VM_SAFEPARMCOUNT(2, VM_setorigin);
157 e = PRVM_G_EDICT(OFS_PARM0);
158 if (e == prog->edicts)
160 VM_Warning("setorigin: can not modify world entity\n");
163 if (e->priv.server->free)
165 VM_Warning("setorigin: can not modify free entity\n");
168 org = PRVM_G_VECTOR(OFS_PARM1);
169 VectorCopy (org, e->fields.server->origin);
170 SV_LinkEdict (e, false);
174 void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
178 for (i=0 ; i<3 ; i++)
180 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
182 // set derived values
183 VectorCopy (min, e->fields.server->mins);
184 VectorCopy (max, e->fields.server->maxs);
185 VectorSubtract (max, min, e->fields.server->size);
187 SV_LinkEdict (e, false);
194 the size box is rotated by the current angle
195 LordHavoc: no it isn't...
197 setsize (entity, minvector, maxvector)
200 static void VM_SV_setsize (void)
205 VM_SAFEPARMCOUNT(3, VM_setsize);
207 e = PRVM_G_EDICT(OFS_PARM0);
208 if (e == prog->edicts)
210 VM_Warning("setsize: can not modify world entity\n");
213 if (e->priv.server->free)
215 VM_Warning("setsize: can not modify free entity\n");
218 min = PRVM_G_VECTOR(OFS_PARM1);
219 max = PRVM_G_VECTOR(OFS_PARM2);
220 SetMinMaxSize (e, min, max, false);
228 setmodel(entity, model)
231 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
232 static void VM_SV_setmodel (void)
238 VM_SAFEPARMCOUNT(2, VM_setmodel);
240 e = PRVM_G_EDICT(OFS_PARM0);
241 if (e == prog->edicts)
243 VM_Warning("setmodel: can not modify world entity\n");
246 if (e->priv.server->free)
248 VM_Warning("setmodel: can not modify free entity\n");
251 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
252 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
253 e->fields.server->modelindex = i;
259 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
260 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
262 SetMinMaxSize (e, quakemins, quakemaxs, true);
265 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
272 single print to a specific client
274 sprint(clientent, value)
277 static void VM_SV_sprint (void)
281 char string[VM_STRINGTEMP_LENGTH];
283 VM_VarString(1, string, sizeof(string));
285 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
287 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
288 // LordHavoc: div0 requested that sprintto world operate like print
295 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
297 VM_Warning("tried to centerprint to a non-client\n");
301 client = svs.clients + entnum-1;
302 if (!client->netconnection)
305 MSG_WriteChar(&client->netconnection->message,svc_print);
306 MSG_WriteString(&client->netconnection->message, string);
314 single print to a specific client
316 centerprint(clientent, value)
319 static void VM_SV_centerprint (void)
323 char string[VM_STRINGTEMP_LENGTH];
325 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
327 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
329 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
331 VM_Warning("tried to centerprint to a non-client\n");
335 client = svs.clients + entnum-1;
336 if (!client->netconnection)
339 VM_VarString(1, string, sizeof(string));
340 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
341 MSG_WriteString(&client->netconnection->message, string);
348 particle(origin, color, count)
351 static void VM_SV_particle (void)
357 VM_SAFEPARMCOUNT(4, VM_SV_particle);
359 org = PRVM_G_VECTOR(OFS_PARM0);
360 dir = PRVM_G_VECTOR(OFS_PARM1);
361 color = PRVM_G_FLOAT(OFS_PARM2);
362 count = PRVM_G_FLOAT(OFS_PARM3);
363 SV_StartParticle (org, dir, (int)color, (int)count);
373 static void VM_SV_ambientsound (void)
377 float vol, attenuation;
380 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
382 pos = PRVM_G_VECTOR (OFS_PARM0);
383 samp = PRVM_G_STRING(OFS_PARM1);
384 vol = PRVM_G_FLOAT(OFS_PARM2);
385 attenuation = PRVM_G_FLOAT(OFS_PARM3);
387 // check to see if samp was properly precached
388 soundnum = SV_SoundIndex(samp, 1);
396 // add an svc_spawnambient command to the level signon packet
399 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
401 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
403 MSG_WriteVector(&sv.signon, pos, sv.protocol);
406 MSG_WriteShort (&sv.signon, soundnum);
408 MSG_WriteByte (&sv.signon, soundnum);
410 MSG_WriteByte (&sv.signon, (int)(vol*255));
411 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
419 Each entity can have eight independant sound sources, like voice,
422 Channel 0 is an auto-allocate channel, the others override anything
423 already running on that entity/channel pair.
425 An attenuation of 0 will play full volume everywhere in the level.
426 Larger attenuations will drop off.
430 static void VM_SV_sound (void)
434 prvm_edict_t *entity;
438 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
440 entity = PRVM_G_EDICT(OFS_PARM0);
441 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
442 sample = PRVM_G_STRING(OFS_PARM2);
443 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
444 attenuation = PRVM_G_FLOAT(OFS_PARM4);
447 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
451 if (volume < 0 || volume > 255)
453 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
457 if (attenuation < 0 || attenuation > 4)
459 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
463 if (channel < 0 || channel > 7)
465 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
469 SV_StartSound (entity, channel, sample, volume, attenuation);
476 Used for use tracing and shot targeting
477 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
478 if the tryents flag is set.
480 traceline (vector1, vector2, movetype, ignore)
483 static void VM_SV_traceline (void)
490 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
492 prog->xfunction->builtinsprofile += 30;
494 v1 = PRVM_G_VECTOR(OFS_PARM0);
495 v2 = PRVM_G_VECTOR(OFS_PARM1);
496 move = (int)PRVM_G_FLOAT(OFS_PARM2);
497 ent = PRVM_G_EDICT(OFS_PARM3);
499 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]))
500 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));
502 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
504 VM_SetTraceGlobals(&trace);
512 Used for use tracing and shot targeting
513 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
514 if the tryents flag is set.
516 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
519 // LordHavoc: added this for my own use, VERY useful, similar to traceline
520 static void VM_SV_tracebox (void)
522 float *v1, *v2, *m1, *m2;
527 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
529 prog->xfunction->builtinsprofile += 30;
531 v1 = PRVM_G_VECTOR(OFS_PARM0);
532 m1 = PRVM_G_VECTOR(OFS_PARM1);
533 m2 = PRVM_G_VECTOR(OFS_PARM2);
534 v2 = PRVM_G_VECTOR(OFS_PARM3);
535 move = (int)PRVM_G_FLOAT(OFS_PARM4);
536 ent = PRVM_G_EDICT(OFS_PARM5);
538 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]))
539 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));
541 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
543 VM_SetTraceGlobals(&trace);
546 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
551 vec3_t original_origin;
552 vec3_t original_velocity;
553 vec3_t original_angles;
554 vec3_t original_avelocity;
558 VectorCopy(tossent->fields.server->origin , original_origin );
559 VectorCopy(tossent->fields.server->velocity , original_velocity );
560 VectorCopy(tossent->fields.server->angles , original_angles );
561 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
563 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
564 if (val != NULL && val->_float != 0)
565 gravity = val->_float;
568 gravity *= sv_gravity.value * 0.05;
570 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
572 SV_CheckVelocity (tossent);
573 tossent->fields.server->velocity[2] -= gravity;
574 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
575 VectorScale (tossent->fields.server->velocity, 0.05, move);
576 VectorAdd (tossent->fields.server->origin, move, end);
577 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
578 VectorCopy (trace.endpos, tossent->fields.server->origin);
580 if (trace.fraction < 1)
584 VectorCopy(original_origin , tossent->fields.server->origin );
585 VectorCopy(original_velocity , tossent->fields.server->velocity );
586 VectorCopy(original_angles , tossent->fields.server->angles );
587 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
592 static void VM_SV_tracetoss (void)
596 prvm_edict_t *ignore;
598 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
600 prog->xfunction->builtinsprofile += 600;
602 ent = PRVM_G_EDICT(OFS_PARM0);
603 if (ent == prog->edicts)
605 VM_Warning("tracetoss: can not use world entity\n");
608 ignore = PRVM_G_EDICT(OFS_PARM1);
610 trace = SV_Trace_Toss (ent, ignore);
612 VM_SetTraceGlobals(&trace);
615 //============================================================================
617 static int checkpvsbytes;
618 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
620 static int VM_SV_newcheckclient (int check)
626 // cycle to the next one
628 check = bound(1, check, svs.maxclients);
629 if (check == svs.maxclients)
637 prog->xfunction->builtinsprofile++;
639 if (i == svs.maxclients+1)
641 // look up the client's edict
642 ent = PRVM_EDICT_NUM(i);
643 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
644 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
646 // found a valid client (possibly the same one again)
650 // get the PVS for the entity
651 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
653 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
654 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
663 Returns a client (or object that has a client enemy) that would be a
666 If there is more than one valid option, they are cycled each frame
668 If (self.origin + self.viewofs) is not in the PVS of the current target,
669 it is not returned at all.
674 int c_invis, c_notvis;
675 static void VM_SV_checkclient (void)
677 prvm_edict_t *ent, *self;
680 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
682 // find a new check if on a new frame
683 if (sv.time - sv.lastchecktime >= 0.1)
685 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
686 sv.lastchecktime = sv.time;
689 // return check if it might be visible
690 ent = PRVM_EDICT_NUM(sv.lastcheck);
691 if (ent->priv.server->free || ent->fields.server->health <= 0)
693 VM_RETURN_EDICT(prog->edicts);
697 // if current entity can't possibly see the check entity, return 0
698 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
699 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
700 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
703 VM_RETURN_EDICT(prog->edicts);
707 // might be able to see it
709 VM_RETURN_EDICT(ent);
712 //============================================================================
719 Sends text over to the client's execution buffer
721 stuffcmd (clientent, value, ...)
724 static void VM_SV_stuffcmd (void)
728 char string[VM_STRINGTEMP_LENGTH];
730 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
732 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
733 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
735 VM_Warning("Can't stuffcmd to a non-client\n");
739 VM_VarString(1, string, sizeof(string));
742 host_client = svs.clients + entnum-1;
743 Host_ClientCommands ("%s", string);
751 Returns a chain of entities that have origins within a spherical area
753 findradius (origin, radius)
756 static void VM_SV_findradius (void)
758 prvm_edict_t *ent, *chain;
759 vec_t radius, radius2;
760 vec3_t org, eorg, mins, maxs;
763 prvm_edict_t *touchedicts[MAX_EDICTS];
765 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
767 chain = (prvm_edict_t *)prog->edicts;
769 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
770 radius = PRVM_G_FLOAT(OFS_PARM1);
771 radius2 = radius * radius;
773 mins[0] = org[0] - (radius + 1);
774 mins[1] = org[1] - (radius + 1);
775 mins[2] = org[2] - (radius + 1);
776 maxs[0] = org[0] + (radius + 1);
777 maxs[1] = org[1] + (radius + 1);
778 maxs[2] = org[2] + (radius + 1);
779 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
780 if (numtouchedicts > MAX_EDICTS)
782 // this never happens
783 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
784 numtouchedicts = MAX_EDICTS;
786 for (i = 0;i < numtouchedicts;i++)
788 ent = touchedicts[i];
789 prog->xfunction->builtinsprofile++;
790 // Quake did not return non-solid entities but darkplaces does
791 // (note: this is the reason you can't blow up fallen zombies)
792 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
794 // LordHavoc: compare against bounding box rather than center so it
795 // doesn't miss large objects, and use DotProduct instead of Length
796 // for a major speedup
797 VectorSubtract(org, ent->fields.server->origin, eorg);
798 if (sv_gameplayfix_findradiusdistancetobox.integer)
800 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
801 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
802 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
805 VectorMAMAM(1, eorg, 0.5f, ent->fields.server->mins, 0.5f, ent->fields.server->maxs, eorg);
806 if (DotProduct(eorg, eorg) < radius2)
808 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
813 VM_RETURN_EDICT(chain);
816 static void VM_SV_precache_sound (void)
818 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
819 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
820 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
823 static void VM_SV_precache_model (void)
825 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
826 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
827 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
834 float(float yaw, float dist[, settrace]) walkmove
837 static void VM_SV_walkmove (void)
846 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
848 // assume failure if it returns early
849 PRVM_G_FLOAT(OFS_RETURN) = 0;
851 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
852 if (ent == prog->edicts)
854 VM_Warning("walkmove: can not modify world entity\n");
857 if (ent->priv.server->free)
859 VM_Warning("walkmove: can not modify free entity\n");
862 yaw = PRVM_G_FLOAT(OFS_PARM0);
863 dist = PRVM_G_FLOAT(OFS_PARM1);
864 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
866 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
869 yaw = yaw*M_PI*2 / 360;
871 move[0] = cos(yaw)*dist;
872 move[1] = sin(yaw)*dist;
875 // save program state, because SV_movestep may call other progs
876 oldf = prog->xfunction;
877 oldself = prog->globals.server->self;
879 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
882 // restore program state
883 prog->xfunction = oldf;
884 prog->globals.server->self = oldself;
894 static void VM_SV_droptofloor (void)
900 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
902 // assume failure if it returns early
903 PRVM_G_FLOAT(OFS_RETURN) = 0;
905 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
906 if (ent == prog->edicts)
908 VM_Warning("droptofloor: can not modify world entity\n");
911 if (ent->priv.server->free)
913 VM_Warning("droptofloor: can not modify free entity\n");
917 VectorCopy (ent->fields.server->origin, end);
920 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
922 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
924 if (trace.fraction < 1)
925 VectorCopy (trace.endpos, ent->fields.server->origin);
926 SV_LinkEdict (ent, false);
927 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
928 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
929 PRVM_G_FLOAT(OFS_RETURN) = 1;
930 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
931 ent->priv.server->suspendedinairflag = true;
939 void(float style, string value) lightstyle
942 static void VM_SV_lightstyle (void)
949 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
951 style = (int)PRVM_G_FLOAT(OFS_PARM0);
952 val = PRVM_G_STRING(OFS_PARM1);
954 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
955 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
958 // change the string in sv
959 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
961 // send message to all clients on this server
962 if (sv.state != ss_active)
965 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
967 if (client->active && client->netconnection)
969 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
970 MSG_WriteChar (&client->netconnection->message,style);
971 MSG_WriteString (&client->netconnection->message, val);
981 static void VM_SV_checkbottom (void)
983 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
984 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
992 static void VM_SV_pointcontents (void)
994 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
995 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1002 Pick a vector for the player to shoot along
1003 vector aim(entity, missilespeed)
1006 static void VM_SV_aim (void)
1008 prvm_edict_t *ent, *check, *bestent;
1009 vec3_t start, dir, end, bestdir;
1012 float dist, bestdist;
1015 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1017 // assume failure if it returns early
1018 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1019 // if sv_aim is so high it can't possibly accept anything, skip out early
1020 if (sv_aim.value >= 1)
1023 ent = PRVM_G_EDICT(OFS_PARM0);
1024 if (ent == prog->edicts)
1026 VM_Warning("aim: can not use world entity\n");
1029 if (ent->priv.server->free)
1031 VM_Warning("aim: can not use free entity\n");
1034 speed = PRVM_G_FLOAT(OFS_PARM1);
1036 VectorCopy (ent->fields.server->origin, start);
1039 // try sending a trace straight
1040 VectorCopy (prog->globals.server->v_forward, dir);
1041 VectorMA (start, 2048, dir, end);
1042 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1043 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1044 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1046 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1051 // try all possible entities
1052 VectorCopy (dir, bestdir);
1053 bestdist = sv_aim.value;
1056 check = PRVM_NEXT_EDICT(prog->edicts);
1057 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1059 prog->xfunction->builtinsprofile++;
1060 if (check->fields.server->takedamage != DAMAGE_AIM)
1064 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1065 continue; // don't aim at teammate
1066 for (j=0 ; j<3 ; j++)
1067 end[j] = check->fields.server->origin[j]
1068 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1069 VectorSubtract (end, start, dir);
1070 VectorNormalize (dir);
1071 dist = DotProduct (dir, prog->globals.server->v_forward);
1072 if (dist < bestdist)
1073 continue; // to far to turn
1074 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1075 if (tr.ent == check)
1076 { // can shoot at this one
1084 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1085 dist = DotProduct (dir, prog->globals.server->v_forward);
1086 VectorScale (prog->globals.server->v_forward, dist, end);
1088 VectorNormalize (end);
1089 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1093 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1098 ===============================================================================
1102 ===============================================================================
1105 #define MSG_BROADCAST 0 // unreliable to all
1106 #define MSG_ONE 1 // reliable to one (msg_entity)
1107 #define MSG_ALL 2 // reliable to all
1108 #define MSG_INIT 3 // write to the init string
1109 #define MSG_ENTITY 5
1111 sizebuf_t *WriteDest (void)
1117 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1121 return &sv.datagram;
1124 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1125 entnum = PRVM_NUM_FOR_EDICT(ent);
1126 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1128 VM_Warning ("WriteDest: tried to write to non-client\n");
1129 return &sv.reliable_datagram;
1132 return &svs.clients[entnum-1].netconnection->message;
1135 VM_Warning ("WriteDest: bad destination\n");
1137 return &sv.reliable_datagram;
1143 return sv.writeentitiestoclient_msg;
1149 static void VM_SV_WriteByte (void)
1151 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1152 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1155 static void VM_SV_WriteChar (void)
1157 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1158 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1161 static void VM_SV_WriteShort (void)
1163 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1164 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1167 static void VM_SV_WriteLong (void)
1169 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1170 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1173 static void VM_SV_WriteAngle (void)
1175 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1176 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1179 static void VM_SV_WriteCoord (void)
1181 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1182 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1185 static void VM_SV_WriteString (void)
1187 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1188 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1191 static void VM_SV_WriteUnterminatedString (void)
1193 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1194 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1198 static void VM_SV_WriteEntity (void)
1200 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1201 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1204 //////////////////////////////////////////////////////////
1206 static void VM_SV_makestatic (void)
1211 // allow 0 parameters due to an id1 qc bug in which this function is used
1212 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1213 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1215 if (prog->argc >= 1)
1216 ent = PRVM_G_EDICT(OFS_PARM0);
1218 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1219 if (ent == prog->edicts)
1221 VM_Warning("makestatic: can not modify world entity\n");
1224 if (ent->priv.server->free)
1226 VM_Warning("makestatic: can not modify free entity\n");
1231 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1236 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1237 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1238 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1242 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1243 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1244 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1247 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1248 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1249 for (i=0 ; i<3 ; i++)
1251 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1252 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1255 // throw the entity away now
1259 //=============================================================================
1266 static void VM_SV_setspawnparms (void)
1272 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1274 ent = PRVM_G_EDICT(OFS_PARM0);
1275 i = PRVM_NUM_FOR_EDICT(ent);
1276 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1278 Con_Print("tried to setspawnparms on a non-client\n");
1282 // copy spawn parms out of the client_t
1283 client = svs.clients + i-1;
1284 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1285 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1292 Returns a color vector indicating the lighting at the requested point.
1294 (Internal Operation note: actually measures the light beneath the point, just like
1295 the model lighting on the client)
1300 static void VM_SV_getlight (void)
1302 vec3_t ambientcolor, diffusecolor, diffusenormal;
1304 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1305 p = PRVM_G_VECTOR(OFS_PARM0);
1306 VectorClear(ambientcolor);
1307 VectorClear(diffusecolor);
1308 VectorClear(diffusenormal);
1309 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1310 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1311 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1316 unsigned char type; // 1/2/8 or other value if isn't used
1320 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1321 static int vm_customstats_last;
1323 void VM_CustomStats_Clear (void)
1327 Z_Free(vm_customstats);
1328 vm_customstats = NULL;
1329 vm_customstats_last = -1;
1333 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1341 for(i=0; i<vm_customstats_last+1 ;i++)
1343 if(!vm_customstats[i].type)
1345 switch(vm_customstats[i].type)
1347 //string as 16 bytes
1350 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1351 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1352 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1353 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1354 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1356 //float field sent as-is
1358 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1360 //integer value of float field
1362 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1370 // void(float index, float type, .void field) SV_AddStat = #232;
1371 // Set up an auto-sent player stat.
1372 // Client's get thier own fields sent to them. Index may not be less than 32.
1373 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1374 // 1: string (4 stats carrying a total of 16 charactures)
1375 // 2: float (one stat, float converted to an integer for transportation)
1376 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1377 static void VM_SV_AddStat (void)
1382 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1386 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1389 VM_Warning("PF_SV_AddStat: not enough memory\n");
1393 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1394 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1395 off = PRVM_G_INT (OFS_PARM2);
1400 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1403 if(i >= (MAX_CL_STATS-32))
1405 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1408 if(i > (MAX_CL_STATS-32-4) && type == 1)
1410 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1413 vm_customstats[i].type = type;
1414 vm_customstats[i].fieldoffset = off;
1415 if(vm_customstats_last < i)
1416 vm_customstats_last = i;
1423 copies data from one entity to another
1425 copyentity(src, dst)
1428 static void VM_SV_copyentity (void)
1430 prvm_edict_t *in, *out;
1431 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1432 in = PRVM_G_EDICT(OFS_PARM0);
1433 if (in == prog->edicts)
1435 VM_Warning("copyentity: can not read world entity\n");
1438 if (in->priv.server->free)
1440 VM_Warning("copyentity: can not read free entity\n");
1443 out = PRVM_G_EDICT(OFS_PARM1);
1444 if (out == prog->edicts)
1446 VM_Warning("copyentity: can not modify world entity\n");
1449 if (out->priv.server->free)
1451 VM_Warning("copyentity: can not modify free entity\n");
1454 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1455 SV_LinkEdict(out, false);
1463 sets the color of a client and broadcasts the update to all connected clients
1465 setcolor(clientent, value)
1468 static void VM_SV_setcolor (void)
1474 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1475 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1476 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1478 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1480 Con_Print("tried to setcolor a non-client\n");
1484 client = svs.clients + entnum-1;
1487 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1489 client->edict->fields.server->team = (i & 15) + 1;
1492 if (client->old_colors != client->colors)
1494 client->old_colors = client->colors;
1495 // send notification to all clients
1496 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1497 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1498 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1506 effect(origin, modelname, startframe, framecount, framerate)
1509 static void VM_SV_effect (void)
1513 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1514 s = PRVM_G_STRING(OFS_PARM1);
1517 VM_Warning("effect: no model specified\n");
1521 i = SV_ModelIndex(s, 1);
1524 VM_Warning("effect: model not precached\n");
1528 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1530 VM_Warning("effect: framecount < 1\n");
1534 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1536 VM_Warning("effect: framerate < 1\n");
1540 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));
1543 static void VM_SV_te_blood (void)
1545 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1546 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1548 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1549 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1551 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1552 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1553 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1555 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1556 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1557 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1559 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1560 SV_FlushBroadcastMessages();
1563 static void VM_SV_te_bloodshower (void)
1565 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1566 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1568 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1569 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1571 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1572 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1573 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1575 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1576 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1577 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1579 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1581 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1582 SV_FlushBroadcastMessages();
1585 static void VM_SV_te_explosionrgb (void)
1587 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1588 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1589 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1591 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1592 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1593 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1595 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1596 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1597 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1598 SV_FlushBroadcastMessages();
1601 static void VM_SV_te_particlecube (void)
1603 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1604 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1606 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1607 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1609 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1610 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1611 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1613 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1614 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1615 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1617 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1618 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1619 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1621 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1623 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1624 // gravity true/false
1625 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1627 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1628 SV_FlushBroadcastMessages();
1631 static void VM_SV_te_particlerain (void)
1633 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1634 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1636 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1637 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1639 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1640 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1641 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1643 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1644 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1645 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1647 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1648 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1649 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1651 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1653 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1654 SV_FlushBroadcastMessages();
1657 static void VM_SV_te_particlesnow (void)
1659 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1660 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1662 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1663 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1665 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1666 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1667 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1671 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1673 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1674 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1675 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1677 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1679 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1680 SV_FlushBroadcastMessages();
1683 static void VM_SV_te_spark (void)
1685 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1686 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1688 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1689 MSG_WriteByte(&sv.datagram, TE_SPARK);
1691 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1692 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1693 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1695 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1696 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1697 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1699 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1700 SV_FlushBroadcastMessages();
1703 static void VM_SV_te_gunshotquad (void)
1705 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1706 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1707 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1709 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1710 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1711 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1712 SV_FlushBroadcastMessages();
1715 static void VM_SV_te_spikequad (void)
1717 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1718 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1719 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1721 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1722 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1723 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1724 SV_FlushBroadcastMessages();
1727 static void VM_SV_te_superspikequad (void)
1729 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1730 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1731 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1733 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1734 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1735 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1736 SV_FlushBroadcastMessages();
1739 static void VM_SV_te_explosionquad (void)
1741 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1742 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1743 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1745 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1746 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1747 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1748 SV_FlushBroadcastMessages();
1751 static void VM_SV_te_smallflash (void)
1753 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1754 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1755 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1757 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1758 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1759 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1760 SV_FlushBroadcastMessages();
1763 static void VM_SV_te_customflash (void)
1765 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1766 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1768 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1769 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1771 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1772 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1773 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1775 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1777 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1779 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1780 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1781 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1782 SV_FlushBroadcastMessages();
1785 static void VM_SV_te_gunshot (void)
1787 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1788 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1789 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1791 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1792 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1793 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1794 SV_FlushBroadcastMessages();
1797 static void VM_SV_te_spike (void)
1799 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1800 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1801 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1803 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1804 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1805 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1806 SV_FlushBroadcastMessages();
1809 static void VM_SV_te_superspike (void)
1811 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1812 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1813 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1815 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1816 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1817 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1818 SV_FlushBroadcastMessages();
1821 static void VM_SV_te_explosion (void)
1823 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1824 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1825 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1827 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1828 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1829 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1830 SV_FlushBroadcastMessages();
1833 static void VM_SV_te_tarexplosion (void)
1835 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1836 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1837 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1839 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1840 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1841 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1842 SV_FlushBroadcastMessages();
1845 static void VM_SV_te_wizspike (void)
1847 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1848 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1849 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1851 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1852 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1853 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1854 SV_FlushBroadcastMessages();
1857 static void VM_SV_te_knightspike (void)
1859 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1860 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1861 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1863 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1864 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1865 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1866 SV_FlushBroadcastMessages();
1869 static void VM_SV_te_lavasplash (void)
1871 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1872 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1873 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1875 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1876 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1877 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1878 SV_FlushBroadcastMessages();
1881 static void VM_SV_te_teleport (void)
1883 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1884 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1885 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1887 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1888 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1889 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1890 SV_FlushBroadcastMessages();
1893 static void VM_SV_te_explosion2 (void)
1895 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1896 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1897 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1899 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1903 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1904 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1905 SV_FlushBroadcastMessages();
1908 static void VM_SV_te_lightning1 (void)
1910 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1911 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1912 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1914 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1916 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1917 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1918 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1920 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1921 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1922 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1923 SV_FlushBroadcastMessages();
1926 static void VM_SV_te_lightning2 (void)
1928 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1929 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1930 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1932 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1934 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1935 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1936 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1938 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1939 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1940 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1941 SV_FlushBroadcastMessages();
1944 static void VM_SV_te_lightning3 (void)
1946 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1947 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1948 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1950 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1952 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1953 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1954 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1956 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1957 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1958 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1959 SV_FlushBroadcastMessages();
1962 static void VM_SV_te_beam (void)
1964 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1965 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1966 MSG_WriteByte(&sv.datagram, TE_BEAM);
1968 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1970 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1974 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1976 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1977 SV_FlushBroadcastMessages();
1980 static void VM_SV_te_plasmaburn (void)
1982 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
1983 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1984 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
1985 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1986 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1987 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1988 SV_FlushBroadcastMessages();
1991 static void VM_SV_te_flamejet (void)
1993 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
1994 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1995 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
1997 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1998 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1999 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2001 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2002 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2003 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2005 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2006 SV_FlushBroadcastMessages();
2009 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2012 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2014 bestdist = 1000000000;
2016 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2018 // clip original point to each triangle of the surface and find the
2019 // triangle that is closest
2020 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2021 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2022 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2023 TriangleNormal(v[0], v[1], v[2], facenormal);
2024 VectorNormalize(facenormal);
2025 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2026 VectorMA(p, offsetdist, facenormal, temp);
2027 for (j = 0, k = 2;j < 3;k = j, j++)
2029 VectorSubtract(v[k], v[j], edgenormal);
2030 CrossProduct(edgenormal, facenormal, sidenormal);
2031 VectorNormalize(sidenormal);
2032 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2034 VectorMA(temp, offsetdist, sidenormal, temp);
2036 dist = VectorDistance2(temp, p);
2037 if (bestdist > dist)
2040 VectorCopy(temp, out);
2045 static model_t *getmodel(prvm_edict_t *ed)
2048 if (!ed || ed->priv.server->free)
2050 modelindex = (int)ed->fields.server->modelindex;
2051 if (modelindex < 1 || modelindex >= MAX_MODELS)
2053 return sv.models[modelindex];
2056 static msurface_t *getsurface(model_t *model, int surfacenum)
2058 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2060 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2064 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2065 static void VM_SV_getsurfacenumpoints(void)
2068 msurface_t *surface;
2069 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2070 // return 0 if no such surface
2071 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2073 PRVM_G_FLOAT(OFS_RETURN) = 0;
2077 // note: this (incorrectly) assumes it is a simple polygon
2078 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2080 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2081 static void VM_SV_getsurfacepoint(void)
2085 msurface_t *surface;
2087 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2088 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2089 ed = PRVM_G_EDICT(OFS_PARM0);
2090 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2092 // note: this (incorrectly) assumes it is a simple polygon
2093 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2094 if (pointnum < 0 || pointnum >= surface->num_vertices)
2096 // FIXME: implement rotation/scaling
2097 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2099 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2100 static void VM_SV_getsurfacenormal(void)
2103 msurface_t *surface;
2105 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2106 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2107 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2109 // FIXME: implement rotation/scaling
2110 // note: this (incorrectly) assumes it is a simple polygon
2111 // note: this only returns the first triangle, so it doesn't work very
2112 // well for curved surfaces or arbitrary meshes
2113 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);
2114 VectorNormalize(normal);
2115 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2117 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2118 static void VM_SV_getsurfacetexture(void)
2121 msurface_t *surface;
2122 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2123 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2124 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2126 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2128 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2129 static void VM_SV_getsurfacenearpoint(void)
2131 int surfacenum, best;
2133 vec_t dist, bestdist;
2136 msurface_t *surface;
2138 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2139 PRVM_G_FLOAT(OFS_RETURN) = -1;
2140 ed = PRVM_G_EDICT(OFS_PARM0);
2141 point = PRVM_G_VECTOR(OFS_PARM1);
2143 if (!ed || ed->priv.server->free)
2145 model = getmodel(ed);
2146 if (!model || !model->num_surfaces)
2149 // FIXME: implement rotation/scaling
2150 VectorSubtract(point, ed->fields.server->origin, p);
2152 bestdist = 1000000000;
2153 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2155 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2156 // first see if the nearest point on the surface's box is closer than the previous match
2157 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2158 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2159 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2160 dist = VectorLength2(clipped);
2161 if (dist < bestdist)
2163 // it is, check the nearest point on the actual geometry
2164 clippointtosurface(model, surface, p, clipped);
2165 VectorSubtract(clipped, p, clipped);
2166 dist += VectorLength2(clipped);
2167 if (dist < bestdist)
2169 // that's closer too, store it as the best match
2175 PRVM_G_FLOAT(OFS_RETURN) = best;
2177 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2178 static void VM_SV_getsurfaceclippedpoint(void)
2182 msurface_t *surface;
2184 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2185 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2186 ed = PRVM_G_EDICT(OFS_PARM0);
2187 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2189 // FIXME: implement rotation/scaling
2190 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2191 clippointtosurface(model, surface, p, out);
2192 // FIXME: implement rotation/scaling
2193 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2196 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2197 //this function originally written by KrimZon, made shorter by LordHavoc
2198 static void VM_SV_clientcommand (void)
2200 client_t *temp_client;
2202 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2204 //find client for this entity
2205 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2206 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2208 Con_Print("PF_clientcommand: entity is not a client\n");
2212 temp_client = host_client;
2213 host_client = svs.clients + i;
2214 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2215 host_client = temp_client;
2218 //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)
2219 static void VM_SV_setattachment (void)
2221 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2222 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2223 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2227 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2229 if (e == prog->edicts)
2231 VM_Warning("setattachment: can not modify world entity\n");
2234 if (e->priv.server->free)
2236 VM_Warning("setattachment: can not modify free entity\n");
2240 if (tagentity == NULL)
2241 tagentity = prog->edicts;
2243 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2245 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2247 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2250 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2252 modelindex = (int)tagentity->fields.server->modelindex;
2253 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2255 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2257 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);
2260 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));
2264 /////////////////////////////////////////
2265 // DP_MD3_TAGINFO extension coded by VorteX
2267 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2272 i = (int)e->fields.server->modelindex;
2273 if (i < 1 || i >= MAX_MODELS)
2275 model = sv.models[i];
2277 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2280 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2282 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2286 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);
2288 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);
2291 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2297 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2298 && (model = sv.models[(int)ent->fields.server->modelindex])
2299 && model->animscenes)
2301 // if model has wrong frame, engine automatically switches to model first frame
2302 frame = (int)ent->fields.server->frame;
2303 if (frame < 0 || frame >= model->numframes)
2305 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2307 *out = identitymatrix;
2311 // Warnings/errors code:
2312 // 0 - normal (everything all-right)
2315 // 3 - null or non-precached model
2316 // 4 - no tags with requested index
2317 // 5 - runaway loop at attachment chain
2318 extern cvar_t cl_bob;
2319 extern cvar_t cl_bobcycle;
2320 extern cvar_t cl_bobup;
2321 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2325 int modelindex, attachloop;
2326 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2329 *out = identitymatrix; // warnings and errors return identical matrix
2331 if (ent == prog->edicts)
2333 if (ent->priv.server->free)
2336 modelindex = (int)ent->fields.server->modelindex;
2337 if (modelindex <= 0 || modelindex > MAX_MODELS)
2340 model = sv.models[modelindex];
2342 tagmatrix = identitymatrix;
2343 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2347 if (attachloop >= 256) // prevent runaway looping
2349 // apply transformation by child's tagindex on parent entity and then
2350 // by parent entity itself
2351 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2352 if (ret && attachloop == 0)
2354 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2355 SV_GetEntityMatrix(ent, &entitymatrix, false);
2356 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2357 // next iteration we process the parent entity
2358 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2360 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2361 ent = PRVM_EDICT_NUM(val->edict);
2368 // RENDER_VIEWMODEL magic
2369 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2371 Matrix4x4_Copy(&tagmatrix, out);
2372 ent = PRVM_EDICT_NUM(val->edict);
2374 SV_GetEntityMatrix(ent, &entitymatrix, true);
2375 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2378 // Cl_bob, ported from rendering code
2379 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2382 // LordHavoc: this code is *weird*, but not replacable (I think it
2383 // should be done in QC on the server, but oh well, quake is quake)
2384 // LordHavoc: figured out bobup: the time at which the sin is at 180
2385 // degrees (which allows lengthening or squishing the peak or valley)
2386 cycle = sv.time/cl_bobcycle.value;
2387 cycle -= (int)cycle;
2388 if (cycle < cl_bobup.value)
2389 cycle = sin(M_PI * cycle / cl_bobup.value);
2391 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2392 // bob is proportional to velocity in the xy plane
2393 // (don't count Z, or jumping messes it up)
2394 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;
2395 bob = bob*0.3 + bob*0.7*cycle;
2396 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2403 //float(entity ent, string tagname) gettagindex;
2405 static void VM_SV_gettagindex (void)
2408 const char *tag_name;
2409 int modelindex, tag_index;
2411 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2413 ent = PRVM_G_EDICT(OFS_PARM0);
2414 tag_name = PRVM_G_STRING(OFS_PARM1);
2416 if (ent == prog->edicts)
2418 VM_Warning("gettagindex: can't affect world entity\n");
2421 if (ent->priv.server->free)
2423 VM_Warning("gettagindex: can't affect free entity\n");
2427 modelindex = (int)ent->fields.server->modelindex;
2429 if (modelindex <= 0 || modelindex > MAX_MODELS)
2430 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2433 tag_index = SV_GetTagIndex(ent, tag_name);
2435 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2437 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2440 //vector(entity ent, float tagindex) gettaginfo;
2441 static void VM_SV_gettaginfo (void)
2445 matrix4x4_t tag_matrix;
2448 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2450 e = PRVM_G_EDICT(OFS_PARM0);
2451 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2453 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2454 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2459 VM_Warning("gettagindex: can't affect world entity\n");
2462 VM_Warning("gettagindex: can't affect free entity\n");
2465 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2468 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2471 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2476 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2477 static void VM_SV_dropclient (void)
2480 client_t *oldhostclient;
2481 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2482 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2483 if (clientnum < 0 || clientnum >= svs.maxclients)
2485 VM_Warning("dropclient: not a client\n");
2488 if (!svs.clients[clientnum].active)
2490 VM_Warning("dropclient: that client slot is not connected\n");
2493 oldhostclient = host_client;
2494 host_client = svs.clients + clientnum;
2495 SV_DropClient(false);
2496 host_client = oldhostclient;
2499 //entity() spawnclient (DP_SV_BOTCLIENT)
2500 static void VM_SV_spawnclient (void)
2504 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2505 prog->xfunction->builtinsprofile += 2;
2507 for (i = 0;i < svs.maxclients;i++)
2509 if (!svs.clients[i].active)
2511 prog->xfunction->builtinsprofile += 100;
2512 SV_ConnectClient (i, NULL);
2513 // this has to be set or else ClientDisconnect won't be called
2514 // we assume the qc will call ClientConnect...
2515 svs.clients[i].clientconnectcalled = true;
2516 ed = PRVM_EDICT_NUM(i + 1);
2520 VM_RETURN_EDICT(ed);
2523 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2524 static void VM_SV_clienttype (void)
2527 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2528 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2529 if (clientnum < 0 || clientnum >= svs.maxclients)
2530 PRVM_G_FLOAT(OFS_RETURN) = 3;
2531 else if (!svs.clients[clientnum].active)
2532 PRVM_G_FLOAT(OFS_RETURN) = 0;
2533 else if (svs.clients[clientnum].netconnection)
2534 PRVM_G_FLOAT(OFS_RETURN) = 1;
2536 PRVM_G_FLOAT(OFS_RETURN) = 2;
2543 string(string key) serverkey
2546 void VM_SV_serverkey(void)
2548 char string[VM_STRINGTEMP_LENGTH];
2549 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2550 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2551 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2554 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2555 static void VM_SV_setmodelindex (void)
2560 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2562 e = PRVM_G_EDICT(OFS_PARM0);
2563 if (e == prog->edicts)
2565 VM_Warning("setmodelindex: can not modify world entity\n");
2568 if (e->priv.server->free)
2570 VM_Warning("setmodelindex: can not modify free entity\n");
2573 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2574 if (i <= 0 || i > MAX_MODELS)
2576 VM_Warning("setmodelindex: invalid modelindex\n");
2579 if (!sv.model_precache[i][0])
2581 VM_Warning("setmodelindex: model not precached\n");
2585 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2586 e->fields.server->modelindex = i;
2592 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2593 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2595 SetMinMaxSize (e, quakemins, quakemaxs, true);
2598 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2601 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2602 static void VM_SV_modelnameforindex (void)
2605 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2607 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2609 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2610 if (i <= 0 || i > MAX_MODELS)
2612 VM_Warning("modelnameforindex: invalid modelindex\n");
2615 if (!sv.model_precache[i][0])
2617 VM_Warning("modelnameforindex: model not precached\n");
2621 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2624 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2625 static void VM_SV_particleeffectnum (void)
2628 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2629 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2632 PRVM_G_FLOAT(OFS_RETURN) = i;
2635 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2636 static void VM_SV_trailparticles (void)
2638 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2640 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2641 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2642 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2643 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2644 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2645 SV_FlushBroadcastMessages();
2648 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2649 static void VM_SV_pointparticles (void)
2651 VM_SAFEPARMCOUNT(4, VM_SV_pointparticles);
2653 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2654 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM0));
2655 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1), sv.protocol);
2656 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2657 MSG_WriteShort(&sv.datagram, bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535));
2658 SV_FlushBroadcastMessages();
2661 prvm_builtin_t vm_sv_builtins[] = {
2662 NULL, // #0 NULL function (not callable) (QUAKE)
2663 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2664 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2665 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2666 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2667 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2668 VM_break, // #6 void() break (QUAKE)
2669 VM_random, // #7 float() random (QUAKE)
2670 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2671 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2672 VM_error, // #10 void(string e) error (QUAKE)
2673 VM_objerror, // #11 void(string e) objerror (QUAKE)
2674 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2675 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2676 VM_spawn, // #14 entity() spawn (QUAKE)
2677 VM_remove, // #15 void(entity e) remove (QUAKE)
2678 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2679 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2680 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2681 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2682 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2683 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2684 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2685 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2686 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2687 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2688 VM_ftos, // #26 string(float f) ftos (QUAKE)
2689 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2690 VM_coredump, // #28 void() coredump (QUAKE)
2691 VM_traceon, // #29 void() traceon (QUAKE)
2692 VM_traceoff, // #30 void() traceoff (QUAKE)
2693 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2694 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2695 NULL, // #33 (QUAKE)
2696 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2697 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2698 VM_rint, // #36 float(float v) rint (QUAKE)
2699 VM_floor, // #37 float(float v) floor (QUAKE)
2700 VM_ceil, // #38 float(float v) ceil (QUAKE)
2701 NULL, // #39 (QUAKE)
2702 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2703 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2704 NULL, // #42 (QUAKE)
2705 VM_fabs, // #43 float(float f) fabs (QUAKE)
2706 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2707 VM_cvar, // #45 float(string s) cvar (QUAKE)
2708 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2709 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2710 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2711 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2712 NULL, // #50 (QUAKE)
2713 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2714 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2715 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2716 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2717 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2718 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2719 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2720 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2721 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2722 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2723 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2724 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2725 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2726 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2727 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2728 NULL, // #66 (QUAKE)
2729 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2730 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2731 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2732 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2733 NULL, // #71 (QUAKE)
2734 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2735 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2736 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2737 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2738 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2739 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2740 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2741 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2742 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2743 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2744 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2745 NULL, // #83 (QUAKE)
2746 NULL, // #84 (QUAKE)
2747 NULL, // #85 (QUAKE)
2748 NULL, // #86 (QUAKE)
2749 NULL, // #87 (QUAKE)
2750 NULL, // #88 (QUAKE)
2751 NULL, // #89 (QUAKE)
2752 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2753 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2754 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2755 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2756 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2757 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2758 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2759 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2760 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2761 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2762 // FrikaC and Telejano range #100-#199
2773 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2774 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2775 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2776 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2777 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2778 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2779 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2780 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2781 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2782 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2863 // FTEQW range #200-#299
2882 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2886 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2887 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2892 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2896 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2964 // CSQC range #300-#399
2965 NULL, // #300 void() clearscene (EXT_CSQC)
2966 NULL, // #301 void(float mask) addentities (EXT_CSQC)
2967 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
2968 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
2969 NULL, // #304 void() renderscene (EXT_CSQC)
2970 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2971 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2972 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2973 NULL, // #308 void() R_EndPolygon
2975 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
2976 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
2980 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
2981 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
2982 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
2983 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
2984 NULL, // #319 void(string name) freepic (EXT_CSQC)
2985 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
2986 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
2987 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
2988 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
2989 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
2990 NULL, // #325 void(void) drawresetcliparea
2995 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
2996 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
2997 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
2998 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2999 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3000 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3001 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3002 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3003 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3004 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3005 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3006 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3007 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3008 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3009 NULL, // #344 vector() getmousepos (EXT_CSQC)
3010 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3011 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3012 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3013 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3014 NULL, // #349 float() isdemo (EXT_CSQC)
3015 VM_isserver, // #350 float() isserver (EXT_CSQC)
3016 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3017 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3018 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3019 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3025 NULL, // #360 float() readbyte (EXT_CSQC)
3026 NULL, // #361 float() readchar (EXT_CSQC)
3027 NULL, // #362 float() readshort (EXT_CSQC)
3028 NULL, // #363 float() readlong (EXT_CSQC)
3029 NULL, // #364 float() readcoord (EXT_CSQC)
3030 NULL, // #365 float() readangle (EXT_CSQC)
3031 NULL, // #366 string() readstring (EXT_CSQC)
3032 NULL, // #367 float() readfloat (EXT_CSQC)
3065 // LordHavoc's range #400-#499
3066 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3067 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3068 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3069 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3070 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3071 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3072 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3073 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3074 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)
3075 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3076 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3077 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3078 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3079 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3080 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3081 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3082 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3083 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3084 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3085 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3086 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3087 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3088 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3089 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3090 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3091 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3092 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3093 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3094 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3095 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3096 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3097 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3098 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3099 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3100 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3101 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3102 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3103 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3104 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3105 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3106 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3107 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3108 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3109 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3110 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
3111 VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
3112 VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
3113 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
3114 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3115 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3116 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3117 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3118 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3119 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3120 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3121 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3122 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3123 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3125 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3126 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3127 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3128 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3129 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3130 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3131 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3132 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3133 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3134 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3135 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3137 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3138 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3139 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3140 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3141 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3142 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3143 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3144 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3145 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3146 VM_strtolower, // #480 string(string s) VM_strtolower : DRESK - Return string as lowercase
3147 VM_strtoupper, // #481 string(string s) VM_strtoupper : DRESK - Return string as uppercase
3168 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3170 void VM_SV_Cmd_Init(void)
3175 void VM_SV_Cmd_Reset(void)