2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 cvar_t sv_aim = {CVAR_SAVE, "sv_aim", "2"}; //"0.93"}; // LordHavoc: disabled autoaim by default
25 #define RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e))
29 ===============================================================================
33 ===============================================================================
37 char *PF_VarString (int first)
40 static char out[4096]; // FIXME: buffer overflow potential
43 for (i = first;i < pr_argc;i++)
44 strcat (out, G_STRING((OFS_PARM0+i*3)));
48 char *ENGINE_EXTENSIONS = "\
51 DP_ENT_DELTACOMPRESS \
64 DP_QC_FINDCHAINFLOAT \
76 DP_SV_DRAWONLYTOCLIENT \
78 DP_SV_EXTERIORMODELTOCLIENT \
79 DP_SV_NODRAWTOCLIENT \
92 qboolean checkextension(char *name)
97 for (e = ENGINE_EXTENSIONS;*e;e++)
104 while (*e && *e != ' ')
106 if (e - start == len)
107 if (!strncasecmp(start, name, len))
117 returns true if the extension is supported by the server
119 checkextension(extensionname)
122 void PF_checkextension (void)
124 G_FLOAT(OFS_RETURN) = checkextension(G_STRING(OFS_PARM0));
131 This is a TERMINAL error, which will kill off the entire server.
143 Con_Printf ("======SERVER ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
144 ed = PROG_TO_EDICT(pr_global_struct->self);
147 Host_Error ("Program error");
154 Dumps out self, then an error message. The program is aborted and self is
155 removed, but the level can continue.
160 void PF_objerror (void)
166 Con_Printf ("======OBJECT ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
167 ed = PROG_TO_EDICT(pr_global_struct->self);
177 Writes new values for v_forward, v_up, and v_right based on angles
181 void PF_makevectors (void)
183 AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
190 Writes new values for v_forward, v_up, and v_right based on the given forward vector
191 vectorvectors(vector, vector)
194 void PF_vectorvectors (void)
196 VectorNormalize2(G_VECTOR(OFS_PARM0), pr_global_struct->v_forward);
197 VectorVectors(pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
204 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.
206 setorigin (entity, origin)
209 void PF_setorigin (void)
214 e = G_EDICT(OFS_PARM0);
215 org = G_VECTOR(OFS_PARM1);
216 VectorCopy (org, e->v.origin);
217 SV_LinkEdict (e, false);
221 void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
225 for (i=0 ; i<3 ; i++)
227 PR_RunError ("backwards mins/maxs");
229 // set derived values
230 VectorCopy (min, e->v.mins);
231 VectorCopy (max, e->v.maxs);
232 VectorSubtract (max, min, e->v.size);
234 SV_LinkEdict (e, false);
241 the size box is rotated by the current angle
242 LordHavoc: no it isn't...
244 setsize (entity, minvector, maxvector)
247 void PF_setsize (void)
252 e = G_EDICT(OFS_PARM0);
253 min = G_VECTOR(OFS_PARM1);
254 max = G_VECTOR(OFS_PARM2);
255 SetMinMaxSize (e, min, max, false);
263 setmodel(entity, model)
266 void PF_setmodel (void)
273 e = G_EDICT(OFS_PARM0);
274 m = G_STRING(OFS_PARM1);
276 // check to see if model was properly precached
277 for (i=0, check = sv.model_precache ; *check ; i++, check++)
278 if (!strcmp(*check, m))
282 PR_RunError ("no precache: %s\n", m);
285 e->v.model = m - pr_strings;
288 mod = sv.models[ (int)e->v.modelindex];
291 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
293 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
300 broadcast print to everyone on server
305 void PF_bprint (void)
310 SV_BroadcastPrintf ("%s", s);
317 single print to a specific client
319 sprint(clientent, value)
322 void PF_sprint (void)
328 entnum = G_EDICTNUM(OFS_PARM0);
331 if (entnum < 1 || entnum > svs.maxclients)
333 Con_Printf ("tried to sprint to a non-client\n");
337 client = &svs.clients[entnum-1];
339 MSG_WriteChar (&client->message,svc_print);
340 MSG_WriteString (&client->message, s );
348 single print to a specific client
350 centerprint(clientent, value)
353 void PF_centerprint (void)
359 entnum = G_EDICTNUM(OFS_PARM0);
362 if (entnum < 1 || entnum > svs.maxclients)
364 Con_Printf ("tried to sprint to a non-client\n");
368 client = &svs.clients[entnum-1];
370 MSG_WriteChar (&client->message,svc_centerprint);
371 MSG_WriteString (&client->message, s );
379 vector normalize(vector)
382 void PF_normalize (void)
388 value1 = G_VECTOR(OFS_PARM0);
390 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
394 newvalue[0] = newvalue[1] = newvalue[2] = 0;
398 newvalue[0] = value1[0] * new;
399 newvalue[1] = value1[1] * new;
400 newvalue[2] = value1[2] * new;
403 VectorCopy (newvalue, G_VECTOR(OFS_RETURN));
418 value1 = G_VECTOR(OFS_PARM0);
420 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
423 G_FLOAT(OFS_RETURN) = new;
430 float vectoyaw(vector)
433 void PF_vectoyaw (void)
438 value1 = G_VECTOR(OFS_PARM0);
440 if (value1[1] == 0 && value1[0] == 0)
444 yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
449 G_FLOAT(OFS_RETURN) = yaw;
457 vector vectoangles(vector)
460 void PF_vectoangles (void)
466 value1 = G_VECTOR(OFS_PARM0);
468 if (value1[1] == 0 && value1[0] == 0)
478 // LordHavoc: optimized a bit
481 yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
485 else if (value1[1] > 0)
490 forward = sqrt(value1[0]*value1[0] + value1[1]*value1[1]);
491 pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
496 G_FLOAT(OFS_RETURN+0) = pitch;
497 G_FLOAT(OFS_RETURN+1) = yaw;
498 G_FLOAT(OFS_RETURN+2) = 0;
505 Returns a number from 0<= num < 1
510 void PF_random (void)
514 num = (rand ()&0x7fff) / ((float)0x7fff);
516 G_FLOAT(OFS_RETURN) = num;
523 particle(origin, color, count)
526 void PF_particle (void)
532 org = G_VECTOR(OFS_PARM0);
533 dir = G_VECTOR(OFS_PARM1);
534 color = G_FLOAT(OFS_PARM2);
535 count = G_FLOAT(OFS_PARM3);
536 SV_StartParticle (org, dir, color, count);
546 void PF_ambientsound (void)
551 float vol, attenuation;
552 int i, soundnum, large;
554 pos = G_VECTOR (OFS_PARM0);
555 samp = G_STRING(OFS_PARM1);
556 vol = G_FLOAT(OFS_PARM2);
557 attenuation = G_FLOAT(OFS_PARM3);
559 // check to see if samp was properly precached
560 for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++)
561 if (!strcmp(*check,samp))
566 Con_Printf ("no precache: %s\n", samp);
574 // add an svc_spawnambient command to the level signon packet
577 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
579 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
581 for (i=0 ; i<3 ; i++)
582 MSG_WriteDPCoord(&sv.signon, pos[i]);
585 MSG_WriteShort (&sv.signon, soundnum);
587 MSG_WriteByte (&sv.signon, soundnum);
589 MSG_WriteByte (&sv.signon, vol*255);
590 MSG_WriteByte (&sv.signon, attenuation*64);
598 Each entity can have eight independant sound sources, like voice,
601 Channel 0 is an auto-allocate channel, the others override anything
602 already running on that entity/channel pair.
604 An attenuation of 0 will play full volume everywhere in the level.
605 Larger attenuations will drop off.
617 entity = G_EDICT(OFS_PARM0);
618 channel = G_FLOAT(OFS_PARM1);
619 sample = G_STRING(OFS_PARM2);
620 volume = G_FLOAT(OFS_PARM3) * 255;
621 attenuation = G_FLOAT(OFS_PARM4);
623 if (volume < 0 || volume > 255)
624 Host_Error ("SV_StartSound: volume = %i", volume);
626 if (attenuation < 0 || attenuation > 4)
627 Host_Error ("SV_StartSound: attenuation = %f", attenuation);
629 if (channel < 0 || channel > 7)
630 Host_Error ("SV_StartSound: channel = %i", channel);
632 SV_StartSound (entity, channel, sample, volume, attenuation);
644 PR_RunError ("break statement");
651 Used for use tracing and shot targeting
652 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
653 if the tryents flag is set.
655 traceline (vector1, vector2, tryents)
658 void PF_traceline (void)
665 v1 = G_VECTOR(OFS_PARM0);
666 v2 = G_VECTOR(OFS_PARM1);
667 nomonsters = G_FLOAT(OFS_PARM2);
668 ent = G_EDICT(OFS_PARM3);
670 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters ? MOVE_NOMONSTERS : MOVE_NORMAL, ent);
672 pr_global_struct->trace_allsolid = trace.allsolid;
673 pr_global_struct->trace_startsolid = trace.startsolid;
674 pr_global_struct->trace_fraction = trace.fraction;
675 pr_global_struct->trace_inwater = trace.inwater;
676 pr_global_struct->trace_inopen = trace.inopen;
677 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
678 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
679 pr_global_struct->trace_plane_dist = trace.plane.dist;
681 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
683 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
684 // FIXME: add trace_endcontents
692 Used for use tracing and shot targeting
693 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
694 if the tryents flag is set.
696 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
699 // LordHavoc: added this for my own use, VERY useful, similar to traceline
700 void PF_tracebox (void)
702 float *v1, *v2, *m1, *m2;
707 v1 = G_VECTOR(OFS_PARM0);
708 m1 = G_VECTOR(OFS_PARM1);
709 m2 = G_VECTOR(OFS_PARM2);
710 v2 = G_VECTOR(OFS_PARM3);
711 nomonsters = G_FLOAT(OFS_PARM4);
712 ent = G_EDICT(OFS_PARM5);
714 trace = SV_Move (v1, m1, m2, v2, nomonsters ? MOVE_NOMONSTERS : MOVE_NORMAL, ent);
716 pr_global_struct->trace_allsolid = trace.allsolid;
717 pr_global_struct->trace_startsolid = trace.startsolid;
718 pr_global_struct->trace_fraction = trace.fraction;
719 pr_global_struct->trace_inwater = trace.inwater;
720 pr_global_struct->trace_inopen = trace.inopen;
721 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
722 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
723 pr_global_struct->trace_plane_dist = trace.plane.dist;
725 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
727 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
730 extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore);
731 void PF_TraceToss (void)
737 ent = G_EDICT(OFS_PARM0);
738 ignore = G_EDICT(OFS_PARM1);
740 trace = SV_Trace_Toss (ent, ignore);
742 pr_global_struct->trace_allsolid = trace.allsolid;
743 pr_global_struct->trace_startsolid = trace.startsolid;
744 pr_global_struct->trace_fraction = trace.fraction;
745 pr_global_struct->trace_inwater = trace.inwater;
746 pr_global_struct->trace_inopen = trace.inopen;
747 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
748 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
749 pr_global_struct->trace_plane_dist = trace.plane.dist;
751 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
753 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
761 Returns true if the given entity can move to the given position from it's
762 current position by walking or rolling.
764 scalar checkpos (entity, vector)
767 void PF_checkpos (void)
771 //============================================================================
773 qbyte checkpvs[MAX_MAP_LEAFS/8];
775 int PF_newcheckclient (int check)
783 // cycle to the next one
787 if (check > svs.maxclients)
788 check = svs.maxclients;
790 if (check == svs.maxclients)
797 if (i == svs.maxclients+1)
803 break; // didn't find anything else
807 if (ent->v.health <= 0)
809 if ((int)ent->v.flags & FL_NOTARGET)
812 // anything that is a client, or has a client as an enemy
816 // get the PVS for the entity
817 VectorAdd (ent->v.origin, ent->v.view_ofs, org);
818 leaf = Mod_PointInLeaf (org, sv.worldmodel);
819 pvs = Mod_LeafPVS (leaf, sv.worldmodel);
820 memcpy (checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 );
829 Returns a client (or object that has a client enemy) that would be a
832 If there is more than one valid option, they are cycled each frame
834 If (self.origin + self.viewofs) is not in the PVS of the current target,
835 it is not returned at all.
840 int c_invis, c_notvis;
841 void PF_checkclient (void)
848 // find a new check if on a new frame
849 if (sv.time - sv.lastchecktime >= 0.1)
851 sv.lastcheck = PF_newcheckclient (sv.lastcheck);
852 sv.lastchecktime = sv.time;
855 // return check if it might be visible
856 ent = EDICT_NUM(sv.lastcheck);
857 if (ent->free || ent->v.health <= 0)
859 RETURN_EDICT(sv.edicts);
863 // if current entity can't possibly see the check entity, return 0
864 self = PROG_TO_EDICT(pr_global_struct->self);
865 VectorAdd (self->v.origin, self->v.view_ofs, view);
866 leaf = Mod_PointInLeaf (view, sv.worldmodel);
867 l = (leaf - sv.worldmodel->leafs) - 1;
868 if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
871 RETURN_EDICT(sv.edicts);
875 // might be able to see it
880 //============================================================================
887 Sends text over to the client's execution buffer
889 stuffcmd (clientent, value)
892 void PF_stuffcmd (void)
898 entnum = G_EDICTNUM(OFS_PARM0);
899 if (entnum < 1 || entnum > svs.maxclients)
900 PR_RunError ("Parm 0 not a client");
901 str = G_STRING(OFS_PARM1);
904 host_client = &svs.clients[entnum-1];
905 Host_ClientCommands ("%s", str);
913 Sends text over to the client's execution buffer
918 void PF_localcmd (void)
922 str = G_STRING(OFS_PARM0);
937 str = G_STRING(OFS_PARM0);
939 G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str);
949 void PF_cvar_set (void)
953 var = G_STRING(OFS_PARM0);
954 val = G_STRING(OFS_PARM1);
963 Returns a chain of entities that have origins within a spherical area
965 findradius (origin, radius)
968 void PF_findradius (void)
970 edict_t *ent, *chain;
977 chain = (edict_t *)sv.edicts;
979 org = G_VECTOR(OFS_PARM0);
980 radius = G_FLOAT(OFS_PARM1);
981 radius2 = radius * radius;
983 ent = NEXT_EDICT(sv.edicts);
984 for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
988 if (ent->v.solid == SOLID_NOT)
991 // LordHavoc: compare against bounding box rather than center,
992 // and use DotProduct instead of Length, major speedup
993 eorg[0] = (org[0] - ent->v.origin[0]) - bound(ent->v.mins[0], (org[0] - ent->v.origin[0]), ent->v.maxs[0]);
994 eorg[1] = (org[1] - ent->v.origin[1]) - bound(ent->v.mins[1], (org[1] - ent->v.origin[1]), ent->v.maxs[1]);
995 eorg[2] = (org[2] - ent->v.origin[2]) - bound(ent->v.mins[2], (org[2] - ent->v.origin[2]), ent->v.maxs[2]);
996 if (DotProduct(eorg, eorg) > radius2)
999 ent->v.chain = EDICT_TO_PROG(chain);
1003 RETURN_EDICT(chain);
1012 void PF_dprint (void)
1014 Con_DPrintf ("%s",PF_VarString(0));
1017 // LordHavoc: added this to semi-fix the problem of using many ftos calls in a print
1018 #define STRINGTEMP_BUFFERS 16
1019 #define STRINGTEMP_LENGTH 128
1020 static char pr_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH];
1021 static int pr_string_tempindex = 0;
1023 static char *PR_GetTempString(void)
1026 s = pr_string_temp[pr_string_tempindex];
1027 pr_string_tempindex = (pr_string_tempindex + 1) % STRINGTEMP_BUFFERS;
1035 v = G_FLOAT(OFS_PARM0);
1037 s = PR_GetTempString();
1038 // LordHavoc: ftos improvement
1039 sprintf (s, "%g", v);
1040 G_INT(OFS_RETURN) = s - pr_strings;
1046 v = G_FLOAT(OFS_PARM0);
1047 G_FLOAT(OFS_RETURN) = fabs(v);
1053 s = PR_GetTempString();
1054 sprintf (s, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
1055 G_INT(OFS_RETURN) = s - pr_strings;
1061 s = PR_GetTempString();
1062 sprintf (s, "entity %i", G_EDICTNUM(OFS_PARM0));
1063 G_INT(OFS_RETURN) = s - pr_strings;
1066 void PF_Spawn (void)
1073 void PF_Remove (void)
1077 ed = G_EDICT(OFS_PARM0);
1078 if (ed == sv.edicts)
1079 PR_RunError("remove: tried to remove world\n");
1080 if (NUM_FOR_EDICT(ed) <= svs.maxclients)
1081 PR_RunError("remove: tried to remove a client\n");
1086 // entity (entity start, .string field, string match) find = #5;
1094 e = G_EDICTNUM(OFS_PARM0);
1095 f = G_INT(OFS_PARM1);
1096 s = G_STRING(OFS_PARM2);
1099 RETURN_EDICT(sv.edicts);
1103 for (e++ ; e < sv.num_edicts ; e++)
1118 RETURN_EDICT(sv.edicts);
1121 // LordHavoc: added this for searching float, int, and entity reference fields
1122 void PF_FindFloat (void)
1129 e = G_EDICTNUM(OFS_PARM0);
1130 f = G_INT(OFS_PARM1);
1131 s = G_FLOAT(OFS_PARM2);
1133 for (e++ ; e < sv.num_edicts ; e++)
1138 if (E_FLOAT(ed,f) == s)
1145 RETURN_EDICT(sv.edicts);
1148 // chained search for strings in entity fields
1149 // entity(.string field, string match) findchain = #402;
1150 void PF_findchain (void)
1155 edict_t *ent, *chain;
1157 chain = (edict_t *)sv.edicts;
1159 f = G_INT(OFS_PARM0);
1160 s = G_STRING(OFS_PARM1);
1163 RETURN_EDICT(sv.edicts);
1167 ent = NEXT_EDICT(sv.edicts);
1168 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1172 t = E_STRING(ent,f);
1178 ent->v.chain = EDICT_TO_PROG(chain);
1182 RETURN_EDICT(chain);
1185 // LordHavoc: chained search for float, int, and entity reference fields
1186 // entity(.string field, float match) findchainfloat = #403;
1187 void PF_findchainfloat (void)
1192 edict_t *ent, *chain;
1194 chain = (edict_t *)sv.edicts;
1196 f = G_INT(OFS_PARM0);
1197 s = G_FLOAT(OFS_PARM1);
1199 ent = NEXT_EDICT(sv.edicts);
1200 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1204 if (E_FLOAT(ent,f) != s)
1207 ent->v.chain = EDICT_TO_PROG(chain);
1211 RETURN_EDICT(chain);
1214 void PR_CheckEmptyString (char *s)
1217 PR_RunError ("Bad string");
1220 void PF_precache_file (void)
1221 { // precache_file is only used to copy files with qcc, it does nothing
1222 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1225 void PF_precache_sound (void)
1230 if (sv.state != ss_loading)
1231 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1233 s = G_STRING(OFS_PARM0);
1234 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1235 PR_CheckEmptyString (s);
1237 for (i=0 ; i<MAX_SOUNDS ; i++)
1239 if (!sv.sound_precache[i])
1241 sv.sound_precache[i] = s;
1244 if (!strcmp(sv.sound_precache[i], s))
1247 PR_RunError ("PF_precache_sound: overflow");
1250 void PF_precache_model (void)
1255 if (sv.state != ss_loading)
1256 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1258 s = G_STRING(OFS_PARM0);
1259 if (sv.worldmodel->ishlbsp && ((!s) || (!s[0])))
1261 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1262 PR_CheckEmptyString (s);
1264 for (i=0 ; i<MAX_MODELS ; i++)
1266 if (!sv.model_precache[i])
1268 sv.model_precache[i] = s;
1269 sv.models[i] = Mod_ForName (s, true, false, false);
1272 if (!strcmp(sv.model_precache[i], s))
1275 PR_RunError ("PF_precache_model: overflow");
1279 void PF_coredump (void)
1284 void PF_traceon (void)
1289 void PF_traceoff (void)
1294 void PF_eprint (void)
1296 ED_PrintNum (G_EDICTNUM(OFS_PARM0));
1303 float(float yaw, float dist) walkmove
1306 void PF_walkmove (void)
1314 ent = PROG_TO_EDICT(pr_global_struct->self);
1315 yaw = G_FLOAT(OFS_PARM0);
1316 dist = G_FLOAT(OFS_PARM1);
1318 if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1320 G_FLOAT(OFS_RETURN) = 0;
1324 yaw = yaw*M_PI*2 / 360;
1326 move[0] = cos(yaw)*dist;
1327 move[1] = sin(yaw)*dist;
1330 // save program state, because SV_movestep may call other progs
1331 oldf = pr_xfunction;
1332 oldself = pr_global_struct->self;
1334 G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
1337 // restore program state
1338 pr_xfunction = oldf;
1339 pr_global_struct->self = oldself;
1349 void PF_droptofloor (void)
1355 ent = PROG_TO_EDICT(pr_global_struct->self);
1357 VectorCopy (ent->v.origin, end);
1360 trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
1362 if (trace.fraction == 1 || trace.allsolid)
1363 G_FLOAT(OFS_RETURN) = 0;
1366 VectorCopy (trace.endpos, ent->v.origin);
1367 SV_LinkEdict (ent, false);
1368 ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
1369 ent->v.groundentity = EDICT_TO_PROG(trace.ent);
1370 G_FLOAT(OFS_RETURN) = 1;
1371 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1372 ent->suspendedinairflag = true;
1380 void(float style, string value) lightstyle
1383 void PF_lightstyle (void)
1390 style = G_FLOAT(OFS_PARM0);
1391 val = G_STRING(OFS_PARM1);
1393 // change the string in sv
1394 sv.lightstyles[style] = val;
1396 // send message to all clients on this server
1397 if (sv.state != ss_active)
1400 for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
1401 if (client->active || client->spawned)
1403 MSG_WriteChar (&client->message, svc_lightstyle);
1404 MSG_WriteChar (&client->message,style);
1405 MSG_WriteString (&client->message, val);
1412 f = G_FLOAT(OFS_PARM0);
1414 G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1416 G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1418 void PF_floor (void)
1420 G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
1424 G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
1433 void PF_checkbottom (void)
1435 G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0));
1443 void PF_pointcontents (void)
1445 G_FLOAT(OFS_RETURN) = Mod_PointInLeaf(G_VECTOR(OFS_PARM0), sv.worldmodel)->contents;
1452 entity nextent(entity)
1455 void PF_nextent (void)
1460 i = G_EDICTNUM(OFS_PARM0);
1464 if (i == sv.num_edicts)
1466 RETURN_EDICT(sv.edicts);
1482 Pick a vector for the player to shoot along
1483 vector aim(entity, missilespeed)
1488 edict_t *ent, *check, *bestent;
1489 vec3_t start, dir, end, bestdir;
1492 float dist, bestdist;
1495 ent = G_EDICT(OFS_PARM0);
1496 speed = G_FLOAT(OFS_PARM1);
1498 VectorCopy (ent->v.origin, start);
1501 // try sending a trace straight
1502 VectorCopy (pr_global_struct->v_forward, dir);
1503 VectorMA (start, 2048, dir, end);
1504 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1505 if (tr.ent && ((edict_t *)tr.ent)->v.takedamage == DAMAGE_AIM
1506 && (!teamplay.integer || ent->v.team <=0 || ent->v.team != ((edict_t *)tr.ent)->v.team) )
1508 VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
1513 // try all possible entities
1514 VectorCopy (dir, bestdir);
1515 bestdist = sv_aim.value;
1518 check = NEXT_EDICT(sv.edicts);
1519 for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
1521 if (check->v.takedamage != DAMAGE_AIM)
1525 if (teamplay.integer && ent->v.team > 0 && ent->v.team == check->v.team)
1526 continue; // don't aim at teammate
1527 for (j=0 ; j<3 ; j++)
1528 end[j] = check->v.origin[j]
1529 + 0.5*(check->v.mins[j] + check->v.maxs[j]);
1530 VectorSubtract (end, start, dir);
1531 VectorNormalize (dir);
1532 dist = DotProduct (dir, pr_global_struct->v_forward);
1533 if (dist < bestdist)
1534 continue; // to far to turn
1535 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1536 if (tr.ent == check)
1537 { // can shoot at this one
1545 VectorSubtract (bestent->v.origin, ent->v.origin, dir);
1546 dist = DotProduct (dir, pr_global_struct->v_forward);
1547 VectorScale (pr_global_struct->v_forward, dist, end);
1549 VectorNormalize (end);
1550 VectorCopy (end, G_VECTOR(OFS_RETURN));
1554 VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
1562 This was a major timewaster in progs, so it was converted to C
1565 void PF_changeyaw (void)
1568 float ideal, current, move, speed;
1570 ent = PROG_TO_EDICT(pr_global_struct->self);
1571 current = ANGLEMOD(ent->v.angles[1]);
1572 ideal = ent->v.ideal_yaw;
1573 speed = ent->v.yaw_speed;
1575 if (current == ideal)
1577 move = ideal - current;
1578 if (ideal > current)
1599 ent->v.angles[1] = ANGLEMOD (current + move);
1607 void PF_changepitch (void)
1610 float ideal, current, move, speed;
1613 ent = G_EDICT(OFS_PARM0);
1614 current = ANGLEMOD( ent->v.angles[0] );
1615 if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
1616 ideal = val->_float;
1619 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1622 if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
1623 speed = val->_float;
1626 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1630 if (current == ideal)
1632 move = ideal - current;
1633 if (ideal > current)
1654 ent->v.angles[0] = ANGLEMOD (current + move);
1658 ===============================================================================
1662 ===============================================================================
1665 #define MSG_BROADCAST 0 // unreliable to all
1666 #define MSG_ONE 1 // reliable to one (msg_entity)
1667 #define MSG_ALL 2 // reliable to all
1668 #define MSG_INIT 3 // write to the init string
1670 sizebuf_t *WriteDest (void)
1676 dest = G_FLOAT(OFS_PARM0);
1680 return &sv.datagram;
1683 ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
1684 entnum = NUM_FOR_EDICT(ent);
1685 if (entnum < 1 || entnum > svs.maxclients)
1686 PR_RunError ("WriteDest: not a client");
1687 return &svs.clients[entnum-1].message;
1690 return &sv.reliable_datagram;
1696 PR_RunError ("WriteDest: bad destination");
1703 void PF_WriteByte (void)
1705 MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
1708 void PF_WriteChar (void)
1710 MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
1713 void PF_WriteShort (void)
1715 MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
1718 void PF_WriteLong (void)
1720 MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
1723 void PF_WriteAngle (void)
1725 MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
1728 void PF_WriteCoord (void)
1730 MSG_WriteDPCoord (WriteDest(), G_FLOAT(OFS_PARM1));
1733 void PF_WriteString (void)
1735 MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
1739 void PF_WriteEntity (void)
1741 MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
1744 //=============================================================================
1746 int SV_ModelIndex (char *name);
1748 void PF_makestatic (void)
1753 ent = G_EDICT(OFS_PARM0);
1756 if (ent->v.modelindex >= 256 || ent->v.frame >= 256)
1761 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1762 MSG_WriteShort (&sv.signon, ent->v.modelindex);
1763 MSG_WriteShort (&sv.signon, ent->v.frame);
1767 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1768 MSG_WriteByte (&sv.signon, ent->v.modelindex);
1769 MSG_WriteByte (&sv.signon, ent->v.frame);
1772 MSG_WriteByte (&sv.signon, ent->v.colormap);
1773 MSG_WriteByte (&sv.signon, ent->v.skin);
1774 for (i=0 ; i<3 ; i++)
1776 MSG_WriteDPCoord(&sv.signon, ent->v.origin[i]);
1777 MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
1780 // throw the entity away now
1784 //=============================================================================
1791 void PF_setspawnparms (void)
1797 ent = G_EDICT(OFS_PARM0);
1798 i = NUM_FOR_EDICT(ent);
1799 if (i < 1 || i > svs.maxclients)
1800 PR_RunError ("Entity is not a client");
1802 // copy spawn parms out of the client_t
1803 client = svs.clients + (i-1);
1805 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1806 (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
1814 void PF_changelevel (void)
1818 // make sure we don't issue two changelevels
1819 if (svs.changelevel_issued)
1821 svs.changelevel_issued = true;
1823 s = G_STRING(OFS_PARM0);
1824 Cbuf_AddText (va("changelevel %s\n",s));
1829 G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
1834 G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
1839 G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
1846 Returns a vector of length < 1
1851 void PF_randomvec (void)
1856 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1857 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1858 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1860 while (DotProduct(temp, temp) >= 1);
1861 VectorCopy (temp, G_VECTOR(OFS_RETURN));
1864 void SV_LightPoint (vec3_t color, vec3_t p);
1869 Returns a color vector indicating the lighting at the requested point.
1871 (Internal Operation note: actually measures the light beneath the point, just like
1872 the model lighting on the client)
1877 void PF_GetLight (void)
1881 p = G_VECTOR(OFS_PARM0);
1882 SV_LightPoint (color, p);
1883 VectorCopy (color, G_VECTOR(OFS_RETURN));
1886 #define MAX_QC_CVARS 128
1887 cvar_t qc_cvar[MAX_QC_CVARS];
1890 void PF_registercvar (void)
1894 name = G_STRING(OFS_PARM0);
1895 value = G_STRING(OFS_PARM1);
1896 G_FLOAT(OFS_RETURN) = 0;
1897 // first check to see if it has already been defined
1898 if (Cvar_FindVar (name))
1901 // check for overlap with a command
1902 if (Cmd_Exists (name))
1904 Con_Printf ("PF_registercvar: %s is a command\n", name);
1908 if (currentqc_cvar >= MAX_QC_CVARS)
1909 PR_RunError ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
1911 // copy the name and value
1912 variable = &qc_cvar[currentqc_cvar++];
1913 variable->name = Z_Malloc (strlen(name)+1);
1914 strcpy (variable->name, name);
1915 variable->string = Z_Malloc (strlen(value)+1);
1916 strcpy (variable->string, value);
1917 variable->value = atof (value);
1919 // link the variable in
1920 variable->next = cvar_vars;
1921 cvar_vars = variable;
1922 G_FLOAT(OFS_RETURN) = 1; // success
1929 returns the minimum of two supplied floats
1936 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1938 G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1939 else if (pr_argc >= 3)
1942 float f = G_FLOAT(OFS_PARM0);
1943 for (i = 1;i < pr_argc;i++)
1944 if (G_FLOAT((OFS_PARM0+i*3)) < f)
1945 f = G_FLOAT((OFS_PARM0+i*3));
1946 G_FLOAT(OFS_RETURN) = f;
1949 PR_RunError("min: must supply at least 2 floats\n");
1956 returns the maximum of two supplied floats
1963 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1965 G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1966 else if (pr_argc >= 3)
1969 float f = G_FLOAT(OFS_PARM0);
1970 for (i = 1;i < pr_argc;i++)
1971 if (G_FLOAT((OFS_PARM0+i*3)) > f)
1972 f = G_FLOAT((OFS_PARM0+i*3));
1973 G_FLOAT(OFS_RETURN) = f;
1976 PR_RunError("max: must supply at least 2 floats\n");
1983 returns number bounded by supplied range
1985 min(min, value, max)
1988 void PF_bound (void)
1990 G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
1997 returns a raised to power b
2004 G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2011 copies data from one entity to another
2013 copyentity(src, dst)
2016 void PF_copyentity (void)
2019 in = G_EDICT(OFS_PARM0);
2020 out = G_EDICT(OFS_PARM1);
2021 memcpy(out, in, pr_edict_size);
2028 sets the color of a client and broadcasts the update to all connected clients
2030 setcolor(clientent, value)
2033 void PF_setcolor (void)
2038 entnum = G_EDICTNUM(OFS_PARM0);
2039 i = G_FLOAT(OFS_PARM1);
2041 if (entnum < 1 || entnum > svs.maxclients)
2043 Con_Printf ("tried to setcolor a non-client\n");
2047 client = &svs.clients[entnum-1];
2049 client->edict->v.team = (i & 15) + 1;
2051 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
2052 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
2053 MSG_WriteByte (&sv.reliable_datagram, i);
2060 effect(origin, modelname, startframe, framecount, framerate)
2063 void PF_effect (void)
2066 s = G_STRING(OFS_PARM1);
2068 PR_RunError("effect: no model specified\n");
2070 SV_StartEffect(G_VECTOR(OFS_PARM0), SV_ModelIndex(s), G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
2073 void PF_te_blood (void)
2075 if (G_FLOAT(OFS_PARM2) < 1)
2077 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2078 MSG_WriteByte(&sv.datagram, TE_BLOOD);
2080 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2081 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2082 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2084 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2085 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2086 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2088 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2091 void PF_te_bloodshower (void)
2093 if (G_FLOAT(OFS_PARM3) < 1)
2095 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2096 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
2098 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2099 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2100 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2102 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2103 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2104 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2106 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
2108 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2111 void PF_te_explosionrgb (void)
2113 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2114 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
2116 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2117 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2118 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2120 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
2121 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
2122 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
2125 void PF_te_particlecube (void)
2127 if (G_FLOAT(OFS_PARM3) < 1)
2129 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2130 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
2132 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2133 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2134 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2136 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2137 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2138 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2140 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2141 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2142 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2144 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2146 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2147 // gravity true/false
2148 MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
2150 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
2153 void PF_te_particlerain (void)
2155 if (G_FLOAT(OFS_PARM3) < 1)
2157 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2158 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
2160 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2161 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2162 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2164 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2165 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2166 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2168 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2169 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2170 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2172 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2174 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2177 void PF_te_particlesnow (void)
2179 if (G_FLOAT(OFS_PARM3) < 1)
2181 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2182 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
2184 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2185 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2186 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2188 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2189 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2190 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2192 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2193 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2194 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2196 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2198 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2201 void PF_te_spark (void)
2203 if (G_FLOAT(OFS_PARM2) < 1)
2205 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2206 MSG_WriteByte(&sv.datagram, TE_SPARK);
2208 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2209 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2210 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2212 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2213 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2214 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2216 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2219 void PF_te_gunshotquad (void)
2221 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2222 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
2224 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2225 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2226 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2229 void PF_te_spikequad (void)
2231 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2232 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
2234 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2235 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2236 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2239 void PF_te_superspikequad (void)
2241 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2242 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
2244 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2245 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2246 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2249 void PF_te_explosionquad (void)
2251 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2252 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2254 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2255 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2256 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2259 void PF_te_smallflash (void)
2261 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2262 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2264 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2265 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2266 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2269 void PF_te_customflash (void)
2271 if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2273 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2274 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2276 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2277 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2278 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2280 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2282 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255));
2284 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
2285 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
2286 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
2289 void PF_te_gunshot (void)
2291 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2292 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2294 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2295 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2296 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2299 void PF_te_spike (void)
2301 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2302 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2304 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2305 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2306 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2309 void PF_te_superspike (void)
2311 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2312 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2314 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2315 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2316 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2319 void PF_te_explosion (void)
2321 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2322 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2324 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2325 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2326 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2329 void PF_te_tarexplosion (void)
2331 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2332 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2334 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2335 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2336 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2339 void PF_te_wizspike (void)
2341 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2342 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2344 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2345 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2346 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2349 void PF_te_knightspike (void)
2351 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2352 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2354 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2355 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2356 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2359 void PF_te_lavasplash (void)
2361 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2362 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2364 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2365 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2366 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2369 void PF_te_teleport (void)
2371 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2372 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2374 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2375 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2376 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2379 void PF_te_explosion2 (void)
2381 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2382 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2384 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2385 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2386 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2388 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
2391 void PF_te_lightning1 (void)
2393 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2394 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2396 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2398 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2399 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2400 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2402 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2403 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2404 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2407 void PF_te_lightning2 (void)
2409 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2410 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2412 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2414 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2415 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2416 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2418 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2419 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2420 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2423 void PF_te_lightning3 (void)
2425 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2426 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2428 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2430 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2431 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2432 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2434 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2435 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2436 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2439 void PF_te_beam (void)
2441 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2442 MSG_WriteByte(&sv.datagram, TE_BEAM);
2444 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2446 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2447 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2448 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2450 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2451 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2452 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2455 void PF_te_plasmaburn (void)
2457 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2458 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2459 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2460 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2461 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2464 void PF_Fixme (void)
2466 PR_RunError ("unimplemented builtin"); // LordHavoc: was misspelled (bulitin)
2471 builtin_t pr_builtin[] =
2474 PF_makevectors, // void(entity e) makevectors = #1;
2475 PF_setorigin, // void(entity e, vector o) setorigin = #2;
2476 PF_setmodel, // void(entity e, string m) setmodel = #3;
2477 PF_setsize, // void(entity e, vector min, vector max) setsize = #4;
2478 PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5;
2479 PF_break, // void() break = #6;
2480 PF_random, // float() random = #7;
2481 PF_sound, // void(entity e, float chan, string samp) sound = #8;
2482 PF_normalize, // vector(vector v) normalize = #9;
2483 PF_error, // void(string e) error = #10;
2484 PF_objerror, // void(string e) objerror = #11;
2485 PF_vlen, // float(vector v) vlen = #12;
2486 PF_vectoyaw, // float(vector v) vectoyaw = #13;
2487 PF_Spawn, // entity() spawn = #14;
2488 PF_Remove, // void(entity e) remove = #15;
2489 PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16;
2490 PF_checkclient, // entity() clientlist = #17;
2491 PF_Find, // entity(entity start, .string fld, string match) find = #18;
2492 PF_precache_sound, // void(string s) precache_sound = #19;
2493 PF_precache_model, // void(string s) precache_model = #20;
2494 PF_stuffcmd, // void(entity client, string s)stuffcmd = #21;
2495 PF_findradius, // entity(vector org, float rad) findradius = #22;
2496 PF_bprint, // void(string s) bprint = #23;
2497 PF_sprint, // void(entity client, string s) sprint = #24;
2498 PF_dprint, // void(string s) dprint = #25;
2499 PF_ftos, // void(string s) ftos = #26;
2500 PF_vtos, // void(string s) vtos = #27;
2504 PF_eprint, // void(entity e) debug print an entire entity
2505 PF_walkmove, // float(float yaw, float dist) walkmove
2506 PF_Fixme, // float(float yaw, float dist) walkmove
2556 PF_precache_sound, // precache_sound2 is different only for qcc
2561 PF_Fixme, // #79 LordHavoc: dunno who owns 79-89, so these are just padding
2573 PF_tracebox, // #90 LordHavoc builtin range (9x)
2574 PF_randomvec, // #91
2576 PF_registercvar, // #93
2581 PF_FindFloat, // #98
2582 PF_checkextension, // #99
2583 #define a PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme,
2584 #define aa a a a a a a a a a a
2588 PF_copyentity, // #400 LordHavoc: builtin range (4xx)
2589 PF_setcolor, // #401
2590 PF_findchain, // #402
2591 PF_findchainfloat, // #403
2593 PF_te_blood, // #405
2594 PF_te_bloodshower, // #406
2595 PF_te_explosionrgb, // #407
2596 PF_te_particlecube, // #408
2597 PF_te_particlerain, // #409
2598 PF_te_particlesnow, // #410
2599 PF_te_spark, // #411
2600 PF_te_gunshotquad, // #412
2601 PF_te_spikequad, // #413
2602 PF_te_superspikequad, // #414
2603 PF_te_explosionquad, // #415
2604 PF_te_smallflash, // #416
2605 PF_te_customflash, // #417
2606 PF_te_gunshot, // #418
2607 PF_te_spike, // #419
2608 PF_te_superspike, // #420
2609 PF_te_explosion, // #421
2610 PF_te_tarexplosion, // #422
2611 PF_te_wizspike, // #423
2612 PF_te_knightspike, // #424
2613 PF_te_lavasplash, // #425
2614 PF_te_teleport, // #426
2615 PF_te_explosion2, // #427
2616 PF_te_lightning1, // #428
2617 PF_te_lightning2, // #429
2618 PF_te_lightning3, // #430
2620 PF_vectorvectors, // #432
2621 PF_te_plasmaburn, // #433
2624 builtin_t *pr_builtins = pr_builtin;
2625 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);