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 "
59 "DP_QC_ASINACOSATANATAN2TAN "
64 "DP_QC_CVAR_DEFSTRING "
71 "DP_QC_FINDCHAINFLAGS "
72 "DP_QC_FINDCHAINFLOAT "
78 "DP_QC_GETSURFACEPOINTATTRIBUTE "
81 "DP_QC_MULTIPLETEMPSTRINGS "
82 "DP_QC_NUM_FOR_EDICT "
84 "DP_QC_SINCOSSQRTPOW "
86 "DP_QC_STRINGBUFFERS "
87 "DP_QC_STRINGCOLORFUNCTIONS "
88 "DP_QC_STRING_CASE_FUNCTIONS "
90 "DP_QC_TOKENIZEBYSEPARATOR "
91 "DP_QC_TOKENIZE_CONSOLE "
94 "DP_QC_TRACE_MOVETYPE_HITMODEL "
95 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
96 "DP_QC_UNLIMITEDTEMPSTRINGS "
99 "DP_QC_VECTOANGLES_WITH_ROLL "
100 "DP_QC_VECTORVECTORS "
107 "DP_SND_DIRECTIONLESSATTNNONE "
114 "DP_SV_CLIENTCOLORS "
117 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
118 "DP_SV_DRAWONLYTOCLIENT "
121 "DP_SV_ENTITYCONTENTSTRANSITION "
122 "DP_SV_MODELFLAGS_AS_EFFECTS "
123 "DP_SV_MOVETYPESTEP_LANDEVENT "
125 "DP_SV_NODRAWTOCLIENT "
126 "DP_SV_ONENTITYNOSPAWNFUNCTION "
127 "DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
129 "DP_SV_PLAYERPHYSICS "
130 "DP_SV_POINTPARTICLES "
132 "DP_SV_PRECACHEANYTIME "
136 "DP_SV_ROTATINGBMODEL "
140 "DP_SV_SPAWNFUNC_PREFIX "
141 "DP_SV_WRITEPICTURE "
142 "DP_SV_WRITEUNTERMINATEDSTRING "
146 "DP_TE_EXPLOSIONRGB "
148 "DP_TE_PARTICLECUBE "
149 "DP_TE_PARTICLERAIN "
150 "DP_TE_PARTICLESNOW "
152 "DP_TE_QUADEFFECTS1 "
155 "DP_TE_STANDARDEFFECTBUILTINS "
156 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
161 "KRIMZON_SV_PARSECLIENTCOMMAND "
164 "NEXUIZ_PLAYERMODEL "
166 "PRYDON_CLIENTCURSOR "
167 "TENEBRAE_GFX_DLIGHTS "
169 //"EXT_CSQC " // not ready yet
176 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.
178 setorigin (entity, origin)
181 static void VM_SV_setorigin (void)
186 VM_SAFEPARMCOUNT(2, VM_setorigin);
188 e = PRVM_G_EDICT(OFS_PARM0);
189 if (e == prog->edicts)
191 VM_Warning("setorigin: can not modify world entity\n");
194 if (e->priv.server->free)
196 VM_Warning("setorigin: can not modify free entity\n");
199 org = PRVM_G_VECTOR(OFS_PARM1);
200 VectorCopy (org, e->fields.server->origin);
201 SV_LinkEdict (e, false);
204 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
205 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
209 for (i=0 ; i<3 ; i++)
211 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
213 // set derived values
214 VectorCopy (min, e->fields.server->mins);
215 VectorCopy (max, e->fields.server->maxs);
216 VectorSubtract (max, min, e->fields.server->size);
218 SV_LinkEdict (e, false);
225 the size box is rotated by the current angle
226 LordHavoc: no it isn't...
228 setsize (entity, minvector, maxvector)
231 static void VM_SV_setsize (void)
236 VM_SAFEPARMCOUNT(3, VM_setsize);
238 e = PRVM_G_EDICT(OFS_PARM0);
239 if (e == prog->edicts)
241 VM_Warning("setsize: can not modify world entity\n");
244 if (e->priv.server->free)
246 VM_Warning("setsize: can not modify free entity\n");
249 min = PRVM_G_VECTOR(OFS_PARM1);
250 max = PRVM_G_VECTOR(OFS_PARM2);
251 SetMinMaxSize (e, min, max, false);
259 setmodel(entity, model)
262 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
263 static void VM_SV_setmodel (void)
269 VM_SAFEPARMCOUNT(2, VM_setmodel);
271 e = PRVM_G_EDICT(OFS_PARM0);
272 if (e == prog->edicts)
274 VM_Warning("setmodel: can not modify world entity\n");
277 if (e->priv.server->free)
279 VM_Warning("setmodel: can not modify free entity\n");
282 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
283 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
284 e->fields.server->modelindex = i;
290 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
291 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
293 SetMinMaxSize (e, quakemins, quakemaxs, true);
296 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
303 single print to a specific client
305 sprint(clientent, value)
308 static void VM_SV_sprint (void)
312 char string[VM_STRINGTEMP_LENGTH];
314 VM_VarString(1, string, sizeof(string));
316 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
318 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
319 // LordHavoc: div0 requested that sprintto world operate like print
326 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
328 VM_Warning("tried to centerprint to a non-client\n");
332 client = svs.clients + entnum-1;
333 if (!client->netconnection)
336 MSG_WriteChar(&client->netconnection->message,svc_print);
337 MSG_WriteString(&client->netconnection->message, string);
345 single print to a specific client
347 centerprint(clientent, value)
350 static void VM_SV_centerprint (void)
354 char string[VM_STRINGTEMP_LENGTH];
356 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
358 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
360 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
362 VM_Warning("tried to centerprint to a non-client\n");
366 client = svs.clients + entnum-1;
367 if (!client->netconnection)
370 VM_VarString(1, string, sizeof(string));
371 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
372 MSG_WriteString(&client->netconnection->message, string);
379 particle(origin, color, count)
382 static void VM_SV_particle (void)
388 VM_SAFEPARMCOUNT(4, VM_SV_particle);
390 org = PRVM_G_VECTOR(OFS_PARM0);
391 dir = PRVM_G_VECTOR(OFS_PARM1);
392 color = PRVM_G_FLOAT(OFS_PARM2);
393 count = PRVM_G_FLOAT(OFS_PARM3);
394 SV_StartParticle (org, dir, (int)color, (int)count);
404 static void VM_SV_ambientsound (void)
408 float vol, attenuation;
411 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
413 pos = PRVM_G_VECTOR (OFS_PARM0);
414 samp = PRVM_G_STRING(OFS_PARM1);
415 vol = PRVM_G_FLOAT(OFS_PARM2);
416 attenuation = PRVM_G_FLOAT(OFS_PARM3);
418 // check to see if samp was properly precached
419 soundnum = SV_SoundIndex(samp, 1);
427 // add an svc_spawnambient command to the level signon packet
430 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
432 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
434 MSG_WriteVector(&sv.signon, pos, sv.protocol);
436 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
437 MSG_WriteShort (&sv.signon, soundnum);
439 MSG_WriteByte (&sv.signon, soundnum);
441 MSG_WriteByte (&sv.signon, (int)(vol*255));
442 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
450 Each entity can have eight independant sound sources, like voice,
453 Channel 0 is an auto-allocate channel, the others override anything
454 already running on that entity/channel pair.
456 An attenuation of 0 will play full volume everywhere in the level.
457 Larger attenuations will drop off.
461 static void VM_SV_sound (void)
465 prvm_edict_t *entity;
469 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
471 entity = PRVM_G_EDICT(OFS_PARM0);
472 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
473 sample = PRVM_G_STRING(OFS_PARM2);
474 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
475 attenuation = PRVM_G_FLOAT(OFS_PARM4);
478 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
482 if (volume < 0 || volume > 255)
484 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
488 if (attenuation < 0 || attenuation > 4)
490 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
494 if (channel < 0 || channel > 7)
496 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
500 SV_StartSound (entity, channel, sample, volume, attenuation);
507 Follows the same logic as VM_SV_sound, except instead of
508 an entity, an origin for the sound is provided, and channel
509 is omitted (since no entity is being tracked).
513 static void VM_SV_pointsound(void)
520 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
522 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
523 sample = PRVM_G_STRING(OFS_PARM1);
524 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
525 attenuation = PRVM_G_FLOAT(OFS_PARM3);
527 if (volume < 0 || volume > 255)
529 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
533 if (attenuation < 0 || attenuation > 4)
535 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
539 SV_StartPointSound (org, sample, volume, attenuation);
546 Used for use tracing and shot targeting
547 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
548 if the tryents flag is set.
550 traceline (vector1, vector2, movetype, ignore)
553 static void VM_SV_traceline (void)
560 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
562 prog->xfunction->builtinsprofile += 30;
564 v1 = PRVM_G_VECTOR(OFS_PARM0);
565 v2 = PRVM_G_VECTOR(OFS_PARM1);
566 move = (int)PRVM_G_FLOAT(OFS_PARM2);
567 ent = PRVM_G_EDICT(OFS_PARM3);
569 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]))
570 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));
572 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
574 VM_SetTraceGlobals(&trace);
582 Used for use tracing and shot targeting
583 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
584 if the tryents flag is set.
586 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
589 // LordHavoc: added this for my own use, VERY useful, similar to traceline
590 static void VM_SV_tracebox (void)
592 float *v1, *v2, *m1, *m2;
597 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
599 prog->xfunction->builtinsprofile += 30;
601 v1 = PRVM_G_VECTOR(OFS_PARM0);
602 m1 = PRVM_G_VECTOR(OFS_PARM1);
603 m2 = PRVM_G_VECTOR(OFS_PARM2);
604 v2 = PRVM_G_VECTOR(OFS_PARM3);
605 move = (int)PRVM_G_FLOAT(OFS_PARM4);
606 ent = PRVM_G_EDICT(OFS_PARM5);
608 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]))
609 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));
611 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
613 VM_SetTraceGlobals(&trace);
616 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
621 vec3_t original_origin;
622 vec3_t original_velocity;
623 vec3_t original_angles;
624 vec3_t original_avelocity;
628 VectorCopy(tossent->fields.server->origin , original_origin );
629 VectorCopy(tossent->fields.server->velocity , original_velocity );
630 VectorCopy(tossent->fields.server->angles , original_angles );
631 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
633 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
634 if (val != NULL && val->_float != 0)
635 gravity = val->_float;
638 gravity *= sv_gravity.value * 0.05;
640 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
642 SV_CheckVelocity (tossent);
643 tossent->fields.server->velocity[2] -= gravity;
644 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
645 VectorScale (tossent->fields.server->velocity, 0.05, move);
646 VectorAdd (tossent->fields.server->origin, move, end);
647 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
648 VectorCopy (trace.endpos, tossent->fields.server->origin);
650 if (trace.fraction < 1)
654 VectorCopy(original_origin , tossent->fields.server->origin );
655 VectorCopy(original_velocity , tossent->fields.server->velocity );
656 VectorCopy(original_angles , tossent->fields.server->angles );
657 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
662 static void VM_SV_tracetoss (void)
666 prvm_edict_t *ignore;
668 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
670 prog->xfunction->builtinsprofile += 600;
672 ent = PRVM_G_EDICT(OFS_PARM0);
673 if (ent == prog->edicts)
675 VM_Warning("tracetoss: can not use world entity\n");
678 ignore = PRVM_G_EDICT(OFS_PARM1);
680 trace = SV_Trace_Toss (ent, ignore);
682 VM_SetTraceGlobals(&trace);
685 //============================================================================
687 static int checkpvsbytes;
688 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
690 static int VM_SV_newcheckclient (int check)
696 // cycle to the next one
698 check = bound(1, check, svs.maxclients);
699 if (check == svs.maxclients)
707 prog->xfunction->builtinsprofile++;
709 if (i == svs.maxclients+1)
711 // look up the client's edict
712 ent = PRVM_EDICT_NUM(i);
713 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
714 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
716 // found a valid client (possibly the same one again)
720 // get the PVS for the entity
721 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
723 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
724 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
733 Returns a client (or object that has a client enemy) that would be a
736 If there is more than one valid option, they are cycled each frame
738 If (self.origin + self.viewofs) is not in the PVS of the current target,
739 it is not returned at all.
744 int c_invis, c_notvis;
745 static void VM_SV_checkclient (void)
747 prvm_edict_t *ent, *self;
750 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
752 // find a new check if on a new frame
753 if (sv.time - sv.lastchecktime >= 0.1)
755 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
756 sv.lastchecktime = sv.time;
759 // return check if it might be visible
760 ent = PRVM_EDICT_NUM(sv.lastcheck);
761 if (ent->priv.server->free || ent->fields.server->health <= 0)
763 VM_RETURN_EDICT(prog->edicts);
767 // if current entity can't possibly see the check entity, return 0
768 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
769 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
770 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
773 VM_RETURN_EDICT(prog->edicts);
777 // might be able to see it
779 VM_RETURN_EDICT(ent);
782 //============================================================================
789 Sends text over to the client's execution buffer
791 stuffcmd (clientent, value, ...)
794 static void VM_SV_stuffcmd (void)
798 char string[VM_STRINGTEMP_LENGTH];
800 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
802 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
803 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
805 VM_Warning("Can't stuffcmd to a non-client\n");
809 VM_VarString(1, string, sizeof(string));
812 host_client = svs.clients + entnum-1;
813 Host_ClientCommands ("%s", string);
821 Returns a chain of entities that have origins within a spherical area
823 findradius (origin, radius)
826 static void VM_SV_findradius (void)
828 prvm_edict_t *ent, *chain;
829 vec_t radius, radius2;
830 vec3_t org, eorg, mins, maxs;
833 prvm_edict_t *touchedicts[MAX_EDICTS];
835 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
837 chain = (prvm_edict_t *)prog->edicts;
839 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
840 radius = PRVM_G_FLOAT(OFS_PARM1);
841 radius2 = radius * radius;
843 mins[0] = org[0] - (radius + 1);
844 mins[1] = org[1] - (radius + 1);
845 mins[2] = org[2] - (radius + 1);
846 maxs[0] = org[0] + (radius + 1);
847 maxs[1] = org[1] + (radius + 1);
848 maxs[2] = org[2] + (radius + 1);
849 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
850 if (numtouchedicts > MAX_EDICTS)
852 // this never happens
853 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
854 numtouchedicts = MAX_EDICTS;
856 for (i = 0;i < numtouchedicts;i++)
858 ent = touchedicts[i];
859 prog->xfunction->builtinsprofile++;
860 // Quake did not return non-solid entities but darkplaces does
861 // (note: this is the reason you can't blow up fallen zombies)
862 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
864 // LordHavoc: compare against bounding box rather than center so it
865 // doesn't miss large objects, and use DotProduct instead of Length
866 // for a major speedup
867 VectorSubtract(org, ent->fields.server->origin, eorg);
868 if (sv_gameplayfix_findradiusdistancetobox.integer)
870 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
871 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
872 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
875 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
876 if (DotProduct(eorg, eorg) < radius2)
878 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
883 VM_RETURN_EDICT(chain);
886 static void VM_SV_precache_sound (void)
888 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
889 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
892 static void VM_SV_precache_model (void)
894 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
895 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
896 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
903 float(float yaw, float dist[, settrace]) walkmove
906 static void VM_SV_walkmove (void)
915 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
917 // assume failure if it returns early
918 PRVM_G_FLOAT(OFS_RETURN) = 0;
920 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
921 if (ent == prog->edicts)
923 VM_Warning("walkmove: can not modify world entity\n");
926 if (ent->priv.server->free)
928 VM_Warning("walkmove: can not modify free entity\n");
931 yaw = PRVM_G_FLOAT(OFS_PARM0);
932 dist = PRVM_G_FLOAT(OFS_PARM1);
933 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
935 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
938 yaw = yaw*M_PI*2 / 360;
940 move[0] = cos(yaw)*dist;
941 move[1] = sin(yaw)*dist;
944 // save program state, because SV_movestep may call other progs
945 oldf = prog->xfunction;
946 oldself = prog->globals.server->self;
948 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
951 // restore program state
952 prog->xfunction = oldf;
953 prog->globals.server->self = oldself;
963 static void VM_SV_droptofloor (void)
969 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
971 // assume failure if it returns early
972 PRVM_G_FLOAT(OFS_RETURN) = 0;
974 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
975 if (ent == prog->edicts)
977 VM_Warning("droptofloor: can not modify world entity\n");
980 if (ent->priv.server->free)
982 VM_Warning("droptofloor: can not modify free entity\n");
986 VectorCopy (ent->fields.server->origin, end);
989 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
990 SV_UnstickEntity(ent);
992 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
993 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
996 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]);
997 VectorAdd(ent->fields.server->origin, offset, org);
998 trace = SV_Move (org, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
999 VectorSubtract(trace.endpos, offset, trace.endpos);
1000 if (trace.startsolid)
1002 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]);
1003 SV_UnstickEntity(ent);
1004 SV_LinkEdict (ent, false);
1005 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1006 ent->fields.server->groundentity = 0;
1007 PRVM_G_FLOAT(OFS_RETURN) = 1;
1009 else if (trace.fraction < 1)
1011 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]);
1012 VectorCopy (trace.endpos, ent->fields.server->origin);
1013 SV_UnstickEntity(ent);
1014 SV_LinkEdict (ent, false);
1015 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1016 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1017 PRVM_G_FLOAT(OFS_RETURN) = 1;
1018 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1019 ent->priv.server->suspendedinairflag = true;
1024 if (trace.fraction != 1)
1026 if (trace.fraction < 1)
1027 VectorCopy (trace.endpos, ent->fields.server->origin);
1028 SV_LinkEdict (ent, false);
1029 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1030 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1031 PRVM_G_FLOAT(OFS_RETURN) = 1;
1032 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1033 ent->priv.server->suspendedinairflag = true;
1042 void(float style, string value) lightstyle
1045 static void VM_SV_lightstyle (void)
1052 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1054 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1055 val = PRVM_G_STRING(OFS_PARM1);
1057 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1058 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1061 // change the string in sv
1062 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1064 // send message to all clients on this server
1065 if (sv.state != ss_active)
1068 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1070 if (client->active && client->netconnection)
1072 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1073 MSG_WriteChar (&client->netconnection->message,style);
1074 MSG_WriteString (&client->netconnection->message, val);
1084 static void VM_SV_checkbottom (void)
1086 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1087 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1095 static void VM_SV_pointcontents (void)
1097 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1098 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1105 Pick a vector for the player to shoot along
1106 vector aim(entity, missilespeed)
1109 static void VM_SV_aim (void)
1111 prvm_edict_t *ent, *check, *bestent;
1112 vec3_t start, dir, end, bestdir;
1115 float dist, bestdist;
1118 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1120 // assume failure if it returns early
1121 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1122 // if sv_aim is so high it can't possibly accept anything, skip out early
1123 if (sv_aim.value >= 1)
1126 ent = PRVM_G_EDICT(OFS_PARM0);
1127 if (ent == prog->edicts)
1129 VM_Warning("aim: can not use world entity\n");
1132 if (ent->priv.server->free)
1134 VM_Warning("aim: can not use free entity\n");
1137 speed = PRVM_G_FLOAT(OFS_PARM1);
1139 VectorCopy (ent->fields.server->origin, start);
1142 // try sending a trace straight
1143 VectorCopy (prog->globals.server->v_forward, dir);
1144 VectorMA (start, 2048, dir, end);
1145 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1146 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1147 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1149 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1154 // try all possible entities
1155 VectorCopy (dir, bestdir);
1156 bestdist = sv_aim.value;
1159 check = PRVM_NEXT_EDICT(prog->edicts);
1160 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1162 prog->xfunction->builtinsprofile++;
1163 if (check->fields.server->takedamage != DAMAGE_AIM)
1167 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1168 continue; // don't aim at teammate
1169 for (j=0 ; j<3 ; j++)
1170 end[j] = check->fields.server->origin[j]
1171 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1172 VectorSubtract (end, start, dir);
1173 VectorNormalize (dir);
1174 dist = DotProduct (dir, prog->globals.server->v_forward);
1175 if (dist < bestdist)
1176 continue; // to far to turn
1177 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1178 if (tr.ent == check)
1179 { // can shoot at this one
1187 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1188 dist = DotProduct (dir, prog->globals.server->v_forward);
1189 VectorScale (prog->globals.server->v_forward, dist, end);
1191 VectorNormalize (end);
1192 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1196 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1201 ===============================================================================
1205 ===============================================================================
1208 #define MSG_BROADCAST 0 // unreliable to all
1209 #define MSG_ONE 1 // reliable to one (msg_entity)
1210 #define MSG_ALL 2 // reliable to all
1211 #define MSG_INIT 3 // write to the init string
1212 #define MSG_ENTITY 5
1214 sizebuf_t *WriteDest (void)
1220 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1224 return &sv.datagram;
1227 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1228 entnum = PRVM_NUM_FOR_EDICT(ent);
1229 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1231 VM_Warning ("WriteDest: tried to write to non-client\n");
1232 return &sv.reliable_datagram;
1235 return &svs.clients[entnum-1].netconnection->message;
1238 VM_Warning ("WriteDest: bad destination\n");
1240 return &sv.reliable_datagram;
1246 return sv.writeentitiestoclient_msg;
1252 static void VM_SV_WriteByte (void)
1254 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1255 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1258 static void VM_SV_WriteChar (void)
1260 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1261 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1264 static void VM_SV_WriteShort (void)
1266 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1267 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1270 static void VM_SV_WriteLong (void)
1272 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1273 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1276 static void VM_SV_WriteAngle (void)
1278 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1279 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1282 static void VM_SV_WriteCoord (void)
1284 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1285 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1288 static void VM_SV_WriteString (void)
1290 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1291 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1294 static void VM_SV_WriteUnterminatedString (void)
1296 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1297 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1301 static void VM_SV_WriteEntity (void)
1303 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1304 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1307 // writes a picture as at most size bytes of data
1309 // IMGNAME \0 SIZE(short) IMGDATA
1310 // if failed to read/compress:
1312 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1313 static void VM_SV_WritePicture (void)
1315 const char *imgname;
1319 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1321 imgname = PRVM_G_STRING(OFS_PARM1);
1322 size = PRVM_G_FLOAT(OFS_PARM2);
1326 MSG_WriteString(WriteDest(), imgname);
1327 if(Image_Compress(imgname, size, &buf, &size))
1330 MSG_WriteShort(WriteDest(), size);
1331 SZ_Write(WriteDest(), buf, size);
1336 MSG_WriteShort(WriteDest(), 0);
1340 //////////////////////////////////////////////////////////
1342 static void VM_SV_makestatic (void)
1347 // allow 0 parameters due to an id1 qc bug in which this function is used
1348 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1349 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1351 if (prog->argc >= 1)
1352 ent = PRVM_G_EDICT(OFS_PARM0);
1354 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1355 if (ent == prog->edicts)
1357 VM_Warning("makestatic: can not modify world entity\n");
1360 if (ent->priv.server->free)
1362 VM_Warning("makestatic: can not modify free entity\n");
1367 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1372 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1373 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1374 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1376 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1378 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1379 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1380 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1384 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1385 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1386 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1389 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1390 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1391 for (i=0 ; i<3 ; i++)
1393 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1394 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1397 // throw the entity away now
1401 //=============================================================================
1408 static void VM_SV_setspawnparms (void)
1414 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1416 ent = PRVM_G_EDICT(OFS_PARM0);
1417 i = PRVM_NUM_FOR_EDICT(ent);
1418 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1420 Con_Print("tried to setspawnparms on a non-client\n");
1424 // copy spawn parms out of the client_t
1425 client = svs.clients + i-1;
1426 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1427 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1434 Returns a color vector indicating the lighting at the requested point.
1436 (Internal Operation note: actually measures the light beneath the point, just like
1437 the model lighting on the client)
1442 static void VM_SV_getlight (void)
1444 vec3_t ambientcolor, diffusecolor, diffusenormal;
1446 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1447 p = PRVM_G_VECTOR(OFS_PARM0);
1448 VectorClear(ambientcolor);
1449 VectorClear(diffusecolor);
1450 VectorClear(diffusenormal);
1451 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1452 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1453 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1458 unsigned char type; // 1/2/8 or other value if isn't used
1462 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1463 static int vm_customstats_last;
1465 void VM_CustomStats_Clear (void)
1469 Z_Free(vm_customstats);
1470 vm_customstats = NULL;
1471 vm_customstats_last = -1;
1475 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1483 for(i=0; i<vm_customstats_last+1 ;i++)
1485 if(!vm_customstats[i].type)
1487 switch(vm_customstats[i].type)
1489 //string as 16 bytes
1492 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1493 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1494 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1495 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1496 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1498 //float field sent as-is
1500 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1502 //integer value of float field
1504 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1512 // void(float index, float type, .void field) SV_AddStat = #232;
1513 // Set up an auto-sent player stat.
1514 // Client's get thier own fields sent to them. Index may not be less than 32.
1515 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1516 // 1: string (4 stats carrying a total of 16 charactures)
1517 // 2: float (one stat, float converted to an integer for transportation)
1518 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1519 static void VM_SV_AddStat (void)
1524 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1528 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1531 VM_Warning("PF_SV_AddStat: not enough memory\n");
1535 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1536 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1537 off = PRVM_G_INT (OFS_PARM2);
1542 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1545 if(i >= (MAX_CL_STATS-32))
1547 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1550 if(i > (MAX_CL_STATS-32-4) && type == 1)
1552 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1555 vm_customstats[i].type = type;
1556 vm_customstats[i].fieldoffset = off;
1557 if(vm_customstats_last < i)
1558 vm_customstats_last = i;
1565 copies data from one entity to another
1567 copyentity(src, dst)
1570 static void VM_SV_copyentity (void)
1572 prvm_edict_t *in, *out;
1573 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1574 in = PRVM_G_EDICT(OFS_PARM0);
1575 if (in == prog->edicts)
1577 VM_Warning("copyentity: can not read world entity\n");
1580 if (in->priv.server->free)
1582 VM_Warning("copyentity: can not read free entity\n");
1585 out = PRVM_G_EDICT(OFS_PARM1);
1586 if (out == prog->edicts)
1588 VM_Warning("copyentity: can not modify world entity\n");
1591 if (out->priv.server->free)
1593 VM_Warning("copyentity: can not modify free entity\n");
1596 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1597 SV_LinkEdict(out, false);
1605 sets the color of a client and broadcasts the update to all connected clients
1607 setcolor(clientent, value)
1610 static void VM_SV_setcolor (void)
1616 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1617 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1618 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1620 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1622 Con_Print("tried to setcolor a non-client\n");
1626 client = svs.clients + entnum-1;
1629 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1631 client->edict->fields.server->team = (i & 15) + 1;
1634 if (client->old_colors != client->colors)
1636 client->old_colors = client->colors;
1637 // send notification to all clients
1638 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1639 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1640 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1648 effect(origin, modelname, startframe, framecount, framerate)
1651 static void VM_SV_effect (void)
1655 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1656 s = PRVM_G_STRING(OFS_PARM1);
1659 VM_Warning("effect: no model specified\n");
1663 i = SV_ModelIndex(s, 1);
1666 VM_Warning("effect: model not precached\n");
1670 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1672 VM_Warning("effect: framecount < 1\n");
1676 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1678 VM_Warning("effect: framerate < 1\n");
1682 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));
1685 static void VM_SV_te_blood (void)
1687 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1688 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1690 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1691 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1693 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1694 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1695 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1697 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1698 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1699 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1701 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1702 SV_FlushBroadcastMessages();
1705 static void VM_SV_te_bloodshower (void)
1707 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1708 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1710 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1711 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1713 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1714 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1715 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1717 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1718 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1719 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1721 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1723 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1724 SV_FlushBroadcastMessages();
1727 static void VM_SV_te_explosionrgb (void)
1729 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1730 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1731 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1733 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1734 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1735 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1737 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1738 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1739 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1740 SV_FlushBroadcastMessages();
1743 static void VM_SV_te_particlecube (void)
1745 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1746 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1748 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1749 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1751 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1752 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1753 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1755 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1756 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1757 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1759 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1760 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1761 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1763 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1765 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1766 // gravity true/false
1767 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1769 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1770 SV_FlushBroadcastMessages();
1773 static void VM_SV_te_particlerain (void)
1775 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1776 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1778 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1779 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1781 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1782 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1783 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1785 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1786 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1787 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1790 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1791 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1793 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1795 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1796 SV_FlushBroadcastMessages();
1799 static void VM_SV_te_particlesnow (void)
1801 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1802 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1804 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1805 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1807 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1808 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1809 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1811 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1812 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1815 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1816 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1817 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1819 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1821 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1822 SV_FlushBroadcastMessages();
1825 static void VM_SV_te_spark (void)
1827 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1828 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1830 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1831 MSG_WriteByte(&sv.datagram, TE_SPARK);
1833 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1834 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1835 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1837 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1838 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1839 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1841 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1842 SV_FlushBroadcastMessages();
1845 static void VM_SV_te_gunshotquad (void)
1847 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1848 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1849 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1851 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1852 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1853 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1854 SV_FlushBroadcastMessages();
1857 static void VM_SV_te_spikequad (void)
1859 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1860 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1861 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1863 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1864 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1865 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1866 SV_FlushBroadcastMessages();
1869 static void VM_SV_te_superspikequad (void)
1871 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1872 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1873 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1875 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1876 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1877 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1878 SV_FlushBroadcastMessages();
1881 static void VM_SV_te_explosionquad (void)
1883 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1884 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1885 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1887 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1888 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1889 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1890 SV_FlushBroadcastMessages();
1893 static void VM_SV_te_smallflash (void)
1895 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1896 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1897 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1899 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1900 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1901 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1902 SV_FlushBroadcastMessages();
1905 static void VM_SV_te_customflash (void)
1907 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1908 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1910 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1911 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1913 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1914 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1915 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1917 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1919 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1921 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1922 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1923 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1924 SV_FlushBroadcastMessages();
1927 static void VM_SV_te_gunshot (void)
1929 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1930 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1931 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1933 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1934 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1935 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1936 SV_FlushBroadcastMessages();
1939 static void VM_SV_te_spike (void)
1941 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1942 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1943 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1945 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1946 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1947 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1948 SV_FlushBroadcastMessages();
1951 static void VM_SV_te_superspike (void)
1953 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1954 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1955 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1957 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1958 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1959 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1960 SV_FlushBroadcastMessages();
1963 static void VM_SV_te_explosion (void)
1965 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1966 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1967 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1969 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1970 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1971 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1972 SV_FlushBroadcastMessages();
1975 static void VM_SV_te_tarexplosion (void)
1977 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1978 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1979 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1981 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1982 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1983 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1984 SV_FlushBroadcastMessages();
1987 static void VM_SV_te_wizspike (void)
1989 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1990 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1991 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1993 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1994 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1995 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1996 SV_FlushBroadcastMessages();
1999 static void VM_SV_te_knightspike (void)
2001 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2002 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2003 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2005 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2006 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2007 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2008 SV_FlushBroadcastMessages();
2011 static void VM_SV_te_lavasplash (void)
2013 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2014 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2015 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2017 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2018 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2019 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2020 SV_FlushBroadcastMessages();
2023 static void VM_SV_te_teleport (void)
2025 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2026 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2027 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2029 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2030 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2031 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2032 SV_FlushBroadcastMessages();
2035 static void VM_SV_te_explosion2 (void)
2037 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2038 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2039 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2041 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2042 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2043 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2045 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2046 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2047 SV_FlushBroadcastMessages();
2050 static void VM_SV_te_lightning1 (void)
2052 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2053 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2054 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2056 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2058 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2059 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2060 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2062 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2063 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2064 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2065 SV_FlushBroadcastMessages();
2068 static void VM_SV_te_lightning2 (void)
2070 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2071 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2072 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2074 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2076 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2077 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2078 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2080 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2081 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2082 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2083 SV_FlushBroadcastMessages();
2086 static void VM_SV_te_lightning3 (void)
2088 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2089 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2090 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2092 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2094 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2095 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2096 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2098 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2099 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2100 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2101 SV_FlushBroadcastMessages();
2104 static void VM_SV_te_beam (void)
2106 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2107 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2108 MSG_WriteByte(&sv.datagram, TE_BEAM);
2110 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2112 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2113 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2114 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2116 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2117 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2118 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2119 SV_FlushBroadcastMessages();
2122 static void VM_SV_te_plasmaburn (void)
2124 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2125 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2126 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2127 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2128 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2129 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2130 SV_FlushBroadcastMessages();
2133 static void VM_SV_te_flamejet (void)
2135 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2136 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2137 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2139 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2140 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2141 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2143 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2144 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2145 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2147 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2148 SV_FlushBroadcastMessages();
2151 void clippointtosurface(dp_model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2154 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2156 bestdist = 1000000000;
2158 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2160 // clip original point to each triangle of the surface and find the
2161 // triangle that is closest
2162 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2163 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2164 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2165 TriangleNormal(v[0], v[1], v[2], facenormal);
2166 VectorNormalize(facenormal);
2167 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2168 VectorMA(p, offsetdist, facenormal, temp);
2169 for (j = 0, k = 2;j < 3;k = j, j++)
2171 VectorSubtract(v[k], v[j], edgenormal);
2172 CrossProduct(edgenormal, facenormal, sidenormal);
2173 VectorNormalize(sidenormal);
2174 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2176 VectorMA(temp, offsetdist, sidenormal, temp);
2178 dist = VectorDistance2(temp, p);
2179 if (bestdist > dist)
2182 VectorCopy(temp, out);
2187 static dp_model_t *getmodel(prvm_edict_t *ed)
2190 if (!ed || ed->priv.server->free)
2192 modelindex = (int)ed->fields.server->modelindex;
2193 if (modelindex < 1 || modelindex >= MAX_MODELS)
2195 return sv.models[modelindex];
2198 static msurface_t *getsurface(dp_model_t *model, int surfacenum)
2200 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2202 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2206 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2207 static void VM_SV_getsurfacenumpoints(void)
2210 msurface_t *surface;
2211 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2212 // return 0 if no such surface
2213 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2215 PRVM_G_FLOAT(OFS_RETURN) = 0;
2219 // note: this (incorrectly) assumes it is a simple polygon
2220 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2222 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2223 static void VM_SV_getsurfacepoint(void)
2227 msurface_t *surface;
2229 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2230 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2231 ed = PRVM_G_EDICT(OFS_PARM0);
2232 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2234 // note: this (incorrectly) assumes it is a simple polygon
2235 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2236 if (pointnum < 0 || pointnum >= surface->num_vertices)
2238 // FIXME: implement rotation/scaling
2239 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2241 //PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
2242 // float SPA_POSITION = 0;
2243 // float SPA_S_AXIS = 1;
2244 // float SPA_T_AXIS = 2;
2245 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2246 // float SPA_TEXCOORDS0 = 4;
2247 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2248 // float SPA_LIGHTMAP0_COLOR = 6;
2249 static void VM_SV_getsurfacepointattribute(void)
2253 msurface_t *surface;
2257 VM_SAFEPARMCOUNT(4, VM_SV_getsurfacepoint);
2258 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2259 ed = PRVM_G_EDICT(OFS_PARM0);
2260 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2262 // note: this (incorrectly) assumes it is a simple polygon
2263 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2264 if (pointnum < 0 || pointnum >= surface->num_vertices)
2266 // FIXME: implement rotation/scaling
2267 attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
2269 switch( attributetype ) {
2270 // float SPA_POSITION = 0;
2272 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2274 // float SPA_S_AXIS = 1;
2276 VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2278 // float SPA_T_AXIS = 2;
2280 VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2282 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2284 VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2286 // float SPA_TEXCOORDS0 = 4;
2288 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2289 float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2];
2290 ret[0] = texcoord[0];
2291 ret[1] = texcoord[1];
2295 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2297 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2298 float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2];
2299 ret[0] = texcoord[0];
2300 ret[1] = texcoord[1];
2304 // float SPA_LIGHTMAP0_COLOR = 6;
2306 // ignore alpha for now..
2307 VectorCopy( &(model->surfmesh.data_lightmapcolor4f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
2310 VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
2314 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2315 static void VM_SV_getsurfacenormal(void)
2318 msurface_t *surface;
2320 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2321 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2322 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2324 // FIXME: implement rotation/scaling
2325 // note: this (incorrectly) assumes it is a simple polygon
2326 // note: this only returns the first triangle, so it doesn't work very
2327 // well for curved surfaces or arbitrary meshes
2328 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);
2329 VectorNormalize(normal);
2330 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2332 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2333 static void VM_SV_getsurfacetexture(void)
2336 msurface_t *surface;
2337 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2338 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2339 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2341 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2343 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2344 static void VM_SV_getsurfacenearpoint(void)
2346 int surfacenum, best;
2348 vec_t dist, bestdist;
2351 msurface_t *surface;
2353 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2354 PRVM_G_FLOAT(OFS_RETURN) = -1;
2355 ed = PRVM_G_EDICT(OFS_PARM0);
2356 point = PRVM_G_VECTOR(OFS_PARM1);
2358 if (!ed || ed->priv.server->free)
2360 model = getmodel(ed);
2361 if (!model || !model->num_surfaces)
2364 // FIXME: implement rotation/scaling
2365 VectorSubtract(point, ed->fields.server->origin, p);
2367 bestdist = 1000000000;
2368 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2370 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2371 // first see if the nearest point on the surface's box is closer than the previous match
2372 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2373 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2374 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2375 dist = VectorLength2(clipped);
2376 if (dist < bestdist)
2378 // it is, check the nearest point on the actual geometry
2379 clippointtosurface(model, surface, p, clipped);
2380 VectorSubtract(clipped, p, clipped);
2381 dist += VectorLength2(clipped);
2382 if (dist < bestdist)
2384 // that's closer too, store it as the best match
2390 PRVM_G_FLOAT(OFS_RETURN) = best;
2392 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2393 static void VM_SV_getsurfaceclippedpoint(void)
2397 msurface_t *surface;
2399 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2400 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2401 ed = PRVM_G_EDICT(OFS_PARM0);
2402 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2404 // FIXME: implement rotation/scaling
2405 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2406 clippointtosurface(model, surface, p, out);
2407 // FIXME: implement rotation/scaling
2408 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2411 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2412 //this function originally written by KrimZon, made shorter by LordHavoc
2413 static void VM_SV_clientcommand (void)
2415 client_t *temp_client;
2417 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2419 //find client for this entity
2420 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2421 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2423 Con_Print("PF_clientcommand: entity is not a client\n");
2427 temp_client = host_client;
2428 host_client = svs.clients + i;
2429 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2430 host_client = temp_client;
2433 //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)
2434 static void VM_SV_setattachment (void)
2436 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2437 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2438 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2442 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2444 if (e == prog->edicts)
2446 VM_Warning("setattachment: can not modify world entity\n");
2449 if (e->priv.server->free)
2451 VM_Warning("setattachment: can not modify free entity\n");
2455 if (tagentity == NULL)
2456 tagentity = prog->edicts;
2458 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2460 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2462 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2465 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2467 modelindex = (int)tagentity->fields.server->modelindex;
2468 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2470 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2472 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);
2475 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));
2479 /////////////////////////////////////////
2480 // DP_MD3_TAGINFO extension coded by VorteX
2482 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2487 i = (int)e->fields.server->modelindex;
2488 if (i < 1 || i >= MAX_MODELS)
2490 model = sv.models[i];
2492 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2495 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2497 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2501 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);
2503 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);
2506 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2512 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2513 && (model = sv.models[(int)ent->fields.server->modelindex])
2514 && model->animscenes)
2516 // if model has wrong frame, engine automatically switches to model first frame
2517 frame = (int)ent->fields.server->frame;
2518 if (frame < 0 || frame >= model->numframes)
2520 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2522 *out = identitymatrix;
2526 // Warnings/errors code:
2527 // 0 - normal (everything all-right)
2530 // 3 - null or non-precached model
2531 // 4 - no tags with requested index
2532 // 5 - runaway loop at attachment chain
2533 extern cvar_t cl_bob;
2534 extern cvar_t cl_bobcycle;
2535 extern cvar_t cl_bobup;
2536 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2540 int modelindex, attachloop;
2541 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2544 *out = identitymatrix; // warnings and errors return identical matrix
2546 if (ent == prog->edicts)
2548 if (ent->priv.server->free)
2551 modelindex = (int)ent->fields.server->modelindex;
2552 if (modelindex <= 0 || modelindex > MAX_MODELS)
2555 model = sv.models[modelindex];
2557 tagmatrix = identitymatrix;
2558 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2562 if (attachloop >= 256) // prevent runaway looping
2564 // apply transformation by child's tagindex on parent entity and then
2565 // by parent entity itself
2566 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2567 if (ret && attachloop == 0)
2569 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2570 SV_GetEntityMatrix(ent, &entitymatrix, false);
2571 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2572 // next iteration we process the parent entity
2573 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2575 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2576 ent = PRVM_EDICT_NUM(val->edict);
2583 // RENDER_VIEWMODEL magic
2584 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2586 Matrix4x4_Copy(&tagmatrix, out);
2587 ent = PRVM_EDICT_NUM(val->edict);
2589 SV_GetEntityMatrix(ent, &entitymatrix, true);
2590 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2593 // Cl_bob, ported from rendering code
2594 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2597 // LordHavoc: this code is *weird*, but not replacable (I think it
2598 // should be done in QC on the server, but oh well, quake is quake)
2599 // LordHavoc: figured out bobup: the time at which the sin is at 180
2600 // degrees (which allows lengthening or squishing the peak or valley)
2601 cycle = sv.time/cl_bobcycle.value;
2602 cycle -= (int)cycle;
2603 if (cycle < cl_bobup.value)
2604 cycle = sin(M_PI * cycle / cl_bobup.value);
2606 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2607 // bob is proportional to velocity in the xy plane
2608 // (don't count Z, or jumping messes it up)
2609 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;
2610 bob = bob*0.3 + bob*0.7*cycle;
2611 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2618 //float(entity ent, string tagname) gettagindex;
2620 static void VM_SV_gettagindex (void)
2623 const char *tag_name;
2624 int modelindex, tag_index;
2626 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2628 ent = PRVM_G_EDICT(OFS_PARM0);
2629 tag_name = PRVM_G_STRING(OFS_PARM1);
2631 if (ent == prog->edicts)
2633 VM_Warning("gettagindex: can't affect world entity\n");
2636 if (ent->priv.server->free)
2638 VM_Warning("gettagindex: can't affect free entity\n");
2642 modelindex = (int)ent->fields.server->modelindex;
2644 if (modelindex <= 0 || modelindex > MAX_MODELS)
2645 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2648 tag_index = SV_GetTagIndex(ent, tag_name);
2650 if(developer.integer >= 100)
2651 Con_Printf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2653 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2656 //vector(entity ent, float tagindex) gettaginfo;
2657 static void VM_SV_gettaginfo (void)
2661 matrix4x4_t tag_matrix;
2664 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2666 e = PRVM_G_EDICT(OFS_PARM0);
2667 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2669 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2670 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2675 VM_Warning("gettagindex: can't affect world entity\n");
2678 VM_Warning("gettagindex: can't affect free entity\n");
2681 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2684 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2687 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2692 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2693 static void VM_SV_dropclient (void)
2696 client_t *oldhostclient;
2697 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2698 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2699 if (clientnum < 0 || clientnum >= svs.maxclients)
2701 VM_Warning("dropclient: not a client\n");
2704 if (!svs.clients[clientnum].active)
2706 VM_Warning("dropclient: that client slot is not connected\n");
2709 oldhostclient = host_client;
2710 host_client = svs.clients + clientnum;
2711 SV_DropClient(false);
2712 host_client = oldhostclient;
2715 //entity() spawnclient (DP_SV_BOTCLIENT)
2716 static void VM_SV_spawnclient (void)
2720 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2721 prog->xfunction->builtinsprofile += 2;
2723 for (i = 0;i < svs.maxclients;i++)
2725 if (!svs.clients[i].active)
2727 prog->xfunction->builtinsprofile += 100;
2728 SV_ConnectClient (i, NULL);
2729 // this has to be set or else ClientDisconnect won't be called
2730 // we assume the qc will call ClientConnect...
2731 svs.clients[i].clientconnectcalled = true;
2732 ed = PRVM_EDICT_NUM(i + 1);
2736 VM_RETURN_EDICT(ed);
2739 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2740 static void VM_SV_clienttype (void)
2743 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2744 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2745 if (clientnum < 0 || clientnum >= svs.maxclients)
2746 PRVM_G_FLOAT(OFS_RETURN) = 3;
2747 else if (!svs.clients[clientnum].active)
2748 PRVM_G_FLOAT(OFS_RETURN) = 0;
2749 else if (svs.clients[clientnum].netconnection)
2750 PRVM_G_FLOAT(OFS_RETURN) = 1;
2752 PRVM_G_FLOAT(OFS_RETURN) = 2;
2759 string(string key) serverkey
2762 void VM_SV_serverkey(void)
2764 char string[VM_STRINGTEMP_LENGTH];
2765 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2766 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2767 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2770 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2771 static void VM_SV_setmodelindex (void)
2776 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2778 e = PRVM_G_EDICT(OFS_PARM0);
2779 if (e == prog->edicts)
2781 VM_Warning("setmodelindex: can not modify world entity\n");
2784 if (e->priv.server->free)
2786 VM_Warning("setmodelindex: can not modify free entity\n");
2789 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2790 if (i <= 0 || i > MAX_MODELS)
2792 VM_Warning("setmodelindex: invalid modelindex\n");
2795 if (!sv.model_precache[i][0])
2797 VM_Warning("setmodelindex: model not precached\n");
2801 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2802 e->fields.server->modelindex = i;
2808 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2809 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2811 SetMinMaxSize (e, quakemins, quakemaxs, true);
2814 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2817 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2818 static void VM_SV_modelnameforindex (void)
2821 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2823 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2825 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2826 if (i <= 0 || i > MAX_MODELS)
2828 VM_Warning("modelnameforindex: invalid modelindex\n");
2831 if (!sv.model_precache[i][0])
2833 VM_Warning("modelnameforindex: model not precached\n");
2837 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2840 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2841 static void VM_SV_particleeffectnum (void)
2844 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2845 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2848 PRVM_G_FLOAT(OFS_RETURN) = i;
2851 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2852 static void VM_SV_trailparticles (void)
2854 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2856 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2859 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2860 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2861 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2862 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2863 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2864 SV_FlushBroadcastMessages();
2867 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2868 static void VM_SV_pointparticles (void)
2870 int effectnum, count;
2872 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2874 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2877 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2878 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2879 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2880 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2881 if (count == 1 && !VectorLength2(vel))
2884 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2885 MSG_WriteShort(&sv.datagram, effectnum);
2886 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2890 // 1+2+12+12+2=29 bytes
2891 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2892 MSG_WriteShort(&sv.datagram, effectnum);
2893 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2894 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2895 MSG_WriteShort(&sv.datagram, count);
2898 SV_FlushBroadcastMessages();
2901 prvm_builtin_t vm_sv_builtins[] = {
2902 NULL, // #0 NULL function (not callable) (QUAKE)
2903 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2904 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2905 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2906 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2907 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2908 VM_break, // #6 void() break (QUAKE)
2909 VM_random, // #7 float() random (QUAKE)
2910 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2911 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2912 VM_error, // #10 void(string e) error (QUAKE)
2913 VM_objerror, // #11 void(string e) objerror (QUAKE)
2914 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2915 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2916 VM_spawn, // #14 entity() spawn (QUAKE)
2917 VM_remove, // #15 void(entity e) remove (QUAKE)
2918 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2919 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2920 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2921 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2922 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2923 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2924 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2925 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2926 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2927 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2928 VM_ftos, // #26 string(float f) ftos (QUAKE)
2929 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2930 VM_coredump, // #28 void() coredump (QUAKE)
2931 VM_traceon, // #29 void() traceon (QUAKE)
2932 VM_traceoff, // #30 void() traceoff (QUAKE)
2933 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2934 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2935 NULL, // #33 (QUAKE)
2936 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2937 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2938 VM_rint, // #36 float(float v) rint (QUAKE)
2939 VM_floor, // #37 float(float v) floor (QUAKE)
2940 VM_ceil, // #38 float(float v) ceil (QUAKE)
2941 NULL, // #39 (QUAKE)
2942 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2943 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2944 NULL, // #42 (QUAKE)
2945 VM_fabs, // #43 float(float f) fabs (QUAKE)
2946 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2947 VM_cvar, // #45 float(string s) cvar (QUAKE)
2948 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2949 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2950 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2951 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2952 NULL, // #50 (QUAKE)
2953 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2954 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2955 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2956 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2957 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2958 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2959 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2960 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2961 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2962 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2963 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2964 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2965 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2966 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2967 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2968 NULL, // #66 (QUAKE)
2969 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2970 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2971 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2972 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2973 NULL, // #71 (QUAKE)
2974 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2975 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2976 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2977 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2978 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2979 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2980 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2981 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2982 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2983 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2984 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2985 NULL, // #83 (QUAKE)
2986 NULL, // #84 (QUAKE)
2987 NULL, // #85 (QUAKE)
2988 NULL, // #86 (QUAKE)
2989 NULL, // #87 (QUAKE)
2990 NULL, // #88 (QUAKE)
2991 NULL, // #89 (QUAKE)
2992 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2993 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2994 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2995 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2996 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2997 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2998 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2999 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3000 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3001 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3002 // FrikaC and Telejano range #100-#199
3013 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3014 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3015 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3016 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3017 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3018 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3019 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3020 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3021 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3022 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3103 // FTEQW range #200-#299
3122 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3125 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3126 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3127 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3128 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3129 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3130 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3131 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3132 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3133 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3134 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3136 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3204 // CSQC range #300-#399
3205 NULL, // #300 void() clearscene (EXT_CSQC)
3206 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3207 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3208 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3209 NULL, // #304 void() renderscene (EXT_CSQC)
3210 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3211 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3212 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3213 NULL, // #308 void() R_EndPolygon
3215 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3216 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3220 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3221 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3222 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3223 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3224 NULL, // #319 void(string name) freepic (EXT_CSQC)
3225 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3226 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3227 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3228 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3229 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3230 NULL, // #325 void(void) drawresetcliparea
3235 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3236 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3237 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3238 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3239 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3240 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3241 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3242 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3243 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3244 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3245 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3246 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3247 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3248 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3249 NULL, // #344 vector() getmousepos (EXT_CSQC)
3250 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3251 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3252 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3253 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3254 NULL, // #349 float() isdemo (EXT_CSQC)
3255 VM_isserver, // #350 float() isserver (EXT_CSQC)
3256 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3257 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3258 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3259 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3265 NULL, // #360 float() readbyte (EXT_CSQC)
3266 NULL, // #361 float() readchar (EXT_CSQC)
3267 NULL, // #362 float() readshort (EXT_CSQC)
3268 NULL, // #363 float() readlong (EXT_CSQC)
3269 NULL, // #364 float() readcoord (EXT_CSQC)
3270 NULL, // #365 float() readangle (EXT_CSQC)
3271 NULL, // #366 string() readstring (EXT_CSQC)
3272 NULL, // #367 float() readfloat (EXT_CSQC)
3305 // LordHavoc's range #400-#499
3306 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3307 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3308 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3309 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3310 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3311 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3312 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3313 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3314 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)
3315 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3316 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3317 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3318 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3319 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3320 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3321 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3322 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3323 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3324 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3325 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3326 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3327 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3328 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3329 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3330 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3331 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3332 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3333 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3334 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3335 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3336 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3337 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3338 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3339 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3340 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3341 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3342 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3343 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3344 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3345 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3346 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3347 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3348 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3349 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3350 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3351 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3352 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3353 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3354 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3355 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3356 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3357 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3358 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3359 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3360 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3361 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3362 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3363 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3365 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3366 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3367 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3368 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3369 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3370 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3371 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3372 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3373 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3374 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3375 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3377 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3378 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3379 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3380 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3381 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3382 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3383 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3384 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3385 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3386 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3387 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3388 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3389 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3390 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3391 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3392 VM_SV_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3400 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3401 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3402 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3403 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3404 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3405 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3406 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3407 VM_SV_WritePicture, // #501
3409 VM_whichpack, // #503 string(string) whichpack = #503;
3416 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3417 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3418 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3419 VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3420 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3421 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3422 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3428 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3430 void VM_SV_Cmd_Init(void)
3435 void VM_SV_Cmd_Reset(void)
3437 if(prog->funcoffsets.SV_Shutdown)
3439 func_t s = prog->funcoffsets.SV_Shutdown;
3440 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3441 PRVM_ExecuteProgram(s,"SV_Shutdown() required");