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)
43 for (i=first ; i<pr_argc ; i++)
45 strcat (out, G_STRING((OFS_PARM0+i*3)));
50 char *ENGINE_EXTENSIONS = "\
53 DP_ENT_DELTACOMPRESS \
65 DP_SV_DRAWONLYTOCLIENT \
66 DP_SV_NODRAWTOCLIENT \
67 DP_SV_EXTERIORMODELTOCLIENT \
82 DP_QC_FINDCHAINFLOAT \
93 qboolean checkextension(char *name)
98 for (e = ENGINE_EXTENSIONS;*e;e++)
105 while (*e && *e != ' ')
107 if (e - start == len)
108 if (!strncasecmp(e, name, len))
118 returns true if the extension is supported by the server
120 checkextension(extensionname)
123 void PF_checkextension (void)
125 G_FLOAT(OFS_RETURN) = checkextension(G_STRING(OFS_PARM0));
132 This is a TERMINAL error, which will kill off the entire server.
144 Con_Printf ("======SERVER ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
145 ed = PROG_TO_EDICT(pr_global_struct->self);
148 Host_Error ("Program error");
155 Dumps out self, then an error message. The program is aborted and self is
156 removed, but the level can continue.
161 void PF_objerror (void)
167 Con_Printf ("======OBJECT ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
168 ed = PROG_TO_EDICT(pr_global_struct->self);
172 // LordHavoc: bug fix - no longer kills server
173 // Host_Error ("Program error");
182 Writes new values for v_forward, v_up, and v_right based on angles
186 void PF_makevectors (void)
188 AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
195 Writes new values for v_forward, v_up, and v_right based on the given forward vector
196 vectorvectors(vector, vector)
199 void PF_vectorvectors (void)
201 VectorNormalize2(G_VECTOR(OFS_PARM0), pr_global_struct->v_forward);
202 VectorVectors(pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
209 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.
211 setorigin (entity, origin)
214 void PF_setorigin (void)
219 e = G_EDICT(OFS_PARM0);
220 org = G_VECTOR(OFS_PARM1);
221 VectorCopy (org, e->v.origin);
222 SV_LinkEdict (e, false);
226 void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
232 float xvector[2], yvector[2];
234 vec3_t base, transformed;
239 for (i=0 ; i<3 ; i++)
241 PR_RunError ("backwards mins/maxs");
244 rotate = false; // FIXME: implement rotation properly again
248 VectorCopy (min, rmin);
249 VectorCopy (max, rmax);
253 // find min / max for rotations
254 angles = e->v.angles;
256 a = angles[1]/180 * M_PI;
260 yvector[0] = -sin(a);
263 VectorCopy (min, bounds[0]);
264 VectorCopy (max, bounds[1]);
266 rmin[0] = rmin[1] = rmin[2] = 9999;
267 rmax[0] = rmax[1] = rmax[2] = -9999;
269 for (i=0 ; i<= 1 ; i++)
271 base[0] = bounds[i][0];
272 for (j=0 ; j<= 1 ; j++)
274 base[1] = bounds[j][1];
275 for (k=0 ; k<= 1 ; k++)
277 base[2] = bounds[k][2];
279 // transform the point
280 transformed[0] = xvector[0]*base[0] + yvector[0]*base[1];
281 transformed[1] = xvector[1]*base[0] + yvector[1]*base[1];
282 transformed[2] = base[2];
284 for (l=0 ; l<3 ; l++)
286 if (transformed[l] < rmin[l])
287 rmin[l] = transformed[l];
288 if (transformed[l] > rmax[l])
289 rmax[l] = transformed[l];
296 // set derived values
297 VectorCopy (rmin, e->v.mins);
298 VectorCopy (rmax, e->v.maxs);
299 VectorSubtract (max, min, e->v.size);
302 // set derived values
303 VectorCopy (min, e->v.mins);
304 VectorCopy (max, e->v.maxs);
305 VectorSubtract (max, min, e->v.size);
307 SV_LinkEdict (e, false);
314 the size box is rotated by the current angle
315 LordHavoc: no it isn't...
317 setsize (entity, minvector, maxvector)
320 void PF_setsize (void)
325 e = G_EDICT(OFS_PARM0);
326 min = G_VECTOR(OFS_PARM1);
327 max = G_VECTOR(OFS_PARM2);
328 SetMinMaxSize (e, min, max, false);
336 setmodel(entity, model)
339 void PF_setmodel (void)
346 e = G_EDICT(OFS_PARM0);
347 m = G_STRING(OFS_PARM1);
349 // check to see if model was properly precached
350 for (i=0, check = sv.model_precache ; *check ; i++, check++)
351 if (!strcmp(*check, m))
355 PR_RunError ("no precache: %s\n", m);
358 e->v.model = m - pr_strings;
359 e->v.modelindex = i; //SV_ModelIndex (m);
361 mod = sv.models[ (int)e->v.modelindex]; // Mod_ForName (m, true);
365 { // LordHavoc: corrected model bounding box, but for compatibility that means I have to break it here
367 if (mod->type == ALIASTYPE_MDL)
369 min[0] = min[1] = min[2] = -16;
370 max[0] = max[1] = max[2] = 16;
371 SetMinMaxSize (e, min, max, true);
374 SetMinMaxSize (e, mod->mins, mod->maxs, true);
377 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
379 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
386 broadcast print to everyone on server
391 void PF_bprint (void)
396 SV_BroadcastPrintf ("%s", s);
403 single print to a specific client
405 sprint(clientent, value)
408 void PF_sprint (void)
414 entnum = G_EDICTNUM(OFS_PARM0);
417 if (entnum < 1 || entnum > svs.maxclients)
419 Con_Printf ("tried to sprint to a non-client\n");
423 client = &svs.clients[entnum-1];
425 MSG_WriteChar (&client->message,svc_print);
426 MSG_WriteString (&client->message, s );
434 single print to a specific client
436 centerprint(clientent, value)
439 void PF_centerprint (void)
445 entnum = G_EDICTNUM(OFS_PARM0);
448 if (entnum < 1 || entnum > svs.maxclients)
450 Con_Printf ("tried to sprint to a non-client\n");
454 client = &svs.clients[entnum-1];
456 MSG_WriteChar (&client->message,svc_centerprint);
457 MSG_WriteString (&client->message, s );
465 vector normalize(vector)
468 void PF_normalize (void)
474 value1 = G_VECTOR(OFS_PARM0);
476 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
480 newvalue[0] = newvalue[1] = newvalue[2] = 0;
484 newvalue[0] = value1[0] * new;
485 newvalue[1] = value1[1] * new;
486 newvalue[2] = value1[2] * new;
489 VectorCopy (newvalue, G_VECTOR(OFS_RETURN));
504 value1 = G_VECTOR(OFS_PARM0);
506 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
509 G_FLOAT(OFS_RETURN) = new;
516 float vectoyaw(vector)
519 void PF_vectoyaw (void)
524 value1 = G_VECTOR(OFS_PARM0);
526 if (value1[1] == 0 && value1[0] == 0)
530 yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
535 G_FLOAT(OFS_RETURN) = yaw;
543 vector vectoangles(vector)
546 void PF_vectoangles (void)
552 value1 = G_VECTOR(OFS_PARM0);
554 if (value1[1] == 0 && value1[0] == 0)
564 // LordHavoc: optimized a bit
567 yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
571 else if (value1[1] > 0)
576 forward = sqrt(value1[0]*value1[0] + value1[1]*value1[1]);
577 pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
582 G_FLOAT(OFS_RETURN+0) = pitch;
583 G_FLOAT(OFS_RETURN+1) = yaw;
584 G_FLOAT(OFS_RETURN+2) = 0;
591 Returns a number from 0<= num < 1
596 void PF_random (void)
600 num = (rand ()&0x7fff) / ((float)0x7fff);
602 G_FLOAT(OFS_RETURN) = num;
609 particle(origin, color, count)
612 void PF_particle (void)
618 org = G_VECTOR(OFS_PARM0);
619 dir = G_VECTOR(OFS_PARM1);
620 color = G_FLOAT(OFS_PARM2);
621 count = G_FLOAT(OFS_PARM3);
622 SV_StartParticle (org, dir, color, count);
632 void PF_ambientsound (void)
637 float vol, attenuation;
638 int i, soundnum, large;
640 pos = G_VECTOR (OFS_PARM0);
641 samp = G_STRING(OFS_PARM1);
642 vol = G_FLOAT(OFS_PARM2);
643 attenuation = G_FLOAT(OFS_PARM3);
645 // check to see if samp was properly precached
646 for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++)
647 if (!strcmp(*check,samp))
652 Con_Printf ("no precache: %s\n", samp);
660 // add an svc_spawnambient command to the level signon packet
663 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
665 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
667 for (i=0 ; i<3 ; i++)
668 MSG_WriteFloatCoord(&sv.signon, pos[i]);
671 MSG_WriteShort (&sv.signon, soundnum);
673 MSG_WriteByte (&sv.signon, soundnum);
675 MSG_WriteByte (&sv.signon, vol*255);
676 MSG_WriteByte (&sv.signon, attenuation*64);
684 Each entity can have eight independant sound sources, like voice,
687 Channel 0 is an auto-allocate channel, the others override anything
688 already running on that entity/channel pair.
690 An attenuation of 0 will play full volume everywhere in the level.
691 Larger attenuations will drop off.
703 entity = G_EDICT(OFS_PARM0);
704 channel = G_FLOAT(OFS_PARM1);
705 sample = G_STRING(OFS_PARM2);
706 volume = G_FLOAT(OFS_PARM3) * 255;
707 attenuation = G_FLOAT(OFS_PARM4);
709 if (volume < 0 || volume > 255)
710 Host_Error ("SV_StartSound: volume = %i", volume);
712 if (attenuation < 0 || attenuation > 4)
713 Host_Error ("SV_StartSound: attenuation = %f", attenuation);
715 if (channel < 0 || channel > 7)
716 Host_Error ("SV_StartSound: channel = %i", channel);
718 SV_StartSound (entity, channel, sample, volume, attenuation);
730 // Con_Printf ("break statement\n");
731 // *(int *)-4 = 0; // dump to debugger
732 PR_RunError ("break statement");
739 Used for use tracing and shot targeting
740 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
741 if the tryents flag is set.
743 traceline (vector1, vector2, tryents)
746 void PF_traceline (void)
753 v1 = G_VECTOR(OFS_PARM0);
754 v2 = G_VECTOR(OFS_PARM1);
755 nomonsters = G_FLOAT(OFS_PARM2);
756 ent = G_EDICT(OFS_PARM3);
758 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters ? MOVE_NOMONSTERS : MOVE_NORMAL, ent);
760 pr_global_struct->trace_allsolid = trace.allsolid;
761 pr_global_struct->trace_startsolid = trace.startsolid;
762 pr_global_struct->trace_fraction = trace.fraction;
763 pr_global_struct->trace_inwater = trace.inwater;
764 pr_global_struct->trace_inopen = trace.inopen;
765 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
766 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
767 pr_global_struct->trace_plane_dist = trace.plane.dist;
769 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
771 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
772 // FIXME: add trace_endcontents
780 Used for use tracing and shot targeting
781 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
782 if the tryents flag is set.
784 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
787 // LordHavoc: added this for my own use, VERY useful, similar to traceline
788 void PF_tracebox (void)
790 float *v1, *v2, *m1, *m2;
795 v1 = G_VECTOR(OFS_PARM0);
796 m1 = G_VECTOR(OFS_PARM1);
797 m2 = G_VECTOR(OFS_PARM2);
798 v2 = G_VECTOR(OFS_PARM3);
799 nomonsters = G_FLOAT(OFS_PARM4);
800 ent = G_EDICT(OFS_PARM5);
802 trace = SV_Move (v1, m1, m2, v2, nomonsters ? MOVE_NOMONSTERS : MOVE_NORMAL, ent);
804 pr_global_struct->trace_allsolid = trace.allsolid;
805 pr_global_struct->trace_startsolid = trace.startsolid;
806 pr_global_struct->trace_fraction = trace.fraction;
807 pr_global_struct->trace_inwater = trace.inwater;
808 pr_global_struct->trace_inopen = trace.inopen;
809 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
810 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
811 pr_global_struct->trace_plane_dist = trace.plane.dist;
813 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
815 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
818 extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore);
819 void PF_TraceToss (void)
825 ent = G_EDICT(OFS_PARM0);
826 ignore = G_EDICT(OFS_PARM1);
828 trace = SV_Trace_Toss (ent, ignore);
830 pr_global_struct->trace_allsolid = trace.allsolid;
831 pr_global_struct->trace_startsolid = trace.startsolid;
832 pr_global_struct->trace_fraction = trace.fraction;
833 pr_global_struct->trace_inwater = trace.inwater;
834 pr_global_struct->trace_inopen = trace.inopen;
835 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
836 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
837 pr_global_struct->trace_plane_dist = trace.plane.dist;
839 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
841 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
849 Returns true if the given entity can move to the given position from it's
850 current position by walking or rolling.
852 scalar checkpos (entity, vector)
855 void PF_checkpos (void)
859 //============================================================================
861 byte checkpvs[MAX_MAP_LEAFS/8];
863 int PF_newcheckclient (int check)
871 // cycle to the next one
875 if (check > svs.maxclients)
876 check = svs.maxclients;
878 if (check == svs.maxclients)
885 if (i == svs.maxclients+1)
891 break; // didn't find anything else
895 if (ent->v.health <= 0)
897 if ((int)ent->v.flags & FL_NOTARGET)
900 // anything that is a client, or has a client as an enemy
904 // get the PVS for the entity
905 VectorAdd (ent->v.origin, ent->v.view_ofs, org);
906 leaf = Mod_PointInLeaf (org, sv.worldmodel);
907 pvs = Mod_LeafPVS (leaf, sv.worldmodel);
908 memcpy (checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 );
917 Returns a client (or object that has a client enemy) that would be a
920 If there is more than one valid option, they are cycled each frame
922 If (self.origin + self.viewofs) is not in the PVS of the current target,
923 it is not returned at all.
928 int c_invis, c_notvis;
929 void PF_checkclient (void)
936 // find a new check if on a new frame
937 if (sv.time - sv.lastchecktime >= 0.1)
939 sv.lastcheck = PF_newcheckclient (sv.lastcheck);
940 sv.lastchecktime = sv.time;
943 // return check if it might be visible
944 ent = EDICT_NUM(sv.lastcheck);
945 if (ent->free || ent->v.health <= 0)
947 RETURN_EDICT(sv.edicts);
951 // if current entity can't possibly see the check entity, return 0
952 self = PROG_TO_EDICT(pr_global_struct->self);
953 VectorAdd (self->v.origin, self->v.view_ofs, view);
954 leaf = Mod_PointInLeaf (view, sv.worldmodel);
955 l = (leaf - sv.worldmodel->leafs) - 1;
956 if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
959 RETURN_EDICT(sv.edicts);
963 // might be able to see it
968 //============================================================================
975 Sends text over to the client's execution buffer
977 stuffcmd (clientent, value)
980 void PF_stuffcmd (void)
986 entnum = G_EDICTNUM(OFS_PARM0);
987 if (entnum < 1 || entnum > svs.maxclients)
988 PR_RunError ("Parm 0 not a client");
989 str = G_STRING(OFS_PARM1);
992 host_client = &svs.clients[entnum-1];
993 Host_ClientCommands ("%s", str);
1001 Sends text over to the client's execution buffer
1006 void PF_localcmd (void)
1010 str = G_STRING(OFS_PARM0);
1025 str = G_STRING(OFS_PARM0);
1027 G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str);
1037 void PF_cvar_set (void)
1041 var = G_STRING(OFS_PARM0);
1042 val = G_STRING(OFS_PARM1);
1044 Cvar_Set (var, val);
1051 Returns a chain of entities that have origins within a spherical area
1053 findradius (origin, radius)
1056 void PF_findradius (void)
1058 edict_t *ent, *chain;
1064 chain = (edict_t *)sv.edicts;
1066 org = G_VECTOR(OFS_PARM0);
1067 rad = G_FLOAT(OFS_PARM1);
1069 ent = NEXT_EDICT(sv.edicts);
1070 for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
1074 if (ent->v.solid == SOLID_NOT)
1076 for (j=0 ; j<3 ; j++)
1077 eorg[j] = org[j] - (ent->v.origin[j] + (ent->v.mins[j] + ent->v.maxs[j])*0.5);
1078 if (Length(eorg) > rad)
1081 ent->v.chain = EDICT_TO_PROG(chain);
1085 RETURN_EDICT(chain);
1094 void PF_dprint (void)
1096 Con_DPrintf ("%s",PF_VarString(0));
1099 char pr_string_temp[128];
1104 v = G_FLOAT(OFS_PARM0);
1106 // LordHavoc: ftos improvement
1107 sprintf (pr_string_temp, "%g", v);
1110 sprintf (pr_string_temp, "%d",(int)v);
1112 sprintf (pr_string_temp, "%5.1f",v);
1114 G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
1120 v = G_FLOAT(OFS_PARM0);
1121 G_FLOAT(OFS_RETURN) = fabs(v);
1126 sprintf (pr_string_temp, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
1127 G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
1132 sprintf (pr_string_temp, "entity %i", G_EDICTNUM(OFS_PARM0));
1133 G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
1136 void PF_Spawn (void)
1143 void PF_Remove (void)
1147 ed = G_EDICT(OFS_PARM0);
1148 if (ed == sv.edicts)
1149 PR_RunError("remove: tried to remove world\n");
1150 if (NUM_FOR_EDICT(ed) <= svs.maxclients)
1151 PR_RunError("remove: tried to remove a client\n");
1156 // entity (entity start, .string field, string match) find = #5;
1164 e = G_EDICTNUM(OFS_PARM0);
1165 f = G_INT(OFS_PARM1);
1166 s = G_STRING(OFS_PARM2);
1169 RETURN_EDICT(sv.edicts);
1173 for (e++ ; e < sv.num_edicts ; e++)
1188 RETURN_EDICT(sv.edicts);
1191 // LordHavoc: added this for searching float, int, and entity reference fields
1192 void PF_FindFloat (void)
1199 e = G_EDICTNUM(OFS_PARM0);
1200 f = G_INT(OFS_PARM1);
1201 s = G_FLOAT(OFS_PARM2);
1203 for (e++ ; e < sv.num_edicts ; e++)
1208 if (E_FLOAT(ed,f) == s)
1215 RETURN_EDICT(sv.edicts);
1218 // chained search for strings in entity fields
1219 // entity(.string field, string match) findchain = #402;
1220 void PF_findchain (void)
1225 edict_t *ent, *chain;
1227 chain = (edict_t *)sv.edicts;
1229 f = G_INT(OFS_PARM0);
1230 s = G_STRING(OFS_PARM1);
1233 RETURN_EDICT(sv.edicts);
1237 ent = NEXT_EDICT(sv.edicts);
1238 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1242 t = E_STRING(ent,f);
1248 ent->v.chain = EDICT_TO_PROG(chain);
1252 RETURN_EDICT(chain);
1255 // LordHavoc: chained search for float, int, and entity reference fields
1256 // entity(.string field, float match) findchainfloat = #403;
1257 void PF_findchainfloat (void)
1262 edict_t *ent, *chain;
1264 chain = (edict_t *)sv.edicts;
1266 f = G_INT(OFS_PARM0);
1267 s = G_FLOAT(OFS_PARM1);
1269 ent = NEXT_EDICT(sv.edicts);
1270 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1274 if (E_FLOAT(ent,f) != s)
1277 ent->v.chain = EDICT_TO_PROG(chain);
1281 RETURN_EDICT(chain);
1284 void PR_CheckEmptyString (char *s)
1287 PR_RunError ("Bad string");
1290 void PF_precache_file (void)
1291 { // precache_file is only used to copy files with qcc, it does nothing
1292 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1295 void PF_precache_sound (void)
1300 if (sv.state != ss_loading)
1301 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1303 s = G_STRING(OFS_PARM0);
1304 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1305 PR_CheckEmptyString (s);
1307 for (i=0 ; i<MAX_SOUNDS ; i++)
1309 if (!sv.sound_precache[i])
1311 sv.sound_precache[i] = s;
1314 if (!strcmp(sv.sound_precache[i], s))
1317 PR_RunError ("PF_precache_sound: overflow");
1320 void PF_precache_model (void)
1325 if (sv.state != ss_loading)
1326 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1328 s = G_STRING(OFS_PARM0);
1329 if (sv.worldmodel->ishlbsp && ((!s) || (!s[0])))
1331 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1332 PR_CheckEmptyString (s);
1334 for (i=0 ; i<MAX_MODELS ; i++)
1336 if (!sv.model_precache[i])
1338 sv.model_precache[i] = s;
1339 sv.models[i] = Mod_ForName (s, true, true, false);
1342 if (!strcmp(sv.model_precache[i], s))
1345 PR_RunError ("PF_precache_model: overflow");
1349 void PF_coredump (void)
1354 void PF_traceon (void)
1359 void PF_traceoff (void)
1364 void PF_eprint (void)
1366 ED_PrintNum (G_EDICTNUM(OFS_PARM0));
1373 float(float yaw, float dist) walkmove
1376 void PF_walkmove (void)
1384 ent = PROG_TO_EDICT(pr_global_struct->self);
1385 yaw = G_FLOAT(OFS_PARM0);
1386 dist = G_FLOAT(OFS_PARM1);
1388 if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1390 G_FLOAT(OFS_RETURN) = 0;
1394 yaw = yaw*M_PI*2 / 360;
1396 move[0] = cos(yaw)*dist;
1397 move[1] = sin(yaw)*dist;
1400 // save program state, because SV_movestep may call other progs
1401 oldf = pr_xfunction;
1402 oldself = pr_global_struct->self;
1404 G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
1407 // restore program state
1408 pr_xfunction = oldf;
1409 pr_global_struct->self = oldself;
1419 void PF_droptofloor (void)
1425 ent = PROG_TO_EDICT(pr_global_struct->self);
1427 VectorCopy (ent->v.origin, end);
1430 trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
1432 if (trace.fraction == 1 || trace.allsolid)
1433 G_FLOAT(OFS_RETURN) = 0;
1436 VectorCopy (trace.endpos, ent->v.origin);
1437 SV_LinkEdict (ent, false);
1438 ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
1439 ent->v.groundentity = EDICT_TO_PROG(trace.ent);
1440 G_FLOAT(OFS_RETURN) = 1;
1448 void(float style, string value) lightstyle
1451 void PF_lightstyle (void)
1458 style = G_FLOAT(OFS_PARM0);
1459 val = G_STRING(OFS_PARM1);
1461 // change the string in sv
1462 sv.lightstyles[style] = val;
1464 // send message to all clients on this server
1465 if (sv.state != ss_active)
1468 for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
1469 if (client->active || client->spawned)
1471 MSG_WriteChar (&client->message, svc_lightstyle);
1472 MSG_WriteChar (&client->message,style);
1473 MSG_WriteString (&client->message, val);
1480 f = G_FLOAT(OFS_PARM0);
1482 G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1484 G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1486 void PF_floor (void)
1488 G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
1492 G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
1501 void PF_checkbottom (void)
1503 G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0));
1511 void PF_pointcontents (void)
1513 G_FLOAT(OFS_RETURN) = SV_PointContents (G_VECTOR(OFS_PARM0));
1520 entity nextent(entity)
1523 void PF_nextent (void)
1528 i = G_EDICTNUM(OFS_PARM0);
1532 if (i == sv.num_edicts)
1534 RETURN_EDICT(sv.edicts);
1550 Pick a vector for the player to shoot along
1551 vector aim(entity, missilespeed)
1556 edict_t *ent, *check, *bestent;
1557 vec3_t start, dir, end, bestdir;
1560 float dist, bestdist;
1563 ent = G_EDICT(OFS_PARM0);
1564 speed = G_FLOAT(OFS_PARM1);
1566 VectorCopy (ent->v.origin, start);
1569 // try sending a trace straight
1570 VectorCopy (pr_global_struct->v_forward, dir);
1571 VectorMA (start, 2048, dir, end);
1572 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1573 if (tr.ent && tr.ent->v.takedamage == DAMAGE_AIM
1574 && (!teamplay.integer || ent->v.team <=0 || ent->v.team != tr.ent->v.team) )
1576 VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
1581 // try all possible entities
1582 VectorCopy (dir, bestdir);
1583 bestdist = sv_aim.value;
1586 check = NEXT_EDICT(sv.edicts);
1587 for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
1589 if (check->v.takedamage != DAMAGE_AIM)
1593 if (teamplay.integer && ent->v.team > 0 && ent->v.team == check->v.team)
1594 continue; // don't aim at teammate
1595 for (j=0 ; j<3 ; j++)
1596 end[j] = check->v.origin[j]
1597 + 0.5*(check->v.mins[j] + check->v.maxs[j]);
1598 VectorSubtract (end, start, dir);
1599 VectorNormalize (dir);
1600 dist = DotProduct (dir, pr_global_struct->v_forward);
1601 if (dist < bestdist)
1602 continue; // to far to turn
1603 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1604 if (tr.ent == check)
1605 { // can shoot at this one
1613 VectorSubtract (bestent->v.origin, ent->v.origin, dir);
1614 dist = DotProduct (dir, pr_global_struct->v_forward);
1615 VectorScale (pr_global_struct->v_forward, dist, end);
1617 VectorNormalize (end);
1618 VectorCopy (end, G_VECTOR(OFS_RETURN));
1622 VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
1630 This was a major timewaster in progs, so it was converted to C
1633 void PF_changeyaw (void)
1636 float ideal, current, move, speed;
1638 ent = PROG_TO_EDICT(pr_global_struct->self);
1639 current = ANGLEMOD(ent->v.angles[1]);
1640 ideal = ent->v.ideal_yaw;
1641 speed = ent->v.yaw_speed;
1643 if (current == ideal)
1645 move = ideal - current;
1646 if (ideal > current)
1667 ent->v.angles[1] = ANGLEMOD (current + move);
1675 void PF_changepitch (void)
1678 float ideal, current, move, speed;
1681 ent = G_EDICT(OFS_PARM0);
1682 current = ANGLEMOD( ent->v.angles[0] );
1683 if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
1684 ideal = val->_float;
1687 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1690 if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
1691 speed = val->_float;
1694 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1698 if (current == ideal)
1700 move = ideal - current;
1701 if (ideal > current)
1722 ent->v.angles[0] = ANGLEMOD (current + move);
1726 ===============================================================================
1730 ===============================================================================
1733 #define MSG_BROADCAST 0 // unreliable to all
1734 #define MSG_ONE 1 // reliable to one (msg_entity)
1735 #define MSG_ALL 2 // reliable to all
1736 #define MSG_INIT 3 // write to the init string
1738 sizebuf_t *WriteDest (void)
1744 dest = G_FLOAT(OFS_PARM0);
1748 return &sv.datagram;
1751 ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
1752 entnum = NUM_FOR_EDICT(ent);
1753 if (entnum < 1 || entnum > svs.maxclients)
1754 PR_RunError ("WriteDest: not a client");
1755 return &svs.clients[entnum-1].message;
1758 return &sv.reliable_datagram;
1764 PR_RunError ("WriteDest: bad destination");
1771 void PF_WriteByte (void)
1773 MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
1776 void PF_WriteChar (void)
1778 MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
1781 void PF_WriteShort (void)
1783 MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
1786 void PF_WriteLong (void)
1788 MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
1791 void PF_WriteAngle (void)
1793 MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
1796 void PF_WriteCoord (void)
1798 MSG_WriteFloatCoord (WriteDest(), G_FLOAT(OFS_PARM1));
1801 void PF_WriteString (void)
1803 MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
1807 void PF_WriteEntity (void)
1809 MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
1812 //=============================================================================
1814 int SV_ModelIndex (char *name);
1816 void PF_makestatic (void)
1821 ent = G_EDICT(OFS_PARM0);
1824 if (ent->v.modelindex >= 256 || ent->v.frame >= 256)
1829 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1830 MSG_WriteShort (&sv.signon, ent->v.modelindex);
1831 MSG_WriteShort (&sv.signon, ent->v.frame);
1835 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1836 MSG_WriteByte (&sv.signon, ent->v.modelindex);
1837 MSG_WriteByte (&sv.signon, ent->v.frame);
1840 MSG_WriteByte (&sv.signon, ent->v.colormap);
1841 MSG_WriteByte (&sv.signon, ent->v.skin);
1842 for (i=0 ; i<3 ; i++)
1844 MSG_WriteFloatCoord(&sv.signon, ent->v.origin[i]);
1845 MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
1848 // throw the entity away now
1852 //=============================================================================
1859 void PF_setspawnparms (void)
1865 ent = G_EDICT(OFS_PARM0);
1866 i = NUM_FOR_EDICT(ent);
1867 if (i < 1 || i > svs.maxclients)
1868 PR_RunError ("Entity is not a client");
1870 // copy spawn parms out of the client_t
1871 client = svs.clients + (i-1);
1873 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1874 (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
1882 void PF_changelevel (void)
1886 // make sure we don't issue two changelevels
1887 if (svs.changelevel_issued)
1889 svs.changelevel_issued = true;
1891 s = G_STRING(OFS_PARM0);
1892 Cbuf_AddText (va("changelevel %s\n",s));
1897 G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
1902 G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
1907 G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
1914 Returns a vector of length < 1
1919 void PF_randomvec (void)
1924 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1925 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1926 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1928 while (DotProduct(temp, temp) >= 1);
1929 VectorCopy (temp, G_VECTOR(OFS_RETURN));
1932 void SV_LightPoint (vec3_t color, vec3_t p);
1937 Returns a color vector indicating the lighting at the requested point.
1939 (Internal Operation note: actually measures the light beneath the point, just like
1940 the model lighting on the client)
1945 void PF_GetLight (void)
1949 p = G_VECTOR(OFS_PARM0);
1950 SV_LightPoint (color, p);
1951 VectorCopy (color, G_VECTOR(OFS_RETURN));
1954 #define MAX_QC_CVARS 128
1955 cvar_t qc_cvar[MAX_QC_CVARS];
1958 void PF_registercvar (void)
1962 name = G_STRING(OFS_PARM1);
1963 value = G_STRING(OFS_PARM2);
1964 G_FLOAT(OFS_RETURN) = 0;
1965 // first check to see if it has already been defined
1966 if (Cvar_FindVar (name))
1969 // check for overlap with a command
1970 if (Cmd_Exists (name))
1972 Con_Printf ("PF_registercvar: %s is a command\n", name);
1976 if (currentqc_cvar >= MAX_QC_CVARS)
1977 PR_RunError ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
1979 // copy the name and value
1980 variable = &qc_cvar[currentqc_cvar++];
1981 variable->name = Z_Malloc (strlen(name)+1);
1982 strcpy (variable->name, name);
1983 variable->string = Z_Malloc (strlen(value)+1);
1984 strcpy (variable->string, value);
1985 variable->value = atof (value);
1987 // link the variable in
1988 variable->next = cvar_vars;
1989 cvar_vars = variable;
1990 G_FLOAT(OFS_RETURN) = 1; // success
1997 returns the minimum of two supplied floats
2004 // LordHavoc: 3+ argument enhancement suggested by FrikaC
2006 G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2007 else if (pr_argc >= 3)
2010 float f = G_FLOAT(OFS_PARM0);
2011 for (i = 1;i < pr_argc;i++)
2012 if (G_FLOAT((OFS_PARM0+i*3)) < f)
2013 f = G_FLOAT((OFS_PARM0+i*3));
2014 G_FLOAT(OFS_RETURN) = f;
2017 PR_RunError("min: must supply at least 2 floats\n");
2024 returns the maximum of two supplied floats
2031 // LordHavoc: 3+ argument enhancement suggested by FrikaC
2033 G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2034 else if (pr_argc >= 3)
2037 float f = G_FLOAT(OFS_PARM0);
2038 for (i = 1;i < pr_argc;i++)
2039 if (G_FLOAT((OFS_PARM0+i*3)) > f)
2040 f = G_FLOAT((OFS_PARM0+i*3));
2041 G_FLOAT(OFS_RETURN) = f;
2044 PR_RunError("max: must supply at least 2 floats\n");
2051 returns number bounded by supplied range
2053 min(min, value, max)
2056 void PF_bound (void)
2058 G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
2065 returns a raised to power b
2072 G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2079 copies data from one entity to another
2081 copyentity(src, dst)
2084 void PF_copyentity (void)
2087 in = G_EDICT(OFS_PARM0);
2088 out = G_EDICT(OFS_PARM1);
2089 memcpy(out, in, pr_edict_size);
2096 sets the color of a client and broadcasts the update to all connected clients
2098 setcolor(clientent, value)
2101 void PF_setcolor (void)
2106 entnum = G_EDICTNUM(OFS_PARM0);
2107 i = G_FLOAT(OFS_PARM1);
2109 if (entnum < 1 || entnum > svs.maxclients)
2111 Con_Printf ("tried to setcolor a non-client\n");
2115 client = &svs.clients[entnum-1];
2117 client->edict->v.team = (i & 15) + 1;
2119 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
2120 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
2121 MSG_WriteByte (&sv.reliable_datagram, i);
2128 effect(origin, modelname, startframe, framecount, framerate)
2131 void PF_effect (void)
2134 s = G_STRING(OFS_PARM1);
2136 PR_RunError("effect: no model specified\n");
2138 SV_StartEffect(G_VECTOR(OFS_PARM0), SV_ModelIndex(s), G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
2141 void PF_te_blood (void)
2143 if (G_FLOAT(OFS_PARM2) < 1)
2145 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2146 MSG_WriteByte(&sv.datagram, TE_BLOOD);
2148 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2149 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2150 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2152 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2153 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2154 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2156 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2159 void PF_te_bloodshower (void)
2161 if (G_FLOAT(OFS_PARM3) < 1)
2163 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2164 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
2166 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2167 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2168 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2170 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2171 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2172 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2174 MSG_WriteFloatCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
2176 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2179 void PF_te_explosionrgb (void)
2181 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2182 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
2184 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2185 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2186 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2188 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
2189 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
2190 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
2193 void PF_te_particlecube (void)
2195 if (G_FLOAT(OFS_PARM3) < 1)
2197 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2198 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
2200 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2201 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2202 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2204 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2205 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2206 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2208 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2209 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2210 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2212 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2214 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2215 // gravity true/false
2216 MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
2218 MSG_WriteFloatCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
2221 void PF_te_particlerain (void)
2223 if (G_FLOAT(OFS_PARM3) < 1)
2225 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2226 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
2228 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2229 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2230 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2232 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2233 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2234 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2236 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2237 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2238 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2240 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2242 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2245 void PF_te_particlesnow (void)
2247 if (G_FLOAT(OFS_PARM3) < 1)
2249 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2250 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
2252 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2253 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2254 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2256 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2257 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2258 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2260 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2261 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2262 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2264 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2266 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2269 void PF_te_spark (void)
2271 if (G_FLOAT(OFS_PARM2) < 1)
2273 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2274 MSG_WriteByte(&sv.datagram, TE_SPARK);
2276 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2277 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2278 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2280 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2281 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2282 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2284 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2287 void PF_te_gunshotquad (void)
2289 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2290 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
2292 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2293 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2294 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2297 void PF_te_spikequad (void)
2299 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2300 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
2302 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2303 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2304 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2307 void PF_te_superspikequad (void)
2309 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2310 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
2312 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2313 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2314 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2317 void PF_te_explosionquad (void)
2319 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2320 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2322 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2323 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2324 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2327 void PF_te_smallflash (void)
2329 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2330 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2332 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2333 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2334 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2337 void PF_te_customflash (void)
2339 if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2341 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2342 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2344 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2345 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2346 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2348 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2350 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255));
2352 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
2353 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
2354 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
2357 void PF_te_gunshot (void)
2359 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2360 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2362 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2363 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2364 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2367 void PF_te_spike (void)
2369 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2370 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2372 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2373 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2374 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2377 void PF_te_superspike (void)
2379 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2380 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2382 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2383 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2384 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2387 void PF_te_explosion (void)
2389 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2390 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2392 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2393 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2394 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2397 void PF_te_tarexplosion (void)
2399 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2400 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2402 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2403 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2404 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2407 void PF_te_wizspike (void)
2409 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2410 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2412 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2413 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2414 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2417 void PF_te_knightspike (void)
2419 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2420 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2422 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2423 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2424 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2427 void PF_te_lavasplash (void)
2429 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2430 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2432 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2433 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2434 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2437 void PF_te_teleport (void)
2439 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2440 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2442 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2443 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2444 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2447 void PF_te_explosion2 (void)
2449 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2450 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2452 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2453 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2454 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2456 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
2459 void PF_te_lightning1 (void)
2461 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2462 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2464 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2466 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2467 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2468 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2470 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2471 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2472 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2475 void PF_te_lightning2 (void)
2477 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2478 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2480 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2482 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2483 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2484 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2486 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2487 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2488 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2491 void PF_te_lightning3 (void)
2493 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2494 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2496 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2498 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2499 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2500 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2502 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2503 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2504 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2507 void PF_te_beam (void)
2509 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2510 MSG_WriteByte(&sv.datagram, TE_BEAM);
2512 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2514 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2515 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2516 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2518 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2519 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2520 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2523 void PF_Fixme (void)
2525 PR_RunError ("unimplemented builtin"); // LordHavoc: was misspelled (bulitin)
2530 builtin_t pr_builtin[] =
2533 PF_makevectors, // void(entity e) makevectors = #1;
2534 PF_setorigin, // void(entity e, vector o) setorigin = #2;
2535 PF_setmodel, // void(entity e, string m) setmodel = #3;
2536 PF_setsize, // void(entity e, vector min, vector max) setsize = #4;
2537 PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5;
2538 PF_break, // void() break = #6;
2539 PF_random, // float() random = #7;
2540 PF_sound, // void(entity e, float chan, string samp) sound = #8;
2541 PF_normalize, // vector(vector v) normalize = #9;
2542 PF_error, // void(string e) error = #10;
2543 PF_objerror, // void(string e) objerror = #11;
2544 PF_vlen, // float(vector v) vlen = #12;
2545 PF_vectoyaw, // float(vector v) vectoyaw = #13;
2546 PF_Spawn, // entity() spawn = #14;
2547 PF_Remove, // void(entity e) remove = #15;
2548 PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16;
2549 PF_checkclient, // entity() clientlist = #17;
2550 PF_Find, // entity(entity start, .string fld, string match) find = #18;
2551 PF_precache_sound, // void(string s) precache_sound = #19;
2552 PF_precache_model, // void(string s) precache_model = #20;
2553 PF_stuffcmd, // void(entity client, string s)stuffcmd = #21;
2554 PF_findradius, // entity(vector org, float rad) findradius = #22;
2555 PF_bprint, // void(string s) bprint = #23;
2556 PF_sprint, // void(entity client, string s) sprint = #24;
2557 PF_dprint, // void(string s) dprint = #25;
2558 PF_ftos, // void(string s) ftos = #26;
2559 PF_vtos, // void(string s) vtos = #27;
2563 PF_eprint, // void(entity e) debug print an entire entity
2564 PF_walkmove, // float(float yaw, float dist) walkmove
2565 PF_Fixme, // float(float yaw, float dist) walkmove
2615 PF_precache_sound, // precache_sound2 is different only for qcc
2620 PF_Fixme, // #79 LordHavoc: dunno who owns 79-89, so these are just padding
2632 PF_tracebox, // #90 LordHavoc builtin range (9x)
2633 PF_randomvec, // #91
2635 PF_registercvar, // #93
2640 PF_FindFloat, // #98
2641 PF_checkextension, // #99
2642 #define a PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme,
2643 #define aa a a a a a a a a a a
2647 PF_copyentity, // #400 LordHavoc: builtin range (4xx)
2648 PF_setcolor, // #401
2649 PF_findchain, // #402
2650 PF_findchainfloat, // #403
2652 PF_te_blood, // #405
2653 PF_te_bloodshower, // #406
2654 PF_te_explosionrgb, // #407
2655 PF_te_particlecube, // #408
2656 PF_te_particlerain, // #409
2657 PF_te_particlesnow, // #410
2658 PF_te_spark, // #411
2659 PF_te_gunshotquad, // #412
2660 PF_te_spikequad, // #413
2661 PF_te_superspikequad, // #414
2662 PF_te_explosionquad, // #415
2663 PF_te_smallflash, // #416
2664 PF_te_customflash, // #417
2665 PF_te_gunshot, // #418
2666 PF_te_spike, // #419
2667 PF_te_superspike, // #420
2668 PF_te_explosion, // #421
2669 PF_te_tarexplosion, // #422
2670 PF_te_wizspike, // #423
2671 PF_te_knightspike, // #424
2672 PF_te_lavasplash, // #425
2673 PF_te_teleport, // #426
2674 PF_te_explosion2, // #427
2675 PF_te_lightning1, // #428
2676 PF_te_lightning2, // #429
2677 PF_te_lightning3, // #430
2679 PF_vectorvectors, // #432
2682 builtin_t *pr_builtins = pr_builtin;
2683 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);