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 Cvar_RegisterVariable(variable);
1920 G_FLOAT(OFS_RETURN) = 1; // success
1927 returns the minimum of two supplied floats
1934 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1936 G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1937 else if (pr_argc >= 3)
1940 float f = G_FLOAT(OFS_PARM0);
1941 for (i = 1;i < pr_argc;i++)
1942 if (G_FLOAT((OFS_PARM0+i*3)) < f)
1943 f = G_FLOAT((OFS_PARM0+i*3));
1944 G_FLOAT(OFS_RETURN) = f;
1947 PR_RunError("min: must supply at least 2 floats\n");
1954 returns the maximum of two supplied floats
1961 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1963 G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1964 else if (pr_argc >= 3)
1967 float f = G_FLOAT(OFS_PARM0);
1968 for (i = 1;i < pr_argc;i++)
1969 if (G_FLOAT((OFS_PARM0+i*3)) > f)
1970 f = G_FLOAT((OFS_PARM0+i*3));
1971 G_FLOAT(OFS_RETURN) = f;
1974 PR_RunError("max: must supply at least 2 floats\n");
1981 returns number bounded by supplied range
1983 min(min, value, max)
1986 void PF_bound (void)
1988 G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
1995 returns a raised to power b
2002 G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2009 copies data from one entity to another
2011 copyentity(src, dst)
2014 void PF_copyentity (void)
2017 in = G_EDICT(OFS_PARM0);
2018 out = G_EDICT(OFS_PARM1);
2019 memcpy(out, in, pr_edict_size);
2026 sets the color of a client and broadcasts the update to all connected clients
2028 setcolor(clientent, value)
2031 void PF_setcolor (void)
2036 entnum = G_EDICTNUM(OFS_PARM0);
2037 i = G_FLOAT(OFS_PARM1);
2039 if (entnum < 1 || entnum > svs.maxclients)
2041 Con_Printf ("tried to setcolor a non-client\n");
2045 client = &svs.clients[entnum-1];
2047 client->edict->v.team = (i & 15) + 1;
2049 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
2050 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
2051 MSG_WriteByte (&sv.reliable_datagram, i);
2058 effect(origin, modelname, startframe, framecount, framerate)
2061 void PF_effect (void)
2064 s = G_STRING(OFS_PARM1);
2066 PR_RunError("effect: no model specified\n");
2068 SV_StartEffect(G_VECTOR(OFS_PARM0), SV_ModelIndex(s), G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
2071 void PF_te_blood (void)
2073 if (G_FLOAT(OFS_PARM2) < 1)
2075 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2076 MSG_WriteByte(&sv.datagram, TE_BLOOD);
2078 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2079 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2080 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2082 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2083 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2084 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2086 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2089 void PF_te_bloodshower (void)
2091 if (G_FLOAT(OFS_PARM3) < 1)
2093 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2094 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
2096 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2097 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2098 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2100 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2101 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2102 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2104 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
2106 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2109 void PF_te_explosionrgb (void)
2111 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2112 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
2114 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2115 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2116 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2118 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
2119 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
2120 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
2123 void PF_te_particlecube (void)
2125 if (G_FLOAT(OFS_PARM3) < 1)
2127 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2128 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
2130 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2131 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2132 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2134 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2135 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2136 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2138 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2139 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2140 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2142 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2144 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2145 // gravity true/false
2146 MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
2148 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
2151 void PF_te_particlerain (void)
2153 if (G_FLOAT(OFS_PARM3) < 1)
2155 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2156 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
2158 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2159 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2160 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2162 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2163 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2164 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2166 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2167 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2168 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2170 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2172 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2175 void PF_te_particlesnow (void)
2177 if (G_FLOAT(OFS_PARM3) < 1)
2179 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2180 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
2182 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2183 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2184 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2186 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2187 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2188 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2190 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2191 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2192 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2194 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2196 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2199 void PF_te_spark (void)
2201 if (G_FLOAT(OFS_PARM2) < 1)
2203 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2204 MSG_WriteByte(&sv.datagram, TE_SPARK);
2206 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2207 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2208 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2210 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2211 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2212 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2214 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2217 void PF_te_gunshotquad (void)
2219 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2220 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
2222 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2223 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2224 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2227 void PF_te_spikequad (void)
2229 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2230 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
2232 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2233 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2234 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2237 void PF_te_superspikequad (void)
2239 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2240 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
2242 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2243 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2244 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2247 void PF_te_explosionquad (void)
2249 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2250 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2252 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2253 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2254 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2257 void PF_te_smallflash (void)
2259 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2260 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2262 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2263 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2264 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2267 void PF_te_customflash (void)
2269 if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2271 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2272 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2274 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2275 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2276 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2278 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2280 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255));
2282 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
2283 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
2284 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
2287 void PF_te_gunshot (void)
2289 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2290 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2292 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2293 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2294 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2297 void PF_te_spike (void)
2299 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2300 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2302 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2303 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2304 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2307 void PF_te_superspike (void)
2309 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2310 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2312 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2313 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2314 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2317 void PF_te_explosion (void)
2319 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2320 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2322 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2323 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2324 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2327 void PF_te_tarexplosion (void)
2329 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2330 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2332 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2333 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2334 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2337 void PF_te_wizspike (void)
2339 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2340 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2342 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2343 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2344 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2347 void PF_te_knightspike (void)
2349 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2350 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2352 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2353 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2354 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2357 void PF_te_lavasplash (void)
2359 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2360 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2362 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2363 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2364 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2367 void PF_te_teleport (void)
2369 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2370 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2372 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2373 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2374 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2377 void PF_te_explosion2 (void)
2379 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2380 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2382 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2383 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2384 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2386 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
2389 void PF_te_lightning1 (void)
2391 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2392 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2394 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2396 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2397 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2398 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2400 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2401 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2402 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2405 void PF_te_lightning2 (void)
2407 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2408 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2410 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2412 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2413 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2414 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2416 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2417 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2418 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2421 void PF_te_lightning3 (void)
2423 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2424 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2426 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2428 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2429 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2430 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2432 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2433 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2434 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2437 void PF_te_beam (void)
2439 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2440 MSG_WriteByte(&sv.datagram, TE_BEAM);
2442 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2444 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2445 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2446 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2448 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2449 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2450 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2453 void PF_te_plasmaburn (void)
2455 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2456 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2457 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2458 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2459 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2462 void PF_Fixme (void)
2464 PR_RunError ("unimplemented builtin"); // LordHavoc: was misspelled (bulitin)
2469 builtin_t pr_builtin[] =
2472 PF_makevectors, // void(entity e) makevectors = #1;
2473 PF_setorigin, // void(entity e, vector o) setorigin = #2;
2474 PF_setmodel, // void(entity e, string m) setmodel = #3;
2475 PF_setsize, // void(entity e, vector min, vector max) setsize = #4;
2476 PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5;
2477 PF_break, // void() break = #6;
2478 PF_random, // float() random = #7;
2479 PF_sound, // void(entity e, float chan, string samp) sound = #8;
2480 PF_normalize, // vector(vector v) normalize = #9;
2481 PF_error, // void(string e) error = #10;
2482 PF_objerror, // void(string e) objerror = #11;
2483 PF_vlen, // float(vector v) vlen = #12;
2484 PF_vectoyaw, // float(vector v) vectoyaw = #13;
2485 PF_Spawn, // entity() spawn = #14;
2486 PF_Remove, // void(entity e) remove = #15;
2487 PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16;
2488 PF_checkclient, // entity() clientlist = #17;
2489 PF_Find, // entity(entity start, .string fld, string match) find = #18;
2490 PF_precache_sound, // void(string s) precache_sound = #19;
2491 PF_precache_model, // void(string s) precache_model = #20;
2492 PF_stuffcmd, // void(entity client, string s)stuffcmd = #21;
2493 PF_findradius, // entity(vector org, float rad) findradius = #22;
2494 PF_bprint, // void(string s) bprint = #23;
2495 PF_sprint, // void(entity client, string s) sprint = #24;
2496 PF_dprint, // void(string s) dprint = #25;
2497 PF_ftos, // void(string s) ftos = #26;
2498 PF_vtos, // void(string s) vtos = #27;
2502 PF_eprint, // void(entity e) debug print an entire entity
2503 PF_walkmove, // float(float yaw, float dist) walkmove
2504 PF_Fixme, // float(float yaw, float dist) walkmove
2554 PF_precache_sound, // precache_sound2 is different only for qcc
2559 PF_Fixme, // #79 LordHavoc: dunno who owns 79-89, so these are just padding
2571 PF_tracebox, // #90 LordHavoc builtin range (9x)
2572 PF_randomvec, // #91
2574 PF_registercvar, // #93
2579 PF_FindFloat, // #98
2580 PF_checkextension, // #99
2581 #define a PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme,
2582 #define aa a a a a a a a a a a
2586 PF_copyentity, // #400 LordHavoc: builtin range (4xx)
2587 PF_setcolor, // #401
2588 PF_findchain, // #402
2589 PF_findchainfloat, // #403
2591 PF_te_blood, // #405
2592 PF_te_bloodshower, // #406
2593 PF_te_explosionrgb, // #407
2594 PF_te_particlecube, // #408
2595 PF_te_particlerain, // #409
2596 PF_te_particlesnow, // #410
2597 PF_te_spark, // #411
2598 PF_te_gunshotquad, // #412
2599 PF_te_spikequad, // #413
2600 PF_te_superspikequad, // #414
2601 PF_te_explosionquad, // #415
2602 PF_te_smallflash, // #416
2603 PF_te_customflash, // #417
2604 PF_te_gunshot, // #418
2605 PF_te_spike, // #419
2606 PF_te_superspike, // #420
2607 PF_te_explosion, // #421
2608 PF_te_tarexplosion, // #422
2609 PF_te_wizspike, // #423
2610 PF_te_knightspike, // #424
2611 PF_te_lavasplash, // #425
2612 PF_te_teleport, // #426
2613 PF_te_explosion2, // #427
2614 PF_te_lightning1, // #428
2615 PF_te_lightning2, // #429
2616 PF_te_lightning3, // #430
2618 PF_vectorvectors, // #432
2619 PF_te_plasmaburn, // #433
2622 builtin_t *pr_builtins = pr_builtin;
2623 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);