3 //============================================================================
8 char *vm_sv_extensions =
13 "DP_CON_ALIASPARAMETERS "
31 "DP_ENT_CUSTOMCOLORMAP "
32 "DP_ENT_EXTERIORMODELTOCLIENT "
34 "DP_ENT_LOWPRECISION "
37 "DP_GFX_EXTERNALTEXTURES "
38 "DP_GFX_EXTERNALTEXTURES_PERMAP "
40 "DP_GFX_QUAKE3MODELTAGS "
44 "DP_HALFLIFE_MAP_CVAR "
50 "DP_MOVETYPEBOUNCEMISSILE "
52 "DP_QC_ASINACOSATANATAN2TAN "
55 "DP_QC_CVAR_DEFSTRING "
59 "DP_QC_FINDCHAINFLAGS "
60 "DP_QC_FINDCHAINFLOAT "
68 "DP_QC_MULTIPLETEMPSTRINGS "
70 "DP_QC_SINCOSSQRTPOW "
72 "DP_QC_STRING_CASE_FUNCTIONS "
73 "DP_QC_STRINGBUFFERS "
74 "DP_QC_STRINGCOLORFUNCTIONS "
75 "DP_QC_TOKENIZEBYSEPARATOR "
78 "DP_QC_TRACE_MOVETYPE_HITMODEL "
79 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
80 "DP_QC_UNLIMITEDTEMPSTRINGS "
81 "DP_QC_VECTORVECTORS "
87 "DP_SND_DIRECTIONLESSATTNNONE "
96 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
97 "DP_SV_DRAWONLYTOCLIENT "
100 "DP_SV_ENTITYCONTENTSTRANSITION "
101 "DP_SV_ONENTITYNOSPAWNFUNCTION "
102 "DP_SV_MODELFLAGS_AS_EFFECTS "
104 "DP_SV_NODRAWTOCLIENT "
106 "DP_SV_PLAYERPHYSICS "
107 "DP_SV_POINTPARTICLES "
108 "DP_SV_PRECACHEANYTIME "
111 "DP_SV_ROTATINGBMODEL "
114 "DP_SV_WRITEUNTERMINATEDSTRING "
118 "DP_TE_EXPLOSIONRGB "
120 "DP_TE_PARTICLECUBE "
121 "DP_TE_PARTICLERAIN "
122 "DP_TE_PARTICLESNOW "
124 "DP_TE_QUADEFFECTS1 "
127 "DP_TE_STANDARDEFFECTBUILTINS "
128 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
131 //"EXT_CSQC " // not ready yet
133 "KRIMZON_SV_PARSECLIENTCOMMAND "
136 "NEXUIZ_PLAYERMODEL "
138 "PRYDON_CLIENTCURSOR "
139 "TENEBRAE_GFX_DLIGHTS "
150 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.
152 setorigin (entity, origin)
155 static void VM_SV_setorigin (void)
160 VM_SAFEPARMCOUNT(2, VM_setorigin);
162 e = PRVM_G_EDICT(OFS_PARM0);
163 if (e == prog->edicts)
165 VM_Warning("setorigin: can not modify world entity\n");
168 if (e->priv.server->free)
170 VM_Warning("setorigin: can not modify free entity\n");
173 org = PRVM_G_VECTOR(OFS_PARM1);
174 VectorCopy (org, e->fields.server->origin);
175 SV_LinkEdict (e, false);
179 void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
183 for (i=0 ; i<3 ; i++)
185 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
187 // set derived values
188 VectorCopy (min, e->fields.server->mins);
189 VectorCopy (max, e->fields.server->maxs);
190 VectorSubtract (max, min, e->fields.server->size);
192 SV_LinkEdict (e, false);
199 the size box is rotated by the current angle
200 LordHavoc: no it isn't...
202 setsize (entity, minvector, maxvector)
205 static void VM_SV_setsize (void)
210 VM_SAFEPARMCOUNT(3, VM_setsize);
212 e = PRVM_G_EDICT(OFS_PARM0);
213 if (e == prog->edicts)
215 VM_Warning("setsize: can not modify world entity\n");
218 if (e->priv.server->free)
220 VM_Warning("setsize: can not modify free entity\n");
223 min = PRVM_G_VECTOR(OFS_PARM1);
224 max = PRVM_G_VECTOR(OFS_PARM2);
225 SetMinMaxSize (e, min, max, false);
233 setmodel(entity, model)
236 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
237 static void VM_SV_setmodel (void)
243 VM_SAFEPARMCOUNT(2, VM_setmodel);
245 e = PRVM_G_EDICT(OFS_PARM0);
246 if (e == prog->edicts)
248 VM_Warning("setmodel: can not modify world entity\n");
251 if (e->priv.server->free)
253 VM_Warning("setmodel: can not modify free entity\n");
256 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
257 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
258 e->fields.server->modelindex = i;
264 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
265 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
267 SetMinMaxSize (e, quakemins, quakemaxs, true);
270 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
277 single print to a specific client
279 sprint(clientent, value)
282 static void VM_SV_sprint (void)
286 char string[VM_STRINGTEMP_LENGTH];
288 VM_VarString(1, string, sizeof(string));
290 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
292 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
293 // LordHavoc: div0 requested that sprintto world operate like print
300 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
302 VM_Warning("tried to centerprint to a non-client\n");
306 client = svs.clients + entnum-1;
307 if (!client->netconnection)
310 MSG_WriteChar(&client->netconnection->message,svc_print);
311 MSG_WriteString(&client->netconnection->message, string);
319 single print to a specific client
321 centerprint(clientent, value)
324 static void VM_SV_centerprint (void)
328 char string[VM_STRINGTEMP_LENGTH];
330 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
332 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
334 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
336 VM_Warning("tried to centerprint to a non-client\n");
340 client = svs.clients + entnum-1;
341 if (!client->netconnection)
344 VM_VarString(1, string, sizeof(string));
345 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
346 MSG_WriteString(&client->netconnection->message, string);
353 particle(origin, color, count)
356 static void VM_SV_particle (void)
362 VM_SAFEPARMCOUNT(4, VM_SV_particle);
364 org = PRVM_G_VECTOR(OFS_PARM0);
365 dir = PRVM_G_VECTOR(OFS_PARM1);
366 color = PRVM_G_FLOAT(OFS_PARM2);
367 count = PRVM_G_FLOAT(OFS_PARM3);
368 SV_StartParticle (org, dir, (int)color, (int)count);
378 static void VM_SV_ambientsound (void)
382 float vol, attenuation;
385 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
387 pos = PRVM_G_VECTOR (OFS_PARM0);
388 samp = PRVM_G_STRING(OFS_PARM1);
389 vol = PRVM_G_FLOAT(OFS_PARM2);
390 attenuation = PRVM_G_FLOAT(OFS_PARM3);
392 // check to see if samp was properly precached
393 soundnum = SV_SoundIndex(samp, 1);
401 // add an svc_spawnambient command to the level signon packet
404 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
406 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
408 MSG_WriteVector(&sv.signon, pos, sv.protocol);
411 MSG_WriteShort (&sv.signon, soundnum);
413 MSG_WriteByte (&sv.signon, soundnum);
415 MSG_WriteByte (&sv.signon, (int)(vol*255));
416 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
424 Each entity can have eight independant sound sources, like voice,
427 Channel 0 is an auto-allocate channel, the others override anything
428 already running on that entity/channel pair.
430 An attenuation of 0 will play full volume everywhere in the level.
431 Larger attenuations will drop off.
435 static void VM_SV_sound (void)
439 prvm_edict_t *entity;
443 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
445 entity = PRVM_G_EDICT(OFS_PARM0);
446 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
447 sample = PRVM_G_STRING(OFS_PARM2);
448 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
449 attenuation = PRVM_G_FLOAT(OFS_PARM4);
452 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
456 if (volume < 0 || volume > 255)
458 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
462 if (attenuation < 0 || attenuation > 4)
464 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
468 if (channel < 0 || channel > 7)
470 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
474 SV_StartSound (entity, channel, sample, volume, attenuation);
481 Used for use tracing and shot targeting
482 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
483 if the tryents flag is set.
485 traceline (vector1, vector2, movetype, ignore)
488 static void VM_SV_traceline (void)
495 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
497 prog->xfunction->builtinsprofile += 30;
499 v1 = PRVM_G_VECTOR(OFS_PARM0);
500 v2 = PRVM_G_VECTOR(OFS_PARM1);
501 move = (int)PRVM_G_FLOAT(OFS_PARM2);
502 ent = PRVM_G_EDICT(OFS_PARM3);
504 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]))
505 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));
507 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
509 VM_SetTraceGlobals(&trace);
517 Used for use tracing and shot targeting
518 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
519 if the tryents flag is set.
521 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
524 // LordHavoc: added this for my own use, VERY useful, similar to traceline
525 static void VM_SV_tracebox (void)
527 float *v1, *v2, *m1, *m2;
532 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
534 prog->xfunction->builtinsprofile += 30;
536 v1 = PRVM_G_VECTOR(OFS_PARM0);
537 m1 = PRVM_G_VECTOR(OFS_PARM1);
538 m2 = PRVM_G_VECTOR(OFS_PARM2);
539 v2 = PRVM_G_VECTOR(OFS_PARM3);
540 move = (int)PRVM_G_FLOAT(OFS_PARM4);
541 ent = PRVM_G_EDICT(OFS_PARM5);
543 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]))
544 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));
546 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
548 VM_SetTraceGlobals(&trace);
551 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
556 vec3_t original_origin;
557 vec3_t original_velocity;
558 vec3_t original_angles;
559 vec3_t original_avelocity;
563 VectorCopy(tossent->fields.server->origin , original_origin );
564 VectorCopy(tossent->fields.server->velocity , original_velocity );
565 VectorCopy(tossent->fields.server->angles , original_angles );
566 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
568 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
569 if (val != NULL && val->_float != 0)
570 gravity = val->_float;
573 gravity *= sv_gravity.value * 0.05;
575 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
577 SV_CheckVelocity (tossent);
578 tossent->fields.server->velocity[2] -= gravity;
579 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
580 VectorScale (tossent->fields.server->velocity, 0.05, move);
581 VectorAdd (tossent->fields.server->origin, move, end);
582 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
583 VectorCopy (trace.endpos, tossent->fields.server->origin);
585 if (trace.fraction < 1)
589 VectorCopy(original_origin , tossent->fields.server->origin );
590 VectorCopy(original_velocity , tossent->fields.server->velocity );
591 VectorCopy(original_angles , tossent->fields.server->angles );
592 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
597 static void VM_SV_tracetoss (void)
601 prvm_edict_t *ignore;
603 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
605 prog->xfunction->builtinsprofile += 600;
607 ent = PRVM_G_EDICT(OFS_PARM0);
608 if (ent == prog->edicts)
610 VM_Warning("tracetoss: can not use world entity\n");
613 ignore = PRVM_G_EDICT(OFS_PARM1);
615 trace = SV_Trace_Toss (ent, ignore);
617 VM_SetTraceGlobals(&trace);
620 //============================================================================
622 static int checkpvsbytes;
623 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
625 static int VM_SV_newcheckclient (int check)
631 // cycle to the next one
633 check = bound(1, check, svs.maxclients);
634 if (check == svs.maxclients)
642 prog->xfunction->builtinsprofile++;
644 if (i == svs.maxclients+1)
646 // look up the client's edict
647 ent = PRVM_EDICT_NUM(i);
648 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
649 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
651 // found a valid client (possibly the same one again)
655 // get the PVS for the entity
656 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
658 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
659 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
668 Returns a client (or object that has a client enemy) that would be a
671 If there is more than one valid option, they are cycled each frame
673 If (self.origin + self.viewofs) is not in the PVS of the current target,
674 it is not returned at all.
679 int c_invis, c_notvis;
680 static void VM_SV_checkclient (void)
682 prvm_edict_t *ent, *self;
685 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
687 // find a new check if on a new frame
688 if (sv.time - sv.lastchecktime >= 0.1)
690 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
691 sv.lastchecktime = sv.time;
694 // return check if it might be visible
695 ent = PRVM_EDICT_NUM(sv.lastcheck);
696 if (ent->priv.server->free || ent->fields.server->health <= 0)
698 VM_RETURN_EDICT(prog->edicts);
702 // if current entity can't possibly see the check entity, return 0
703 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
704 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
705 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
708 VM_RETURN_EDICT(prog->edicts);
712 // might be able to see it
714 VM_RETURN_EDICT(ent);
717 //============================================================================
724 Sends text over to the client's execution buffer
726 stuffcmd (clientent, value, ...)
729 static void VM_SV_stuffcmd (void)
733 char string[VM_STRINGTEMP_LENGTH];
735 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
737 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
738 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
740 VM_Warning("Can't stuffcmd to a non-client\n");
744 VM_VarString(1, string, sizeof(string));
747 host_client = svs.clients + entnum-1;
748 Host_ClientCommands ("%s", string);
756 Returns a chain of entities that have origins within a spherical area
758 findradius (origin, radius)
761 static void VM_SV_findradius (void)
763 prvm_edict_t *ent, *chain;
764 vec_t radius, radius2;
765 vec3_t org, eorg, mins, maxs;
768 prvm_edict_t *touchedicts[MAX_EDICTS];
770 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
772 chain = (prvm_edict_t *)prog->edicts;
774 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
775 radius = PRVM_G_FLOAT(OFS_PARM1);
776 radius2 = radius * radius;
778 mins[0] = org[0] - (radius + 1);
779 mins[1] = org[1] - (radius + 1);
780 mins[2] = org[2] - (radius + 1);
781 maxs[0] = org[0] + (radius + 1);
782 maxs[1] = org[1] + (radius + 1);
783 maxs[2] = org[2] + (radius + 1);
784 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
785 if (numtouchedicts > MAX_EDICTS)
787 // this never happens
788 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
789 numtouchedicts = MAX_EDICTS;
791 for (i = 0;i < numtouchedicts;i++)
793 ent = touchedicts[i];
794 prog->xfunction->builtinsprofile++;
795 // Quake did not return non-solid entities but darkplaces does
796 // (note: this is the reason you can't blow up fallen zombies)
797 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
799 // LordHavoc: compare against bounding box rather than center so it
800 // doesn't miss large objects, and use DotProduct instead of Length
801 // for a major speedup
802 VectorSubtract(org, ent->fields.server->origin, eorg);
803 if (sv_gameplayfix_findradiusdistancetobox.integer)
805 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
806 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
807 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
810 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
811 if (DotProduct(eorg, eorg) < radius2)
813 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
818 VM_RETURN_EDICT(chain);
821 static void VM_SV_precache_sound (void)
823 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
824 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
825 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
828 static void VM_SV_precache_model (void)
830 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
831 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
832 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
839 float(float yaw, float dist[, settrace]) walkmove
842 static void VM_SV_walkmove (void)
851 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
853 // assume failure if it returns early
854 PRVM_G_FLOAT(OFS_RETURN) = 0;
856 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
857 if (ent == prog->edicts)
859 VM_Warning("walkmove: can not modify world entity\n");
862 if (ent->priv.server->free)
864 VM_Warning("walkmove: can not modify free entity\n");
867 yaw = PRVM_G_FLOAT(OFS_PARM0);
868 dist = PRVM_G_FLOAT(OFS_PARM1);
869 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
871 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
874 yaw = yaw*M_PI*2 / 360;
876 move[0] = cos(yaw)*dist;
877 move[1] = sin(yaw)*dist;
880 // save program state, because SV_movestep may call other progs
881 oldf = prog->xfunction;
882 oldself = prog->globals.server->self;
884 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
887 // restore program state
888 prog->xfunction = oldf;
889 prog->globals.server->self = oldself;
899 static void VM_SV_droptofloor (void)
905 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
907 // assume failure if it returns early
908 PRVM_G_FLOAT(OFS_RETURN) = 0;
910 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
911 if (ent == prog->edicts)
913 VM_Warning("droptofloor: can not modify world entity\n");
916 if (ent->priv.server->free)
918 VM_Warning("droptofloor: can not modify free entity\n");
922 VectorCopy (ent->fields.server->origin, end);
925 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
927 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
929 if (trace.fraction < 1)
930 VectorCopy (trace.endpos, ent->fields.server->origin);
931 SV_LinkEdict (ent, false);
932 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
933 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
934 PRVM_G_FLOAT(OFS_RETURN) = 1;
935 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
936 ent->priv.server->suspendedinairflag = true;
944 void(float style, string value) lightstyle
947 static void VM_SV_lightstyle (void)
954 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
956 style = (int)PRVM_G_FLOAT(OFS_PARM0);
957 val = PRVM_G_STRING(OFS_PARM1);
959 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
960 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
963 // change the string in sv
964 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
966 // send message to all clients on this server
967 if (sv.state != ss_active)
970 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
972 if (client->active && client->netconnection)
974 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
975 MSG_WriteChar (&client->netconnection->message,style);
976 MSG_WriteString (&client->netconnection->message, val);
986 static void VM_SV_checkbottom (void)
988 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
989 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
997 static void VM_SV_pointcontents (void)
999 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1000 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1007 Pick a vector for the player to shoot along
1008 vector aim(entity, missilespeed)
1011 static void VM_SV_aim (void)
1013 prvm_edict_t *ent, *check, *bestent;
1014 vec3_t start, dir, end, bestdir;
1017 float dist, bestdist;
1020 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1022 // assume failure if it returns early
1023 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1024 // if sv_aim is so high it can't possibly accept anything, skip out early
1025 if (sv_aim.value >= 1)
1028 ent = PRVM_G_EDICT(OFS_PARM0);
1029 if (ent == prog->edicts)
1031 VM_Warning("aim: can not use world entity\n");
1034 if (ent->priv.server->free)
1036 VM_Warning("aim: can not use free entity\n");
1039 speed = PRVM_G_FLOAT(OFS_PARM1);
1041 VectorCopy (ent->fields.server->origin, start);
1044 // try sending a trace straight
1045 VectorCopy (prog->globals.server->v_forward, dir);
1046 VectorMA (start, 2048, dir, end);
1047 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1048 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1049 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1051 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1056 // try all possible entities
1057 VectorCopy (dir, bestdir);
1058 bestdist = sv_aim.value;
1061 check = PRVM_NEXT_EDICT(prog->edicts);
1062 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1064 prog->xfunction->builtinsprofile++;
1065 if (check->fields.server->takedamage != DAMAGE_AIM)
1069 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1070 continue; // don't aim at teammate
1071 for (j=0 ; j<3 ; j++)
1072 end[j] = check->fields.server->origin[j]
1073 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1074 VectorSubtract (end, start, dir);
1075 VectorNormalize (dir);
1076 dist = DotProduct (dir, prog->globals.server->v_forward);
1077 if (dist < bestdist)
1078 continue; // to far to turn
1079 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1080 if (tr.ent == check)
1081 { // can shoot at this one
1089 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1090 dist = DotProduct (dir, prog->globals.server->v_forward);
1091 VectorScale (prog->globals.server->v_forward, dist, end);
1093 VectorNormalize (end);
1094 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1098 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1103 ===============================================================================
1107 ===============================================================================
1110 #define MSG_BROADCAST 0 // unreliable to all
1111 #define MSG_ONE 1 // reliable to one (msg_entity)
1112 #define MSG_ALL 2 // reliable to all
1113 #define MSG_INIT 3 // write to the init string
1114 #define MSG_ENTITY 5
1116 sizebuf_t *WriteDest (void)
1122 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1126 return &sv.datagram;
1129 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1130 entnum = PRVM_NUM_FOR_EDICT(ent);
1131 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1133 VM_Warning ("WriteDest: tried to write to non-client\n");
1134 return &sv.reliable_datagram;
1137 return &svs.clients[entnum-1].netconnection->message;
1140 VM_Warning ("WriteDest: bad destination\n");
1142 return &sv.reliable_datagram;
1148 return sv.writeentitiestoclient_msg;
1154 static void VM_SV_WriteByte (void)
1156 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1157 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1160 static void VM_SV_WriteChar (void)
1162 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1163 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1166 static void VM_SV_WriteShort (void)
1168 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1169 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1172 static void VM_SV_WriteLong (void)
1174 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1175 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1178 static void VM_SV_WriteAngle (void)
1180 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1181 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1184 static void VM_SV_WriteCoord (void)
1186 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1187 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1190 static void VM_SV_WriteString (void)
1192 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1193 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1196 static void VM_SV_WriteUnterminatedString (void)
1198 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1199 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1203 static void VM_SV_WriteEntity (void)
1205 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1206 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1209 //////////////////////////////////////////////////////////
1211 static void VM_SV_makestatic (void)
1216 // allow 0 parameters due to an id1 qc bug in which this function is used
1217 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1218 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1220 if (prog->argc >= 1)
1221 ent = PRVM_G_EDICT(OFS_PARM0);
1223 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1224 if (ent == prog->edicts)
1226 VM_Warning("makestatic: can not modify world entity\n");
1229 if (ent->priv.server->free)
1231 VM_Warning("makestatic: can not modify free entity\n");
1236 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1241 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1242 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1243 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1247 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1248 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1249 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1252 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1253 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1254 for (i=0 ; i<3 ; i++)
1256 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1257 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1260 // throw the entity away now
1264 //=============================================================================
1271 static void VM_SV_setspawnparms (void)
1277 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1279 ent = PRVM_G_EDICT(OFS_PARM0);
1280 i = PRVM_NUM_FOR_EDICT(ent);
1281 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1283 Con_Print("tried to setspawnparms on a non-client\n");
1287 // copy spawn parms out of the client_t
1288 client = svs.clients + i-1;
1289 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1290 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1297 Returns a color vector indicating the lighting at the requested point.
1299 (Internal Operation note: actually measures the light beneath the point, just like
1300 the model lighting on the client)
1305 static void VM_SV_getlight (void)
1307 vec3_t ambientcolor, diffusecolor, diffusenormal;
1309 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1310 p = PRVM_G_VECTOR(OFS_PARM0);
1311 VectorClear(ambientcolor);
1312 VectorClear(diffusecolor);
1313 VectorClear(diffusenormal);
1314 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1315 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1316 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1321 unsigned char type; // 1/2/8 or other value if isn't used
1325 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1326 static int vm_customstats_last;
1328 void VM_CustomStats_Clear (void)
1332 Z_Free(vm_customstats);
1333 vm_customstats = NULL;
1334 vm_customstats_last = -1;
1338 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1346 for(i=0; i<vm_customstats_last+1 ;i++)
1348 if(!vm_customstats[i].type)
1350 switch(vm_customstats[i].type)
1352 //string as 16 bytes
1355 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1356 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1357 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1358 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1359 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1361 //float field sent as-is
1363 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1365 //integer value of float field
1367 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1375 // void(float index, float type, .void field) SV_AddStat = #232;
1376 // Set up an auto-sent player stat.
1377 // Client's get thier own fields sent to them. Index may not be less than 32.
1378 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1379 // 1: string (4 stats carrying a total of 16 charactures)
1380 // 2: float (one stat, float converted to an integer for transportation)
1381 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1382 static void VM_SV_AddStat (void)
1387 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1391 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1394 VM_Warning("PF_SV_AddStat: not enough memory\n");
1398 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1399 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1400 off = PRVM_G_INT (OFS_PARM2);
1405 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1408 if(i >= (MAX_CL_STATS-32))
1410 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1413 if(i > (MAX_CL_STATS-32-4) && type == 1)
1415 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1418 vm_customstats[i].type = type;
1419 vm_customstats[i].fieldoffset = off;
1420 if(vm_customstats_last < i)
1421 vm_customstats_last = i;
1428 copies data from one entity to another
1430 copyentity(src, dst)
1433 static void VM_SV_copyentity (void)
1435 prvm_edict_t *in, *out;
1436 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1437 in = PRVM_G_EDICT(OFS_PARM0);
1438 if (in == prog->edicts)
1440 VM_Warning("copyentity: can not read world entity\n");
1443 if (in->priv.server->free)
1445 VM_Warning("copyentity: can not read free entity\n");
1448 out = PRVM_G_EDICT(OFS_PARM1);
1449 if (out == prog->edicts)
1451 VM_Warning("copyentity: can not modify world entity\n");
1454 if (out->priv.server->free)
1456 VM_Warning("copyentity: can not modify free entity\n");
1459 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1460 SV_LinkEdict(out, false);
1468 sets the color of a client and broadcasts the update to all connected clients
1470 setcolor(clientent, value)
1473 static void VM_SV_setcolor (void)
1479 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1480 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1481 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1483 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1485 Con_Print("tried to setcolor a non-client\n");
1489 client = svs.clients + entnum-1;
1492 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1494 client->edict->fields.server->team = (i & 15) + 1;
1497 if (client->old_colors != client->colors)
1499 client->old_colors = client->colors;
1500 // send notification to all clients
1501 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1502 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1503 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1511 effect(origin, modelname, startframe, framecount, framerate)
1514 static void VM_SV_effect (void)
1518 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1519 s = PRVM_G_STRING(OFS_PARM1);
1522 VM_Warning("effect: no model specified\n");
1526 i = SV_ModelIndex(s, 1);
1529 VM_Warning("effect: model not precached\n");
1533 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1535 VM_Warning("effect: framecount < 1\n");
1539 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1541 VM_Warning("effect: framerate < 1\n");
1545 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));
1548 static void VM_SV_te_blood (void)
1550 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1551 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1553 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1554 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1556 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1557 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1558 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1560 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1561 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1562 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1564 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1565 SV_FlushBroadcastMessages();
1568 static void VM_SV_te_bloodshower (void)
1570 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1571 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1573 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1574 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1576 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1577 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1578 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1580 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1581 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1582 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1584 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1586 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1587 SV_FlushBroadcastMessages();
1590 static void VM_SV_te_explosionrgb (void)
1592 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1593 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1594 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1596 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1597 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1598 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1600 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1601 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1602 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1603 SV_FlushBroadcastMessages();
1606 static void VM_SV_te_particlecube (void)
1608 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1609 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1611 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1612 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1614 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1615 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1616 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1618 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1619 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1620 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1622 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1623 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1624 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1626 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1628 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1629 // gravity true/false
1630 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1632 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1633 SV_FlushBroadcastMessages();
1636 static void VM_SV_te_particlerain (void)
1638 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1639 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1641 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1642 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1644 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1645 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1646 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1648 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1649 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1650 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1652 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1653 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1654 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1656 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1658 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1659 SV_FlushBroadcastMessages();
1662 static void VM_SV_te_particlesnow (void)
1664 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1665 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1667 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1668 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1671 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1672 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1674 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1675 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1676 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1678 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1679 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1680 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1682 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1684 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1685 SV_FlushBroadcastMessages();
1688 static void VM_SV_te_spark (void)
1690 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1691 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1693 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1694 MSG_WriteByte(&sv.datagram, TE_SPARK);
1696 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1697 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1698 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1700 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1701 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1702 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1704 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1705 SV_FlushBroadcastMessages();
1708 static void VM_SV_te_gunshotquad (void)
1710 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1711 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1712 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1714 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1715 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1716 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1717 SV_FlushBroadcastMessages();
1720 static void VM_SV_te_spikequad (void)
1722 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1723 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1724 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1726 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1727 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1728 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1729 SV_FlushBroadcastMessages();
1732 static void VM_SV_te_superspikequad (void)
1734 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1735 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1736 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1738 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1739 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1740 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1741 SV_FlushBroadcastMessages();
1744 static void VM_SV_te_explosionquad (void)
1746 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1747 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1748 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1750 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1751 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1752 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1753 SV_FlushBroadcastMessages();
1756 static void VM_SV_te_smallflash (void)
1758 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1759 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1760 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1762 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1763 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1764 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1765 SV_FlushBroadcastMessages();
1768 static void VM_SV_te_customflash (void)
1770 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1771 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1773 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1774 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1776 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1777 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1778 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1780 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1782 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1784 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1785 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1786 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1787 SV_FlushBroadcastMessages();
1790 static void VM_SV_te_gunshot (void)
1792 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1793 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1794 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1796 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1797 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1798 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1799 SV_FlushBroadcastMessages();
1802 static void VM_SV_te_spike (void)
1804 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1805 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1806 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1808 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1809 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1810 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1811 SV_FlushBroadcastMessages();
1814 static void VM_SV_te_superspike (void)
1816 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1817 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1818 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1820 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1821 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1822 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1823 SV_FlushBroadcastMessages();
1826 static void VM_SV_te_explosion (void)
1828 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1829 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1830 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1833 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1834 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1835 SV_FlushBroadcastMessages();
1838 static void VM_SV_te_tarexplosion (void)
1840 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1841 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1842 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1844 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1845 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1846 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1847 SV_FlushBroadcastMessages();
1850 static void VM_SV_te_wizspike (void)
1852 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1853 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1854 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1856 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1857 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1858 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1859 SV_FlushBroadcastMessages();
1862 static void VM_SV_te_knightspike (void)
1864 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1865 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1866 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1871 SV_FlushBroadcastMessages();
1874 static void VM_SV_te_lavasplash (void)
1876 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1877 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1878 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1880 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1881 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1882 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1883 SV_FlushBroadcastMessages();
1886 static void VM_SV_te_teleport (void)
1888 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1889 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1890 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1892 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1893 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1894 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1895 SV_FlushBroadcastMessages();
1898 static void VM_SV_te_explosion2 (void)
1900 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1901 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1902 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1904 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1905 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1906 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1908 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1909 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1910 SV_FlushBroadcastMessages();
1913 static void VM_SV_te_lightning1 (void)
1915 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1916 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1917 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1919 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1921 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1922 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1923 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1925 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1926 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1927 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1928 SV_FlushBroadcastMessages();
1931 static void VM_SV_te_lightning2 (void)
1933 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1934 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1935 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1937 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1939 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1940 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1941 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1943 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1944 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1945 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1946 SV_FlushBroadcastMessages();
1949 static void VM_SV_te_lightning3 (void)
1951 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
1952 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1953 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
1955 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1957 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1958 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1959 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1961 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1962 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1963 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1964 SV_FlushBroadcastMessages();
1967 static void VM_SV_te_beam (void)
1969 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
1970 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1971 MSG_WriteByte(&sv.datagram, TE_BEAM);
1973 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1976 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1977 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1979 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1980 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1981 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1982 SV_FlushBroadcastMessages();
1985 static void VM_SV_te_plasmaburn (void)
1987 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
1988 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1989 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
1990 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1991 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1992 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1993 SV_FlushBroadcastMessages();
1996 static void VM_SV_te_flamejet (void)
1998 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
1999 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2000 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2002 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2003 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2004 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2006 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2007 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2008 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2010 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2011 SV_FlushBroadcastMessages();
2014 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2017 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2019 bestdist = 1000000000;
2021 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2023 // clip original point to each triangle of the surface and find the
2024 // triangle that is closest
2025 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2026 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2027 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2028 TriangleNormal(v[0], v[1], v[2], facenormal);
2029 VectorNormalize(facenormal);
2030 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2031 VectorMA(p, offsetdist, facenormal, temp);
2032 for (j = 0, k = 2;j < 3;k = j, j++)
2034 VectorSubtract(v[k], v[j], edgenormal);
2035 CrossProduct(edgenormal, facenormal, sidenormal);
2036 VectorNormalize(sidenormal);
2037 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2039 VectorMA(temp, offsetdist, sidenormal, temp);
2041 dist = VectorDistance2(temp, p);
2042 if (bestdist > dist)
2045 VectorCopy(temp, out);
2050 static model_t *getmodel(prvm_edict_t *ed)
2053 if (!ed || ed->priv.server->free)
2055 modelindex = (int)ed->fields.server->modelindex;
2056 if (modelindex < 1 || modelindex >= MAX_MODELS)
2058 return sv.models[modelindex];
2061 static msurface_t *getsurface(model_t *model, int surfacenum)
2063 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2065 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2069 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2070 static void VM_SV_getsurfacenumpoints(void)
2073 msurface_t *surface;
2074 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2075 // return 0 if no such surface
2076 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2078 PRVM_G_FLOAT(OFS_RETURN) = 0;
2082 // note: this (incorrectly) assumes it is a simple polygon
2083 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2085 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2086 static void VM_SV_getsurfacepoint(void)
2090 msurface_t *surface;
2092 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2093 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2094 ed = PRVM_G_EDICT(OFS_PARM0);
2095 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2097 // note: this (incorrectly) assumes it is a simple polygon
2098 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2099 if (pointnum < 0 || pointnum >= surface->num_vertices)
2101 // FIXME: implement rotation/scaling
2102 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2104 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2105 static void VM_SV_getsurfacenormal(void)
2108 msurface_t *surface;
2110 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2111 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2112 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2114 // FIXME: implement rotation/scaling
2115 // note: this (incorrectly) assumes it is a simple polygon
2116 // note: this only returns the first triangle, so it doesn't work very
2117 // well for curved surfaces or arbitrary meshes
2118 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);
2119 VectorNormalize(normal);
2120 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2122 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2123 static void VM_SV_getsurfacetexture(void)
2126 msurface_t *surface;
2127 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2128 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2129 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2131 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2133 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2134 static void VM_SV_getsurfacenearpoint(void)
2136 int surfacenum, best;
2138 vec_t dist, bestdist;
2141 msurface_t *surface;
2143 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2144 PRVM_G_FLOAT(OFS_RETURN) = -1;
2145 ed = PRVM_G_EDICT(OFS_PARM0);
2146 point = PRVM_G_VECTOR(OFS_PARM1);
2148 if (!ed || ed->priv.server->free)
2150 model = getmodel(ed);
2151 if (!model || !model->num_surfaces)
2154 // FIXME: implement rotation/scaling
2155 VectorSubtract(point, ed->fields.server->origin, p);
2157 bestdist = 1000000000;
2158 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2160 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2161 // first see if the nearest point on the surface's box is closer than the previous match
2162 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2163 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2164 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2165 dist = VectorLength2(clipped);
2166 if (dist < bestdist)
2168 // it is, check the nearest point on the actual geometry
2169 clippointtosurface(model, surface, p, clipped);
2170 VectorSubtract(clipped, p, clipped);
2171 dist += VectorLength2(clipped);
2172 if (dist < bestdist)
2174 // that's closer too, store it as the best match
2180 PRVM_G_FLOAT(OFS_RETURN) = best;
2182 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2183 static void VM_SV_getsurfaceclippedpoint(void)
2187 msurface_t *surface;
2189 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2190 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2191 ed = PRVM_G_EDICT(OFS_PARM0);
2192 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2194 // FIXME: implement rotation/scaling
2195 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2196 clippointtosurface(model, surface, p, out);
2197 // FIXME: implement rotation/scaling
2198 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2201 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2202 //this function originally written by KrimZon, made shorter by LordHavoc
2203 static void VM_SV_clientcommand (void)
2205 client_t *temp_client;
2207 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2209 //find client for this entity
2210 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2211 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2213 Con_Print("PF_clientcommand: entity is not a client\n");
2217 temp_client = host_client;
2218 host_client = svs.clients + i;
2219 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2220 host_client = temp_client;
2223 //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)
2224 static void VM_SV_setattachment (void)
2226 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2227 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2228 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2232 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2234 if (e == prog->edicts)
2236 VM_Warning("setattachment: can not modify world entity\n");
2239 if (e->priv.server->free)
2241 VM_Warning("setattachment: can not modify free entity\n");
2245 if (tagentity == NULL)
2246 tagentity = prog->edicts;
2248 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2250 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2252 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2255 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2257 modelindex = (int)tagentity->fields.server->modelindex;
2258 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2260 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2262 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);
2265 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));
2269 /////////////////////////////////////////
2270 // DP_MD3_TAGINFO extension coded by VorteX
2272 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2277 i = (int)e->fields.server->modelindex;
2278 if (i < 1 || i >= MAX_MODELS)
2280 model = sv.models[i];
2282 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2285 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2287 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2291 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);
2293 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);
2296 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2302 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2303 && (model = sv.models[(int)ent->fields.server->modelindex])
2304 && model->animscenes)
2306 // if model has wrong frame, engine automatically switches to model first frame
2307 frame = (int)ent->fields.server->frame;
2308 if (frame < 0 || frame >= model->numframes)
2310 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2312 *out = identitymatrix;
2316 // Warnings/errors code:
2317 // 0 - normal (everything all-right)
2320 // 3 - null or non-precached model
2321 // 4 - no tags with requested index
2322 // 5 - runaway loop at attachment chain
2323 extern cvar_t cl_bob;
2324 extern cvar_t cl_bobcycle;
2325 extern cvar_t cl_bobup;
2326 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2330 int modelindex, attachloop;
2331 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2334 *out = identitymatrix; // warnings and errors return identical matrix
2336 if (ent == prog->edicts)
2338 if (ent->priv.server->free)
2341 modelindex = (int)ent->fields.server->modelindex;
2342 if (modelindex <= 0 || modelindex > MAX_MODELS)
2345 model = sv.models[modelindex];
2347 tagmatrix = identitymatrix;
2348 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2352 if (attachloop >= 256) // prevent runaway looping
2354 // apply transformation by child's tagindex on parent entity and then
2355 // by parent entity itself
2356 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2357 if (ret && attachloop == 0)
2359 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2360 SV_GetEntityMatrix(ent, &entitymatrix, false);
2361 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2362 // next iteration we process the parent entity
2363 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2365 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2366 ent = PRVM_EDICT_NUM(val->edict);
2373 // RENDER_VIEWMODEL magic
2374 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2376 Matrix4x4_Copy(&tagmatrix, out);
2377 ent = PRVM_EDICT_NUM(val->edict);
2379 SV_GetEntityMatrix(ent, &entitymatrix, true);
2380 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2383 // Cl_bob, ported from rendering code
2384 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2387 // LordHavoc: this code is *weird*, but not replacable (I think it
2388 // should be done in QC on the server, but oh well, quake is quake)
2389 // LordHavoc: figured out bobup: the time at which the sin is at 180
2390 // degrees (which allows lengthening or squishing the peak or valley)
2391 cycle = sv.time/cl_bobcycle.value;
2392 cycle -= (int)cycle;
2393 if (cycle < cl_bobup.value)
2394 cycle = sin(M_PI * cycle / cl_bobup.value);
2396 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2397 // bob is proportional to velocity in the xy plane
2398 // (don't count Z, or jumping messes it up)
2399 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;
2400 bob = bob*0.3 + bob*0.7*cycle;
2401 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2408 //float(entity ent, string tagname) gettagindex;
2410 static void VM_SV_gettagindex (void)
2413 const char *tag_name;
2414 int modelindex, tag_index;
2416 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2418 ent = PRVM_G_EDICT(OFS_PARM0);
2419 tag_name = PRVM_G_STRING(OFS_PARM1);
2421 if (ent == prog->edicts)
2423 VM_Warning("gettagindex: can't affect world entity\n");
2426 if (ent->priv.server->free)
2428 VM_Warning("gettagindex: can't affect free entity\n");
2432 modelindex = (int)ent->fields.server->modelindex;
2434 if (modelindex <= 0 || modelindex > MAX_MODELS)
2435 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2438 tag_index = SV_GetTagIndex(ent, tag_name);
2440 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2442 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2445 //vector(entity ent, float tagindex) gettaginfo;
2446 static void VM_SV_gettaginfo (void)
2450 matrix4x4_t tag_matrix;
2453 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2455 e = PRVM_G_EDICT(OFS_PARM0);
2456 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2458 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2459 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2464 VM_Warning("gettagindex: can't affect world entity\n");
2467 VM_Warning("gettagindex: can't affect free entity\n");
2470 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2473 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2476 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2481 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2482 static void VM_SV_dropclient (void)
2485 client_t *oldhostclient;
2486 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2487 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2488 if (clientnum < 0 || clientnum >= svs.maxclients)
2490 VM_Warning("dropclient: not a client\n");
2493 if (!svs.clients[clientnum].active)
2495 VM_Warning("dropclient: that client slot is not connected\n");
2498 oldhostclient = host_client;
2499 host_client = svs.clients + clientnum;
2500 SV_DropClient(false);
2501 host_client = oldhostclient;
2504 //entity() spawnclient (DP_SV_BOTCLIENT)
2505 static void VM_SV_spawnclient (void)
2509 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2510 prog->xfunction->builtinsprofile += 2;
2512 for (i = 0;i < svs.maxclients;i++)
2514 if (!svs.clients[i].active)
2516 prog->xfunction->builtinsprofile += 100;
2517 SV_ConnectClient (i, NULL);
2518 // this has to be set or else ClientDisconnect won't be called
2519 // we assume the qc will call ClientConnect...
2520 svs.clients[i].clientconnectcalled = true;
2521 ed = PRVM_EDICT_NUM(i + 1);
2525 VM_RETURN_EDICT(ed);
2528 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2529 static void VM_SV_clienttype (void)
2532 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2533 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2534 if (clientnum < 0 || clientnum >= svs.maxclients)
2535 PRVM_G_FLOAT(OFS_RETURN) = 3;
2536 else if (!svs.clients[clientnum].active)
2537 PRVM_G_FLOAT(OFS_RETURN) = 0;
2538 else if (svs.clients[clientnum].netconnection)
2539 PRVM_G_FLOAT(OFS_RETURN) = 1;
2541 PRVM_G_FLOAT(OFS_RETURN) = 2;
2548 string(string key) serverkey
2551 void VM_SV_serverkey(void)
2553 char string[VM_STRINGTEMP_LENGTH];
2554 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2555 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2556 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2559 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2560 static void VM_SV_setmodelindex (void)
2565 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2567 e = PRVM_G_EDICT(OFS_PARM0);
2568 if (e == prog->edicts)
2570 VM_Warning("setmodelindex: can not modify world entity\n");
2573 if (e->priv.server->free)
2575 VM_Warning("setmodelindex: can not modify free entity\n");
2578 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2579 if (i <= 0 || i > MAX_MODELS)
2581 VM_Warning("setmodelindex: invalid modelindex\n");
2584 if (!sv.model_precache[i][0])
2586 VM_Warning("setmodelindex: model not precached\n");
2590 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2591 e->fields.server->modelindex = i;
2597 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2598 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2600 SetMinMaxSize (e, quakemins, quakemaxs, true);
2603 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2606 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2607 static void VM_SV_modelnameforindex (void)
2610 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2612 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2614 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2615 if (i <= 0 || i > MAX_MODELS)
2617 VM_Warning("modelnameforindex: invalid modelindex\n");
2620 if (!sv.model_precache[i][0])
2622 VM_Warning("modelnameforindex: model not precached\n");
2626 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2629 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2630 static void VM_SV_particleeffectnum (void)
2633 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2634 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2637 PRVM_G_FLOAT(OFS_RETURN) = i;
2640 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2641 static void VM_SV_trailparticles (void)
2643 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2645 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2646 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2647 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2648 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2649 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2650 SV_FlushBroadcastMessages();
2653 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2654 static void VM_SV_pointparticles (void)
2656 int effectnum, count;
2658 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2659 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2660 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2661 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2662 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2663 if (count == 1 && !VectorLength2(vel))
2666 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2667 MSG_WriteShort(&sv.datagram, effectnum);
2668 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2672 // 1+2+12+12+2=29 bytes
2673 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2674 MSG_WriteShort(&sv.datagram, effectnum);
2675 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2676 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2677 MSG_WriteShort(&sv.datagram, count);
2680 SV_FlushBroadcastMessages();
2683 prvm_builtin_t vm_sv_builtins[] = {
2684 NULL, // #0 NULL function (not callable) (QUAKE)
2685 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2686 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2687 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2688 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2689 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2690 VM_break, // #6 void() break (QUAKE)
2691 VM_random, // #7 float() random (QUAKE)
2692 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2693 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2694 VM_error, // #10 void(string e) error (QUAKE)
2695 VM_objerror, // #11 void(string e) objerror (QUAKE)
2696 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2697 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2698 VM_spawn, // #14 entity() spawn (QUAKE)
2699 VM_remove, // #15 void(entity e) remove (QUAKE)
2700 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2701 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2702 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2703 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2704 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2705 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2706 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2707 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2708 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2709 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2710 VM_ftos, // #26 string(float f) ftos (QUAKE)
2711 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2712 VM_coredump, // #28 void() coredump (QUAKE)
2713 VM_traceon, // #29 void() traceon (QUAKE)
2714 VM_traceoff, // #30 void() traceoff (QUAKE)
2715 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2716 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2717 NULL, // #33 (QUAKE)
2718 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2719 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2720 VM_rint, // #36 float(float v) rint (QUAKE)
2721 VM_floor, // #37 float(float v) floor (QUAKE)
2722 VM_ceil, // #38 float(float v) ceil (QUAKE)
2723 NULL, // #39 (QUAKE)
2724 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2725 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2726 NULL, // #42 (QUAKE)
2727 VM_fabs, // #43 float(float f) fabs (QUAKE)
2728 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2729 VM_cvar, // #45 float(string s) cvar (QUAKE)
2730 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2731 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2732 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2733 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2734 NULL, // #50 (QUAKE)
2735 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2736 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2737 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2738 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2739 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2740 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2741 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2742 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2743 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2744 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2745 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2746 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2747 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2748 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2749 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2750 NULL, // #66 (QUAKE)
2751 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2752 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2753 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2754 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2755 NULL, // #71 (QUAKE)
2756 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2757 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2758 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2759 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2760 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2761 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2762 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2763 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2764 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2765 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2766 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2767 NULL, // #83 (QUAKE)
2768 NULL, // #84 (QUAKE)
2769 NULL, // #85 (QUAKE)
2770 NULL, // #86 (QUAKE)
2771 NULL, // #87 (QUAKE)
2772 NULL, // #88 (QUAKE)
2773 NULL, // #89 (QUAKE)
2774 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2775 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2776 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2777 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2778 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2779 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2780 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2781 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2782 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2783 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2784 // FrikaC and Telejano range #100-#199
2795 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2796 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2797 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2798 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2799 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2800 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2801 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2802 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2803 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2804 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2885 // FTEQW range #200-#299
2904 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2907 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
2908 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2909 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2910 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
2911 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
2912 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
2913 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
2914 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2915 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
2916 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
2918 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
2986 // CSQC range #300-#399
2987 NULL, // #300 void() clearscene (EXT_CSQC)
2988 NULL, // #301 void(float mask) addentities (EXT_CSQC)
2989 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
2990 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
2991 NULL, // #304 void() renderscene (EXT_CSQC)
2992 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
2993 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
2994 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
2995 NULL, // #308 void() R_EndPolygon
2997 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
2998 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3002 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3003 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3004 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3005 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3006 NULL, // #319 void(string name) freepic (EXT_CSQC)
3007 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3008 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3009 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3010 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3011 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3012 NULL, // #325 void(void) drawresetcliparea
3017 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3018 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3019 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3020 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3021 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3022 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3023 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3024 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3025 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3026 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3027 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3028 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3029 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3030 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3031 NULL, // #344 vector() getmousepos (EXT_CSQC)
3032 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3033 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3034 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3035 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3036 NULL, // #349 float() isdemo (EXT_CSQC)
3037 VM_isserver, // #350 float() isserver (EXT_CSQC)
3038 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3039 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3040 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3041 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3047 NULL, // #360 float() readbyte (EXT_CSQC)
3048 NULL, // #361 float() readchar (EXT_CSQC)
3049 NULL, // #362 float() readshort (EXT_CSQC)
3050 NULL, // #363 float() readlong (EXT_CSQC)
3051 NULL, // #364 float() readcoord (EXT_CSQC)
3052 NULL, // #365 float() readangle (EXT_CSQC)
3053 NULL, // #366 string() readstring (EXT_CSQC)
3054 NULL, // #367 float() readfloat (EXT_CSQC)
3087 // LordHavoc's range #400-#499
3088 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3089 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3090 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3091 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3092 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3093 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3094 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3095 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3096 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)
3097 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3098 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3099 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3100 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3101 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3102 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3103 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3104 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3105 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3106 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3107 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3108 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3109 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3110 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3111 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3112 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3113 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3114 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3115 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3116 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3117 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3118 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3119 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3120 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3121 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3122 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3123 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3124 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3125 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3126 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3127 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3128 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3129 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3130 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3131 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3132 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3133 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3134 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3135 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3136 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3137 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3138 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3139 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3140 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3141 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3142 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3143 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3144 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3145 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3147 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3148 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3149 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3150 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3151 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3152 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3153 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3154 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3155 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3156 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3157 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3159 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3160 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3161 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3162 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3163 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3164 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3165 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3166 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3167 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3168 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3169 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3170 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3190 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3192 void VM_SV_Cmd_Init(void)
3197 void VM_SV_Cmd_Reset(void)