5 //============================================================================
10 char *vm_sv_extensions =
15 "DP_CON_ALIASPARAMETERS "
33 "DP_ENT_CUSTOMCOLORMAP "
34 "DP_ENT_EXTERIORMODELTOCLIENT "
36 "DP_ENT_LOWPRECISION "
39 "DP_GFX_EXTERNALTEXTURES "
40 "DP_GFX_EXTERNALTEXTURES_PERMAP "
42 "DP_GFX_QUAKE3MODELTAGS "
46 "DP_HALFLIFE_MAP_CVAR "
52 "DP_MOVETYPEBOUNCEMISSILE "
54 "DP_QC_ASINACOSATANATAN2TAN "
57 "DP_QC_CVAR_DEFSTRING "
63 "DP_QC_FINDCHAINFLAGS "
64 "DP_QC_FINDCHAINFLOAT "
72 "DP_QC_MULTIPLETEMPSTRINGS "
74 "DP_QC_SINCOSSQRTPOW "
76 "DP_QC_STRING_CASE_FUNCTIONS "
77 "DP_QC_STRINGBUFFERS "
78 "DP_QC_STRINGCOLORFUNCTIONS "
79 "DP_QC_TOKENIZEBYSEPARATOR "
82 "DP_QC_TRACE_MOVETYPE_HITMODEL "
83 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
84 "DP_QC_UNLIMITEDTEMPSTRINGS "
85 "DP_QC_VECTOANGLES_WITH_ROLL "
86 "DP_QC_VECTORVECTORS "
92 "DP_SND_DIRECTIONLESSATTNNONE "
101 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
102 "DP_SV_DRAWONLYTOCLIENT "
105 "DP_SV_ENTITYCONTENTSTRANSITION "
106 "DP_SV_ONENTITYNOSPAWNFUNCTION "
107 "DP_SV_MODELFLAGS_AS_EFFECTS "
109 "DP_SV_NODRAWTOCLIENT "
111 "DP_SV_PLAYERPHYSICS "
112 "DP_SV_POINTPARTICLES "
114 "DP_SV_PRECACHEANYTIME "
117 "DP_SV_ROTATINGBMODEL "
120 "DP_SV_WRITEUNTERMINATEDSTRING "
124 "DP_TE_EXPLOSIONRGB "
126 "DP_TE_PARTICLECUBE "
127 "DP_TE_PARTICLERAIN "
128 "DP_TE_PARTICLESNOW "
130 "DP_TE_QUADEFFECTS1 "
133 "DP_TE_STANDARDEFFECTBUILTINS "
134 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
137 //"EXT_CSQC " // not ready yet
139 "KRIMZON_SV_PARSECLIENTCOMMAND "
142 "NEXUIZ_PLAYERMODEL "
144 "PRYDON_CLIENTCURSOR "
145 "TENEBRAE_GFX_DLIGHTS "
155 "DP_QC_GETSURFACEPOINTATTRIBUTE "
163 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.
165 setorigin (entity, origin)
168 static void VM_SV_setorigin (void)
173 VM_SAFEPARMCOUNT(2, VM_setorigin);
175 e = PRVM_G_EDICT(OFS_PARM0);
176 if (e == prog->edicts)
178 VM_Warning("setorigin: can not modify world entity\n");
181 if (e->priv.server->free)
183 VM_Warning("setorigin: can not modify free entity\n");
186 org = PRVM_G_VECTOR(OFS_PARM1);
187 VectorCopy (org, e->fields.server->origin);
188 SV_LinkEdict (e, false);
191 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
192 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
196 for (i=0 ; i<3 ; i++)
198 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
200 // set derived values
201 VectorCopy (min, e->fields.server->mins);
202 VectorCopy (max, e->fields.server->maxs);
203 VectorSubtract (max, min, e->fields.server->size);
205 SV_LinkEdict (e, false);
212 the size box is rotated by the current angle
213 LordHavoc: no it isn't...
215 setsize (entity, minvector, maxvector)
218 static void VM_SV_setsize (void)
223 VM_SAFEPARMCOUNT(3, VM_setsize);
225 e = PRVM_G_EDICT(OFS_PARM0);
226 if (e == prog->edicts)
228 VM_Warning("setsize: can not modify world entity\n");
231 if (e->priv.server->free)
233 VM_Warning("setsize: can not modify free entity\n");
236 min = PRVM_G_VECTOR(OFS_PARM1);
237 max = PRVM_G_VECTOR(OFS_PARM2);
238 SetMinMaxSize (e, min, max, false);
246 setmodel(entity, model)
249 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
250 static void VM_SV_setmodel (void)
256 VM_SAFEPARMCOUNT(2, VM_setmodel);
258 e = PRVM_G_EDICT(OFS_PARM0);
259 if (e == prog->edicts)
261 VM_Warning("setmodel: can not modify world entity\n");
264 if (e->priv.server->free)
266 VM_Warning("setmodel: can not modify free entity\n");
269 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
270 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
271 e->fields.server->modelindex = i;
277 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
278 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
280 SetMinMaxSize (e, quakemins, quakemaxs, true);
283 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
290 single print to a specific client
292 sprint(clientent, value)
295 static void VM_SV_sprint (void)
299 char string[VM_STRINGTEMP_LENGTH];
301 VM_VarString(1, string, sizeof(string));
303 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
305 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
306 // LordHavoc: div0 requested that sprintto world operate like print
313 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
315 VM_Warning("tried to centerprint to a non-client\n");
319 client = svs.clients + entnum-1;
320 if (!client->netconnection)
323 MSG_WriteChar(&client->netconnection->message,svc_print);
324 MSG_WriteString(&client->netconnection->message, string);
332 single print to a specific client
334 centerprint(clientent, value)
337 static void VM_SV_centerprint (void)
341 char string[VM_STRINGTEMP_LENGTH];
343 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
345 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
347 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
349 VM_Warning("tried to centerprint to a non-client\n");
353 client = svs.clients + entnum-1;
354 if (!client->netconnection)
357 VM_VarString(1, string, sizeof(string));
358 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
359 MSG_WriteString(&client->netconnection->message, string);
366 particle(origin, color, count)
369 static void VM_SV_particle (void)
375 VM_SAFEPARMCOUNT(4, VM_SV_particle);
377 org = PRVM_G_VECTOR(OFS_PARM0);
378 dir = PRVM_G_VECTOR(OFS_PARM1);
379 color = PRVM_G_FLOAT(OFS_PARM2);
380 count = PRVM_G_FLOAT(OFS_PARM3);
381 SV_StartParticle (org, dir, (int)color, (int)count);
391 static void VM_SV_ambientsound (void)
395 float vol, attenuation;
398 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
400 pos = PRVM_G_VECTOR (OFS_PARM0);
401 samp = PRVM_G_STRING(OFS_PARM1);
402 vol = PRVM_G_FLOAT(OFS_PARM2);
403 attenuation = PRVM_G_FLOAT(OFS_PARM3);
405 // check to see if samp was properly precached
406 soundnum = SV_SoundIndex(samp, 1);
414 // add an svc_spawnambient command to the level signon packet
417 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
419 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
421 MSG_WriteVector(&sv.signon, pos, sv.protocol);
423 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
424 MSG_WriteShort (&sv.signon, soundnum);
426 MSG_WriteByte (&sv.signon, soundnum);
428 MSG_WriteByte (&sv.signon, (int)(vol*255));
429 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
437 Each entity can have eight independant sound sources, like voice,
440 Channel 0 is an auto-allocate channel, the others override anything
441 already running on that entity/channel pair.
443 An attenuation of 0 will play full volume everywhere in the level.
444 Larger attenuations will drop off.
448 static void VM_SV_sound (void)
452 prvm_edict_t *entity;
456 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
458 entity = PRVM_G_EDICT(OFS_PARM0);
459 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
460 sample = PRVM_G_STRING(OFS_PARM2);
461 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
462 attenuation = PRVM_G_FLOAT(OFS_PARM4);
465 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
469 if (volume < 0 || volume > 255)
471 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
475 if (attenuation < 0 || attenuation > 4)
477 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
481 if (channel < 0 || channel > 7)
483 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
487 SV_StartSound (entity, channel, sample, volume, attenuation);
494 Follows the same logic as VM_SV_sound, except instead of
495 an entity, an origin for the sound is provided, and channel
496 is omitted (since no entity is being tracked).
500 static void VM_SV_pointsound(void)
507 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
509 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
510 sample = PRVM_G_STRING(OFS_PARM1);
511 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
512 attenuation = PRVM_G_FLOAT(OFS_PARM3);
514 if (volume < 0 || volume > 255)
516 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
520 if (attenuation < 0 || attenuation > 4)
522 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
526 SV_StartPointSound (org, sample, volume, attenuation);
533 Used for use tracing and shot targeting
534 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
535 if the tryents flag is set.
537 traceline (vector1, vector2, movetype, ignore)
540 static void VM_SV_traceline (void)
547 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
549 prog->xfunction->builtinsprofile += 30;
551 v1 = PRVM_G_VECTOR(OFS_PARM0);
552 v2 = PRVM_G_VECTOR(OFS_PARM1);
553 move = (int)PRVM_G_FLOAT(OFS_PARM2);
554 ent = PRVM_G_EDICT(OFS_PARM3);
556 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]))
557 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));
559 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
561 VM_SetTraceGlobals(&trace);
569 Used for use tracing and shot targeting
570 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
571 if the tryents flag is set.
573 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
576 // LordHavoc: added this for my own use, VERY useful, similar to traceline
577 static void VM_SV_tracebox (void)
579 float *v1, *v2, *m1, *m2;
584 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
586 prog->xfunction->builtinsprofile += 30;
588 v1 = PRVM_G_VECTOR(OFS_PARM0);
589 m1 = PRVM_G_VECTOR(OFS_PARM1);
590 m2 = PRVM_G_VECTOR(OFS_PARM2);
591 v2 = PRVM_G_VECTOR(OFS_PARM3);
592 move = (int)PRVM_G_FLOAT(OFS_PARM4);
593 ent = PRVM_G_EDICT(OFS_PARM5);
595 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]))
596 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));
598 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
600 VM_SetTraceGlobals(&trace);
603 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
608 vec3_t original_origin;
609 vec3_t original_velocity;
610 vec3_t original_angles;
611 vec3_t original_avelocity;
615 VectorCopy(tossent->fields.server->origin , original_origin );
616 VectorCopy(tossent->fields.server->velocity , original_velocity );
617 VectorCopy(tossent->fields.server->angles , original_angles );
618 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
620 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
621 if (val != NULL && val->_float != 0)
622 gravity = val->_float;
625 gravity *= sv_gravity.value * 0.05;
627 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
629 SV_CheckVelocity (tossent);
630 tossent->fields.server->velocity[2] -= gravity;
631 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
632 VectorScale (tossent->fields.server->velocity, 0.05, move);
633 VectorAdd (tossent->fields.server->origin, move, end);
634 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
635 VectorCopy (trace.endpos, tossent->fields.server->origin);
637 if (trace.fraction < 1)
641 VectorCopy(original_origin , tossent->fields.server->origin );
642 VectorCopy(original_velocity , tossent->fields.server->velocity );
643 VectorCopy(original_angles , tossent->fields.server->angles );
644 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
649 static void VM_SV_tracetoss (void)
653 prvm_edict_t *ignore;
655 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
657 prog->xfunction->builtinsprofile += 600;
659 ent = PRVM_G_EDICT(OFS_PARM0);
660 if (ent == prog->edicts)
662 VM_Warning("tracetoss: can not use world entity\n");
665 ignore = PRVM_G_EDICT(OFS_PARM1);
667 trace = SV_Trace_Toss (ent, ignore);
669 VM_SetTraceGlobals(&trace);
672 //============================================================================
674 static int checkpvsbytes;
675 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
677 static int VM_SV_newcheckclient (int check)
683 // cycle to the next one
685 check = bound(1, check, svs.maxclients);
686 if (check == svs.maxclients)
694 prog->xfunction->builtinsprofile++;
696 if (i == svs.maxclients+1)
698 // look up the client's edict
699 ent = PRVM_EDICT_NUM(i);
700 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
701 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
703 // found a valid client (possibly the same one again)
707 // get the PVS for the entity
708 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
710 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
711 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
720 Returns a client (or object that has a client enemy) that would be a
723 If there is more than one valid option, they are cycled each frame
725 If (self.origin + self.viewofs) is not in the PVS of the current target,
726 it is not returned at all.
731 int c_invis, c_notvis;
732 static void VM_SV_checkclient (void)
734 prvm_edict_t *ent, *self;
737 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
739 // find a new check if on a new frame
740 if (sv.time - sv.lastchecktime >= 0.1)
742 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
743 sv.lastchecktime = sv.time;
746 // return check if it might be visible
747 ent = PRVM_EDICT_NUM(sv.lastcheck);
748 if (ent->priv.server->free || ent->fields.server->health <= 0)
750 VM_RETURN_EDICT(prog->edicts);
754 // if current entity can't possibly see the check entity, return 0
755 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
756 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
757 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
760 VM_RETURN_EDICT(prog->edicts);
764 // might be able to see it
766 VM_RETURN_EDICT(ent);
769 //============================================================================
776 Sends text over to the client's execution buffer
778 stuffcmd (clientent, value, ...)
781 static void VM_SV_stuffcmd (void)
785 char string[VM_STRINGTEMP_LENGTH];
787 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
789 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
790 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
792 VM_Warning("Can't stuffcmd to a non-client\n");
796 VM_VarString(1, string, sizeof(string));
799 host_client = svs.clients + entnum-1;
800 Host_ClientCommands ("%s", string);
808 Returns a chain of entities that have origins within a spherical area
810 findradius (origin, radius)
813 static void VM_SV_findradius (void)
815 prvm_edict_t *ent, *chain;
816 vec_t radius, radius2;
817 vec3_t org, eorg, mins, maxs;
820 prvm_edict_t *touchedicts[MAX_EDICTS];
822 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
824 chain = (prvm_edict_t *)prog->edicts;
826 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
827 radius = PRVM_G_FLOAT(OFS_PARM1);
828 radius2 = radius * radius;
830 mins[0] = org[0] - (radius + 1);
831 mins[1] = org[1] - (radius + 1);
832 mins[2] = org[2] - (radius + 1);
833 maxs[0] = org[0] + (radius + 1);
834 maxs[1] = org[1] + (radius + 1);
835 maxs[2] = org[2] + (radius + 1);
836 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
837 if (numtouchedicts > MAX_EDICTS)
839 // this never happens
840 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
841 numtouchedicts = MAX_EDICTS;
843 for (i = 0;i < numtouchedicts;i++)
845 ent = touchedicts[i];
846 prog->xfunction->builtinsprofile++;
847 // Quake did not return non-solid entities but darkplaces does
848 // (note: this is the reason you can't blow up fallen zombies)
849 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
851 // LordHavoc: compare against bounding box rather than center so it
852 // doesn't miss large objects, and use DotProduct instead of Length
853 // for a major speedup
854 VectorSubtract(org, ent->fields.server->origin, eorg);
855 if (sv_gameplayfix_findradiusdistancetobox.integer)
857 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
858 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
859 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
862 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
863 if (DotProduct(eorg, eorg) < radius2)
865 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
870 VM_RETURN_EDICT(chain);
873 static void VM_SV_precache_sound (void)
875 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
876 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
879 static void VM_SV_precache_model (void)
881 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
882 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
883 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
890 float(float yaw, float dist[, settrace]) walkmove
893 static void VM_SV_walkmove (void)
902 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
904 // assume failure if it returns early
905 PRVM_G_FLOAT(OFS_RETURN) = 0;
907 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
908 if (ent == prog->edicts)
910 VM_Warning("walkmove: can not modify world entity\n");
913 if (ent->priv.server->free)
915 VM_Warning("walkmove: can not modify free entity\n");
918 yaw = PRVM_G_FLOAT(OFS_PARM0);
919 dist = PRVM_G_FLOAT(OFS_PARM1);
920 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
922 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
925 yaw = yaw*M_PI*2 / 360;
927 move[0] = cos(yaw)*dist;
928 move[1] = sin(yaw)*dist;
931 // save program state, because SV_movestep may call other progs
932 oldf = prog->xfunction;
933 oldself = prog->globals.server->self;
935 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
938 // restore program state
939 prog->xfunction = oldf;
940 prog->globals.server->self = oldself;
950 static void VM_SV_droptofloor (void)
956 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
958 // assume failure if it returns early
959 PRVM_G_FLOAT(OFS_RETURN) = 0;
961 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
962 if (ent == prog->edicts)
964 VM_Warning("droptofloor: can not modify world entity\n");
967 if (ent->priv.server->free)
969 VM_Warning("droptofloor: can not modify free entity\n");
973 VectorCopy (ent->fields.server->origin, end);
976 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
977 SV_UnstickEntity(ent);
979 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
980 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
983 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]);
984 VectorAdd(ent->fields.server->origin, offset, org);
985 trace = SV_Move (org, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
986 VectorSubtract(trace.endpos, offset, trace.endpos);
987 if (trace.startsolid)
989 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]);
990 SV_UnstickEntity(ent);
991 SV_LinkEdict (ent, false);
992 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
993 ent->fields.server->groundentity = 0;
994 PRVM_G_FLOAT(OFS_RETURN) = 1;
996 else if (trace.fraction < 1)
998 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]);
999 VectorCopy (trace.endpos, ent->fields.server->origin);
1000 SV_UnstickEntity(ent);
1001 SV_LinkEdict (ent, false);
1002 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1003 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1004 PRVM_G_FLOAT(OFS_RETURN) = 1;
1005 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1006 ent->priv.server->suspendedinairflag = true;
1011 if (trace.fraction != 1)
1013 if (trace.fraction < 1)
1014 VectorCopy (trace.endpos, ent->fields.server->origin);
1015 SV_LinkEdict (ent, false);
1016 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1017 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1018 PRVM_G_FLOAT(OFS_RETURN) = 1;
1019 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1020 ent->priv.server->suspendedinairflag = true;
1029 void(float style, string value) lightstyle
1032 static void VM_SV_lightstyle (void)
1039 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1041 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1042 val = PRVM_G_STRING(OFS_PARM1);
1044 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1045 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1048 // change the string in sv
1049 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1051 // send message to all clients on this server
1052 if (sv.state != ss_active)
1055 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1057 if (client->active && client->netconnection)
1059 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1060 MSG_WriteChar (&client->netconnection->message,style);
1061 MSG_WriteString (&client->netconnection->message, val);
1071 static void VM_SV_checkbottom (void)
1073 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1074 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1082 static void VM_SV_pointcontents (void)
1084 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1085 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1092 Pick a vector for the player to shoot along
1093 vector aim(entity, missilespeed)
1096 static void VM_SV_aim (void)
1098 prvm_edict_t *ent, *check, *bestent;
1099 vec3_t start, dir, end, bestdir;
1102 float dist, bestdist;
1105 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1107 // assume failure if it returns early
1108 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1109 // if sv_aim is so high it can't possibly accept anything, skip out early
1110 if (sv_aim.value >= 1)
1113 ent = PRVM_G_EDICT(OFS_PARM0);
1114 if (ent == prog->edicts)
1116 VM_Warning("aim: can not use world entity\n");
1119 if (ent->priv.server->free)
1121 VM_Warning("aim: can not use free entity\n");
1124 speed = PRVM_G_FLOAT(OFS_PARM1);
1126 VectorCopy (ent->fields.server->origin, start);
1129 // try sending a trace straight
1130 VectorCopy (prog->globals.server->v_forward, dir);
1131 VectorMA (start, 2048, dir, end);
1132 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1133 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1134 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1136 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1141 // try all possible entities
1142 VectorCopy (dir, bestdir);
1143 bestdist = sv_aim.value;
1146 check = PRVM_NEXT_EDICT(prog->edicts);
1147 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1149 prog->xfunction->builtinsprofile++;
1150 if (check->fields.server->takedamage != DAMAGE_AIM)
1154 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1155 continue; // don't aim at teammate
1156 for (j=0 ; j<3 ; j++)
1157 end[j] = check->fields.server->origin[j]
1158 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1159 VectorSubtract (end, start, dir);
1160 VectorNormalize (dir);
1161 dist = DotProduct (dir, prog->globals.server->v_forward);
1162 if (dist < bestdist)
1163 continue; // to far to turn
1164 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1165 if (tr.ent == check)
1166 { // can shoot at this one
1174 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1175 dist = DotProduct (dir, prog->globals.server->v_forward);
1176 VectorScale (prog->globals.server->v_forward, dist, end);
1178 VectorNormalize (end);
1179 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1183 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1188 ===============================================================================
1192 ===============================================================================
1195 #define MSG_BROADCAST 0 // unreliable to all
1196 #define MSG_ONE 1 // reliable to one (msg_entity)
1197 #define MSG_ALL 2 // reliable to all
1198 #define MSG_INIT 3 // write to the init string
1199 #define MSG_ENTITY 5
1201 sizebuf_t *WriteDest (void)
1207 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1211 return &sv.datagram;
1214 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1215 entnum = PRVM_NUM_FOR_EDICT(ent);
1216 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1218 VM_Warning ("WriteDest: tried to write to non-client\n");
1219 return &sv.reliable_datagram;
1222 return &svs.clients[entnum-1].netconnection->message;
1225 VM_Warning ("WriteDest: bad destination\n");
1227 return &sv.reliable_datagram;
1233 return sv.writeentitiestoclient_msg;
1239 static void VM_SV_WriteByte (void)
1241 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1242 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1245 static void VM_SV_WriteChar (void)
1247 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1248 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1251 static void VM_SV_WriteShort (void)
1253 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1254 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1257 static void VM_SV_WriteLong (void)
1259 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1260 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1263 static void VM_SV_WriteAngle (void)
1265 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1266 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1269 static void VM_SV_WriteCoord (void)
1271 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1272 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1275 static void VM_SV_WriteString (void)
1277 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1278 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1281 static void VM_SV_WriteUnterminatedString (void)
1283 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1284 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1288 static void VM_SV_WriteEntity (void)
1290 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1291 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1294 //////////////////////////////////////////////////////////
1296 static void VM_SV_makestatic (void)
1301 // allow 0 parameters due to an id1 qc bug in which this function is used
1302 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1303 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1305 if (prog->argc >= 1)
1306 ent = PRVM_G_EDICT(OFS_PARM0);
1308 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1309 if (ent == prog->edicts)
1311 VM_Warning("makestatic: can not modify world entity\n");
1314 if (ent->priv.server->free)
1316 VM_Warning("makestatic: can not modify free entity\n");
1321 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1326 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1327 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1328 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1330 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1332 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1333 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1334 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1338 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1339 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1340 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1343 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1344 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1345 for (i=0 ; i<3 ; i++)
1347 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1348 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1351 // throw the entity away now
1355 //=============================================================================
1362 static void VM_SV_setspawnparms (void)
1368 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1370 ent = PRVM_G_EDICT(OFS_PARM0);
1371 i = PRVM_NUM_FOR_EDICT(ent);
1372 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1374 Con_Print("tried to setspawnparms on a non-client\n");
1378 // copy spawn parms out of the client_t
1379 client = svs.clients + i-1;
1380 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1381 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1388 Returns a color vector indicating the lighting at the requested point.
1390 (Internal Operation note: actually measures the light beneath the point, just like
1391 the model lighting on the client)
1396 static void VM_SV_getlight (void)
1398 vec3_t ambientcolor, diffusecolor, diffusenormal;
1400 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1401 p = PRVM_G_VECTOR(OFS_PARM0);
1402 VectorClear(ambientcolor);
1403 VectorClear(diffusecolor);
1404 VectorClear(diffusenormal);
1405 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1406 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1407 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1412 unsigned char type; // 1/2/8 or other value if isn't used
1416 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1417 static int vm_customstats_last;
1419 void VM_CustomStats_Clear (void)
1423 Z_Free(vm_customstats);
1424 vm_customstats = NULL;
1425 vm_customstats_last = -1;
1429 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1437 for(i=0; i<vm_customstats_last+1 ;i++)
1439 if(!vm_customstats[i].type)
1441 switch(vm_customstats[i].type)
1443 //string as 16 bytes
1446 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1447 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1448 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1449 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1450 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1452 //float field sent as-is
1454 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1456 //integer value of float field
1458 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1466 // void(float index, float type, .void field) SV_AddStat = #232;
1467 // Set up an auto-sent player stat.
1468 // Client's get thier own fields sent to them. Index may not be less than 32.
1469 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1470 // 1: string (4 stats carrying a total of 16 charactures)
1471 // 2: float (one stat, float converted to an integer for transportation)
1472 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1473 static void VM_SV_AddStat (void)
1478 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1482 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1485 VM_Warning("PF_SV_AddStat: not enough memory\n");
1489 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1490 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1491 off = PRVM_G_INT (OFS_PARM2);
1496 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1499 if(i >= (MAX_CL_STATS-32))
1501 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1504 if(i > (MAX_CL_STATS-32-4) && type == 1)
1506 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1509 vm_customstats[i].type = type;
1510 vm_customstats[i].fieldoffset = off;
1511 if(vm_customstats_last < i)
1512 vm_customstats_last = i;
1519 copies data from one entity to another
1521 copyentity(src, dst)
1524 static void VM_SV_copyentity (void)
1526 prvm_edict_t *in, *out;
1527 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1528 in = PRVM_G_EDICT(OFS_PARM0);
1529 if (in == prog->edicts)
1531 VM_Warning("copyentity: can not read world entity\n");
1534 if (in->priv.server->free)
1536 VM_Warning("copyentity: can not read free entity\n");
1539 out = PRVM_G_EDICT(OFS_PARM1);
1540 if (out == prog->edicts)
1542 VM_Warning("copyentity: can not modify world entity\n");
1545 if (out->priv.server->free)
1547 VM_Warning("copyentity: can not modify free entity\n");
1550 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1551 SV_LinkEdict(out, false);
1559 sets the color of a client and broadcasts the update to all connected clients
1561 setcolor(clientent, value)
1564 static void VM_SV_setcolor (void)
1570 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1571 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1572 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1574 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1576 Con_Print("tried to setcolor a non-client\n");
1580 client = svs.clients + entnum-1;
1583 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1585 client->edict->fields.server->team = (i & 15) + 1;
1588 if (client->old_colors != client->colors)
1590 client->old_colors = client->colors;
1591 // send notification to all clients
1592 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1593 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1594 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1602 effect(origin, modelname, startframe, framecount, framerate)
1605 static void VM_SV_effect (void)
1609 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1610 s = PRVM_G_STRING(OFS_PARM1);
1613 VM_Warning("effect: no model specified\n");
1617 i = SV_ModelIndex(s, 1);
1620 VM_Warning("effect: model not precached\n");
1624 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1626 VM_Warning("effect: framecount < 1\n");
1630 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1632 VM_Warning("effect: framerate < 1\n");
1636 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));
1639 static void VM_SV_te_blood (void)
1641 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1642 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1644 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1645 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1647 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1648 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1649 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1651 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1652 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1653 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1655 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1656 SV_FlushBroadcastMessages();
1659 static void VM_SV_te_bloodshower (void)
1661 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1662 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1664 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1665 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1667 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1668 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1671 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1672 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1673 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1675 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1677 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1678 SV_FlushBroadcastMessages();
1681 static void VM_SV_te_explosionrgb (void)
1683 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1684 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1685 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1687 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1688 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1689 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1691 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1692 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1693 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1694 SV_FlushBroadcastMessages();
1697 static void VM_SV_te_particlecube (void)
1699 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1700 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1702 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1703 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1705 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1706 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1707 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1709 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1710 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1711 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1713 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1714 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1715 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1717 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1719 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1720 // gravity true/false
1721 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1723 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1724 SV_FlushBroadcastMessages();
1727 static void VM_SV_te_particlerain (void)
1729 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1730 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1732 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1733 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1735 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1736 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1737 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1739 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1740 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1741 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1743 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1744 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1745 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1747 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1749 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1750 SV_FlushBroadcastMessages();
1753 static void VM_SV_te_particlesnow (void)
1755 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1756 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1758 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1759 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1761 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1762 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1763 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1765 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1766 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1767 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1769 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1770 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1771 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1773 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1775 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1776 SV_FlushBroadcastMessages();
1779 static void VM_SV_te_spark (void)
1781 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1782 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1784 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1785 MSG_WriteByte(&sv.datagram, TE_SPARK);
1787 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1788 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1791 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1792 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1793 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1795 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1796 SV_FlushBroadcastMessages();
1799 static void VM_SV_te_gunshotquad (void)
1801 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1802 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1803 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1805 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1806 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1807 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1808 SV_FlushBroadcastMessages();
1811 static void VM_SV_te_spikequad (void)
1813 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1814 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1815 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1817 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1818 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1819 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1820 SV_FlushBroadcastMessages();
1823 static void VM_SV_te_superspikequad (void)
1825 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1826 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1827 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1829 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1830 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1831 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1832 SV_FlushBroadcastMessages();
1835 static void VM_SV_te_explosionquad (void)
1837 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1838 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1839 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1841 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1842 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1843 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1844 SV_FlushBroadcastMessages();
1847 static void VM_SV_te_smallflash (void)
1849 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1850 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1851 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1853 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1854 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1855 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1856 SV_FlushBroadcastMessages();
1859 static void VM_SV_te_customflash (void)
1861 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1862 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1864 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1865 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1867 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1871 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1873 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1875 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1876 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1877 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1878 SV_FlushBroadcastMessages();
1881 static void VM_SV_te_gunshot (void)
1883 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1884 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1885 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1887 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1888 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1889 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1890 SV_FlushBroadcastMessages();
1893 static void VM_SV_te_spike (void)
1895 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1896 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1897 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1899 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1902 SV_FlushBroadcastMessages();
1905 static void VM_SV_te_superspike (void)
1907 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1908 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1909 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1911 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1912 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1913 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1914 SV_FlushBroadcastMessages();
1917 static void VM_SV_te_explosion (void)
1919 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1920 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1921 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1923 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1924 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1925 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1926 SV_FlushBroadcastMessages();
1929 static void VM_SV_te_tarexplosion (void)
1931 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1932 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1933 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1935 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1936 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1937 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1938 SV_FlushBroadcastMessages();
1941 static void VM_SV_te_wizspike (void)
1943 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1944 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1945 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1947 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1948 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1949 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1950 SV_FlushBroadcastMessages();
1953 static void VM_SV_te_knightspike (void)
1955 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1956 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1957 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1959 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1960 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1961 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1962 SV_FlushBroadcastMessages();
1965 static void VM_SV_te_lavasplash (void)
1967 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1968 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1969 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1972 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1974 SV_FlushBroadcastMessages();
1977 static void VM_SV_te_teleport (void)
1979 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1980 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1981 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1983 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1984 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1985 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1986 SV_FlushBroadcastMessages();
1989 static void VM_SV_te_explosion2 (void)
1991 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1992 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1993 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1996 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1997 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1999 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2000 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2001 SV_FlushBroadcastMessages();
2004 static void VM_SV_te_lightning1 (void)
2006 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2007 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2008 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2010 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2012 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2013 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2014 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2016 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2017 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2018 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2019 SV_FlushBroadcastMessages();
2022 static void VM_SV_te_lightning2 (void)
2024 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2025 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2026 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2028 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2030 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2031 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2032 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2034 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2035 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2036 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2037 SV_FlushBroadcastMessages();
2040 static void VM_SV_te_lightning3 (void)
2042 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2043 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2044 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2046 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2048 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2049 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2050 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2052 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2053 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2054 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2055 SV_FlushBroadcastMessages();
2058 static void VM_SV_te_beam (void)
2060 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2061 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2062 MSG_WriteByte(&sv.datagram, TE_BEAM);
2064 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2066 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2067 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2068 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2070 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2071 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2072 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2073 SV_FlushBroadcastMessages();
2076 static void VM_SV_te_plasmaburn (void)
2078 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2079 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2080 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2081 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2082 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2083 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2084 SV_FlushBroadcastMessages();
2087 static void VM_SV_te_flamejet (void)
2089 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2090 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2091 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2093 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2094 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2095 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2097 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2098 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2099 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2101 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2102 SV_FlushBroadcastMessages();
2105 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2108 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2110 bestdist = 1000000000;
2112 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2114 // clip original point to each triangle of the surface and find the
2115 // triangle that is closest
2116 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2117 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2118 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2119 TriangleNormal(v[0], v[1], v[2], facenormal);
2120 VectorNormalize(facenormal);
2121 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2122 VectorMA(p, offsetdist, facenormal, temp);
2123 for (j = 0, k = 2;j < 3;k = j, j++)
2125 VectorSubtract(v[k], v[j], edgenormal);
2126 CrossProduct(edgenormal, facenormal, sidenormal);
2127 VectorNormalize(sidenormal);
2128 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2130 VectorMA(temp, offsetdist, sidenormal, temp);
2132 dist = VectorDistance2(temp, p);
2133 if (bestdist > dist)
2136 VectorCopy(temp, out);
2141 static model_t *getmodel(prvm_edict_t *ed)
2144 if (!ed || ed->priv.server->free)
2146 modelindex = (int)ed->fields.server->modelindex;
2147 if (modelindex < 1 || modelindex >= MAX_MODELS)
2149 return sv.models[modelindex];
2152 static msurface_t *getsurface(model_t *model, int surfacenum)
2154 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2156 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2160 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2161 static void VM_SV_getsurfacenumpoints(void)
2164 msurface_t *surface;
2165 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2166 // return 0 if no such surface
2167 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2169 PRVM_G_FLOAT(OFS_RETURN) = 0;
2173 // note: this (incorrectly) assumes it is a simple polygon
2174 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2176 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2177 static void VM_SV_getsurfacepoint(void)
2181 msurface_t *surface;
2183 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2184 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2185 ed = PRVM_G_EDICT(OFS_PARM0);
2186 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2188 // note: this (incorrectly) assumes it is a simple polygon
2189 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2190 if (pointnum < 0 || pointnum >= surface->num_vertices)
2192 // FIXME: implement rotation/scaling
2193 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2195 //PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
2196 // float SPA_POSITION = 0;
2197 // float SPA_S_AXIS = 1;
2198 // float SPA_T_AXIS = 2;
2199 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2200 // float SPA_TEXCOORDS0 = 4;
2201 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2202 // float SPA_LIGHTMAP0_COLOR = 6;
2203 static void VM_SV_getsurfacepointattribute(void)
2207 msurface_t *surface;
2211 VM_SAFEPARMCOUNT(4, VM_SV_getsurfacepoint);
2212 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2213 ed = PRVM_G_EDICT(OFS_PARM0);
2214 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2216 // note: this (incorrectly) assumes it is a simple polygon
2217 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2218 if (pointnum < 0 || pointnum >= surface->num_vertices)
2220 // FIXME: implement rotation/scaling
2221 attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
2223 switch( attributetype ) {
2224 // float SPA_POSITION = 0;
2226 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2228 // float SPA_S_AXIS = 1;
2230 VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2232 // float SPA_T_AXIS = 2;
2234 VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2236 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2238 VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2240 // float SPA_TEXCOORDS0 = 4;
2242 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2243 float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2];
2244 ret[0] = texcoord[0];
2245 ret[1] = texcoord[1];
2249 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2251 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2252 float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2];
2253 ret[0] = texcoord[0];
2254 ret[1] = texcoord[1];
2258 // float SPA_LIGHTMAP0_COLOR = 6;
2260 // ignore alpha for now..
2261 VectorCopy( &(model->surfmesh.data_lightmapcolor4f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
2264 VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
2268 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2269 static void VM_SV_getsurfacenormal(void)
2272 msurface_t *surface;
2274 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2275 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2276 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2278 // FIXME: implement rotation/scaling
2279 // note: this (incorrectly) assumes it is a simple polygon
2280 // note: this only returns the first triangle, so it doesn't work very
2281 // well for curved surfaces or arbitrary meshes
2282 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);
2283 VectorNormalize(normal);
2284 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2286 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2287 static void VM_SV_getsurfacetexture(void)
2290 msurface_t *surface;
2291 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2292 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2293 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2295 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2297 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2298 static void VM_SV_getsurfacenearpoint(void)
2300 int surfacenum, best;
2302 vec_t dist, bestdist;
2305 msurface_t *surface;
2307 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2308 PRVM_G_FLOAT(OFS_RETURN) = -1;
2309 ed = PRVM_G_EDICT(OFS_PARM0);
2310 point = PRVM_G_VECTOR(OFS_PARM1);
2312 if (!ed || ed->priv.server->free)
2314 model = getmodel(ed);
2315 if (!model || !model->num_surfaces)
2318 // FIXME: implement rotation/scaling
2319 VectorSubtract(point, ed->fields.server->origin, p);
2321 bestdist = 1000000000;
2322 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2324 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2325 // first see if the nearest point on the surface's box is closer than the previous match
2326 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2327 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2328 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2329 dist = VectorLength2(clipped);
2330 if (dist < bestdist)
2332 // it is, check the nearest point on the actual geometry
2333 clippointtosurface(model, surface, p, clipped);
2334 VectorSubtract(clipped, p, clipped);
2335 dist += VectorLength2(clipped);
2336 if (dist < bestdist)
2338 // that's closer too, store it as the best match
2344 PRVM_G_FLOAT(OFS_RETURN) = best;
2346 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2347 static void VM_SV_getsurfaceclippedpoint(void)
2351 msurface_t *surface;
2353 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2354 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2355 ed = PRVM_G_EDICT(OFS_PARM0);
2356 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2358 // FIXME: implement rotation/scaling
2359 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2360 clippointtosurface(model, surface, p, out);
2361 // FIXME: implement rotation/scaling
2362 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2365 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2366 //this function originally written by KrimZon, made shorter by LordHavoc
2367 static void VM_SV_clientcommand (void)
2369 client_t *temp_client;
2371 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2373 //find client for this entity
2374 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2375 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2377 Con_Print("PF_clientcommand: entity is not a client\n");
2381 temp_client = host_client;
2382 host_client = svs.clients + i;
2383 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2384 host_client = temp_client;
2387 //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)
2388 static void VM_SV_setattachment (void)
2390 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2391 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2392 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2396 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2398 if (e == prog->edicts)
2400 VM_Warning("setattachment: can not modify world entity\n");
2403 if (e->priv.server->free)
2405 VM_Warning("setattachment: can not modify free entity\n");
2409 if (tagentity == NULL)
2410 tagentity = prog->edicts;
2412 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2414 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2416 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2419 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2421 modelindex = (int)tagentity->fields.server->modelindex;
2422 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2424 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2426 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);
2429 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));
2433 /////////////////////////////////////////
2434 // DP_MD3_TAGINFO extension coded by VorteX
2436 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2441 i = (int)e->fields.server->modelindex;
2442 if (i < 1 || i >= MAX_MODELS)
2444 model = sv.models[i];
2446 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2449 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2451 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2455 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);
2457 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);
2460 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2466 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2467 && (model = sv.models[(int)ent->fields.server->modelindex])
2468 && model->animscenes)
2470 // if model has wrong frame, engine automatically switches to model first frame
2471 frame = (int)ent->fields.server->frame;
2472 if (frame < 0 || frame >= model->numframes)
2474 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2476 *out = identitymatrix;
2480 // Warnings/errors code:
2481 // 0 - normal (everything all-right)
2484 // 3 - null or non-precached model
2485 // 4 - no tags with requested index
2486 // 5 - runaway loop at attachment chain
2487 extern cvar_t cl_bob;
2488 extern cvar_t cl_bobcycle;
2489 extern cvar_t cl_bobup;
2490 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2494 int modelindex, attachloop;
2495 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2498 *out = identitymatrix; // warnings and errors return identical matrix
2500 if (ent == prog->edicts)
2502 if (ent->priv.server->free)
2505 modelindex = (int)ent->fields.server->modelindex;
2506 if (modelindex <= 0 || modelindex > MAX_MODELS)
2509 model = sv.models[modelindex];
2511 tagmatrix = identitymatrix;
2512 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2516 if (attachloop >= 256) // prevent runaway looping
2518 // apply transformation by child's tagindex on parent entity and then
2519 // by parent entity itself
2520 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2521 if (ret && attachloop == 0)
2523 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2524 SV_GetEntityMatrix(ent, &entitymatrix, false);
2525 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2526 // next iteration we process the parent entity
2527 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2529 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2530 ent = PRVM_EDICT_NUM(val->edict);
2537 // RENDER_VIEWMODEL magic
2538 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2540 Matrix4x4_Copy(&tagmatrix, out);
2541 ent = PRVM_EDICT_NUM(val->edict);
2543 SV_GetEntityMatrix(ent, &entitymatrix, true);
2544 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2547 // Cl_bob, ported from rendering code
2548 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2551 // LordHavoc: this code is *weird*, but not replacable (I think it
2552 // should be done in QC on the server, but oh well, quake is quake)
2553 // LordHavoc: figured out bobup: the time at which the sin is at 180
2554 // degrees (which allows lengthening or squishing the peak or valley)
2555 cycle = sv.time/cl_bobcycle.value;
2556 cycle -= (int)cycle;
2557 if (cycle < cl_bobup.value)
2558 cycle = sin(M_PI * cycle / cl_bobup.value);
2560 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2561 // bob is proportional to velocity in the xy plane
2562 // (don't count Z, or jumping messes it up)
2563 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;
2564 bob = bob*0.3 + bob*0.7*cycle;
2565 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2572 //float(entity ent, string tagname) gettagindex;
2574 static void VM_SV_gettagindex (void)
2577 const char *tag_name;
2578 int modelindex, tag_index;
2580 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2582 ent = PRVM_G_EDICT(OFS_PARM0);
2583 tag_name = PRVM_G_STRING(OFS_PARM1);
2585 if (ent == prog->edicts)
2587 VM_Warning("gettagindex: can't affect world entity\n");
2590 if (ent->priv.server->free)
2592 VM_Warning("gettagindex: can't affect free entity\n");
2596 modelindex = (int)ent->fields.server->modelindex;
2598 if (modelindex <= 0 || modelindex > MAX_MODELS)
2599 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2602 tag_index = SV_GetTagIndex(ent, tag_name);
2604 if(developer.integer >= 100)
2605 Con_Printf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2607 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2610 //vector(entity ent, float tagindex) gettaginfo;
2611 static void VM_SV_gettaginfo (void)
2615 matrix4x4_t tag_matrix;
2618 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2620 e = PRVM_G_EDICT(OFS_PARM0);
2621 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2623 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2624 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2629 VM_Warning("gettagindex: can't affect world entity\n");
2632 VM_Warning("gettagindex: can't affect free entity\n");
2635 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2638 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2641 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2646 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2647 static void VM_SV_dropclient (void)
2650 client_t *oldhostclient;
2651 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2652 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2653 if (clientnum < 0 || clientnum >= svs.maxclients)
2655 VM_Warning("dropclient: not a client\n");
2658 if (!svs.clients[clientnum].active)
2660 VM_Warning("dropclient: that client slot is not connected\n");
2663 oldhostclient = host_client;
2664 host_client = svs.clients + clientnum;
2665 SV_DropClient(false);
2666 host_client = oldhostclient;
2669 //entity() spawnclient (DP_SV_BOTCLIENT)
2670 static void VM_SV_spawnclient (void)
2674 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2675 prog->xfunction->builtinsprofile += 2;
2677 for (i = 0;i < svs.maxclients;i++)
2679 if (!svs.clients[i].active)
2681 prog->xfunction->builtinsprofile += 100;
2682 SV_ConnectClient (i, NULL);
2683 // this has to be set or else ClientDisconnect won't be called
2684 // we assume the qc will call ClientConnect...
2685 svs.clients[i].clientconnectcalled = true;
2686 ed = PRVM_EDICT_NUM(i + 1);
2690 VM_RETURN_EDICT(ed);
2693 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2694 static void VM_SV_clienttype (void)
2697 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2698 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2699 if (clientnum < 0 || clientnum >= svs.maxclients)
2700 PRVM_G_FLOAT(OFS_RETURN) = 3;
2701 else if (!svs.clients[clientnum].active)
2702 PRVM_G_FLOAT(OFS_RETURN) = 0;
2703 else if (svs.clients[clientnum].netconnection)
2704 PRVM_G_FLOAT(OFS_RETURN) = 1;
2706 PRVM_G_FLOAT(OFS_RETURN) = 2;
2713 string(string key) serverkey
2716 void VM_SV_serverkey(void)
2718 char string[VM_STRINGTEMP_LENGTH];
2719 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2720 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2721 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2724 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2725 static void VM_SV_setmodelindex (void)
2730 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2732 e = PRVM_G_EDICT(OFS_PARM0);
2733 if (e == prog->edicts)
2735 VM_Warning("setmodelindex: can not modify world entity\n");
2738 if (e->priv.server->free)
2740 VM_Warning("setmodelindex: can not modify free entity\n");
2743 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2744 if (i <= 0 || i > MAX_MODELS)
2746 VM_Warning("setmodelindex: invalid modelindex\n");
2749 if (!sv.model_precache[i][0])
2751 VM_Warning("setmodelindex: model not precached\n");
2755 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2756 e->fields.server->modelindex = i;
2762 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2763 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2765 SetMinMaxSize (e, quakemins, quakemaxs, true);
2768 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2771 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2772 static void VM_SV_modelnameforindex (void)
2775 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2777 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2779 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2780 if (i <= 0 || i > MAX_MODELS)
2782 VM_Warning("modelnameforindex: invalid modelindex\n");
2785 if (!sv.model_precache[i][0])
2787 VM_Warning("modelnameforindex: model not precached\n");
2791 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2794 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2795 static void VM_SV_particleeffectnum (void)
2798 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2799 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2802 PRVM_G_FLOAT(OFS_RETURN) = i;
2805 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2806 static void VM_SV_trailparticles (void)
2808 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2810 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2811 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2812 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2813 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2814 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2815 SV_FlushBroadcastMessages();
2818 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2819 static void VM_SV_pointparticles (void)
2821 int effectnum, count;
2823 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2824 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2825 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2826 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2827 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2828 if (count == 1 && !VectorLength2(vel))
2831 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2832 MSG_WriteShort(&sv.datagram, effectnum);
2833 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2837 // 1+2+12+12+2=29 bytes
2838 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2839 MSG_WriteShort(&sv.datagram, effectnum);
2840 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2841 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2842 MSG_WriteShort(&sv.datagram, count);
2845 SV_FlushBroadcastMessages();
2848 prvm_builtin_t vm_sv_builtins[] = {
2849 NULL, // #0 NULL function (not callable) (QUAKE)
2850 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2851 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2852 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2853 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2854 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2855 VM_break, // #6 void() break (QUAKE)
2856 VM_random, // #7 float() random (QUAKE)
2857 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2858 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2859 VM_error, // #10 void(string e) error (QUAKE)
2860 VM_objerror, // #11 void(string e) objerror (QUAKE)
2861 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2862 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2863 VM_spawn, // #14 entity() spawn (QUAKE)
2864 VM_remove, // #15 void(entity e) remove (QUAKE)
2865 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2866 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2867 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2868 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2869 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2870 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2871 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2872 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2873 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2874 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2875 VM_ftos, // #26 string(float f) ftos (QUAKE)
2876 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2877 VM_coredump, // #28 void() coredump (QUAKE)
2878 VM_traceon, // #29 void() traceon (QUAKE)
2879 VM_traceoff, // #30 void() traceoff (QUAKE)
2880 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2881 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2882 NULL, // #33 (QUAKE)
2883 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2884 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2885 VM_rint, // #36 float(float v) rint (QUAKE)
2886 VM_floor, // #37 float(float v) floor (QUAKE)
2887 VM_ceil, // #38 float(float v) ceil (QUAKE)
2888 NULL, // #39 (QUAKE)
2889 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2890 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2891 NULL, // #42 (QUAKE)
2892 VM_fabs, // #43 float(float f) fabs (QUAKE)
2893 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2894 VM_cvar, // #45 float(string s) cvar (QUAKE)
2895 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2896 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2897 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2898 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2899 NULL, // #50 (QUAKE)
2900 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2901 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2902 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2903 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2904 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2905 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2906 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2907 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2908 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2909 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2910 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2911 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2912 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2913 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2914 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2915 NULL, // #66 (QUAKE)
2916 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2917 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2918 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2919 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2920 NULL, // #71 (QUAKE)
2921 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2922 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2923 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2924 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2925 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2926 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2927 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2928 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2929 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2930 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2931 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2932 NULL, // #83 (QUAKE)
2933 NULL, // #84 (QUAKE)
2934 NULL, // #85 (QUAKE)
2935 NULL, // #86 (QUAKE)
2936 NULL, // #87 (QUAKE)
2937 NULL, // #88 (QUAKE)
2938 NULL, // #89 (QUAKE)
2939 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2940 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2941 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2942 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2943 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2944 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2945 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2946 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2947 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2948 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2949 // FrikaC and Telejano range #100-#199
2960 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2961 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2962 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2963 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2964 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2965 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2966 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2967 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2968 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2969 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3050 // FTEQW range #200-#299
3069 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3072 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3073 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3074 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3075 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3076 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3077 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3078 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3079 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3080 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3081 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3083 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3151 // CSQC range #300-#399
3152 NULL, // #300 void() clearscene (EXT_CSQC)
3153 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3154 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3155 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3156 NULL, // #304 void() renderscene (EXT_CSQC)
3157 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3158 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3159 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3160 NULL, // #308 void() R_EndPolygon
3162 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3163 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3167 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3168 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3169 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3170 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3171 NULL, // #319 void(string name) freepic (EXT_CSQC)
3172 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3173 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3174 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3175 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3176 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3177 NULL, // #325 void(void) drawresetcliparea
3182 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3183 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3184 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3185 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3186 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3187 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3188 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3189 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3190 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3191 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3192 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3193 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3194 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3195 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3196 NULL, // #344 vector() getmousepos (EXT_CSQC)
3197 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3198 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3199 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3200 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3201 NULL, // #349 float() isdemo (EXT_CSQC)
3202 VM_isserver, // #350 float() isserver (EXT_CSQC)
3203 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3204 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3205 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3206 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3212 NULL, // #360 float() readbyte (EXT_CSQC)
3213 NULL, // #361 float() readchar (EXT_CSQC)
3214 NULL, // #362 float() readshort (EXT_CSQC)
3215 NULL, // #363 float() readlong (EXT_CSQC)
3216 NULL, // #364 float() readcoord (EXT_CSQC)
3217 NULL, // #365 float() readangle (EXT_CSQC)
3218 NULL, // #366 string() readstring (EXT_CSQC)
3219 NULL, // #367 float() readfloat (EXT_CSQC)
3252 // LordHavoc's range #400-#499
3253 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3254 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3255 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3256 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3257 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3258 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3259 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3260 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3261 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)
3262 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3263 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3264 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3265 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3266 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3267 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3268 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3269 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3270 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3271 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3272 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3273 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3274 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3275 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3276 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3277 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3278 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3279 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3280 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3281 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3282 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3283 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3284 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3285 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3286 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3287 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3288 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3289 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3290 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3291 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3292 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3293 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3294 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3295 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3296 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3297 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3298 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3299 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3300 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3301 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3302 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3303 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3304 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3305 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3306 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3307 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3308 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3309 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3310 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3312 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3313 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3314 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3315 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3316 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3317 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3318 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3319 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3320 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3321 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3322 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3324 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3325 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3326 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3327 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3328 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3329 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3330 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3331 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3332 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3333 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3334 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3335 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3336 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3337 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3338 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3339 VM_SV_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3347 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3348 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3363 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3364 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3375 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3377 void VM_SV_Cmd_Init(void)
3382 void VM_SV_Cmd_Reset(void)
3384 if(prog->funcoffsets.SV_Shutdown)
3386 func_t s = prog->funcoffsets.SV_Shutdown;
3387 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3388 PRVM_ExecuteProgram(s,"SV_Shutdown() required");