5 //============================================================================
10 char *vm_sv_extensions =
15 "DP_CON_ALIASPARAMETERS "
33 "DP_ENT_CUSTOMCOLORMAP "
34 "DP_ENT_EXTERIORMODELTOCLIENT "
36 "DP_ENT_LOWPRECISION "
39 "DP_GFX_EXTERNALTEXTURES "
40 "DP_GFX_EXTERNALTEXTURES_PERMAP "
42 "DP_GFX_QUAKE3MODELTAGS "
46 "DP_HALFLIFE_MAP_CVAR "
52 "DP_MOVETYPEBOUNCEMISSILE "
54 "DP_QC_ASINACOSATANATAN2TAN "
57 "DP_QC_CVAR_DEFSTRING "
61 "DP_QC_FINDCHAINFLAGS "
62 "DP_QC_FINDCHAINFLOAT "
70 "DP_QC_MULTIPLETEMPSTRINGS "
72 "DP_QC_SINCOSSQRTPOW "
74 "DP_QC_STRING_CASE_FUNCTIONS "
75 "DP_QC_STRINGBUFFERS "
76 "DP_QC_STRINGCOLORFUNCTIONS "
77 "DP_QC_TOKENIZEBYSEPARATOR "
80 "DP_QC_TRACE_MOVETYPE_HITMODEL "
81 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
82 "DP_QC_UNLIMITEDTEMPSTRINGS "
83 "DP_QC_VECTORVECTORS "
89 "DP_SND_DIRECTIONLESSATTNNONE "
98 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
99 "DP_SV_DRAWONLYTOCLIENT "
102 "DP_SV_ENTITYCONTENTSTRANSITION "
103 "DP_SV_ONENTITYNOSPAWNFUNCTION "
104 "DP_SV_MODELFLAGS_AS_EFFECTS "
106 "DP_SV_NODRAWTOCLIENT "
108 "DP_SV_PLAYERPHYSICS "
109 "DP_SV_POINTPARTICLES "
111 "DP_SV_PRECACHEANYTIME "
114 "DP_SV_ROTATINGBMODEL "
117 "DP_SV_WRITEUNTERMINATEDSTRING "
121 "DP_TE_EXPLOSIONRGB "
123 "DP_TE_PARTICLECUBE "
124 "DP_TE_PARTICLERAIN "
125 "DP_TE_PARTICLESNOW "
127 "DP_TE_QUADEFFECTS1 "
130 "DP_TE_STANDARDEFFECTBUILTINS "
131 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
134 //"EXT_CSQC " // not ready yet
136 "KRIMZON_SV_PARSECLIENTCOMMAND "
139 "NEXUIZ_PLAYERMODEL "
141 "PRYDON_CLIENTCURSOR "
142 "TENEBRAE_GFX_DLIGHTS "
155 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.
157 setorigin (entity, origin)
160 static void VM_SV_setorigin (void)
165 VM_SAFEPARMCOUNT(2, VM_setorigin);
167 e = PRVM_G_EDICT(OFS_PARM0);
168 if (e == prog->edicts)
170 VM_Warning("setorigin: can not modify world entity\n");
173 if (e->priv.server->free)
175 VM_Warning("setorigin: can not modify free entity\n");
178 org = PRVM_G_VECTOR(OFS_PARM1);
179 VectorCopy (org, e->fields.server->origin);
180 SV_LinkEdict (e, false);
184 void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
188 for (i=0 ; i<3 ; i++)
190 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
192 // set derived values
193 VectorCopy (min, e->fields.server->mins);
194 VectorCopy (max, e->fields.server->maxs);
195 VectorSubtract (max, min, e->fields.server->size);
197 SV_LinkEdict (e, false);
204 the size box is rotated by the current angle
205 LordHavoc: no it isn't...
207 setsize (entity, minvector, maxvector)
210 static void VM_SV_setsize (void)
215 VM_SAFEPARMCOUNT(3, VM_setsize);
217 e = PRVM_G_EDICT(OFS_PARM0);
218 if (e == prog->edicts)
220 VM_Warning("setsize: can not modify world entity\n");
223 if (e->priv.server->free)
225 VM_Warning("setsize: can not modify free entity\n");
228 min = PRVM_G_VECTOR(OFS_PARM1);
229 max = PRVM_G_VECTOR(OFS_PARM2);
230 SetMinMaxSize (e, min, max, false);
238 setmodel(entity, model)
241 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
242 static void VM_SV_setmodel (void)
248 VM_SAFEPARMCOUNT(2, VM_setmodel);
250 e = PRVM_G_EDICT(OFS_PARM0);
251 if (e == prog->edicts)
253 VM_Warning("setmodel: can not modify world entity\n");
256 if (e->priv.server->free)
258 VM_Warning("setmodel: can not modify free entity\n");
261 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
262 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
263 e->fields.server->modelindex = i;
269 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
270 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
272 SetMinMaxSize (e, quakemins, quakemaxs, true);
275 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
282 single print to a specific client
284 sprint(clientent, value)
287 static void VM_SV_sprint (void)
291 char string[VM_STRINGTEMP_LENGTH];
293 VM_VarString(1, string, sizeof(string));
295 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
297 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
298 // LordHavoc: div0 requested that sprintto world operate like print
305 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
307 VM_Warning("tried to centerprint to a non-client\n");
311 client = svs.clients + entnum-1;
312 if (!client->netconnection)
315 MSG_WriteChar(&client->netconnection->message,svc_print);
316 MSG_WriteString(&client->netconnection->message, string);
324 single print to a specific client
326 centerprint(clientent, value)
329 static void VM_SV_centerprint (void)
333 char string[VM_STRINGTEMP_LENGTH];
335 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
337 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
339 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
341 VM_Warning("tried to centerprint to a non-client\n");
345 client = svs.clients + entnum-1;
346 if (!client->netconnection)
349 VM_VarString(1, string, sizeof(string));
350 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
351 MSG_WriteString(&client->netconnection->message, string);
358 particle(origin, color, count)
361 static void VM_SV_particle (void)
367 VM_SAFEPARMCOUNT(4, VM_SV_particle);
369 org = PRVM_G_VECTOR(OFS_PARM0);
370 dir = PRVM_G_VECTOR(OFS_PARM1);
371 color = PRVM_G_FLOAT(OFS_PARM2);
372 count = PRVM_G_FLOAT(OFS_PARM3);
373 SV_StartParticle (org, dir, (int)color, (int)count);
383 static void VM_SV_ambientsound (void)
387 float vol, attenuation;
390 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
392 pos = PRVM_G_VECTOR (OFS_PARM0);
393 samp = PRVM_G_STRING(OFS_PARM1);
394 vol = PRVM_G_FLOAT(OFS_PARM2);
395 attenuation = PRVM_G_FLOAT(OFS_PARM3);
397 // check to see if samp was properly precached
398 soundnum = SV_SoundIndex(samp, 1);
406 // add an svc_spawnambient command to the level signon packet
409 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
411 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
413 MSG_WriteVector(&sv.signon, pos, sv.protocol);
415 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
416 MSG_WriteShort (&sv.signon, soundnum);
418 MSG_WriteByte (&sv.signon, soundnum);
420 MSG_WriteByte (&sv.signon, (int)(vol*255));
421 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
429 Each entity can have eight independant sound sources, like voice,
432 Channel 0 is an auto-allocate channel, the others override anything
433 already running on that entity/channel pair.
435 An attenuation of 0 will play full volume everywhere in the level.
436 Larger attenuations will drop off.
440 static void VM_SV_sound (void)
444 prvm_edict_t *entity;
448 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
450 entity = PRVM_G_EDICT(OFS_PARM0);
451 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
452 sample = PRVM_G_STRING(OFS_PARM2);
453 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
454 attenuation = PRVM_G_FLOAT(OFS_PARM4);
457 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
461 if (volume < 0 || volume > 255)
463 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
467 if (attenuation < 0 || attenuation > 4)
469 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
473 if (channel < 0 || channel > 7)
475 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
479 SV_StartSound (entity, channel, sample, volume, attenuation);
486 Follows the same logic as VM_SV_sound, except instead of
487 an entity, an origin for the sound is provided, and channel
488 is omitted (since no entity is being tracked).
492 static void VM_SV_pointsound(void)
499 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
501 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
502 sample = PRVM_G_STRING(OFS_PARM1);
503 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
504 attenuation = PRVM_G_FLOAT(OFS_PARM3);
506 if (volume < 0 || volume > 255)
508 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
512 if (attenuation < 0 || attenuation > 4)
514 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
518 SV_StartPointSound (org, sample, volume, attenuation);
525 Used for use tracing and shot targeting
526 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
527 if the tryents flag is set.
529 traceline (vector1, vector2, movetype, ignore)
532 static void VM_SV_traceline (void)
539 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
541 prog->xfunction->builtinsprofile += 30;
543 v1 = PRVM_G_VECTOR(OFS_PARM0);
544 v2 = PRVM_G_VECTOR(OFS_PARM1);
545 move = (int)PRVM_G_FLOAT(OFS_PARM2);
546 ent = PRVM_G_EDICT(OFS_PARM3);
548 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]))
549 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));
551 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
553 VM_SetTraceGlobals(&trace);
561 Used for use tracing and shot targeting
562 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
563 if the tryents flag is set.
565 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
568 // LordHavoc: added this for my own use, VERY useful, similar to traceline
569 static void VM_SV_tracebox (void)
571 float *v1, *v2, *m1, *m2;
576 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
578 prog->xfunction->builtinsprofile += 30;
580 v1 = PRVM_G_VECTOR(OFS_PARM0);
581 m1 = PRVM_G_VECTOR(OFS_PARM1);
582 m2 = PRVM_G_VECTOR(OFS_PARM2);
583 v2 = PRVM_G_VECTOR(OFS_PARM3);
584 move = (int)PRVM_G_FLOAT(OFS_PARM4);
585 ent = PRVM_G_EDICT(OFS_PARM5);
587 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]))
588 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));
590 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
592 VM_SetTraceGlobals(&trace);
595 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
600 vec3_t original_origin;
601 vec3_t original_velocity;
602 vec3_t original_angles;
603 vec3_t original_avelocity;
607 VectorCopy(tossent->fields.server->origin , original_origin );
608 VectorCopy(tossent->fields.server->velocity , original_velocity );
609 VectorCopy(tossent->fields.server->angles , original_angles );
610 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
612 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
613 if (val != NULL && val->_float != 0)
614 gravity = val->_float;
617 gravity *= sv_gravity.value * 0.05;
619 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
621 SV_CheckVelocity (tossent);
622 tossent->fields.server->velocity[2] -= gravity;
623 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
624 VectorScale (tossent->fields.server->velocity, 0.05, move);
625 VectorAdd (tossent->fields.server->origin, move, end);
626 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
627 VectorCopy (trace.endpos, tossent->fields.server->origin);
629 if (trace.fraction < 1)
633 VectorCopy(original_origin , tossent->fields.server->origin );
634 VectorCopy(original_velocity , tossent->fields.server->velocity );
635 VectorCopy(original_angles , tossent->fields.server->angles );
636 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
641 static void VM_SV_tracetoss (void)
645 prvm_edict_t *ignore;
647 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
649 prog->xfunction->builtinsprofile += 600;
651 ent = PRVM_G_EDICT(OFS_PARM0);
652 if (ent == prog->edicts)
654 VM_Warning("tracetoss: can not use world entity\n");
657 ignore = PRVM_G_EDICT(OFS_PARM1);
659 trace = SV_Trace_Toss (ent, ignore);
661 VM_SetTraceGlobals(&trace);
664 //============================================================================
666 static int checkpvsbytes;
667 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
669 static int VM_SV_newcheckclient (int check)
675 // cycle to the next one
677 check = bound(1, check, svs.maxclients);
678 if (check == svs.maxclients)
686 prog->xfunction->builtinsprofile++;
688 if (i == svs.maxclients+1)
690 // look up the client's edict
691 ent = PRVM_EDICT_NUM(i);
692 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
693 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
695 // found a valid client (possibly the same one again)
699 // get the PVS for the entity
700 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
702 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
703 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
712 Returns a client (or object that has a client enemy) that would be a
715 If there is more than one valid option, they are cycled each frame
717 If (self.origin + self.viewofs) is not in the PVS of the current target,
718 it is not returned at all.
723 int c_invis, c_notvis;
724 static void VM_SV_checkclient (void)
726 prvm_edict_t *ent, *self;
729 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
731 // find a new check if on a new frame
732 if (sv.time - sv.lastchecktime >= 0.1)
734 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
735 sv.lastchecktime = sv.time;
738 // return check if it might be visible
739 ent = PRVM_EDICT_NUM(sv.lastcheck);
740 if (ent->priv.server->free || ent->fields.server->health <= 0)
742 VM_RETURN_EDICT(prog->edicts);
746 // if current entity can't possibly see the check entity, return 0
747 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
748 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
749 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
752 VM_RETURN_EDICT(prog->edicts);
756 // might be able to see it
758 VM_RETURN_EDICT(ent);
761 //============================================================================
768 Sends text over to the client's execution buffer
770 stuffcmd (clientent, value, ...)
773 static void VM_SV_stuffcmd (void)
777 char string[VM_STRINGTEMP_LENGTH];
779 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
781 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
782 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
784 VM_Warning("Can't stuffcmd to a non-client\n");
788 VM_VarString(1, string, sizeof(string));
791 host_client = svs.clients + entnum-1;
792 Host_ClientCommands ("%s", string);
800 Returns a chain of entities that have origins within a spherical area
802 findradius (origin, radius)
805 static void VM_SV_findradius (void)
807 prvm_edict_t *ent, *chain;
808 vec_t radius, radius2;
809 vec3_t org, eorg, mins, maxs;
812 prvm_edict_t *touchedicts[MAX_EDICTS];
814 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
816 chain = (prvm_edict_t *)prog->edicts;
818 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
819 radius = PRVM_G_FLOAT(OFS_PARM1);
820 radius2 = radius * radius;
822 mins[0] = org[0] - (radius + 1);
823 mins[1] = org[1] - (radius + 1);
824 mins[2] = org[2] - (radius + 1);
825 maxs[0] = org[0] + (radius + 1);
826 maxs[1] = org[1] + (radius + 1);
827 maxs[2] = org[2] + (radius + 1);
828 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
829 if (numtouchedicts > MAX_EDICTS)
831 // this never happens
832 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
833 numtouchedicts = MAX_EDICTS;
835 for (i = 0;i < numtouchedicts;i++)
837 ent = touchedicts[i];
838 prog->xfunction->builtinsprofile++;
839 // Quake did not return non-solid entities but darkplaces does
840 // (note: this is the reason you can't blow up fallen zombies)
841 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
843 // LordHavoc: compare against bounding box rather than center so it
844 // doesn't miss large objects, and use DotProduct instead of Length
845 // for a major speedup
846 VectorSubtract(org, ent->fields.server->origin, eorg);
847 if (sv_gameplayfix_findradiusdistancetobox.integer)
849 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
850 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
851 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
854 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
855 if (DotProduct(eorg, eorg) < radius2)
857 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
862 VM_RETURN_EDICT(chain);
865 static void VM_SV_precache_sound (void)
867 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
868 SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
869 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
872 static void VM_SV_precache_model (void)
874 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
875 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
876 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
883 float(float yaw, float dist[, settrace]) walkmove
886 static void VM_SV_walkmove (void)
895 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
897 // assume failure if it returns early
898 PRVM_G_FLOAT(OFS_RETURN) = 0;
900 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
901 if (ent == prog->edicts)
903 VM_Warning("walkmove: can not modify world entity\n");
906 if (ent->priv.server->free)
908 VM_Warning("walkmove: can not modify free entity\n");
911 yaw = PRVM_G_FLOAT(OFS_PARM0);
912 dist = PRVM_G_FLOAT(OFS_PARM1);
913 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
915 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
918 yaw = yaw*M_PI*2 / 360;
920 move[0] = cos(yaw)*dist;
921 move[1] = sin(yaw)*dist;
924 // save program state, because SV_movestep may call other progs
925 oldf = prog->xfunction;
926 oldself = prog->globals.server->self;
928 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
931 // restore program state
932 prog->xfunction = oldf;
933 prog->globals.server->self = oldself;
943 static void VM_SV_droptofloor (void)
949 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
951 // assume failure if it returns early
952 PRVM_G_FLOAT(OFS_RETURN) = 0;
954 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
955 if (ent == prog->edicts)
957 VM_Warning("droptofloor: can not modify world entity\n");
960 if (ent->priv.server->free)
962 VM_Warning("droptofloor: can not modify free entity\n");
966 VectorCopy (ent->fields.server->origin, end);
969 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
971 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
973 if (trace.fraction < 1)
974 VectorCopy (trace.endpos, ent->fields.server->origin);
975 SV_LinkEdict (ent, false);
976 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
977 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
978 PRVM_G_FLOAT(OFS_RETURN) = 1;
979 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
980 ent->priv.server->suspendedinairflag = true;
988 void(float style, string value) lightstyle
991 static void VM_SV_lightstyle (void)
998 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1000 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1001 val = PRVM_G_STRING(OFS_PARM1);
1003 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1004 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1007 // change the string in sv
1008 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1010 // send message to all clients on this server
1011 if (sv.state != ss_active)
1014 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1016 if (client->active && client->netconnection)
1018 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1019 MSG_WriteChar (&client->netconnection->message,style);
1020 MSG_WriteString (&client->netconnection->message, val);
1030 static void VM_SV_checkbottom (void)
1032 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1033 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1041 static void VM_SV_pointcontents (void)
1043 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1044 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1051 Pick a vector for the player to shoot along
1052 vector aim(entity, missilespeed)
1055 static void VM_SV_aim (void)
1057 prvm_edict_t *ent, *check, *bestent;
1058 vec3_t start, dir, end, bestdir;
1061 float dist, bestdist;
1064 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1066 // assume failure if it returns early
1067 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1068 // if sv_aim is so high it can't possibly accept anything, skip out early
1069 if (sv_aim.value >= 1)
1072 ent = PRVM_G_EDICT(OFS_PARM0);
1073 if (ent == prog->edicts)
1075 VM_Warning("aim: can not use world entity\n");
1078 if (ent->priv.server->free)
1080 VM_Warning("aim: can not use free entity\n");
1083 speed = PRVM_G_FLOAT(OFS_PARM1);
1085 VectorCopy (ent->fields.server->origin, start);
1088 // try sending a trace straight
1089 VectorCopy (prog->globals.server->v_forward, dir);
1090 VectorMA (start, 2048, dir, end);
1091 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1092 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1093 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1095 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1100 // try all possible entities
1101 VectorCopy (dir, bestdir);
1102 bestdist = sv_aim.value;
1105 check = PRVM_NEXT_EDICT(prog->edicts);
1106 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1108 prog->xfunction->builtinsprofile++;
1109 if (check->fields.server->takedamage != DAMAGE_AIM)
1113 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1114 continue; // don't aim at teammate
1115 for (j=0 ; j<3 ; j++)
1116 end[j] = check->fields.server->origin[j]
1117 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1118 VectorSubtract (end, start, dir);
1119 VectorNormalize (dir);
1120 dist = DotProduct (dir, prog->globals.server->v_forward);
1121 if (dist < bestdist)
1122 continue; // to far to turn
1123 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1124 if (tr.ent == check)
1125 { // can shoot at this one
1133 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1134 dist = DotProduct (dir, prog->globals.server->v_forward);
1135 VectorScale (prog->globals.server->v_forward, dist, end);
1137 VectorNormalize (end);
1138 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1142 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1147 ===============================================================================
1151 ===============================================================================
1154 #define MSG_BROADCAST 0 // unreliable to all
1155 #define MSG_ONE 1 // reliable to one (msg_entity)
1156 #define MSG_ALL 2 // reliable to all
1157 #define MSG_INIT 3 // write to the init string
1158 #define MSG_ENTITY 5
1160 sizebuf_t *WriteDest (void)
1166 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1170 return &sv.datagram;
1173 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1174 entnum = PRVM_NUM_FOR_EDICT(ent);
1175 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1177 VM_Warning ("WriteDest: tried to write to non-client\n");
1178 return &sv.reliable_datagram;
1181 return &svs.clients[entnum-1].netconnection->message;
1184 VM_Warning ("WriteDest: bad destination\n");
1186 return &sv.reliable_datagram;
1192 return sv.writeentitiestoclient_msg;
1198 static void VM_SV_WriteByte (void)
1200 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1201 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1204 static void VM_SV_WriteChar (void)
1206 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1207 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1210 static void VM_SV_WriteShort (void)
1212 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1213 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1216 static void VM_SV_WriteLong (void)
1218 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1219 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1222 static void VM_SV_WriteAngle (void)
1224 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1225 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1228 static void VM_SV_WriteCoord (void)
1230 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1231 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1234 static void VM_SV_WriteString (void)
1236 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1237 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1240 static void VM_SV_WriteUnterminatedString (void)
1242 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1243 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1247 static void VM_SV_WriteEntity (void)
1249 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1250 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1253 //////////////////////////////////////////////////////////
1255 static void VM_SV_makestatic (void)
1260 // allow 0 parameters due to an id1 qc bug in which this function is used
1261 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1262 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1264 if (prog->argc >= 1)
1265 ent = PRVM_G_EDICT(OFS_PARM0);
1267 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1268 if (ent == prog->edicts)
1270 VM_Warning("makestatic: can not modify world entity\n");
1273 if (ent->priv.server->free)
1275 VM_Warning("makestatic: can not modify free entity\n");
1280 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1285 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1286 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1287 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1289 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1291 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1292 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1293 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1297 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1298 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1299 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1302 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1303 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1304 for (i=0 ; i<3 ; i++)
1306 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1307 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1310 // throw the entity away now
1314 //=============================================================================
1321 static void VM_SV_setspawnparms (void)
1327 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1329 ent = PRVM_G_EDICT(OFS_PARM0);
1330 i = PRVM_NUM_FOR_EDICT(ent);
1331 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1333 Con_Print("tried to setspawnparms on a non-client\n");
1337 // copy spawn parms out of the client_t
1338 client = svs.clients + i-1;
1339 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1340 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1347 Returns a color vector indicating the lighting at the requested point.
1349 (Internal Operation note: actually measures the light beneath the point, just like
1350 the model lighting on the client)
1355 static void VM_SV_getlight (void)
1357 vec3_t ambientcolor, diffusecolor, diffusenormal;
1359 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1360 p = PRVM_G_VECTOR(OFS_PARM0);
1361 VectorClear(ambientcolor);
1362 VectorClear(diffusecolor);
1363 VectorClear(diffusenormal);
1364 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1365 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1366 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1371 unsigned char type; // 1/2/8 or other value if isn't used
1375 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1376 static int vm_customstats_last;
1378 void VM_CustomStats_Clear (void)
1382 Z_Free(vm_customstats);
1383 vm_customstats = NULL;
1384 vm_customstats_last = -1;
1388 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1396 for(i=0; i<vm_customstats_last+1 ;i++)
1398 if(!vm_customstats[i].type)
1400 switch(vm_customstats[i].type)
1402 //string as 16 bytes
1405 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1406 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1407 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1408 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1409 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1411 //float field sent as-is
1413 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1415 //integer value of float field
1417 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1425 // void(float index, float type, .void field) SV_AddStat = #232;
1426 // Set up an auto-sent player stat.
1427 // Client's get thier own fields sent to them. Index may not be less than 32.
1428 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1429 // 1: string (4 stats carrying a total of 16 charactures)
1430 // 2: float (one stat, float converted to an integer for transportation)
1431 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1432 static void VM_SV_AddStat (void)
1437 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1441 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1444 VM_Warning("PF_SV_AddStat: not enough memory\n");
1448 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1449 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1450 off = PRVM_G_INT (OFS_PARM2);
1455 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1458 if(i >= (MAX_CL_STATS-32))
1460 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1463 if(i > (MAX_CL_STATS-32-4) && type == 1)
1465 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1468 vm_customstats[i].type = type;
1469 vm_customstats[i].fieldoffset = off;
1470 if(vm_customstats_last < i)
1471 vm_customstats_last = i;
1478 copies data from one entity to another
1480 copyentity(src, dst)
1483 static void VM_SV_copyentity (void)
1485 prvm_edict_t *in, *out;
1486 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1487 in = PRVM_G_EDICT(OFS_PARM0);
1488 if (in == prog->edicts)
1490 VM_Warning("copyentity: can not read world entity\n");
1493 if (in->priv.server->free)
1495 VM_Warning("copyentity: can not read free entity\n");
1498 out = PRVM_G_EDICT(OFS_PARM1);
1499 if (out == prog->edicts)
1501 VM_Warning("copyentity: can not modify world entity\n");
1504 if (out->priv.server->free)
1506 VM_Warning("copyentity: can not modify free entity\n");
1509 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1510 SV_LinkEdict(out, false);
1518 sets the color of a client and broadcasts the update to all connected clients
1520 setcolor(clientent, value)
1523 static void VM_SV_setcolor (void)
1529 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1530 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1531 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1533 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1535 Con_Print("tried to setcolor a non-client\n");
1539 client = svs.clients + entnum-1;
1542 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1544 client->edict->fields.server->team = (i & 15) + 1;
1547 if (client->old_colors != client->colors)
1549 client->old_colors = client->colors;
1550 // send notification to all clients
1551 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1552 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1553 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1561 effect(origin, modelname, startframe, framecount, framerate)
1564 static void VM_SV_effect (void)
1568 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1569 s = PRVM_G_STRING(OFS_PARM1);
1572 VM_Warning("effect: no model specified\n");
1576 i = SV_ModelIndex(s, 1);
1579 VM_Warning("effect: model not precached\n");
1583 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1585 VM_Warning("effect: framecount < 1\n");
1589 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1591 VM_Warning("effect: framerate < 1\n");
1595 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));
1598 static void VM_SV_te_blood (void)
1600 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1601 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1603 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1604 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1606 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1607 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1608 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1610 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1611 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1612 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1614 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1615 SV_FlushBroadcastMessages();
1618 static void VM_SV_te_bloodshower (void)
1620 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1621 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1623 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1624 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1626 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1627 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1628 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1630 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1631 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1632 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1634 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1636 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1637 SV_FlushBroadcastMessages();
1640 static void VM_SV_te_explosionrgb (void)
1642 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1643 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1644 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1646 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1647 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1648 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1650 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1651 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1652 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1653 SV_FlushBroadcastMessages();
1656 static void VM_SV_te_particlecube (void)
1658 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1659 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1661 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1662 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1664 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1665 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1666 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1668 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1672 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1673 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1674 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1676 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1678 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1679 // gravity true/false
1680 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1682 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1683 SV_FlushBroadcastMessages();
1686 static void VM_SV_te_particlerain (void)
1688 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1689 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1691 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1692 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1694 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1695 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1696 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1698 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1699 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1700 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1702 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1703 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1704 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1706 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1708 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1709 SV_FlushBroadcastMessages();
1712 static void VM_SV_te_particlesnow (void)
1714 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1715 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1717 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1718 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1720 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1721 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1722 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1724 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1725 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1726 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1728 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1729 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1730 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1732 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1734 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1735 SV_FlushBroadcastMessages();
1738 static void VM_SV_te_spark (void)
1740 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1741 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1743 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1744 MSG_WriteByte(&sv.datagram, TE_SPARK);
1746 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1747 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1748 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1750 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1751 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1752 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1754 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1755 SV_FlushBroadcastMessages();
1758 static void VM_SV_te_gunshotquad (void)
1760 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1761 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1762 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1764 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1765 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1766 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1767 SV_FlushBroadcastMessages();
1770 static void VM_SV_te_spikequad (void)
1772 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1773 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1774 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
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);
1779 SV_FlushBroadcastMessages();
1782 static void VM_SV_te_superspikequad (void)
1784 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1785 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1786 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1788 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1790 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1791 SV_FlushBroadcastMessages();
1794 static void VM_SV_te_explosionquad (void)
1796 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1797 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1798 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1800 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1801 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1802 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1803 SV_FlushBroadcastMessages();
1806 static void VM_SV_te_smallflash (void)
1808 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1809 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1810 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1812 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1814 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1815 SV_FlushBroadcastMessages();
1818 static void VM_SV_te_customflash (void)
1820 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1821 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1823 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1824 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1826 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1827 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1828 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1830 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1832 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1834 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1835 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1836 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1837 SV_FlushBroadcastMessages();
1840 static void VM_SV_te_gunshot (void)
1842 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1843 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1844 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1846 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1847 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1848 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1849 SV_FlushBroadcastMessages();
1852 static void VM_SV_te_spike (void)
1854 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1855 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1856 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1858 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1859 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1860 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1861 SV_FlushBroadcastMessages();
1864 static void VM_SV_te_superspike (void)
1866 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1867 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1868 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1871 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1872 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1873 SV_FlushBroadcastMessages();
1876 static void VM_SV_te_explosion (void)
1878 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1879 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1880 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1882 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1883 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1884 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1885 SV_FlushBroadcastMessages();
1888 static void VM_SV_te_tarexplosion (void)
1890 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1891 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1892 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1894 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1895 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1896 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1897 SV_FlushBroadcastMessages();
1900 static void VM_SV_te_wizspike (void)
1902 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1903 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1904 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1906 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1907 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1908 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1909 SV_FlushBroadcastMessages();
1912 static void VM_SV_te_knightspike (void)
1914 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1915 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1916 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1918 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1919 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1920 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1921 SV_FlushBroadcastMessages();
1924 static void VM_SV_te_lavasplash (void)
1926 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1927 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1928 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1930 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1931 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1933 SV_FlushBroadcastMessages();
1936 static void VM_SV_te_teleport (void)
1938 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1939 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1940 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1942 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1943 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1944 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1945 SV_FlushBroadcastMessages();
1948 static void VM_SV_te_explosion2 (void)
1950 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1951 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1952 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1954 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1955 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1956 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1958 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1959 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1960 SV_FlushBroadcastMessages();
1963 static void VM_SV_te_lightning1 (void)
1965 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1966 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1967 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1969 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1976 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1977 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1978 SV_FlushBroadcastMessages();
1981 static void VM_SV_te_lightning2 (void)
1983 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1984 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1985 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1987 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1989 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1990 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1991 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1993 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1994 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1996 SV_FlushBroadcastMessages();
1999 static void VM_SV_te_lightning3 (void)
2001 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2002 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2003 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2005 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2007 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2008 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2009 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2011 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2012 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2013 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2014 SV_FlushBroadcastMessages();
2017 static void VM_SV_te_beam (void)
2019 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2020 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2021 MSG_WriteByte(&sv.datagram, TE_BEAM);
2023 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2025 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2026 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2027 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2029 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2030 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2031 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2032 SV_FlushBroadcastMessages();
2035 static void VM_SV_te_plasmaburn (void)
2037 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2038 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2039 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2040 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2041 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2042 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2043 SV_FlushBroadcastMessages();
2046 static void VM_SV_te_flamejet (void)
2048 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2049 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2050 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2052 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2053 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2054 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2056 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2057 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2058 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2060 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2061 SV_FlushBroadcastMessages();
2064 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2067 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2069 bestdist = 1000000000;
2071 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2073 // clip original point to each triangle of the surface and find the
2074 // triangle that is closest
2075 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2076 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2077 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2078 TriangleNormal(v[0], v[1], v[2], facenormal);
2079 VectorNormalize(facenormal);
2080 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2081 VectorMA(p, offsetdist, facenormal, temp);
2082 for (j = 0, k = 2;j < 3;k = j, j++)
2084 VectorSubtract(v[k], v[j], edgenormal);
2085 CrossProduct(edgenormal, facenormal, sidenormal);
2086 VectorNormalize(sidenormal);
2087 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2089 VectorMA(temp, offsetdist, sidenormal, temp);
2091 dist = VectorDistance2(temp, p);
2092 if (bestdist > dist)
2095 VectorCopy(temp, out);
2100 static model_t *getmodel(prvm_edict_t *ed)
2103 if (!ed || ed->priv.server->free)
2105 modelindex = (int)ed->fields.server->modelindex;
2106 if (modelindex < 1 || modelindex >= MAX_MODELS)
2108 return sv.models[modelindex];
2111 static msurface_t *getsurface(model_t *model, int surfacenum)
2113 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2115 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2119 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2120 static void VM_SV_getsurfacenumpoints(void)
2123 msurface_t *surface;
2124 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2125 // return 0 if no such surface
2126 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2128 PRVM_G_FLOAT(OFS_RETURN) = 0;
2132 // note: this (incorrectly) assumes it is a simple polygon
2133 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2135 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2136 static void VM_SV_getsurfacepoint(void)
2140 msurface_t *surface;
2142 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2143 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2144 ed = PRVM_G_EDICT(OFS_PARM0);
2145 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2147 // note: this (incorrectly) assumes it is a simple polygon
2148 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2149 if (pointnum < 0 || pointnum >= surface->num_vertices)
2151 // FIXME: implement rotation/scaling
2152 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2154 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2155 static void VM_SV_getsurfacenormal(void)
2158 msurface_t *surface;
2160 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2161 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2162 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2164 // FIXME: implement rotation/scaling
2165 // note: this (incorrectly) assumes it is a simple polygon
2166 // note: this only returns the first triangle, so it doesn't work very
2167 // well for curved surfaces or arbitrary meshes
2168 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);
2169 VectorNormalize(normal);
2170 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2172 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2173 static void VM_SV_getsurfacetexture(void)
2176 msurface_t *surface;
2177 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2178 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2179 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2181 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2183 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2184 static void VM_SV_getsurfacenearpoint(void)
2186 int surfacenum, best;
2188 vec_t dist, bestdist;
2191 msurface_t *surface;
2193 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2194 PRVM_G_FLOAT(OFS_RETURN) = -1;
2195 ed = PRVM_G_EDICT(OFS_PARM0);
2196 point = PRVM_G_VECTOR(OFS_PARM1);
2198 if (!ed || ed->priv.server->free)
2200 model = getmodel(ed);
2201 if (!model || !model->num_surfaces)
2204 // FIXME: implement rotation/scaling
2205 VectorSubtract(point, ed->fields.server->origin, p);
2207 bestdist = 1000000000;
2208 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2210 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2211 // first see if the nearest point on the surface's box is closer than the previous match
2212 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2213 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2214 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2215 dist = VectorLength2(clipped);
2216 if (dist < bestdist)
2218 // it is, check the nearest point on the actual geometry
2219 clippointtosurface(model, surface, p, clipped);
2220 VectorSubtract(clipped, p, clipped);
2221 dist += VectorLength2(clipped);
2222 if (dist < bestdist)
2224 // that's closer too, store it as the best match
2230 PRVM_G_FLOAT(OFS_RETURN) = best;
2232 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2233 static void VM_SV_getsurfaceclippedpoint(void)
2237 msurface_t *surface;
2239 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2240 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2241 ed = PRVM_G_EDICT(OFS_PARM0);
2242 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2244 // FIXME: implement rotation/scaling
2245 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2246 clippointtosurface(model, surface, p, out);
2247 // FIXME: implement rotation/scaling
2248 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2251 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2252 //this function originally written by KrimZon, made shorter by LordHavoc
2253 static void VM_SV_clientcommand (void)
2255 client_t *temp_client;
2257 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2259 //find client for this entity
2260 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2261 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2263 Con_Print("PF_clientcommand: entity is not a client\n");
2267 temp_client = host_client;
2268 host_client = svs.clients + i;
2269 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2270 host_client = temp_client;
2273 //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)
2274 static void VM_SV_setattachment (void)
2276 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2277 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2278 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2282 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2284 if (e == prog->edicts)
2286 VM_Warning("setattachment: can not modify world entity\n");
2289 if (e->priv.server->free)
2291 VM_Warning("setattachment: can not modify free entity\n");
2295 if (tagentity == NULL)
2296 tagentity = prog->edicts;
2298 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2300 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2302 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2305 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2307 modelindex = (int)tagentity->fields.server->modelindex;
2308 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2310 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2312 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);
2315 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));
2319 /////////////////////////////////////////
2320 // DP_MD3_TAGINFO extension coded by VorteX
2322 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2327 i = (int)e->fields.server->modelindex;
2328 if (i < 1 || i >= MAX_MODELS)
2330 model = sv.models[i];
2332 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2335 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2337 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2341 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);
2343 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);
2346 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2352 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2353 && (model = sv.models[(int)ent->fields.server->modelindex])
2354 && model->animscenes)
2356 // if model has wrong frame, engine automatically switches to model first frame
2357 frame = (int)ent->fields.server->frame;
2358 if (frame < 0 || frame >= model->numframes)
2360 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2362 *out = identitymatrix;
2366 // Warnings/errors code:
2367 // 0 - normal (everything all-right)
2370 // 3 - null or non-precached model
2371 // 4 - no tags with requested index
2372 // 5 - runaway loop at attachment chain
2373 extern cvar_t cl_bob;
2374 extern cvar_t cl_bobcycle;
2375 extern cvar_t cl_bobup;
2376 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2380 int modelindex, attachloop;
2381 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2384 *out = identitymatrix; // warnings and errors return identical matrix
2386 if (ent == prog->edicts)
2388 if (ent->priv.server->free)
2391 modelindex = (int)ent->fields.server->modelindex;
2392 if (modelindex <= 0 || modelindex > MAX_MODELS)
2395 model = sv.models[modelindex];
2397 tagmatrix = identitymatrix;
2398 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2402 if (attachloop >= 256) // prevent runaway looping
2404 // apply transformation by child's tagindex on parent entity and then
2405 // by parent entity itself
2406 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2407 if (ret && attachloop == 0)
2409 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2410 SV_GetEntityMatrix(ent, &entitymatrix, false);
2411 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2412 // next iteration we process the parent entity
2413 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2415 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2416 ent = PRVM_EDICT_NUM(val->edict);
2423 // RENDER_VIEWMODEL magic
2424 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2426 Matrix4x4_Copy(&tagmatrix, out);
2427 ent = PRVM_EDICT_NUM(val->edict);
2429 SV_GetEntityMatrix(ent, &entitymatrix, true);
2430 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2433 // Cl_bob, ported from rendering code
2434 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2437 // LordHavoc: this code is *weird*, but not replacable (I think it
2438 // should be done in QC on the server, but oh well, quake is quake)
2439 // LordHavoc: figured out bobup: the time at which the sin is at 180
2440 // degrees (which allows lengthening or squishing the peak or valley)
2441 cycle = sv.time/cl_bobcycle.value;
2442 cycle -= (int)cycle;
2443 if (cycle < cl_bobup.value)
2444 cycle = sin(M_PI * cycle / cl_bobup.value);
2446 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2447 // bob is proportional to velocity in the xy plane
2448 // (don't count Z, or jumping messes it up)
2449 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;
2450 bob = bob*0.3 + bob*0.7*cycle;
2451 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2458 //float(entity ent, string tagname) gettagindex;
2460 static void VM_SV_gettagindex (void)
2463 const char *tag_name;
2464 int modelindex, tag_index;
2466 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2468 ent = PRVM_G_EDICT(OFS_PARM0);
2469 tag_name = PRVM_G_STRING(OFS_PARM1);
2471 if (ent == prog->edicts)
2473 VM_Warning("gettagindex: can't affect world entity\n");
2476 if (ent->priv.server->free)
2478 VM_Warning("gettagindex: can't affect free entity\n");
2482 modelindex = (int)ent->fields.server->modelindex;
2484 if (modelindex <= 0 || modelindex > MAX_MODELS)
2485 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2488 tag_index = SV_GetTagIndex(ent, tag_name);
2490 Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2492 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2495 //vector(entity ent, float tagindex) gettaginfo;
2496 static void VM_SV_gettaginfo (void)
2500 matrix4x4_t tag_matrix;
2503 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2505 e = PRVM_G_EDICT(OFS_PARM0);
2506 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2508 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2509 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2514 VM_Warning("gettagindex: can't affect world entity\n");
2517 VM_Warning("gettagindex: can't affect free entity\n");
2520 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2523 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2526 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2531 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2532 static void VM_SV_dropclient (void)
2535 client_t *oldhostclient;
2536 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2537 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2538 if (clientnum < 0 || clientnum >= svs.maxclients)
2540 VM_Warning("dropclient: not a client\n");
2543 if (!svs.clients[clientnum].active)
2545 VM_Warning("dropclient: that client slot is not connected\n");
2548 oldhostclient = host_client;
2549 host_client = svs.clients + clientnum;
2550 SV_DropClient(false);
2551 host_client = oldhostclient;
2554 //entity() spawnclient (DP_SV_BOTCLIENT)
2555 static void VM_SV_spawnclient (void)
2559 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2560 prog->xfunction->builtinsprofile += 2;
2562 for (i = 0;i < svs.maxclients;i++)
2564 if (!svs.clients[i].active)
2566 prog->xfunction->builtinsprofile += 100;
2567 SV_ConnectClient (i, NULL);
2568 // this has to be set or else ClientDisconnect won't be called
2569 // we assume the qc will call ClientConnect...
2570 svs.clients[i].clientconnectcalled = true;
2571 ed = PRVM_EDICT_NUM(i + 1);
2575 VM_RETURN_EDICT(ed);
2578 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2579 static void VM_SV_clienttype (void)
2582 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2583 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2584 if (clientnum < 0 || clientnum >= svs.maxclients)
2585 PRVM_G_FLOAT(OFS_RETURN) = 3;
2586 else if (!svs.clients[clientnum].active)
2587 PRVM_G_FLOAT(OFS_RETURN) = 0;
2588 else if (svs.clients[clientnum].netconnection)
2589 PRVM_G_FLOAT(OFS_RETURN) = 1;
2591 PRVM_G_FLOAT(OFS_RETURN) = 2;
2598 string(string key) serverkey
2601 void VM_SV_serverkey(void)
2603 char string[VM_STRINGTEMP_LENGTH];
2604 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2605 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2606 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2609 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2610 static void VM_SV_setmodelindex (void)
2615 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2617 e = PRVM_G_EDICT(OFS_PARM0);
2618 if (e == prog->edicts)
2620 VM_Warning("setmodelindex: can not modify world entity\n");
2623 if (e->priv.server->free)
2625 VM_Warning("setmodelindex: can not modify free entity\n");
2628 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2629 if (i <= 0 || i > MAX_MODELS)
2631 VM_Warning("setmodelindex: invalid modelindex\n");
2634 if (!sv.model_precache[i][0])
2636 VM_Warning("setmodelindex: model not precached\n");
2640 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2641 e->fields.server->modelindex = i;
2647 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2648 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2650 SetMinMaxSize (e, quakemins, quakemaxs, true);
2653 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2656 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2657 static void VM_SV_modelnameforindex (void)
2660 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2662 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2664 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2665 if (i <= 0 || i > MAX_MODELS)
2667 VM_Warning("modelnameforindex: invalid modelindex\n");
2670 if (!sv.model_precache[i][0])
2672 VM_Warning("modelnameforindex: model not precached\n");
2676 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2679 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2680 static void VM_SV_particleeffectnum (void)
2683 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2684 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2687 PRVM_G_FLOAT(OFS_RETURN) = i;
2690 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2691 static void VM_SV_trailparticles (void)
2693 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2695 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2696 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2697 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2698 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2699 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2700 SV_FlushBroadcastMessages();
2703 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2704 static void VM_SV_pointparticles (void)
2706 int effectnum, count;
2708 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2709 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2710 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2711 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2712 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2713 if (count == 1 && !VectorLength2(vel))
2716 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2717 MSG_WriteShort(&sv.datagram, effectnum);
2718 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2722 // 1+2+12+12+2=29 bytes
2723 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2724 MSG_WriteShort(&sv.datagram, effectnum);
2725 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2726 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2727 MSG_WriteShort(&sv.datagram, count);
2730 SV_FlushBroadcastMessages();
2733 prvm_builtin_t vm_sv_builtins[] = {
2734 NULL, // #0 NULL function (not callable) (QUAKE)
2735 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2736 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2737 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2738 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2739 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2740 VM_break, // #6 void() break (QUAKE)
2741 VM_random, // #7 float() random (QUAKE)
2742 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2743 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2744 VM_error, // #10 void(string e) error (QUAKE)
2745 VM_objerror, // #11 void(string e) objerror (QUAKE)
2746 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2747 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2748 VM_spawn, // #14 entity() spawn (QUAKE)
2749 VM_remove, // #15 void(entity e) remove (QUAKE)
2750 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2751 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2752 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2753 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2754 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2755 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2756 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2757 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2758 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2759 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2760 VM_ftos, // #26 string(float f) ftos (QUAKE)
2761 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2762 VM_coredump, // #28 void() coredump (QUAKE)
2763 VM_traceon, // #29 void() traceon (QUAKE)
2764 VM_traceoff, // #30 void() traceoff (QUAKE)
2765 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2766 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2767 NULL, // #33 (QUAKE)
2768 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2769 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2770 VM_rint, // #36 float(float v) rint (QUAKE)
2771 VM_floor, // #37 float(float v) floor (QUAKE)
2772 VM_ceil, // #38 float(float v) ceil (QUAKE)
2773 NULL, // #39 (QUAKE)
2774 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2775 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2776 NULL, // #42 (QUAKE)
2777 VM_fabs, // #43 float(float f) fabs (QUAKE)
2778 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2779 VM_cvar, // #45 float(string s) cvar (QUAKE)
2780 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2781 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2782 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2783 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2784 NULL, // #50 (QUAKE)
2785 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2786 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2787 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2788 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2789 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2790 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2791 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2792 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2793 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2794 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2795 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2796 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2797 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2798 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2799 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2800 NULL, // #66 (QUAKE)
2801 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2802 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2803 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2804 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2805 NULL, // #71 (QUAKE)
2806 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2807 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2808 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2809 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2810 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2811 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2812 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2813 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2814 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2815 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2816 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2817 NULL, // #83 (QUAKE)
2818 NULL, // #84 (QUAKE)
2819 NULL, // #85 (QUAKE)
2820 NULL, // #86 (QUAKE)
2821 NULL, // #87 (QUAKE)
2822 NULL, // #88 (QUAKE)
2823 NULL, // #89 (QUAKE)
2824 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2825 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2826 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2827 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2828 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2829 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2830 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2831 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2832 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2833 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2834 // FrikaC and Telejano range #100-#199
2845 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2846 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2847 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2848 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2849 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2850 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2851 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2852 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2853 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2854 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
2935 // FTEQW range #200-#299
2954 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
2957 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
2958 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
2959 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
2960 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
2961 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
2962 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
2963 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
2964 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
2965 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
2966 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
2968 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3036 // CSQC range #300-#399
3037 NULL, // #300 void() clearscene (EXT_CSQC)
3038 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3039 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3040 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3041 NULL, // #304 void() renderscene (EXT_CSQC)
3042 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3043 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3044 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3045 NULL, // #308 void() R_EndPolygon
3047 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3048 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3052 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3053 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3054 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3055 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3056 NULL, // #319 void(string name) freepic (EXT_CSQC)
3057 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3058 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3059 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3060 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3061 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3062 NULL, // #325 void(void) drawresetcliparea
3067 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3068 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3069 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3070 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3071 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3072 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3073 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3074 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3075 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3076 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3077 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3078 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3079 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3080 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3081 NULL, // #344 vector() getmousepos (EXT_CSQC)
3082 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3083 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3084 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3085 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3086 NULL, // #349 float() isdemo (EXT_CSQC)
3087 VM_isserver, // #350 float() isserver (EXT_CSQC)
3088 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3089 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3090 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3091 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3097 NULL, // #360 float() readbyte (EXT_CSQC)
3098 NULL, // #361 float() readchar (EXT_CSQC)
3099 NULL, // #362 float() readshort (EXT_CSQC)
3100 NULL, // #363 float() readlong (EXT_CSQC)
3101 NULL, // #364 float() readcoord (EXT_CSQC)
3102 NULL, // #365 float() readangle (EXT_CSQC)
3103 NULL, // #366 string() readstring (EXT_CSQC)
3104 NULL, // #367 float() readfloat (EXT_CSQC)
3137 // LordHavoc's range #400-#499
3138 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3139 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3140 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3141 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3142 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3143 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3144 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3145 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3146 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)
3147 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3148 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3149 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3150 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3151 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3152 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3153 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3154 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3155 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3156 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3157 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3158 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3159 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3160 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3161 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3162 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3163 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3164 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3165 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3166 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3167 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3168 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3169 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3170 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3171 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3172 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3173 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3174 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3175 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3176 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3177 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3178 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3179 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3180 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3181 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3182 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3183 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3184 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3185 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3186 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3187 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3188 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3189 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3190 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3191 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3192 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3193 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3194 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3195 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3197 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3198 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3199 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3200 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3201 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3202 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3203 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3204 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3205 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3206 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3207 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3209 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3210 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3211 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3212 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3213 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3214 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3215 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3216 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3217 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3218 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3219 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3220 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3221 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3222 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3223 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3240 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3242 void VM_SV_Cmd_Init(void)
3247 void VM_SV_Cmd_Reset(void)