6 //============================================================================
11 char *vm_sv_extensions =
16 "DP_CON_ALIASPARAMETERS "
37 "DP_ENT_CUSTOMCOLORMAP "
38 "DP_ENT_EXTERIORMODELTOCLIENT "
40 "DP_ENT_LOWPRECISION "
44 "DP_GFX_EXTERNALTEXTURES "
45 "DP_GFX_EXTERNALTEXTURES_PERMAP "
47 "DP_GFX_QUAKE3MODELTAGS "
51 "DP_HALFLIFE_MAP_CVAR "
57 "DP_MOVETYPEBOUNCEMISSILE "
60 "DP_QC_ASINACOSATANATAN2TAN "
65 "DP_QC_CVAR_DEFSTRING "
66 "DP_QC_CVAR_DESCRIPTION "
73 "DP_QC_FINDCHAINFLAGS "
74 "DP_QC_FINDCHAINFLOAT "
80 "DP_QC_GETSURFACEPOINTATTRIBUTE "
82 "DP_QC_GETTAGINFO_BONEPROPERTIES "
84 "DP_QC_MULTIPLETEMPSTRINGS "
85 "DP_QC_NUM_FOR_EDICT "
87 "DP_QC_SINCOSSQRTPOW "
89 "DP_QC_STRINGBUFFERS "
90 "DP_QC_STRINGBUFFERS_CVARLIST "
91 "DP_QC_STRINGCOLORFUNCTIONS "
92 "DP_QC_STRING_CASE_FUNCTIONS "
94 "DP_QC_TOKENIZEBYSEPARATOR "
95 "DP_QC_TOKENIZE_CONSOLE "
98 "DP_QC_TRACE_MOVETYPE_HITMODEL "
99 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
100 "DP_QC_UNLIMITEDTEMPSTRINGS "
103 "DP_QC_VECTOANGLES_WITH_ROLL "
104 "DP_QC_VECTORVECTORS "
111 "DP_SND_DIRECTIONLESSATTNNONE "
118 "DP_SV_CLIENTCOLORS "
121 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
122 "DP_SV_DRAWONLYTOCLIENT "
125 "DP_SV_ENTITYCONTENTSTRANSITION "
126 "DP_SV_MODELFLAGS_AS_EFFECTS "
127 "DP_SV_MOVETYPESTEP_LANDEVENT "
129 "DP_SV_NODRAWTOCLIENT "
130 "DP_SV_ONENTITYNOSPAWNFUNCTION "
131 "DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
133 "DP_SV_PLAYERPHYSICS "
134 "DP_SV_POINTPARTICLES "
136 "DP_SV_PRECACHEANYTIME "
140 "DP_SV_ROTATINGBMODEL "
144 "DP_SV_SPAWNFUNC_PREFIX "
145 "DP_SV_WRITEPICTURE "
146 "DP_SV_WRITEUNTERMINATEDSTRING "
150 "DP_TE_EXPLOSIONRGB "
152 "DP_TE_PARTICLECUBE "
153 "DP_TE_PARTICLERAIN "
154 "DP_TE_PARTICLESNOW "
156 "DP_TE_QUADEFFECTS1 "
159 "DP_TE_STANDARDEFFECTBUILTINS "
160 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
165 "KRIMZON_SV_PARSECLIENTCOMMAND "
168 "NEXUIZ_PLAYERMODEL "
170 "PRYDON_CLIENTCURSOR "
171 "TENEBRAE_GFX_DLIGHTS "
173 //"EXT_CSQC " // not ready yet
180 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.
182 setorigin (entity, origin)
185 static void VM_SV_setorigin (void)
190 VM_SAFEPARMCOUNT(2, VM_setorigin);
192 e = PRVM_G_EDICT(OFS_PARM0);
193 if (e == prog->edicts)
195 VM_Warning("setorigin: can not modify world entity\n");
198 if (e->priv.server->free)
200 VM_Warning("setorigin: can not modify free entity\n");
203 org = PRVM_G_VECTOR(OFS_PARM1);
204 VectorCopy (org, e->fields.server->origin);
205 SV_LinkEdict (e, false);
208 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
209 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
213 for (i=0 ; i<3 ; i++)
215 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
217 // set derived values
218 VectorCopy (min, e->fields.server->mins);
219 VectorCopy (max, e->fields.server->maxs);
220 VectorSubtract (max, min, e->fields.server->size);
222 SV_LinkEdict (e, false);
229 the size box is rotated by the current angle
230 LordHavoc: no it isn't...
232 setsize (entity, minvector, maxvector)
235 static void VM_SV_setsize (void)
240 VM_SAFEPARMCOUNT(3, VM_setsize);
242 e = PRVM_G_EDICT(OFS_PARM0);
243 if (e == prog->edicts)
245 VM_Warning("setsize: can not modify world entity\n");
248 if (e->priv.server->free)
250 VM_Warning("setsize: can not modify free entity\n");
253 min = PRVM_G_VECTOR(OFS_PARM1);
254 max = PRVM_G_VECTOR(OFS_PARM2);
255 SetMinMaxSize (e, min, max, false);
263 setmodel(entity, model)
266 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
267 static void VM_SV_setmodel (void)
273 VM_SAFEPARMCOUNT(2, VM_setmodel);
275 e = PRVM_G_EDICT(OFS_PARM0);
276 if (e == prog->edicts)
278 VM_Warning("setmodel: can not modify world entity\n");
281 if (e->priv.server->free)
283 VM_Warning("setmodel: can not modify free entity\n");
286 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
287 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
288 e->fields.server->modelindex = i;
294 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
295 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
297 SetMinMaxSize (e, quakemins, quakemaxs, true);
300 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
307 single print to a specific client
309 sprint(clientent, value)
312 static void VM_SV_sprint (void)
316 char string[VM_STRINGTEMP_LENGTH];
318 VM_VarString(1, string, sizeof(string));
320 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
322 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
323 // LordHavoc: div0 requested that sprintto world operate like print
330 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
332 VM_Warning("tried to centerprint to a non-client\n");
336 client = svs.clients + entnum-1;
337 if (!client->netconnection)
340 MSG_WriteChar(&client->netconnection->message,svc_print);
341 MSG_WriteString(&client->netconnection->message, string);
349 single print to a specific client
351 centerprint(clientent, value)
354 static void VM_SV_centerprint (void)
358 char string[VM_STRINGTEMP_LENGTH];
360 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
362 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
364 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
366 VM_Warning("tried to centerprint to a non-client\n");
370 client = svs.clients + entnum-1;
371 if (!client->netconnection)
374 VM_VarString(1, string, sizeof(string));
375 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
376 MSG_WriteString(&client->netconnection->message, string);
383 particle(origin, color, count)
386 static void VM_SV_particle (void)
392 VM_SAFEPARMCOUNT(4, VM_SV_particle);
394 org = PRVM_G_VECTOR(OFS_PARM0);
395 dir = PRVM_G_VECTOR(OFS_PARM1);
396 color = PRVM_G_FLOAT(OFS_PARM2);
397 count = PRVM_G_FLOAT(OFS_PARM3);
398 SV_StartParticle (org, dir, (int)color, (int)count);
408 static void VM_SV_ambientsound (void)
412 float vol, attenuation;
415 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
417 pos = PRVM_G_VECTOR (OFS_PARM0);
418 samp = PRVM_G_STRING(OFS_PARM1);
419 vol = PRVM_G_FLOAT(OFS_PARM2);
420 attenuation = PRVM_G_FLOAT(OFS_PARM3);
422 // check to see if samp was properly precached
423 soundnum = SV_SoundIndex(samp, 1);
431 // add an svc_spawnambient command to the level signon packet
434 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
436 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
438 MSG_WriteVector(&sv.signon, pos, sv.protocol);
440 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
441 MSG_WriteShort (&sv.signon, soundnum);
443 MSG_WriteByte (&sv.signon, soundnum);
445 MSG_WriteByte (&sv.signon, (int)(vol*255));
446 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
454 Each entity can have eight independant sound sources, like voice,
457 Channel 0 is an auto-allocate channel, the others override anything
458 already running on that entity/channel pair.
460 An attenuation of 0 will play full volume everywhere in the level.
461 Larger attenuations will drop off.
465 static void VM_SV_sound (void)
469 prvm_edict_t *entity;
473 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
475 entity = PRVM_G_EDICT(OFS_PARM0);
476 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
477 sample = PRVM_G_STRING(OFS_PARM2);
478 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
479 attenuation = PRVM_G_FLOAT(OFS_PARM4);
482 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
486 if (volume < 0 || volume > 255)
488 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
492 if (attenuation < 0 || attenuation > 4)
494 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
498 if (channel < 0 || channel > 7)
500 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
504 SV_StartSound (entity, channel, sample, volume, attenuation);
511 Follows the same logic as VM_SV_sound, except instead of
512 an entity, an origin for the sound is provided, and channel
513 is omitted (since no entity is being tracked).
517 static void VM_SV_pointsound(void)
524 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
526 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
527 sample = PRVM_G_STRING(OFS_PARM1);
528 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
529 attenuation = PRVM_G_FLOAT(OFS_PARM3);
531 if (volume < 0 || volume > 255)
533 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
537 if (attenuation < 0 || attenuation > 4)
539 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
543 SV_StartPointSound (org, sample, volume, attenuation);
550 Used for use tracing and shot targeting
551 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
552 if the tryents flag is set.
554 traceline (vector1, vector2, movetype, ignore)
557 static void VM_SV_traceline (void)
564 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
566 prog->xfunction->builtinsprofile += 30;
568 v1 = PRVM_G_VECTOR(OFS_PARM0);
569 v2 = PRVM_G_VECTOR(OFS_PARM1);
570 move = (int)PRVM_G_FLOAT(OFS_PARM2);
571 ent = PRVM_G_EDICT(OFS_PARM3);
573 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]))
574 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));
576 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
578 VM_SetTraceGlobals(&trace);
586 Used for use tracing and shot targeting
587 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
588 if the tryents flag is set.
590 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
593 // LordHavoc: added this for my own use, VERY useful, similar to traceline
594 static void VM_SV_tracebox (void)
596 float *v1, *v2, *m1, *m2;
601 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
603 prog->xfunction->builtinsprofile += 30;
605 v1 = PRVM_G_VECTOR(OFS_PARM0);
606 m1 = PRVM_G_VECTOR(OFS_PARM1);
607 m2 = PRVM_G_VECTOR(OFS_PARM2);
608 v2 = PRVM_G_VECTOR(OFS_PARM3);
609 move = (int)PRVM_G_FLOAT(OFS_PARM4);
610 ent = PRVM_G_EDICT(OFS_PARM5);
612 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]))
613 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));
615 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
617 VM_SetTraceGlobals(&trace);
620 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
625 vec3_t original_origin;
626 vec3_t original_velocity;
627 vec3_t original_angles;
628 vec3_t original_avelocity;
632 VectorCopy(tossent->fields.server->origin , original_origin );
633 VectorCopy(tossent->fields.server->velocity , original_velocity );
634 VectorCopy(tossent->fields.server->angles , original_angles );
635 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
637 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
638 if (val != NULL && val->_float != 0)
639 gravity = val->_float;
642 gravity *= sv_gravity.value * 0.025;
644 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
646 SV_CheckVelocity (tossent);
647 tossent->fields.server->velocity[2] -= gravity;
648 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
649 VectorScale (tossent->fields.server->velocity, 0.05, move);
650 VectorAdd (tossent->fields.server->origin, move, end);
651 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
652 VectorCopy (trace.endpos, tossent->fields.server->origin);
653 tossent->fields.server->velocity[2] -= gravity;
655 if (trace.fraction < 1)
659 VectorCopy(original_origin , tossent->fields.server->origin );
660 VectorCopy(original_velocity , tossent->fields.server->velocity );
661 VectorCopy(original_angles , tossent->fields.server->angles );
662 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
667 static void VM_SV_tracetoss (void)
671 prvm_edict_t *ignore;
673 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
675 prog->xfunction->builtinsprofile += 600;
677 ent = PRVM_G_EDICT(OFS_PARM0);
678 if (ent == prog->edicts)
680 VM_Warning("tracetoss: can not use world entity\n");
683 ignore = PRVM_G_EDICT(OFS_PARM1);
685 trace = SV_Trace_Toss (ent, ignore);
687 VM_SetTraceGlobals(&trace);
690 //============================================================================
692 static int checkpvsbytes;
693 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
695 static int VM_SV_newcheckclient (int check)
701 // cycle to the next one
703 check = bound(1, check, svs.maxclients);
704 if (check == svs.maxclients)
712 prog->xfunction->builtinsprofile++;
714 if (i == svs.maxclients+1)
716 // look up the client's edict
717 ent = PRVM_EDICT_NUM(i);
718 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
719 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
721 // found a valid client (possibly the same one again)
725 // get the PVS for the entity
726 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
728 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
729 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
738 Returns a client (or object that has a client enemy) that would be a
741 If there is more than one valid option, they are cycled each frame
743 If (self.origin + self.viewofs) is not in the PVS of the current target,
744 it is not returned at all.
749 int c_invis, c_notvis;
750 static void VM_SV_checkclient (void)
752 prvm_edict_t *ent, *self;
755 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
757 // find a new check if on a new frame
758 if (sv.time - sv.lastchecktime >= 0.1)
760 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
761 sv.lastchecktime = sv.time;
764 // return check if it might be visible
765 ent = PRVM_EDICT_NUM(sv.lastcheck);
766 if (ent->priv.server->free || ent->fields.server->health <= 0)
768 VM_RETURN_EDICT(prog->edicts);
772 // if current entity can't possibly see the check entity, return 0
773 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
774 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
775 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
778 VM_RETURN_EDICT(prog->edicts);
782 // might be able to see it
784 VM_RETURN_EDICT(ent);
787 //============================================================================
794 Sends text over to the client's execution buffer
796 stuffcmd (clientent, value, ...)
799 static void VM_SV_stuffcmd (void)
803 char string[VM_STRINGTEMP_LENGTH];
805 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
807 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
808 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
810 VM_Warning("Can't stuffcmd to a non-client\n");
814 VM_VarString(1, string, sizeof(string));
817 host_client = svs.clients + entnum-1;
818 Host_ClientCommands ("%s", string);
826 Returns a chain of entities that have origins within a spherical area
828 findradius (origin, radius)
831 static void VM_SV_findradius (void)
833 prvm_edict_t *ent, *chain;
834 vec_t radius, radius2;
835 vec3_t org, eorg, mins, maxs;
838 prvm_edict_t *touchedicts[MAX_EDICTS];
840 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
842 chain = (prvm_edict_t *)prog->edicts;
844 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
845 radius = PRVM_G_FLOAT(OFS_PARM1);
846 radius2 = radius * radius;
848 mins[0] = org[0] - (radius + 1);
849 mins[1] = org[1] - (radius + 1);
850 mins[2] = org[2] - (radius + 1);
851 maxs[0] = org[0] + (radius + 1);
852 maxs[1] = org[1] + (radius + 1);
853 maxs[2] = org[2] + (radius + 1);
854 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
855 if (numtouchedicts > MAX_EDICTS)
857 // this never happens
858 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
859 numtouchedicts = MAX_EDICTS;
861 for (i = 0;i < numtouchedicts;i++)
863 ent = touchedicts[i];
864 prog->xfunction->builtinsprofile++;
865 // Quake did not return non-solid entities but darkplaces does
866 // (note: this is the reason you can't blow up fallen zombies)
867 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
869 // LordHavoc: compare against bounding box rather than center so it
870 // doesn't miss large objects, and use DotProduct instead of Length
871 // for a major speedup
872 VectorSubtract(org, ent->fields.server->origin, eorg);
873 if (sv_gameplayfix_findradiusdistancetobox.integer)
875 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
876 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
877 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
880 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
881 if (DotProduct(eorg, eorg) < radius2)
883 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
888 VM_RETURN_EDICT(chain);
891 static void VM_SV_precache_sound (void)
893 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
894 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
897 static void VM_SV_precache_model (void)
899 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
900 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
901 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
908 float(float yaw, float dist[, settrace]) walkmove
911 static void VM_SV_walkmove (void)
920 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
922 // assume failure if it returns early
923 PRVM_G_FLOAT(OFS_RETURN) = 0;
925 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
926 if (ent == prog->edicts)
928 VM_Warning("walkmove: can not modify world entity\n");
931 if (ent->priv.server->free)
933 VM_Warning("walkmove: can not modify free entity\n");
936 yaw = PRVM_G_FLOAT(OFS_PARM0);
937 dist = PRVM_G_FLOAT(OFS_PARM1);
938 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
940 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
943 yaw = yaw*M_PI*2 / 360;
945 move[0] = cos(yaw)*dist;
946 move[1] = sin(yaw)*dist;
949 // save program state, because SV_movestep may call other progs
950 oldf = prog->xfunction;
951 oldself = prog->globals.server->self;
953 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
956 // restore program state
957 prog->xfunction = oldf;
958 prog->globals.server->self = oldself;
968 static void VM_SV_droptofloor (void)
974 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
976 // assume failure if it returns early
977 PRVM_G_FLOAT(OFS_RETURN) = 0;
979 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
980 if (ent == prog->edicts)
982 VM_Warning("droptofloor: can not modify world entity\n");
985 if (ent->priv.server->free)
987 VM_Warning("droptofloor: can not modify free entity\n");
991 VectorCopy (ent->fields.server->origin, end);
994 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
995 SV_UnstickEntity(ent);
997 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
998 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
1001 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]);
1002 VectorAdd(ent->fields.server->origin, offset, org);
1003 trace = SV_Move (org, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1004 VectorSubtract(trace.endpos, offset, trace.endpos);
1005 if (trace.startsolid)
1007 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]);
1008 SV_UnstickEntity(ent);
1009 SV_LinkEdict (ent, false);
1010 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1011 ent->fields.server->groundentity = 0;
1012 PRVM_G_FLOAT(OFS_RETURN) = 1;
1014 else if (trace.fraction < 1)
1016 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]);
1017 VectorCopy (trace.endpos, ent->fields.server->origin);
1018 SV_UnstickEntity(ent);
1019 SV_LinkEdict (ent, false);
1020 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1021 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1022 PRVM_G_FLOAT(OFS_RETURN) = 1;
1023 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1024 ent->priv.server->suspendedinairflag = true;
1029 if (trace.fraction != 1)
1031 if (trace.fraction < 1)
1032 VectorCopy (trace.endpos, ent->fields.server->origin);
1033 SV_LinkEdict (ent, false);
1034 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1035 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1036 PRVM_G_FLOAT(OFS_RETURN) = 1;
1037 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1038 ent->priv.server->suspendedinairflag = true;
1047 void(float style, string value) lightstyle
1050 static void VM_SV_lightstyle (void)
1057 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1059 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1060 val = PRVM_G_STRING(OFS_PARM1);
1062 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1063 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1066 // change the string in sv
1067 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1069 // send message to all clients on this server
1070 if (sv.state != ss_active)
1073 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1075 if (client->active && client->netconnection)
1077 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1078 MSG_WriteChar (&client->netconnection->message,style);
1079 MSG_WriteString (&client->netconnection->message, val);
1089 static void VM_SV_checkbottom (void)
1091 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1092 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1100 static void VM_SV_pointcontents (void)
1102 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1103 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1110 Pick a vector for the player to shoot along
1111 vector aim(entity, missilespeed)
1114 static void VM_SV_aim (void)
1116 prvm_edict_t *ent, *check, *bestent;
1117 vec3_t start, dir, end, bestdir;
1120 float dist, bestdist;
1123 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1125 // assume failure if it returns early
1126 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1127 // if sv_aim is so high it can't possibly accept anything, skip out early
1128 if (sv_aim.value >= 1)
1131 ent = PRVM_G_EDICT(OFS_PARM0);
1132 if (ent == prog->edicts)
1134 VM_Warning("aim: can not use world entity\n");
1137 if (ent->priv.server->free)
1139 VM_Warning("aim: can not use free entity\n");
1142 speed = PRVM_G_FLOAT(OFS_PARM1);
1144 VectorCopy (ent->fields.server->origin, start);
1147 // try sending a trace straight
1148 VectorCopy (prog->globals.server->v_forward, dir);
1149 VectorMA (start, 2048, dir, end);
1150 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1151 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1152 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1154 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1159 // try all possible entities
1160 VectorCopy (dir, bestdir);
1161 bestdist = sv_aim.value;
1164 check = PRVM_NEXT_EDICT(prog->edicts);
1165 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1167 prog->xfunction->builtinsprofile++;
1168 if (check->fields.server->takedamage != DAMAGE_AIM)
1172 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1173 continue; // don't aim at teammate
1174 for (j=0 ; j<3 ; j++)
1175 end[j] = check->fields.server->origin[j]
1176 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1177 VectorSubtract (end, start, dir);
1178 VectorNormalize (dir);
1179 dist = DotProduct (dir, prog->globals.server->v_forward);
1180 if (dist < bestdist)
1181 continue; // to far to turn
1182 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1183 if (tr.ent == check)
1184 { // can shoot at this one
1192 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1193 dist = DotProduct (dir, prog->globals.server->v_forward);
1194 VectorScale (prog->globals.server->v_forward, dist, end);
1196 VectorNormalize (end);
1197 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1201 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1206 ===============================================================================
1210 ===============================================================================
1213 #define MSG_BROADCAST 0 // unreliable to all
1214 #define MSG_ONE 1 // reliable to one (msg_entity)
1215 #define MSG_ALL 2 // reliable to all
1216 #define MSG_INIT 3 // write to the init string
1217 #define MSG_ENTITY 5
1219 sizebuf_t *WriteDest (void)
1225 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1229 return &sv.datagram;
1232 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1233 entnum = PRVM_NUM_FOR_EDICT(ent);
1234 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1236 VM_Warning ("WriteDest: tried to write to non-client\n");
1237 return &sv.reliable_datagram;
1240 return &svs.clients[entnum-1].netconnection->message;
1243 VM_Warning ("WriteDest: bad destination\n");
1245 return &sv.reliable_datagram;
1251 return sv.writeentitiestoclient_msg;
1257 static void VM_SV_WriteByte (void)
1259 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1260 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1263 static void VM_SV_WriteChar (void)
1265 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1266 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1269 static void VM_SV_WriteShort (void)
1271 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1272 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1275 static void VM_SV_WriteLong (void)
1277 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1278 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1281 static void VM_SV_WriteAngle (void)
1283 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1284 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1287 static void VM_SV_WriteCoord (void)
1289 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1290 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1293 static void VM_SV_WriteString (void)
1295 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1296 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1299 static void VM_SV_WriteUnterminatedString (void)
1301 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1302 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1306 static void VM_SV_WriteEntity (void)
1308 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1309 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1312 // writes a picture as at most size bytes of data
1314 // IMGNAME \0 SIZE(short) IMGDATA
1315 // if failed to read/compress:
1317 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1318 static void VM_SV_WritePicture (void)
1320 const char *imgname;
1324 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1326 imgname = PRVM_G_STRING(OFS_PARM1);
1327 size = (int) PRVM_G_FLOAT(OFS_PARM2);
1331 MSG_WriteString(WriteDest(), imgname);
1332 if(Image_Compress(imgname, size, &buf, &size))
1335 MSG_WriteShort(WriteDest(), size);
1336 SZ_Write(WriteDest(), (unsigned char *) buf, size);
1341 MSG_WriteShort(WriteDest(), 0);
1345 //////////////////////////////////////////////////////////
1347 static void VM_SV_makestatic (void)
1352 // allow 0 parameters due to an id1 qc bug in which this function is used
1353 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1354 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1356 if (prog->argc >= 1)
1357 ent = PRVM_G_EDICT(OFS_PARM0);
1359 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1360 if (ent == prog->edicts)
1362 VM_Warning("makestatic: can not modify world entity\n");
1365 if (ent->priv.server->free)
1367 VM_Warning("makestatic: can not modify free entity\n");
1372 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1377 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1378 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1379 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1381 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1383 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1384 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1385 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1389 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1390 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1391 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1394 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1395 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1396 for (i=0 ; i<3 ; i++)
1398 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1399 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1402 // throw the entity away now
1406 //=============================================================================
1413 static void VM_SV_setspawnparms (void)
1419 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1421 ent = PRVM_G_EDICT(OFS_PARM0);
1422 i = PRVM_NUM_FOR_EDICT(ent);
1423 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1425 Con_Print("tried to setspawnparms on a non-client\n");
1429 // copy spawn parms out of the client_t
1430 client = svs.clients + i-1;
1431 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1432 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1439 Returns a color vector indicating the lighting at the requested point.
1441 (Internal Operation note: actually measures the light beneath the point, just like
1442 the model lighting on the client)
1447 static void VM_SV_getlight (void)
1449 vec3_t ambientcolor, diffusecolor, diffusenormal;
1451 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1452 p = PRVM_G_VECTOR(OFS_PARM0);
1453 VectorClear(ambientcolor);
1454 VectorClear(diffusecolor);
1455 VectorClear(diffusenormal);
1456 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1457 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1458 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1463 unsigned char type; // 1/2/8 or other value if isn't used
1467 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1468 static int vm_customstats_last;
1470 void VM_CustomStats_Clear (void)
1474 Z_Free(vm_customstats);
1475 vm_customstats = NULL;
1476 vm_customstats_last = -1;
1480 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1488 for(i=0; i<vm_customstats_last+1 ;i++)
1490 if(!vm_customstats[i].type)
1492 switch(vm_customstats[i].type)
1494 //string as 16 bytes
1497 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1498 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1499 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1500 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1501 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1503 //float field sent as-is
1505 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1507 //integer value of float field
1509 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1517 // void(float index, float type, .void field) SV_AddStat = #232;
1518 // Set up an auto-sent player stat.
1519 // Client's get thier own fields sent to them. Index may not be less than 32.
1520 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1521 // 1: string (4 stats carrying a total of 16 charactures)
1522 // 2: float (one stat, float converted to an integer for transportation)
1523 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1524 static void VM_SV_AddStat (void)
1529 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1533 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1536 VM_Warning("PF_SV_AddStat: not enough memory\n");
1540 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1541 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1542 off = PRVM_G_INT (OFS_PARM2);
1547 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1550 if(i >= (MAX_CL_STATS-32))
1552 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1555 if(i > (MAX_CL_STATS-32-4) && type == 1)
1557 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1560 vm_customstats[i].type = type;
1561 vm_customstats[i].fieldoffset = off;
1562 if(vm_customstats_last < i)
1563 vm_customstats_last = i;
1570 copies data from one entity to another
1572 copyentity(src, dst)
1575 static void VM_SV_copyentity (void)
1577 prvm_edict_t *in, *out;
1578 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1579 in = PRVM_G_EDICT(OFS_PARM0);
1580 if (in == prog->edicts)
1582 VM_Warning("copyentity: can not read world entity\n");
1585 if (in->priv.server->free)
1587 VM_Warning("copyentity: can not read free entity\n");
1590 out = PRVM_G_EDICT(OFS_PARM1);
1591 if (out == prog->edicts)
1593 VM_Warning("copyentity: can not modify world entity\n");
1596 if (out->priv.server->free)
1598 VM_Warning("copyentity: can not modify free entity\n");
1601 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1602 SV_LinkEdict(out, false);
1610 sets the color of a client and broadcasts the update to all connected clients
1612 setcolor(clientent, value)
1615 static void VM_SV_setcolor (void)
1621 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1622 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1623 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1625 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1627 Con_Print("tried to setcolor a non-client\n");
1631 client = svs.clients + entnum-1;
1634 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1636 client->edict->fields.server->team = (i & 15) + 1;
1639 if (client->old_colors != client->colors)
1641 client->old_colors = client->colors;
1642 // send notification to all clients
1643 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1644 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1645 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1653 effect(origin, modelname, startframe, framecount, framerate)
1656 static void VM_SV_effect (void)
1660 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1661 s = PRVM_G_STRING(OFS_PARM1);
1664 VM_Warning("effect: no model specified\n");
1668 i = SV_ModelIndex(s, 1);
1671 VM_Warning("effect: model not precached\n");
1675 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1677 VM_Warning("effect: framecount < 1\n");
1681 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1683 VM_Warning("effect: framerate < 1\n");
1687 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));
1690 static void VM_SV_te_blood (void)
1692 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1693 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1695 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1696 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1698 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1699 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1700 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1702 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1703 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1704 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1706 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1707 SV_FlushBroadcastMessages();
1710 static void VM_SV_te_bloodshower (void)
1712 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1713 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1715 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1716 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1718 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1719 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1720 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1722 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1723 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1724 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1726 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1728 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1729 SV_FlushBroadcastMessages();
1732 static void VM_SV_te_explosionrgb (void)
1734 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1735 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1736 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1738 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1739 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1740 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1742 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1743 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1744 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1745 SV_FlushBroadcastMessages();
1748 static void VM_SV_te_particlecube (void)
1750 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1751 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1753 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1754 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1756 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1757 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1758 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1760 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1761 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1762 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1764 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1765 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1766 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1768 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1770 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1771 // gravity true/false
1772 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1774 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1775 SV_FlushBroadcastMessages();
1778 static void VM_SV_te_particlerain (void)
1780 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1781 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1783 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1784 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1786 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1787 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1788 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1790 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1791 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1792 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1794 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1795 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1796 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1798 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1800 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1801 SV_FlushBroadcastMessages();
1804 static void VM_SV_te_particlesnow (void)
1806 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1807 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1809 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1810 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1812 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1814 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1816 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1817 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1818 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1820 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1821 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1822 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1824 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1826 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1827 SV_FlushBroadcastMessages();
1830 static void VM_SV_te_spark (void)
1832 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1833 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1835 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1836 MSG_WriteByte(&sv.datagram, TE_SPARK);
1838 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1839 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1840 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1842 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1843 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1844 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1846 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1847 SV_FlushBroadcastMessages();
1850 static void VM_SV_te_gunshotquad (void)
1852 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1853 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1854 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1856 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1857 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1858 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1859 SV_FlushBroadcastMessages();
1862 static void VM_SV_te_spikequad (void)
1864 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1865 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1866 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1870 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1871 SV_FlushBroadcastMessages();
1874 static void VM_SV_te_superspikequad (void)
1876 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1877 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1878 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1880 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1881 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1882 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1883 SV_FlushBroadcastMessages();
1886 static void VM_SV_te_explosionquad (void)
1888 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1889 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1890 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1892 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1893 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1894 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1895 SV_FlushBroadcastMessages();
1898 static void VM_SV_te_smallflash (void)
1900 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1901 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1902 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1904 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1905 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1906 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1907 SV_FlushBroadcastMessages();
1910 static void VM_SV_te_customflash (void)
1912 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1913 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1915 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1916 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1918 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1919 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1920 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1922 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1924 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1926 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1927 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1928 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1929 SV_FlushBroadcastMessages();
1932 static void VM_SV_te_gunshot (void)
1934 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1935 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1936 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1938 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1939 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1940 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1941 SV_FlushBroadcastMessages();
1944 static void VM_SV_te_spike (void)
1946 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1947 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1948 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1950 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1951 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1952 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1953 SV_FlushBroadcastMessages();
1956 static void VM_SV_te_superspike (void)
1958 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1959 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1960 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1962 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1963 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1964 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1965 SV_FlushBroadcastMessages();
1968 static void VM_SV_te_explosion (void)
1970 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1971 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1972 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1974 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1976 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1977 SV_FlushBroadcastMessages();
1980 static void VM_SV_te_tarexplosion (void)
1982 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1983 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1984 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1986 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1987 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1988 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1989 SV_FlushBroadcastMessages();
1992 static void VM_SV_te_wizspike (void)
1994 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1995 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1996 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1998 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1999 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2000 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2001 SV_FlushBroadcastMessages();
2004 static void VM_SV_te_knightspike (void)
2006 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2007 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2008 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2010 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2011 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2012 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2013 SV_FlushBroadcastMessages();
2016 static void VM_SV_te_lavasplash (void)
2018 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2019 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2020 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2022 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2023 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2024 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2025 SV_FlushBroadcastMessages();
2028 static void VM_SV_te_teleport (void)
2030 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2031 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2032 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2034 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2035 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2036 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2037 SV_FlushBroadcastMessages();
2040 static void VM_SV_te_explosion2 (void)
2042 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2043 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2044 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2046 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2047 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2048 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2050 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2051 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2052 SV_FlushBroadcastMessages();
2055 static void VM_SV_te_lightning1 (void)
2057 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2058 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2059 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2061 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2063 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2064 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2065 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2067 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2068 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2069 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2070 SV_FlushBroadcastMessages();
2073 static void VM_SV_te_lightning2 (void)
2075 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2076 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2077 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2079 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2081 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2082 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2083 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2085 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2086 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2087 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2088 SV_FlushBroadcastMessages();
2091 static void VM_SV_te_lightning3 (void)
2093 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2094 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2095 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2097 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2099 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2100 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2101 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2103 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2104 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2105 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2106 SV_FlushBroadcastMessages();
2109 static void VM_SV_te_beam (void)
2111 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2112 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2113 MSG_WriteByte(&sv.datagram, TE_BEAM);
2115 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2117 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2118 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2119 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2121 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2122 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2123 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2124 SV_FlushBroadcastMessages();
2127 static void VM_SV_te_plasmaburn (void)
2129 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2130 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2131 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2132 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2133 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2134 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2135 SV_FlushBroadcastMessages();
2138 static void VM_SV_te_flamejet (void)
2140 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2141 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2142 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2144 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2145 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2146 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2148 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2149 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2150 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2152 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2153 SV_FlushBroadcastMessages();
2156 void clippointtosurface(dp_model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2159 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2161 bestdist = 1000000000;
2163 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2165 // clip original point to each triangle of the surface and find the
2166 // triangle that is closest
2167 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2168 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2169 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2170 TriangleNormal(v[0], v[1], v[2], facenormal);
2171 VectorNormalize(facenormal);
2172 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2173 VectorMA(p, offsetdist, facenormal, temp);
2174 for (j = 0, k = 2;j < 3;k = j, j++)
2176 VectorSubtract(v[k], v[j], edgenormal);
2177 CrossProduct(edgenormal, facenormal, sidenormal);
2178 VectorNormalize(sidenormal);
2179 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2181 VectorMA(temp, offsetdist, sidenormal, temp);
2183 dist = VectorDistance2(temp, p);
2184 if (bestdist > dist)
2187 VectorCopy(temp, out);
2192 static dp_model_t *getmodel(prvm_edict_t *ed)
2195 if (!ed || ed->priv.server->free)
2197 modelindex = (int)ed->fields.server->modelindex;
2198 if (modelindex < 1 || modelindex >= MAX_MODELS)
2200 return sv.models[modelindex];
2203 static msurface_t *getsurface(dp_model_t *model, int surfacenum)
2205 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2207 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2211 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2212 static void VM_SV_getsurfacenumpoints(void)
2215 msurface_t *surface;
2216 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2217 // return 0 if no such surface
2218 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2220 PRVM_G_FLOAT(OFS_RETURN) = 0;
2224 // note: this (incorrectly) assumes it is a simple polygon
2225 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2227 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2228 static void VM_SV_getsurfacepoint(void)
2232 msurface_t *surface;
2234 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2235 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2236 ed = PRVM_G_EDICT(OFS_PARM0);
2237 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2239 // note: this (incorrectly) assumes it is a simple polygon
2240 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2241 if (pointnum < 0 || pointnum >= surface->num_vertices)
2243 // FIXME: implement rotation/scaling
2244 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2246 //PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
2247 // float SPA_POSITION = 0;
2248 // float SPA_S_AXIS = 1;
2249 // float SPA_T_AXIS = 2;
2250 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2251 // float SPA_TEXCOORDS0 = 4;
2252 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2253 // float SPA_LIGHTMAP0_COLOR = 6;
2254 static void VM_SV_getsurfacepointattribute(void)
2258 msurface_t *surface;
2262 VM_SAFEPARMCOUNT(4, VM_SV_getsurfacepoint);
2263 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2264 ed = PRVM_G_EDICT(OFS_PARM0);
2265 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2267 // note: this (incorrectly) assumes it is a simple polygon
2268 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2269 if (pointnum < 0 || pointnum >= surface->num_vertices)
2271 // FIXME: implement rotation/scaling
2272 attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
2274 switch( attributetype ) {
2275 // float SPA_POSITION = 0;
2277 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2279 // float SPA_S_AXIS = 1;
2281 VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2283 // float SPA_T_AXIS = 2;
2285 VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2287 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2289 VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2291 // float SPA_TEXCOORDS0 = 4;
2293 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2294 float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2];
2295 ret[0] = texcoord[0];
2296 ret[1] = texcoord[1];
2300 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2302 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2303 float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2];
2304 ret[0] = texcoord[0];
2305 ret[1] = texcoord[1];
2309 // float SPA_LIGHTMAP0_COLOR = 6;
2311 // ignore alpha for now..
2312 VectorCopy( &(model->surfmesh.data_lightmapcolor4f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
2315 VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
2319 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2320 static void VM_SV_getsurfacenormal(void)
2323 msurface_t *surface;
2325 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2326 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2327 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2329 // FIXME: implement rotation/scaling
2330 // note: this (incorrectly) assumes it is a simple polygon
2331 // note: this only returns the first triangle, so it doesn't work very
2332 // well for curved surfaces or arbitrary meshes
2333 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);
2334 VectorNormalize(normal);
2335 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2337 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2338 static void VM_SV_getsurfacetexture(void)
2341 msurface_t *surface;
2342 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2343 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2344 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2346 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2348 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2349 static void VM_SV_getsurfacenearpoint(void)
2351 int surfacenum, best;
2353 vec_t dist, bestdist;
2356 msurface_t *surface;
2358 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2359 PRVM_G_FLOAT(OFS_RETURN) = -1;
2360 ed = PRVM_G_EDICT(OFS_PARM0);
2361 point = PRVM_G_VECTOR(OFS_PARM1);
2363 if (!ed || ed->priv.server->free)
2365 model = getmodel(ed);
2366 if (!model || !model->num_surfaces)
2369 // FIXME: implement rotation/scaling
2370 VectorSubtract(point, ed->fields.server->origin, p);
2372 bestdist = 1000000000;
2373 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2375 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2376 // first see if the nearest point on the surface's box is closer than the previous match
2377 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2378 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2379 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2380 dist = VectorLength2(clipped);
2381 if (dist < bestdist)
2383 // it is, check the nearest point on the actual geometry
2384 clippointtosurface(model, surface, p, clipped);
2385 VectorSubtract(clipped, p, clipped);
2386 dist += VectorLength2(clipped);
2387 if (dist < bestdist)
2389 // that's closer too, store it as the best match
2395 PRVM_G_FLOAT(OFS_RETURN) = best;
2397 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2398 static void VM_SV_getsurfaceclippedpoint(void)
2402 msurface_t *surface;
2404 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2405 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2406 ed = PRVM_G_EDICT(OFS_PARM0);
2407 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2409 // FIXME: implement rotation/scaling
2410 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2411 clippointtosurface(model, surface, p, out);
2412 // FIXME: implement rotation/scaling
2413 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2416 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2417 //this function originally written by KrimZon, made shorter by LordHavoc
2418 static void VM_SV_clientcommand (void)
2420 client_t *temp_client;
2422 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2424 //find client for this entity
2425 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2426 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2428 Con_Print("PF_clientcommand: entity is not a client\n");
2432 temp_client = host_client;
2433 host_client = svs.clients + i;
2434 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2435 host_client = temp_client;
2438 //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)
2439 static void VM_SV_setattachment (void)
2441 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2442 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2443 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2447 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2449 if (e == prog->edicts)
2451 VM_Warning("setattachment: can not modify world entity\n");
2454 if (e->priv.server->free)
2456 VM_Warning("setattachment: can not modify free entity\n");
2460 if (tagentity == NULL)
2461 tagentity = prog->edicts;
2463 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2465 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2467 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2470 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2472 modelindex = (int)tagentity->fields.server->modelindex;
2473 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2475 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2477 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);
2480 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));
2484 /////////////////////////////////////////
2485 // DP_MD3_TAGINFO extension coded by VorteX
2487 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2492 i = (int)e->fields.server->modelindex;
2493 if (i < 1 || i >= MAX_MODELS)
2495 model = sv.models[i];
2497 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2500 int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
2509 Matrix4x4_CreateIdentity(tag_localmatrix);
2512 && (modelindex = (int)e->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2513 && (model = sv.models[(int)e->fields.server->modelindex])
2514 && model->animscenes)
2516 frame = (int)e->fields.server->frame;
2517 if (frame < 0 || frame >= model->numframes)
2520 r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, model->animscenes[frame].firstframe, tagindex - 1, parentindex, tagname, tag_localmatrix);
2531 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2533 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2537 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);
2539 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);
2542 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2548 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2549 && (model = sv.models[(int)ent->fields.server->modelindex])
2550 && model->animscenes)
2552 // if model has wrong frame, engine automatically switches to model first frame
2553 frame = (int)ent->fields.server->frame;
2554 if (frame < 0 || frame >= model->numframes)
2556 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2558 *out = identitymatrix;
2562 // Warnings/errors code:
2563 // 0 - normal (everything all-right)
2566 // 3 - null or non-precached model
2567 // 4 - no tags with requested index
2568 // 5 - runaway loop at attachment chain
2569 extern cvar_t cl_bob;
2570 extern cvar_t cl_bobcycle;
2571 extern cvar_t cl_bobup;
2572 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2576 int modelindex, attachloop;
2577 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2580 *out = identitymatrix; // warnings and errors return identical matrix
2582 if (ent == prog->edicts)
2584 if (ent->priv.server->free)
2587 modelindex = (int)ent->fields.server->modelindex;
2588 if (modelindex <= 0 || modelindex > MAX_MODELS)
2591 model = sv.models[modelindex];
2593 tagmatrix = identitymatrix;
2594 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2598 if (attachloop >= 256) // prevent runaway looping
2600 // apply transformation by child's tagindex on parent entity and then
2601 // by parent entity itself
2602 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2603 if (ret && attachloop == 0)
2605 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2606 SV_GetEntityMatrix(ent, &entitymatrix, false);
2607 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2608 // next iteration we process the parent entity
2609 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2611 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2612 ent = PRVM_EDICT_NUM(val->edict);
2619 // RENDER_VIEWMODEL magic
2620 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2622 Matrix4x4_Copy(&tagmatrix, out);
2623 ent = PRVM_EDICT_NUM(val->edict);
2625 SV_GetEntityMatrix(ent, &entitymatrix, true);
2626 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2629 // Cl_bob, ported from rendering code
2630 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2633 // LordHavoc: this code is *weird*, but not replacable (I think it
2634 // should be done in QC on the server, but oh well, quake is quake)
2635 // LordHavoc: figured out bobup: the time at which the sin is at 180
2636 // degrees (which allows lengthening or squishing the peak or valley)
2637 cycle = sv.time/cl_bobcycle.value;
2638 cycle -= (int)cycle;
2639 if (cycle < cl_bobup.value)
2640 cycle = sin(M_PI * cycle / cl_bobup.value);
2642 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2643 // bob is proportional to velocity in the xy plane
2644 // (don't count Z, or jumping messes it up)
2645 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;
2646 bob = bob*0.3 + bob*0.7*cycle;
2647 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2654 //float(entity ent, string tagname) gettagindex;
2656 static void VM_SV_gettagindex (void)
2659 const char *tag_name;
2660 int modelindex, tag_index;
2662 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2664 ent = PRVM_G_EDICT(OFS_PARM0);
2665 tag_name = PRVM_G_STRING(OFS_PARM1);
2667 if (ent == prog->edicts)
2669 VM_Warning("gettagindex: can't affect world entity\n");
2672 if (ent->priv.server->free)
2674 VM_Warning("gettagindex: can't affect free entity\n");
2678 modelindex = (int)ent->fields.server->modelindex;
2680 if (modelindex <= 0 || modelindex > MAX_MODELS)
2681 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2684 tag_index = SV_GetTagIndex(ent, tag_name);
2686 if(developer.integer >= 100)
2687 Con_Printf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2689 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2692 //vector(entity ent, float tagindex) gettaginfo;
2693 static void VM_SV_gettaginfo (void)
2697 matrix4x4_t tag_matrix;
2698 matrix4x4_t tag_localmatrix;
2700 const char *tagname;
2703 vec3_t fo, ri, up, trans;
2705 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2707 e = PRVM_G_EDICT(OFS_PARM0);
2708 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2710 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2711 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2712 SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
2713 Matrix4x4_ToVectors(&tag_localmatrix, fo, ri, up, trans);
2715 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
2716 val->_float = parentindex;
2717 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
2718 val->string = tagname ? PRVM_SetTempString(tagname) : 0;
2719 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
2720 VectorCopy(trans, val->vector);
2721 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
2722 VectorCopy(fo, val->vector);
2723 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
2724 VectorCopy(ri, val->vector);
2725 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
2726 VectorCopy(up, val->vector);
2731 VM_Warning("gettagindex: can't affect world entity\n");
2734 VM_Warning("gettagindex: can't affect free entity\n");
2737 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2740 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2743 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2748 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2749 static void VM_SV_dropclient (void)
2752 client_t *oldhostclient;
2753 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2754 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2755 if (clientnum < 0 || clientnum >= svs.maxclients)
2757 VM_Warning("dropclient: not a client\n");
2760 if (!svs.clients[clientnum].active)
2762 VM_Warning("dropclient: that client slot is not connected\n");
2765 oldhostclient = host_client;
2766 host_client = svs.clients + clientnum;
2767 SV_DropClient(false);
2768 host_client = oldhostclient;
2771 //entity() spawnclient (DP_SV_BOTCLIENT)
2772 static void VM_SV_spawnclient (void)
2776 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2777 prog->xfunction->builtinsprofile += 2;
2779 for (i = 0;i < svs.maxclients;i++)
2781 if (!svs.clients[i].active)
2783 prog->xfunction->builtinsprofile += 100;
2784 SV_ConnectClient (i, NULL);
2785 // this has to be set or else ClientDisconnect won't be called
2786 // we assume the qc will call ClientConnect...
2787 svs.clients[i].clientconnectcalled = true;
2788 ed = PRVM_EDICT_NUM(i + 1);
2792 VM_RETURN_EDICT(ed);
2795 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2796 static void VM_SV_clienttype (void)
2799 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2800 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2801 if (clientnum < 0 || clientnum >= svs.maxclients)
2802 PRVM_G_FLOAT(OFS_RETURN) = 3;
2803 else if (!svs.clients[clientnum].active)
2804 PRVM_G_FLOAT(OFS_RETURN) = 0;
2805 else if (svs.clients[clientnum].netconnection)
2806 PRVM_G_FLOAT(OFS_RETURN) = 1;
2808 PRVM_G_FLOAT(OFS_RETURN) = 2;
2815 string(string key) serverkey
2818 void VM_SV_serverkey(void)
2820 char string[VM_STRINGTEMP_LENGTH];
2821 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2822 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2823 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2826 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2827 static void VM_SV_setmodelindex (void)
2832 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2834 e = PRVM_G_EDICT(OFS_PARM0);
2835 if (e == prog->edicts)
2837 VM_Warning("setmodelindex: can not modify world entity\n");
2840 if (e->priv.server->free)
2842 VM_Warning("setmodelindex: can not modify free entity\n");
2845 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2846 if (i <= 0 || i > MAX_MODELS)
2848 VM_Warning("setmodelindex: invalid modelindex\n");
2851 if (!sv.model_precache[i][0])
2853 VM_Warning("setmodelindex: model not precached\n");
2857 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2858 e->fields.server->modelindex = i;
2864 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2865 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2867 SetMinMaxSize (e, quakemins, quakemaxs, true);
2870 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2873 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2874 static void VM_SV_modelnameforindex (void)
2877 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2879 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2881 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2882 if (i <= 0 || i > MAX_MODELS)
2884 VM_Warning("modelnameforindex: invalid modelindex\n");
2887 if (!sv.model_precache[i][0])
2889 VM_Warning("modelnameforindex: model not precached\n");
2893 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2896 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2897 static void VM_SV_particleeffectnum (void)
2900 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2901 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2904 PRVM_G_FLOAT(OFS_RETURN) = i;
2907 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2908 static void VM_SV_trailparticles (void)
2910 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2912 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2915 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2916 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2917 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2918 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2919 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2920 SV_FlushBroadcastMessages();
2923 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2924 static void VM_SV_pointparticles (void)
2926 int effectnum, count;
2928 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2930 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2933 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2934 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2935 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2936 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2937 if (count == 1 && !VectorLength2(vel))
2940 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2941 MSG_WriteShort(&sv.datagram, effectnum);
2942 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2946 // 1+2+12+12+2=29 bytes
2947 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2948 MSG_WriteShort(&sv.datagram, effectnum);
2949 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2950 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2951 MSG_WriteShort(&sv.datagram, count);
2954 SV_FlushBroadcastMessages();
2957 prvm_builtin_t vm_sv_builtins[] = {
2958 NULL, // #0 NULL function (not callable) (QUAKE)
2959 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2960 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2961 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2962 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2963 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2964 VM_break, // #6 void() break (QUAKE)
2965 VM_random, // #7 float() random (QUAKE)
2966 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2967 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2968 VM_error, // #10 void(string e) error (QUAKE)
2969 VM_objerror, // #11 void(string e) objerror (QUAKE)
2970 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2971 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2972 VM_spawn, // #14 entity() spawn (QUAKE)
2973 VM_remove, // #15 void(entity e) remove (QUAKE)
2974 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2975 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2976 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2977 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2978 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2979 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2980 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2981 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2982 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2983 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2984 VM_ftos, // #26 string(float f) ftos (QUAKE)
2985 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2986 VM_coredump, // #28 void() coredump (QUAKE)
2987 VM_traceon, // #29 void() traceon (QUAKE)
2988 VM_traceoff, // #30 void() traceoff (QUAKE)
2989 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2990 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2991 NULL, // #33 (QUAKE)
2992 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2993 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2994 VM_rint, // #36 float(float v) rint (QUAKE)
2995 VM_floor, // #37 float(float v) floor (QUAKE)
2996 VM_ceil, // #38 float(float v) ceil (QUAKE)
2997 NULL, // #39 (QUAKE)
2998 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2999 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
3000 NULL, // #42 (QUAKE)
3001 VM_fabs, // #43 float(float f) fabs (QUAKE)
3002 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
3003 VM_cvar, // #45 float(string s) cvar (QUAKE)
3004 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
3005 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
3006 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
3007 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
3008 NULL, // #50 (QUAKE)
3009 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
3010 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
3011 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
3012 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
3013 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
3014 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
3015 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
3016 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
3017 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
3018 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
3019 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
3020 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
3021 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
3022 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
3023 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
3024 NULL, // #66 (QUAKE)
3025 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
3026 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
3027 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
3028 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
3029 NULL, // #71 (QUAKE)
3030 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
3031 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
3032 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
3033 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
3034 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
3035 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
3036 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
3037 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
3038 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
3039 VM_stof, // #81 float(string s) stof (FRIK_FILE)
3040 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
3041 NULL, // #83 (QUAKE)
3042 NULL, // #84 (QUAKE)
3043 NULL, // #85 (QUAKE)
3044 NULL, // #86 (QUAKE)
3045 NULL, // #87 (QUAKE)
3046 NULL, // #88 (QUAKE)
3047 NULL, // #89 (QUAKE)
3048 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
3049 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
3050 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
3051 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
3052 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
3053 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3054 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3055 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3056 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3057 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3058 // FrikaC and Telejano range #100-#199
3069 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3070 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3071 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3072 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3073 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3074 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3075 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3076 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3077 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3078 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3159 // FTEQW range #200-#299
3178 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3181 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3182 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3183 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3184 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3185 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3186 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3187 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3188 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3189 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3190 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3192 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3260 // CSQC range #300-#399
3261 NULL, // #300 void() clearscene (EXT_CSQC)
3262 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3263 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3264 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3265 NULL, // #304 void() renderscene (EXT_CSQC)
3266 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3267 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3268 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3269 NULL, // #308 void() R_EndPolygon
3271 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3272 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3276 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3277 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3278 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3279 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3280 NULL, // #319 void(string name) freepic (EXT_CSQC)
3281 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3282 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3283 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3284 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3285 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3286 NULL, // #325 void(void) drawresetcliparea
3291 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3292 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3293 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3294 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3295 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3296 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3297 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3298 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3299 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3300 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3301 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3302 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3303 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3304 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3305 NULL, // #344 vector() getmousepos (EXT_CSQC)
3306 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3307 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3308 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3309 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3310 NULL, // #349 float() isdemo (EXT_CSQC)
3311 VM_isserver, // #350 float() isserver (EXT_CSQC)
3312 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3313 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3314 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3315 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3321 NULL, // #360 float() readbyte (EXT_CSQC)
3322 NULL, // #361 float() readchar (EXT_CSQC)
3323 NULL, // #362 float() readshort (EXT_CSQC)
3324 NULL, // #363 float() readlong (EXT_CSQC)
3325 NULL, // #364 float() readcoord (EXT_CSQC)
3326 NULL, // #365 float() readangle (EXT_CSQC)
3327 NULL, // #366 string() readstring (EXT_CSQC)
3328 NULL, // #367 float() readfloat (EXT_CSQC)
3361 // LordHavoc's range #400-#499
3362 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3363 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3364 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3365 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3366 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3367 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3368 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3369 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3370 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)
3371 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3372 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3373 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3374 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3375 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3376 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3377 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3378 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3379 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3380 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3381 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3382 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3383 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3384 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3385 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3386 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3387 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3388 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3389 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3390 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3391 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3392 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3393 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3394 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3395 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3396 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3397 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3398 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3399 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3400 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3401 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3402 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3403 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3404 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3405 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3406 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3407 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3408 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3409 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3410 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3411 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3412 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3413 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3414 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3415 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3416 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3417 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3418 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3419 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3421 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3422 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3423 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3424 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3425 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3426 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3427 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3428 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3429 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3430 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3431 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3433 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3434 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3435 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3436 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3437 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3438 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3439 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3440 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3441 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3442 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3443 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3444 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3445 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3446 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3447 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3448 VM_SV_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3456 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3457 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3458 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3459 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3460 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3461 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3462 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3463 VM_SV_WritePicture, // #501
3465 VM_whichpack, // #503 string(string) whichpack = #503;
3472 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3473 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3474 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3475 VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3476 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3477 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3478 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3479 VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
3480 VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
3484 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3486 void VM_SV_Cmd_Init(void)
3491 void VM_SV_Cmd_Reset(void)
3493 if(prog->funcoffsets.SV_Shutdown)
3495 func_t s = prog->funcoffsets.SV_Shutdown;
3496 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3497 PRVM_ExecuteProgram(s,"SV_Shutdown() required");