5 //============================================================================
10 char *vm_sv_extensions =
15 "DP_CON_ALIASPARAMETERS "
34 "DP_ENT_CUSTOMCOLORMAP "
35 "DP_ENT_EXTERIORMODELTOCLIENT "
37 "DP_ENT_LOWPRECISION "
41 "DP_GFX_EXTERNALTEXTURES "
42 "DP_GFX_EXTERNALTEXTURES_PERMAP "
44 "DP_GFX_QUAKE3MODELTAGS "
48 "DP_HALFLIFE_MAP_CVAR "
54 "DP_MOVETYPEBOUNCEMISSILE "
56 "DP_QC_ASINACOSATANATAN2TAN "
61 "DP_QC_CVAR_DEFSTRING "
67 "DP_QC_FINDCHAINFLAGS "
68 "DP_QC_FINDCHAINFLOAT "
74 "DP_QC_GETSURFACEPOINTATTRIBUTE "
77 "DP_QC_MULTIPLETEMPSTRINGS "
78 "DP_QC_NUM_FOR_EDICT "
80 "DP_QC_SINCOSSQRTPOW "
82 "DP_QC_STRINGBUFFERS "
83 "DP_QC_STRINGCOLORFUNCTIONS "
84 "DP_QC_STRING_CASE_FUNCTIONS "
86 "DP_QC_TOKENIZEBYSEPARATOR "
89 "DP_QC_TRACE_MOVETYPE_HITMODEL "
90 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
91 "DP_QC_UNLIMITEDTEMPSTRINGS "
93 "DP_QC_VECTOANGLES_WITH_ROLL "
94 "DP_QC_VECTORVECTORS "
100 "DP_SND_DIRECTIONLESSATTNNONE "
107 "DP_SV_CLIENTCOLORS "
110 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
111 "DP_SV_DRAWONLYTOCLIENT "
114 "DP_SV_ENTITYCONTENTSTRANSITION "
115 "DP_SV_MODELFLAGS_AS_EFFECTS "
117 "DP_SV_NODRAWTOCLIENT "
118 "DP_SV_ONENTITYNOSPAWNFUNCTION "
120 "DP_SV_PLAYERPHYSICS "
121 "DP_SV_POINTPARTICLES "
123 "DP_SV_PRECACHEANYTIME "
126 "DP_SV_ROTATINGBMODEL "
130 "DP_SV_WRITEUNTERMINATEDSTRING "
134 "DP_TE_EXPLOSIONRGB "
136 "DP_TE_PARTICLECUBE "
137 "DP_TE_PARTICLERAIN "
138 "DP_TE_PARTICLESNOW "
140 "DP_TE_QUADEFFECTS1 "
143 "DP_TE_STANDARDEFFECTBUILTINS "
144 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
149 "KRIMZON_SV_PARSECLIENTCOMMAND "
152 "NEXUIZ_PLAYERMODEL "
154 "PRYDON_CLIENTCURSOR "
155 "TENEBRAE_GFX_DLIGHTS "
157 //"EXT_CSQC " // not ready yet
164 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.
166 setorigin (entity, origin)
169 static void VM_SV_setorigin (void)
174 VM_SAFEPARMCOUNT(2, VM_setorigin);
176 e = PRVM_G_EDICT(OFS_PARM0);
177 if (e == prog->edicts)
179 VM_Warning("setorigin: can not modify world entity\n");
182 if (e->priv.server->free)
184 VM_Warning("setorigin: can not modify free entity\n");
187 org = PRVM_G_VECTOR(OFS_PARM1);
188 VectorCopy (org, e->fields.server->origin);
189 SV_LinkEdict (e, false);
192 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
193 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
197 for (i=0 ; i<3 ; i++)
199 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
201 // set derived values
202 VectorCopy (min, e->fields.server->mins);
203 VectorCopy (max, e->fields.server->maxs);
204 VectorSubtract (max, min, e->fields.server->size);
206 SV_LinkEdict (e, false);
213 the size box is rotated by the current angle
214 LordHavoc: no it isn't...
216 setsize (entity, minvector, maxvector)
219 static void VM_SV_setsize (void)
224 VM_SAFEPARMCOUNT(3, VM_setsize);
226 e = PRVM_G_EDICT(OFS_PARM0);
227 if (e == prog->edicts)
229 VM_Warning("setsize: can not modify world entity\n");
232 if (e->priv.server->free)
234 VM_Warning("setsize: can not modify free entity\n");
237 min = PRVM_G_VECTOR(OFS_PARM1);
238 max = PRVM_G_VECTOR(OFS_PARM2);
239 SetMinMaxSize (e, min, max, false);
247 setmodel(entity, model)
250 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
251 static void VM_SV_setmodel (void)
257 VM_SAFEPARMCOUNT(2, VM_setmodel);
259 e = PRVM_G_EDICT(OFS_PARM0);
260 if (e == prog->edicts)
262 VM_Warning("setmodel: can not modify world entity\n");
265 if (e->priv.server->free)
267 VM_Warning("setmodel: can not modify free entity\n");
270 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
271 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
272 e->fields.server->modelindex = i;
278 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
279 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
281 SetMinMaxSize (e, quakemins, quakemaxs, true);
284 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
291 single print to a specific client
293 sprint(clientent, value)
296 static void VM_SV_sprint (void)
300 char string[VM_STRINGTEMP_LENGTH];
302 VM_VarString(1, string, sizeof(string));
304 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
306 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
307 // LordHavoc: div0 requested that sprintto world operate like print
314 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
316 VM_Warning("tried to centerprint to a non-client\n");
320 client = svs.clients + entnum-1;
321 if (!client->netconnection)
324 MSG_WriteChar(&client->netconnection->message,svc_print);
325 MSG_WriteString(&client->netconnection->message, string);
333 single print to a specific client
335 centerprint(clientent, value)
338 static void VM_SV_centerprint (void)
342 char string[VM_STRINGTEMP_LENGTH];
344 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
346 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
348 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
350 VM_Warning("tried to centerprint to a non-client\n");
354 client = svs.clients + entnum-1;
355 if (!client->netconnection)
358 VM_VarString(1, string, sizeof(string));
359 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
360 MSG_WriteString(&client->netconnection->message, string);
367 particle(origin, color, count)
370 static void VM_SV_particle (void)
376 VM_SAFEPARMCOUNT(4, VM_SV_particle);
378 org = PRVM_G_VECTOR(OFS_PARM0);
379 dir = PRVM_G_VECTOR(OFS_PARM1);
380 color = PRVM_G_FLOAT(OFS_PARM2);
381 count = PRVM_G_FLOAT(OFS_PARM3);
382 SV_StartParticle (org, dir, (int)color, (int)count);
392 static void VM_SV_ambientsound (void)
396 float vol, attenuation;
399 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
401 pos = PRVM_G_VECTOR (OFS_PARM0);
402 samp = PRVM_G_STRING(OFS_PARM1);
403 vol = PRVM_G_FLOAT(OFS_PARM2);
404 attenuation = PRVM_G_FLOAT(OFS_PARM3);
406 // check to see if samp was properly precached
407 soundnum = SV_SoundIndex(samp, 1);
415 // add an svc_spawnambient command to the level signon packet
418 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
420 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
422 MSG_WriteVector(&sv.signon, pos, sv.protocol);
424 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
425 MSG_WriteShort (&sv.signon, soundnum);
427 MSG_WriteByte (&sv.signon, soundnum);
429 MSG_WriteByte (&sv.signon, (int)(vol*255));
430 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
438 Each entity can have eight independant sound sources, like voice,
441 Channel 0 is an auto-allocate channel, the others override anything
442 already running on that entity/channel pair.
444 An attenuation of 0 will play full volume everywhere in the level.
445 Larger attenuations will drop off.
449 static void VM_SV_sound (void)
453 prvm_edict_t *entity;
457 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
459 entity = PRVM_G_EDICT(OFS_PARM0);
460 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
461 sample = PRVM_G_STRING(OFS_PARM2);
462 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
463 attenuation = PRVM_G_FLOAT(OFS_PARM4);
466 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
470 if (volume < 0 || volume > 255)
472 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
476 if (attenuation < 0 || attenuation > 4)
478 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
482 if (channel < 0 || channel > 7)
484 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
488 SV_StartSound (entity, channel, sample, volume, attenuation);
495 Follows the same logic as VM_SV_sound, except instead of
496 an entity, an origin for the sound is provided, and channel
497 is omitted (since no entity is being tracked).
501 static void VM_SV_pointsound(void)
508 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
510 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
511 sample = PRVM_G_STRING(OFS_PARM1);
512 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
513 attenuation = PRVM_G_FLOAT(OFS_PARM3);
515 if (volume < 0 || volume > 255)
517 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
521 if (attenuation < 0 || attenuation > 4)
523 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
527 SV_StartPointSound (org, sample, volume, attenuation);
534 Used for use tracing and shot targeting
535 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
536 if the tryents flag is set.
538 traceline (vector1, vector2, movetype, ignore)
541 static void VM_SV_traceline (void)
548 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
550 prog->xfunction->builtinsprofile += 30;
552 v1 = PRVM_G_VECTOR(OFS_PARM0);
553 v2 = PRVM_G_VECTOR(OFS_PARM1);
554 move = (int)PRVM_G_FLOAT(OFS_PARM2);
555 ent = PRVM_G_EDICT(OFS_PARM3);
557 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]))
558 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));
560 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
562 VM_SetTraceGlobals(&trace);
570 Used for use tracing and shot targeting
571 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
572 if the tryents flag is set.
574 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
577 // LordHavoc: added this for my own use, VERY useful, similar to traceline
578 static void VM_SV_tracebox (void)
580 float *v1, *v2, *m1, *m2;
585 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
587 prog->xfunction->builtinsprofile += 30;
589 v1 = PRVM_G_VECTOR(OFS_PARM0);
590 m1 = PRVM_G_VECTOR(OFS_PARM1);
591 m2 = PRVM_G_VECTOR(OFS_PARM2);
592 v2 = PRVM_G_VECTOR(OFS_PARM3);
593 move = (int)PRVM_G_FLOAT(OFS_PARM4);
594 ent = PRVM_G_EDICT(OFS_PARM5);
596 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]))
597 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));
599 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
601 VM_SetTraceGlobals(&trace);
604 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
609 vec3_t original_origin;
610 vec3_t original_velocity;
611 vec3_t original_angles;
612 vec3_t original_avelocity;
616 VectorCopy(tossent->fields.server->origin , original_origin );
617 VectorCopy(tossent->fields.server->velocity , original_velocity );
618 VectorCopy(tossent->fields.server->angles , original_angles );
619 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
621 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
622 if (val != NULL && val->_float != 0)
623 gravity = val->_float;
626 gravity *= sv_gravity.value * 0.05;
628 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
630 SV_CheckVelocity (tossent);
631 tossent->fields.server->velocity[2] -= gravity;
632 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
633 VectorScale (tossent->fields.server->velocity, 0.05, move);
634 VectorAdd (tossent->fields.server->origin, move, end);
635 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
636 VectorCopy (trace.endpos, tossent->fields.server->origin);
638 if (trace.fraction < 1)
642 VectorCopy(original_origin , tossent->fields.server->origin );
643 VectorCopy(original_velocity , tossent->fields.server->velocity );
644 VectorCopy(original_angles , tossent->fields.server->angles );
645 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
650 static void VM_SV_tracetoss (void)
654 prvm_edict_t *ignore;
656 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
658 prog->xfunction->builtinsprofile += 600;
660 ent = PRVM_G_EDICT(OFS_PARM0);
661 if (ent == prog->edicts)
663 VM_Warning("tracetoss: can not use world entity\n");
666 ignore = PRVM_G_EDICT(OFS_PARM1);
668 trace = SV_Trace_Toss (ent, ignore);
670 VM_SetTraceGlobals(&trace);
673 //============================================================================
675 static int checkpvsbytes;
676 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
678 static int VM_SV_newcheckclient (int check)
684 // cycle to the next one
686 check = bound(1, check, svs.maxclients);
687 if (check == svs.maxclients)
695 prog->xfunction->builtinsprofile++;
697 if (i == svs.maxclients+1)
699 // look up the client's edict
700 ent = PRVM_EDICT_NUM(i);
701 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
702 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
704 // found a valid client (possibly the same one again)
708 // get the PVS for the entity
709 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
711 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
712 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
721 Returns a client (or object that has a client enemy) that would be a
724 If there is more than one valid option, they are cycled each frame
726 If (self.origin + self.viewofs) is not in the PVS of the current target,
727 it is not returned at all.
732 int c_invis, c_notvis;
733 static void VM_SV_checkclient (void)
735 prvm_edict_t *ent, *self;
738 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
740 // find a new check if on a new frame
741 if (sv.time - sv.lastchecktime >= 0.1)
743 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
744 sv.lastchecktime = sv.time;
747 // return check if it might be visible
748 ent = PRVM_EDICT_NUM(sv.lastcheck);
749 if (ent->priv.server->free || ent->fields.server->health <= 0)
751 VM_RETURN_EDICT(prog->edicts);
755 // if current entity can't possibly see the check entity, return 0
756 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
757 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
758 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
761 VM_RETURN_EDICT(prog->edicts);
765 // might be able to see it
767 VM_RETURN_EDICT(ent);
770 //============================================================================
777 Sends text over to the client's execution buffer
779 stuffcmd (clientent, value, ...)
782 static void VM_SV_stuffcmd (void)
786 char string[VM_STRINGTEMP_LENGTH];
788 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
790 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
791 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
793 VM_Warning("Can't stuffcmd to a non-client\n");
797 VM_VarString(1, string, sizeof(string));
800 host_client = svs.clients + entnum-1;
801 Host_ClientCommands ("%s", string);
809 Returns a chain of entities that have origins within a spherical area
811 findradius (origin, radius)
814 static void VM_SV_findradius (void)
816 prvm_edict_t *ent, *chain;
817 vec_t radius, radius2;
818 vec3_t org, eorg, mins, maxs;
821 prvm_edict_t *touchedicts[MAX_EDICTS];
823 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
825 chain = (prvm_edict_t *)prog->edicts;
827 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
828 radius = PRVM_G_FLOAT(OFS_PARM1);
829 radius2 = radius * radius;
831 mins[0] = org[0] - (radius + 1);
832 mins[1] = org[1] - (radius + 1);
833 mins[2] = org[2] - (radius + 1);
834 maxs[0] = org[0] + (radius + 1);
835 maxs[1] = org[1] + (radius + 1);
836 maxs[2] = org[2] + (radius + 1);
837 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
838 if (numtouchedicts > MAX_EDICTS)
840 // this never happens
841 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
842 numtouchedicts = MAX_EDICTS;
844 for (i = 0;i < numtouchedicts;i++)
846 ent = touchedicts[i];
847 prog->xfunction->builtinsprofile++;
848 // Quake did not return non-solid entities but darkplaces does
849 // (note: this is the reason you can't blow up fallen zombies)
850 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
852 // LordHavoc: compare against bounding box rather than center so it
853 // doesn't miss large objects, and use DotProduct instead of Length
854 // for a major speedup
855 VectorSubtract(org, ent->fields.server->origin, eorg);
856 if (sv_gameplayfix_findradiusdistancetobox.integer)
858 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
859 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
860 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
863 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
864 if (DotProduct(eorg, eorg) < radius2)
866 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
871 VM_RETURN_EDICT(chain);
874 static void VM_SV_precache_sound (void)
876 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
877 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
880 static void VM_SV_precache_model (void)
882 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
883 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
884 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
891 float(float yaw, float dist[, settrace]) walkmove
894 static void VM_SV_walkmove (void)
903 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
905 // assume failure if it returns early
906 PRVM_G_FLOAT(OFS_RETURN) = 0;
908 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
909 if (ent == prog->edicts)
911 VM_Warning("walkmove: can not modify world entity\n");
914 if (ent->priv.server->free)
916 VM_Warning("walkmove: can not modify free entity\n");
919 yaw = PRVM_G_FLOAT(OFS_PARM0);
920 dist = PRVM_G_FLOAT(OFS_PARM1);
921 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
923 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
926 yaw = yaw*M_PI*2 / 360;
928 move[0] = cos(yaw)*dist;
929 move[1] = sin(yaw)*dist;
932 // save program state, because SV_movestep may call other progs
933 oldf = prog->xfunction;
934 oldself = prog->globals.server->self;
936 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
939 // restore program state
940 prog->xfunction = oldf;
941 prog->globals.server->self = oldself;
951 static void VM_SV_droptofloor (void)
957 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
959 // assume failure if it returns early
960 PRVM_G_FLOAT(OFS_RETURN) = 0;
962 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
963 if (ent == prog->edicts)
965 VM_Warning("droptofloor: can not modify world entity\n");
968 if (ent->priv.server->free)
970 VM_Warning("droptofloor: can not modify free entity\n");
974 VectorCopy (ent->fields.server->origin, end);
977 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
978 SV_UnstickEntity(ent);
980 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
981 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
984 VectorSet(offset, 0.5f * (ent->fields.server->mins[0] + ent->fields.server->maxs[0]), 0.5f * (ent->fields.server->mins[1] + ent->fields.server->maxs[1]), ent->fields.server->mins[2]);
985 VectorAdd(ent->fields.server->origin, offset, org);
986 trace = SV_Move (org, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
987 VectorSubtract(trace.endpos, offset, trace.endpos);
988 if (trace.startsolid)
990 Con_DPrintf("droptofloor at %f %f %f - COULD NOT FIX BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
991 SV_UnstickEntity(ent);
992 SV_LinkEdict (ent, false);
993 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
994 ent->fields.server->groundentity = 0;
995 PRVM_G_FLOAT(OFS_RETURN) = 1;
997 else if (trace.fraction < 1)
999 Con_DPrintf("droptofloor at %f %f %f - FIXED BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
1000 VectorCopy (trace.endpos, ent->fields.server->origin);
1001 SV_UnstickEntity(ent);
1002 SV_LinkEdict (ent, false);
1003 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1004 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1005 PRVM_G_FLOAT(OFS_RETURN) = 1;
1006 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1007 ent->priv.server->suspendedinairflag = true;
1012 if (trace.fraction != 1)
1014 if (trace.fraction < 1)
1015 VectorCopy (trace.endpos, ent->fields.server->origin);
1016 SV_LinkEdict (ent, false);
1017 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1018 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1019 PRVM_G_FLOAT(OFS_RETURN) = 1;
1020 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1021 ent->priv.server->suspendedinairflag = true;
1030 void(float style, string value) lightstyle
1033 static void VM_SV_lightstyle (void)
1040 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1042 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1043 val = PRVM_G_STRING(OFS_PARM1);
1045 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1046 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1049 // change the string in sv
1050 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1052 // send message to all clients on this server
1053 if (sv.state != ss_active)
1056 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1058 if (client->active && client->netconnection)
1060 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1061 MSG_WriteChar (&client->netconnection->message,style);
1062 MSG_WriteString (&client->netconnection->message, val);
1072 static void VM_SV_checkbottom (void)
1074 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1075 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1083 static void VM_SV_pointcontents (void)
1085 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1086 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1093 Pick a vector for the player to shoot along
1094 vector aim(entity, missilespeed)
1097 static void VM_SV_aim (void)
1099 prvm_edict_t *ent, *check, *bestent;
1100 vec3_t start, dir, end, bestdir;
1103 float dist, bestdist;
1106 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1108 // assume failure if it returns early
1109 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1110 // if sv_aim is so high it can't possibly accept anything, skip out early
1111 if (sv_aim.value >= 1)
1114 ent = PRVM_G_EDICT(OFS_PARM0);
1115 if (ent == prog->edicts)
1117 VM_Warning("aim: can not use world entity\n");
1120 if (ent->priv.server->free)
1122 VM_Warning("aim: can not use free entity\n");
1125 speed = PRVM_G_FLOAT(OFS_PARM1);
1127 VectorCopy (ent->fields.server->origin, start);
1130 // try sending a trace straight
1131 VectorCopy (prog->globals.server->v_forward, dir);
1132 VectorMA (start, 2048, dir, end);
1133 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1134 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1135 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1137 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1142 // try all possible entities
1143 VectorCopy (dir, bestdir);
1144 bestdist = sv_aim.value;
1147 check = PRVM_NEXT_EDICT(prog->edicts);
1148 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1150 prog->xfunction->builtinsprofile++;
1151 if (check->fields.server->takedamage != DAMAGE_AIM)
1155 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1156 continue; // don't aim at teammate
1157 for (j=0 ; j<3 ; j++)
1158 end[j] = check->fields.server->origin[j]
1159 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1160 VectorSubtract (end, start, dir);
1161 VectorNormalize (dir);
1162 dist = DotProduct (dir, prog->globals.server->v_forward);
1163 if (dist < bestdist)
1164 continue; // to far to turn
1165 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1166 if (tr.ent == check)
1167 { // can shoot at this one
1175 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1176 dist = DotProduct (dir, prog->globals.server->v_forward);
1177 VectorScale (prog->globals.server->v_forward, dist, end);
1179 VectorNormalize (end);
1180 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1184 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1189 ===============================================================================
1193 ===============================================================================
1196 #define MSG_BROADCAST 0 // unreliable to all
1197 #define MSG_ONE 1 // reliable to one (msg_entity)
1198 #define MSG_ALL 2 // reliable to all
1199 #define MSG_INIT 3 // write to the init string
1200 #define MSG_ENTITY 5
1202 sizebuf_t *WriteDest (void)
1208 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1212 return &sv.datagram;
1215 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1216 entnum = PRVM_NUM_FOR_EDICT(ent);
1217 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1219 VM_Warning ("WriteDest: tried to write to non-client\n");
1220 return &sv.reliable_datagram;
1223 return &svs.clients[entnum-1].netconnection->message;
1226 VM_Warning ("WriteDest: bad destination\n");
1228 return &sv.reliable_datagram;
1234 return sv.writeentitiestoclient_msg;
1240 static void VM_SV_WriteByte (void)
1242 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1243 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1246 static void VM_SV_WriteChar (void)
1248 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1249 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1252 static void VM_SV_WriteShort (void)
1254 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1255 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1258 static void VM_SV_WriteLong (void)
1260 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1261 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1264 static void VM_SV_WriteAngle (void)
1266 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1267 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1270 static void VM_SV_WriteCoord (void)
1272 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1273 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1276 static void VM_SV_WriteString (void)
1278 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1279 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1282 static void VM_SV_WriteUnterminatedString (void)
1284 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1285 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1289 static void VM_SV_WriteEntity (void)
1291 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1292 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1295 //////////////////////////////////////////////////////////
1297 static void VM_SV_makestatic (void)
1302 // allow 0 parameters due to an id1 qc bug in which this function is used
1303 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1304 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1306 if (prog->argc >= 1)
1307 ent = PRVM_G_EDICT(OFS_PARM0);
1309 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1310 if (ent == prog->edicts)
1312 VM_Warning("makestatic: can not modify world entity\n");
1315 if (ent->priv.server->free)
1317 VM_Warning("makestatic: can not modify free entity\n");
1322 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1327 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1328 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1329 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1331 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1333 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1334 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1335 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1339 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1340 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1341 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1344 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1345 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1346 for (i=0 ; i<3 ; i++)
1348 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1349 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1352 // throw the entity away now
1356 //=============================================================================
1363 static void VM_SV_setspawnparms (void)
1369 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1371 ent = PRVM_G_EDICT(OFS_PARM0);
1372 i = PRVM_NUM_FOR_EDICT(ent);
1373 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1375 Con_Print("tried to setspawnparms on a non-client\n");
1379 // copy spawn parms out of the client_t
1380 client = svs.clients + i-1;
1381 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1382 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1389 Returns a color vector indicating the lighting at the requested point.
1391 (Internal Operation note: actually measures the light beneath the point, just like
1392 the model lighting on the client)
1397 static void VM_SV_getlight (void)
1399 vec3_t ambientcolor, diffusecolor, diffusenormal;
1401 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1402 p = PRVM_G_VECTOR(OFS_PARM0);
1403 VectorClear(ambientcolor);
1404 VectorClear(diffusecolor);
1405 VectorClear(diffusenormal);
1406 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1407 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1408 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1413 unsigned char type; // 1/2/8 or other value if isn't used
1417 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1418 static int vm_customstats_last;
1420 void VM_CustomStats_Clear (void)
1424 Z_Free(vm_customstats);
1425 vm_customstats = NULL;
1426 vm_customstats_last = -1;
1430 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1438 for(i=0; i<vm_customstats_last+1 ;i++)
1440 if(!vm_customstats[i].type)
1442 switch(vm_customstats[i].type)
1444 //string as 16 bytes
1447 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1448 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1449 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1450 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1451 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1453 //float field sent as-is
1455 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1457 //integer value of float field
1459 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1467 // void(float index, float type, .void field) SV_AddStat = #232;
1468 // Set up an auto-sent player stat.
1469 // Client's get thier own fields sent to them. Index may not be less than 32.
1470 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1471 // 1: string (4 stats carrying a total of 16 charactures)
1472 // 2: float (one stat, float converted to an integer for transportation)
1473 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1474 static void VM_SV_AddStat (void)
1479 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1483 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1486 VM_Warning("PF_SV_AddStat: not enough memory\n");
1490 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1491 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1492 off = PRVM_G_INT (OFS_PARM2);
1497 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1500 if(i >= (MAX_CL_STATS-32))
1502 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1505 if(i > (MAX_CL_STATS-32-4) && type == 1)
1507 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1510 vm_customstats[i].type = type;
1511 vm_customstats[i].fieldoffset = off;
1512 if(vm_customstats_last < i)
1513 vm_customstats_last = i;
1520 copies data from one entity to another
1522 copyentity(src, dst)
1525 static void VM_SV_copyentity (void)
1527 prvm_edict_t *in, *out;
1528 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1529 in = PRVM_G_EDICT(OFS_PARM0);
1530 if (in == prog->edicts)
1532 VM_Warning("copyentity: can not read world entity\n");
1535 if (in->priv.server->free)
1537 VM_Warning("copyentity: can not read free entity\n");
1540 out = PRVM_G_EDICT(OFS_PARM1);
1541 if (out == prog->edicts)
1543 VM_Warning("copyentity: can not modify world entity\n");
1546 if (out->priv.server->free)
1548 VM_Warning("copyentity: can not modify free entity\n");
1551 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1552 SV_LinkEdict(out, false);
1560 sets the color of a client and broadcasts the update to all connected clients
1562 setcolor(clientent, value)
1565 static void VM_SV_setcolor (void)
1571 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1572 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1573 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1575 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1577 Con_Print("tried to setcolor a non-client\n");
1581 client = svs.clients + entnum-1;
1584 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1586 client->edict->fields.server->team = (i & 15) + 1;
1589 if (client->old_colors != client->colors)
1591 client->old_colors = client->colors;
1592 // send notification to all clients
1593 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1594 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1595 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1603 effect(origin, modelname, startframe, framecount, framerate)
1606 static void VM_SV_effect (void)
1610 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1611 s = PRVM_G_STRING(OFS_PARM1);
1614 VM_Warning("effect: no model specified\n");
1618 i = SV_ModelIndex(s, 1);
1621 VM_Warning("effect: model not precached\n");
1625 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1627 VM_Warning("effect: framecount < 1\n");
1631 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1633 VM_Warning("effect: framerate < 1\n");
1637 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));
1640 static void VM_SV_te_blood (void)
1642 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1643 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1645 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1646 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1648 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1649 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1650 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1652 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1653 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1654 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1656 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1657 SV_FlushBroadcastMessages();
1660 static void VM_SV_te_bloodshower (void)
1662 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1663 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1665 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1666 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1668 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1672 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1673 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1674 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1676 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1678 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1679 SV_FlushBroadcastMessages();
1682 static void VM_SV_te_explosionrgb (void)
1684 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1685 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1686 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1688 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1689 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1690 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1692 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1693 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1694 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1695 SV_FlushBroadcastMessages();
1698 static void VM_SV_te_particlecube (void)
1700 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1701 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1703 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1704 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1706 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1707 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1708 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1710 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1711 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1712 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1714 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1715 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1716 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1718 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1720 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1721 // gravity true/false
1722 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1724 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1725 SV_FlushBroadcastMessages();
1728 static void VM_SV_te_particlerain (void)
1730 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1731 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1733 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1734 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1736 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1737 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1738 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1740 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1741 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1742 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1744 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1745 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1746 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1748 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1750 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1751 SV_FlushBroadcastMessages();
1754 static void VM_SV_te_particlesnow (void)
1756 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1757 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1759 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1760 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1762 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1763 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1764 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1766 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1767 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1768 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1770 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1771 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1772 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1774 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1776 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1777 SV_FlushBroadcastMessages();
1780 static void VM_SV_te_spark (void)
1782 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1783 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1785 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1786 MSG_WriteByte(&sv.datagram, TE_SPARK);
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);
1792 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1793 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1794 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1796 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1797 SV_FlushBroadcastMessages();
1800 static void VM_SV_te_gunshotquad (void)
1802 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1803 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1804 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1806 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1807 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1808 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1809 SV_FlushBroadcastMessages();
1812 static void VM_SV_te_spikequad (void)
1814 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1815 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1816 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1818 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1819 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1820 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1821 SV_FlushBroadcastMessages();
1824 static void VM_SV_te_superspikequad (void)
1826 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1827 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1828 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1830 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1831 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1833 SV_FlushBroadcastMessages();
1836 static void VM_SV_te_explosionquad (void)
1838 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1839 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1840 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1842 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1843 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1844 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1845 SV_FlushBroadcastMessages();
1848 static void VM_SV_te_smallflash (void)
1850 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1851 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1852 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1854 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1855 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1856 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1857 SV_FlushBroadcastMessages();
1860 static void VM_SV_te_customflash (void)
1862 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1863 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1865 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1866 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1872 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1874 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1876 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1877 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1878 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1879 SV_FlushBroadcastMessages();
1882 static void VM_SV_te_gunshot (void)
1884 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1885 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1886 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1888 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1889 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1890 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1891 SV_FlushBroadcastMessages();
1894 static void VM_SV_te_spike (void)
1896 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1897 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1898 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1902 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1903 SV_FlushBroadcastMessages();
1906 static void VM_SV_te_superspike (void)
1908 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1909 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1910 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1912 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1913 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1914 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1915 SV_FlushBroadcastMessages();
1918 static void VM_SV_te_explosion (void)
1920 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1921 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1922 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1924 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1925 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1926 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1927 SV_FlushBroadcastMessages();
1930 static void VM_SV_te_tarexplosion (void)
1932 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1933 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1934 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1936 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1937 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1938 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1939 SV_FlushBroadcastMessages();
1942 static void VM_SV_te_wizspike (void)
1944 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1945 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1946 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1948 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1949 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1950 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1951 SV_FlushBroadcastMessages();
1954 static void VM_SV_te_knightspike (void)
1956 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1957 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1958 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1960 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1961 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1962 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1963 SV_FlushBroadcastMessages();
1966 static void VM_SV_te_lavasplash (void)
1968 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1969 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1970 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1974 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1975 SV_FlushBroadcastMessages();
1978 static void VM_SV_te_teleport (void)
1980 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1981 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1982 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1984 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1985 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1986 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1987 SV_FlushBroadcastMessages();
1990 static void VM_SV_te_explosion2 (void)
1992 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1993 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1994 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1996 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1997 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1998 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2000 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2001 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2002 SV_FlushBroadcastMessages();
2005 static void VM_SV_te_lightning1 (void)
2007 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2008 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2009 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2011 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2013 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2014 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2015 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2017 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2018 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2019 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2020 SV_FlushBroadcastMessages();
2023 static void VM_SV_te_lightning2 (void)
2025 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2026 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2027 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2029 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2031 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2032 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2033 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2035 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2036 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2037 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2038 SV_FlushBroadcastMessages();
2041 static void VM_SV_te_lightning3 (void)
2043 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2044 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2045 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2047 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2049 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2050 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2051 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2053 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2054 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2055 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2056 SV_FlushBroadcastMessages();
2059 static void VM_SV_te_beam (void)
2061 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2062 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2063 MSG_WriteByte(&sv.datagram, TE_BEAM);
2065 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2067 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2068 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2069 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2071 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2072 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2073 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2074 SV_FlushBroadcastMessages();
2077 static void VM_SV_te_plasmaburn (void)
2079 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2080 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2081 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2082 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2083 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2084 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2085 SV_FlushBroadcastMessages();
2088 static void VM_SV_te_flamejet (void)
2090 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2091 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2092 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2094 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2095 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2096 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2098 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2099 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2100 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2102 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2103 SV_FlushBroadcastMessages();
2106 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2109 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2111 bestdist = 1000000000;
2113 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2115 // clip original point to each triangle of the surface and find the
2116 // triangle that is closest
2117 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2118 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2119 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2120 TriangleNormal(v[0], v[1], v[2], facenormal);
2121 VectorNormalize(facenormal);
2122 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2123 VectorMA(p, offsetdist, facenormal, temp);
2124 for (j = 0, k = 2;j < 3;k = j, j++)
2126 VectorSubtract(v[k], v[j], edgenormal);
2127 CrossProduct(edgenormal, facenormal, sidenormal);
2128 VectorNormalize(sidenormal);
2129 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2131 VectorMA(temp, offsetdist, sidenormal, temp);
2133 dist = VectorDistance2(temp, p);
2134 if (bestdist > dist)
2137 VectorCopy(temp, out);
2142 static model_t *getmodel(prvm_edict_t *ed)
2145 if (!ed || ed->priv.server->free)
2147 modelindex = (int)ed->fields.server->modelindex;
2148 if (modelindex < 1 || modelindex >= MAX_MODELS)
2150 return sv.models[modelindex];
2153 static msurface_t *getsurface(model_t *model, int surfacenum)
2155 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2157 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2161 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2162 static void VM_SV_getsurfacenumpoints(void)
2165 msurface_t *surface;
2166 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2167 // return 0 if no such surface
2168 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2170 PRVM_G_FLOAT(OFS_RETURN) = 0;
2174 // note: this (incorrectly) assumes it is a simple polygon
2175 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2177 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2178 static void VM_SV_getsurfacepoint(void)
2182 msurface_t *surface;
2184 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2185 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2186 ed = PRVM_G_EDICT(OFS_PARM0);
2187 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2189 // note: this (incorrectly) assumes it is a simple polygon
2190 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2191 if (pointnum < 0 || pointnum >= surface->num_vertices)
2193 // FIXME: implement rotation/scaling
2194 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2196 //PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
2197 // float SPA_POSITION = 0;
2198 // float SPA_S_AXIS = 1;
2199 // float SPA_T_AXIS = 2;
2200 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2201 // float SPA_TEXCOORDS0 = 4;
2202 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2203 // float SPA_LIGHTMAP0_COLOR = 6;
2204 static void VM_SV_getsurfacepointattribute(void)
2208 msurface_t *surface;
2212 VM_SAFEPARMCOUNT(4, VM_SV_getsurfacepoint);
2213 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2214 ed = PRVM_G_EDICT(OFS_PARM0);
2215 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2217 // note: this (incorrectly) assumes it is a simple polygon
2218 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2219 if (pointnum < 0 || pointnum >= surface->num_vertices)
2221 // FIXME: implement rotation/scaling
2222 attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
2224 switch( attributetype ) {
2225 // float SPA_POSITION = 0;
2227 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2229 // float SPA_S_AXIS = 1;
2231 VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2233 // float SPA_T_AXIS = 2;
2235 VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2237 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2239 VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2241 // float SPA_TEXCOORDS0 = 4;
2243 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2244 float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2];
2245 ret[0] = texcoord[0];
2246 ret[1] = texcoord[1];
2250 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2252 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2253 float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2];
2254 ret[0] = texcoord[0];
2255 ret[1] = texcoord[1];
2259 // float SPA_LIGHTMAP0_COLOR = 6;
2261 // ignore alpha for now..
2262 VectorCopy( &(model->surfmesh.data_lightmapcolor4f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
2265 VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
2269 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2270 static void VM_SV_getsurfacenormal(void)
2273 msurface_t *surface;
2275 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2276 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2277 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2279 // FIXME: implement rotation/scaling
2280 // note: this (incorrectly) assumes it is a simple polygon
2281 // note: this only returns the first triangle, so it doesn't work very
2282 // well for curved surfaces or arbitrary meshes
2283 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);
2284 VectorNormalize(normal);
2285 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2287 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2288 static void VM_SV_getsurfacetexture(void)
2291 msurface_t *surface;
2292 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2293 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2294 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2296 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2298 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2299 static void VM_SV_getsurfacenearpoint(void)
2301 int surfacenum, best;
2303 vec_t dist, bestdist;
2306 msurface_t *surface;
2308 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2309 PRVM_G_FLOAT(OFS_RETURN) = -1;
2310 ed = PRVM_G_EDICT(OFS_PARM0);
2311 point = PRVM_G_VECTOR(OFS_PARM1);
2313 if (!ed || ed->priv.server->free)
2315 model = getmodel(ed);
2316 if (!model || !model->num_surfaces)
2319 // FIXME: implement rotation/scaling
2320 VectorSubtract(point, ed->fields.server->origin, p);
2322 bestdist = 1000000000;
2323 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2325 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2326 // first see if the nearest point on the surface's box is closer than the previous match
2327 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2328 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2329 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2330 dist = VectorLength2(clipped);
2331 if (dist < bestdist)
2333 // it is, check the nearest point on the actual geometry
2334 clippointtosurface(model, surface, p, clipped);
2335 VectorSubtract(clipped, p, clipped);
2336 dist += VectorLength2(clipped);
2337 if (dist < bestdist)
2339 // that's closer too, store it as the best match
2345 PRVM_G_FLOAT(OFS_RETURN) = best;
2347 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2348 static void VM_SV_getsurfaceclippedpoint(void)
2352 msurface_t *surface;
2354 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2355 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2356 ed = PRVM_G_EDICT(OFS_PARM0);
2357 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2359 // FIXME: implement rotation/scaling
2360 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2361 clippointtosurface(model, surface, p, out);
2362 // FIXME: implement rotation/scaling
2363 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2366 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2367 //this function originally written by KrimZon, made shorter by LordHavoc
2368 static void VM_SV_clientcommand (void)
2370 client_t *temp_client;
2372 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2374 //find client for this entity
2375 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2376 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2378 Con_Print("PF_clientcommand: entity is not a client\n");
2382 temp_client = host_client;
2383 host_client = svs.clients + i;
2384 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2385 host_client = temp_client;
2388 //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)
2389 static void VM_SV_setattachment (void)
2391 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2392 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2393 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2397 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2399 if (e == prog->edicts)
2401 VM_Warning("setattachment: can not modify world entity\n");
2404 if (e->priv.server->free)
2406 VM_Warning("setattachment: can not modify free entity\n");
2410 if (tagentity == NULL)
2411 tagentity = prog->edicts;
2413 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2415 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2417 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2420 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2422 modelindex = (int)tagentity->fields.server->modelindex;
2423 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2425 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2427 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);
2430 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));
2434 /////////////////////////////////////////
2435 // DP_MD3_TAGINFO extension coded by VorteX
2437 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2442 i = (int)e->fields.server->modelindex;
2443 if (i < 1 || i >= MAX_MODELS)
2445 model = sv.models[i];
2447 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2450 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2452 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2456 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);
2458 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);
2461 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2467 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2468 && (model = sv.models[(int)ent->fields.server->modelindex])
2469 && model->animscenes)
2471 // if model has wrong frame, engine automatically switches to model first frame
2472 frame = (int)ent->fields.server->frame;
2473 if (frame < 0 || frame >= model->numframes)
2475 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2477 *out = identitymatrix;
2481 // Warnings/errors code:
2482 // 0 - normal (everything all-right)
2485 // 3 - null or non-precached model
2486 // 4 - no tags with requested index
2487 // 5 - runaway loop at attachment chain
2488 extern cvar_t cl_bob;
2489 extern cvar_t cl_bobcycle;
2490 extern cvar_t cl_bobup;
2491 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2495 int modelindex, attachloop;
2496 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2499 *out = identitymatrix; // warnings and errors return identical matrix
2501 if (ent == prog->edicts)
2503 if (ent->priv.server->free)
2506 modelindex = (int)ent->fields.server->modelindex;
2507 if (modelindex <= 0 || modelindex > MAX_MODELS)
2510 model = sv.models[modelindex];
2512 tagmatrix = identitymatrix;
2513 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2517 if (attachloop >= 256) // prevent runaway looping
2519 // apply transformation by child's tagindex on parent entity and then
2520 // by parent entity itself
2521 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2522 if (ret && attachloop == 0)
2524 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2525 SV_GetEntityMatrix(ent, &entitymatrix, false);
2526 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2527 // next iteration we process the parent entity
2528 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2530 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2531 ent = PRVM_EDICT_NUM(val->edict);
2538 // RENDER_VIEWMODEL magic
2539 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2541 Matrix4x4_Copy(&tagmatrix, out);
2542 ent = PRVM_EDICT_NUM(val->edict);
2544 SV_GetEntityMatrix(ent, &entitymatrix, true);
2545 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2548 // Cl_bob, ported from rendering code
2549 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2552 // LordHavoc: this code is *weird*, but not replacable (I think it
2553 // should be done in QC on the server, but oh well, quake is quake)
2554 // LordHavoc: figured out bobup: the time at which the sin is at 180
2555 // degrees (which allows lengthening or squishing the peak or valley)
2556 cycle = sv.time/cl_bobcycle.value;
2557 cycle -= (int)cycle;
2558 if (cycle < cl_bobup.value)
2559 cycle = sin(M_PI * cycle / cl_bobup.value);
2561 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2562 // bob is proportional to velocity in the xy plane
2563 // (don't count Z, or jumping messes it up)
2564 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;
2565 bob = bob*0.3 + bob*0.7*cycle;
2566 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2573 //float(entity ent, string tagname) gettagindex;
2575 static void VM_SV_gettagindex (void)
2578 const char *tag_name;
2579 int modelindex, tag_index;
2581 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2583 ent = PRVM_G_EDICT(OFS_PARM0);
2584 tag_name = PRVM_G_STRING(OFS_PARM1);
2586 if (ent == prog->edicts)
2588 VM_Warning("gettagindex: can't affect world entity\n");
2591 if (ent->priv.server->free)
2593 VM_Warning("gettagindex: can't affect free entity\n");
2597 modelindex = (int)ent->fields.server->modelindex;
2599 if (modelindex <= 0 || modelindex > MAX_MODELS)
2600 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2603 tag_index = SV_GetTagIndex(ent, tag_name);
2605 if(developer.integer >= 100)
2606 Con_Printf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2608 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2611 //vector(entity ent, float tagindex) gettaginfo;
2612 static void VM_SV_gettaginfo (void)
2616 matrix4x4_t tag_matrix;
2619 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2621 e = PRVM_G_EDICT(OFS_PARM0);
2622 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2624 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2625 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2630 VM_Warning("gettagindex: can't affect world entity\n");
2633 VM_Warning("gettagindex: can't affect free entity\n");
2636 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2639 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2642 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2647 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2648 static void VM_SV_dropclient (void)
2651 client_t *oldhostclient;
2652 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2653 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2654 if (clientnum < 0 || clientnum >= svs.maxclients)
2656 VM_Warning("dropclient: not a client\n");
2659 if (!svs.clients[clientnum].active)
2661 VM_Warning("dropclient: that client slot is not connected\n");
2664 oldhostclient = host_client;
2665 host_client = svs.clients + clientnum;
2666 SV_DropClient(false);
2667 host_client = oldhostclient;
2670 //entity() spawnclient (DP_SV_BOTCLIENT)
2671 static void VM_SV_spawnclient (void)
2675 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2676 prog->xfunction->builtinsprofile += 2;
2678 for (i = 0;i < svs.maxclients;i++)
2680 if (!svs.clients[i].active)
2682 prog->xfunction->builtinsprofile += 100;
2683 SV_ConnectClient (i, NULL);
2684 // this has to be set or else ClientDisconnect won't be called
2685 // we assume the qc will call ClientConnect...
2686 svs.clients[i].clientconnectcalled = true;
2687 ed = PRVM_EDICT_NUM(i + 1);
2691 VM_RETURN_EDICT(ed);
2694 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2695 static void VM_SV_clienttype (void)
2698 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2699 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2700 if (clientnum < 0 || clientnum >= svs.maxclients)
2701 PRVM_G_FLOAT(OFS_RETURN) = 3;
2702 else if (!svs.clients[clientnum].active)
2703 PRVM_G_FLOAT(OFS_RETURN) = 0;
2704 else if (svs.clients[clientnum].netconnection)
2705 PRVM_G_FLOAT(OFS_RETURN) = 1;
2707 PRVM_G_FLOAT(OFS_RETURN) = 2;
2714 string(string key) serverkey
2717 void VM_SV_serverkey(void)
2719 char string[VM_STRINGTEMP_LENGTH];
2720 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2721 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2722 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2725 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2726 static void VM_SV_setmodelindex (void)
2731 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2733 e = PRVM_G_EDICT(OFS_PARM0);
2734 if (e == prog->edicts)
2736 VM_Warning("setmodelindex: can not modify world entity\n");
2739 if (e->priv.server->free)
2741 VM_Warning("setmodelindex: can not modify free entity\n");
2744 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2745 if (i <= 0 || i > MAX_MODELS)
2747 VM_Warning("setmodelindex: invalid modelindex\n");
2750 if (!sv.model_precache[i][0])
2752 VM_Warning("setmodelindex: model not precached\n");
2756 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2757 e->fields.server->modelindex = i;
2763 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2764 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2766 SetMinMaxSize (e, quakemins, quakemaxs, true);
2769 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2772 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2773 static void VM_SV_modelnameforindex (void)
2776 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2778 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2780 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2781 if (i <= 0 || i > MAX_MODELS)
2783 VM_Warning("modelnameforindex: invalid modelindex\n");
2786 if (!sv.model_precache[i][0])
2788 VM_Warning("modelnameforindex: model not precached\n");
2792 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2795 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2796 static void VM_SV_particleeffectnum (void)
2799 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2800 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2803 PRVM_G_FLOAT(OFS_RETURN) = i;
2806 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2807 static void VM_SV_trailparticles (void)
2809 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2811 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2812 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2813 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2814 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2815 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2816 SV_FlushBroadcastMessages();
2819 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2820 static void VM_SV_pointparticles (void)
2822 int effectnum, count;
2824 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2825 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2826 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2827 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2828 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2829 if (count == 1 && !VectorLength2(vel))
2832 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2833 MSG_WriteShort(&sv.datagram, effectnum);
2834 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2838 // 1+2+12+12+2=29 bytes
2839 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2840 MSG_WriteShort(&sv.datagram, effectnum);
2841 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2842 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2843 MSG_WriteShort(&sv.datagram, count);
2846 SV_FlushBroadcastMessages();
2849 prvm_builtin_t vm_sv_builtins[] = {
2850 NULL, // #0 NULL function (not callable) (QUAKE)
2851 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2852 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2853 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2854 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2855 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2856 VM_break, // #6 void() break (QUAKE)
2857 VM_random, // #7 float() random (QUAKE)
2858 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2859 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2860 VM_error, // #10 void(string e) error (QUAKE)
2861 VM_objerror, // #11 void(string e) objerror (QUAKE)
2862 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2863 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2864 VM_spawn, // #14 entity() spawn (QUAKE)
2865 VM_remove, // #15 void(entity e) remove (QUAKE)
2866 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2867 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2868 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2869 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2870 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2871 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2872 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2873 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2874 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2875 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2876 VM_ftos, // #26 string(float f) ftos (QUAKE)
2877 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2878 VM_coredump, // #28 void() coredump (QUAKE)
2879 VM_traceon, // #29 void() traceon (QUAKE)
2880 VM_traceoff, // #30 void() traceoff (QUAKE)
2881 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2882 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2883 NULL, // #33 (QUAKE)
2884 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2885 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2886 VM_rint, // #36 float(float v) rint (QUAKE)
2887 VM_floor, // #37 float(float v) floor (QUAKE)
2888 VM_ceil, // #38 float(float v) ceil (QUAKE)
2889 NULL, // #39 (QUAKE)
2890 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2891 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2892 NULL, // #42 (QUAKE)
2893 VM_fabs, // #43 float(float f) fabs (QUAKE)
2894 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2895 VM_cvar, // #45 float(string s) cvar (QUAKE)
2896 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2897 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2898 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2899 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2900 NULL, // #50 (QUAKE)
2901 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2902 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2903 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2904 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2905 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2906 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2907 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2908 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2909 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2910 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2911 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2912 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2913 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2914 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2915 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2916 NULL, // #66 (QUAKE)
2917 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2918 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2919 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2920 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2921 NULL, // #71 (QUAKE)
2922 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2923 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2924 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2925 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2926 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2927 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2928 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2929 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2930 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2931 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2932 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2933 NULL, // #83 (QUAKE)
2934 NULL, // #84 (QUAKE)
2935 NULL, // #85 (QUAKE)
2936 NULL, // #86 (QUAKE)
2937 NULL, // #87 (QUAKE)
2938 NULL, // #88 (QUAKE)
2939 NULL, // #89 (QUAKE)
2940 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2941 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2942 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2943 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2944 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2945 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2946 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2947 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2948 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2949 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2950 // FrikaC and Telejano range #100-#199
2961 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2962 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2963 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2964 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2965 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2966 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2967 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2968 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2969 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2970 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3051 // FTEQW range #200-#299
3070 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3073 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3074 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3075 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3076 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3077 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3078 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3079 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3080 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3081 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3082 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3084 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3152 // CSQC range #300-#399
3153 NULL, // #300 void() clearscene (EXT_CSQC)
3154 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3155 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3156 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3157 NULL, // #304 void() renderscene (EXT_CSQC)
3158 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3159 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3160 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3161 NULL, // #308 void() R_EndPolygon
3163 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3164 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3168 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3169 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3170 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3171 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3172 NULL, // #319 void(string name) freepic (EXT_CSQC)
3173 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3174 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3175 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3176 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3177 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3178 NULL, // #325 void(void) drawresetcliparea
3183 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3184 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3185 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3186 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3187 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3188 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3189 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3190 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3191 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3192 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3193 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3194 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3195 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3196 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3197 NULL, // #344 vector() getmousepos (EXT_CSQC)
3198 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3199 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3200 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3201 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3202 NULL, // #349 float() isdemo (EXT_CSQC)
3203 VM_isserver, // #350 float() isserver (EXT_CSQC)
3204 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3205 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3206 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3207 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3213 NULL, // #360 float() readbyte (EXT_CSQC)
3214 NULL, // #361 float() readchar (EXT_CSQC)
3215 NULL, // #362 float() readshort (EXT_CSQC)
3216 NULL, // #363 float() readlong (EXT_CSQC)
3217 NULL, // #364 float() readcoord (EXT_CSQC)
3218 NULL, // #365 float() readangle (EXT_CSQC)
3219 NULL, // #366 string() readstring (EXT_CSQC)
3220 NULL, // #367 float() readfloat (EXT_CSQC)
3253 // LordHavoc's range #400-#499
3254 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3255 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3256 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3257 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3258 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3259 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3260 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3261 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3262 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)
3263 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3264 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3265 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3266 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3267 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3268 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3269 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3270 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3271 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3272 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3273 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3274 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3275 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3276 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3277 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3278 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3279 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3280 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3281 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3282 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3283 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3284 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3285 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3286 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3287 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3288 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3289 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3290 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3291 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3292 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3293 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3294 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3295 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3296 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3297 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3298 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3299 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3300 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3301 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3302 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3303 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3304 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3305 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3306 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3307 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3308 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3309 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3310 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3311 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3313 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3314 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3315 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3316 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3317 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3318 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3319 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3320 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3321 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3322 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3323 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3325 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3326 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3327 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3328 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3329 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3330 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3331 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3332 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3333 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3334 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3335 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3336 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3337 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3338 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3339 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3340 VM_SV_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3348 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3349 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3364 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3365 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3366 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3376 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3378 void VM_SV_Cmd_Init(void)
3383 void VM_SV_Cmd_Reset(void)
3385 if(prog->funcoffsets.SV_Shutdown)
3387 func_t s = prog->funcoffsets.SV_Shutdown;
3388 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3389 PRVM_ExecuteProgram(s,"SV_Shutdown() required");