6 //============================================================================
11 char *vm_sv_extensions =
16 "DP_CON_ALIASPARAMETERS "
36 "DP_ENT_CUSTOMCOLORMAP "
37 "DP_ENT_EXTERIORMODELTOCLIENT "
39 "DP_ENT_LOWPRECISION "
43 "DP_GFX_EXTERNALTEXTURES "
44 "DP_GFX_EXTERNALTEXTURES_PERMAP "
46 "DP_GFX_QUAKE3MODELTAGS "
50 "DP_HALFLIFE_MAP_CVAR "
56 "DP_MOVETYPEBOUNCEMISSILE "
58 "DP_QC_ASINACOSATANATAN2TAN "
63 "DP_QC_CVAR_DEFSTRING "
70 "DP_QC_FINDCHAINFLAGS "
71 "DP_QC_FINDCHAINFLOAT "
77 "DP_QC_GETSURFACEPOINTATTRIBUTE "
80 "DP_QC_MULTIPLETEMPSTRINGS "
81 "DP_QC_NUM_FOR_EDICT "
83 "DP_QC_SINCOSSQRTPOW "
85 "DP_QC_STRINGBUFFERS "
86 "DP_QC_STRINGCOLORFUNCTIONS "
87 "DP_QC_STRING_CASE_FUNCTIONS "
89 "DP_QC_TOKENIZEBYSEPARATOR "
92 "DP_QC_TRACE_MOVETYPE_HITMODEL "
93 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
94 "DP_QC_UNLIMITEDTEMPSTRINGS "
97 "DP_QC_VECTOANGLES_WITH_ROLL "
98 "DP_QC_VECTORVECTORS "
105 "DP_SND_DIRECTIONLESSATTNNONE "
112 "DP_SV_CLIENTCOLORS "
115 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
116 "DP_SV_DRAWONLYTOCLIENT "
119 "DP_SV_ENTITYCONTENTSTRANSITION "
120 "DP_SV_MODELFLAGS_AS_EFFECTS "
121 "DP_SV_MOVETYPESTEP_LANDEVENT "
123 "DP_SV_NODRAWTOCLIENT "
124 "DP_SV_ONENTITYNOSPAWNFUNCTION "
126 "DP_SV_PLAYERPHYSICS "
127 "DP_SV_POINTPARTICLES "
129 "DP_SV_PRECACHEANYTIME "
133 "DP_SV_ROTATINGBMODEL "
137 "DP_SV_SPAWNFUNC_PREFIX "
138 "DP_SV_WRITEPICTURE "
139 "DP_SV_WRITEUNTERMINATEDSTRING "
143 "DP_TE_EXPLOSIONRGB "
145 "DP_TE_PARTICLECUBE "
146 "DP_TE_PARTICLERAIN "
147 "DP_TE_PARTICLESNOW "
149 "DP_TE_QUADEFFECTS1 "
152 "DP_TE_STANDARDEFFECTBUILTINS "
153 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
158 "KRIMZON_SV_PARSECLIENTCOMMAND "
161 "NEXUIZ_PLAYERMODEL "
163 "PRYDON_CLIENTCURSOR "
164 "TENEBRAE_GFX_DLIGHTS "
166 //"EXT_CSQC " // not ready yet
173 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.
175 setorigin (entity, origin)
178 static void VM_SV_setorigin (void)
183 VM_SAFEPARMCOUNT(2, VM_setorigin);
185 e = PRVM_G_EDICT(OFS_PARM0);
186 if (e == prog->edicts)
188 VM_Warning("setorigin: can not modify world entity\n");
191 if (e->priv.server->free)
193 VM_Warning("setorigin: can not modify free entity\n");
196 org = PRVM_G_VECTOR(OFS_PARM1);
197 VectorCopy (org, e->fields.server->origin);
198 SV_LinkEdict (e, false);
201 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
202 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
206 for (i=0 ; i<3 ; i++)
208 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
210 // set derived values
211 VectorCopy (min, e->fields.server->mins);
212 VectorCopy (max, e->fields.server->maxs);
213 VectorSubtract (max, min, e->fields.server->size);
215 SV_LinkEdict (e, false);
222 the size box is rotated by the current angle
223 LordHavoc: no it isn't...
225 setsize (entity, minvector, maxvector)
228 static void VM_SV_setsize (void)
233 VM_SAFEPARMCOUNT(3, VM_setsize);
235 e = PRVM_G_EDICT(OFS_PARM0);
236 if (e == prog->edicts)
238 VM_Warning("setsize: can not modify world entity\n");
241 if (e->priv.server->free)
243 VM_Warning("setsize: can not modify free entity\n");
246 min = PRVM_G_VECTOR(OFS_PARM1);
247 max = PRVM_G_VECTOR(OFS_PARM2);
248 SetMinMaxSize (e, min, max, false);
256 setmodel(entity, model)
259 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
260 static void VM_SV_setmodel (void)
266 VM_SAFEPARMCOUNT(2, VM_setmodel);
268 e = PRVM_G_EDICT(OFS_PARM0);
269 if (e == prog->edicts)
271 VM_Warning("setmodel: can not modify world entity\n");
274 if (e->priv.server->free)
276 VM_Warning("setmodel: can not modify free entity\n");
279 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
280 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
281 e->fields.server->modelindex = i;
287 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
288 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
290 SetMinMaxSize (e, quakemins, quakemaxs, true);
293 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
300 single print to a specific client
302 sprint(clientent, value)
305 static void VM_SV_sprint (void)
309 char string[VM_STRINGTEMP_LENGTH];
311 VM_VarString(1, string, sizeof(string));
313 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
315 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
316 // LordHavoc: div0 requested that sprintto world operate like print
323 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
325 VM_Warning("tried to centerprint to a non-client\n");
329 client = svs.clients + entnum-1;
330 if (!client->netconnection)
333 MSG_WriteChar(&client->netconnection->message,svc_print);
334 MSG_WriteString(&client->netconnection->message, string);
342 single print to a specific client
344 centerprint(clientent, value)
347 static void VM_SV_centerprint (void)
351 char string[VM_STRINGTEMP_LENGTH];
353 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
355 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
357 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
359 VM_Warning("tried to centerprint to a non-client\n");
363 client = svs.clients + entnum-1;
364 if (!client->netconnection)
367 VM_VarString(1, string, sizeof(string));
368 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
369 MSG_WriteString(&client->netconnection->message, string);
376 particle(origin, color, count)
379 static void VM_SV_particle (void)
385 VM_SAFEPARMCOUNT(4, VM_SV_particle);
387 org = PRVM_G_VECTOR(OFS_PARM0);
388 dir = PRVM_G_VECTOR(OFS_PARM1);
389 color = PRVM_G_FLOAT(OFS_PARM2);
390 count = PRVM_G_FLOAT(OFS_PARM3);
391 SV_StartParticle (org, dir, (int)color, (int)count);
401 static void VM_SV_ambientsound (void)
405 float vol, attenuation;
408 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
410 pos = PRVM_G_VECTOR (OFS_PARM0);
411 samp = PRVM_G_STRING(OFS_PARM1);
412 vol = PRVM_G_FLOAT(OFS_PARM2);
413 attenuation = PRVM_G_FLOAT(OFS_PARM3);
415 // check to see if samp was properly precached
416 soundnum = SV_SoundIndex(samp, 1);
424 // add an svc_spawnambient command to the level signon packet
427 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
429 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
431 MSG_WriteVector(&sv.signon, pos, sv.protocol);
433 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
434 MSG_WriteShort (&sv.signon, soundnum);
436 MSG_WriteByte (&sv.signon, soundnum);
438 MSG_WriteByte (&sv.signon, (int)(vol*255));
439 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
447 Each entity can have eight independant sound sources, like voice,
450 Channel 0 is an auto-allocate channel, the others override anything
451 already running on that entity/channel pair.
453 An attenuation of 0 will play full volume everywhere in the level.
454 Larger attenuations will drop off.
458 static void VM_SV_sound (void)
462 prvm_edict_t *entity;
466 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
468 entity = PRVM_G_EDICT(OFS_PARM0);
469 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
470 sample = PRVM_G_STRING(OFS_PARM2);
471 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
472 attenuation = PRVM_G_FLOAT(OFS_PARM4);
475 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
479 if (volume < 0 || volume > 255)
481 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
485 if (attenuation < 0 || attenuation > 4)
487 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
491 if (channel < 0 || channel > 7)
493 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
497 SV_StartSound (entity, channel, sample, volume, attenuation);
504 Follows the same logic as VM_SV_sound, except instead of
505 an entity, an origin for the sound is provided, and channel
506 is omitted (since no entity is being tracked).
510 static void VM_SV_pointsound(void)
517 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
519 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
520 sample = PRVM_G_STRING(OFS_PARM1);
521 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
522 attenuation = PRVM_G_FLOAT(OFS_PARM3);
524 if (volume < 0 || volume > 255)
526 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
530 if (attenuation < 0 || attenuation > 4)
532 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
536 SV_StartPointSound (org, sample, volume, attenuation);
543 Used for use tracing and shot targeting
544 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
545 if the tryents flag is set.
547 traceline (vector1, vector2, movetype, ignore)
550 static void VM_SV_traceline (void)
557 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
559 prog->xfunction->builtinsprofile += 30;
561 v1 = PRVM_G_VECTOR(OFS_PARM0);
562 v2 = PRVM_G_VECTOR(OFS_PARM1);
563 move = (int)PRVM_G_FLOAT(OFS_PARM2);
564 ent = PRVM_G_EDICT(OFS_PARM3);
566 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]))
567 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));
569 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
571 VM_SetTraceGlobals(&trace);
579 Used for use tracing and shot targeting
580 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
581 if the tryents flag is set.
583 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
586 // LordHavoc: added this for my own use, VERY useful, similar to traceline
587 static void VM_SV_tracebox (void)
589 float *v1, *v2, *m1, *m2;
594 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
596 prog->xfunction->builtinsprofile += 30;
598 v1 = PRVM_G_VECTOR(OFS_PARM0);
599 m1 = PRVM_G_VECTOR(OFS_PARM1);
600 m2 = PRVM_G_VECTOR(OFS_PARM2);
601 v2 = PRVM_G_VECTOR(OFS_PARM3);
602 move = (int)PRVM_G_FLOAT(OFS_PARM4);
603 ent = PRVM_G_EDICT(OFS_PARM5);
605 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]))
606 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));
608 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
610 VM_SetTraceGlobals(&trace);
613 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
618 vec3_t original_origin;
619 vec3_t original_velocity;
620 vec3_t original_angles;
621 vec3_t original_avelocity;
625 VectorCopy(tossent->fields.server->origin , original_origin );
626 VectorCopy(tossent->fields.server->velocity , original_velocity );
627 VectorCopy(tossent->fields.server->angles , original_angles );
628 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
630 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
631 if (val != NULL && val->_float != 0)
632 gravity = val->_float;
635 gravity *= sv_gravity.value * 0.05;
637 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
639 SV_CheckVelocity (tossent);
640 tossent->fields.server->velocity[2] -= gravity;
641 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
642 VectorScale (tossent->fields.server->velocity, 0.05, move);
643 VectorAdd (tossent->fields.server->origin, move, end);
644 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
645 VectorCopy (trace.endpos, tossent->fields.server->origin);
647 if (trace.fraction < 1)
651 VectorCopy(original_origin , tossent->fields.server->origin );
652 VectorCopy(original_velocity , tossent->fields.server->velocity );
653 VectorCopy(original_angles , tossent->fields.server->angles );
654 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
659 static void VM_SV_tracetoss (void)
663 prvm_edict_t *ignore;
665 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
667 prog->xfunction->builtinsprofile += 600;
669 ent = PRVM_G_EDICT(OFS_PARM0);
670 if (ent == prog->edicts)
672 VM_Warning("tracetoss: can not use world entity\n");
675 ignore = PRVM_G_EDICT(OFS_PARM1);
677 trace = SV_Trace_Toss (ent, ignore);
679 VM_SetTraceGlobals(&trace);
682 //============================================================================
684 static int checkpvsbytes;
685 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
687 static int VM_SV_newcheckclient (int check)
693 // cycle to the next one
695 check = bound(1, check, svs.maxclients);
696 if (check == svs.maxclients)
704 prog->xfunction->builtinsprofile++;
706 if (i == svs.maxclients+1)
708 // look up the client's edict
709 ent = PRVM_EDICT_NUM(i);
710 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
711 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
713 // found a valid client (possibly the same one again)
717 // get the PVS for the entity
718 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
720 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
721 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
730 Returns a client (or object that has a client enemy) that would be a
733 If there is more than one valid option, they are cycled each frame
735 If (self.origin + self.viewofs) is not in the PVS of the current target,
736 it is not returned at all.
741 int c_invis, c_notvis;
742 static void VM_SV_checkclient (void)
744 prvm_edict_t *ent, *self;
747 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
749 // find a new check if on a new frame
750 if (sv.time - sv.lastchecktime >= 0.1)
752 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
753 sv.lastchecktime = sv.time;
756 // return check if it might be visible
757 ent = PRVM_EDICT_NUM(sv.lastcheck);
758 if (ent->priv.server->free || ent->fields.server->health <= 0)
760 VM_RETURN_EDICT(prog->edicts);
764 // if current entity can't possibly see the check entity, return 0
765 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
766 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
767 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
770 VM_RETURN_EDICT(prog->edicts);
774 // might be able to see it
776 VM_RETURN_EDICT(ent);
779 //============================================================================
786 Sends text over to the client's execution buffer
788 stuffcmd (clientent, value, ...)
791 static void VM_SV_stuffcmd (void)
795 char string[VM_STRINGTEMP_LENGTH];
797 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
799 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
800 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
802 VM_Warning("Can't stuffcmd to a non-client\n");
806 VM_VarString(1, string, sizeof(string));
809 host_client = svs.clients + entnum-1;
810 Host_ClientCommands ("%s", string);
818 Returns a chain of entities that have origins within a spherical area
820 findradius (origin, radius)
823 static void VM_SV_findradius (void)
825 prvm_edict_t *ent, *chain;
826 vec_t radius, radius2;
827 vec3_t org, eorg, mins, maxs;
830 prvm_edict_t *touchedicts[MAX_EDICTS];
832 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
834 chain = (prvm_edict_t *)prog->edicts;
836 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
837 radius = PRVM_G_FLOAT(OFS_PARM1);
838 radius2 = radius * radius;
840 mins[0] = org[0] - (radius + 1);
841 mins[1] = org[1] - (radius + 1);
842 mins[2] = org[2] - (radius + 1);
843 maxs[0] = org[0] + (radius + 1);
844 maxs[1] = org[1] + (radius + 1);
845 maxs[2] = org[2] + (radius + 1);
846 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
847 if (numtouchedicts > MAX_EDICTS)
849 // this never happens
850 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
851 numtouchedicts = MAX_EDICTS;
853 for (i = 0;i < numtouchedicts;i++)
855 ent = touchedicts[i];
856 prog->xfunction->builtinsprofile++;
857 // Quake did not return non-solid entities but darkplaces does
858 // (note: this is the reason you can't blow up fallen zombies)
859 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
861 // LordHavoc: compare against bounding box rather than center so it
862 // doesn't miss large objects, and use DotProduct instead of Length
863 // for a major speedup
864 VectorSubtract(org, ent->fields.server->origin, eorg);
865 if (sv_gameplayfix_findradiusdistancetobox.integer)
867 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
868 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
869 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
872 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
873 if (DotProduct(eorg, eorg) < radius2)
875 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
880 VM_RETURN_EDICT(chain);
883 static void VM_SV_precache_sound (void)
885 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
886 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
889 static void VM_SV_precache_model (void)
891 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
892 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
893 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
900 float(float yaw, float dist[, settrace]) walkmove
903 static void VM_SV_walkmove (void)
912 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
914 // assume failure if it returns early
915 PRVM_G_FLOAT(OFS_RETURN) = 0;
917 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
918 if (ent == prog->edicts)
920 VM_Warning("walkmove: can not modify world entity\n");
923 if (ent->priv.server->free)
925 VM_Warning("walkmove: can not modify free entity\n");
928 yaw = PRVM_G_FLOAT(OFS_PARM0);
929 dist = PRVM_G_FLOAT(OFS_PARM1);
930 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
932 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
935 yaw = yaw*M_PI*2 / 360;
937 move[0] = cos(yaw)*dist;
938 move[1] = sin(yaw)*dist;
941 // save program state, because SV_movestep may call other progs
942 oldf = prog->xfunction;
943 oldself = prog->globals.server->self;
945 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
948 // restore program state
949 prog->xfunction = oldf;
950 prog->globals.server->self = oldself;
960 static void VM_SV_droptofloor (void)
966 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
968 // assume failure if it returns early
969 PRVM_G_FLOAT(OFS_RETURN) = 0;
971 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
972 if (ent == prog->edicts)
974 VM_Warning("droptofloor: can not modify world entity\n");
977 if (ent->priv.server->free)
979 VM_Warning("droptofloor: can not modify free entity\n");
983 VectorCopy (ent->fields.server->origin, end);
986 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
987 SV_UnstickEntity(ent);
989 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
990 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
993 VectorSet(offset, 0.5f * (ent->fields.server->mins[0] + ent->fields.server->maxs[0]), 0.5f * (ent->fields.server->mins[1] + ent->fields.server->maxs[1]), ent->fields.server->mins[2]);
994 VectorAdd(ent->fields.server->origin, offset, org);
995 trace = SV_Move (org, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
996 VectorSubtract(trace.endpos, offset, trace.endpos);
997 if (trace.startsolid)
999 Con_DPrintf("droptofloor at %f %f %f - COULD NOT FIX BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
1000 SV_UnstickEntity(ent);
1001 SV_LinkEdict (ent, false);
1002 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1003 ent->fields.server->groundentity = 0;
1004 PRVM_G_FLOAT(OFS_RETURN) = 1;
1006 else if (trace.fraction < 1)
1008 Con_DPrintf("droptofloor at %f %f %f - FIXED BADLY PLACED ENTITY\n", ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
1009 VectorCopy (trace.endpos, ent->fields.server->origin);
1010 SV_UnstickEntity(ent);
1011 SV_LinkEdict (ent, false);
1012 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1013 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1014 PRVM_G_FLOAT(OFS_RETURN) = 1;
1015 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1016 ent->priv.server->suspendedinairflag = true;
1021 if (trace.fraction != 1)
1023 if (trace.fraction < 1)
1024 VectorCopy (trace.endpos, ent->fields.server->origin);
1025 SV_LinkEdict (ent, false);
1026 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1027 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1028 PRVM_G_FLOAT(OFS_RETURN) = 1;
1029 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1030 ent->priv.server->suspendedinairflag = true;
1039 void(float style, string value) lightstyle
1042 static void VM_SV_lightstyle (void)
1049 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1051 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1052 val = PRVM_G_STRING(OFS_PARM1);
1054 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1055 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1058 // change the string in sv
1059 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1061 // send message to all clients on this server
1062 if (sv.state != ss_active)
1065 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1067 if (client->active && client->netconnection)
1069 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1070 MSG_WriteChar (&client->netconnection->message,style);
1071 MSG_WriteString (&client->netconnection->message, val);
1081 static void VM_SV_checkbottom (void)
1083 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1084 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1092 static void VM_SV_pointcontents (void)
1094 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1095 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1102 Pick a vector for the player to shoot along
1103 vector aim(entity, missilespeed)
1106 static void VM_SV_aim (void)
1108 prvm_edict_t *ent, *check, *bestent;
1109 vec3_t start, dir, end, bestdir;
1112 float dist, bestdist;
1115 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1117 // assume failure if it returns early
1118 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1119 // if sv_aim is so high it can't possibly accept anything, skip out early
1120 if (sv_aim.value >= 1)
1123 ent = PRVM_G_EDICT(OFS_PARM0);
1124 if (ent == prog->edicts)
1126 VM_Warning("aim: can not use world entity\n");
1129 if (ent->priv.server->free)
1131 VM_Warning("aim: can not use free entity\n");
1134 speed = PRVM_G_FLOAT(OFS_PARM1);
1136 VectorCopy (ent->fields.server->origin, start);
1139 // try sending a trace straight
1140 VectorCopy (prog->globals.server->v_forward, dir);
1141 VectorMA (start, 2048, dir, end);
1142 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1143 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1144 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1146 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1151 // try all possible entities
1152 VectorCopy (dir, bestdir);
1153 bestdist = sv_aim.value;
1156 check = PRVM_NEXT_EDICT(prog->edicts);
1157 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1159 prog->xfunction->builtinsprofile++;
1160 if (check->fields.server->takedamage != DAMAGE_AIM)
1164 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1165 continue; // don't aim at teammate
1166 for (j=0 ; j<3 ; j++)
1167 end[j] = check->fields.server->origin[j]
1168 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1169 VectorSubtract (end, start, dir);
1170 VectorNormalize (dir);
1171 dist = DotProduct (dir, prog->globals.server->v_forward);
1172 if (dist < bestdist)
1173 continue; // to far to turn
1174 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1175 if (tr.ent == check)
1176 { // can shoot at this one
1184 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1185 dist = DotProduct (dir, prog->globals.server->v_forward);
1186 VectorScale (prog->globals.server->v_forward, dist, end);
1188 VectorNormalize (end);
1189 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1193 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1198 ===============================================================================
1202 ===============================================================================
1205 #define MSG_BROADCAST 0 // unreliable to all
1206 #define MSG_ONE 1 // reliable to one (msg_entity)
1207 #define MSG_ALL 2 // reliable to all
1208 #define MSG_INIT 3 // write to the init string
1209 #define MSG_ENTITY 5
1211 sizebuf_t *WriteDest (void)
1217 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1221 return &sv.datagram;
1224 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1225 entnum = PRVM_NUM_FOR_EDICT(ent);
1226 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1228 VM_Warning ("WriteDest: tried to write to non-client\n");
1229 return &sv.reliable_datagram;
1232 return &svs.clients[entnum-1].netconnection->message;
1235 VM_Warning ("WriteDest: bad destination\n");
1237 return &sv.reliable_datagram;
1243 return sv.writeentitiestoclient_msg;
1249 static void VM_SV_WriteByte (void)
1251 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1252 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1255 static void VM_SV_WriteChar (void)
1257 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1258 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1261 static void VM_SV_WriteShort (void)
1263 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1264 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1267 static void VM_SV_WriteLong (void)
1269 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1270 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1273 static void VM_SV_WriteAngle (void)
1275 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1276 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1279 static void VM_SV_WriteCoord (void)
1281 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1282 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1285 static void VM_SV_WriteString (void)
1287 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1288 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1291 static void VM_SV_WriteUnterminatedString (void)
1293 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1294 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1298 static void VM_SV_WriteEntity (void)
1300 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1301 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1304 // writes a picture as at most size bytes of data
1306 // IMGNAME \0 SIZE(short) IMGDATA
1307 // if failed to read/compress:
1309 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1310 static void VM_SV_WritePicture (void)
1312 const char *imgname;
1316 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1318 imgname = PRVM_G_STRING(OFS_PARM1);
1319 size = PRVM_G_FLOAT(OFS_PARM2);
1323 MSG_WriteString(WriteDest(), imgname);
1324 if(Image_Compress(imgname, size, &buf, &size))
1327 MSG_WriteShort(WriteDest(), size);
1328 SZ_Write(WriteDest(), buf, size);
1333 MSG_WriteShort(WriteDest(), 0);
1337 //////////////////////////////////////////////////////////
1339 static void VM_SV_makestatic (void)
1344 // allow 0 parameters due to an id1 qc bug in which this function is used
1345 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1346 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1348 if (prog->argc >= 1)
1349 ent = PRVM_G_EDICT(OFS_PARM0);
1351 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1352 if (ent == prog->edicts)
1354 VM_Warning("makestatic: can not modify world entity\n");
1357 if (ent->priv.server->free)
1359 VM_Warning("makestatic: can not modify free entity\n");
1364 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1369 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1370 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1371 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1373 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1375 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1376 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1377 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1381 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1382 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1383 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1386 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1387 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1388 for (i=0 ; i<3 ; i++)
1390 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1391 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1394 // throw the entity away now
1398 //=============================================================================
1405 static void VM_SV_setspawnparms (void)
1411 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1413 ent = PRVM_G_EDICT(OFS_PARM0);
1414 i = PRVM_NUM_FOR_EDICT(ent);
1415 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1417 Con_Print("tried to setspawnparms on a non-client\n");
1421 // copy spawn parms out of the client_t
1422 client = svs.clients + i-1;
1423 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1424 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1431 Returns a color vector indicating the lighting at the requested point.
1433 (Internal Operation note: actually measures the light beneath the point, just like
1434 the model lighting on the client)
1439 static void VM_SV_getlight (void)
1441 vec3_t ambientcolor, diffusecolor, diffusenormal;
1443 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1444 p = PRVM_G_VECTOR(OFS_PARM0);
1445 VectorClear(ambientcolor);
1446 VectorClear(diffusecolor);
1447 VectorClear(diffusenormal);
1448 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1449 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1450 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1455 unsigned char type; // 1/2/8 or other value if isn't used
1459 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1460 static int vm_customstats_last;
1462 void VM_CustomStats_Clear (void)
1466 Z_Free(vm_customstats);
1467 vm_customstats = NULL;
1468 vm_customstats_last = -1;
1472 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1480 for(i=0; i<vm_customstats_last+1 ;i++)
1482 if(!vm_customstats[i].type)
1484 switch(vm_customstats[i].type)
1486 //string as 16 bytes
1489 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1490 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1491 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1492 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1493 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1495 //float field sent as-is
1497 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1499 //integer value of float field
1501 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1509 // void(float index, float type, .void field) SV_AddStat = #232;
1510 // Set up an auto-sent player stat.
1511 // Client's get thier own fields sent to them. Index may not be less than 32.
1512 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1513 // 1: string (4 stats carrying a total of 16 charactures)
1514 // 2: float (one stat, float converted to an integer for transportation)
1515 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1516 static void VM_SV_AddStat (void)
1521 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1525 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1528 VM_Warning("PF_SV_AddStat: not enough memory\n");
1532 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1533 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1534 off = PRVM_G_INT (OFS_PARM2);
1539 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1542 if(i >= (MAX_CL_STATS-32))
1544 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1547 if(i > (MAX_CL_STATS-32-4) && type == 1)
1549 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1552 vm_customstats[i].type = type;
1553 vm_customstats[i].fieldoffset = off;
1554 if(vm_customstats_last < i)
1555 vm_customstats_last = i;
1562 copies data from one entity to another
1564 copyentity(src, dst)
1567 static void VM_SV_copyentity (void)
1569 prvm_edict_t *in, *out;
1570 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1571 in = PRVM_G_EDICT(OFS_PARM0);
1572 if (in == prog->edicts)
1574 VM_Warning("copyentity: can not read world entity\n");
1577 if (in->priv.server->free)
1579 VM_Warning("copyentity: can not read free entity\n");
1582 out = PRVM_G_EDICT(OFS_PARM1);
1583 if (out == prog->edicts)
1585 VM_Warning("copyentity: can not modify world entity\n");
1588 if (out->priv.server->free)
1590 VM_Warning("copyentity: can not modify free entity\n");
1593 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1594 SV_LinkEdict(out, false);
1602 sets the color of a client and broadcasts the update to all connected clients
1604 setcolor(clientent, value)
1607 static void VM_SV_setcolor (void)
1613 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1614 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1615 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1617 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1619 Con_Print("tried to setcolor a non-client\n");
1623 client = svs.clients + entnum-1;
1626 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1628 client->edict->fields.server->team = (i & 15) + 1;
1631 if (client->old_colors != client->colors)
1633 client->old_colors = client->colors;
1634 // send notification to all clients
1635 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1636 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1637 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1645 effect(origin, modelname, startframe, framecount, framerate)
1648 static void VM_SV_effect (void)
1652 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1653 s = PRVM_G_STRING(OFS_PARM1);
1656 VM_Warning("effect: no model specified\n");
1660 i = SV_ModelIndex(s, 1);
1663 VM_Warning("effect: model not precached\n");
1667 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1669 VM_Warning("effect: framecount < 1\n");
1673 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1675 VM_Warning("effect: framerate < 1\n");
1679 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));
1682 static void VM_SV_te_blood (void)
1684 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1685 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1687 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1688 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1690 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1691 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1692 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1694 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1695 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1696 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1698 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1699 SV_FlushBroadcastMessages();
1702 static void VM_SV_te_bloodshower (void)
1704 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1705 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1707 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1708 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1710 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1711 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1712 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1714 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1715 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1716 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1718 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1720 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1721 SV_FlushBroadcastMessages();
1724 static void VM_SV_te_explosionrgb (void)
1726 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1727 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1728 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1730 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1731 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1732 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1734 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1735 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1736 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1737 SV_FlushBroadcastMessages();
1740 static void VM_SV_te_particlecube (void)
1742 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1743 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1745 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1746 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1748 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1749 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1750 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1752 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1753 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1754 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1756 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1757 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1758 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1760 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1762 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1763 // gravity true/false
1764 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1766 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1767 SV_FlushBroadcastMessages();
1770 static void VM_SV_te_particlerain (void)
1772 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1773 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1775 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1776 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1778 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1779 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1780 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1782 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1783 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1784 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1786 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1787 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1788 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1790 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1792 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1793 SV_FlushBroadcastMessages();
1796 static void VM_SV_te_particlesnow (void)
1798 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1799 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1801 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1802 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
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);
1808 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1809 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1810 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1812 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1814 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1816 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1818 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1819 SV_FlushBroadcastMessages();
1822 static void VM_SV_te_spark (void)
1824 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1825 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1827 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1828 MSG_WriteByte(&sv.datagram, TE_SPARK);
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_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1835 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1836 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1838 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1839 SV_FlushBroadcastMessages();
1842 static void VM_SV_te_gunshotquad (void)
1844 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1845 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1846 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1848 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1849 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1850 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1851 SV_FlushBroadcastMessages();
1854 static void VM_SV_te_spikequad (void)
1856 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1857 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1858 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1860 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1861 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1862 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1863 SV_FlushBroadcastMessages();
1866 static void VM_SV_te_superspikequad (void)
1868 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1869 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1870 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1872 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1873 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1874 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1875 SV_FlushBroadcastMessages();
1878 static void VM_SV_te_explosionquad (void)
1880 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1881 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1882 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1884 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1885 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1886 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1887 SV_FlushBroadcastMessages();
1890 static void VM_SV_te_smallflash (void)
1892 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1893 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1894 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1896 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1897 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1898 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1899 SV_FlushBroadcastMessages();
1902 static void VM_SV_te_customflash (void)
1904 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1905 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1907 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1908 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
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);
1914 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1916 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1918 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1919 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1920 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1921 SV_FlushBroadcastMessages();
1924 static void VM_SV_te_gunshot (void)
1926 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1927 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1928 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1930 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1931 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1933 SV_FlushBroadcastMessages();
1936 static void VM_SV_te_spike (void)
1938 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1939 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1940 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1942 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1943 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1944 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1945 SV_FlushBroadcastMessages();
1948 static void VM_SV_te_superspike (void)
1950 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1951 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1952 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1954 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1955 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1956 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1957 SV_FlushBroadcastMessages();
1960 static void VM_SV_te_explosion (void)
1962 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1963 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1964 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1966 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1967 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1968 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1969 SV_FlushBroadcastMessages();
1972 static void VM_SV_te_tarexplosion (void)
1974 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1975 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1976 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1978 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1979 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1980 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1981 SV_FlushBroadcastMessages();
1984 static void VM_SV_te_wizspike (void)
1986 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1987 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1988 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1990 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1991 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1992 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1993 SV_FlushBroadcastMessages();
1996 static void VM_SV_te_knightspike (void)
1998 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
1999 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2000 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2002 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2003 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2004 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2005 SV_FlushBroadcastMessages();
2008 static void VM_SV_te_lavasplash (void)
2010 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2011 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2012 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2014 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2015 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2016 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2017 SV_FlushBroadcastMessages();
2020 static void VM_SV_te_teleport (void)
2022 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2023 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2024 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2026 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2027 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2028 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2029 SV_FlushBroadcastMessages();
2032 static void VM_SV_te_explosion2 (void)
2034 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2035 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2036 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2038 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2039 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2040 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2042 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2043 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2044 SV_FlushBroadcastMessages();
2047 static void VM_SV_te_lightning1 (void)
2049 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2050 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2051 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2053 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2055 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2056 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2057 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2059 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2060 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2061 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2062 SV_FlushBroadcastMessages();
2065 static void VM_SV_te_lightning2 (void)
2067 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2068 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2069 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2071 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2073 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2074 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2075 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2077 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2078 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2079 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2080 SV_FlushBroadcastMessages();
2083 static void VM_SV_te_lightning3 (void)
2085 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2086 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2087 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2089 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2091 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2092 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2093 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2095 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2096 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2097 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2098 SV_FlushBroadcastMessages();
2101 static void VM_SV_te_beam (void)
2103 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2104 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2105 MSG_WriteByte(&sv.datagram, TE_BEAM);
2107 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2109 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2110 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2111 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2113 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2114 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2115 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2116 SV_FlushBroadcastMessages();
2119 static void VM_SV_te_plasmaburn (void)
2121 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2122 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2123 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2124 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2125 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2126 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2127 SV_FlushBroadcastMessages();
2130 static void VM_SV_te_flamejet (void)
2132 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2133 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2134 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2136 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2137 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2138 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2140 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2141 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2142 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2144 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2145 SV_FlushBroadcastMessages();
2148 void clippointtosurface(dp_model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2151 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2153 bestdist = 1000000000;
2155 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2157 // clip original point to each triangle of the surface and find the
2158 // triangle that is closest
2159 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2160 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2161 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2162 TriangleNormal(v[0], v[1], v[2], facenormal);
2163 VectorNormalize(facenormal);
2164 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2165 VectorMA(p, offsetdist, facenormal, temp);
2166 for (j = 0, k = 2;j < 3;k = j, j++)
2168 VectorSubtract(v[k], v[j], edgenormal);
2169 CrossProduct(edgenormal, facenormal, sidenormal);
2170 VectorNormalize(sidenormal);
2171 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2173 VectorMA(temp, offsetdist, sidenormal, temp);
2175 dist = VectorDistance2(temp, p);
2176 if (bestdist > dist)
2179 VectorCopy(temp, out);
2184 static dp_model_t *getmodel(prvm_edict_t *ed)
2187 if (!ed || ed->priv.server->free)
2189 modelindex = (int)ed->fields.server->modelindex;
2190 if (modelindex < 1 || modelindex >= MAX_MODELS)
2192 return sv.models[modelindex];
2195 static msurface_t *getsurface(dp_model_t *model, int surfacenum)
2197 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2199 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2203 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2204 static void VM_SV_getsurfacenumpoints(void)
2207 msurface_t *surface;
2208 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2209 // return 0 if no such surface
2210 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2212 PRVM_G_FLOAT(OFS_RETURN) = 0;
2216 // note: this (incorrectly) assumes it is a simple polygon
2217 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2219 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2220 static void VM_SV_getsurfacepoint(void)
2224 msurface_t *surface;
2226 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2227 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2228 ed = PRVM_G_EDICT(OFS_PARM0);
2229 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2231 // note: this (incorrectly) assumes it is a simple polygon
2232 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2233 if (pointnum < 0 || pointnum >= surface->num_vertices)
2235 // FIXME: implement rotation/scaling
2236 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2238 //PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
2239 // float SPA_POSITION = 0;
2240 // float SPA_S_AXIS = 1;
2241 // float SPA_T_AXIS = 2;
2242 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2243 // float SPA_TEXCOORDS0 = 4;
2244 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2245 // float SPA_LIGHTMAP0_COLOR = 6;
2246 static void VM_SV_getsurfacepointattribute(void)
2250 msurface_t *surface;
2254 VM_SAFEPARMCOUNT(4, VM_SV_getsurfacepoint);
2255 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2256 ed = PRVM_G_EDICT(OFS_PARM0);
2257 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2259 // note: this (incorrectly) assumes it is a simple polygon
2260 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2261 if (pointnum < 0 || pointnum >= surface->num_vertices)
2263 // FIXME: implement rotation/scaling
2264 attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
2266 switch( attributetype ) {
2267 // float SPA_POSITION = 0;
2269 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2271 // float SPA_S_AXIS = 1;
2273 VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2275 // float SPA_T_AXIS = 2;
2277 VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2279 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2281 VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2283 // float SPA_TEXCOORDS0 = 4;
2285 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2286 float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2];
2287 ret[0] = texcoord[0];
2288 ret[1] = texcoord[1];
2292 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2294 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2295 float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2];
2296 ret[0] = texcoord[0];
2297 ret[1] = texcoord[1];
2301 // float SPA_LIGHTMAP0_COLOR = 6;
2303 // ignore alpha for now..
2304 VectorCopy( &(model->surfmesh.data_lightmapcolor4f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
2307 VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
2311 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2312 static void VM_SV_getsurfacenormal(void)
2315 msurface_t *surface;
2317 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2318 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2319 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2321 // FIXME: implement rotation/scaling
2322 // note: this (incorrectly) assumes it is a simple polygon
2323 // note: this only returns the first triangle, so it doesn't work very
2324 // well for curved surfaces or arbitrary meshes
2325 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);
2326 VectorNormalize(normal);
2327 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2329 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2330 static void VM_SV_getsurfacetexture(void)
2333 msurface_t *surface;
2334 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2335 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2336 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2338 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2340 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2341 static void VM_SV_getsurfacenearpoint(void)
2343 int surfacenum, best;
2345 vec_t dist, bestdist;
2348 msurface_t *surface;
2350 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2351 PRVM_G_FLOAT(OFS_RETURN) = -1;
2352 ed = PRVM_G_EDICT(OFS_PARM0);
2353 point = PRVM_G_VECTOR(OFS_PARM1);
2355 if (!ed || ed->priv.server->free)
2357 model = getmodel(ed);
2358 if (!model || !model->num_surfaces)
2361 // FIXME: implement rotation/scaling
2362 VectorSubtract(point, ed->fields.server->origin, p);
2364 bestdist = 1000000000;
2365 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2367 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2368 // first see if the nearest point on the surface's box is closer than the previous match
2369 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2370 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2371 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2372 dist = VectorLength2(clipped);
2373 if (dist < bestdist)
2375 // it is, check the nearest point on the actual geometry
2376 clippointtosurface(model, surface, p, clipped);
2377 VectorSubtract(clipped, p, clipped);
2378 dist += VectorLength2(clipped);
2379 if (dist < bestdist)
2381 // that's closer too, store it as the best match
2387 PRVM_G_FLOAT(OFS_RETURN) = best;
2389 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2390 static void VM_SV_getsurfaceclippedpoint(void)
2394 msurface_t *surface;
2396 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2397 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2398 ed = PRVM_G_EDICT(OFS_PARM0);
2399 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2401 // FIXME: implement rotation/scaling
2402 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2403 clippointtosurface(model, surface, p, out);
2404 // FIXME: implement rotation/scaling
2405 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2408 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2409 //this function originally written by KrimZon, made shorter by LordHavoc
2410 static void VM_SV_clientcommand (void)
2412 client_t *temp_client;
2414 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2416 //find client for this entity
2417 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2418 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2420 Con_Print("PF_clientcommand: entity is not a client\n");
2424 temp_client = host_client;
2425 host_client = svs.clients + i;
2426 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2427 host_client = temp_client;
2430 //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)
2431 static void VM_SV_setattachment (void)
2433 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2434 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2435 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2439 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2441 if (e == prog->edicts)
2443 VM_Warning("setattachment: can not modify world entity\n");
2446 if (e->priv.server->free)
2448 VM_Warning("setattachment: can not modify free entity\n");
2452 if (tagentity == NULL)
2453 tagentity = prog->edicts;
2455 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2457 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2459 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2462 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2464 modelindex = (int)tagentity->fields.server->modelindex;
2465 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2467 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2469 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);
2472 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));
2476 /////////////////////////////////////////
2477 // DP_MD3_TAGINFO extension coded by VorteX
2479 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2484 i = (int)e->fields.server->modelindex;
2485 if (i < 1 || i >= MAX_MODELS)
2487 model = sv.models[i];
2489 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2492 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2494 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2498 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);
2500 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);
2503 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2509 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2510 && (model = sv.models[(int)ent->fields.server->modelindex])
2511 && model->animscenes)
2513 // if model has wrong frame, engine automatically switches to model first frame
2514 frame = (int)ent->fields.server->frame;
2515 if (frame < 0 || frame >= model->numframes)
2517 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2519 *out = identitymatrix;
2523 // Warnings/errors code:
2524 // 0 - normal (everything all-right)
2527 // 3 - null or non-precached model
2528 // 4 - no tags with requested index
2529 // 5 - runaway loop at attachment chain
2530 extern cvar_t cl_bob;
2531 extern cvar_t cl_bobcycle;
2532 extern cvar_t cl_bobup;
2533 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2537 int modelindex, attachloop;
2538 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2541 *out = identitymatrix; // warnings and errors return identical matrix
2543 if (ent == prog->edicts)
2545 if (ent->priv.server->free)
2548 modelindex = (int)ent->fields.server->modelindex;
2549 if (modelindex <= 0 || modelindex > MAX_MODELS)
2552 model = sv.models[modelindex];
2554 tagmatrix = identitymatrix;
2555 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2559 if (attachloop >= 256) // prevent runaway looping
2561 // apply transformation by child's tagindex on parent entity and then
2562 // by parent entity itself
2563 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2564 if (ret && attachloop == 0)
2566 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2567 SV_GetEntityMatrix(ent, &entitymatrix, false);
2568 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2569 // next iteration we process the parent entity
2570 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2572 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2573 ent = PRVM_EDICT_NUM(val->edict);
2580 // RENDER_VIEWMODEL magic
2581 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2583 Matrix4x4_Copy(&tagmatrix, out);
2584 ent = PRVM_EDICT_NUM(val->edict);
2586 SV_GetEntityMatrix(ent, &entitymatrix, true);
2587 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2590 // Cl_bob, ported from rendering code
2591 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2594 // LordHavoc: this code is *weird*, but not replacable (I think it
2595 // should be done in QC on the server, but oh well, quake is quake)
2596 // LordHavoc: figured out bobup: the time at which the sin is at 180
2597 // degrees (which allows lengthening or squishing the peak or valley)
2598 cycle = sv.time/cl_bobcycle.value;
2599 cycle -= (int)cycle;
2600 if (cycle < cl_bobup.value)
2601 cycle = sin(M_PI * cycle / cl_bobup.value);
2603 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2604 // bob is proportional to velocity in the xy plane
2605 // (don't count Z, or jumping messes it up)
2606 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;
2607 bob = bob*0.3 + bob*0.7*cycle;
2608 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2615 //float(entity ent, string tagname) gettagindex;
2617 static void VM_SV_gettagindex (void)
2620 const char *tag_name;
2621 int modelindex, tag_index;
2623 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2625 ent = PRVM_G_EDICT(OFS_PARM0);
2626 tag_name = PRVM_G_STRING(OFS_PARM1);
2628 if (ent == prog->edicts)
2630 VM_Warning("gettagindex: can't affect world entity\n");
2633 if (ent->priv.server->free)
2635 VM_Warning("gettagindex: can't affect free entity\n");
2639 modelindex = (int)ent->fields.server->modelindex;
2641 if (modelindex <= 0 || modelindex > MAX_MODELS)
2642 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2645 tag_index = SV_GetTagIndex(ent, tag_name);
2647 if(developer.integer >= 100)
2648 Con_Printf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2650 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2653 //vector(entity ent, float tagindex) gettaginfo;
2654 static void VM_SV_gettaginfo (void)
2658 matrix4x4_t tag_matrix;
2661 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2663 e = PRVM_G_EDICT(OFS_PARM0);
2664 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2666 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2667 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2672 VM_Warning("gettagindex: can't affect world entity\n");
2675 VM_Warning("gettagindex: can't affect free entity\n");
2678 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2681 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2684 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2689 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2690 static void VM_SV_dropclient (void)
2693 client_t *oldhostclient;
2694 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2695 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2696 if (clientnum < 0 || clientnum >= svs.maxclients)
2698 VM_Warning("dropclient: not a client\n");
2701 if (!svs.clients[clientnum].active)
2703 VM_Warning("dropclient: that client slot is not connected\n");
2706 oldhostclient = host_client;
2707 host_client = svs.clients + clientnum;
2708 SV_DropClient(false);
2709 host_client = oldhostclient;
2712 //entity() spawnclient (DP_SV_BOTCLIENT)
2713 static void VM_SV_spawnclient (void)
2717 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2718 prog->xfunction->builtinsprofile += 2;
2720 for (i = 0;i < svs.maxclients;i++)
2722 if (!svs.clients[i].active)
2724 prog->xfunction->builtinsprofile += 100;
2725 SV_ConnectClient (i, NULL);
2726 // this has to be set or else ClientDisconnect won't be called
2727 // we assume the qc will call ClientConnect...
2728 svs.clients[i].clientconnectcalled = true;
2729 ed = PRVM_EDICT_NUM(i + 1);
2733 VM_RETURN_EDICT(ed);
2736 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2737 static void VM_SV_clienttype (void)
2740 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2741 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2742 if (clientnum < 0 || clientnum >= svs.maxclients)
2743 PRVM_G_FLOAT(OFS_RETURN) = 3;
2744 else if (!svs.clients[clientnum].active)
2745 PRVM_G_FLOAT(OFS_RETURN) = 0;
2746 else if (svs.clients[clientnum].netconnection)
2747 PRVM_G_FLOAT(OFS_RETURN) = 1;
2749 PRVM_G_FLOAT(OFS_RETURN) = 2;
2756 string(string key) serverkey
2759 void VM_SV_serverkey(void)
2761 char string[VM_STRINGTEMP_LENGTH];
2762 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2763 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2764 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2767 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2768 static void VM_SV_setmodelindex (void)
2773 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2775 e = PRVM_G_EDICT(OFS_PARM0);
2776 if (e == prog->edicts)
2778 VM_Warning("setmodelindex: can not modify world entity\n");
2781 if (e->priv.server->free)
2783 VM_Warning("setmodelindex: can not modify free entity\n");
2786 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2787 if (i <= 0 || i > MAX_MODELS)
2789 VM_Warning("setmodelindex: invalid modelindex\n");
2792 if (!sv.model_precache[i][0])
2794 VM_Warning("setmodelindex: model not precached\n");
2798 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2799 e->fields.server->modelindex = i;
2805 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2806 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2808 SetMinMaxSize (e, quakemins, quakemaxs, true);
2811 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2814 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2815 static void VM_SV_modelnameforindex (void)
2818 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2820 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2822 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2823 if (i <= 0 || i > MAX_MODELS)
2825 VM_Warning("modelnameforindex: invalid modelindex\n");
2828 if (!sv.model_precache[i][0])
2830 VM_Warning("modelnameforindex: model not precached\n");
2834 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2837 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2838 static void VM_SV_particleeffectnum (void)
2841 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2842 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2845 PRVM_G_FLOAT(OFS_RETURN) = i;
2848 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2849 static void VM_SV_trailparticles (void)
2851 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2853 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2856 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2857 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2858 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2859 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2860 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2861 SV_FlushBroadcastMessages();
2864 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2865 static void VM_SV_pointparticles (void)
2867 int effectnum, count;
2869 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2871 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2874 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2875 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2876 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2877 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2878 if (count == 1 && !VectorLength2(vel))
2881 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2882 MSG_WriteShort(&sv.datagram, effectnum);
2883 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2887 // 1+2+12+12+2=29 bytes
2888 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2889 MSG_WriteShort(&sv.datagram, effectnum);
2890 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2891 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2892 MSG_WriteShort(&sv.datagram, count);
2895 SV_FlushBroadcastMessages();
2898 prvm_builtin_t vm_sv_builtins[] = {
2899 NULL, // #0 NULL function (not callable) (QUAKE)
2900 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2901 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2902 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2903 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2904 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2905 VM_break, // #6 void() break (QUAKE)
2906 VM_random, // #7 float() random (QUAKE)
2907 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2908 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2909 VM_error, // #10 void(string e) error (QUAKE)
2910 VM_objerror, // #11 void(string e) objerror (QUAKE)
2911 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2912 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2913 VM_spawn, // #14 entity() spawn (QUAKE)
2914 VM_remove, // #15 void(entity e) remove (QUAKE)
2915 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2916 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2917 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2918 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2919 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2920 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2921 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2922 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2923 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2924 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2925 VM_ftos, // #26 string(float f) ftos (QUAKE)
2926 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2927 VM_coredump, // #28 void() coredump (QUAKE)
2928 VM_traceon, // #29 void() traceon (QUAKE)
2929 VM_traceoff, // #30 void() traceoff (QUAKE)
2930 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2931 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2932 NULL, // #33 (QUAKE)
2933 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2934 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2935 VM_rint, // #36 float(float v) rint (QUAKE)
2936 VM_floor, // #37 float(float v) floor (QUAKE)
2937 VM_ceil, // #38 float(float v) ceil (QUAKE)
2938 NULL, // #39 (QUAKE)
2939 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2940 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2941 NULL, // #42 (QUAKE)
2942 VM_fabs, // #43 float(float f) fabs (QUAKE)
2943 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2944 VM_cvar, // #45 float(string s) cvar (QUAKE)
2945 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2946 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2947 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2948 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2949 NULL, // #50 (QUAKE)
2950 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2951 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2952 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2953 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2954 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2955 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2956 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2957 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2958 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2959 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2960 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2961 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2962 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2963 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2964 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2965 NULL, // #66 (QUAKE)
2966 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2967 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2968 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2969 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2970 NULL, // #71 (QUAKE)
2971 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2972 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2973 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2974 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2975 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2976 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2977 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2978 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2979 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2980 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2981 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2982 NULL, // #83 (QUAKE)
2983 NULL, // #84 (QUAKE)
2984 NULL, // #85 (QUAKE)
2985 NULL, // #86 (QUAKE)
2986 NULL, // #87 (QUAKE)
2987 NULL, // #88 (QUAKE)
2988 NULL, // #89 (QUAKE)
2989 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2990 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2991 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2992 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2993 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2994 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2995 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2996 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2997 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2998 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
2999 // FrikaC and Telejano range #100-#199
3010 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3011 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3012 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3013 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3014 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3015 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3016 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3017 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3018 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3019 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3100 // FTEQW range #200-#299
3119 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3122 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3123 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3124 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3125 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3126 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3127 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3128 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3129 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3130 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3131 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3133 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3201 // CSQC range #300-#399
3202 NULL, // #300 void() clearscene (EXT_CSQC)
3203 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3204 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3205 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3206 NULL, // #304 void() renderscene (EXT_CSQC)
3207 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3208 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3209 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3210 NULL, // #308 void() R_EndPolygon
3212 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3213 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3217 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3218 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3219 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3220 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3221 NULL, // #319 void(string name) freepic (EXT_CSQC)
3222 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3223 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3224 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3225 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3226 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3227 NULL, // #325 void(void) drawresetcliparea
3232 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3233 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3234 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3235 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3236 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3237 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3238 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3239 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3240 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3241 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3242 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3243 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3244 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3245 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3246 NULL, // #344 vector() getmousepos (EXT_CSQC)
3247 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3248 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3249 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3250 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3251 NULL, // #349 float() isdemo (EXT_CSQC)
3252 VM_isserver, // #350 float() isserver (EXT_CSQC)
3253 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3254 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3255 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3256 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3262 NULL, // #360 float() readbyte (EXT_CSQC)
3263 NULL, // #361 float() readchar (EXT_CSQC)
3264 NULL, // #362 float() readshort (EXT_CSQC)
3265 NULL, // #363 float() readlong (EXT_CSQC)
3266 NULL, // #364 float() readcoord (EXT_CSQC)
3267 NULL, // #365 float() readangle (EXT_CSQC)
3268 NULL, // #366 string() readstring (EXT_CSQC)
3269 NULL, // #367 float() readfloat (EXT_CSQC)
3302 // LordHavoc's range #400-#499
3303 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3304 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3305 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3306 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3307 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3308 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3309 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3310 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3311 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)
3312 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3313 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3314 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3315 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3316 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3317 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3318 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3319 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3320 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3321 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3322 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3323 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3324 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3325 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3326 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3327 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3328 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3329 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3330 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3331 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3332 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3333 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3334 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3335 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3336 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3337 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3338 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3339 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3340 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3341 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3342 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3343 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3344 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3345 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3346 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3347 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3348 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3349 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3350 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3351 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3352 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3353 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3354 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3355 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3356 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3357 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3358 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3359 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3360 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3362 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3363 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3364 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3365 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3366 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3367 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3368 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3369 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3370 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3371 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3372 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3374 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3375 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3376 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3377 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3378 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3379 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3380 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3381 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3382 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3383 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3384 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3385 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3386 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3387 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3388 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3389 VM_SV_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3397 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3398 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3399 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3400 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3401 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3402 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3403 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3404 VM_SV_WritePicture, // #501
3406 VM_whichpack, // #503 string(string) whichpack = #503;
3413 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3414 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3415 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3416 VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3425 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3427 void VM_SV_Cmd_Init(void)
3432 void VM_SV_Cmd_Reset(void)
3434 if(prog->funcoffsets.SV_Shutdown)
3436 func_t s = prog->funcoffsets.SV_Shutdown;
3437 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3438 PRVM_ExecuteProgram(s,"SV_Shutdown() required");