5 //============================================================================
10 char *vm_sv_extensions =
15 "DP_CON_ALIASPARAMETERS "
33 "DP_ENT_CUSTOMCOLORMAP "
34 "DP_ENT_EXTERIORMODELTOCLIENT "
36 "DP_ENT_LOWPRECISION "
39 "DP_GFX_EXTERNALTEXTURES "
40 "DP_GFX_EXTERNALTEXTURES_PERMAP "
42 "DP_GFX_QUAKE3MODELTAGS "
46 "DP_HALFLIFE_MAP_CVAR "
52 "DP_MOVETYPEBOUNCEMISSILE "
54 "DP_QC_ASINACOSATANATAN2TAN "
57 "DP_QC_CVAR_DEFSTRING "
61 "DP_QC_FINDCHAINFLAGS "
62 "DP_QC_FINDCHAINFLOAT "
70 "DP_QC_MULTIPLETEMPSTRINGS "
72 "DP_QC_SINCOSSQRTPOW "
74 "DP_QC_STRING_CASE_FUNCTIONS "
75 "DP_QC_STRINGBUFFERS "
76 "DP_QC_STRINGCOLORFUNCTIONS "
77 "DP_QC_TOKENIZEBYSEPARATOR "
80 "DP_QC_TRACE_MOVETYPE_HITMODEL "
81 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
82 "DP_QC_UNLIMITEDTEMPSTRINGS "
83 "DP_QC_VECTOANGLES_WITH_ROLL "
84 "DP_QC_VECTORVECTORS "
90 "DP_SND_DIRECTIONLESSATTNNONE "
99 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
100 "DP_SV_DRAWONLYTOCLIENT "
103 "DP_SV_ENTITYCONTENTSTRANSITION "
104 "DP_SV_ONENTITYNOSPAWNFUNCTION "
105 "DP_SV_MODELFLAGS_AS_EFFECTS "
107 "DP_SV_NODRAWTOCLIENT "
109 "DP_SV_PLAYERPHYSICS "
110 "DP_SV_POINTPARTICLES "
112 "DP_SV_PRECACHEANYTIME "
115 "DP_SV_ROTATINGBMODEL "
118 "DP_SV_WRITEUNTERMINATEDSTRING "
122 "DP_TE_EXPLOSIONRGB "
124 "DP_TE_PARTICLECUBE "
125 "DP_TE_PARTICLERAIN "
126 "DP_TE_PARTICLESNOW "
128 "DP_TE_QUADEFFECTS1 "
131 "DP_TE_STANDARDEFFECTBUILTINS "
132 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
135 //"EXT_CSQC " // not ready yet
137 "KRIMZON_SV_PARSECLIENTCOMMAND "
140 "NEXUIZ_PLAYERMODEL "
142 "PRYDON_CLIENTCURSOR "
143 "TENEBRAE_GFX_DLIGHTS "
153 "DP_QC_GETSURFACEPOINTATTRIBUTE "
160 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.
162 setorigin (entity, origin)
165 static void VM_SV_setorigin (void)
170 VM_SAFEPARMCOUNT(2, VM_setorigin);
172 e = PRVM_G_EDICT(OFS_PARM0);
173 if (e == prog->edicts)
175 VM_Warning("setorigin: can not modify world entity\n");
178 if (e->priv.server->free)
180 VM_Warning("setorigin: can not modify free entity\n");
183 org = PRVM_G_VECTOR(OFS_PARM1);
184 VectorCopy (org, e->fields.server->origin);
185 SV_LinkEdict (e, false);
188 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
189 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
193 for (i=0 ; i<3 ; i++)
195 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
197 // set derived values
198 VectorCopy (min, e->fields.server->mins);
199 VectorCopy (max, e->fields.server->maxs);
200 VectorSubtract (max, min, e->fields.server->size);
202 SV_LinkEdict (e, false);
209 the size box is rotated by the current angle
210 LordHavoc: no it isn't...
212 setsize (entity, minvector, maxvector)
215 static void VM_SV_setsize (void)
220 VM_SAFEPARMCOUNT(3, VM_setsize);
222 e = PRVM_G_EDICT(OFS_PARM0);
223 if (e == prog->edicts)
225 VM_Warning("setsize: can not modify world entity\n");
228 if (e->priv.server->free)
230 VM_Warning("setsize: can not modify free entity\n");
233 min = PRVM_G_VECTOR(OFS_PARM1);
234 max = PRVM_G_VECTOR(OFS_PARM2);
235 SetMinMaxSize (e, min, max, false);
243 setmodel(entity, model)
246 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
247 static void VM_SV_setmodel (void)
253 VM_SAFEPARMCOUNT(2, VM_setmodel);
255 e = PRVM_G_EDICT(OFS_PARM0);
256 if (e == prog->edicts)
258 VM_Warning("setmodel: can not modify world entity\n");
261 if (e->priv.server->free)
263 VM_Warning("setmodel: can not modify free entity\n");
266 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
267 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
268 e->fields.server->modelindex = i;
274 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
275 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
277 SetMinMaxSize (e, quakemins, quakemaxs, true);
280 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
287 single print to a specific client
289 sprint(clientent, value)
292 static void VM_SV_sprint (void)
296 char string[VM_STRINGTEMP_LENGTH];
298 VM_VarString(1, string, sizeof(string));
300 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
302 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
303 // LordHavoc: div0 requested that sprintto world operate like print
310 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
312 VM_Warning("tried to centerprint to a non-client\n");
316 client = svs.clients + entnum-1;
317 if (!client->netconnection)
320 MSG_WriteChar(&client->netconnection->message,svc_print);
321 MSG_WriteString(&client->netconnection->message, string);
329 single print to a specific client
331 centerprint(clientent, value)
334 static void VM_SV_centerprint (void)
338 char string[VM_STRINGTEMP_LENGTH];
340 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
342 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
344 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
346 VM_Warning("tried to centerprint to a non-client\n");
350 client = svs.clients + entnum-1;
351 if (!client->netconnection)
354 VM_VarString(1, string, sizeof(string));
355 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
356 MSG_WriteString(&client->netconnection->message, string);
363 particle(origin, color, count)
366 static void VM_SV_particle (void)
372 VM_SAFEPARMCOUNT(4, VM_SV_particle);
374 org = PRVM_G_VECTOR(OFS_PARM0);
375 dir = PRVM_G_VECTOR(OFS_PARM1);
376 color = PRVM_G_FLOAT(OFS_PARM2);
377 count = PRVM_G_FLOAT(OFS_PARM3);
378 SV_StartParticle (org, dir, (int)color, (int)count);
388 static void VM_SV_ambientsound (void)
392 float vol, attenuation;
395 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
397 pos = PRVM_G_VECTOR (OFS_PARM0);
398 samp = PRVM_G_STRING(OFS_PARM1);
399 vol = PRVM_G_FLOAT(OFS_PARM2);
400 attenuation = PRVM_G_FLOAT(OFS_PARM3);
402 // check to see if samp was properly precached
403 soundnum = SV_SoundIndex(samp, 1);
411 // add an svc_spawnambient command to the level signon packet
414 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
416 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
418 MSG_WriteVector(&sv.signon, pos, sv.protocol);
420 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
421 MSG_WriteShort (&sv.signon, soundnum);
423 MSG_WriteByte (&sv.signon, soundnum);
425 MSG_WriteByte (&sv.signon, (int)(vol*255));
426 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
434 Each entity can have eight independant sound sources, like voice,
437 Channel 0 is an auto-allocate channel, the others override anything
438 already running on that entity/channel pair.
440 An attenuation of 0 will play full volume everywhere in the level.
441 Larger attenuations will drop off.
445 static void VM_SV_sound (void)
449 prvm_edict_t *entity;
453 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
455 entity = PRVM_G_EDICT(OFS_PARM0);
456 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
457 sample = PRVM_G_STRING(OFS_PARM2);
458 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
459 attenuation = PRVM_G_FLOAT(OFS_PARM4);
462 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
466 if (volume < 0 || volume > 255)
468 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
472 if (attenuation < 0 || attenuation > 4)
474 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
478 if (channel < 0 || channel > 7)
480 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
484 SV_StartSound (entity, channel, sample, volume, attenuation);
491 Follows the same logic as VM_SV_sound, except instead of
492 an entity, an origin for the sound is provided, and channel
493 is omitted (since no entity is being tracked).
497 static void VM_SV_pointsound(void)
504 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
506 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
507 sample = PRVM_G_STRING(OFS_PARM1);
508 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
509 attenuation = PRVM_G_FLOAT(OFS_PARM3);
511 if (volume < 0 || volume > 255)
513 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
517 if (attenuation < 0 || attenuation > 4)
519 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
523 SV_StartPointSound (org, sample, volume, attenuation);
530 Used for use tracing and shot targeting
531 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
532 if the tryents flag is set.
534 traceline (vector1, vector2, movetype, ignore)
537 static void VM_SV_traceline (void)
544 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
546 prog->xfunction->builtinsprofile += 30;
548 v1 = PRVM_G_VECTOR(OFS_PARM0);
549 v2 = PRVM_G_VECTOR(OFS_PARM1);
550 move = (int)PRVM_G_FLOAT(OFS_PARM2);
551 ent = PRVM_G_EDICT(OFS_PARM3);
553 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]))
554 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));
556 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
558 VM_SetTraceGlobals(&trace);
566 Used for use tracing and shot targeting
567 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
568 if the tryents flag is set.
570 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
573 // LordHavoc: added this for my own use, VERY useful, similar to traceline
574 static void VM_SV_tracebox (void)
576 float *v1, *v2, *m1, *m2;
581 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
583 prog->xfunction->builtinsprofile += 30;
585 v1 = PRVM_G_VECTOR(OFS_PARM0);
586 m1 = PRVM_G_VECTOR(OFS_PARM1);
587 m2 = PRVM_G_VECTOR(OFS_PARM2);
588 v2 = PRVM_G_VECTOR(OFS_PARM3);
589 move = (int)PRVM_G_FLOAT(OFS_PARM4);
590 ent = PRVM_G_EDICT(OFS_PARM5);
592 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]))
593 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));
595 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
597 VM_SetTraceGlobals(&trace);
600 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
605 vec3_t original_origin;
606 vec3_t original_velocity;
607 vec3_t original_angles;
608 vec3_t original_avelocity;
612 VectorCopy(tossent->fields.server->origin , original_origin );
613 VectorCopy(tossent->fields.server->velocity , original_velocity );
614 VectorCopy(tossent->fields.server->angles , original_angles );
615 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
617 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
618 if (val != NULL && val->_float != 0)
619 gravity = val->_float;
622 gravity *= sv_gravity.value * 0.05;
624 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
626 SV_CheckVelocity (tossent);
627 tossent->fields.server->velocity[2] -= gravity;
628 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
629 VectorScale (tossent->fields.server->velocity, 0.05, move);
630 VectorAdd (tossent->fields.server->origin, move, end);
631 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
632 VectorCopy (trace.endpos, tossent->fields.server->origin);
634 if (trace.fraction < 1)
638 VectorCopy(original_origin , tossent->fields.server->origin );
639 VectorCopy(original_velocity , tossent->fields.server->velocity );
640 VectorCopy(original_angles , tossent->fields.server->angles );
641 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
646 static void VM_SV_tracetoss (void)
650 prvm_edict_t *ignore;
652 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
654 prog->xfunction->builtinsprofile += 600;
656 ent = PRVM_G_EDICT(OFS_PARM0);
657 if (ent == prog->edicts)
659 VM_Warning("tracetoss: can not use world entity\n");
662 ignore = PRVM_G_EDICT(OFS_PARM1);
664 trace = SV_Trace_Toss (ent, ignore);
666 VM_SetTraceGlobals(&trace);
669 //============================================================================
671 static int checkpvsbytes;
672 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
674 static int VM_SV_newcheckclient (int check)
680 // cycle to the next one
682 check = bound(1, check, svs.maxclients);
683 if (check == svs.maxclients)
691 prog->xfunction->builtinsprofile++;
693 if (i == svs.maxclients+1)
695 // look up the client's edict
696 ent = PRVM_EDICT_NUM(i);
697 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
698 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
700 // found a valid client (possibly the same one again)
704 // get the PVS for the entity
705 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
707 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
708 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
717 Returns a client (or object that has a client enemy) that would be a
720 If there is more than one valid option, they are cycled each frame
722 If (self.origin + self.viewofs) is not in the PVS of the current target,
723 it is not returned at all.
728 int c_invis, c_notvis;
729 static void VM_SV_checkclient (void)
731 prvm_edict_t *ent, *self;
734 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
736 // find a new check if on a new frame
737 if (sv.time - sv.lastchecktime >= 0.1)
739 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
740 sv.lastchecktime = sv.time;
743 // return check if it might be visible
744 ent = PRVM_EDICT_NUM(sv.lastcheck);
745 if (ent->priv.server->free || ent->fields.server->health <= 0)
747 VM_RETURN_EDICT(prog->edicts);
751 // if current entity can't possibly see the check entity, return 0
752 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
753 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
754 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
757 VM_RETURN_EDICT(prog->edicts);
761 // might be able to see it
763 VM_RETURN_EDICT(ent);
766 //============================================================================
773 Sends text over to the client's execution buffer
775 stuffcmd (clientent, value, ...)
778 static void VM_SV_stuffcmd (void)
782 char string[VM_STRINGTEMP_LENGTH];
784 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
786 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
787 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
789 VM_Warning("Can't stuffcmd to a non-client\n");
793 VM_VarString(1, string, sizeof(string));
796 host_client = svs.clients + entnum-1;
797 Host_ClientCommands ("%s", string);
805 Returns a chain of entities that have origins within a spherical area
807 findradius (origin, radius)
810 static void VM_SV_findradius (void)
812 prvm_edict_t *ent, *chain;
813 vec_t radius, radius2;
814 vec3_t org, eorg, mins, maxs;
817 prvm_edict_t *touchedicts[MAX_EDICTS];
819 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
821 chain = (prvm_edict_t *)prog->edicts;
823 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
824 radius = PRVM_G_FLOAT(OFS_PARM1);
825 radius2 = radius * radius;
827 mins[0] = org[0] - (radius + 1);
828 mins[1] = org[1] - (radius + 1);
829 mins[2] = org[2] - (radius + 1);
830 maxs[0] = org[0] + (radius + 1);
831 maxs[1] = org[1] + (radius + 1);
832 maxs[2] = org[2] + (radius + 1);
833 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
834 if (numtouchedicts > MAX_EDICTS)
836 // this never happens
837 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
838 numtouchedicts = MAX_EDICTS;
840 for (i = 0;i < numtouchedicts;i++)
842 ent = touchedicts[i];
843 prog->xfunction->builtinsprofile++;
844 // Quake did not return non-solid entities but darkplaces does
845 // (note: this is the reason you can't blow up fallen zombies)
846 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
848 // LordHavoc: compare against bounding box rather than center so it
849 // doesn't miss large objects, and use DotProduct instead of Length
850 // for a major speedup
851 VectorSubtract(org, ent->fields.server->origin, eorg);
852 if (sv_gameplayfix_findradiusdistancetobox.integer)
854 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
855 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
856 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
859 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
860 if (DotProduct(eorg, eorg) < radius2)
862 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
867 VM_RETURN_EDICT(chain);
870 static void VM_SV_precache_sound (void)
872 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
873 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
876 static void VM_SV_precache_model (void)
878 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
879 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
880 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
887 float(float yaw, float dist[, settrace]) walkmove
890 static void VM_SV_walkmove (void)
899 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
901 // assume failure if it returns early
902 PRVM_G_FLOAT(OFS_RETURN) = 0;
904 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
905 if (ent == prog->edicts)
907 VM_Warning("walkmove: can not modify world entity\n");
910 if (ent->priv.server->free)
912 VM_Warning("walkmove: can not modify free entity\n");
915 yaw = PRVM_G_FLOAT(OFS_PARM0);
916 dist = PRVM_G_FLOAT(OFS_PARM1);
917 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
919 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
922 yaw = yaw*M_PI*2 / 360;
924 move[0] = cos(yaw)*dist;
925 move[1] = sin(yaw)*dist;
928 // save program state, because SV_movestep may call other progs
929 oldf = prog->xfunction;
930 oldself = prog->globals.server->self;
932 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
935 // restore program state
936 prog->xfunction = oldf;
937 prog->globals.server->self = oldself;
947 static void VM_SV_droptofloor (void)
953 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
955 // assume failure if it returns early
956 PRVM_G_FLOAT(OFS_RETURN) = 0;
958 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
959 if (ent == prog->edicts)
961 VM_Warning("droptofloor: can not modify world entity\n");
964 if (ent->priv.server->free)
966 VM_Warning("droptofloor: can not modify free entity\n");
970 VectorCopy (ent->fields.server->origin, end);
973 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
975 if (trace.fraction != 1 || (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer))
977 if (trace.fraction < 1)
978 VectorCopy (trace.endpos, ent->fields.server->origin);
979 SV_LinkEdict (ent, false);
980 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
981 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
982 PRVM_G_FLOAT(OFS_RETURN) = 1;
983 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
984 ent->priv.server->suspendedinairflag = true;
992 void(float style, string value) lightstyle
995 static void VM_SV_lightstyle (void)
1002 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1004 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1005 val = PRVM_G_STRING(OFS_PARM1);
1007 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1008 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1011 // change the string in sv
1012 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1014 // send message to all clients on this server
1015 if (sv.state != ss_active)
1018 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1020 if (client->active && client->netconnection)
1022 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1023 MSG_WriteChar (&client->netconnection->message,style);
1024 MSG_WriteString (&client->netconnection->message, val);
1034 static void VM_SV_checkbottom (void)
1036 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1037 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1045 static void VM_SV_pointcontents (void)
1047 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1048 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1055 Pick a vector for the player to shoot along
1056 vector aim(entity, missilespeed)
1059 static void VM_SV_aim (void)
1061 prvm_edict_t *ent, *check, *bestent;
1062 vec3_t start, dir, end, bestdir;
1065 float dist, bestdist;
1068 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1070 // assume failure if it returns early
1071 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1072 // if sv_aim is so high it can't possibly accept anything, skip out early
1073 if (sv_aim.value >= 1)
1076 ent = PRVM_G_EDICT(OFS_PARM0);
1077 if (ent == prog->edicts)
1079 VM_Warning("aim: can not use world entity\n");
1082 if (ent->priv.server->free)
1084 VM_Warning("aim: can not use free entity\n");
1087 speed = PRVM_G_FLOAT(OFS_PARM1);
1089 VectorCopy (ent->fields.server->origin, start);
1092 // try sending a trace straight
1093 VectorCopy (prog->globals.server->v_forward, dir);
1094 VectorMA (start, 2048, dir, end);
1095 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1096 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1097 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1099 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1104 // try all possible entities
1105 VectorCopy (dir, bestdir);
1106 bestdist = sv_aim.value;
1109 check = PRVM_NEXT_EDICT(prog->edicts);
1110 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1112 prog->xfunction->builtinsprofile++;
1113 if (check->fields.server->takedamage != DAMAGE_AIM)
1117 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1118 continue; // don't aim at teammate
1119 for (j=0 ; j<3 ; j++)
1120 end[j] = check->fields.server->origin[j]
1121 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1122 VectorSubtract (end, start, dir);
1123 VectorNormalize (dir);
1124 dist = DotProduct (dir, prog->globals.server->v_forward);
1125 if (dist < bestdist)
1126 continue; // to far to turn
1127 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1128 if (tr.ent == check)
1129 { // can shoot at this one
1137 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1138 dist = DotProduct (dir, prog->globals.server->v_forward);
1139 VectorScale (prog->globals.server->v_forward, dist, end);
1141 VectorNormalize (end);
1142 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1146 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1151 ===============================================================================
1155 ===============================================================================
1158 #define MSG_BROADCAST 0 // unreliable to all
1159 #define MSG_ONE 1 // reliable to one (msg_entity)
1160 #define MSG_ALL 2 // reliable to all
1161 #define MSG_INIT 3 // write to the init string
1162 #define MSG_ENTITY 5
1164 sizebuf_t *WriteDest (void)
1170 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1174 return &sv.datagram;
1177 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1178 entnum = PRVM_NUM_FOR_EDICT(ent);
1179 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1181 VM_Warning ("WriteDest: tried to write to non-client\n");
1182 return &sv.reliable_datagram;
1185 return &svs.clients[entnum-1].netconnection->message;
1188 VM_Warning ("WriteDest: bad destination\n");
1190 return &sv.reliable_datagram;
1196 return sv.writeentitiestoclient_msg;
1202 static void VM_SV_WriteByte (void)
1204 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1205 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1208 static void VM_SV_WriteChar (void)
1210 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1211 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1214 static void VM_SV_WriteShort (void)
1216 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1217 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1220 static void VM_SV_WriteLong (void)
1222 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1223 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1226 static void VM_SV_WriteAngle (void)
1228 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1229 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1232 static void VM_SV_WriteCoord (void)
1234 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1235 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1238 static void VM_SV_WriteString (void)
1240 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1241 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1244 static void VM_SV_WriteUnterminatedString (void)
1246 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1247 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1251 static void VM_SV_WriteEntity (void)
1253 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1254 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1257 //////////////////////////////////////////////////////////
1259 static void VM_SV_makestatic (void)
1264 // allow 0 parameters due to an id1 qc bug in which this function is used
1265 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1266 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1268 if (prog->argc >= 1)
1269 ent = PRVM_G_EDICT(OFS_PARM0);
1271 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1272 if (ent == prog->edicts)
1274 VM_Warning("makestatic: can not modify world entity\n");
1277 if (ent->priv.server->free)
1279 VM_Warning("makestatic: can not modify free entity\n");
1284 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1289 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1290 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1291 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1293 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1295 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1296 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1297 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1301 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1302 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1303 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1306 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1307 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1308 for (i=0 ; i<3 ; i++)
1310 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1311 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1314 // throw the entity away now
1318 //=============================================================================
1325 static void VM_SV_setspawnparms (void)
1331 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1333 ent = PRVM_G_EDICT(OFS_PARM0);
1334 i = PRVM_NUM_FOR_EDICT(ent);
1335 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1337 Con_Print("tried to setspawnparms on a non-client\n");
1341 // copy spawn parms out of the client_t
1342 client = svs.clients + i-1;
1343 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1344 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1351 Returns a color vector indicating the lighting at the requested point.
1353 (Internal Operation note: actually measures the light beneath the point, just like
1354 the model lighting on the client)
1359 static void VM_SV_getlight (void)
1361 vec3_t ambientcolor, diffusecolor, diffusenormal;
1363 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1364 p = PRVM_G_VECTOR(OFS_PARM0);
1365 VectorClear(ambientcolor);
1366 VectorClear(diffusecolor);
1367 VectorClear(diffusenormal);
1368 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1369 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1370 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1375 unsigned char type; // 1/2/8 or other value if isn't used
1379 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1380 static int vm_customstats_last;
1382 void VM_CustomStats_Clear (void)
1386 Z_Free(vm_customstats);
1387 vm_customstats = NULL;
1388 vm_customstats_last = -1;
1392 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1400 for(i=0; i<vm_customstats_last+1 ;i++)
1402 if(!vm_customstats[i].type)
1404 switch(vm_customstats[i].type)
1406 //string as 16 bytes
1409 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1410 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1411 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1412 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1413 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1415 //float field sent as-is
1417 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1419 //integer value of float field
1421 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1429 // void(float index, float type, .void field) SV_AddStat = #232;
1430 // Set up an auto-sent player stat.
1431 // Client's get thier own fields sent to them. Index may not be less than 32.
1432 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1433 // 1: string (4 stats carrying a total of 16 charactures)
1434 // 2: float (one stat, float converted to an integer for transportation)
1435 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1436 static void VM_SV_AddStat (void)
1441 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1445 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1448 VM_Warning("PF_SV_AddStat: not enough memory\n");
1452 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1453 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1454 off = PRVM_G_INT (OFS_PARM2);
1459 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1462 if(i >= (MAX_CL_STATS-32))
1464 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1467 if(i > (MAX_CL_STATS-32-4) && type == 1)
1469 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1472 vm_customstats[i].type = type;
1473 vm_customstats[i].fieldoffset = off;
1474 if(vm_customstats_last < i)
1475 vm_customstats_last = i;
1482 copies data from one entity to another
1484 copyentity(src, dst)
1487 static void VM_SV_copyentity (void)
1489 prvm_edict_t *in, *out;
1490 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1491 in = PRVM_G_EDICT(OFS_PARM0);
1492 if (in == prog->edicts)
1494 VM_Warning("copyentity: can not read world entity\n");
1497 if (in->priv.server->free)
1499 VM_Warning("copyentity: can not read free entity\n");
1502 out = PRVM_G_EDICT(OFS_PARM1);
1503 if (out == prog->edicts)
1505 VM_Warning("copyentity: can not modify world entity\n");
1508 if (out->priv.server->free)
1510 VM_Warning("copyentity: can not modify free entity\n");
1513 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1514 SV_LinkEdict(out, false);
1522 sets the color of a client and broadcasts the update to all connected clients
1524 setcolor(clientent, value)
1527 static void VM_SV_setcolor (void)
1533 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1534 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1535 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1537 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1539 Con_Print("tried to setcolor a non-client\n");
1543 client = svs.clients + entnum-1;
1546 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1548 client->edict->fields.server->team = (i & 15) + 1;
1551 if (client->old_colors != client->colors)
1553 client->old_colors = client->colors;
1554 // send notification to all clients
1555 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1556 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1557 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1565 effect(origin, modelname, startframe, framecount, framerate)
1568 static void VM_SV_effect (void)
1572 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1573 s = PRVM_G_STRING(OFS_PARM1);
1576 VM_Warning("effect: no model specified\n");
1580 i = SV_ModelIndex(s, 1);
1583 VM_Warning("effect: model not precached\n");
1587 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1589 VM_Warning("effect: framecount < 1\n");
1593 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1595 VM_Warning("effect: framerate < 1\n");
1599 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));
1602 static void VM_SV_te_blood (void)
1604 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1605 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1607 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1608 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1610 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1611 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1612 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1614 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1615 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1616 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1618 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1619 SV_FlushBroadcastMessages();
1622 static void VM_SV_te_bloodshower (void)
1624 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1625 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1627 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1628 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1630 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1631 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1632 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1634 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1635 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1636 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1638 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1640 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1641 SV_FlushBroadcastMessages();
1644 static void VM_SV_te_explosionrgb (void)
1646 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1647 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1648 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1650 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1651 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1652 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1654 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1655 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1656 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1657 SV_FlushBroadcastMessages();
1660 static void VM_SV_te_particlecube (void)
1662 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1663 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1665 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1666 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1668 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1669 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1670 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1672 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1673 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1674 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1676 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1677 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1678 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1680 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1682 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1683 // gravity true/false
1684 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1686 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1687 SV_FlushBroadcastMessages();
1690 static void VM_SV_te_particlerain (void)
1692 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1693 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1695 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1696 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1698 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1699 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1700 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1702 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1703 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1704 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1706 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1707 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1708 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1710 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1712 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1713 SV_FlushBroadcastMessages();
1716 static void VM_SV_te_particlesnow (void)
1718 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1719 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1721 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1722 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1724 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1725 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1726 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1728 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1729 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1730 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1732 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1733 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1734 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1736 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1738 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1739 SV_FlushBroadcastMessages();
1742 static void VM_SV_te_spark (void)
1744 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1745 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1747 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1748 MSG_WriteByte(&sv.datagram, TE_SPARK);
1750 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1751 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1752 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1754 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1755 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1756 MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1758 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1759 SV_FlushBroadcastMessages();
1762 static void VM_SV_te_gunshotquad (void)
1764 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1765 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1766 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1768 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1769 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1770 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1771 SV_FlushBroadcastMessages();
1774 static void VM_SV_te_spikequad (void)
1776 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1777 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1778 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1780 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1781 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1782 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1783 SV_FlushBroadcastMessages();
1786 static void VM_SV_te_superspikequad (void)
1788 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1789 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1790 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1792 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1793 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1794 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1795 SV_FlushBroadcastMessages();
1798 static void VM_SV_te_explosionquad (void)
1800 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1801 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1802 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1804 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1805 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1806 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1807 SV_FlushBroadcastMessages();
1810 static void VM_SV_te_smallflash (void)
1812 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1813 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1814 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1816 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1817 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1818 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1819 SV_FlushBroadcastMessages();
1822 static void VM_SV_te_customflash (void)
1824 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1825 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1827 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1828 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1830 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1831 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1834 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1836 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1838 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1839 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1840 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1841 SV_FlushBroadcastMessages();
1844 static void VM_SV_te_gunshot (void)
1846 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1847 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1848 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1850 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1851 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1852 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1853 SV_FlushBroadcastMessages();
1856 static void VM_SV_te_spike (void)
1858 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1859 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1860 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1862 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1863 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1864 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1865 SV_FlushBroadcastMessages();
1868 static void VM_SV_te_superspike (void)
1870 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1871 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1872 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1874 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1875 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1876 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1877 SV_FlushBroadcastMessages();
1880 static void VM_SV_te_explosion (void)
1882 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1883 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1884 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1886 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1887 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1888 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1889 SV_FlushBroadcastMessages();
1892 static void VM_SV_te_tarexplosion (void)
1894 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1895 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1896 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1898 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1899 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1901 SV_FlushBroadcastMessages();
1904 static void VM_SV_te_wizspike (void)
1906 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1907 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1908 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1910 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1911 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1912 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1913 SV_FlushBroadcastMessages();
1916 static void VM_SV_te_knightspike (void)
1918 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1919 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1920 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
1922 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1923 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1924 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1925 SV_FlushBroadcastMessages();
1928 static void VM_SV_te_lavasplash (void)
1930 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
1931 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1932 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
1934 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1935 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1936 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1937 SV_FlushBroadcastMessages();
1940 static void VM_SV_te_teleport (void)
1942 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
1943 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1944 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
1946 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1947 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1948 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1949 SV_FlushBroadcastMessages();
1952 static void VM_SV_te_explosion2 (void)
1954 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
1955 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1956 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
1958 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1959 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1960 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1962 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
1963 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
1964 SV_FlushBroadcastMessages();
1967 static void VM_SV_te_lightning1 (void)
1969 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
1970 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1971 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
1973 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1976 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1977 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1979 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1980 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1981 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1982 SV_FlushBroadcastMessages();
1985 static void VM_SV_te_lightning2 (void)
1987 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
1988 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1989 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
1991 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
1993 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1994 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1997 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1998 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1999 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2000 SV_FlushBroadcastMessages();
2003 static void VM_SV_te_lightning3 (void)
2005 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2006 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2007 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2009 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2011 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2012 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2013 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2015 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2016 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2017 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2018 SV_FlushBroadcastMessages();
2021 static void VM_SV_te_beam (void)
2023 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2024 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2025 MSG_WriteByte(&sv.datagram, TE_BEAM);
2027 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2029 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2030 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2031 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2033 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2034 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2035 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2036 SV_FlushBroadcastMessages();
2039 static void VM_SV_te_plasmaburn (void)
2041 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2042 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2043 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2044 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2045 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2046 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2047 SV_FlushBroadcastMessages();
2050 static void VM_SV_te_flamejet (void)
2052 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2053 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2054 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2056 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2057 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2058 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2060 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2061 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2062 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2064 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2065 SV_FlushBroadcastMessages();
2068 void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2071 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2073 bestdist = 1000000000;
2075 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2077 // clip original point to each triangle of the surface and find the
2078 // triangle that is closest
2079 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2080 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2081 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2082 TriangleNormal(v[0], v[1], v[2], facenormal);
2083 VectorNormalize(facenormal);
2084 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2085 VectorMA(p, offsetdist, facenormal, temp);
2086 for (j = 0, k = 2;j < 3;k = j, j++)
2088 VectorSubtract(v[k], v[j], edgenormal);
2089 CrossProduct(edgenormal, facenormal, sidenormal);
2090 VectorNormalize(sidenormal);
2091 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2093 VectorMA(temp, offsetdist, sidenormal, temp);
2095 dist = VectorDistance2(temp, p);
2096 if (bestdist > dist)
2099 VectorCopy(temp, out);
2104 static model_t *getmodel(prvm_edict_t *ed)
2107 if (!ed || ed->priv.server->free)
2109 modelindex = (int)ed->fields.server->modelindex;
2110 if (modelindex < 1 || modelindex >= MAX_MODELS)
2112 return sv.models[modelindex];
2115 static msurface_t *getsurface(model_t *model, int surfacenum)
2117 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2119 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2123 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2124 static void VM_SV_getsurfacenumpoints(void)
2127 msurface_t *surface;
2128 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2129 // return 0 if no such surface
2130 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2132 PRVM_G_FLOAT(OFS_RETURN) = 0;
2136 // note: this (incorrectly) assumes it is a simple polygon
2137 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2139 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2140 static void VM_SV_getsurfacepoint(void)
2144 msurface_t *surface;
2146 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2147 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2148 ed = PRVM_G_EDICT(OFS_PARM0);
2149 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2151 // note: this (incorrectly) assumes it is a simple polygon
2152 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2153 if (pointnum < 0 || pointnum >= surface->num_vertices)
2155 // FIXME: implement rotation/scaling
2156 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2158 //PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
2159 // float SPA_POSITION = 0;
2160 // float SPA_S_AXIS = 1;
2161 // float SPA_T_AXIS = 2;
2162 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2163 // float SPA_TEXCOORDS0 = 4;
2164 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2165 // float SPA_LIGHTMAP0_COLOR = 6;
2166 static void VM_SV_getsurfacepointattribute(void)
2170 msurface_t *surface;
2174 VM_SAFEPARMCOUNT(4, VM_SV_getsurfacepoint);
2175 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2176 ed = PRVM_G_EDICT(OFS_PARM0);
2177 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2179 // note: this (incorrectly) assumes it is a simple polygon
2180 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2181 if (pointnum < 0 || pointnum >= surface->num_vertices)
2183 // FIXME: implement rotation/scaling
2184 attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
2186 switch( attributetype ) {
2187 // float SPA_POSITION = 0;
2189 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2191 // float SPA_S_AXIS = 1;
2193 VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2195 // float SPA_T_AXIS = 2;
2197 VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2199 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2201 VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2203 // float SPA_TEXCOORDS0 = 4;
2205 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2206 float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2];
2207 ret[0] = texcoord[0];
2208 ret[1] = texcoord[1];
2212 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2214 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2215 float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2];
2216 ret[0] = texcoord[0];
2217 ret[1] = texcoord[1];
2221 // float SPA_LIGHTMAP0_COLOR = 6;
2223 // ignore alpha for now..
2224 VectorCopy( &(model->surfmesh.data_lightmapcolor4f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
2227 VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
2231 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2232 static void VM_SV_getsurfacenormal(void)
2235 msurface_t *surface;
2237 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2238 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2239 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2241 // FIXME: implement rotation/scaling
2242 // note: this (incorrectly) assumes it is a simple polygon
2243 // note: this only returns the first triangle, so it doesn't work very
2244 // well for curved surfaces or arbitrary meshes
2245 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);
2246 VectorNormalize(normal);
2247 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2249 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2250 static void VM_SV_getsurfacetexture(void)
2253 msurface_t *surface;
2254 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2255 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2256 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2258 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2260 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2261 static void VM_SV_getsurfacenearpoint(void)
2263 int surfacenum, best;
2265 vec_t dist, bestdist;
2268 msurface_t *surface;
2270 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2271 PRVM_G_FLOAT(OFS_RETURN) = -1;
2272 ed = PRVM_G_EDICT(OFS_PARM0);
2273 point = PRVM_G_VECTOR(OFS_PARM1);
2275 if (!ed || ed->priv.server->free)
2277 model = getmodel(ed);
2278 if (!model || !model->num_surfaces)
2281 // FIXME: implement rotation/scaling
2282 VectorSubtract(point, ed->fields.server->origin, p);
2284 bestdist = 1000000000;
2285 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2287 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2288 // first see if the nearest point on the surface's box is closer than the previous match
2289 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2290 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2291 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2292 dist = VectorLength2(clipped);
2293 if (dist < bestdist)
2295 // it is, check the nearest point on the actual geometry
2296 clippointtosurface(model, surface, p, clipped);
2297 VectorSubtract(clipped, p, clipped);
2298 dist += VectorLength2(clipped);
2299 if (dist < bestdist)
2301 // that's closer too, store it as the best match
2307 PRVM_G_FLOAT(OFS_RETURN) = best;
2309 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2310 static void VM_SV_getsurfaceclippedpoint(void)
2314 msurface_t *surface;
2316 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2317 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2318 ed = PRVM_G_EDICT(OFS_PARM0);
2319 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2321 // FIXME: implement rotation/scaling
2322 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2323 clippointtosurface(model, surface, p, out);
2324 // FIXME: implement rotation/scaling
2325 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2328 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2329 //this function originally written by KrimZon, made shorter by LordHavoc
2330 static void VM_SV_clientcommand (void)
2332 client_t *temp_client;
2334 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2336 //find client for this entity
2337 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2338 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2340 Con_Print("PF_clientcommand: entity is not a client\n");
2344 temp_client = host_client;
2345 host_client = svs.clients + i;
2346 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2347 host_client = temp_client;
2350 //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)
2351 static void VM_SV_setattachment (void)
2353 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2354 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2355 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2359 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2361 if (e == prog->edicts)
2363 VM_Warning("setattachment: can not modify world entity\n");
2366 if (e->priv.server->free)
2368 VM_Warning("setattachment: can not modify free entity\n");
2372 if (tagentity == NULL)
2373 tagentity = prog->edicts;
2375 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2377 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2379 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2382 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2384 modelindex = (int)tagentity->fields.server->modelindex;
2385 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2387 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2389 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);
2392 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));
2396 /////////////////////////////////////////
2397 // DP_MD3_TAGINFO extension coded by VorteX
2399 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2404 i = (int)e->fields.server->modelindex;
2405 if (i < 1 || i >= MAX_MODELS)
2407 model = sv.models[i];
2409 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2412 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2414 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2418 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);
2420 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);
2423 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2429 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2430 && (model = sv.models[(int)ent->fields.server->modelindex])
2431 && model->animscenes)
2433 // if model has wrong frame, engine automatically switches to model first frame
2434 frame = (int)ent->fields.server->frame;
2435 if (frame < 0 || frame >= model->numframes)
2437 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2439 *out = identitymatrix;
2443 // Warnings/errors code:
2444 // 0 - normal (everything all-right)
2447 // 3 - null or non-precached model
2448 // 4 - no tags with requested index
2449 // 5 - runaway loop at attachment chain
2450 extern cvar_t cl_bob;
2451 extern cvar_t cl_bobcycle;
2452 extern cvar_t cl_bobup;
2453 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2457 int modelindex, attachloop;
2458 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2461 *out = identitymatrix; // warnings and errors return identical matrix
2463 if (ent == prog->edicts)
2465 if (ent->priv.server->free)
2468 modelindex = (int)ent->fields.server->modelindex;
2469 if (modelindex <= 0 || modelindex > MAX_MODELS)
2472 model = sv.models[modelindex];
2474 tagmatrix = identitymatrix;
2475 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2479 if (attachloop >= 256) // prevent runaway looping
2481 // apply transformation by child's tagindex on parent entity and then
2482 // by parent entity itself
2483 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2484 if (ret && attachloop == 0)
2486 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2487 SV_GetEntityMatrix(ent, &entitymatrix, false);
2488 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2489 // next iteration we process the parent entity
2490 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2492 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2493 ent = PRVM_EDICT_NUM(val->edict);
2500 // RENDER_VIEWMODEL magic
2501 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2503 Matrix4x4_Copy(&tagmatrix, out);
2504 ent = PRVM_EDICT_NUM(val->edict);
2506 SV_GetEntityMatrix(ent, &entitymatrix, true);
2507 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2510 // Cl_bob, ported from rendering code
2511 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2514 // LordHavoc: this code is *weird*, but not replacable (I think it
2515 // should be done in QC on the server, but oh well, quake is quake)
2516 // LordHavoc: figured out bobup: the time at which the sin is at 180
2517 // degrees (which allows lengthening or squishing the peak or valley)
2518 cycle = sv.time/cl_bobcycle.value;
2519 cycle -= (int)cycle;
2520 if (cycle < cl_bobup.value)
2521 cycle = sin(M_PI * cycle / cl_bobup.value);
2523 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2524 // bob is proportional to velocity in the xy plane
2525 // (don't count Z, or jumping messes it up)
2526 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;
2527 bob = bob*0.3 + bob*0.7*cycle;
2528 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2535 //float(entity ent, string tagname) gettagindex;
2537 static void VM_SV_gettagindex (void)
2540 const char *tag_name;
2541 int modelindex, tag_index;
2543 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2545 ent = PRVM_G_EDICT(OFS_PARM0);
2546 tag_name = PRVM_G_STRING(OFS_PARM1);
2548 if (ent == prog->edicts)
2550 VM_Warning("gettagindex: can't affect world entity\n");
2553 if (ent->priv.server->free)
2555 VM_Warning("gettagindex: can't affect free entity\n");
2559 modelindex = (int)ent->fields.server->modelindex;
2561 if (modelindex <= 0 || modelindex > MAX_MODELS)
2562 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2565 tag_index = SV_GetTagIndex(ent, tag_name);
2567 if(developer.integer >= 100)
2568 Con_Printf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2570 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2573 //vector(entity ent, float tagindex) gettaginfo;
2574 static void VM_SV_gettaginfo (void)
2578 matrix4x4_t tag_matrix;
2581 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2583 e = PRVM_G_EDICT(OFS_PARM0);
2584 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2586 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2587 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2592 VM_Warning("gettagindex: can't affect world entity\n");
2595 VM_Warning("gettagindex: can't affect free entity\n");
2598 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2601 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2604 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2609 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2610 static void VM_SV_dropclient (void)
2613 client_t *oldhostclient;
2614 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2615 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2616 if (clientnum < 0 || clientnum >= svs.maxclients)
2618 VM_Warning("dropclient: not a client\n");
2621 if (!svs.clients[clientnum].active)
2623 VM_Warning("dropclient: that client slot is not connected\n");
2626 oldhostclient = host_client;
2627 host_client = svs.clients + clientnum;
2628 SV_DropClient(false);
2629 host_client = oldhostclient;
2632 //entity() spawnclient (DP_SV_BOTCLIENT)
2633 static void VM_SV_spawnclient (void)
2637 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2638 prog->xfunction->builtinsprofile += 2;
2640 for (i = 0;i < svs.maxclients;i++)
2642 if (!svs.clients[i].active)
2644 prog->xfunction->builtinsprofile += 100;
2645 SV_ConnectClient (i, NULL);
2646 // this has to be set or else ClientDisconnect won't be called
2647 // we assume the qc will call ClientConnect...
2648 svs.clients[i].clientconnectcalled = true;
2649 ed = PRVM_EDICT_NUM(i + 1);
2653 VM_RETURN_EDICT(ed);
2656 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2657 static void VM_SV_clienttype (void)
2660 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2661 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2662 if (clientnum < 0 || clientnum >= svs.maxclients)
2663 PRVM_G_FLOAT(OFS_RETURN) = 3;
2664 else if (!svs.clients[clientnum].active)
2665 PRVM_G_FLOAT(OFS_RETURN) = 0;
2666 else if (svs.clients[clientnum].netconnection)
2667 PRVM_G_FLOAT(OFS_RETURN) = 1;
2669 PRVM_G_FLOAT(OFS_RETURN) = 2;
2676 string(string key) serverkey
2679 void VM_SV_serverkey(void)
2681 char string[VM_STRINGTEMP_LENGTH];
2682 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2683 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2684 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2687 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2688 static void VM_SV_setmodelindex (void)
2693 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2695 e = PRVM_G_EDICT(OFS_PARM0);
2696 if (e == prog->edicts)
2698 VM_Warning("setmodelindex: can not modify world entity\n");
2701 if (e->priv.server->free)
2703 VM_Warning("setmodelindex: can not modify free entity\n");
2706 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2707 if (i <= 0 || i > MAX_MODELS)
2709 VM_Warning("setmodelindex: invalid modelindex\n");
2712 if (!sv.model_precache[i][0])
2714 VM_Warning("setmodelindex: model not precached\n");
2718 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2719 e->fields.server->modelindex = i;
2725 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2726 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2728 SetMinMaxSize (e, quakemins, quakemaxs, true);
2731 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2734 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2735 static void VM_SV_modelnameforindex (void)
2738 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2740 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2742 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2743 if (i <= 0 || i > MAX_MODELS)
2745 VM_Warning("modelnameforindex: invalid modelindex\n");
2748 if (!sv.model_precache[i][0])
2750 VM_Warning("modelnameforindex: model not precached\n");
2754 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2757 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2758 static void VM_SV_particleeffectnum (void)
2761 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2762 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2765 PRVM_G_FLOAT(OFS_RETURN) = i;
2768 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2769 static void VM_SV_trailparticles (void)
2771 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2773 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2774 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2775 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2776 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2777 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2778 SV_FlushBroadcastMessages();
2781 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2782 static void VM_SV_pointparticles (void)
2784 int effectnum, count;
2786 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2787 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2788 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2789 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2790 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2791 if (count == 1 && !VectorLength2(vel))
2794 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2795 MSG_WriteShort(&sv.datagram, effectnum);
2796 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2800 // 1+2+12+12+2=29 bytes
2801 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2802 MSG_WriteShort(&sv.datagram, effectnum);
2803 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2804 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2805 MSG_WriteShort(&sv.datagram, count);
2808 SV_FlushBroadcastMessages();
2811 prvm_builtin_t vm_sv_builtins[] = {
2812 NULL, // #0 NULL function (not callable) (QUAKE)
2813 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2814 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2815 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2816 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2817 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2818 VM_break, // #6 void() break (QUAKE)
2819 VM_random, // #7 float() random (QUAKE)
2820 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2821 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2822 VM_error, // #10 void(string e) error (QUAKE)
2823 VM_objerror, // #11 void(string e) objerror (QUAKE)
2824 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2825 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2826 VM_spawn, // #14 entity() spawn (QUAKE)
2827 VM_remove, // #15 void(entity e) remove (QUAKE)
2828 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2829 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2830 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2831 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2832 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2833 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2834 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2835 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2836 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2837 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2838 VM_ftos, // #26 string(float f) ftos (QUAKE)
2839 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2840 VM_coredump, // #28 void() coredump (QUAKE)
2841 VM_traceon, // #29 void() traceon (QUAKE)
2842 VM_traceoff, // #30 void() traceoff (QUAKE)
2843 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2844 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2845 NULL, // #33 (QUAKE)
2846 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2847 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2848 VM_rint, // #36 float(float v) rint (QUAKE)
2849 VM_floor, // #37 float(float v) floor (QUAKE)
2850 VM_ceil, // #38 float(float v) ceil (QUAKE)
2851 NULL, // #39 (QUAKE)
2852 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2853 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2854 NULL, // #42 (QUAKE)
2855 VM_fabs, // #43 float(float f) fabs (QUAKE)
2856 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2857 VM_cvar, // #45 float(string s) cvar (QUAKE)
2858 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2859 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2860 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2861 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2862 NULL, // #50 (QUAKE)
2863 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2864 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2865 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2866 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2867 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2868 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2869 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2870 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2871 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2872 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2873 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2874 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2875 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2876 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2877 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2878 NULL, // #66 (QUAKE)
2879 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2880 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2881 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2882 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2883 NULL, // #71 (QUAKE)
2884 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2885 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2886 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2887 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2888 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2889 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2890 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2891 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2892 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2893 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2894 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2895 NULL, // #83 (QUAKE)
2896 NULL, // #84 (QUAKE)
2897 NULL, // #85 (QUAKE)
2898 NULL, // #86 (QUAKE)
2899 NULL, // #87 (QUAKE)
2900 NULL, // #88 (QUAKE)
2901 NULL, // #89 (QUAKE)
2902 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2903 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2904 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2905 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2906 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2907 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2908 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2909 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2910 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2911 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2912 // FrikaC and Telejano range #100-#199
2923 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
2924 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
2925 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
2926 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
2927 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
2928 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
2929 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
2930 VM_stov, // #117 vector(string) stov (FRIK_FILE)
2931 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
2932 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3013 // FTEQW range #200-#299
3032 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3035 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3036 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3037 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3038 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3039 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3040 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3041 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3042 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3043 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3044 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3046 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3114 // CSQC range #300-#399
3115 NULL, // #300 void() clearscene (EXT_CSQC)
3116 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3117 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3118 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3119 NULL, // #304 void() renderscene (EXT_CSQC)
3120 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3121 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3122 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3123 NULL, // #308 void() R_EndPolygon
3125 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3126 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3130 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3131 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3132 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3133 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3134 NULL, // #319 void(string name) freepic (EXT_CSQC)
3135 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3136 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3137 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3138 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3139 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3140 NULL, // #325 void(void) drawresetcliparea
3145 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3146 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3147 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3148 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3149 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3150 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3151 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3152 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3153 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3154 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3155 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3156 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3157 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3158 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3159 NULL, // #344 vector() getmousepos (EXT_CSQC)
3160 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3161 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3162 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3163 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3164 NULL, // #349 float() isdemo (EXT_CSQC)
3165 VM_isserver, // #350 float() isserver (EXT_CSQC)
3166 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3167 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3168 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3169 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3175 NULL, // #360 float() readbyte (EXT_CSQC)
3176 NULL, // #361 float() readchar (EXT_CSQC)
3177 NULL, // #362 float() readshort (EXT_CSQC)
3178 NULL, // #363 float() readlong (EXT_CSQC)
3179 NULL, // #364 float() readcoord (EXT_CSQC)
3180 NULL, // #365 float() readangle (EXT_CSQC)
3181 NULL, // #366 string() readstring (EXT_CSQC)
3182 NULL, // #367 float() readfloat (EXT_CSQC)
3215 // LordHavoc's range #400-#499
3216 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3217 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3218 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3219 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3220 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3221 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3222 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3223 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3224 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)
3225 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3226 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3227 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3228 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3229 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3230 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3231 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3232 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3233 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3234 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3235 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3236 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3237 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3238 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3239 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3240 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3241 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3242 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3243 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3244 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3245 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3246 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3247 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3248 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3249 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3250 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3251 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3252 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3253 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3254 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3255 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3256 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3257 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3258 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3259 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3260 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3261 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3262 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3263 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3264 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3265 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3266 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3267 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3268 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3269 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3270 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3271 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3272 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3273 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3275 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3276 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3277 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3278 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3279 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3280 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3281 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3282 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3283 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3284 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3285 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3287 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3288 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3289 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3290 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3291 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3292 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3293 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3294 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3295 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3296 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3297 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3298 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3299 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3300 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3301 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3302 VM_SV_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3310 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3318 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3320 void VM_SV_Cmd_Init(void)
3325 void VM_SV_Cmd_Reset(void)
3327 if(prog->funcoffsets.SV_Shutdown)
3329 func_t s = prog->funcoffsets.SV_Shutdown;
3330 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3331 PRVM_ExecuteProgram(s,"SV_Shutdown() required");