6 //============================================================================
11 char *vm_sv_extensions =
16 "DP_CON_ALIASPARAMETERS "
36 "DP_ENT_CUSTOMCOLORMAP "
37 "DP_ENT_EXTERIORMODELTOCLIENT "
39 "DP_ENT_LOWPRECISION "
43 "DP_GFX_EXTERNALTEXTURES "
44 "DP_GFX_EXTERNALTEXTURES_PERMAP "
46 "DP_GFX_QUAKE3MODELTAGS "
50 "DP_HALFLIFE_MAP_CVAR "
56 "DP_MOVETYPEBOUNCEMISSILE "
59 "DP_QC_ASINACOSATANATAN2TAN "
64 "DP_QC_CVAR_DEFSTRING "
65 "DP_QC_CVAR_DESCRIPTION "
72 "DP_QC_FINDCHAINFLAGS "
73 "DP_QC_FINDCHAINFLOAT "
79 "DP_QC_GETSURFACEPOINTATTRIBUTE "
81 "DP_QC_GETTAGINFO_BONEPROPERTIES "
83 "DP_QC_MULTIPLETEMPSTRINGS "
84 "DP_QC_NUM_FOR_EDICT "
86 "DP_QC_SINCOSSQRTPOW "
88 "DP_QC_STRINGBUFFERS "
89 "DP_QC_STRINGBUFFERS_CVARLIST "
90 "DP_QC_STRINGCOLORFUNCTIONS "
91 "DP_QC_STRING_CASE_FUNCTIONS "
93 "DP_QC_TOKENIZEBYSEPARATOR "
94 "DP_QC_TOKENIZE_CONSOLE "
97 "DP_QC_TRACE_MOVETYPE_HITMODEL "
98 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
99 "DP_QC_UNLIMITEDTEMPSTRINGS "
102 "DP_QC_VECTOANGLES_WITH_ROLL "
103 "DP_QC_VECTORVECTORS "
110 "DP_SND_DIRECTIONLESSATTNNONE "
117 "DP_SV_CLIENTCOLORS "
120 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
121 "DP_SV_DRAWONLYTOCLIENT "
124 "DP_SV_ENTITYCONTENTSTRANSITION "
125 "DP_SV_MODELFLAGS_AS_EFFECTS "
126 "DP_SV_MOVETYPESTEP_LANDEVENT "
128 "DP_SV_NODRAWTOCLIENT "
129 "DP_SV_ONENTITYNOSPAWNFUNCTION "
130 "DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
132 "DP_SV_PLAYERPHYSICS "
133 "DP_SV_POINTPARTICLES "
135 "DP_SV_PRECACHEANYTIME "
139 "DP_SV_ROTATINGBMODEL "
143 "DP_SV_SPAWNFUNC_PREFIX "
144 "DP_SV_WRITEPICTURE "
145 "DP_SV_WRITEUNTERMINATEDSTRING "
149 "DP_TE_EXPLOSIONRGB "
151 "DP_TE_PARTICLECUBE "
152 "DP_TE_PARTICLERAIN "
153 "DP_TE_PARTICLESNOW "
155 "DP_TE_QUADEFFECTS1 "
158 "DP_TE_STANDARDEFFECTBUILTINS "
159 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
164 "KRIMZON_SV_PARSECLIENTCOMMAND "
167 "NEXUIZ_PLAYERMODEL "
169 "PRYDON_CLIENTCURSOR "
170 "TENEBRAE_GFX_DLIGHTS "
172 //"EXT_CSQC " // not ready yet
179 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.
181 setorigin (entity, origin)
184 static void VM_SV_setorigin (void)
189 VM_SAFEPARMCOUNT(2, VM_setorigin);
191 e = PRVM_G_EDICT(OFS_PARM0);
192 if (e == prog->edicts)
194 VM_Warning("setorigin: can not modify world entity\n");
197 if (e->priv.server->free)
199 VM_Warning("setorigin: can not modify free entity\n");
202 org = PRVM_G_VECTOR(OFS_PARM1);
203 VectorCopy (org, e->fields.server->origin);
204 SV_LinkEdict (e, false);
207 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
208 static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
212 for (i=0 ; i<3 ; i++)
214 PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
216 // set derived values
217 VectorCopy (min, e->fields.server->mins);
218 VectorCopy (max, e->fields.server->maxs);
219 VectorSubtract (max, min, e->fields.server->size);
221 SV_LinkEdict (e, false);
228 the size box is rotated by the current angle
229 LordHavoc: no it isn't...
231 setsize (entity, minvector, maxvector)
234 static void VM_SV_setsize (void)
239 VM_SAFEPARMCOUNT(3, VM_setsize);
241 e = PRVM_G_EDICT(OFS_PARM0);
242 if (e == prog->edicts)
244 VM_Warning("setsize: can not modify world entity\n");
247 if (e->priv.server->free)
249 VM_Warning("setsize: can not modify free entity\n");
252 min = PRVM_G_VECTOR(OFS_PARM1);
253 max = PRVM_G_VECTOR(OFS_PARM2);
254 SetMinMaxSize (e, min, max, false);
262 setmodel(entity, model)
265 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
266 static void VM_SV_setmodel (void)
272 VM_SAFEPARMCOUNT(2, VM_setmodel);
274 e = PRVM_G_EDICT(OFS_PARM0);
275 if (e == prog->edicts)
277 VM_Warning("setmodel: can not modify world entity\n");
280 if (e->priv.server->free)
282 VM_Warning("setmodel: can not modify free entity\n");
285 i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
286 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
287 e->fields.server->modelindex = i;
293 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
294 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
296 SetMinMaxSize (e, quakemins, quakemaxs, true);
299 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
306 single print to a specific client
308 sprint(clientent, value)
311 static void VM_SV_sprint (void)
315 char string[VM_STRINGTEMP_LENGTH];
317 VM_VarString(1, string, sizeof(string));
319 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_sprint);
321 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
322 // LordHavoc: div0 requested that sprintto world operate like print
329 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
331 VM_Warning("tried to centerprint to a non-client\n");
335 client = svs.clients + entnum-1;
336 if (!client->netconnection)
339 MSG_WriteChar(&client->netconnection->message,svc_print);
340 MSG_WriteString(&client->netconnection->message, string);
348 single print to a specific client
350 centerprint(clientent, value)
353 static void VM_SV_centerprint (void)
357 char string[VM_STRINGTEMP_LENGTH];
359 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_centerprint);
361 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
363 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
365 VM_Warning("tried to centerprint to a non-client\n");
369 client = svs.clients + entnum-1;
370 if (!client->netconnection)
373 VM_VarString(1, string, sizeof(string));
374 MSG_WriteChar(&client->netconnection->message,svc_centerprint);
375 MSG_WriteString(&client->netconnection->message, string);
382 particle(origin, color, count)
385 static void VM_SV_particle (void)
391 VM_SAFEPARMCOUNT(4, VM_SV_particle);
393 org = PRVM_G_VECTOR(OFS_PARM0);
394 dir = PRVM_G_VECTOR(OFS_PARM1);
395 color = PRVM_G_FLOAT(OFS_PARM2);
396 count = PRVM_G_FLOAT(OFS_PARM3);
397 SV_StartParticle (org, dir, (int)color, (int)count);
407 static void VM_SV_ambientsound (void)
411 float vol, attenuation;
414 VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
416 pos = PRVM_G_VECTOR (OFS_PARM0);
417 samp = PRVM_G_STRING(OFS_PARM1);
418 vol = PRVM_G_FLOAT(OFS_PARM2);
419 attenuation = PRVM_G_FLOAT(OFS_PARM3);
421 // check to see if samp was properly precached
422 soundnum = SV_SoundIndex(samp, 1);
430 // add an svc_spawnambient command to the level signon packet
433 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
435 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
437 MSG_WriteVector(&sv.signon, pos, sv.protocol);
439 if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
440 MSG_WriteShort (&sv.signon, soundnum);
442 MSG_WriteByte (&sv.signon, soundnum);
444 MSG_WriteByte (&sv.signon, (int)(vol*255));
445 MSG_WriteByte (&sv.signon, (int)(attenuation*64));
453 Each entity can have eight independant sound sources, like voice,
456 Channel 0 is an auto-allocate channel, the others override anything
457 already running on that entity/channel pair.
459 An attenuation of 0 will play full volume everywhere in the level.
460 Larger attenuations will drop off.
464 static void VM_SV_sound (void)
468 prvm_edict_t *entity;
472 VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_sound);
474 entity = PRVM_G_EDICT(OFS_PARM0);
475 channel = (int)PRVM_G_FLOAT(OFS_PARM1);
476 sample = PRVM_G_STRING(OFS_PARM2);
477 volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
478 attenuation = PRVM_G_FLOAT(OFS_PARM4);
481 Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
485 if (volume < 0 || volume > 255)
487 VM_Warning("SV_StartSound: volume must be in range 0-1\n");
491 if (attenuation < 0 || attenuation > 4)
493 VM_Warning("SV_StartSound: attenuation must be in range 0-4\n");
497 if (channel < 0 || channel > 7)
499 VM_Warning("SV_StartSound: channel must be in range 0-7\n");
503 SV_StartSound (entity, channel, sample, volume, attenuation);
510 Follows the same logic as VM_SV_sound, except instead of
511 an entity, an origin for the sound is provided, and channel
512 is omitted (since no entity is being tracked).
516 static void VM_SV_pointsound(void)
523 VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
525 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
526 sample = PRVM_G_STRING(OFS_PARM1);
527 volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
528 attenuation = PRVM_G_FLOAT(OFS_PARM3);
530 if (volume < 0 || volume > 255)
532 VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
536 if (attenuation < 0 || attenuation > 4)
538 VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
542 SV_StartPointSound (org, sample, volume, attenuation);
549 Used for use tracing and shot targeting
550 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
551 if the tryents flag is set.
553 traceline (vector1, vector2, movetype, ignore)
556 static void VM_SV_traceline (void)
563 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_traceline); // allow more parameters for future expansion
565 prog->xfunction->builtinsprofile += 30;
567 v1 = PRVM_G_VECTOR(OFS_PARM0);
568 v2 = PRVM_G_VECTOR(OFS_PARM1);
569 move = (int)PRVM_G_FLOAT(OFS_PARM2);
570 ent = PRVM_G_EDICT(OFS_PARM3);
572 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]))
573 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));
575 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
577 VM_SetTraceGlobals(&trace);
585 Used for use tracing and shot targeting
586 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
587 if the tryents flag is set.
589 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
592 // LordHavoc: added this for my own use, VERY useful, similar to traceline
593 static void VM_SV_tracebox (void)
595 float *v1, *v2, *m1, *m2;
600 VM_SAFEPARMCOUNTRANGE(6, 8, VM_SV_tracebox); // allow more parameters for future expansion
602 prog->xfunction->builtinsprofile += 30;
604 v1 = PRVM_G_VECTOR(OFS_PARM0);
605 m1 = PRVM_G_VECTOR(OFS_PARM1);
606 m2 = PRVM_G_VECTOR(OFS_PARM2);
607 v2 = PRVM_G_VECTOR(OFS_PARM3);
608 move = (int)PRVM_G_FLOAT(OFS_PARM4);
609 ent = PRVM_G_EDICT(OFS_PARM5);
611 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]))
612 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));
614 trace = SV_Move (v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
616 VM_SetTraceGlobals(&trace);
619 static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
624 vec3_t original_origin;
625 vec3_t original_velocity;
626 vec3_t original_angles;
627 vec3_t original_avelocity;
631 VectorCopy(tossent->fields.server->origin , original_origin );
632 VectorCopy(tossent->fields.server->velocity , original_velocity );
633 VectorCopy(tossent->fields.server->angles , original_angles );
634 VectorCopy(tossent->fields.server->avelocity, original_avelocity);
636 val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
637 if (val != NULL && val->_float != 0)
638 gravity = val->_float;
641 gravity *= sv_gravity.value * 0.025;
643 for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
645 SV_CheckVelocity (tossent);
646 tossent->fields.server->velocity[2] -= gravity;
647 VectorMA (tossent->fields.server->angles, 0.05, tossent->fields.server->avelocity, tossent->fields.server->angles);
648 VectorScale (tossent->fields.server->velocity, 0.05, move);
649 VectorAdd (tossent->fields.server->origin, move, end);
650 trace = SV_Move (tossent->fields.server->origin, tossent->fields.server->mins, tossent->fields.server->maxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
651 VectorCopy (trace.endpos, tossent->fields.server->origin);
652 tossent->fields.server->velocity[2] -= gravity;
654 if (trace.fraction < 1)
658 VectorCopy(original_origin , tossent->fields.server->origin );
659 VectorCopy(original_velocity , tossent->fields.server->velocity );
660 VectorCopy(original_angles , tossent->fields.server->angles );
661 VectorCopy(original_avelocity, tossent->fields.server->avelocity);
666 static void VM_SV_tracetoss (void)
670 prvm_edict_t *ignore;
672 VM_SAFEPARMCOUNT(2, VM_SV_tracetoss);
674 prog->xfunction->builtinsprofile += 600;
676 ent = PRVM_G_EDICT(OFS_PARM0);
677 if (ent == prog->edicts)
679 VM_Warning("tracetoss: can not use world entity\n");
682 ignore = PRVM_G_EDICT(OFS_PARM1);
684 trace = SV_Trace_Toss (ent, ignore);
686 VM_SetTraceGlobals(&trace);
689 //============================================================================
691 static int checkpvsbytes;
692 static unsigned char checkpvs[MAX_MAP_LEAFS/8];
694 static int VM_SV_newcheckclient (int check)
700 // cycle to the next one
702 check = bound(1, check, svs.maxclients);
703 if (check == svs.maxclients)
711 prog->xfunction->builtinsprofile++;
713 if (i == svs.maxclients+1)
715 // look up the client's edict
716 ent = PRVM_EDICT_NUM(i);
717 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
718 if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
720 // found a valid client (possibly the same one again)
724 // get the PVS for the entity
725 VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
727 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
728 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs), false);
737 Returns a client (or object that has a client enemy) that would be a
740 If there is more than one valid option, they are cycled each frame
742 If (self.origin + self.viewofs) is not in the PVS of the current target,
743 it is not returned at all.
748 int c_invis, c_notvis;
749 static void VM_SV_checkclient (void)
751 prvm_edict_t *ent, *self;
754 VM_SAFEPARMCOUNT(0, VM_SV_checkclient);
756 // find a new check if on a new frame
757 if (sv.time - sv.lastchecktime >= 0.1)
759 sv.lastcheck = VM_SV_newcheckclient (sv.lastcheck);
760 sv.lastchecktime = sv.time;
763 // return check if it might be visible
764 ent = PRVM_EDICT_NUM(sv.lastcheck);
765 if (ent->priv.server->free || ent->fields.server->health <= 0)
767 VM_RETURN_EDICT(prog->edicts);
771 // if current entity can't possibly see the check entity, return 0
772 self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
773 VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
774 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
777 VM_RETURN_EDICT(prog->edicts);
781 // might be able to see it
783 VM_RETURN_EDICT(ent);
786 //============================================================================
793 Sends text over to the client's execution buffer
795 stuffcmd (clientent, value, ...)
798 static void VM_SV_stuffcmd (void)
802 char string[VM_STRINGTEMP_LENGTH];
804 VM_SAFEPARMCOUNTRANGE(2, 8, VM_SV_stuffcmd);
806 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
807 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
809 VM_Warning("Can't stuffcmd to a non-client\n");
813 VM_VarString(1, string, sizeof(string));
816 host_client = svs.clients + entnum-1;
817 Host_ClientCommands ("%s", string);
825 Returns a chain of entities that have origins within a spherical area
827 findradius (origin, radius)
830 static void VM_SV_findradius (void)
832 prvm_edict_t *ent, *chain;
833 vec_t radius, radius2;
834 vec3_t org, eorg, mins, maxs;
837 prvm_edict_t *touchedicts[MAX_EDICTS];
839 VM_SAFEPARMCOUNT(2, VM_SV_findradius);
841 chain = (prvm_edict_t *)prog->edicts;
843 VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
844 radius = PRVM_G_FLOAT(OFS_PARM1);
845 radius2 = radius * radius;
847 mins[0] = org[0] - (radius + 1);
848 mins[1] = org[1] - (radius + 1);
849 mins[2] = org[2] - (radius + 1);
850 maxs[0] = org[0] + (radius + 1);
851 maxs[1] = org[1] + (radius + 1);
852 maxs[2] = org[2] + (radius + 1);
853 numtouchedicts = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, touchedicts);
854 if (numtouchedicts > MAX_EDICTS)
856 // this never happens
857 Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
858 numtouchedicts = MAX_EDICTS;
860 for (i = 0;i < numtouchedicts;i++)
862 ent = touchedicts[i];
863 prog->xfunction->builtinsprofile++;
864 // Quake did not return non-solid entities but darkplaces does
865 // (note: this is the reason you can't blow up fallen zombies)
866 if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
868 // LordHavoc: compare against bounding box rather than center so it
869 // doesn't miss large objects, and use DotProduct instead of Length
870 // for a major speedup
871 VectorSubtract(org, ent->fields.server->origin, eorg);
872 if (sv_gameplayfix_findradiusdistancetobox.integer)
874 eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
875 eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
876 eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
879 VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
880 if (DotProduct(eorg, eorg) < radius2)
882 ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
887 VM_RETURN_EDICT(chain);
890 static void VM_SV_precache_sound (void)
892 VM_SAFEPARMCOUNT(1, VM_SV_precache_sound);
893 PRVM_G_FLOAT(OFS_RETURN) = SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
896 static void VM_SV_precache_model (void)
898 VM_SAFEPARMCOUNT(1, VM_SV_precache_model);
899 SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
900 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
907 float(float yaw, float dist[, settrace]) walkmove
910 static void VM_SV_walkmove (void)
919 VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
921 // assume failure if it returns early
922 PRVM_G_FLOAT(OFS_RETURN) = 0;
924 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
925 if (ent == prog->edicts)
927 VM_Warning("walkmove: can not modify world entity\n");
930 if (ent->priv.server->free)
932 VM_Warning("walkmove: can not modify free entity\n");
935 yaw = PRVM_G_FLOAT(OFS_PARM0);
936 dist = PRVM_G_FLOAT(OFS_PARM1);
937 settrace = prog->argc >= 3 && PRVM_G_FLOAT(OFS_PARM2);
939 if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
942 yaw = yaw*M_PI*2 / 360;
944 move[0] = cos(yaw)*dist;
945 move[1] = sin(yaw)*dist;
948 // save program state, because SV_movestep may call other progs
949 oldf = prog->xfunction;
950 oldself = prog->globals.server->self;
952 PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace);
955 // restore program state
956 prog->xfunction = oldf;
957 prog->globals.server->self = oldself;
967 static void VM_SV_droptofloor (void)
973 VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
975 // assume failure if it returns early
976 PRVM_G_FLOAT(OFS_RETURN) = 0;
978 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
979 if (ent == prog->edicts)
981 VM_Warning("droptofloor: can not modify world entity\n");
984 if (ent->priv.server->free)
986 VM_Warning("droptofloor: can not modify free entity\n");
990 VectorCopy (ent->fields.server->origin, end);
993 if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
994 SV_UnstickEntity(ent);
996 trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
997 if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
1000 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]);
1001 VectorAdd(ent->fields.server->origin, offset, org);
1002 trace = SV_Move (org, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
1003 VectorSubtract(trace.endpos, offset, trace.endpos);
1004 if (trace.startsolid)
1006 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]);
1007 SV_UnstickEntity(ent);
1008 SV_LinkEdict (ent, false);
1009 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1010 ent->fields.server->groundentity = 0;
1011 PRVM_G_FLOAT(OFS_RETURN) = 1;
1013 else if (trace.fraction < 1)
1015 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]);
1016 VectorCopy (trace.endpos, ent->fields.server->origin);
1017 SV_UnstickEntity(ent);
1018 SV_LinkEdict (ent, false);
1019 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1020 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1021 PRVM_G_FLOAT(OFS_RETURN) = 1;
1022 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1023 ent->priv.server->suspendedinairflag = true;
1028 if (trace.fraction != 1)
1030 if (trace.fraction < 1)
1031 VectorCopy (trace.endpos, ent->fields.server->origin);
1032 SV_LinkEdict (ent, false);
1033 ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
1034 ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
1035 PRVM_G_FLOAT(OFS_RETURN) = 1;
1036 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1037 ent->priv.server->suspendedinairflag = true;
1046 void(float style, string value) lightstyle
1049 static void VM_SV_lightstyle (void)
1056 VM_SAFEPARMCOUNT(2, VM_SV_lightstyle);
1058 style = (int)PRVM_G_FLOAT(OFS_PARM0);
1059 val = PRVM_G_STRING(OFS_PARM1);
1061 if( (unsigned) style >= MAX_LIGHTSTYLES ) {
1062 PRVM_ERROR( "PF_lightstyle: style: %i >= 64", style );
1065 // change the string in sv
1066 strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
1068 // send message to all clients on this server
1069 if (sv.state != ss_active)
1072 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1074 if (client->active && client->netconnection)
1076 MSG_WriteChar (&client->netconnection->message, svc_lightstyle);
1077 MSG_WriteChar (&client->netconnection->message,style);
1078 MSG_WriteString (&client->netconnection->message, val);
1088 static void VM_SV_checkbottom (void)
1090 VM_SAFEPARMCOUNT(1, VM_SV_checkbottom);
1091 PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
1099 static void VM_SV_pointcontents (void)
1101 VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
1102 PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
1109 Pick a vector for the player to shoot along
1110 vector aim(entity, missilespeed)
1113 static void VM_SV_aim (void)
1115 prvm_edict_t *ent, *check, *bestent;
1116 vec3_t start, dir, end, bestdir;
1119 float dist, bestdist;
1122 VM_SAFEPARMCOUNT(2, VM_SV_aim);
1124 // assume failure if it returns early
1125 VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1126 // if sv_aim is so high it can't possibly accept anything, skip out early
1127 if (sv_aim.value >= 1)
1130 ent = PRVM_G_EDICT(OFS_PARM0);
1131 if (ent == prog->edicts)
1133 VM_Warning("aim: can not use world entity\n");
1136 if (ent->priv.server->free)
1138 VM_Warning("aim: can not use free entity\n");
1141 speed = PRVM_G_FLOAT(OFS_PARM1);
1143 VectorCopy (ent->fields.server->origin, start);
1146 // try sending a trace straight
1147 VectorCopy (prog->globals.server->v_forward, dir);
1148 VectorMA (start, 2048, dir, end);
1149 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1150 if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
1151 && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
1153 VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
1158 // try all possible entities
1159 VectorCopy (dir, bestdir);
1160 bestdist = sv_aim.value;
1163 check = PRVM_NEXT_EDICT(prog->edicts);
1164 for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
1166 prog->xfunction->builtinsprofile++;
1167 if (check->fields.server->takedamage != DAMAGE_AIM)
1171 if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
1172 continue; // don't aim at teammate
1173 for (j=0 ; j<3 ; j++)
1174 end[j] = check->fields.server->origin[j]
1175 + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
1176 VectorSubtract (end, start, dir);
1177 VectorNormalize (dir);
1178 dist = DotProduct (dir, prog->globals.server->v_forward);
1179 if (dist < bestdist)
1180 continue; // to far to turn
1181 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
1182 if (tr.ent == check)
1183 { // can shoot at this one
1191 VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
1192 dist = DotProduct (dir, prog->globals.server->v_forward);
1193 VectorScale (prog->globals.server->v_forward, dist, end);
1195 VectorNormalize (end);
1196 VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
1200 VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
1205 ===============================================================================
1209 ===============================================================================
1212 #define MSG_BROADCAST 0 // unreliable to all
1213 #define MSG_ONE 1 // reliable to one (msg_entity)
1214 #define MSG_ALL 2 // reliable to all
1215 #define MSG_INIT 3 // write to the init string
1216 #define MSG_ENTITY 5
1218 sizebuf_t *WriteDest (void)
1224 dest = (int)PRVM_G_FLOAT(OFS_PARM0);
1228 return &sv.datagram;
1231 ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
1232 entnum = PRVM_NUM_FOR_EDICT(ent);
1233 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active || !svs.clients[entnum-1].netconnection)
1235 VM_Warning ("WriteDest: tried to write to non-client\n");
1236 return &sv.reliable_datagram;
1239 return &svs.clients[entnum-1].netconnection->message;
1242 VM_Warning ("WriteDest: bad destination\n");
1244 return &sv.reliable_datagram;
1250 return sv.writeentitiestoclient_msg;
1256 static void VM_SV_WriteByte (void)
1258 VM_SAFEPARMCOUNT(2, VM_SV_WriteByte);
1259 MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1262 static void VM_SV_WriteChar (void)
1264 VM_SAFEPARMCOUNT(2, VM_SV_WriteChar);
1265 MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1268 static void VM_SV_WriteShort (void)
1270 VM_SAFEPARMCOUNT(2, VM_SV_WriteShort);
1271 MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1274 static void VM_SV_WriteLong (void)
1276 VM_SAFEPARMCOUNT(2, VM_SV_WriteLong);
1277 MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1));
1280 static void VM_SV_WriteAngle (void)
1282 VM_SAFEPARMCOUNT(2, VM_SV_WriteAngle);
1283 MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1286 static void VM_SV_WriteCoord (void)
1288 VM_SAFEPARMCOUNT(2, VM_SV_WriteCoord);
1289 MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
1292 static void VM_SV_WriteString (void)
1294 VM_SAFEPARMCOUNT(2, VM_SV_WriteString);
1295 MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1298 static void VM_SV_WriteUnterminatedString (void)
1300 VM_SAFEPARMCOUNT(2, VM_SV_WriteUnterminatedString);
1301 MSG_WriteUnterminatedString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
1305 static void VM_SV_WriteEntity (void)
1307 VM_SAFEPARMCOUNT(2, VM_SV_WriteEntity);
1308 MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
1311 // writes a picture as at most size bytes of data
1313 // IMGNAME \0 SIZE(short) IMGDATA
1314 // if failed to read/compress:
1316 //#501 void(float dest, string name, float maxsize) WritePicture (DP_SV_WRITEPICTURE))
1317 static void VM_SV_WritePicture (void)
1319 const char *imgname;
1323 VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
1325 imgname = PRVM_G_STRING(OFS_PARM1);
1326 size = (int) PRVM_G_FLOAT(OFS_PARM2);
1330 MSG_WriteString(WriteDest(), imgname);
1331 if(Image_Compress(imgname, size, &buf, &size))
1334 MSG_WriteShort(WriteDest(), size);
1335 SZ_Write(WriteDest(), (unsigned char *) buf, size);
1340 MSG_WriteShort(WriteDest(), 0);
1344 //////////////////////////////////////////////////////////
1346 static void VM_SV_makestatic (void)
1351 // allow 0 parameters due to an id1 qc bug in which this function is used
1352 // with no parameters (but directly after setmodel with self in OFS_PARM0)
1353 VM_SAFEPARMCOUNTRANGE(0, 1, VM_SV_makestatic);
1355 if (prog->argc >= 1)
1356 ent = PRVM_G_EDICT(OFS_PARM0);
1358 ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
1359 if (ent == prog->edicts)
1361 VM_Warning("makestatic: can not modify world entity\n");
1364 if (ent->priv.server->free)
1366 VM_Warning("makestatic: can not modify free entity\n");
1371 if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
1376 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1377 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1378 MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame);
1380 else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
1382 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1383 MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex);
1384 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1388 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1389 MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex);
1390 MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame);
1393 MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap);
1394 MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin);
1395 for (i=0 ; i<3 ; i++)
1397 MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
1398 MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
1401 // throw the entity away now
1405 //=============================================================================
1412 static void VM_SV_setspawnparms (void)
1418 VM_SAFEPARMCOUNT(1, VM_SV_setspawnparms);
1420 ent = PRVM_G_EDICT(OFS_PARM0);
1421 i = PRVM_NUM_FOR_EDICT(ent);
1422 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1424 Con_Print("tried to setspawnparms on a non-client\n");
1428 // copy spawn parms out of the client_t
1429 client = svs.clients + i-1;
1430 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1431 (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
1438 Returns a color vector indicating the lighting at the requested point.
1440 (Internal Operation note: actually measures the light beneath the point, just like
1441 the model lighting on the client)
1446 static void VM_SV_getlight (void)
1448 vec3_t ambientcolor, diffusecolor, diffusenormal;
1450 VM_SAFEPARMCOUNT(1, VM_SV_getlight);
1451 p = PRVM_G_VECTOR(OFS_PARM0);
1452 VectorClear(ambientcolor);
1453 VectorClear(diffusecolor);
1454 VectorClear(diffusenormal);
1455 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
1456 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
1457 VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
1462 unsigned char type; // 1/2/8 or other value if isn't used
1466 static customstat_t *vm_customstats = NULL; //[515]: it starts from 0, not 32
1467 static int vm_customstats_last;
1469 void VM_CustomStats_Clear (void)
1473 Z_Free(vm_customstats);
1474 vm_customstats = NULL;
1475 vm_customstats_last = -1;
1479 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
1487 for(i=0; i<vm_customstats_last+1 ;i++)
1489 if(!vm_customstats[i].type)
1491 switch(vm_customstats[i].type)
1493 //string as 16 bytes
1496 strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
1497 stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
1498 stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
1499 stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
1500 stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
1502 //float field sent as-is
1504 stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
1506 //integer value of float field
1508 stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
1516 // void(float index, float type, .void field) SV_AddStat = #232;
1517 // Set up an auto-sent player stat.
1518 // Client's get thier own fields sent to them. Index may not be less than 32.
1519 // Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
1520 // 1: string (4 stats carrying a total of 16 charactures)
1521 // 2: float (one stat, float converted to an integer for transportation)
1522 // 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
1523 static void VM_SV_AddStat (void)
1528 VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
1532 vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
1535 VM_Warning("PF_SV_AddStat: not enough memory\n");
1539 i = (int)PRVM_G_FLOAT(OFS_PARM0);
1540 type = (int)PRVM_G_FLOAT(OFS_PARM1);
1541 off = PRVM_G_INT (OFS_PARM2);
1546 VM_Warning("PF_SV_AddStat: index may not be less than 32\n");
1549 if(i >= (MAX_CL_STATS-32))
1551 VM_Warning("PF_SV_AddStat: index >= MAX_CL_STATS\n");
1554 if(i > (MAX_CL_STATS-32-4) && type == 1)
1556 VM_Warning("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
1559 vm_customstats[i].type = type;
1560 vm_customstats[i].fieldoffset = off;
1561 if(vm_customstats_last < i)
1562 vm_customstats_last = i;
1569 copies data from one entity to another
1571 copyentity(src, dst)
1574 static void VM_SV_copyentity (void)
1576 prvm_edict_t *in, *out;
1577 VM_SAFEPARMCOUNT(2, VM_SV_copyentity);
1578 in = PRVM_G_EDICT(OFS_PARM0);
1579 if (in == prog->edicts)
1581 VM_Warning("copyentity: can not read world entity\n");
1584 if (in->priv.server->free)
1586 VM_Warning("copyentity: can not read free entity\n");
1589 out = PRVM_G_EDICT(OFS_PARM1);
1590 if (out == prog->edicts)
1592 VM_Warning("copyentity: can not modify world entity\n");
1595 if (out->priv.server->free)
1597 VM_Warning("copyentity: can not modify free entity\n");
1600 memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
1601 SV_LinkEdict(out, false);
1609 sets the color of a client and broadcasts the update to all connected clients
1611 setcolor(clientent, value)
1614 static void VM_SV_setcolor (void)
1620 VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
1621 entnum = PRVM_G_EDICTNUM(OFS_PARM0);
1622 i = (int)PRVM_G_FLOAT(OFS_PARM1);
1624 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1626 Con_Print("tried to setcolor a non-client\n");
1630 client = svs.clients + entnum-1;
1633 if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
1635 client->edict->fields.server->team = (i & 15) + 1;
1638 if (client->old_colors != client->colors)
1640 client->old_colors = client->colors;
1641 // send notification to all clients
1642 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1643 MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
1644 MSG_WriteByte (&sv.reliable_datagram, client->colors);
1652 effect(origin, modelname, startframe, framecount, framerate)
1655 static void VM_SV_effect (void)
1659 VM_SAFEPARMCOUNT(5, VM_SV_effect);
1660 s = PRVM_G_STRING(OFS_PARM1);
1663 VM_Warning("effect: no model specified\n");
1667 i = SV_ModelIndex(s, 1);
1670 VM_Warning("effect: model not precached\n");
1674 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1676 VM_Warning("effect: framecount < 1\n");
1680 if (PRVM_G_FLOAT(OFS_PARM4) < 1)
1682 VM_Warning("effect: framerate < 1\n");
1686 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));
1689 static void VM_SV_te_blood (void)
1691 VM_SAFEPARMCOUNT(3, VM_SV_te_blood);
1692 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1694 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1695 MSG_WriteByte(&sv.datagram, TE_BLOOD);
1697 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1698 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1699 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1701 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1702 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1703 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1705 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1706 SV_FlushBroadcastMessages();
1709 static void VM_SV_te_bloodshower (void)
1711 VM_SAFEPARMCOUNT(4, VM_SV_te_bloodshower);
1712 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1714 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1715 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
1717 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1718 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1719 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1721 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1722 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1723 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1725 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
1727 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1728 SV_FlushBroadcastMessages();
1731 static void VM_SV_te_explosionrgb (void)
1733 VM_SAFEPARMCOUNT(2, VM_SV_te_explosionrgb);
1734 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1735 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
1737 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1738 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1739 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1741 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
1742 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
1743 MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
1744 SV_FlushBroadcastMessages();
1747 static void VM_SV_te_particlecube (void)
1749 VM_SAFEPARMCOUNT(7, VM_SV_te_particlecube);
1750 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1752 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1753 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
1755 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1756 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1757 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1759 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1760 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1761 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1763 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1764 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1765 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1767 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1769 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1770 // gravity true/false
1771 MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
1773 MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
1774 SV_FlushBroadcastMessages();
1777 static void VM_SV_te_particlerain (void)
1779 VM_SAFEPARMCOUNT(5, VM_SV_te_particlerain);
1780 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1782 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1783 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
1785 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1786 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1787 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1789 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1790 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1791 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1793 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1794 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1795 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1797 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1799 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1800 SV_FlushBroadcastMessages();
1803 static void VM_SV_te_particlesnow (void)
1805 VM_SAFEPARMCOUNT(5, VM_SV_te_particlesnow);
1806 if (PRVM_G_FLOAT(OFS_PARM3) < 1)
1808 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1809 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
1811 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1812 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1813 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1815 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
1816 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
1817 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
1819 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
1820 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
1821 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
1823 MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
1825 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4));
1826 SV_FlushBroadcastMessages();
1829 static void VM_SV_te_spark (void)
1831 VM_SAFEPARMCOUNT(3, VM_SV_te_spark);
1832 if (PRVM_G_FLOAT(OFS_PARM2) < 1)
1834 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1835 MSG_WriteByte(&sv.datagram, TE_SPARK);
1837 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1838 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1839 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1841 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
1842 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
1843 MSG_WriteChar(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
1845 MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
1846 SV_FlushBroadcastMessages();
1849 static void VM_SV_te_gunshotquad (void)
1851 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshotquad);
1852 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1853 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
1855 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1856 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1857 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1858 SV_FlushBroadcastMessages();
1861 static void VM_SV_te_spikequad (void)
1863 VM_SAFEPARMCOUNT(1, VM_SV_te_spikequad);
1864 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1865 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
1867 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1868 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1869 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1870 SV_FlushBroadcastMessages();
1873 static void VM_SV_te_superspikequad (void)
1875 VM_SAFEPARMCOUNT(1, VM_SV_te_superspikequad);
1876 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1877 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
1879 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1880 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1881 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1882 SV_FlushBroadcastMessages();
1885 static void VM_SV_te_explosionquad (void)
1887 VM_SAFEPARMCOUNT(1, VM_SV_te_explosionquad);
1888 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1889 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
1891 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1892 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1893 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1894 SV_FlushBroadcastMessages();
1897 static void VM_SV_te_smallflash (void)
1899 VM_SAFEPARMCOUNT(1, VM_SV_te_smallflash);
1900 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1901 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
1903 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1904 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1905 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1906 SV_FlushBroadcastMessages();
1909 static void VM_SV_te_customflash (void)
1911 VM_SAFEPARMCOUNT(4, VM_SV_te_customflash);
1912 if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
1914 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1915 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
1917 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1918 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1919 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1921 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
1923 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
1925 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
1926 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
1927 MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
1928 SV_FlushBroadcastMessages();
1931 static void VM_SV_te_gunshot (void)
1933 VM_SAFEPARMCOUNT(1, VM_SV_te_gunshot);
1934 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1935 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
1937 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1938 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1939 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1940 SV_FlushBroadcastMessages();
1943 static void VM_SV_te_spike (void)
1945 VM_SAFEPARMCOUNT(1, VM_SV_te_spike);
1946 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1947 MSG_WriteByte(&sv.datagram, TE_SPIKE);
1949 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1950 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1951 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1952 SV_FlushBroadcastMessages();
1955 static void VM_SV_te_superspike (void)
1957 VM_SAFEPARMCOUNT(1, VM_SV_te_superspike);
1958 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1959 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
1961 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1962 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1963 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1964 SV_FlushBroadcastMessages();
1967 static void VM_SV_te_explosion (void)
1969 VM_SAFEPARMCOUNT(1, VM_SV_te_explosion);
1970 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1971 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
1973 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1974 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1975 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1976 SV_FlushBroadcastMessages();
1979 static void VM_SV_te_tarexplosion (void)
1981 VM_SAFEPARMCOUNT(1, VM_SV_te_tarexplosion);
1982 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1983 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
1985 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1986 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1987 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
1988 SV_FlushBroadcastMessages();
1991 static void VM_SV_te_wizspike (void)
1993 VM_SAFEPARMCOUNT(1, VM_SV_te_wizspike);
1994 MSG_WriteByte(&sv.datagram, svc_temp_entity);
1995 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
1997 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
1998 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
1999 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2000 SV_FlushBroadcastMessages();
2003 static void VM_SV_te_knightspike (void)
2005 VM_SAFEPARMCOUNT(1, VM_SV_te_knightspike);
2006 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2007 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2009 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2010 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2011 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2012 SV_FlushBroadcastMessages();
2015 static void VM_SV_te_lavasplash (void)
2017 VM_SAFEPARMCOUNT(1, VM_SV_te_lavasplash);
2018 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2019 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2021 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2022 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2023 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2024 SV_FlushBroadcastMessages();
2027 static void VM_SV_te_teleport (void)
2029 VM_SAFEPARMCOUNT(1, VM_SV_te_teleport);
2030 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2031 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2033 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2034 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2035 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2036 SV_FlushBroadcastMessages();
2039 static void VM_SV_te_explosion2 (void)
2041 VM_SAFEPARMCOUNT(3, VM_SV_te_explosion2);
2042 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2043 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2045 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2046 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2047 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2049 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2050 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2051 SV_FlushBroadcastMessages();
2054 static void VM_SV_te_lightning1 (void)
2056 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning1);
2057 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2058 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2060 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2062 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2063 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2064 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2066 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2067 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2068 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2069 SV_FlushBroadcastMessages();
2072 static void VM_SV_te_lightning2 (void)
2074 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning2);
2075 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2076 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2078 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2080 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2081 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2082 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2084 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2085 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2086 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2087 SV_FlushBroadcastMessages();
2090 static void VM_SV_te_lightning3 (void)
2092 VM_SAFEPARMCOUNT(3, VM_SV_te_lightning3);
2093 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2094 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2096 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2098 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2099 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2100 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2102 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2103 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2104 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2105 SV_FlushBroadcastMessages();
2108 static void VM_SV_te_beam (void)
2110 VM_SAFEPARMCOUNT(3, VM_SV_te_beam);
2111 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2112 MSG_WriteByte(&sv.datagram, TE_BEAM);
2114 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2116 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2117 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2118 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2120 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
2121 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
2122 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
2123 SV_FlushBroadcastMessages();
2126 static void VM_SV_te_plasmaburn (void)
2128 VM_SAFEPARMCOUNT(1, VM_SV_te_plasmaburn);
2129 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2130 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2131 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2132 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2133 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2134 SV_FlushBroadcastMessages();
2137 static void VM_SV_te_flamejet (void)
2139 VM_SAFEPARMCOUNT(3, VM_SV_te_flamejet);
2140 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2141 MSG_WriteByte(&sv.datagram, TE_FLAMEJET);
2143 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
2144 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
2145 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
2147 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
2148 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
2149 MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
2151 MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2));
2152 SV_FlushBroadcastMessages();
2155 void clippointtosurface(dp_model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
2158 float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
2160 bestdist = 1000000000;
2162 for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
2164 // clip original point to each triangle of the surface and find the
2165 // triangle that is closest
2166 v[0] = model->surfmesh.data_vertex3f + e[0] * 3;
2167 v[1] = model->surfmesh.data_vertex3f + e[1] * 3;
2168 v[2] = model->surfmesh.data_vertex3f + e[2] * 3;
2169 TriangleNormal(v[0], v[1], v[2], facenormal);
2170 VectorNormalize(facenormal);
2171 offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
2172 VectorMA(p, offsetdist, facenormal, temp);
2173 for (j = 0, k = 2;j < 3;k = j, j++)
2175 VectorSubtract(v[k], v[j], edgenormal);
2176 CrossProduct(edgenormal, facenormal, sidenormal);
2177 VectorNormalize(sidenormal);
2178 offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
2180 VectorMA(temp, offsetdist, sidenormal, temp);
2182 dist = VectorDistance2(temp, p);
2183 if (bestdist > dist)
2186 VectorCopy(temp, out);
2191 static dp_model_t *getmodel(prvm_edict_t *ed)
2194 if (!ed || ed->priv.server->free)
2196 modelindex = (int)ed->fields.server->modelindex;
2197 if (modelindex < 1 || modelindex >= MAX_MODELS)
2199 return sv.models[modelindex];
2202 static msurface_t *getsurface(dp_model_t *model, int surfacenum)
2204 if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
2206 return model->data_surfaces + surfacenum + model->firstmodelsurface;
2210 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2211 static void VM_SV_getsurfacenumpoints(void)
2214 msurface_t *surface;
2215 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumpoints);
2216 // return 0 if no such surface
2217 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2219 PRVM_G_FLOAT(OFS_RETURN) = 0;
2223 // note: this (incorrectly) assumes it is a simple polygon
2224 PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
2226 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2227 static void VM_SV_getsurfacepoint(void)
2231 msurface_t *surface;
2233 VM_SAFEPARMCOUNT(3, VM_SV_getsurfacepoint);
2234 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2235 ed = PRVM_G_EDICT(OFS_PARM0);
2236 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2238 // note: this (incorrectly) assumes it is a simple polygon
2239 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2240 if (pointnum < 0 || pointnum >= surface->num_vertices)
2242 // FIXME: implement rotation/scaling
2243 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2245 //PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
2246 // float SPA_POSITION = 0;
2247 // float SPA_S_AXIS = 1;
2248 // float SPA_T_AXIS = 2;
2249 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2250 // float SPA_TEXCOORDS0 = 4;
2251 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2252 // float SPA_LIGHTMAP0_COLOR = 6;
2253 static void VM_SV_getsurfacepointattribute(void)
2257 msurface_t *surface;
2261 VM_SAFEPARMCOUNT(4, VM_SV_getsurfacepoint);
2262 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2263 ed = PRVM_G_EDICT(OFS_PARM0);
2264 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2266 // note: this (incorrectly) assumes it is a simple polygon
2267 pointnum = (int)PRVM_G_FLOAT(OFS_PARM2);
2268 if (pointnum < 0 || pointnum >= surface->num_vertices)
2270 // FIXME: implement rotation/scaling
2271 attributetype = (int) PRVM_G_FLOAT(OFS_PARM3);
2273 switch( attributetype ) {
2274 // float SPA_POSITION = 0;
2276 VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2278 // float SPA_S_AXIS = 1;
2280 VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2282 // float SPA_T_AXIS = 2;
2284 VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2286 // float SPA_R_AXIS = 3; // same as SPA_NORMAL
2288 VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
2290 // float SPA_TEXCOORDS0 = 4;
2292 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2293 float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2];
2294 ret[0] = texcoord[0];
2295 ret[1] = texcoord[1];
2299 // float SPA_LIGHTMAP0_TEXCOORDS = 5;
2301 float *ret = PRVM_G_VECTOR(OFS_RETURN);
2302 float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2];
2303 ret[0] = texcoord[0];
2304 ret[1] = texcoord[1];
2308 // float SPA_LIGHTMAP0_COLOR = 6;
2310 // ignore alpha for now..
2311 VectorCopy( &(model->surfmesh.data_lightmapcolor4f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
2314 VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
2318 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2319 static void VM_SV_getsurfacenormal(void)
2322 msurface_t *surface;
2324 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenormal);
2325 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2326 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2328 // FIXME: implement rotation/scaling
2329 // note: this (incorrectly) assumes it is a simple polygon
2330 // note: this only returns the first triangle, so it doesn't work very
2331 // well for curved surfaces or arbitrary meshes
2332 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);
2333 VectorNormalize(normal);
2334 VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
2336 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2337 static void VM_SV_getsurfacetexture(void)
2340 msurface_t *surface;
2341 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacetexture);
2342 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2343 if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2345 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(surface->texture->name);
2347 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2348 static void VM_SV_getsurfacenearpoint(void)
2350 int surfacenum, best;
2352 vec_t dist, bestdist;
2355 msurface_t *surface;
2357 VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenearpoint);
2358 PRVM_G_FLOAT(OFS_RETURN) = -1;
2359 ed = PRVM_G_EDICT(OFS_PARM0);
2360 point = PRVM_G_VECTOR(OFS_PARM1);
2362 if (!ed || ed->priv.server->free)
2364 model = getmodel(ed);
2365 if (!model || !model->num_surfaces)
2368 // FIXME: implement rotation/scaling
2369 VectorSubtract(point, ed->fields.server->origin, p);
2371 bestdist = 1000000000;
2372 for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
2374 surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
2375 // first see if the nearest point on the surface's box is closer than the previous match
2376 clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
2377 clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
2378 clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
2379 dist = VectorLength2(clipped);
2380 if (dist < bestdist)
2382 // it is, check the nearest point on the actual geometry
2383 clippointtosurface(model, surface, p, clipped);
2384 VectorSubtract(clipped, p, clipped);
2385 dist += VectorLength2(clipped);
2386 if (dist < bestdist)
2388 // that's closer too, store it as the best match
2394 PRVM_G_FLOAT(OFS_RETURN) = best;
2396 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2397 static void VM_SV_getsurfaceclippedpoint(void)
2401 msurface_t *surface;
2403 VM_SAFEPARMCOUNT(3, VM_SV_te_getsurfaceclippedpoint);
2404 VectorClear(PRVM_G_VECTOR(OFS_RETURN));
2405 ed = PRVM_G_EDICT(OFS_PARM0);
2406 if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
2408 // FIXME: implement rotation/scaling
2409 VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
2410 clippointtosurface(model, surface, p, out);
2411 // FIXME: implement rotation/scaling
2412 VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
2415 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2416 //this function originally written by KrimZon, made shorter by LordHavoc
2417 static void VM_SV_clientcommand (void)
2419 client_t *temp_client;
2421 VM_SAFEPARMCOUNT(2, VM_SV_clientcommand);
2423 //find client for this entity
2424 i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
2425 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2427 Con_Print("PF_clientcommand: entity is not a client\n");
2431 temp_client = host_client;
2432 host_client = svs.clients + i;
2433 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2434 host_client = temp_client;
2437 //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)
2438 static void VM_SV_setattachment (void)
2440 prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
2441 prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
2442 const char *tagname = PRVM_G_STRING(OFS_PARM2);
2446 VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
2448 if (e == prog->edicts)
2450 VM_Warning("setattachment: can not modify world entity\n");
2453 if (e->priv.server->free)
2455 VM_Warning("setattachment: can not modify free entity\n");
2459 if (tagentity == NULL)
2460 tagentity = prog->edicts;
2462 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
2464 v->edict = PRVM_EDICT_TO_PROG(tagentity);
2466 v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
2469 if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
2471 modelindex = (int)tagentity->fields.server->modelindex;
2472 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
2474 v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
2476 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);
2479 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));
2483 /////////////////////////////////////////
2484 // DP_MD3_TAGINFO extension coded by VorteX
2486 int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
2491 i = (int)e->fields.server->modelindex;
2492 if (i < 1 || i >= MAX_MODELS)
2494 model = sv.models[i];
2496 return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname);
2499 int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
2508 Matrix4x4_CreateIdentity(tag_localmatrix);
2511 && (modelindex = (int)e->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2512 && (model = sv.models[(int)e->fields.server->modelindex])
2513 && model->animscenes)
2515 frame = (int)e->fields.server->frame;
2516 if (frame < 0 || frame >= model->numframes)
2519 r = Mod_Alias_GetExtendedTagInfoForIndex(model, (int)e->fields.server->skin, model->animscenes[frame].firstframe, tagindex - 1, parentindex, tagname, tag_localmatrix);
2530 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
2532 float scale = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float;
2536 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);
2538 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);
2541 int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
2547 && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS
2548 && (model = sv.models[(int)ent->fields.server->modelindex])
2549 && model->animscenes)
2551 // if model has wrong frame, engine automatically switches to model first frame
2552 frame = (int)ent->fields.server->frame;
2553 if (frame < 0 || frame >= model->numframes)
2555 return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out);
2557 *out = identitymatrix;
2561 // Warnings/errors code:
2562 // 0 - normal (everything all-right)
2565 // 3 - null or non-precached model
2566 // 4 - no tags with requested index
2567 // 5 - runaway loop at attachment chain
2568 extern cvar_t cl_bob;
2569 extern cvar_t cl_bobcycle;
2570 extern cvar_t cl_bobup;
2571 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
2575 int modelindex, attachloop;
2576 matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
2579 *out = identitymatrix; // warnings and errors return identical matrix
2581 if (ent == prog->edicts)
2583 if (ent->priv.server->free)
2586 modelindex = (int)ent->fields.server->modelindex;
2587 if (modelindex <= 0 || modelindex > MAX_MODELS)
2590 model = sv.models[modelindex];
2592 tagmatrix = identitymatrix;
2593 // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
2597 if (attachloop >= 256) // prevent runaway looping
2599 // apply transformation by child's tagindex on parent entity and then
2600 // by parent entity itself
2601 ret = SV_GetEntityLocalTagMatrix(ent, tagindex - 1, &attachmatrix);
2602 if (ret && attachloop == 0)
2604 Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
2605 SV_GetEntityMatrix(ent, &entitymatrix, false);
2606 Matrix4x4_Concat(&tagmatrix, &entitymatrix, out);
2607 // next iteration we process the parent entity
2608 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
2610 tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
2611 ent = PRVM_EDICT_NUM(val->edict);
2618 // RENDER_VIEWMODEL magic
2619 if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
2621 Matrix4x4_Copy(&tagmatrix, out);
2622 ent = PRVM_EDICT_NUM(val->edict);
2624 SV_GetEntityMatrix(ent, &entitymatrix, true);
2625 Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
2628 // Cl_bob, ported from rendering code
2629 if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
2632 // LordHavoc: this code is *weird*, but not replacable (I think it
2633 // should be done in QC on the server, but oh well, quake is quake)
2634 // LordHavoc: figured out bobup: the time at which the sin is at 180
2635 // degrees (which allows lengthening or squishing the peak or valley)
2636 cycle = sv.time/cl_bobcycle.value;
2637 cycle -= (int)cycle;
2638 if (cycle < cl_bobup.value)
2639 cycle = sin(M_PI * cycle / cl_bobup.value);
2641 cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
2642 // bob is proportional to velocity in the xy plane
2643 // (don't count Z, or jumping messes it up)
2644 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;
2645 bob = bob*0.3 + bob*0.7*cycle;
2646 Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
2653 //float(entity ent, string tagname) gettagindex;
2655 static void VM_SV_gettagindex (void)
2658 const char *tag_name;
2659 int modelindex, tag_index;
2661 VM_SAFEPARMCOUNT(2, VM_SV_gettagindex);
2663 ent = PRVM_G_EDICT(OFS_PARM0);
2664 tag_name = PRVM_G_STRING(OFS_PARM1);
2666 if (ent == prog->edicts)
2668 VM_Warning("gettagindex: can't affect world entity\n");
2671 if (ent->priv.server->free)
2673 VM_Warning("gettagindex: can't affect free entity\n");
2677 modelindex = (int)ent->fields.server->modelindex;
2679 if (modelindex <= 0 || modelindex > MAX_MODELS)
2680 Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
2683 tag_index = SV_GetTagIndex(ent, tag_name);
2685 if(developer.integer >= 100)
2686 Con_Printf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
2688 PRVM_G_FLOAT(OFS_RETURN) = tag_index;
2691 //vector(entity ent, float tagindex) gettaginfo;
2692 static void VM_SV_gettaginfo (void)
2696 matrix4x4_t tag_matrix;
2697 matrix4x4_t tag_localmatrix;
2699 const char *tagname;
2702 vec3_t fo, ri, up, trans;
2704 VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
2706 e = PRVM_G_EDICT(OFS_PARM0);
2707 tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
2709 returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
2710 Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
2711 SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
2712 Matrix4x4_ToVectors(&tag_localmatrix, fo, ri, up, trans);
2714 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
2715 val->_float = parentindex;
2716 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
2717 val->string = tagname ? PRVM_SetTempString(tagname) : 0;
2718 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
2719 VectorCopy(trans, val->vector);
2720 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
2721 VectorCopy(fo, val->vector);
2722 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
2723 VectorCopy(ri, val->vector);
2724 if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
2725 VectorCopy(up, val->vector);
2730 VM_Warning("gettagindex: can't affect world entity\n");
2733 VM_Warning("gettagindex: can't affect free entity\n");
2736 Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
2739 Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
2742 Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
2747 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
2748 static void VM_SV_dropclient (void)
2751 client_t *oldhostclient;
2752 VM_SAFEPARMCOUNT(1, VM_SV_dropclient);
2753 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2754 if (clientnum < 0 || clientnum >= svs.maxclients)
2756 VM_Warning("dropclient: not a client\n");
2759 if (!svs.clients[clientnum].active)
2761 VM_Warning("dropclient: that client slot is not connected\n");
2764 oldhostclient = host_client;
2765 host_client = svs.clients + clientnum;
2766 SV_DropClient(false);
2767 host_client = oldhostclient;
2770 //entity() spawnclient (DP_SV_BOTCLIENT)
2771 static void VM_SV_spawnclient (void)
2775 VM_SAFEPARMCOUNT(0, VM_SV_spawnclient);
2776 prog->xfunction->builtinsprofile += 2;
2778 for (i = 0;i < svs.maxclients;i++)
2780 if (!svs.clients[i].active)
2782 prog->xfunction->builtinsprofile += 100;
2783 SV_ConnectClient (i, NULL);
2784 // this has to be set or else ClientDisconnect won't be called
2785 // we assume the qc will call ClientConnect...
2786 svs.clients[i].clientconnectcalled = true;
2787 ed = PRVM_EDICT_NUM(i + 1);
2791 VM_RETURN_EDICT(ed);
2794 //float(entity clent) clienttype (DP_SV_BOTCLIENT)
2795 static void VM_SV_clienttype (void)
2798 VM_SAFEPARMCOUNT(1, VM_SV_clienttype);
2799 clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
2800 if (clientnum < 0 || clientnum >= svs.maxclients)
2801 PRVM_G_FLOAT(OFS_RETURN) = 3;
2802 else if (!svs.clients[clientnum].active)
2803 PRVM_G_FLOAT(OFS_RETURN) = 0;
2804 else if (svs.clients[clientnum].netconnection)
2805 PRVM_G_FLOAT(OFS_RETURN) = 1;
2807 PRVM_G_FLOAT(OFS_RETURN) = 2;
2814 string(string key) serverkey
2817 void VM_SV_serverkey(void)
2819 char string[VM_STRINGTEMP_LENGTH];
2820 VM_SAFEPARMCOUNT(1, VM_SV_serverkey);
2821 InfoString_GetValue(svs.serverinfo, PRVM_G_STRING(OFS_PARM0), string, sizeof(string));
2822 PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);
2825 //#333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
2826 static void VM_SV_setmodelindex (void)
2831 VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
2833 e = PRVM_G_EDICT(OFS_PARM0);
2834 if (e == prog->edicts)
2836 VM_Warning("setmodelindex: can not modify world entity\n");
2839 if (e->priv.server->free)
2841 VM_Warning("setmodelindex: can not modify free entity\n");
2844 i = (int)PRVM_G_FLOAT(OFS_PARM1);
2845 if (i <= 0 || i > MAX_MODELS)
2847 VM_Warning("setmodelindex: invalid modelindex\n");
2850 if (!sv.model_precache[i][0])
2852 VM_Warning("setmodelindex: model not precached\n");
2856 e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
2857 e->fields.server->modelindex = i;
2863 if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
2864 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
2866 SetMinMaxSize (e, quakemins, quakemaxs, true);
2869 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
2872 //#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
2873 static void VM_SV_modelnameforindex (void)
2876 VM_SAFEPARMCOUNT(1, VM_SV_modelnameforindex);
2878 PRVM_G_INT(OFS_RETURN) = OFS_NULL;
2880 i = (int)PRVM_G_FLOAT(OFS_PARM0);
2881 if (i <= 0 || i > MAX_MODELS)
2883 VM_Warning("modelnameforindex: invalid modelindex\n");
2886 if (!sv.model_precache[i][0])
2888 VM_Warning("modelnameforindex: model not precached\n");
2892 PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(sv.model_precache[i]);
2895 //#335 float(string effectname) particleeffectnum (EXT_CSQC)
2896 static void VM_SV_particleeffectnum (void)
2899 VM_SAFEPARMCOUNT(1, VM_SV_particleeffectnum);
2900 i = SV_ParticleEffectIndex(PRVM_G_STRING(OFS_PARM0));
2903 PRVM_G_FLOAT(OFS_RETURN) = i;
2906 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
2907 static void VM_SV_trailparticles (void)
2909 VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
2911 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2914 MSG_WriteByte(&sv.datagram, svc_trailparticles);
2915 MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
2916 MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
2917 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
2918 MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
2919 SV_FlushBroadcastMessages();
2922 //#337 void(float effectnum, vector origin, vector dir, float count) pointparticles (EXT_CSQC)
2923 static void VM_SV_pointparticles (void)
2925 int effectnum, count;
2927 VM_SAFEPARMCOUNTRANGE(4, 8, VM_SV_pointparticles);
2929 if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
2932 effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
2933 VectorCopy(PRVM_G_VECTOR(OFS_PARM1), org);
2934 VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
2935 count = bound(0, (int)PRVM_G_FLOAT(OFS_PARM3), 65535);
2936 if (count == 1 && !VectorLength2(vel))
2939 MSG_WriteByte(&sv.datagram, svc_pointparticles1);
2940 MSG_WriteShort(&sv.datagram, effectnum);
2941 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2945 // 1+2+12+12+2=29 bytes
2946 MSG_WriteByte(&sv.datagram, svc_pointparticles);
2947 MSG_WriteShort(&sv.datagram, effectnum);
2948 MSG_WriteVector(&sv.datagram, org, sv.protocol);
2949 MSG_WriteVector(&sv.datagram, vel, sv.protocol);
2950 MSG_WriteShort(&sv.datagram, count);
2953 SV_FlushBroadcastMessages();
2956 prvm_builtin_t vm_sv_builtins[] = {
2957 NULL, // #0 NULL function (not callable) (QUAKE)
2958 VM_makevectors, // #1 void(vector ang) makevectors (QUAKE)
2959 VM_SV_setorigin, // #2 void(entity e, vector o) setorigin (QUAKE)
2960 VM_SV_setmodel, // #3 void(entity e, string m) setmodel (QUAKE)
2961 VM_SV_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE)
2962 NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
2963 VM_break, // #6 void() break (QUAKE)
2964 VM_random, // #7 float() random (QUAKE)
2965 VM_SV_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE)
2966 VM_normalize, // #9 vector(vector v) normalize (QUAKE)
2967 VM_error, // #10 void(string e) error (QUAKE)
2968 VM_objerror, // #11 void(string e) objerror (QUAKE)
2969 VM_vlen, // #12 float(vector v) vlen (QUAKE)
2970 VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
2971 VM_spawn, // #14 entity() spawn (QUAKE)
2972 VM_remove, // #15 void(entity e) remove (QUAKE)
2973 VM_SV_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
2974 VM_SV_checkclient, // #17 entity() checkclient (QUAKE)
2975 VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
2976 VM_SV_precache_sound, // #19 void(string s) precache_sound (QUAKE)
2977 VM_SV_precache_model, // #20 void(string s) precache_model (QUAKE)
2978 VM_SV_stuffcmd, // #21 void(entity client, string s, ...) stuffcmd (QUAKE)
2979 VM_SV_findradius, // #22 entity(vector org, float rad) findradius (QUAKE)
2980 VM_bprint, // #23 void(string s, ...) bprint (QUAKE)
2981 VM_SV_sprint, // #24 void(entity client, string s, ...) sprint (QUAKE)
2982 VM_dprint, // #25 void(string s, ...) dprint (QUAKE)
2983 VM_ftos, // #26 string(float f) ftos (QUAKE)
2984 VM_vtos, // #27 string(vector v) vtos (QUAKE)
2985 VM_coredump, // #28 void() coredump (QUAKE)
2986 VM_traceon, // #29 void() traceon (QUAKE)
2987 VM_traceoff, // #30 void() traceoff (QUAKE)
2988 VM_eprint, // #31 void(entity e) eprint (QUAKE)
2989 VM_SV_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
2990 NULL, // #33 (QUAKE)
2991 VM_SV_droptofloor, // #34 float() droptofloor (QUAKE)
2992 VM_SV_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
2993 VM_rint, // #36 float(float v) rint (QUAKE)
2994 VM_floor, // #37 float(float v) floor (QUAKE)
2995 VM_ceil, // #38 float(float v) ceil (QUAKE)
2996 NULL, // #39 (QUAKE)
2997 VM_SV_checkbottom, // #40 float(entity e) checkbottom (QUAKE)
2998 VM_SV_pointcontents, // #41 float(vector v) pointcontents (QUAKE)
2999 NULL, // #42 (QUAKE)
3000 VM_fabs, // #43 float(float f) fabs (QUAKE)
3001 VM_SV_aim, // #44 vector(entity e, float speed) aim (QUAKE)
3002 VM_cvar, // #45 float(string s) cvar (QUAKE)
3003 VM_localcmd, // #46 void(string s) localcmd (QUAKE)
3004 VM_nextent, // #47 entity(entity e) nextent (QUAKE)
3005 VM_SV_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
3006 VM_changeyaw, // #49 void() ChangeYaw (QUAKE)
3007 NULL, // #50 (QUAKE)
3008 VM_vectoangles, // #51 vector(vector v) vectoangles (QUAKE)
3009 VM_SV_WriteByte, // #52 void(float to, float f) WriteByte (QUAKE)
3010 VM_SV_WriteChar, // #53 void(float to, float f) WriteChar (QUAKE)
3011 VM_SV_WriteShort, // #54 void(float to, float f) WriteShort (QUAKE)
3012 VM_SV_WriteLong, // #55 void(float to, float f) WriteLong (QUAKE)
3013 VM_SV_WriteCoord, // #56 void(float to, float f) WriteCoord (QUAKE)
3014 VM_SV_WriteAngle, // #57 void(float to, float f) WriteAngle (QUAKE)
3015 VM_SV_WriteString, // #58 void(float to, string s) WriteString (QUAKE)
3016 VM_SV_WriteEntity, // #59 void(float to, entity e) WriteEntity (QUAKE)
3017 VM_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW) (QUAKE)
3018 VM_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW) (QUAKE)
3019 VM_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW) (QUAKE)
3020 VM_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) (QUAKE)
3021 VM_SV_tracetoss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS) (QUAKE)
3022 VM_etos, // #65 string(entity ent) etos (DP_QC_ETOS) (QUAKE)
3023 NULL, // #66 (QUAKE)
3024 SV_MoveToGoal, // #67 void(float step) movetogoal (QUAKE)
3025 VM_precache_file, // #68 string(string s) precache_file (QUAKE)
3026 VM_SV_makestatic, // #69 void(entity e) makestatic (QUAKE)
3027 VM_changelevel, // #70 void(string s) changelevel (QUAKE)
3028 NULL, // #71 (QUAKE)
3029 VM_cvar_set, // #72 void(string var, string val) cvar_set (QUAKE)
3030 VM_SV_centerprint, // #73 void(entity client, strings) centerprint (QUAKE)
3031 VM_SV_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound (QUAKE)
3032 VM_SV_precache_model, // #75 string(string s) precache_model2 (QUAKE)
3033 VM_SV_precache_sound, // #76 string(string s) precache_sound2 (QUAKE)
3034 VM_precache_file, // #77 string(string s) precache_file2 (QUAKE)
3035 VM_SV_setspawnparms, // #78 void(entity e) setspawnparms (QUAKE)
3036 NULL, // #79 void(entity killer, entity killee) logfrag (QUAKEWORLD)
3037 NULL, // #80 string(entity e, string keyname) infokey (QUAKEWORLD)
3038 VM_stof, // #81 float(string s) stof (FRIK_FILE)
3039 NULL, // #82 void(vector where, float set) multicast (QUAKEWORLD)
3040 NULL, // #83 (QUAKE)
3041 NULL, // #84 (QUAKE)
3042 NULL, // #85 (QUAKE)
3043 NULL, // #86 (QUAKE)
3044 NULL, // #87 (QUAKE)
3045 NULL, // #88 (QUAKE)
3046 NULL, // #89 (QUAKE)
3047 VM_SV_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
3048 VM_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
3049 VM_SV_getlight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
3050 VM_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
3051 VM_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
3052 VM_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3053 VM_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3054 VM_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3055 VM_findfloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3056 VM_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3057 // FrikaC and Telejano range #100-#199
3068 VM_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3069 VM_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3070 VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3071 VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3072 VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
3073 VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
3074 VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3075 VM_stov, // #117 vector(string) stov (FRIK_FILE)
3076 VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
3077 VM_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3158 // FTEQW range #200-#299
3177 VM_bitshift, // #218 float(float number, float quantity) bitshift (EXT_BITSHIFT)
3180 VM_strstrofs, // #221 float(string str, string sub[, float startpos]) strstrofs (FTE_STRINGS)
3181 VM_str2chr, // #222 float(string str, float ofs) str2chr (FTE_STRINGS)
3182 VM_chr2str, // #223 string(float c, ...) chr2str (FTE_STRINGS)
3183 VM_strconv, // #224 string(float ccase, float calpha, float cnum, string s, ...) strconv (FTE_STRINGS)
3184 VM_strpad, // #225 string(float chars, string s, ...) strpad (FTE_STRINGS)
3185 VM_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
3186 VM_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
3187 VM_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
3188 VM_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
3189 VM_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
3191 VM_SV_AddStat, // #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
3259 // CSQC range #300-#399
3260 NULL, // #300 void() clearscene (EXT_CSQC)
3261 NULL, // #301 void(float mask) addentities (EXT_CSQC)
3262 NULL, // #302 void(entity ent) addentity (EXT_CSQC)
3263 NULL, // #303 float(float property, ...) setproperty (EXT_CSQC)
3264 NULL, // #304 void() renderscene (EXT_CSQC)
3265 NULL, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
3266 NULL, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
3267 NULL, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
3268 NULL, // #308 void() R_EndPolygon
3270 NULL, // #310 vector (vector v) cs_unproject (EXT_CSQC)
3271 NULL, // #311 vector (vector v) cs_project (EXT_CSQC)
3275 NULL, // #315 void(float width, vector pos1, vector pos2, float flag) drawline (EXT_CSQC)
3276 NULL, // #316 float(string name) iscachedpic (EXT_CSQC)
3277 NULL, // #317 string(string name, float trywad) precache_pic (EXT_CSQC)
3278 NULL, // #318 vector(string picname) draw_getimagesize (EXT_CSQC)
3279 NULL, // #319 void(string name) freepic (EXT_CSQC)
3280 NULL, // #320 float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter (EXT_CSQC)
3281 NULL, // #321 float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring (EXT_CSQC)
3282 NULL, // #322 float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic (EXT_CSQC)
3283 NULL, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC)
3284 NULL, // #324 void(float x, float y, float width, float height) drawsetcliparea
3285 NULL, // #325 void(void) drawresetcliparea
3290 NULL, // #330 float(float stnum) getstatf (EXT_CSQC)
3291 NULL, // #331 float(float stnum) getstati (EXT_CSQC)
3292 NULL, // #332 string(float firststnum) getstats (EXT_CSQC)
3293 VM_SV_setmodelindex, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
3294 VM_SV_modelnameforindex, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
3295 VM_SV_particleeffectnum, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
3296 VM_SV_trailparticles, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
3297 VM_SV_pointparticles, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
3298 NULL, // #338 void(string s, ...) centerprint (EXT_CSQC)
3299 VM_print, // #339 void(string s, ...) print (EXT_CSQC, DP_SV_PRINT)
3300 NULL, // #340 string(float keynum) keynumtostring (EXT_CSQC)
3301 NULL, // #341 float(string keyname) stringtokeynum (EXT_CSQC)
3302 NULL, // #342 string(float keynum) getkeybind (EXT_CSQC)
3303 NULL, // #343 void(float usecursor) setcursormode (EXT_CSQC)
3304 NULL, // #344 vector() getmousepos (EXT_CSQC)
3305 NULL, // #345 float(float framenum) getinputstate (EXT_CSQC)
3306 NULL, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
3307 NULL, // #347 void() runstandardplayerphysics (EXT_CSQC)
3308 NULL, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
3309 NULL, // #349 float() isdemo (EXT_CSQC)
3310 VM_isserver, // #350 float() isserver (EXT_CSQC)
3311 NULL, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
3312 NULL, // #352 void(string cmdname) registercommand (EXT_CSQC)
3313 VM_wasfreed, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
3314 VM_SV_serverkey, // #354 string(string key) serverkey (EXT_CSQC)
3320 NULL, // #360 float() readbyte (EXT_CSQC)
3321 NULL, // #361 float() readchar (EXT_CSQC)
3322 NULL, // #362 float() readshort (EXT_CSQC)
3323 NULL, // #363 float() readlong (EXT_CSQC)
3324 NULL, // #364 float() readcoord (EXT_CSQC)
3325 NULL, // #365 float() readangle (EXT_CSQC)
3326 NULL, // #366 string() readstring (EXT_CSQC)
3327 NULL, // #367 float() readfloat (EXT_CSQC)
3360 // LordHavoc's range #400-#499
3361 VM_SV_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3362 VM_SV_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3363 VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3364 VM_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3365 VM_SV_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3366 VM_SV_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3367 VM_SV_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3368 VM_SV_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3369 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)
3370 VM_SV_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3371 VM_SV_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3372 VM_SV_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3373 VM_SV_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3374 VM_SV_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3375 VM_SV_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3376 VM_SV_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3377 VM_SV_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3378 VM_SV_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3379 VM_SV_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3380 VM_SV_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3381 VM_SV_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3382 VM_SV_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3383 VM_SV_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3384 VM_SV_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3385 VM_SV_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3386 VM_SV_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3387 VM_SV_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3388 VM_SV_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3389 VM_SV_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3390 VM_SV_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3391 VM_SV_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3392 VM_SV_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3393 VM_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3394 VM_SV_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3395 VM_SV_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3396 VM_SV_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3397 VM_SV_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3398 VM_SV_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3399 VM_SV_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3400 VM_SV_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3401 VM_SV_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3402 VM_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3403 VM_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3404 VM_SV_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3405 VM_search_begin, // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_QC_FS_SEARCH)
3406 VM_search_end, // #445 void(float handle) search_end (DP_QC_FS_SEARCH)
3407 VM_search_getsize, // #446 float(float handle) search_getsize (DP_QC_FS_SEARCH)
3408 VM_search_getfilename, // #447 string(float handle, float num) search_getfilename (DP_QC_FS_SEARCH)
3409 VM_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3410 VM_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3411 VM_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3412 VM_SV_gettagindex, // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
3413 VM_SV_gettaginfo, // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
3414 VM_SV_dropclient, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
3415 VM_SV_spawnclient, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
3416 VM_SV_clienttype, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
3417 VM_SV_WriteUnterminatedString, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
3418 VM_SV_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
3420 VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
3421 VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
3422 VM_buf_del, // #461 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS)
3423 VM_buf_getsize, // #462 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS)
3424 VM_buf_copy, // #463 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS)
3425 VM_buf_sort, // #464 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS)
3426 VM_buf_implode, // #465 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS)
3427 VM_bufstr_get, // #466 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS)
3428 VM_bufstr_set, // #467 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS)
3429 VM_bufstr_add, // #468 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS)
3430 VM_bufstr_free, // #469 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
3432 VM_asin, // #471 float(float s) VM_asin (DP_QC_ASINACOSATANATAN2TAN)
3433 VM_acos, // #472 float(float c) VM_acos (DP_QC_ASINACOSATANATAN2TAN)
3434 VM_atan, // #473 float(float t) VM_atan (DP_QC_ASINACOSATANATAN2TAN)
3435 VM_atan2, // #474 float(float c, float s) VM_atan2 (DP_QC_ASINACOSATANATAN2TAN)
3436 VM_tan, // #475 float(float a) VM_tan (DP_QC_ASINACOSATANATAN2TAN)
3437 VM_strlennocol, // #476 float(string s) : DRESK - String Length (not counting color codes) (DP_QC_STRINGCOLORFUNCTIONS)
3438 VM_strdecolorize, // #477 string(string s) : DRESK - Decolorized String (DP_SV_STRINGCOLORFUNCTIONS)
3439 VM_strftime, // #478 string(float uselocaltime, string format, ...) (DP_QC_STRFTIME)
3440 VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOKENIZEBYSEPARATOR)
3441 VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
3442 VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
3443 VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
3444 VM_SV_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
3445 VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
3446 VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
3447 VM_SV_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
3455 VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
3456 VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
3457 VM_numentityfields, // #496 float() numentityfields = #496; (DP_QC_ENTITYDATA)
3458 VM_entityfieldname, // #497 string(float fieldnum) entityfieldname = #497; (DP_QC_ENTITYDATA)
3459 VM_entityfieldtype, // #498 float(float fieldnum) entityfieldtype = #498; (DP_QC_ENTITYDATA)
3460 VM_getentityfieldstring, // #499 string(float fieldnum, entity ent) getentityfieldstring = #499; (DP_QC_ENTITYDATA)
3461 VM_putentityfieldstring, // #500 float(float fieldnum, entity ent, string s) putentityfieldstring = #500; (DP_QC_ENTITYDATA)
3462 VM_SV_WritePicture, // #501
3464 VM_whichpack, // #503 string(string) whichpack = #503;
3471 VM_uri_escape, // #510 string(string in) uri_escape = #510;
3472 VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
3473 VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
3474 VM_uri_get, // #513 float(string uril, float id) uri_get = #513; (DP_QC_URI_GET)
3475 VM_tokenize_console, // #514 float(string str) tokenize_console = #514; (DP_QC_TOKENIZE_CONSOLE)
3476 VM_argv_start_index, // #515 float(float idx) argv_start_index = #515; (DP_QC_TOKENIZE_CONSOLE)
3477 VM_argv_end_index, // #516 float(float idx) argv_end_index = #516; (DP_QC_TOKENIZE_CONSOLE)
3478 VM_buf_cvarlist, // #517 void(float buf, string prefix, string antiprefix) buf_cvarlist = #517; (DP_QC_STRINGBUFFERS_CVARLIST)
3479 VM_cvar_description, // #518 float(string name) cvar_description = #518; (DP_QC_CVAR_DESCRIPTION)
3483 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
3485 void VM_SV_Cmd_Init(void)
3490 void VM_SV_Cmd_Reset(void)
3492 if(prog->funcoffsets.SV_Shutdown)
3494 func_t s = prog->funcoffsets.SV_Shutdown;
3495 prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
3496 PRVM_ExecuteProgram(s,"SV_Shutdown() required");