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_POINTPARTICLES "
105 "DP_SV_PRECACHEANYTIME "
108 "DP_SV_ROTATINGBMODEL "
111 "DP_SV_WRITEUNTERMINATEDSTRING "
115 "DP_TE_EXPLOSIONRGB "
117 "DP_TE_PARTICLECUBE "
118 "DP_TE_PARTICLERAIN "
119 "DP_TE_PARTICLESNOW "
121 "DP_TE_QUADEFFECTS1 "
124 "DP_TE_STANDARDEFFECTBUILTINS "
125 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
128 //"EXT_CSQC " // not ready yet
130 "KRIMZON_SV_PARSECLIENTCOMMAND "
133 "NEXUIZ_PLAYERMODEL "
135 "PRYDON_CLIENTCURSOR "
136 "TENEBRAE_GFX_DLIGHTS "
146 This is the only valid way to move an object without using the physics of the world (setting velocity and waiting). Directly changing origin will not set internal links correctly, so clipping would be messed up. This should be called when an object is spawned, and then only if it is teleported.
148 setorigin (entity, origin)
151 static void VM_SV_setorigin (void)
156 VM_SAFEPARMCOUNT(2, VM_setorigin);
158 e = PRVM_G_EDICT(OFS_PARM0);
159 if (e == prog->edicts)
161 VM_Warning("setorigin: can not modify world entity\n");
164 if (e->priv.server->free)
166 VM_Warning("setorigin: can not modify free entity\n");
169 org = PRVM_G_VECTOR(OFS_PARM1);
170 VectorCopy (org, e->fields.server->origin);
171 SV_LinkEdict (e, false);
175 void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
179 for (i=0 ; i<3 ; i++)
181 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
183 // set derived values
184 VectorCopy (min, e->fields.server->mins);
185 VectorCopy (max, e->fields.server->maxs);
186 VectorSubtract (max, min, e->fields.server->size);
188 SV_LinkEdict (e, false);
195 the size box is rotated by the current angle
196 LordHavoc: no it isn't...
198 setsize (entity, minvector, maxvector)
201 static void VM_SV_setsize (void)
206 VM_SAFEPARMCOUNT(3, VM_setsize);
208 e = PRVM_G_EDICT(OFS_PARM0);
209 if (e == prog->edicts)
211 VM_Warning("setsize: can not modify world entity\n");
214 if (e->priv.server->free)
216 VM_Warning("setsize: can not modify free entity\n");
219 min = PRVM_G_VECTOR(OFS_PARM1);
220 max = PRVM_G_VECTOR(OFS_PARM2);
221 SetMinMaxSize (e, min, max, false);
229 setmodel(entity, model)
232 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
233 static void VM_SV_setmodel (void)
239 VM_SAFEPARMCOUNT(2, VM_setmodel);
241 e = PRVM_G_EDICT(OFS_PARM0);
242 if (e == prog->edicts)
244 VM_Warning("setmodel: can not modify world entity\n");
247 if (e->priv.server->free)
249 VM_Warning("setmodel: can not modify free entity\n");
252 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
253 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
254 e->fields.server->modelindex = i;
260 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
261 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
263 SetMinMaxSize (e, quakemins, quakemaxs, true);
266 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
273 single print to a specific client
275 sprint(clientent, value)
278 static void VM_SV_sprint (void)
282 char string[VM_STRINGTEMP_LENGTH];
284 VM_VarString(1, string, sizeof(string));
286 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
288 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
289 // LordHavoc: div0 requested that sprintto world operate like print
296 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
298 VM_Warning("tried to centerprint to a non-client\n");
302 client = svs.clients + entnum-1;
303 if (!client->netconnection)
306 MSG_WriteChar(&client->netconnection->message,svc_print);
307 MSG_WriteString(&client->netconnection->message, string);
315 single print to a specific client
317 centerprint(clientent, value)
320 static void VM_SV_centerprint (void)
324 char string[VM_STRINGTEMP_LENGTH];
326 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
328 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
330 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
332 VM_Warning("tried to centerprint to a non-client\n");
336 client = svs.clients + entnum-1;
337 if (!client->netconnection)
340 VM_VarString(1, string, sizeof(string));
341 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
342 MSG_WriteString(&client->netconnection->message, string);
349 particle(origin, color, count)
352 static void VM_SV_particle (void)
358 VM_SAFEPARMCOUNT(4, VM_SV_particle);
360 org = PRVM_G_VECTOR(OFS_PARM0);
361 dir = PRVM_G_VECTOR(OFS_PARM1);
362 color = PRVM_G_FLOAT(OFS_PARM2);
363 count = PRVM_G_FLOAT(OFS_PARM3);
364 SV_StartParticle (org, dir, (int)color, (int)count);
374 static void VM_SV_ambientsound (void)
378 float vol, attenuation;
381 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
383 pos = PRVM_G_VECTOR (OFS_PARM0);
384 samp = PRVM_G_STRING(OFS_PARM1);
385 vol = PRVM_G_FLOAT(OFS_PARM2);
386 attenuation = PRVM_G_FLOAT(OFS_PARM3);
388 // check to see if samp was properly precached
389 soundnum = SV_SoundIndex(samp, 1);
397 // add an svc_spawnambient command to the level signon packet
400 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
402 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
404 MSG_WriteVector(&sv.signon, pos, sv.protocol);
407 MSG_WriteShort (&sv.signon, soundnum);
409 MSG_WriteByte (&sv.signon, soundnum);
411 MSG_WriteByte (&sv.signon, (int)(vol*255));
412 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
420 Each entity can have eight independant sound sources, like voice,
423 Channel 0 is an auto-allocate channel, the others override anything
424 already running on that entity/channel pair.
426 An attenuation of 0 will play full volume everywhere in the level.
427 Larger attenuations will drop off.
431 static void VM_SV_sound (void)
435 prvm_edict_t *entity;
439 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
441 entity = PRVM_G_EDICT(OFS_PARM0);
442 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
443 sample = PRVM_G_STRING(OFS_PARM2);
444 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
445 attenuation = PRVM_G_FLOAT(OFS_PARM4);
448 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
452 if (volume < 0 || volume > 255)
454 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
458 if (attenuation < 0 || attenuation > 4)
460 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
464 if (channel < 0 || channel > 7)
466 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
470 SV_StartSound (entity, channel, sample, volume, attenuation);
477 Used for use tracing and shot targeting
478 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
479 if the tryents flag is set.
481 traceline (vector1, vector2, movetype, ignore)
484 static void VM_SV_traceline (void)
491 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
493 prog->xfunction->builtinsprofile += 30;
495 v1 = PRVM_G_VECTOR(OFS_PARM0);
496 v2 = PRVM_G_VECTOR(OFS_PARM1);
497 move = (int)PRVM_G_FLOAT(OFS_PARM2);
498 ent = PRVM_G_EDICT(OFS_PARM3);
500 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]))
501 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));
503 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
505 VM_SetTraceGlobals(&trace);
513 Used for use tracing and shot targeting
514 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
515 if the tryents flag is set.
517 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
520 // LordHavoc: added this for my own use, VERY useful, similar to traceline
521 static void VM_SV_tracebox (void)
523 float *v1, *v2, *m1, *m2;
528 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
530 prog->xfunction->builtinsprofile += 30;
532 v1 = PRVM_G_VECTOR(OFS_PARM0);
533 m1 = PRVM_G_VECTOR(OFS_PARM1);
534 m2 = PRVM_G_VECTOR(OFS_PARM2);
535 v2 = PRVM_G_VECTOR(OFS_PARM3);
536 move = (int)PRVM_G_FLOAT(OFS_PARM4);
537 ent = PRVM_G_EDICT(OFS_PARM5);
539 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]))
540 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));
542 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
544 VM_SetTraceGlobals(&trace);
547 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
552 vec3_t original_origin;
553 vec3_t original_velocity;
554 vec3_t original_angles;
555 vec3_t original_avelocity;
559 VectorCopy(tossent->fields.server->origin , original_origin );
560 VectorCopy(tossent->fields.server->velocity , original_velocity );
561 VectorCopy(tossent->fields.server->angles , original_angles );
562 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
564 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
565 if (val != NULL && val->_float != 0)
566 gravity = val->_float;
569 gravity *= sv_gravity.value * 0.05;
571 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
573 SV_CheckVelocity (tossent);
574 tossent->fields.server->velocity[2] -= gravity;
575 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
576 VectorScale (tossent->fields.server->velocity, 0.05, move);
577 VectorAdd (tossent->fields.server->origin, move, end);
578 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
579 VectorCopy (trace.endpos, tossent->fields.server->origin);
581 if (trace.fraction < 1)
585 VectorCopy(original_origin , tossent->fields.server->origin );
586 VectorCopy(original_velocity , tossent->fields.server->velocity );
587 VectorCopy(original_angles , tossent->fields.server->angles );
588 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
593 static void VM_SV_tracetoss (void)
597 prvm_edict_t *ignore;
599 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
601 prog->xfunction->builtinsprofile += 600;
603 ent = PRVM_G_EDICT(OFS_PARM0);
604 if (ent == prog->edicts)
606 VM_Warning("tracetoss: can not use world entity\n");
609 ignore = PRVM_G_EDICT(OFS_PARM1);
611 trace = SV_Trace_Toss (ent, ignore);
613 VM_SetTraceGlobals(&trace);
616 //============================================================================
618 static int checkpvsbytes;
619 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
621 static int VM_SV_newcheckclient (int check)
627 // cycle to the next one
629 check = bound(1, check, svs.maxclients);
630 if (check == svs.maxclients)
638 prog->xfunction->builtinsprofile++;
640 if (i == svs.maxclients+1)
642 // look up the client's edict
643 ent = PRVM_EDICT_NUM(i);
644 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
645 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
647 // found a valid client (possibly the same one again)
651 // get the PVS for the entity
652 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
654 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
655 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
664 Returns a client (or object that has a client enemy) that would be a
667 If there is more than one valid option, they are cycled each frame
669 If (self.origin + self.viewofs) is not in the PVS of the current target,
670 it is not returned at all.
675 int c_invis, c_notvis;
676 static void VM_SV_checkclient (void)
678 prvm_edict_t *ent, *self;
681 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
683 // find a new check if on a new frame
684 if (sv.time - sv.lastchecktime >= 0.1)
686 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
687 sv.lastchecktime = sv.time;
690 // return check if it might be visible
691 ent = PRVM_EDICT_NUM(sv.lastcheck);
692 if (ent->priv.server->free || ent->fields.server->health <= 0)
694 VM_RETURN_EDICT(prog->edicts);
698 // if current entity can't possibly see the check entity, return 0
699 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
700 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
701 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
704 VM_RETURN_EDICT(prog->edicts);
708 // might be able to see it
710 VM_RETURN_EDICT(ent);
713 //============================================================================
720 Sends text over to the client's execution buffer
722 stuffcmd (clientent, value, ...)
725 static void VM_SV_stuffcmd (void)
729 char string[VM_STRINGTEMP_LENGTH];
731 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
733 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
734 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
736 VM_Warning("Can't stuffcmd to a non-client\n");
740 VM_VarString(1, string, sizeof(string));
743 host_client = svs.clients + entnum-1;
744 Host_ClientCommands ("%s", string);
752 Returns a chain of entities that have origins within a spherical area
754 findradius (origin, radius)
757 static void VM_SV_findradius (void)
759 prvm_edict_t *ent, *chain;
760 vec_t radius, radius2;
761 vec3_t org, eorg, mins, maxs;
764 prvm_edict_t *touchedicts[MAX_EDICTS];
766 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
768 chain = (prvm_edict_t *)prog->edicts;
770 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
771 radius = PRVM_G_FLOAT(OFS_PARM1);
772 radius2 = radius * radius;
774 mins[0] = org[0] - (radius + 1);
775 mins[1] = org[1] - (radius + 1);
776 mins[2] = org[2] - (radius + 1);
777 maxs[0] = org[0] + (radius + 1);
778 maxs[1] = org[1] + (radius + 1);
779 maxs[2] = org[2] + (radius + 1);
780 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
781 if (numtouchedicts > MAX_EDICTS)
783 // this never happens
784 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
785 numtouchedicts = MAX_EDICTS;
787 for (i = 0;i < numtouchedicts;i++)
789 ent = touchedicts[i];
790 prog->xfunction->builtinsprofile++;
791 // Quake did not return non-solid entities but darkplaces does
792 // (note: this is the reason you can't blow up fallen zombies)
793 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
795 // LordHavoc: compare against bounding box rather than center so it
796 // doesn't miss large objects, and use DotProduct instead of Length
797 // for a major speedup
798 VectorSubtract(org, ent->fields.server->origin, eorg);
799 if (sv_gameplayfix_findradiusdistancetobox.integer)
801 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
802 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
803 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
806 VectorMAMAM(1, eorg, 0.5f, ent->fields.server->mins, 0.5f, ent->fields.server->maxs, eorg);
807 if (DotProduct(eorg, eorg) < radius2)
809 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
814 VM_RETURN_EDICT(chain);
817 static void VM_SV_precache_sound (void)
819 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
820 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
821 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
824 static void VM_SV_precache_model (void)
826 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
827 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
828 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
835 float(float yaw, float dist[, settrace]) walkmove
838 static void VM_SV_walkmove (void)
847 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
849 // assume failure if it returns early
850 PRVM_G_FLOAT(OFS_RETURN) = 0;
852 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
853 if (ent == prog->edicts)
855 VM_Warning("walkmove: can not modify world entity\n");
858 if (ent->priv.server->free)
860 VM_Warning("walkmove: can not modify free entity\n");
863 yaw = PRVM_G_FLOAT(OFS_PARM0);
864 dist = PRVM_G_FLOAT(OFS_PARM1);
865 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
867 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
870 yaw = yaw*M_PI*2 / 360;
872 move[0] = cos(yaw)*dist;
873 move[1] = sin(yaw)*dist;
876 // save program state, because SV_movestep may call other progs
877 oldf = prog->xfunction;
878 oldself = prog->globals.server->self;
880 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
883 // restore program state
884 prog->xfunction = oldf;
885 prog->globals.server->self = oldself;
895 static void VM_SV_droptofloor (void)
901 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
903 // assume failure if it returns early
904 PRVM_G_FLOAT(OFS_RETURN) = 0;
906 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
907 if (ent == prog->edicts)
909 VM_Warning("droptofloor: can not modify world entity\n");
912 if (ent->priv.server->free)
914 VM_Warning("droptofloor: can not modify free entity\n");
918 VectorCopy (ent->fields.server->origin, end);
921 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
923 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
925 if (trace.fraction < 1)
926 VectorCopy (trace.endpos, ent->fields.server->origin);
927 SV_LinkEdict (ent, false);
928 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
929 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
930 PRVM_G_FLOAT(OFS_RETURN) = 1;
931 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
932 ent->priv.server->suspendedinairflag = true;
940 void(float style, string value) lightstyle
943 static void VM_SV_lightstyle (void)
950 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
952 style = (int)PRVM_G_FLOAT(OFS_PARM0);
953 val = PRVM_G_STRING(OFS_PARM1);
955 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
956 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
959 // change the string in sv
960 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
962 // send message to all clients on this server
963 if (sv.state != ss_active)
966 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
968 if (client->active && client->netconnection)
970 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
971 MSG_WriteChar (&client->netconnection->message,style);
972 MSG_WriteString (&client->netconnection->message, val);
982 static void VM_SV_checkbottom (void)
984 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
985 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
993 static void VM_SV_pointcontents (void)
995 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
996 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1003 Pick a vector for the player to shoot along
1004 vector aim(entity, missilespeed)
1007 static void VM_SV_aim (void)
1009 prvm_edict_t *ent, *check, *bestent;
1010 vec3_t start, dir, end, bestdir;
1013 float dist, bestdist;
1016 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1018 // assume failure if it returns early
1019 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1020 // if sv_aim is so high it can't possibly accept anything, skip out early
1021 if (sv_aim.value >= 1)
1024 ent = PRVM_G_EDICT(OFS_PARM0);
1025 if (ent == prog->edicts)
1027 VM_Warning("aim: can not use world entity\n");
1030 if (ent->priv.server->free)
1032 VM_Warning("aim: can not use free entity\n");
1035 speed = PRVM_G_FLOAT(OFS_PARM1);
1037 VectorCopy (ent->fields.server->origin, start);
1040 // try sending a trace straight
1041 VectorCopy (prog->globals.server->v_forward, dir);
1042 VectorMA (start, 2048, dir, end);
1043 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1044 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1045 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1047 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1052 // try all possible entities
1053 VectorCopy (dir, bestdir);
1054 bestdist = sv_aim.value;
1057 check = PRVM_NEXT_EDICT(prog->edicts);
1058 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1060 prog->xfunction->builtinsprofile++;
1061 if (check->fields.server->takedamage != DAMAGE_AIM)
1065 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1066 continue; // don't aim at teammate
1067 for (j=0 ; j<3 ; j++)
1068 end[j] = check->fields.server->origin[j]
1069 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1070 VectorSubtract (end, start, dir);
1071 VectorNormalize (dir);
1072 dist = DotProduct (dir, prog->globals.server->v_forward);
1073 if (dist < bestdist)
1074 continue; // to far to turn
1075 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1076 if (tr.ent == check)
1077 { // can shoot at this one
1085 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1086 dist = DotProduct (dir, prog->globals.server->v_forward);
1087 VectorScale (prog->globals.server->v_forward, dist, end);
1089 VectorNormalize (end);
1090 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1094 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1099 ===============================================================================
1103 ===============================================================================
1106 #define MSG_BROADCAST 0 // unreliable to all
1107 #define MSG_ONE 1 // reliable to one (msg_entity)
1108 #define MSG_ALL 2 // reliable to all
1109 #define MSG_INIT 3 // write to the init string
1110 #define MSG_ENTITY 5
1112 sizebuf_t *WriteDest (void)
1118 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1122 return &sv.datagram;
1125 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1126 entnum = PRVM_NUM_FOR_EDICT(ent);
1127 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1129 VM_Warning ("WriteDest: tried to write to non-client\n");
1130 return &sv.reliable_datagram;
1133 return &svs.clients[entnum-1].netconnection->message;
1136 VM_Warning ("WriteDest: bad destination\n");
1138 return &sv.reliable_datagram;
1144 return sv.writeentitiestoclient_msg;
1150 static void VM_SV_WriteByte (void)
1152 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1153 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1156 static void VM_SV_WriteChar (void)
1158 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1159 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1162 static void VM_SV_WriteShort (void)
1164 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1165 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1168 static void VM_SV_WriteLong (void)
1170 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1171 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1174 static void VM_SV_WriteAngle (void)
1176 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1177 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1180 static void VM_SV_WriteCoord (void)
1182 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1183 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1186 static void VM_SV_WriteString (void)
1188 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1189 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1192 static void VM_SV_WriteUnterminatedString (void)
1194 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1195 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1199 static void VM_SV_WriteEntity (void)
1201 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1202 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1205 //////////////////////////////////////////////////////////
1207 static void VM_SV_makestatic (void)
1212 // allow 0 parameters due to an id1 qc bug in which this function is used
1213 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1214 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1216 if (prog->argc >= 1)
1217 ent = PRVM_G_EDICT(OFS_PARM0);
1219 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1220 if (ent == prog->edicts)
1222 VM_Warning("makestatic: can not modify world entity\n");
1225 if (ent->priv.server->free)
1227 VM_Warning("makestatic: can not modify free entity\n");
1232 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1237 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1238 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1239 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1243 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1244 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1245 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1248 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1249 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1250 for (i=0 ; i<3 ; i++)
1252 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1253 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1256 // throw the entity away now
1260 //=============================================================================
1267 static void VM_SV_setspawnparms (void)
1273 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1275 ent = PRVM_G_EDICT(OFS_PARM0);
1276 i = PRVM_NUM_FOR_EDICT(ent);
1277 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1279 Con_Print("tried to setspawnparms on a non-client\n");
1283 // copy spawn parms out of the client_t
1284 client = svs.clients + i-1;
1285 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1286 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1293 Returns a color vector indicating the lighting at the requested point.
1295 (Internal Operation note: actually measures the light beneath the point, just like
1296 the model lighting on the client)
1301 static void VM_SV_getlight (void)
1303 vec3_t ambientcolor, diffusecolor, diffusenormal;
1305 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1306 p = PRVM_G_VECTOR(OFS_PARM0);
1307 VectorClear(ambientcolor);
1308 VectorClear(diffusecolor);
1309 VectorClear(diffusenormal);
1310 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1311 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1312 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1317 unsigned char type; // 1/2/8 or other value if isn't used
1321 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1322 static int vm_customstats_last;
1324 void VM_CustomStats_Clear (void)
1328 Z_Free(vm_customstats);
1329 vm_customstats = NULL;
1330 vm_customstats_last = -1;
1334 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1342 for(i=0; i<vm_customstats_last+1 ;i++)
1344 if(!vm_customstats[i].type)
1346 switch(vm_customstats[i].type)
1348 //string as 16 bytes
1351 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1352 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1353 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1354 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1355 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1357 //float field sent as-is
1359 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1361 //integer value of float field
1363 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1371 // void(float index, float type, .void field) SV_AddStat = #232;
1372 // Set up an auto-sent player stat.
1373 // Client's get thier own fields sent to them. Index may not be less than 32.
1374 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1375 // 1: string (4 stats carrying a total of 16 charactures)
1376 // 2: float (one stat, float converted to an integer for transportation)
1377 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1378 static void VM_SV_AddStat (void)
1383 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1387 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1390 VM_Warning("PF_SV_AddStat: not enough memory\n");
1394 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1395 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1396 off = PRVM_G_INT (OFS_PARM2);
1401 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1404 if(i >= (MAX_CL_STATS-32))
1406 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1409 if(i > (MAX_CL_STATS-32-4) && type == 1)
1411 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1414 vm_customstats[i].type = type;
1415 vm_customstats[i].fieldoffset = off;
1416 if(vm_customstats_last < i)
1417 vm_customstats_last = i;
1424 copies data from one entity to another
1426 copyentity(src, dst)
1429 static void VM_SV_copyentity (void)
1431 prvm_edict_t *in, *out;
1432 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1433 in = PRVM_G_EDICT(OFS_PARM0);
1434 if (in == prog->edicts)
1436 VM_Warning("copyentity: can not read world entity\n");
1439 if (in->priv.server->free)
1441 VM_Warning("copyentity: can not read free entity\n");
1444 out = PRVM_G_EDICT(OFS_PARM1);
1445 if (out == prog->edicts)
1447 VM_Warning("copyentity: can not modify world entity\n");
1450 if (out->priv.server->free)
1452 VM_Warning("copyentity: can not modify free entity\n");
1455 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1456 SV_LinkEdict(out, false);
1464 sets the color of a client and broadcasts the update to all connected clients
1466 setcolor(clientent, value)
1469 static void VM_SV_setcolor (void)
1475 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1476 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1477 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1479 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1481 Con_Print("tried to setcolor a non-client\n");
1485 client = svs.clients + entnum-1;
1488 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1490 client->edict->fields.server->team = (i & 15) + 1;
1493 if (client->old_colors != client->colors)
1495 client->old_colors = client->colors;
1496 // send notification to all clients
1497 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1498 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1499 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1507 effect(origin, modelname, startframe, framecount, framerate)
1510 static void VM_SV_effect (void)
1514 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1515 s = PRVM_G_STRING(OFS_PARM1);
1518 VM_Warning("effect: no model specified\n");
1522 i = SV_ModelIndex(s, 1);
1525 VM_Warning("effect: model not precached\n");
1529 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1531 VM_Warning("effect: framecount < 1\n");
1535 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1537 VM_Warning("effect: framerate < 1\n");
1541 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));
1544 static void VM_SV_te_blood (void)
1546 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1547 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1549 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1550 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1552 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1553 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1554 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1556 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1557 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1558 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1560 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1561 SV_FlushBroadcastMessages();
1564 static void VM_SV_te_bloodshower (void)
1566 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1567 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1569 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1570 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1572 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1573 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1574 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1576 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1577 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1578 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1580 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1582 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1583 SV_FlushBroadcastMessages();
1586 static void VM_SV_te_explosionrgb (void)
1588 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1589 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1590 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1592 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1593 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1594 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1596 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1597 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1598 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1599 SV_FlushBroadcastMessages();
1602 static void VM_SV_te_particlecube (void)
1604 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1605 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1607 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1608 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1610 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1611 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1612 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1614 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1615 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1616 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1618 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1619 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1620 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1622 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1624 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1625 // gravity true/false
1626 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1628 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1629 SV_FlushBroadcastMessages();
1632 static void VM_SV_te_particlerain (void)
1634 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1635 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1637 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1638 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1640 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1641 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1642 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1644 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1645 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1646 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1648 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1649 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1650 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1652 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1654 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1655 SV_FlushBroadcastMessages();
1658 static void VM_SV_te_particlesnow (void)
1660 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1661 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1663 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1664 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1666 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1667 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1668 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1671 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1672 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1674 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1675 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1676 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1678 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1680 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1681 SV_FlushBroadcastMessages();
1684 static void VM_SV_te_spark (void)
1686 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1687 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1689 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1690 MSG_WriteByte(&sv.datagram, TE_SPARK);
1692 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1693 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1694 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1696 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1697 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1698 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1700 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1701 SV_FlushBroadcastMessages();
1704 static void VM_SV_te_gunshotquad (void)
1706 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1707 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1708 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1710 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1711 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1712 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1713 SV_FlushBroadcastMessages();
1716 static void VM_SV_te_spikequad (void)
1718 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1719 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1720 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1722 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1723 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1724 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1725 SV_FlushBroadcastMessages();
1728 static void VM_SV_te_superspikequad (void)
1730 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1731 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1732 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1734 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1735 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1736 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1737 SV_FlushBroadcastMessages();
1740 static void VM_SV_te_explosionquad (void)
1742 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1743 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1744 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1746 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1747 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1748 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1749 SV_FlushBroadcastMessages();
1752 static void VM_SV_te_smallflash (void)
1754 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1755 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1756 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1758 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1759 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1760 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1761 SV_FlushBroadcastMessages();
1764 static void VM_SV_te_customflash (void)
1766 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1767 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1769 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1770 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1772 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1773 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1774 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1776 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1778 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1780 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1781 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1782 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1783 SV_FlushBroadcastMessages();
1786 static void VM_SV_te_gunshot (void)
1788 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1789 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1790 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1792 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1793 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1794 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1795 SV_FlushBroadcastMessages();
1798 static void VM_SV_te_spike (void)
1800 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1801 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1802 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1804 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1805 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1806 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1807 SV_FlushBroadcastMessages();
1810 static void VM_SV_te_superspike (void)
1812 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1813 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1814 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1816 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1817 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1818 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1819 SV_FlushBroadcastMessages();
1822 static void VM_SV_te_explosion (void)
1824 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1825 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1826 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1828 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1829 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1830 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1831 SV_FlushBroadcastMessages();
1834 static void VM_SV_te_tarexplosion (void)
1836 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1837 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1838 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1840 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1841 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1842 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1843 SV_FlushBroadcastMessages();
1846 static void VM_SV_te_wizspike (void)
1848 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1849 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1850 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1852 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1853 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1854 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1855 SV_FlushBroadcastMessages();
1858 static void VM_SV_te_knightspike (void)
1860 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1861 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1862 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1864 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1865 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1866 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1867 SV_FlushBroadcastMessages();
1870 static void VM_SV_te_lavasplash (void)
1872 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1873 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1874 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1876 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1877 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1878 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1879 SV_FlushBroadcastMessages();
1882 static void VM_SV_te_teleport (void)
1884 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1885 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1886 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1888 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1889 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1890 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1891 SV_FlushBroadcastMessages();
1894 static void VM_SV_te_explosion2 (void)
1896 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1897 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1898 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1902 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1904 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1905 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1906 SV_FlushBroadcastMessages();
1909 static void VM_SV_te_lightning1 (void)
1911 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1912 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1913 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1915 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1917 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1918 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1919 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1921 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1922 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1923 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1924 SV_FlushBroadcastMessages();
1927 static void VM_SV_te_lightning2 (void)
1929 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1930 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1931 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1933 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1935 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1936 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1937 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1939 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1940 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1941 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1942 SV_FlushBroadcastMessages();
1945 static void VM_SV_te_lightning3 (void)
1947 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1948 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1949 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1951 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1953 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1954 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1955 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1957 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1958 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1959 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1960 SV_FlushBroadcastMessages();
1963 static void VM_SV_te_beam (void)
1965 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1966 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1967 MSG_WriteByte(&sv.datagram, TE_BEAM);
1969 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1976 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1977 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1978 SV_FlushBroadcastMessages();
1981 static void VM_SV_te_plasmaburn (void)
1983 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
1984 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1985 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
1986 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1987 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1988 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1989 SV_FlushBroadcastMessages();
1992 static void VM_SV_te_flamejet (void)
1994 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
1995 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1996 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
1998 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1999 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2000 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2002 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2003 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2004 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2006 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2007 SV_FlushBroadcastMessages();
2010 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2013 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2015 bestdist = 1000000000;
2017 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2019 // clip original point to each triangle of the surface and find the
2020 // triangle that is closest
2021 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2022 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2023 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2024 TriangleNormal(v[0], v[1], v[2], facenormal);
2025 VectorNormalize(facenormal);
2026 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2027 VectorMA(p, offsetdist, facenormal, temp);
2028 for (j = 0, k = 2;j < 3;k = j, j++)
2030 VectorSubtract(v[k], v[j], edgenormal);
2031 CrossProduct(edgenormal, facenormal, sidenormal);
2032 VectorNormalize(sidenormal);
2033 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2035 VectorMA(temp, offsetdist, sidenormal, temp);
2037 dist = VectorDistance2(temp, p);
2038 if (bestdist > dist)
2041 VectorCopy(temp, out);
2046 static model_t *getmodel(prvm_edict_t *ed)
2049 if (!ed || ed->priv.server->free)
2051 modelindex = (int)ed->fields.server->modelindex;
2052 if (modelindex < 1 || modelindex >= MAX_MODELS)
2054 return sv.models[modelindex];
2057 static msurface_t *getsurface(model_t *model, int surfacenum)
2059 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2061 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2065 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2066 static void VM_SV_getsurfacenumpoints(void)
2069 msurface_t *surface;
2070 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2071 // return 0 if no such surface
2072 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2074 PRVM_G_FLOAT(OFS_RETURN) = 0;
2078 // note: this (incorrectly) assumes it is a simple polygon
2079 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2081 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2082 static void VM_SV_getsurfacepoint(void)
2086 msurface_t *surface;
2088 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2089 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2090 ed = PRVM_G_EDICT(OFS_PARM0);
2091 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2093 // note: this (incorrectly) assumes it is a simple polygon
2094 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2095 if (pointnum < 0 || pointnum >= surface->num_vertices)
2097 // FIXME: implement rotation/scaling
2098 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2100 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2101 static void VM_SV_getsurfacenormal(void)
2104 msurface_t *surface;
2106 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2107 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2108 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2110 // FIXME: implement rotation/scaling
2111 // note: this (incorrectly) assumes it is a simple polygon
2112 // note: this only returns the first triangle, so it doesn't work very
2113 // well for curved surfaces or arbitrary meshes
2114 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);
2115 VectorNormalize(normal);
2116 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2118 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2119 static void VM_SV_getsurfacetexture(void)
2122 msurface_t *surface;
2123 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2124 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2125 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2127 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2129 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2130 static void VM_SV_getsurfacenearpoint(void)
2132 int surfacenum, best;
2134 vec_t dist, bestdist;
2137 msurface_t *surface;
2139 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2140 PRVM_G_FLOAT(OFS_RETURN) = -1;
2141 ed = PRVM_G_EDICT(OFS_PARM0);
2142 point = PRVM_G_VECTOR(OFS_PARM1);
2144 if (!ed || ed->priv.server->free)
2146 model = getmodel(ed);
2147 if (!model || !model->num_surfaces)
2150 // FIXME: implement rotation/scaling
2151 VectorSubtract(point, ed->fields.server->origin, p);
2153 bestdist = 1000000000;
2154 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2156 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2157 // first see if the nearest point on the surface's box is closer than the previous match
2158 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2159 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2160 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2161 dist = VectorLength2(clipped);
2162 if (dist < bestdist)
2164 // it is, check the nearest point on the actual geometry
2165 clippointtosurface(model, surface, p, clipped);
2166 VectorSubtract(clipped, p, clipped);
2167 dist += VectorLength2(clipped);
2168 if (dist < bestdist)
2170 // that's closer too, store it as the best match
2176 PRVM_G_FLOAT(OFS_RETURN) = best;
2178 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2179 static void VM_SV_getsurfaceclippedpoint(void)
2183 msurface_t *surface;
2185 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2186 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2187 ed = PRVM_G_EDICT(OFS_PARM0);
2188 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2190 // FIXME: implement rotation/scaling
2191 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2192 clippointtosurface(model, surface, p, out);
2193 // FIXME: implement rotation/scaling
2194 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2197 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2198 //this function originally written by KrimZon, made shorter by LordHavoc
2199 static void VM_SV_clientcommand (void)
2201 client_t *temp_client;
2203 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2205 //find client for this entity
2206 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2207 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2209 Con_Print("PF_clientcommand: entity is not a client\n");
2213 temp_client = host_client;
2214 host_client = svs.clients + i;
2215 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2216 host_client = temp_client;
2219 //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)
2220 static void VM_SV_setattachment (void)
2222 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2223 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2224 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2228 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2230 if (e == prog->edicts)
2232 VM_Warning("setattachment: can not modify world entity\n");
2235 if (e->priv.server->free)
2237 VM_Warning("setattachment: can not modify free entity\n");
2241 if (tagentity == NULL)
2242 tagentity = prog->edicts;
2244 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2246 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2248 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2251 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2253 modelindex = (int)tagentity->fields.server->modelindex;
2254 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2256 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2258 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);
2261 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));
2265 /////////////////////////////////////////
2266 // DP_MD3_TAGINFO extension coded by VorteX
2268 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2273 i = (int)e->fields.server->modelindex;
2274 if (i < 1 || i >= MAX_MODELS)
2276 model = sv.models[i];
2278 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2281 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2283 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2287 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);
2289 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);
2292 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2298 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2299 && (model = sv.models[(int)ent->fields.server->modelindex])
2300 && model->animscenes)
2302 // if model has wrong frame, engine automatically switches to model first frame
2303 frame = (int)ent->fields.server->frame;
2304 if (frame < 0 || frame >= model->numframes)
2306 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2308 *out = identitymatrix;
2312 // Warnings/errors code:
2313 // 0 - normal (everything all-right)
2316 // 3 - null or non-precached model
2317 // 4 - no tags with requested index
2318 // 5 - runaway loop at attachment chain
2319 extern cvar_t cl_bob;
2320 extern cvar_t cl_bobcycle;
2321 extern cvar_t cl_bobup;
2322 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2326 int modelindex, attachloop;
2327 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2330 *out = identitymatrix; // warnings and errors return identical matrix
2332 if (ent == prog->edicts)
2334 if (ent->priv.server->free)
2337 modelindex = (int)ent->fields.server->modelindex;
2338 if (modelindex <= 0 || modelindex > MAX_MODELS)
2341 model = sv.models[modelindex];
2343 tagmatrix = identitymatrix;
2344 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2348 if (attachloop >= 256) // prevent runaway looping
2350 // apply transformation by child's tagindex on parent entity and then
2351 // by parent entity itself
2352 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2353 if (ret && attachloop == 0)
2355 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2356 SV_GetEntityMatrix(ent, &entitymatrix, false);
2357 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2358 // next iteration we process the parent entity
2359 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2361 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2362 ent = PRVM_EDICT_NUM(val->edict);
2369 // RENDER_VIEWMODEL magic
2370 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2372 Matrix4x4_Copy(&tagmatrix, out);
2373 ent = PRVM_EDICT_NUM(val->edict);
2375 SV_GetEntityMatrix(ent, &entitymatrix, true);
2376 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2379 // Cl_bob, ported from rendering code
2380 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2383 // LordHavoc: this code is *weird*, but not replacable (I think it
2384 // should be done in QC on the server, but oh well, quake is quake)
2385 // LordHavoc: figured out bobup: the time at which the sin is at 180
2386 // degrees (which allows lengthening or squishing the peak or valley)
2387 cycle = sv.time/cl_bobcycle.value;
2388 cycle -= (int)cycle;
2389 if (cycle < cl_bobup.value)
2390 cycle = sin(M_PI * cycle / cl_bobup.value);
2392 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2393 // bob is proportional to velocity in the xy plane
2394 // (don't count Z, or jumping messes it up)
2395 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;
2396 bob = bob*0.3 + bob*0.7*cycle;
2397 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2404 //float(entity ent, string tagname) gettagindex;
2406 static void VM_SV_gettagindex (void)
2409 const char *tag_name;
2410 int modelindex, tag_index;
2412 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2414 ent = PRVM_G_EDICT(OFS_PARM0);
2415 tag_name = PRVM_G_STRING(OFS_PARM1);
2417 if (ent == prog->edicts)
2419 VM_Warning("gettagindex: can't affect world entity\n");
2422 if (ent->priv.server->free)
2424 VM_Warning("gettagindex: can't affect free entity\n");
2428 modelindex = (int)ent->fields.server->modelindex;
2430 if (modelindex <= 0 || modelindex > MAX_MODELS)
2431 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2434 tag_index = SV_GetTagIndex(ent, tag_name);
2436 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2438 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2441 //vector(entity ent, float tagindex) gettaginfo;
2442 static void VM_SV_gettaginfo (void)
2446 matrix4x4_t tag_matrix;
2449 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2451 e = PRVM_G_EDICT(OFS_PARM0);
2452 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2454 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2455 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2460 VM_Warning("gettagindex: can't affect world entity\n");
2463 VM_Warning("gettagindex: can't affect free entity\n");
2466 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2469 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2472 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2477 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2478 static void VM_SV_dropclient (void)
2481 client_t *oldhostclient;
2482 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2483 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2484 if (clientnum < 0 || clientnum >= svs.maxclients)
2486 VM_Warning("dropclient: not a client\n");
2489 if (!svs.clients[clientnum].active)
2491 VM_Warning("dropclient: that client slot is not connected\n");
2494 oldhostclient = host_client;
2495 host_client = svs.clients + clientnum;
2496 SV_DropClient(false);
2497 host_client = oldhostclient;
2500 //entity() spawnclient (DP_SV_BOTCLIENT)
2501 static void VM_SV_spawnclient (void)
2505 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2506 prog->xfunction->builtinsprofile += 2;
2508 for (i = 0;i < svs.maxclients;i++)
2510 if (!svs.clients[i].active)
2512 prog->xfunction->builtinsprofile += 100;
2513 SV_ConnectClient (i, NULL);
2514 // this has to be set or else ClientDisconnect won't be called
2515 // we assume the qc will call ClientConnect...
2516 svs.clients[i].clientconnectcalled = true;
2517 ed = PRVM_EDICT_NUM(i + 1);
2521 VM_RETURN_EDICT(ed);
2524 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2525 static void VM_SV_clienttype (void)
2528 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2529 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2530 if (clientnum < 0 || clientnum >= svs.maxclients)
2531 PRVM_G_FLOAT(OFS_RETURN) = 3;
2532 else if (!svs.clients[clientnum].active)
2533 PRVM_G_FLOAT(OFS_RETURN) = 0;
2534 else if (svs.clients[clientnum].netconnection)
2535 PRVM_G_FLOAT(OFS_RETURN) = 1;
2537 PRVM_G_FLOAT(OFS_RETURN) = 2;
2544 string(string key) serverkey
2547 void VM_SV_serverkey(void)
2549 char string[VM_STRINGTEMP_LENGTH];
2550 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2551 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2552 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2555 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2556 static void VM_SV_setmodelindex (void)
2561 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2563 e = PRVM_G_EDICT(OFS_PARM0);
2564 if (e == prog->edicts)
2566 VM_Warning("setmodelindex: can not modify world entity\n");
2569 if (e->priv.server->free)
2571 VM_Warning("setmodelindex: can not modify free entity\n");
2574 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2575 if (i <= 0 || i > MAX_MODELS)
2577 VM_Warning("setmodelindex: invalid modelindex\n");
2580 if (!sv.model_precache[i][0])
2582 VM_Warning("setmodelindex: model not precached\n");
2586 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2587 e->fields.server->modelindex = i;
2593 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2594 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2596 SetMinMaxSize (e, quakemins, quakemaxs, true);
2599 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2602 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2603 static void VM_SV_modelnameforindex (void)
2606 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2608 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2610 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2611 if (i <= 0 || i > MAX_MODELS)
2613 VM_Warning("modelnameforindex: invalid modelindex\n");
2616 if (!sv.model_precache[i][0])
2618 VM_Warning("modelnameforindex: model not precached\n");
2622 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2625 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2626 static void VM_SV_particleeffectnum (void)
2629 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2630 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2633 PRVM_G_FLOAT(OFS_RETURN) = i;
2636 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2637 static void VM_SV_trailparticles (void)
2639 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2641 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2642 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2643 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2644 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2645 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2646 SV_FlushBroadcastMessages();
2649 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2650 static void VM_SV_pointparticles (void)
2652 int effectnum, count;
2654 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2655 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2656 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2657 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2658 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2659 if (count == 1 && !VectorLength2(vel) && (sv.protocol != PROTOCOL_QUAKE && sv.protocol != PROTOCOL_QUAKEDP && sv.protocol != PROTOCOL_NEHAHRAMOVIE && sv.protocol != PROTOCOL_DARKPLACES1 && sv.protocol != PROTOCOL_DARKPLACES2 && sv.protocol != PROTOCOL_DARKPLACES3 && sv.protocol != PROTOCOL_DARKPLACES4 && sv.protocol != PROTOCOL_DARKPLACES5 && sv.protocol != PROTOCOL_DARKPLACES6 && sv.protocol != PROTOCOL_DARKPLACES7))
2662 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2663 MSG_WriteShort(&sv.datagram, effectnum);
2664 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2668 // 1+2+12+12+2=29 bytes
2669 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2670 MSG_WriteShort(&sv.datagram, effectnum);
2671 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2672 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2673 MSG_WriteShort(&sv.datagram, count);
2676 SV_FlushBroadcastMessages();
2679 prvm_builtin_t vm_sv_builtins[] = {
2680 NULL, // #0 NULL function (not callable) (QUAKE)
2681 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2682 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2683 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2684 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2685 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2686 VM_break, // #6 void() break (QUAKE)
2687 VM_random, // #7 float() random (QUAKE)
2688 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2689 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2690 VM_error, // #10 void(string e) error (QUAKE)
2691 VM_objerror, // #11 void(string e) objerror (QUAKE)
2692 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2693 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2694 VM_spawn, // #14 entity() spawn (QUAKE)
2695 VM_remove, // #15 void(entity e) remove (QUAKE)
2696 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2697 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2698 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2699 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2700 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2701 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2702 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2703 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2704 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2705 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2706 VM_ftos, // #26 string(float f) ftos (QUAKE)
2707 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2708 VM_coredump, // #28 void() coredump (QUAKE)
2709 VM_traceon, // #29 void() traceon (QUAKE)
2710 VM_traceoff, // #30 void() traceoff (QUAKE)
2711 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2712 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2713 NULL, // #33 (QUAKE)
2714 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2715 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2716 VM_rint, // #36 float(float v) rint (QUAKE)
2717 VM_floor, // #37 float(float v) floor (QUAKE)
2718 VM_ceil, // #38 float(float v) ceil (QUAKE)
2719 NULL, // #39 (QUAKE)
2720 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2721 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2722 NULL, // #42 (QUAKE)
2723 VM_fabs, // #43 float(float f) fabs (QUAKE)
2724 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2725 VM_cvar, // #45 float(string s) cvar (QUAKE)
2726 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2727 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2728 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2729 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2730 NULL, // #50 (QUAKE)
2731 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2732 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2733 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2734 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2735 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2736 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2737 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2738 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2739 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2740 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2741 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2742 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2743 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2744 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2745 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2746 NULL, // #66 (QUAKE)
2747 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2748 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2749 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2750 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2751 NULL, // #71 (QUAKE)
2752 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2753 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2754 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2755 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2756 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2757 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2758 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2759 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2760 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2761 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2762 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2763 NULL, // #83 (QUAKE)
2764 NULL, // #84 (QUAKE)
2765 NULL, // #85 (QUAKE)
2766 NULL, // #86 (QUAKE)
2767 NULL, // #87 (QUAKE)
2768 NULL, // #88 (QUAKE)
2769 NULL, // #89 (QUAKE)
2770 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2771 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2772 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2773 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2774 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2775 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2776 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2777 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2778 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2779 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2780 // FrikaC and Telejano range #100-#199
2791 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2792 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2793 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2794 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2795 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2796 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2797 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2798 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2799 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2800 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2881 // FTEQW range #200-#299
2900 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2904 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2905 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2910 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2914 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2982 // CSQC range #300-#399
2983 NULL, // #300 void() clearscene (EXT_CSQC)
2984 NULL, // #301 void(float mask) addentities (EXT_CSQC)
2985 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
2986 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
2987 NULL, // #304 void() renderscene (EXT_CSQC)
2988 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2989 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2990 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2991 NULL, // #308 void() R_EndPolygon
2993 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
2994 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
2998 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
2999 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3000 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3001 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3002 NULL, // #319 void(string name) freepic (EXT_CSQC)
3003 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3004 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3005 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3006 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3007 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3008 NULL, // #325 void(void) drawresetcliparea
3013 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3014 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3015 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3016 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3017 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3018 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3019 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3020 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3021 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3022 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3023 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3024 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3025 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3026 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3027 NULL, // #344 vector() getmousepos (EXT_CSQC)
3028 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3029 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3030 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3031 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3032 NULL, // #349 float() isdemo (EXT_CSQC)
3033 VM_isserver, // #350 float() isserver (EXT_CSQC)
3034 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3035 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3036 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3037 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3043 NULL, // #360 float() readbyte (EXT_CSQC)
3044 NULL, // #361 float() readchar (EXT_CSQC)
3045 NULL, // #362 float() readshort (EXT_CSQC)
3046 NULL, // #363 float() readlong (EXT_CSQC)
3047 NULL, // #364 float() readcoord (EXT_CSQC)
3048 NULL, // #365 float() readangle (EXT_CSQC)
3049 NULL, // #366 string() readstring (EXT_CSQC)
3050 NULL, // #367 float() readfloat (EXT_CSQC)
3083 // LordHavoc's range #400-#499
3084 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3085 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3086 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3087 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3088 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3089 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3090 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3091 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3092 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)
3093 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3094 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3095 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3096 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3097 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3098 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3099 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3100 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3101 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3102 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3103 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3104 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3105 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3106 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3107 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3108 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3109 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3110 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3111 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3112 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3113 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3114 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3115 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3116 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3117 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3118 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3119 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3120 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3121 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3122 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3123 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3124 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3125 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3126 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3127 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3128 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
3129 VM_search_end, // #445 void(float handle) search_end (DP_FS_SEARCH)
3130 VM_search_getsize, // #446 float(float handle) search_getsize (DP_FS_SEARCH)
3131 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
3132 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3133 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3134 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3135 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3136 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3137 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3138 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3139 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3140 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3141 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3143 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3144 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3145 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3146 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3147 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3148 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3149 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3150 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3151 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3152 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3153 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3155 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3156 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3157 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3158 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3159 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3160 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3161 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3162 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3163 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3164 VM_strtolower, // #480 string(string s) VM_strtolower : DRESK - Return string as lowercase
3165 VM_strtoupper, // #481 string(string s) VM_strtoupper : DRESK - Return string as uppercase
3186 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3188 void VM_SV_Cmd_Init(void)
3193 void VM_SV_Cmd_Reset(void)