6 //============================================================================
11 char *vm_sv_extensions =
16 "DP_CON_ALIASPARAMETERS "
36 "DP_ENT_CUSTOMCOLORMAP "
37 "DP_ENT_EXTERIORMODELTOCLIENT "
39 "DP_ENT_LOWPRECISION "
43 "DP_GFX_EXTERNALTEXTURES "
44 "DP_GFX_EXTERNALTEXTURES_PERMAP "
46 "DP_GFX_QUAKE3MODELTAGS "
50 "DP_HALFLIFE_MAP_CVAR "
56 "DP_MOVETYPEBOUNCEMISSILE "
58 "DP_QC_ASINACOSATANATAN2TAN "
63 "DP_QC_CVAR_DEFSTRING "
70 "DP_QC_FINDCHAINFLAGS "
71 "DP_QC_FINDCHAINFLOAT "
77 "DP_QC_GETSURFACEPOINTATTRIBUTE "
80 "DP_QC_MULTIPLETEMPSTRINGS "
81 "DP_QC_NUM_FOR_EDICT "
83 "DP_QC_SINCOSSQRTPOW "
85 "DP_QC_STRINGBUFFERS "
86 "DP_QC_STRINGCOLORFUNCTIONS "
87 "DP_QC_STRING_CASE_FUNCTIONS "
89 "DP_QC_TOKENIZEBYSEPARATOR "
90 "DP_QC_TOKENIZE_CONSOLE "
93 "DP_QC_TRACE_MOVETYPE_HITMODEL "
94 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
95 "DP_QC_UNLIMITEDTEMPSTRINGS "
98 "DP_QC_VECTOANGLES_WITH_ROLL "
99 "DP_QC_VECTORVECTORS "
106 "DP_SND_DIRECTIONLESSATTNNONE "
113 "DP_SV_CLIENTCOLORS "
116 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
117 "DP_SV_DRAWONLYTOCLIENT "
120 "DP_SV_ENTITYCONTENTSTRANSITION "
121 "DP_SV_MODELFLAGS_AS_EFFECTS "
122 "DP_SV_MOVETYPESTEP_LANDEVENT "
124 "DP_SV_NODRAWTOCLIENT "
125 "DP_SV_ONENTITYNOSPAWNFUNCTION "
127 "DP_SV_PLAYERPHYSICS "
128 "DP_SV_POINTPARTICLES "
130 "DP_SV_PRECACHEANYTIME "
134 "DP_SV_ROTATINGBMODEL "
138 "DP_SV_SPAWNFUNC_PREFIX "
139 "DP_SV_WRITEPICTURE "
140 "DP_SV_WRITEUNTERMINATEDSTRING "
144 "DP_TE_EXPLOSIONRGB "
146 "DP_TE_PARTICLECUBE "
147 "DP_TE_PARTICLERAIN "
148 "DP_TE_PARTICLESNOW "
150 "DP_TE_QUADEFFECTS1 "
153 "DP_TE_STANDARDEFFECTBUILTINS "
154 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
159 "KRIMZON_SV_PARSECLIENTCOMMAND "
162 "NEXUIZ_PLAYERMODEL "
164 "PRYDON_CLIENTCURSOR "
165 "TENEBRAE_GFX_DLIGHTS "
167 //"EXT_CSQC " // not ready yet
174 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.
176 setorigin (entity, origin)
179 static void VM_SV_setorigin (void)
184 VM_SAFEPARMCOUNT(2, VM_setorigin);
186 e = PRVM_G_EDICT(OFS_PARM0);
187 if (e == prog->edicts)
189 VM_Warning("setorigin: can not modify world entity\n");
192 if (e->priv.server->free)
194 VM_Warning("setorigin: can not modify free entity\n");
197 org = PRVM_G_VECTOR(OFS_PARM1);
198 VectorCopy (org, e->fields.server->origin);
199 SV_LinkEdict (e, false);
202 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
203 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
207 for (i=0 ; i<3 ; i++)
209 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
211 // set derived values
212 VectorCopy (min, e->fields.server->mins);
213 VectorCopy (max, e->fields.server->maxs);
214 VectorSubtract (max, min, e->fields.server->size);
216 SV_LinkEdict (e, false);
223 the size box is rotated by the current angle
224 LordHavoc: no it isn't...
226 setsize (entity, minvector, maxvector)
229 static void VM_SV_setsize (void)
234 VM_SAFEPARMCOUNT(3, VM_setsize);
236 e = PRVM_G_EDICT(OFS_PARM0);
237 if (e == prog->edicts)
239 VM_Warning("setsize: can not modify world entity\n");
242 if (e->priv.server->free)
244 VM_Warning("setsize: can not modify free entity\n");
247 min = PRVM_G_VECTOR(OFS_PARM1);
248 max = PRVM_G_VECTOR(OFS_PARM2);
249 SetMinMaxSize (e, min, max, false);
257 setmodel(entity, model)
260 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
261 static void VM_SV_setmodel (void)
267 VM_SAFEPARMCOUNT(2, VM_setmodel);
269 e = PRVM_G_EDICT(OFS_PARM0);
270 if (e == prog->edicts)
272 VM_Warning("setmodel: can not modify world entity\n");
275 if (e->priv.server->free)
277 VM_Warning("setmodel: can not modify free entity\n");
280 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
281 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
282 e->fields.server->modelindex = i;
288 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
289 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
291 SetMinMaxSize (e, quakemins, quakemaxs, true);
294 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
301 single print to a specific client
303 sprint(clientent, value)
306 static void VM_SV_sprint (void)
310 char string[VM_STRINGTEMP_LENGTH];
312 VM_VarString(1, string, sizeof(string));
314 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
316 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
317 // LordHavoc: div0 requested that sprintto world operate like print
324 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
326 VM_Warning("tried to centerprint to a non-client\n");
330 client = svs.clients + entnum-1;
331 if (!client->netconnection)
334 MSG_WriteChar(&client->netconnection->message,svc_print);
335 MSG_WriteString(&client->netconnection->message, string);
343 single print to a specific client
345 centerprint(clientent, value)
348 static void VM_SV_centerprint (void)
352 char string[VM_STRINGTEMP_LENGTH];
354 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
356 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
358 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
360 VM_Warning("tried to centerprint to a non-client\n");
364 client = svs.clients + entnum-1;
365 if (!client->netconnection)
368 VM_VarString(1, string, sizeof(string));
369 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
370 MSG_WriteString(&client->netconnection->message, string);
377 particle(origin, color, count)
380 static void VM_SV_particle (void)
386 VM_SAFEPARMCOUNT(4, VM_SV_particle);
388 org = PRVM_G_VECTOR(OFS_PARM0);
389 dir = PRVM_G_VECTOR(OFS_PARM1);
390 color = PRVM_G_FLOAT(OFS_PARM2);
391 count = PRVM_G_FLOAT(OFS_PARM3);
392 SV_StartParticle (org, dir, (int)color, (int)count);
402 static void VM_SV_ambientsound (void)
406 float vol, attenuation;
409 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
411 pos = PRVM_G_VECTOR (OFS_PARM0);
412 samp = PRVM_G_STRING(OFS_PARM1);
413 vol = PRVM_G_FLOAT(OFS_PARM2);
414 attenuation = PRVM_G_FLOAT(OFS_PARM3);
416 // check to see if samp was properly precached
417 soundnum = SV_SoundIndex(samp, 1);
425 // add an svc_spawnambient command to the level signon packet
428 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
430 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
432 MSG_WriteVector(&sv.signon, pos, sv.protocol);
434 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
435 MSG_WriteShort (&sv.signon, soundnum);
437 MSG_WriteByte (&sv.signon, soundnum);
439 MSG_WriteByte (&sv.signon, (int)(vol*255));
440 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
448 Each entity can have eight independant sound sources, like voice,
451 Channel 0 is an auto-allocate channel, the others override anything
452 already running on that entity/channel pair.
454 An attenuation of 0 will play full volume everywhere in the level.
455 Larger attenuations will drop off.
459 static void VM_SV_sound (void)
463 prvm_edict_t *entity;
467 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
469 entity = PRVM_G_EDICT(OFS_PARM0);
470 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
471 sample = PRVM_G_STRING(OFS_PARM2);
472 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
473 attenuation = PRVM_G_FLOAT(OFS_PARM4);
476 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
480 if (volume < 0 || volume > 255)
482 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
486 if (attenuation < 0 || attenuation > 4)
488 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
492 if (channel < 0 || channel > 7)
494 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
498 SV_StartSound (entity, channel, sample, volume, attenuation);
505 Follows the same logic as VM_SV_sound, except instead of
506 an entity, an origin for the sound is provided, and channel
507 is omitted (since no entity is being tracked).
511 static void VM_SV_pointsound(void)
518 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
520 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
521 sample = PRVM_G_STRING(OFS_PARM1);
522 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
523 attenuation = PRVM_G_FLOAT(OFS_PARM3);
525 if (volume < 0 || volume > 255)
527 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
531 if (attenuation < 0 || attenuation > 4)
533 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
537 SV_StartPointSound (org, sample, volume, attenuation);
544 Used for use tracing and shot targeting
545 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
546 if the tryents flag is set.
548 traceline (vector1, vector2, movetype, ignore)
551 static void VM_SV_traceline (void)
558 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
560 prog->xfunction->builtinsprofile += 30;
562 v1 = PRVM_G_VECTOR(OFS_PARM0);
563 v2 = PRVM_G_VECTOR(OFS_PARM1);
564 move = (int)PRVM_G_FLOAT(OFS_PARM2);
565 ent = PRVM_G_EDICT(OFS_PARM3);
567 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]))
568 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));
570 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
572 VM_SetTraceGlobals(&trace);
580 Used for use tracing and shot targeting
581 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
582 if the tryents flag is set.
584 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
587 // LordHavoc: added this for my own use, VERY useful, similar to traceline
588 static void VM_SV_tracebox (void)
590 float *v1, *v2, *m1, *m2;
595 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
597 prog->xfunction->builtinsprofile += 30;
599 v1 = PRVM_G_VECTOR(OFS_PARM0);
600 m1 = PRVM_G_VECTOR(OFS_PARM1);
601 m2 = PRVM_G_VECTOR(OFS_PARM2);
602 v2 = PRVM_G_VECTOR(OFS_PARM3);
603 move = (int)PRVM_G_FLOAT(OFS_PARM4);
604 ent = PRVM_G_EDICT(OFS_PARM5);
606 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]))
607 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));
609 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
611 VM_SetTraceGlobals(&trace);
614 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
619 vec3_t original_origin;
620 vec3_t original_velocity;
621 vec3_t original_angles;
622 vec3_t original_avelocity;
626 VectorCopy(tossent->fields.server->origin , original_origin );
627 VectorCopy(tossent->fields.server->velocity , original_velocity );
628 VectorCopy(tossent->fields.server->angles , original_angles );
629 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
631 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
632 if (val != NULL && val->_float != 0)
633 gravity = val->_float;
636 gravity *= sv_gravity.value * 0.05;
638 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
640 SV_CheckVelocity (tossent);
641 tossent->fields.server->velocity[2] -= gravity;
642 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
643 VectorScale (tossent->fields.server->velocity, 0.05, move);
644 VectorAdd (tossent->fields.server->origin, move, end);
645 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
646 VectorCopy (trace.endpos, tossent->fields.server->origin);
648 if (trace.fraction < 1)
652 VectorCopy(original_origin , tossent->fields.server->origin );
653 VectorCopy(original_velocity , tossent->fields.server->velocity );
654 VectorCopy(original_angles , tossent->fields.server->angles );
655 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
660 static void VM_SV_tracetoss (void)
664 prvm_edict_t *ignore;
666 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
668 prog->xfunction->builtinsprofile += 600;
670 ent = PRVM_G_EDICT(OFS_PARM0);
671 if (ent == prog->edicts)
673 VM_Warning("tracetoss: can not use world entity\n");
676 ignore = PRVM_G_EDICT(OFS_PARM1);
678 trace = SV_Trace_Toss (ent, ignore);
680 VM_SetTraceGlobals(&trace);
683 //============================================================================
685 static int checkpvsbytes;
686 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
688 static int VM_SV_newcheckclient (int check)
694 // cycle to the next one
696 check = bound(1, check, svs.maxclients);
697 if (check == svs.maxclients)
705 prog->xfunction->builtinsprofile++;
707 if (i == svs.maxclients+1)
709 // look up the client's edict
710 ent = PRVM_EDICT_NUM(i);
711 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
712 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
714 // found a valid client (possibly the same one again)
718 // get the PVS for the entity
719 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
721 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
722 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
731 Returns a client (or object that has a client enemy) that would be a
734 If there is more than one valid option, they are cycled each frame
736 If (self.origin + self.viewofs) is not in the PVS of the current target,
737 it is not returned at all.
742 int c_invis, c_notvis;
743 static void VM_SV_checkclient (void)
745 prvm_edict_t *ent, *self;
748 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
750 // find a new check if on a new frame
751 if (sv.time - sv.lastchecktime >= 0.1)
753 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
754 sv.lastchecktime = sv.time;
757 // return check if it might be visible
758 ent = PRVM_EDICT_NUM(sv.lastcheck);
759 if (ent->priv.server->free || ent->fields.server->health <= 0)
761 VM_RETURN_EDICT(prog->edicts);
765 // if current entity can't possibly see the check entity, return 0
766 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
767 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
768 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
771 VM_RETURN_EDICT(prog->edicts);
775 // might be able to see it
777 VM_RETURN_EDICT(ent);
780 //============================================================================
787 Sends text over to the client's execution buffer
789 stuffcmd (clientent, value, ...)
792 static void VM_SV_stuffcmd (void)
796 char string[VM_STRINGTEMP_LENGTH];
798 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
800 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
801 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
803 VM_Warning("Can't stuffcmd to a non-client\n");
807 VM_VarString(1, string, sizeof(string));
810 host_client = svs.clients + entnum-1;
811 Host_ClientCommands ("%s", string);
819 Returns a chain of entities that have origins within a spherical area
821 findradius (origin, radius)
824 static void VM_SV_findradius (void)
826 prvm_edict_t *ent, *chain;
827 vec_t radius, radius2;
828 vec3_t org, eorg, mins, maxs;
831 prvm_edict_t *touchedicts[MAX_EDICTS];
833 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
835 chain = (prvm_edict_t *)prog->edicts;
837 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
838 radius = PRVM_G_FLOAT(OFS_PARM1);
839 radius2 = radius * radius;
841 mins[0] = org[0] - (radius + 1);
842 mins[1] = org[1] - (radius + 1);
843 mins[2] = org[2] - (radius + 1);
844 maxs[0] = org[0] + (radius + 1);
845 maxs[1] = org[1] + (radius + 1);
846 maxs[2] = org[2] + (radius + 1);
847 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
848 if (numtouchedicts > MAX_EDICTS)
850 // this never happens
851 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
852 numtouchedicts = MAX_EDICTS;
854 for (i = 0;i < numtouchedicts;i++)
856 ent = touchedicts[i];
857 prog->xfunction->builtinsprofile++;
858 // Quake did not return non-solid entities but darkplaces does
859 // (note: this is the reason you can't blow up fallen zombies)
860 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
862 // LordHavoc: compare against bounding box rather than center so it
863 // doesn't miss large objects, and use DotProduct instead of Length
864 // for a major speedup
865 VectorSubtract(org, ent->fields.server->origin, eorg);
866 if (sv_gameplayfix_findradiusdistancetobox.integer)
868 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
869 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
870 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
873 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
874 if (DotProduct(eorg, eorg) < radius2)
876 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
881 VM_RETURN_EDICT(chain);
884 static void VM_SV_precache_sound (void)
886 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
887 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
890 static void VM_SV_precache_model (void)
892 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
893 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
894 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
901 float(float yaw, float dist[, settrace]) walkmove
904 static void VM_SV_walkmove (void)
913 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
915 // assume failure if it returns early
916 PRVM_G_FLOAT(OFS_RETURN) = 0;
918 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
919 if (ent == prog->edicts)
921 VM_Warning("walkmove: can not modify world entity\n");
924 if (ent->priv.server->free)
926 VM_Warning("walkmove: can not modify free entity\n");
929 yaw = PRVM_G_FLOAT(OFS_PARM0);
930 dist = PRVM_G_FLOAT(OFS_PARM1);
931 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
933 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
936 yaw = yaw*M_PI*2 / 360;
938 move[0] = cos(yaw)*dist;
939 move[1] = sin(yaw)*dist;
942 // save program state, because SV_movestep may call other progs
943 oldf = prog->xfunction;
944 oldself = prog->globals.server->self;
946 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
949 // restore program state
950 prog->xfunction = oldf;
951 prog->globals.server->self = oldself;
961 static void VM_SV_droptofloor (void)
967 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
969 // assume failure if it returns early
970 PRVM_G_FLOAT(OFS_RETURN) = 0;
972 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
973 if (ent == prog->edicts)
975 VM_Warning("droptofloor: can not modify world entity\n");
978 if (ent->priv.server->free)
980 VM_Warning("droptofloor: can not modify free entity\n");
984 VectorCopy (ent->fields.server->origin, end);
987 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
988 SV_UnstickEntity(ent);
990 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
991 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
994 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]);
995 VectorAdd(ent->fields.server->origin, offset, org);
996 trace = SV_Move (org, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
997 VectorSubtract(trace.endpos, offset, trace.endpos);
998 if (trace.startsolid)
1000 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]);
1001 SV_UnstickEntity(ent);
1002 SV_LinkEdict (ent, false);
1003 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1004 ent->fields.server->groundentity = 0;
1005 PRVM_G_FLOAT(OFS_RETURN) = 1;
1007 else if (trace.fraction < 1)
1009 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]);
1010 VectorCopy (trace.endpos, ent->fields.server->origin);
1011 SV_UnstickEntity(ent);
1012 SV_LinkEdict (ent, false);
1013 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1014 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1015 PRVM_G_FLOAT(OFS_RETURN) = 1;
1016 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1017 ent->priv.server->suspendedinairflag = true;
1022 if (trace.fraction != 1)
1024 if (trace.fraction < 1)
1025 VectorCopy (trace.endpos, ent->fields.server->origin);
1026 SV_LinkEdict (ent, false);
1027 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1028 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1029 PRVM_G_FLOAT(OFS_RETURN) = 1;
1030 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1031 ent->priv.server->suspendedinairflag = true;
1040 void(float style, string value) lightstyle
1043 static void VM_SV_lightstyle (void)
1050 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1052 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1053 val = PRVM_G_STRING(OFS_PARM1);
1055 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1056 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1059 // change the string in sv
1060 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1062 // send message to all clients on this server
1063 if (sv.state != ss_active)
1066 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1068 if (client->active && client->netconnection)
1070 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1071 MSG_WriteChar (&client->netconnection->message,style);
1072 MSG_WriteString (&client->netconnection->message, val);
1082 static void VM_SV_checkbottom (void)
1084 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1085 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1093 static void VM_SV_pointcontents (void)
1095 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1096 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1103 Pick a vector for the player to shoot along
1104 vector aim(entity, missilespeed)
1107 static void VM_SV_aim (void)
1109 prvm_edict_t *ent, *check, *bestent;
1110 vec3_t start, dir, end, bestdir;
1113 float dist, bestdist;
1116 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1118 // assume failure if it returns early
1119 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1120 // if sv_aim is so high it can't possibly accept anything, skip out early
1121 if (sv_aim.value >= 1)
1124 ent = PRVM_G_EDICT(OFS_PARM0);
1125 if (ent == prog->edicts)
1127 VM_Warning("aim: can not use world entity\n");
1130 if (ent->priv.server->free)
1132 VM_Warning("aim: can not use free entity\n");
1135 speed = PRVM_G_FLOAT(OFS_PARM1);
1137 VectorCopy (ent->fields.server->origin, start);
1140 // try sending a trace straight
1141 VectorCopy (prog->globals.server->v_forward, dir);
1142 VectorMA (start, 2048, dir, end);
1143 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1144 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1145 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1147 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1152 // try all possible entities
1153 VectorCopy (dir, bestdir);
1154 bestdist = sv_aim.value;
1157 check = PRVM_NEXT_EDICT(prog->edicts);
1158 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1160 prog->xfunction->builtinsprofile++;
1161 if (check->fields.server->takedamage != DAMAGE_AIM)
1165 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1166 continue; // don't aim at teammate
1167 for (j=0 ; j<3 ; j++)
1168 end[j] = check->fields.server->origin[j]
1169 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1170 VectorSubtract (end, start, dir);
1171 VectorNormalize (dir);
1172 dist = DotProduct (dir, prog->globals.server->v_forward);
1173 if (dist < bestdist)
1174 continue; // to far to turn
1175 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1176 if (tr.ent == check)
1177 { // can shoot at this one
1185 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1186 dist = DotProduct (dir, prog->globals.server->v_forward);
1187 VectorScale (prog->globals.server->v_forward, dist, end);
1189 VectorNormalize (end);
1190 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1194 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1199 ===============================================================================
1203 ===============================================================================
1206 #define MSG_BROADCAST 0 // unreliable to all
1207 #define MSG_ONE 1 // reliable to one (msg_entity)
1208 #define MSG_ALL 2 // reliable to all
1209 #define MSG_INIT 3 // write to the init string
1210 #define MSG_ENTITY 5
1212 sizebuf_t *WriteDest (void)
1218 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1222 return &sv.datagram;
1225 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1226 entnum = PRVM_NUM_FOR_EDICT(ent);
1227 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1229 VM_Warning ("WriteDest: tried to write to non-client\n");
1230 return &sv.reliable_datagram;
1233 return &svs.clients[entnum-1].netconnection->message;
1236 VM_Warning ("WriteDest: bad destination\n");
1238 return &sv.reliable_datagram;
1244 return sv.writeentitiestoclient_msg;
1250 static void VM_SV_WriteByte (void)
1252 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1253 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1256 static void VM_SV_WriteChar (void)
1258 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1259 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1262 static void VM_SV_WriteShort (void)
1264 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1265 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1268 static void VM_SV_WriteLong (void)
1270 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1271 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1274 static void VM_SV_WriteAngle (void)
1276 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1277 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1280 static void VM_SV_WriteCoord (void)
1282 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1283 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1286 static void VM_SV_WriteString (void)
1288 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1289 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1292 static void VM_SV_WriteUnterminatedString (void)
1294 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1295 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1299 static void VM_SV_WriteEntity (void)
1301 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1302 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1305 // writes a picture as at most size bytes of data
1307 // IMGNAME \0 SIZE(short) IMGDATA
1308 // if failed to read/compress:
1310 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1311 static void VM_SV_WritePicture (void)
1313 const char *imgname;
1317 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1319 imgname = PRVM_G_STRING(OFS_PARM1);
1320 size = PRVM_G_FLOAT(OFS_PARM2);
1324 MSG_WriteString(WriteDest(), imgname);
1325 if(Image_Compress(imgname, size, &buf, &size))
1328 MSG_WriteShort(WriteDest(), size);
1329 SZ_Write(WriteDest(), buf, size);
1334 MSG_WriteShort(WriteDest(), 0);
1338 //////////////////////////////////////////////////////////
1340 static void VM_SV_makestatic (void)
1345 // allow 0 parameters due to an id1 qc bug in which this function is used
1346 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1347 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1349 if (prog->argc >= 1)
1350 ent = PRVM_G_EDICT(OFS_PARM0);
1352 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1353 if (ent == prog->edicts)
1355 VM_Warning("makestatic: can not modify world entity\n");
1358 if (ent->priv.server->free)
1360 VM_Warning("makestatic: can not modify free entity\n");
1365 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1370 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1371 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1372 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1374 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1376 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1377 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1378 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1382 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1383 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1384 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1387 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1388 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1389 for (i=0 ; i<3 ; i++)
1391 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1392 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1395 // throw the entity away now
1399 //=============================================================================
1406 static void VM_SV_setspawnparms (void)
1412 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1414 ent = PRVM_G_EDICT(OFS_PARM0);
1415 i = PRVM_NUM_FOR_EDICT(ent);
1416 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1418 Con_Print("tried to setspawnparms on a non-client\n");
1422 // copy spawn parms out of the client_t
1423 client = svs.clients + i-1;
1424 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1425 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1432 Returns a color vector indicating the lighting at the requested point.
1434 (Internal Operation note: actually measures the light beneath the point, just like
1435 the model lighting on the client)
1440 static void VM_SV_getlight (void)
1442 vec3_t ambientcolor, diffusecolor, diffusenormal;
1444 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1445 p = PRVM_G_VECTOR(OFS_PARM0);
1446 VectorClear(ambientcolor);
1447 VectorClear(diffusecolor);
1448 VectorClear(diffusenormal);
1449 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1450 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1451 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1456 unsigned char type; // 1/2/8 or other value if isn't used
1460 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1461 static int vm_customstats_last;
1463 void VM_CustomStats_Clear (void)
1467 Z_Free(vm_customstats);
1468 vm_customstats = NULL;
1469 vm_customstats_last = -1;
1473 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1481 for(i=0; i<vm_customstats_last+1 ;i++)
1483 if(!vm_customstats[i].type)
1485 switch(vm_customstats[i].type)
1487 //string as 16 bytes
1490 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1491 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1492 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1493 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1494 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1496 //float field sent as-is
1498 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1500 //integer value of float field
1502 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1510 // void(float index, float type, .void field) SV_AddStat = #232;
1511 // Set up an auto-sent player stat.
1512 // Client's get thier own fields sent to them. Index may not be less than 32.
1513 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1514 // 1: string (4 stats carrying a total of 16 charactures)
1515 // 2: float (one stat, float converted to an integer for transportation)
1516 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1517 static void VM_SV_AddStat (void)
1522 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1526 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1529 VM_Warning("PF_SV_AddStat: not enough memory\n");
1533 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1534 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1535 off = PRVM_G_INT (OFS_PARM2);
1540 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1543 if(i >= (MAX_CL_STATS-32))
1545 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1548 if(i > (MAX_CL_STATS-32-4) && type == 1)
1550 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1553 vm_customstats[i].type = type;
1554 vm_customstats[i].fieldoffset = off;
1555 if(vm_customstats_last < i)
1556 vm_customstats_last = i;
1563 copies data from one entity to another
1565 copyentity(src, dst)
1568 static void VM_SV_copyentity (void)
1570 prvm_edict_t *in, *out;
1571 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1572 in = PRVM_G_EDICT(OFS_PARM0);
1573 if (in == prog->edicts)
1575 VM_Warning("copyentity: can not read world entity\n");
1578 if (in->priv.server->free)
1580 VM_Warning("copyentity: can not read free entity\n");
1583 out = PRVM_G_EDICT(OFS_PARM1);
1584 if (out == prog->edicts)
1586 VM_Warning("copyentity: can not modify world entity\n");
1589 if (out->priv.server->free)
1591 VM_Warning("copyentity: can not modify free entity\n");
1594 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1595 SV_LinkEdict(out, false);
1603 sets the color of a client and broadcasts the update to all connected clients
1605 setcolor(clientent, value)
1608 static void VM_SV_setcolor (void)
1614 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1615 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1616 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1618 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1620 Con_Print("tried to setcolor a non-client\n");
1624 client = svs.clients + entnum-1;
1627 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1629 client->edict->fields.server->team = (i & 15) + 1;
1632 if (client->old_colors != client->colors)
1634 client->old_colors = client->colors;
1635 // send notification to all clients
1636 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1637 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1638 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1646 effect(origin, modelname, startframe, framecount, framerate)
1649 static void VM_SV_effect (void)
1653 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1654 s = PRVM_G_STRING(OFS_PARM1);
1657 VM_Warning("effect: no model specified\n");
1661 i = SV_ModelIndex(s, 1);
1664 VM_Warning("effect: model not precached\n");
1668 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1670 VM_Warning("effect: framecount < 1\n");
1674 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1676 VM_Warning("effect: framerate < 1\n");
1680 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));
1683 static void VM_SV_te_blood (void)
1685 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1686 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1688 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1689 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1691 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1692 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1693 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1695 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1696 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1697 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1699 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1700 SV_FlushBroadcastMessages();
1703 static void VM_SV_te_bloodshower (void)
1705 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1706 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1708 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1709 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1711 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1712 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1713 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1715 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1716 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1717 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1719 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1721 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1722 SV_FlushBroadcastMessages();
1725 static void VM_SV_te_explosionrgb (void)
1727 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1728 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1729 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1731 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1732 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1733 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1735 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1736 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1737 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1738 SV_FlushBroadcastMessages();
1741 static void VM_SV_te_particlecube (void)
1743 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1744 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1746 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1747 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1749 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1750 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1751 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1753 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1754 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1755 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1757 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1758 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1759 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1761 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1763 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1764 // gravity true/false
1765 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1767 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1768 SV_FlushBroadcastMessages();
1771 static void VM_SV_te_particlerain (void)
1773 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1774 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1776 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1777 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1779 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1780 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1781 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1783 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1784 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1785 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1787 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1788 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1791 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1793 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1794 SV_FlushBroadcastMessages();
1797 static void VM_SV_te_particlesnow (void)
1799 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1800 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1802 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1803 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1805 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1806 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1807 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1809 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1810 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1811 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1814 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1815 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1817 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1819 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1820 SV_FlushBroadcastMessages();
1823 static void VM_SV_te_spark (void)
1825 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1826 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1828 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1829 MSG_WriteByte(&sv.datagram, TE_SPARK);
1831 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1832 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1833 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1835 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1836 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1837 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1839 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1840 SV_FlushBroadcastMessages();
1843 static void VM_SV_te_gunshotquad (void)
1845 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1846 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1847 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1849 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1850 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1851 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1852 SV_FlushBroadcastMessages();
1855 static void VM_SV_te_spikequad (void)
1857 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1858 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1859 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1861 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1862 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1863 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1864 SV_FlushBroadcastMessages();
1867 static void VM_SV_te_superspikequad (void)
1869 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1870 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1871 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1873 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1874 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1875 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1876 SV_FlushBroadcastMessages();
1879 static void VM_SV_te_explosionquad (void)
1881 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1882 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1883 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1885 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1886 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1887 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1888 SV_FlushBroadcastMessages();
1891 static void VM_SV_te_smallflash (void)
1893 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1894 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1895 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1897 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1898 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1899 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1900 SV_FlushBroadcastMessages();
1903 static void VM_SV_te_customflash (void)
1905 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1906 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1908 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1909 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1911 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1912 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1913 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1915 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1917 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1919 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1920 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1921 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1922 SV_FlushBroadcastMessages();
1925 static void VM_SV_te_gunshot (void)
1927 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1928 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1929 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1931 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1932 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1933 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1934 SV_FlushBroadcastMessages();
1937 static void VM_SV_te_spike (void)
1939 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1940 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1941 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1943 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1944 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1945 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1946 SV_FlushBroadcastMessages();
1949 static void VM_SV_te_superspike (void)
1951 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1952 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1953 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1955 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1956 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1957 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1958 SV_FlushBroadcastMessages();
1961 static void VM_SV_te_explosion (void)
1963 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1964 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1965 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1967 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1968 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1969 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1970 SV_FlushBroadcastMessages();
1973 static void VM_SV_te_tarexplosion (void)
1975 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1976 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1977 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1979 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1980 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1981 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1982 SV_FlushBroadcastMessages();
1985 static void VM_SV_te_wizspike (void)
1987 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1988 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1989 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1991 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1992 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1993 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1994 SV_FlushBroadcastMessages();
1997 static void VM_SV_te_knightspike (void)
1999 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2000 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2001 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2003 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2004 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2005 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2006 SV_FlushBroadcastMessages();
2009 static void VM_SV_te_lavasplash (void)
2011 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2012 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2013 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2015 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2016 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2017 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2018 SV_FlushBroadcastMessages();
2021 static void VM_SV_te_teleport (void)
2023 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2024 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2025 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2027 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2028 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2029 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2030 SV_FlushBroadcastMessages();
2033 static void VM_SV_te_explosion2 (void)
2035 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2036 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2037 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2039 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2040 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2041 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2043 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2044 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2045 SV_FlushBroadcastMessages();
2048 static void VM_SV_te_lightning1 (void)
2050 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2051 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2052 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2054 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2056 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2057 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2058 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2060 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2061 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2062 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2063 SV_FlushBroadcastMessages();
2066 static void VM_SV_te_lightning2 (void)
2068 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2069 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2070 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2072 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2074 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2075 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2076 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2078 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2079 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2080 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2081 SV_FlushBroadcastMessages();
2084 static void VM_SV_te_lightning3 (void)
2086 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2087 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2088 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2090 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2092 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2093 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2094 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2096 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2097 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2098 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2099 SV_FlushBroadcastMessages();
2102 static void VM_SV_te_beam (void)
2104 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2105 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2106 MSG_WriteByte(&sv.datagram, TE_BEAM);
2108 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2110 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2111 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2112 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2114 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2115 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2116 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2117 SV_FlushBroadcastMessages();
2120 static void VM_SV_te_plasmaburn (void)
2122 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2123 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2124 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2125 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2126 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2127 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2128 SV_FlushBroadcastMessages();
2131 static void VM_SV_te_flamejet (void)
2133 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2134 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2135 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2137 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2138 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2139 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2141 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2142 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2143 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2145 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2146 SV_FlushBroadcastMessages();
2149 void clippointtosurface(dp_model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2152 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2154 bestdist = 1000000000;
2156 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2158 // clip original point to each triangle of the surface and find the
2159 // triangle that is closest
2160 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2161 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2162 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2163 TriangleNormal(v[0], v[1], v[2], facenormal);
2164 VectorNormalize(facenormal);
2165 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2166 VectorMA(p, offsetdist, facenormal, temp);
2167 for (j = 0, k = 2;j < 3;k = j, j++)
2169 VectorSubtract(v[k], v[j], edgenormal);
2170 CrossProduct(edgenormal, facenormal, sidenormal);
2171 VectorNormalize(sidenormal);
2172 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2174 VectorMA(temp, offsetdist, sidenormal, temp);
2176 dist = VectorDistance2(temp, p);
2177 if (bestdist > dist)
2180 VectorCopy(temp, out);
2185 static dp_model_t *getmodel(prvm_edict_t *ed)
2188 if (!ed || ed->priv.server->free)
2190 modelindex = (int)ed->fields.server->modelindex;
2191 if (modelindex < 1 || modelindex >= MAX_MODELS)
2193 return sv.models[modelindex];
2196 static msurface_t *getsurface(dp_model_t *model, int surfacenum)
2198 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2200 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2204 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2205 static void VM_SV_getsurfacenumpoints(void)
2208 msurface_t *surface;
2209 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2210 // return 0 if no such surface
2211 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2213 PRVM_G_FLOAT(OFS_RETURN) = 0;
2217 // note: this (incorrectly) assumes it is a simple polygon
2218 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2220 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2221 static void VM_SV_getsurfacepoint(void)
2225 msurface_t *surface;
2227 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2228 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2229 ed = PRVM_G_EDICT(OFS_PARM0);
2230 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2232 // note: this (incorrectly) assumes it is a simple polygon
2233 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2234 if (pointnum < 0 || pointnum >= surface->num_vertices)
2236 // FIXME: implement rotation/scaling
2237 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2239 //PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
2240 // float SPA_POSITION = 0;
2241 // float SPA_S_AXIS = 1;
2242 // float SPA_T_AXIS = 2;
2243 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2244 // float SPA_TEXCOORDS0 = 4;
2245 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2246 // float SPA_LIGHTMAP0_COLOR = 6;
2247 static void VM_SV_getsurfacepointattribute(void)
2251 msurface_t *surface;
2255 VM_SAFEPARMCOUNT(4, VM_SV_getsurfacepoint);
2256 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2257 ed = PRVM_G_EDICT(OFS_PARM0);
2258 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2260 // note: this (incorrectly) assumes it is a simple polygon
2261 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2262 if (pointnum < 0 || pointnum >= surface->num_vertices)
2264 // FIXME: implement rotation/scaling
2265 attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
2267 switch( attributetype ) {
2268 // float SPA_POSITION = 0;
2270 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2272 // float SPA_S_AXIS = 1;
2274 VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2276 // float SPA_T_AXIS = 2;
2278 VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2280 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2282 VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2284 // float SPA_TEXCOORDS0 = 4;
2286 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2287 float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2];
2288 ret[0] = texcoord[0];
2289 ret[1] = texcoord[1];
2293 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2295 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2296 float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2];
2297 ret[0] = texcoord[0];
2298 ret[1] = texcoord[1];
2302 // float SPA_LIGHTMAP0_COLOR = 6;
2304 // ignore alpha for now..
2305 VectorCopy( &(model->surfmesh.data_lightmapcolor4f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
2308 VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
2312 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2313 static void VM_SV_getsurfacenormal(void)
2316 msurface_t *surface;
2318 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2319 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2320 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2322 // FIXME: implement rotation/scaling
2323 // note: this (incorrectly) assumes it is a simple polygon
2324 // note: this only returns the first triangle, so it doesn't work very
2325 // well for curved surfaces or arbitrary meshes
2326 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);
2327 VectorNormalize(normal);
2328 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2330 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2331 static void VM_SV_getsurfacetexture(void)
2334 msurface_t *surface;
2335 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2336 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2337 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2339 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2341 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2342 static void VM_SV_getsurfacenearpoint(void)
2344 int surfacenum, best;
2346 vec_t dist, bestdist;
2349 msurface_t *surface;
2351 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2352 PRVM_G_FLOAT(OFS_RETURN) = -1;
2353 ed = PRVM_G_EDICT(OFS_PARM0);
2354 point = PRVM_G_VECTOR(OFS_PARM1);
2356 if (!ed || ed->priv.server->free)
2358 model = getmodel(ed);
2359 if (!model || !model->num_surfaces)
2362 // FIXME: implement rotation/scaling
2363 VectorSubtract(point, ed->fields.server->origin, p);
2365 bestdist = 1000000000;
2366 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2368 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2369 // first see if the nearest point on the surface's box is closer than the previous match
2370 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2371 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2372 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2373 dist = VectorLength2(clipped);
2374 if (dist < bestdist)
2376 // it is, check the nearest point on the actual geometry
2377 clippointtosurface(model, surface, p, clipped);
2378 VectorSubtract(clipped, p, clipped);
2379 dist += VectorLength2(clipped);
2380 if (dist < bestdist)
2382 // that's closer too, store it as the best match
2388 PRVM_G_FLOAT(OFS_RETURN) = best;
2390 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2391 static void VM_SV_getsurfaceclippedpoint(void)
2395 msurface_t *surface;
2397 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2398 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2399 ed = PRVM_G_EDICT(OFS_PARM0);
2400 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2402 // FIXME: implement rotation/scaling
2403 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2404 clippointtosurface(model, surface, p, out);
2405 // FIXME: implement rotation/scaling
2406 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2409 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2410 //this function originally written by KrimZon, made shorter by LordHavoc
2411 static void VM_SV_clientcommand (void)
2413 client_t *temp_client;
2415 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2417 //find client for this entity
2418 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2419 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2421 Con_Print("PF_clientcommand: entity is not a client\n");
2425 temp_client = host_client;
2426 host_client = svs.clients + i;
2427 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2428 host_client = temp_client;
2431 //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)
2432 static void VM_SV_setattachment (void)
2434 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2435 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2436 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2440 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2442 if (e == prog->edicts)
2444 VM_Warning("setattachment: can not modify world entity\n");
2447 if (e->priv.server->free)
2449 VM_Warning("setattachment: can not modify free entity\n");
2453 if (tagentity == NULL)
2454 tagentity = prog->edicts;
2456 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2458 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2460 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2463 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2465 modelindex = (int)tagentity->fields.server->modelindex;
2466 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2468 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2470 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);
2473 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));
2477 /////////////////////////////////////////
2478 // DP_MD3_TAGINFO extension coded by VorteX
2480 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2485 i = (int)e->fields.server->modelindex;
2486 if (i < 1 || i >= MAX_MODELS)
2488 model = sv.models[i];
2490 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2493 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2495 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2499 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);
2501 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);
2504 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2510 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2511 && (model = sv.models[(int)ent->fields.server->modelindex])
2512 && model->animscenes)
2514 // if model has wrong frame, engine automatically switches to model first frame
2515 frame = (int)ent->fields.server->frame;
2516 if (frame < 0 || frame >= model->numframes)
2518 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2520 *out = identitymatrix;
2524 // Warnings/errors code:
2525 // 0 - normal (everything all-right)
2528 // 3 - null or non-precached model
2529 // 4 - no tags with requested index
2530 // 5 - runaway loop at attachment chain
2531 extern cvar_t cl_bob;
2532 extern cvar_t cl_bobcycle;
2533 extern cvar_t cl_bobup;
2534 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2538 int modelindex, attachloop;
2539 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2542 *out = identitymatrix; // warnings and errors return identical matrix
2544 if (ent == prog->edicts)
2546 if (ent->priv.server->free)
2549 modelindex = (int)ent->fields.server->modelindex;
2550 if (modelindex <= 0 || modelindex > MAX_MODELS)
2553 model = sv.models[modelindex];
2555 tagmatrix = identitymatrix;
2556 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2560 if (attachloop >= 256) // prevent runaway looping
2562 // apply transformation by child's tagindex on parent entity and then
2563 // by parent entity itself
2564 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2565 if (ret && attachloop == 0)
2567 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2568 SV_GetEntityMatrix(ent, &entitymatrix, false);
2569 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2570 // next iteration we process the parent entity
2571 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2573 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2574 ent = PRVM_EDICT_NUM(val->edict);
2581 // RENDER_VIEWMODEL magic
2582 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2584 Matrix4x4_Copy(&tagmatrix, out);
2585 ent = PRVM_EDICT_NUM(val->edict);
2587 SV_GetEntityMatrix(ent, &entitymatrix, true);
2588 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2591 // Cl_bob, ported from rendering code
2592 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2595 // LordHavoc: this code is *weird*, but not replacable (I think it
2596 // should be done in QC on the server, but oh well, quake is quake)
2597 // LordHavoc: figured out bobup: the time at which the sin is at 180
2598 // degrees (which allows lengthening or squishing the peak or valley)
2599 cycle = sv.time/cl_bobcycle.value;
2600 cycle -= (int)cycle;
2601 if (cycle < cl_bobup.value)
2602 cycle = sin(M_PI * cycle / cl_bobup.value);
2604 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2605 // bob is proportional to velocity in the xy plane
2606 // (don't count Z, or jumping messes it up)
2607 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;
2608 bob = bob*0.3 + bob*0.7*cycle;
2609 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2616 //float(entity ent, string tagname) gettagindex;
2618 static void VM_SV_gettagindex (void)
2621 const char *tag_name;
2622 int modelindex, tag_index;
2624 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2626 ent = PRVM_G_EDICT(OFS_PARM0);
2627 tag_name = PRVM_G_STRING(OFS_PARM1);
2629 if (ent == prog->edicts)
2631 VM_Warning("gettagindex: can't affect world entity\n");
2634 if (ent->priv.server->free)
2636 VM_Warning("gettagindex: can't affect free entity\n");
2640 modelindex = (int)ent->fields.server->modelindex;
2642 if (modelindex <= 0 || modelindex > MAX_MODELS)
2643 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2646 tag_index = SV_GetTagIndex(ent, tag_name);
2648 if(developer.integer >= 100)
2649 Con_Printf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2651 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2654 //vector(entity ent, float tagindex) gettaginfo;
2655 static void VM_SV_gettaginfo (void)
2659 matrix4x4_t tag_matrix;
2662 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2664 e = PRVM_G_EDICT(OFS_PARM0);
2665 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2667 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2668 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2673 VM_Warning("gettagindex: can't affect world entity\n");
2676 VM_Warning("gettagindex: can't affect free entity\n");
2679 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2682 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2685 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2690 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2691 static void VM_SV_dropclient (void)
2694 client_t *oldhostclient;
2695 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2696 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2697 if (clientnum < 0 || clientnum >= svs.maxclients)
2699 VM_Warning("dropclient: not a client\n");
2702 if (!svs.clients[clientnum].active)
2704 VM_Warning("dropclient: that client slot is not connected\n");
2707 oldhostclient = host_client;
2708 host_client = svs.clients + clientnum;
2709 SV_DropClient(false);
2710 host_client = oldhostclient;
2713 //entity() spawnclient (DP_SV_BOTCLIENT)
2714 static void VM_SV_spawnclient (void)
2718 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2719 prog->xfunction->builtinsprofile += 2;
2721 for (i = 0;i < svs.maxclients;i++)
2723 if (!svs.clients[i].active)
2725 prog->xfunction->builtinsprofile += 100;
2726 SV_ConnectClient (i, NULL);
2727 // this has to be set or else ClientDisconnect won't be called
2728 // we assume the qc will call ClientConnect...
2729 svs.clients[i].clientconnectcalled = true;
2730 ed = PRVM_EDICT_NUM(i + 1);
2734 VM_RETURN_EDICT(ed);
2737 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2738 static void VM_SV_clienttype (void)
2741 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2742 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2743 if (clientnum < 0 || clientnum >= svs.maxclients)
2744 PRVM_G_FLOAT(OFS_RETURN) = 3;
2745 else if (!svs.clients[clientnum].active)
2746 PRVM_G_FLOAT(OFS_RETURN) = 0;
2747 else if (svs.clients[clientnum].netconnection)
2748 PRVM_G_FLOAT(OFS_RETURN) = 1;
2750 PRVM_G_FLOAT(OFS_RETURN) = 2;
2757 string(string key) serverkey
2760 void VM_SV_serverkey(void)
2762 char string[VM_STRINGTEMP_LENGTH];
2763 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2764 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2765 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2768 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2769 static void VM_SV_setmodelindex (void)
2774 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2776 e = PRVM_G_EDICT(OFS_PARM0);
2777 if (e == prog->edicts)
2779 VM_Warning("setmodelindex: can not modify world entity\n");
2782 if (e->priv.server->free)
2784 VM_Warning("setmodelindex: can not modify free entity\n");
2787 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2788 if (i <= 0 || i > MAX_MODELS)
2790 VM_Warning("setmodelindex: invalid modelindex\n");
2793 if (!sv.model_precache[i][0])
2795 VM_Warning("setmodelindex: model not precached\n");
2799 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2800 e->fields.server->modelindex = i;
2806 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2807 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2809 SetMinMaxSize (e, quakemins, quakemaxs, true);
2812 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2815 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2816 static void VM_SV_modelnameforindex (void)
2819 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2821 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2823 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2824 if (i <= 0 || i > MAX_MODELS)
2826 VM_Warning("modelnameforindex: invalid modelindex\n");
2829 if (!sv.model_precache[i][0])
2831 VM_Warning("modelnameforindex: model not precached\n");
2835 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2838 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2839 static void VM_SV_particleeffectnum (void)
2842 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2843 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2846 PRVM_G_FLOAT(OFS_RETURN) = i;
2849 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2850 static void VM_SV_trailparticles (void)
2852 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2854 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2857 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2858 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2859 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2860 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2861 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2862 SV_FlushBroadcastMessages();
2865 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2866 static void VM_SV_pointparticles (void)
2868 int effectnum, count;
2870 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2872 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2875 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2876 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2877 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2878 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2879 if (count == 1 && !VectorLength2(vel))
2882 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2883 MSG_WriteShort(&sv.datagram, effectnum);
2884 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2888 // 1+2+12+12+2=29 bytes
2889 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2890 MSG_WriteShort(&sv.datagram, effectnum);
2891 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2892 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2893 MSG_WriteShort(&sv.datagram, count);
2896 SV_FlushBroadcastMessages();
2899 prvm_builtin_t vm_sv_builtins[] = {
2900 NULL, // #0 NULL function (not callable) (QUAKE)
2901 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2902 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2903 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2904 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2905 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2906 VM_break, // #6 void() break (QUAKE)
2907 VM_random, // #7 float() random (QUAKE)
2908 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2909 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2910 VM_error, // #10 void(string e) error (QUAKE)
2911 VM_objerror, // #11 void(string e) objerror (QUAKE)
2912 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2913 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2914 VM_spawn, // #14 entity() spawn (QUAKE)
2915 VM_remove, // #15 void(entity e) remove (QUAKE)
2916 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2917 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2918 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2919 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2920 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2921 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2922 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2923 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2924 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2925 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2926 VM_ftos, // #26 string(float f) ftos (QUAKE)
2927 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2928 VM_coredump, // #28 void() coredump (QUAKE)
2929 VM_traceon, // #29 void() traceon (QUAKE)
2930 VM_traceoff, // #30 void() traceoff (QUAKE)
2931 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2932 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2933 NULL, // #33 (QUAKE)
2934 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2935 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2936 VM_rint, // #36 float(float v) rint (QUAKE)
2937 VM_floor, // #37 float(float v) floor (QUAKE)
2938 VM_ceil, // #38 float(float v) ceil (QUAKE)
2939 NULL, // #39 (QUAKE)
2940 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2941 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2942 NULL, // #42 (QUAKE)
2943 VM_fabs, // #43 float(float f) fabs (QUAKE)
2944 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
2945 VM_cvar, // #45 float(string s) cvar (QUAKE)
2946 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
2947 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
2948 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
2949 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
2950 NULL, // #50 (QUAKE)
2951 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
2952 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
2953 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
2954 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
2955 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
2956 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
2957 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
2958 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
2959 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
2960 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
2961 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
2962 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
2963 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
2964 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
2965 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
2966 NULL, // #66 (QUAKE)
2967 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
2968 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
2969 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
2970 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
2971 NULL, // #71 (QUAKE)
2972 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
2973 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
2974 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
2975 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
2976 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
2977 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
2978 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
2979 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
2980 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
2981 VM_stof, // #81 float(string s) stof (FRIK_FILE)
2982 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
2983 NULL, // #83 (QUAKE)
2984 NULL, // #84 (QUAKE)
2985 NULL, // #85 (QUAKE)
2986 NULL, // #86 (QUAKE)
2987 NULL, // #87 (QUAKE)
2988 NULL, // #88 (QUAKE)
2989 NULL, // #89 (QUAKE)
2990 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
2991 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
2992 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
2993 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
2994 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
2995 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
2996 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
2997 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
2998 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
2999 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3000 // FrikaC and Telejano range #100-#199
3011 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3012 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3013 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3014 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3015 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3016 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3017 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3018 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3019 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3020 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3101 // FTEQW range #200-#299
3120 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3123 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3124 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3125 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3126 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3127 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3128 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3129 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3130 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3131 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3132 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3134 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3202 // CSQC range #300-#399
3203 NULL, // #300 void() clearscene (EXT_CSQC)
3204 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3205 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3206 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3207 NULL, // #304 void() renderscene (EXT_CSQC)
3208 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3209 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3210 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3211 NULL, // #308 void() R_EndPolygon
3213 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3214 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3218 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3219 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3220 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3221 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3222 NULL, // #319 void(string name) freepic (EXT_CSQC)
3223 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3224 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3225 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3226 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3227 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3228 NULL, // #325 void(void) drawresetcliparea
3233 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3234 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3235 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3236 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3237 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3238 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3239 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3240 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3241 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3242 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3243 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3244 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3245 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3246 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3247 NULL, // #344 vector() getmousepos (EXT_CSQC)
3248 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3249 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3250 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3251 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3252 NULL, // #349 float() isdemo (EXT_CSQC)
3253 VM_isserver, // #350 float() isserver (EXT_CSQC)
3254 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3255 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3256 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3257 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3263 NULL, // #360 float() readbyte (EXT_CSQC)
3264 NULL, // #361 float() readchar (EXT_CSQC)
3265 NULL, // #362 float() readshort (EXT_CSQC)
3266 NULL, // #363 float() readlong (EXT_CSQC)
3267 NULL, // #364 float() readcoord (EXT_CSQC)
3268 NULL, // #365 float() readangle (EXT_CSQC)
3269 NULL, // #366 string() readstring (EXT_CSQC)
3270 NULL, // #367 float() readfloat (EXT_CSQC)
3303 // LordHavoc's range #400-#499
3304 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3305 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3306 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3307 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3308 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3309 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3310 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3311 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3312 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)
3313 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3314 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3315 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3316 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3317 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3318 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3319 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3320 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3321 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3322 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3323 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3324 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3325 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3326 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3327 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3328 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3329 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3330 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3331 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3332 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3333 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3334 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3335 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3336 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3337 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3338 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3339 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3340 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3341 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3342 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3343 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3344 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3345 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3346 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3347 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3348 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3349 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3350 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3351 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3352 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3353 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3354 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3355 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3356 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3357 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3358 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3359 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3360 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3361 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3363 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3364 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3365 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3366 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3367 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3368 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3369 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3370 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3371 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3372 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3373 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3375 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3376 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3377 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3378 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3379 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3380 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3381 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3382 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3383 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3384 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3385 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3386 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3387 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3388 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3389 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3390 VM_SV_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3398 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3399 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3400 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3401 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3402 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3403 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3404 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3405 VM_SV_WritePicture, // #501
3407 VM_whichpack, // #503 string(string) whichpack = #503;
3414 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3415 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3416 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3417 VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3418 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3419 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3420 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3426 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3428 void VM_SV_Cmd_Init(void)
3433 void VM_SV_Cmd_Reset(void)
3435 if(prog->funcoffsets.SV_Shutdown)
3437 func_t s = prog->funcoffsets.SV_Shutdown;
3438 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3439 PRVM_ExecuteProgram(s,"SV_Shutdown() required");