3 //============================================================================
6 cvar_t sv_aim = {CVAR_SAVE, "sv_aim", "2", "maximum cosine angle for quake's vertical autoaim, a value above 1 completely disables the autoaim, quake used 0.93"};
9 char *vm_sv_extensions =
14 "DP_CON_ALIASPARAMETERS "
31 "DP_ENT_CUSTOMCOLORMAP "
32 "DP_ENT_EXTERIORMODELTOCLIENT "
34 "DP_ENT_LOWPRECISION "
37 "DP_GFX_EXTERNALTEXTURES "
38 "DP_GFX_EXTERNALTEXTURES_PERMAP "
40 "DP_GFX_QUAKE3MODELTAGS "
44 "DP_HALFLIFE_MAP_CVAR "
50 "DP_MOVETYPEBOUNCEMISSILE "
52 "DP_QC_ASINACOSATANATAN2TAN "
58 "DP_QC_FINDCHAINFLAGS "
59 "DP_QC_FINDCHAINFLOAT "
67 "DP_QC_MULTIPLETEMPSTRINGS "
69 "DP_QC_SINCOSSQRTPOW "
71 "DP_QC_STRINGBUFFERS "
72 "DP_QC_STRINGCOLORFUNCTIONS "
73 "DP_QC_TOKENIZEBYSEPARATOR "
76 "DP_QC_TRACE_MOVETYPE_HITMODEL "
77 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
78 "DP_QC_UNLIMITEDTEMPSTRINGS "
79 "DP_QC_VECTORVECTORS "
85 "DP_SND_DIRECTIONLESSATTNNONE "
94 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
95 "DP_SV_DRAWONLYTOCLIENT "
98 "DP_SV_ENTITYCONTENTSTRANSITION "
99 "DP_SV_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_SAFEPARMCOUNT(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);
446 if (volume < 0 || volume > 255)
448 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
452 if (attenuation < 0 || attenuation > 4)
454 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
458 if (channel < 0 || channel > 7)
460 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
464 SV_StartSound (entity, channel, sample, volume, attenuation);
471 Used for use tracing and shot targeting
472 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
473 if the tryents flag is set.
475 traceline (vector1, vector2, movetype, ignore)
478 static void VM_SV_traceline (void)
485 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
487 prog->xfunction->builtinsprofile += 30;
489 v1 = PRVM_G_VECTOR(OFS_PARM0);
490 v2 = PRVM_G_VECTOR(OFS_PARM1);
491 move = (int)PRVM_G_FLOAT(OFS_PARM2);
492 ent = PRVM_G_EDICT(OFS_PARM3);
494 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]))
495 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));
497 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
499 VM_SetTraceGlobals(&trace);
507 Used for use tracing and shot targeting
508 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
509 if the tryents flag is set.
511 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
514 // LordHavoc: added this for my own use, VERY useful, similar to traceline
515 static void VM_SV_tracebox (void)
517 float *v1, *v2, *m1, *m2;
522 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
524 prog->xfunction->builtinsprofile += 30;
526 v1 = PRVM_G_VECTOR(OFS_PARM0);
527 m1 = PRVM_G_VECTOR(OFS_PARM1);
528 m2 = PRVM_G_VECTOR(OFS_PARM2);
529 v2 = PRVM_G_VECTOR(OFS_PARM3);
530 move = (int)PRVM_G_FLOAT(OFS_PARM4);
531 ent = PRVM_G_EDICT(OFS_PARM5);
533 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]))
534 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));
536 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
538 VM_SetTraceGlobals(&trace);
541 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
546 vec3_t original_origin;
547 vec3_t original_velocity;
548 vec3_t original_angles;
549 vec3_t original_avelocity;
553 VectorCopy(tossent->fields.server->origin , original_origin );
554 VectorCopy(tossent->fields.server->velocity , original_velocity );
555 VectorCopy(tossent->fields.server->angles , original_angles );
556 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
558 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
559 if (val != NULL && val->_float != 0)
560 gravity = val->_float;
563 gravity *= sv_gravity.value * 0.05;
565 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
567 SV_CheckVelocity (tossent);
568 tossent->fields.server->velocity[2] -= gravity;
569 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
570 VectorScale (tossent->fields.server->velocity, 0.05, move);
571 VectorAdd (tossent->fields.server->origin, move, end);
572 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
573 VectorCopy (trace.endpos, tossent->fields.server->origin);
575 if (trace.fraction < 1)
579 VectorCopy(original_origin , tossent->fields.server->origin );
580 VectorCopy(original_velocity , tossent->fields.server->velocity );
581 VectorCopy(original_angles , tossent->fields.server->angles );
582 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
587 static void VM_SV_tracetoss (void)
591 prvm_edict_t *ignore;
593 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
595 prog->xfunction->builtinsprofile += 600;
597 ent = PRVM_G_EDICT(OFS_PARM0);
598 if (ent == prog->edicts)
600 VM_Warning("tracetoss: can not use world entity\n");
603 ignore = PRVM_G_EDICT(OFS_PARM1);
605 trace = SV_Trace_Toss (ent, ignore);
607 VM_SetTraceGlobals(&trace);
610 //============================================================================
612 static int checkpvsbytes;
613 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
615 static int VM_SV_newcheckclient (int check)
621 // cycle to the next one
623 check = bound(1, check, svs.maxclients);
624 if (check == svs.maxclients)
632 prog->xfunction->builtinsprofile++;
634 if (i == svs.maxclients+1)
636 // look up the client's edict
637 ent = PRVM_EDICT_NUM(i);
638 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
639 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
641 // found a valid client (possibly the same one again)
645 // get the PVS for the entity
646 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
648 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
649 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
658 Returns a client (or object that has a client enemy) that would be a
661 If there is more than one valid option, they are cycled each frame
663 If (self.origin + self.viewofs) is not in the PVS of the current target,
664 it is not returned at all.
669 int c_invis, c_notvis;
670 static void VM_SV_checkclient (void)
672 prvm_edict_t *ent, *self;
675 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
677 // find a new check if on a new frame
678 if (sv.time - sv.lastchecktime >= 0.1)
680 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
681 sv.lastchecktime = sv.time;
684 // return check if it might be visible
685 ent = PRVM_EDICT_NUM(sv.lastcheck);
686 if (ent->priv.server->free || ent->fields.server->health <= 0)
688 VM_RETURN_EDICT(prog->edicts);
692 // if current entity can't possibly see the check entity, return 0
693 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
694 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
695 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
698 VM_RETURN_EDICT(prog->edicts);
702 // might be able to see it
704 VM_RETURN_EDICT(ent);
707 //============================================================================
714 Sends text over to the client's execution buffer
716 stuffcmd (clientent, value, ...)
719 static void VM_SV_stuffcmd (void)
723 char string[VM_STRINGTEMP_LENGTH];
725 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
727 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
728 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
730 VM_Warning("Can't stuffcmd to a non-client\n");
734 VM_VarString(1, string, sizeof(string));
737 host_client = svs.clients + entnum-1;
738 Host_ClientCommands ("%s", string);
746 Returns a chain of entities that have origins within a spherical area
748 findradius (origin, radius)
751 static void VM_SV_findradius (void)
753 prvm_edict_t *ent, *chain;
754 vec_t radius, radius2;
755 vec3_t org, eorg, mins, maxs;
758 prvm_edict_t *touchedicts[MAX_EDICTS];
760 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
762 chain = (prvm_edict_t *)prog->edicts;
764 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
765 radius = PRVM_G_FLOAT(OFS_PARM1);
766 radius2 = radius * radius;
768 mins[0] = org[0] - (radius + 1);
769 mins[1] = org[1] - (radius + 1);
770 mins[2] = org[2] - (radius + 1);
771 maxs[0] = org[0] + (radius + 1);
772 maxs[1] = org[1] + (radius + 1);
773 maxs[2] = org[2] + (radius + 1);
774 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
775 if (numtouchedicts > MAX_EDICTS)
777 // this never happens
778 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
779 numtouchedicts = MAX_EDICTS;
781 for (i = 0;i < numtouchedicts;i++)
783 ent = touchedicts[i];
784 prog->xfunction->builtinsprofile++;
785 // Quake did not return non-solid entities but darkplaces does
786 // (note: this is the reason you can't blow up fallen zombies)
787 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
789 // LordHavoc: compare against bounding box rather than center so it
790 // doesn't miss large objects, and use DotProduct instead of Length
791 // for a major speedup
792 VectorSubtract(org, ent->fields.server->origin, eorg);
793 if (sv_gameplayfix_findradiusdistancetobox.integer)
795 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
796 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
797 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
800 VectorMAMAM(1, eorg, 0.5f, ent->fields.server->mins, 0.5f, ent->fields.server->maxs, eorg);
801 if (DotProduct(eorg, eorg) < radius2)
803 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
808 VM_RETURN_EDICT(chain);
811 static void VM_SV_precache_sound (void)
813 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
814 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
815 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
818 static void VM_SV_precache_model (void)
820 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
821 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
822 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
829 float(float yaw, float dist[, settrace]) walkmove
832 static void VM_SV_walkmove (void)
841 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
843 // assume failure if it returns early
844 PRVM_G_FLOAT(OFS_RETURN) = 0;
846 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
847 if (ent == prog->edicts)
849 VM_Warning("walkmove: can not modify world entity\n");
852 if (ent->priv.server->free)
854 VM_Warning("walkmove: can not modify free entity\n");
857 yaw = PRVM_G_FLOAT(OFS_PARM0);
858 dist = PRVM_G_FLOAT(OFS_PARM1);
859 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
861 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
864 yaw = yaw*M_PI*2 / 360;
866 move[0] = cos(yaw)*dist;
867 move[1] = sin(yaw)*dist;
870 // save program state, because SV_movestep may call other progs
871 oldf = prog->xfunction;
872 oldself = prog->globals.server->self;
874 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
877 // restore program state
878 prog->xfunction = oldf;
879 prog->globals.server->self = oldself;
889 static void VM_SV_droptofloor (void)
895 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
897 // assume failure if it returns early
898 PRVM_G_FLOAT(OFS_RETURN) = 0;
900 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
901 if (ent == prog->edicts)
903 VM_Warning("droptofloor: can not modify world entity\n");
906 if (ent->priv.server->free)
908 VM_Warning("droptofloor: can not modify free entity\n");
912 VectorCopy (ent->fields.server->origin, end);
915 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
917 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
919 if (trace.fraction < 1)
920 VectorCopy (trace.endpos, ent->fields.server->origin);
921 SV_LinkEdict (ent, false);
922 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
923 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
924 PRVM_G_FLOAT(OFS_RETURN) = 1;
925 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
926 ent->priv.server->suspendedinairflag = true;
934 void(float style, string value) lightstyle
937 static void VM_SV_lightstyle (void)
944 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
946 style = (int)PRVM_G_FLOAT(OFS_PARM0);
947 val = PRVM_G_STRING(OFS_PARM1);
949 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
950 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
953 // change the string in sv
954 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
956 // send message to all clients on this server
957 if (sv.state != ss_active)
960 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
962 if (client->active && client->netconnection)
964 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
965 MSG_WriteChar (&client->netconnection->message,style);
966 MSG_WriteString (&client->netconnection->message, val);
976 static void VM_SV_checkbottom (void)
978 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
979 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
987 static void VM_SV_pointcontents (void)
989 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
990 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
997 Pick a vector for the player to shoot along
998 vector aim(entity, missilespeed)
1001 static void VM_SV_aim (void)
1003 prvm_edict_t *ent, *check, *bestent;
1004 vec3_t start, dir, end, bestdir;
1007 float dist, bestdist;
1010 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1012 // assume failure if it returns early
1013 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1014 // if sv_aim is so high it can't possibly accept anything, skip out early
1015 if (sv_aim.value >= 1)
1018 ent = PRVM_G_EDICT(OFS_PARM0);
1019 if (ent == prog->edicts)
1021 VM_Warning("aim: can not use world entity\n");
1024 if (ent->priv.server->free)
1026 VM_Warning("aim: can not use free entity\n");
1029 speed = PRVM_G_FLOAT(OFS_PARM1);
1031 VectorCopy (ent->fields.server->origin, start);
1034 // try sending a trace straight
1035 VectorCopy (prog->globals.server->v_forward, dir);
1036 VectorMA (start, 2048, dir, end);
1037 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1038 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1039 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1041 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1046 // try all possible entities
1047 VectorCopy (dir, bestdir);
1048 bestdist = sv_aim.value;
1051 check = PRVM_NEXT_EDICT(prog->edicts);
1052 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1054 prog->xfunction->builtinsprofile++;
1055 if (check->fields.server->takedamage != DAMAGE_AIM)
1059 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1060 continue; // don't aim at teammate
1061 for (j=0 ; j<3 ; j++)
1062 end[j] = check->fields.server->origin[j]
1063 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1064 VectorSubtract (end, start, dir);
1065 VectorNormalize (dir);
1066 dist = DotProduct (dir, prog->globals.server->v_forward);
1067 if (dist < bestdist)
1068 continue; // to far to turn
1069 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1070 if (tr.ent == check)
1071 { // can shoot at this one
1079 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1080 dist = DotProduct (dir, prog->globals.server->v_forward);
1081 VectorScale (prog->globals.server->v_forward, dist, end);
1083 VectorNormalize (end);
1084 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1088 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1093 ===============================================================================
1097 ===============================================================================
1100 #define MSG_BROADCAST 0 // unreliable to all
1101 #define MSG_ONE 1 // reliable to one (msg_entity)
1102 #define MSG_ALL 2 // reliable to all
1103 #define MSG_INIT 3 // write to the init string
1104 #define MSG_ENTITY 5
1106 sizebuf_t *WriteDest (void)
1111 extern sizebuf_t *sv2csqcbuf;
1113 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1117 return &sv.datagram;
1120 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1121 entnum = PRVM_NUM_FOR_EDICT(ent);
1122 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1124 VM_Warning ("WriteDest: tried to write to non-client\n");
1125 return &sv.reliable_datagram;
1128 return &svs.clients[entnum-1].netconnection->message;
1131 VM_Warning ("WriteDest: bad destination\n");
1133 return &sv.reliable_datagram;
1145 static void VM_SV_WriteByte (void)
1147 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1148 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1151 static void VM_SV_WriteChar (void)
1153 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1154 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1157 static void VM_SV_WriteShort (void)
1159 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1160 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1163 static void VM_SV_WriteLong (void)
1165 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1166 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1169 static void VM_SV_WriteAngle (void)
1171 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1172 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1175 static void VM_SV_WriteCoord (void)
1177 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1178 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1181 static void VM_SV_WriteString (void)
1183 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1184 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1187 static void VM_SV_WriteUnterminatedString (void)
1189 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1190 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1194 static void VM_SV_WriteEntity (void)
1196 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1197 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1200 //////////////////////////////////////////////////////////
1202 static void VM_SV_makestatic (void)
1207 // allow 0 parameters due to an id1 qc bug in which this function is used
1208 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1209 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1211 if (prog->argc >= 1)
1212 ent = PRVM_G_EDICT(OFS_PARM0);
1214 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1215 if (ent == prog->edicts)
1217 VM_Warning("makestatic: can not modify world entity\n");
1220 if (ent->priv.server->free)
1222 VM_Warning("makestatic: can not modify free entity\n");
1227 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1232 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1233 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1234 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1238 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1239 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1240 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1243 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1244 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1245 for (i=0 ; i<3 ; i++)
1247 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1248 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1251 // throw the entity away now
1255 //=============================================================================
1262 static void VM_SV_setspawnparms (void)
1268 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1270 ent = PRVM_G_EDICT(OFS_PARM0);
1271 i = PRVM_NUM_FOR_EDICT(ent);
1272 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1274 Con_Print("tried to setspawnparms on a non-client\n");
1278 // copy spawn parms out of the client_t
1279 client = svs.clients + i-1;
1280 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1281 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1288 Returns a color vector indicating the lighting at the requested point.
1290 (Internal Operation note: actually measures the light beneath the point, just like
1291 the model lighting on the client)
1296 static void VM_SV_getlight (void)
1298 vec3_t ambientcolor, diffusecolor, diffusenormal;
1300 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1301 p = PRVM_G_VECTOR(OFS_PARM0);
1302 VectorClear(ambientcolor);
1303 VectorClear(diffusecolor);
1304 VectorClear(diffusenormal);
1305 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1306 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1307 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1312 unsigned char type; // 1/2/8 or other value if isn't used
1316 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1317 static int vm_customstats_last;
1319 void VM_CustomStats_Clear (void)
1323 Z_Free(vm_customstats);
1324 vm_customstats = NULL;
1325 vm_customstats_last = -1;
1329 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1337 for(i=0; i<vm_customstats_last+1 ;i++)
1339 if(!vm_customstats[i].type)
1341 switch(vm_customstats[i].type)
1343 //string as 16 bytes
1346 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1347 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1348 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1349 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1350 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1352 //float field sent as-is
1354 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1356 //integer value of float field
1358 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1366 // void(float index, float type, .void field) SV_AddStat = #232;
1367 // Set up an auto-sent player stat.
1368 // Client's get thier own fields sent to them. Index may not be less than 32.
1369 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1370 // 1: string (4 stats carrying a total of 16 charactures)
1371 // 2: float (one stat, float converted to an integer for transportation)
1372 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1373 static void VM_SV_AddStat (void)
1378 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1382 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1385 VM_Warning("PF_SV_AddStat: not enough memory\n");
1389 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1390 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1391 off = PRVM_G_INT (OFS_PARM2);
1396 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1399 if(i >= (MAX_CL_STATS-32))
1401 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1404 if(i > (MAX_CL_STATS-32-4) && type == 1)
1406 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1409 vm_customstats[i].type = type;
1410 vm_customstats[i].fieldoffset = off;
1411 if(vm_customstats_last < i)
1412 vm_customstats_last = i;
1419 copies data from one entity to another
1421 copyentity(src, dst)
1424 static void VM_SV_copyentity (void)
1426 prvm_edict_t *in, *out;
1427 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1428 in = PRVM_G_EDICT(OFS_PARM0);
1429 if (in == prog->edicts)
1431 VM_Warning("copyentity: can not read world entity\n");
1434 if (in->priv.server->free)
1436 VM_Warning("copyentity: can not read free entity\n");
1439 out = PRVM_G_EDICT(OFS_PARM1);
1440 if (out == prog->edicts)
1442 VM_Warning("copyentity: can not modify world entity\n");
1445 if (out->priv.server->free)
1447 VM_Warning("copyentity: can not modify free entity\n");
1450 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1451 SV_LinkEdict(out, false);
1459 sets the color of a client and broadcasts the update to all connected clients
1461 setcolor(clientent, value)
1464 static void VM_SV_setcolor (void)
1470 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1471 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1472 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1474 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1476 Con_Print("tried to setcolor a non-client\n");
1480 client = svs.clients + entnum-1;
1483 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1485 client->edict->fields.server->team = (i & 15) + 1;
1488 if (client->old_colors != client->colors)
1490 client->old_colors = client->colors;
1491 // send notification to all clients
1492 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1493 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1494 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1502 effect(origin, modelname, startframe, framecount, framerate)
1505 static void VM_SV_effect (void)
1509 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1510 s = PRVM_G_STRING(OFS_PARM1);
1513 VM_Warning("effect: no model specified\n");
1517 i = SV_ModelIndex(s, 1);
1520 VM_Warning("effect: model not precached\n");
1524 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1526 VM_Warning("effect: framecount < 1\n");
1530 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1532 VM_Warning("effect: framerate < 1\n");
1536 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));
1539 static void VM_SV_te_blood (void)
1541 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1542 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1544 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1545 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1547 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1548 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1549 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1551 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1552 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1553 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1555 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1556 SV_FlushBroadcastMessages();
1559 static void VM_SV_te_bloodshower (void)
1561 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1562 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1564 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1565 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1567 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1568 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1569 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1571 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1572 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1573 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1575 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1577 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1578 SV_FlushBroadcastMessages();
1581 static void VM_SV_te_explosionrgb (void)
1583 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1584 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1585 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1587 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1588 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1589 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1591 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1592 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1593 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1594 SV_FlushBroadcastMessages();
1597 static void VM_SV_te_particlecube (void)
1599 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1600 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1602 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1603 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1605 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1606 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1607 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1609 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1610 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1611 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1613 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1614 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1615 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1617 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1619 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1620 // gravity true/false
1621 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1623 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1624 SV_FlushBroadcastMessages();
1627 static void VM_SV_te_particlerain (void)
1629 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1630 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1632 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1633 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1635 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1636 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1637 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1639 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1640 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1641 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1643 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1644 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1645 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1647 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1649 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1650 SV_FlushBroadcastMessages();
1653 static void VM_SV_te_particlesnow (void)
1655 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1656 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1658 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1659 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1661 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1662 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1663 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1665 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1666 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1667 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1671 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1673 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1675 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1676 SV_FlushBroadcastMessages();
1679 static void VM_SV_te_spark (void)
1681 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1682 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1684 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1685 MSG_WriteByte(&sv.datagram, TE_SPARK);
1687 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1688 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1689 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1691 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1692 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1693 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1695 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1696 SV_FlushBroadcastMessages();
1699 static void VM_SV_te_gunshotquad (void)
1701 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1702 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1703 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1705 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1706 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1707 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1708 SV_FlushBroadcastMessages();
1711 static void VM_SV_te_spikequad (void)
1713 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1714 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1715 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1717 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1718 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1719 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1720 SV_FlushBroadcastMessages();
1723 static void VM_SV_te_superspikequad (void)
1725 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1726 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1727 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1729 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1730 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1731 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1732 SV_FlushBroadcastMessages();
1735 static void VM_SV_te_explosionquad (void)
1737 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1738 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1739 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1741 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1742 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1743 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1744 SV_FlushBroadcastMessages();
1747 static void VM_SV_te_smallflash (void)
1749 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1750 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1751 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1753 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1754 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1755 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1756 SV_FlushBroadcastMessages();
1759 static void VM_SV_te_customflash (void)
1761 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1762 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1764 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1765 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1767 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1768 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1769 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1771 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1773 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1775 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1776 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1777 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1778 SV_FlushBroadcastMessages();
1781 static void VM_SV_te_gunshot (void)
1783 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1784 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1785 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1787 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1788 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1790 SV_FlushBroadcastMessages();
1793 static void VM_SV_te_spike (void)
1795 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1796 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1797 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1799 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1800 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1801 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1802 SV_FlushBroadcastMessages();
1805 static void VM_SV_te_superspike (void)
1807 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1808 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1809 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1811 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1812 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1814 SV_FlushBroadcastMessages();
1817 static void VM_SV_te_explosion (void)
1819 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1820 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1821 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1823 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1824 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1825 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1826 SV_FlushBroadcastMessages();
1829 static void VM_SV_te_tarexplosion (void)
1831 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1832 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1833 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1835 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1836 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1837 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1838 SV_FlushBroadcastMessages();
1841 static void VM_SV_te_wizspike (void)
1843 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1844 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1845 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1847 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1848 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1849 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1850 SV_FlushBroadcastMessages();
1853 static void VM_SV_te_knightspike (void)
1855 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1856 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1857 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1859 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1860 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1861 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1862 SV_FlushBroadcastMessages();
1865 static void VM_SV_te_lavasplash (void)
1867 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1868 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1869 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1871 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1872 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1873 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1874 SV_FlushBroadcastMessages();
1877 static void VM_SV_te_teleport (void)
1879 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1880 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1881 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1883 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1884 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1885 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1886 SV_FlushBroadcastMessages();
1889 static void VM_SV_te_explosion2 (void)
1891 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1892 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1893 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1895 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1896 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1897 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1899 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1900 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1901 SV_FlushBroadcastMessages();
1904 static void VM_SV_te_lightning1 (void)
1906 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1907 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1908 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1910 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1912 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1913 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1914 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1916 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1917 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1918 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1919 SV_FlushBroadcastMessages();
1922 static void VM_SV_te_lightning2 (void)
1924 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1925 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1926 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1928 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1930 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1931 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1934 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1935 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1936 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1937 SV_FlushBroadcastMessages();
1940 static void VM_SV_te_lightning3 (void)
1942 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1943 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1944 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1946 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1948 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1949 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1950 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1952 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1953 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1954 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1955 SV_FlushBroadcastMessages();
1958 static void VM_SV_te_beam (void)
1960 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1961 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1962 MSG_WriteByte(&sv.datagram, TE_BEAM);
1964 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1966 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1967 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1968 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1970 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1973 SV_FlushBroadcastMessages();
1976 static void VM_SV_te_plasmaburn (void)
1978 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
1979 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1980 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
1981 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1982 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1983 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1984 SV_FlushBroadcastMessages();
1987 static void VM_SV_te_flamejet (void)
1989 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
1990 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1991 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
1993 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1994 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1997 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1998 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1999 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2001 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2002 SV_FlushBroadcastMessages();
2005 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2008 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2010 bestdist = 1000000000;
2012 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2014 // clip original point to each triangle of the surface and find the
2015 // triangle that is closest
2016 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2017 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2018 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2019 TriangleNormal(v[0], v[1], v[2], facenormal);
2020 VectorNormalize(facenormal);
2021 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2022 VectorMA(p, offsetdist, facenormal, temp);
2023 for (j = 0, k = 2;j < 3;k = j, j++)
2025 VectorSubtract(v[k], v[j], edgenormal);
2026 CrossProduct(edgenormal, facenormal, sidenormal);
2027 VectorNormalize(sidenormal);
2028 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2030 VectorMA(temp, offsetdist, sidenormal, temp);
2032 dist = VectorDistance2(temp, p);
2033 if (bestdist > dist)
2036 VectorCopy(temp, out);
2041 static model_t *getmodel(prvm_edict_t *ed)
2044 if (!ed || ed->priv.server->free)
2046 modelindex = (int)ed->fields.server->modelindex;
2047 if (modelindex < 1 || modelindex >= MAX_MODELS)
2049 return sv.models[modelindex];
2052 static msurface_t *getsurface(model_t *model, int surfacenum)
2054 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2056 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2060 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2061 static void VM_SV_getsurfacenumpoints(void)
2064 msurface_t *surface;
2065 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2066 // return 0 if no such surface
2067 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2069 PRVM_G_FLOAT(OFS_RETURN) = 0;
2073 // note: this (incorrectly) assumes it is a simple polygon
2074 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2076 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2077 static void VM_SV_getsurfacepoint(void)
2081 msurface_t *surface;
2083 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2084 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2085 ed = PRVM_G_EDICT(OFS_PARM0);
2086 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2088 // note: this (incorrectly) assumes it is a simple polygon
2089 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2090 if (pointnum < 0 || pointnum >= surface->num_vertices)
2092 // FIXME: implement rotation/scaling
2093 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2095 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2096 static void VM_SV_getsurfacenormal(void)
2099 msurface_t *surface;
2101 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2102 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2103 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2105 // FIXME: implement rotation/scaling
2106 // note: this (incorrectly) assumes it is a simple polygon
2107 // note: this only returns the first triangle, so it doesn't work very
2108 // well for curved surfaces or arbitrary meshes
2109 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);
2110 VectorNormalize(normal);
2111 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2113 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2114 static void VM_SV_getsurfacetexture(void)
2117 msurface_t *surface;
2118 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2119 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2120 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2122 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2124 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2125 static void VM_SV_getsurfacenearpoint(void)
2127 int surfacenum, best;
2129 vec_t dist, bestdist;
2132 msurface_t *surface;
2134 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2135 PRVM_G_FLOAT(OFS_RETURN) = -1;
2136 ed = PRVM_G_EDICT(OFS_PARM0);
2137 point = PRVM_G_VECTOR(OFS_PARM1);
2139 if (!ed || ed->priv.server->free)
2141 model = getmodel(ed);
2142 if (!model || !model->num_surfaces)
2145 // FIXME: implement rotation/scaling
2146 VectorSubtract(point, ed->fields.server->origin, p);
2148 bestdist = 1000000000;
2149 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2151 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2152 // first see if the nearest point on the surface's box is closer than the previous match
2153 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2154 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2155 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2156 dist = VectorLength2(clipped);
2157 if (dist < bestdist)
2159 // it is, check the nearest point on the actual geometry
2160 clippointtosurface(model, surface, p, clipped);
2161 VectorSubtract(clipped, p, clipped);
2162 dist += VectorLength2(clipped);
2163 if (dist < bestdist)
2165 // that's closer too, store it as the best match
2171 PRVM_G_FLOAT(OFS_RETURN) = best;
2173 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2174 static void VM_SV_getsurfaceclippedpoint(void)
2178 msurface_t *surface;
2180 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2181 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2182 ed = PRVM_G_EDICT(OFS_PARM0);
2183 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2185 // FIXME: implement rotation/scaling
2186 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2187 clippointtosurface(model, surface, p, out);
2188 // FIXME: implement rotation/scaling
2189 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2192 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2193 //this function originally written by KrimZon, made shorter by LordHavoc
2194 static void VM_SV_clientcommand (void)
2196 client_t *temp_client;
2198 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2200 //find client for this entity
2201 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2202 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2204 Con_Print("PF_clientcommand: entity is not a client\n");
2208 temp_client = host_client;
2209 host_client = svs.clients + i;
2210 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2211 host_client = temp_client;
2214 //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)
2215 static void VM_SV_setattachment (void)
2217 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2218 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2219 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2223 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2225 if (e == prog->edicts)
2227 VM_Warning("setattachment: can not modify world entity\n");
2230 if (e->priv.server->free)
2232 VM_Warning("setattachment: can not modify free entity\n");
2236 if (tagentity == NULL)
2237 tagentity = prog->edicts;
2239 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2241 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2243 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2246 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2248 modelindex = (int)tagentity->fields.server->modelindex;
2249 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2251 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2253 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);
2256 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));
2260 /////////////////////////////////////////
2261 // DP_MD3_TAGINFO extension coded by VorteX
2263 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2268 i = (int)e->fields.server->modelindex;
2269 if (i < 1 || i >= MAX_MODELS)
2271 model = sv.models[i];
2273 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2276 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2278 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2282 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);
2284 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);
2287 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2293 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2294 && (model = sv.models[(int)ent->fields.server->modelindex])
2295 && model->animscenes)
2297 // if model has wrong frame, engine automatically switches to model first frame
2298 frame = (int)ent->fields.server->frame;
2299 if (frame < 0 || frame >= model->numframes)
2301 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2303 *out = identitymatrix;
2307 // Warnings/errors code:
2308 // 0 - normal (everything all-right)
2311 // 3 - null or non-precached model
2312 // 4 - no tags with requested index
2313 // 5 - runaway loop at attachment chain
2314 extern cvar_t cl_bob;
2315 extern cvar_t cl_bobcycle;
2316 extern cvar_t cl_bobup;
2317 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2321 int modelindex, attachloop;
2322 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2325 *out = identitymatrix; // warnings and errors return identical matrix
2327 if (ent == prog->edicts)
2329 if (ent->priv.server->free)
2332 modelindex = (int)ent->fields.server->modelindex;
2333 if (modelindex <= 0 || modelindex > MAX_MODELS)
2336 model = sv.models[modelindex];
2338 tagmatrix = identitymatrix;
2339 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2343 if (attachloop >= 256) // prevent runaway looping
2345 // apply transformation by child's tagindex on parent entity and then
2346 // by parent entity itself
2347 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2348 if (ret && attachloop == 0)
2350 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2351 SV_GetEntityMatrix(ent, &entitymatrix, false);
2352 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2353 // next iteration we process the parent entity
2354 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2356 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2357 ent = PRVM_EDICT_NUM(val->edict);
2364 // RENDER_VIEWMODEL magic
2365 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2367 Matrix4x4_Copy(&tagmatrix, out);
2368 ent = PRVM_EDICT_NUM(val->edict);
2370 SV_GetEntityMatrix(ent, &entitymatrix, true);
2371 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2374 // Cl_bob, ported from rendering code
2375 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2378 // LordHavoc: this code is *weird*, but not replacable (I think it
2379 // should be done in QC on the server, but oh well, quake is quake)
2380 // LordHavoc: figured out bobup: the time at which the sin is at 180
2381 // degrees (which allows lengthening or squishing the peak or valley)
2382 cycle = sv.time/cl_bobcycle.value;
2383 cycle -= (int)cycle;
2384 if (cycle < cl_bobup.value)
2385 cycle = sin(M_PI * cycle / cl_bobup.value);
2387 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2388 // bob is proportional to velocity in the xy plane
2389 // (don't count Z, or jumping messes it up)
2390 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;
2391 bob = bob*0.3 + bob*0.7*cycle;
2392 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2399 //float(entity ent, string tagname) gettagindex;
2401 static void VM_SV_gettagindex (void)
2404 const char *tag_name;
2405 int modelindex, tag_index;
2407 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2409 ent = PRVM_G_EDICT(OFS_PARM0);
2410 tag_name = PRVM_G_STRING(OFS_PARM1);
2412 if (ent == prog->edicts)
2414 VM_Warning("gettagindex: can't affect world entity\n");
2417 if (ent->priv.server->free)
2419 VM_Warning("gettagindex: can't affect free entity\n");
2423 modelindex = (int)ent->fields.server->modelindex;
2425 if (modelindex <= 0 || modelindex > MAX_MODELS)
2426 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2429 tag_index = SV_GetTagIndex(ent, tag_name);
2431 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2433 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2436 //vector(entity ent, float tagindex) gettaginfo;
2437 static void VM_SV_gettaginfo (void)
2441 matrix4x4_t tag_matrix;
2444 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2446 e = PRVM_G_EDICT(OFS_PARM0);
2447 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2449 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2450 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2455 VM_Warning("gettagindex: can't affect world entity\n");
2458 VM_Warning("gettagindex: can't affect free entity\n");
2461 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2464 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2467 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2472 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2473 static void VM_SV_dropclient (void)
2476 client_t *oldhostclient;
2477 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2478 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2479 if (clientnum < 0 || clientnum >= svs.maxclients)
2481 VM_Warning("dropclient: not a client\n");
2484 if (!svs.clients[clientnum].active)
2486 VM_Warning("dropclient: that client slot is not connected\n");
2489 oldhostclient = host_client;
2490 host_client = svs.clients + clientnum;
2491 SV_DropClient(false);
2492 host_client = oldhostclient;
2495 //entity() spawnclient (DP_SV_BOTCLIENT)
2496 static void VM_SV_spawnclient (void)
2500 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2501 prog->xfunction->builtinsprofile += 2;
2503 for (i = 0;i < svs.maxclients;i++)
2505 if (!svs.clients[i].active)
2507 prog->xfunction->builtinsprofile += 100;
2508 SV_ConnectClient (i, NULL);
2509 // this has to be set or else ClientDisconnect won't be called
2510 // we assume the qc will call ClientConnect...
2511 svs.clients[i].clientconnectcalled = true;
2512 ed = PRVM_EDICT_NUM(i + 1);
2516 VM_RETURN_EDICT(ed);
2519 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2520 static void VM_SV_clienttype (void)
2523 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2524 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2525 if (clientnum < 0 || clientnum >= svs.maxclients)
2526 PRVM_G_FLOAT(OFS_RETURN) = 3;
2527 else if (!svs.clients[clientnum].active)
2528 PRVM_G_FLOAT(OFS_RETURN) = 0;
2529 else if (svs.clients[clientnum].netconnection)
2530 PRVM_G_FLOAT(OFS_RETURN) = 1;
2532 PRVM_G_FLOAT(OFS_RETURN) = 2;
2539 string(string key) serverkey
2542 void VM_SV_serverkey(void)
2544 char string[VM_STRINGTEMP_LENGTH];
2545 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2546 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2547 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2550 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2551 static void VM_SV_setmodelindex (void)
2556 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2558 e = PRVM_G_EDICT(OFS_PARM0);
2559 if (e == prog->edicts)
2561 VM_Warning("setmodelindex: can not modify world entity\n");
2564 if (e->priv.server->free)
2566 VM_Warning("setmodelindex: can not modify free entity\n");
2569 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2570 if (i <= 0 || i > MAX_MODELS)
2572 VM_Warning("setmodelindex: invalid modelindex\n");
2575 if (!sv.model_precache[i][0])
2577 VM_Warning("setmodelindex: model not precached\n");
2581 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2582 e->fields.server->modelindex = i;
2588 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2589 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2591 SetMinMaxSize (e, quakemins, quakemaxs, true);
2594 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2597 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2598 static void VM_SV_modelnameforindex (void)
2601 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2603 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2605 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2606 if (i <= 0 || i > MAX_MODELS)
2608 VM_Warning("modelnameforindex: invalid modelindex\n");
2611 if (!sv.model_precache[i][0])
2613 VM_Warning("modelnameforindex: model not precached\n");
2617 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2620 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2621 static void VM_SV_particleeffectnum (void)
2624 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2625 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2628 PRVM_G_FLOAT(OFS_RETURN) = i;
2631 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2632 static void VM_SV_trailparticles (void)
2634 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2636 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2637 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2638 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2639 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2640 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2641 SV_FlushBroadcastMessages();
2644 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2645 static void VM_SV_pointparticles (void)
2647 VM_SAFEPARMCOUNT(4, VM_SV_pointparticles);
2649 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2650 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM0));
2651 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1), sv.protocol);
2652 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2653 MSG_WriteShort(&sv.datagram, bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535));
2654 SV_FlushBroadcastMessages();
2657 prvm_builtin_t vm_sv_builtins[] = {
2658 NULL, // #0 NULL function (not callable) (QUAKE)
2659 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2660 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2661 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2662 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2663 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2664 VM_break, // #6 void() break (QUAKE)
2665 VM_random, // #7 float() random (QUAKE)
2666 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2667 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2668 VM_error, // #10 void(string e) error (QUAKE)
2669 VM_objerror, // #11 void(string e) objerror (QUAKE)
2670 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2671 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2672 VM_spawn, // #14 entity() spawn (QUAKE)
2673 VM_remove, // #15 void(entity e) remove (QUAKE)
2674 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2675 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2676 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2677 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2678 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2679 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2680 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2681 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2682 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2683 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2684 VM_ftos, // #26 string(float f) ftos (QUAKE)
2685 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2686 VM_coredump, // #28 void() coredump (QUAKE)
2687 VM_traceon, // #29 void() traceon (QUAKE)
2688 VM_traceoff, // #30 void() traceoff (QUAKE)
2689 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2690 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2691 NULL, // #33 (QUAKE)
2692 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2693 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2694 VM_rint, // #36 float(float v) rint (QUAKE)
2695 VM_floor, // #37 float(float v) floor (QUAKE)
2696 VM_ceil, // #38 float(float v) ceil (QUAKE)
2697 NULL, // #39 (QUAKE)
2698 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2699 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2700 NULL, // #42 (QUAKE)
2701 VM_fabs, // #43 float(float f) fabs (QUAKE)
2702 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2703 VM_cvar, // #45 float(string s) cvar (QUAKE)
2704 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2705 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2706 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2707 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2708 NULL, // #50 (QUAKE)
2709 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2710 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2711 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2712 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2713 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2714 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2715 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2716 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2717 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2718 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2719 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2720 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2721 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2722 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2723 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2724 NULL, // #66 (QUAKE)
2725 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2726 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2727 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2728 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2729 NULL, // #71 (QUAKE)
2730 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2731 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2732 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2733 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2734 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2735 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2736 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2737 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2738 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2739 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2740 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2741 NULL, // #83 (QUAKE)
2742 NULL, // #84 (QUAKE)
2743 NULL, // #85 (QUAKE)
2744 NULL, // #86 (QUAKE)
2745 NULL, // #87 (QUAKE)
2746 NULL, // #88 (QUAKE)
2747 NULL, // #89 (QUAKE)
2748 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2749 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2750 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2751 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2752 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2753 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2754 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2755 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2756 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2757 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2758 // FrikaC and Telejano range #100-#199
2769 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2770 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2771 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2772 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2773 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2774 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2775 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2776 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2777 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2778 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2859 // FTEQW range #200-#299
2878 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2882 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2883 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2888 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2892 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2960 // CSQC range #300-#399
2961 NULL, // #300 void() clearscene (EXT_CSQC)
2962 NULL, // #301 void(float mask) addentities (EXT_CSQC)
2963 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
2964 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
2965 NULL, // #304 void() renderscene (EXT_CSQC)
2966 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2967 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2968 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2969 NULL, // #308 void() R_EndPolygon
2971 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
2972 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
2976 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
2977 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
2978 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
2979 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
2980 NULL, // #319 void(string name) freepic (EXT_CSQC)
2981 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
2982 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
2983 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
2984 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
2985 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
2986 NULL, // #325 void(void) drawresetcliparea
2991 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
2992 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
2993 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
2994 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2995 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2996 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
2997 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2998 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
2999 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3000 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3001 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3002 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3003 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3004 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3005 NULL, // #344 vector() getmousepos (EXT_CSQC)
3006 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3007 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3008 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3009 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3010 NULL, // #349 float() isdemo (EXT_CSQC)
3011 VM_isserver, // #350 float() isserver (EXT_CSQC)
3012 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3013 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3014 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3015 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3021 NULL, // #360 float() readbyte (EXT_CSQC)
3022 NULL, // #361 float() readchar (EXT_CSQC)
3023 NULL, // #362 float() readshort (EXT_CSQC)
3024 NULL, // #363 float() readlong (EXT_CSQC)
3025 NULL, // #364 float() readcoord (EXT_CSQC)
3026 NULL, // #365 float() readangle (EXT_CSQC)
3027 NULL, // #366 string() readstring (EXT_CSQC)
3028 NULL, // #367 float() readfloat (EXT_CSQC)
3061 // LordHavoc's range #400-#499
3062 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3063 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3064 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3065 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3066 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3067 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3068 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3069 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3070 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)
3071 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3072 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3073 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3074 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3075 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3076 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3077 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3078 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3079 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3080 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3081 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3082 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3083 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3084 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3085 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3086 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3087 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3088 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3089 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3090 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3091 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3092 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3093 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3094 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3095 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3096 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3097 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3098 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3099 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3100 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3101 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3102 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3103 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3104 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3105 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3106 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
3107 VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
3108 VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
3109 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
3110 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3111 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3112 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3113 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3114 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3115 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3116 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3117 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3118 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3119 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3121 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3122 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3123 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3124 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3125 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3126 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3127 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3128 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3129 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3130 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3131 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3133 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3134 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3135 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3136 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3137 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3138 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3139 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3140 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3141 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3164 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3166 void VM_SV_Cmd_Init(void)
3171 void VM_SV_Cmd_Reset(void)