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(start, 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_WriteDPCoord(&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 qbyte 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 // LordHavoc: added this to semi-fix the problem of using many ftos calls in a print
1100 #define STRINGTEMP_BUFFERS 16
1101 #define STRINGTEMP_LENGTH 128
1102 static char pr_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH];
1103 static int pr_string_tempindex = 0;
1105 static char *PR_GetTempString(void)
1108 s = pr_string_temp[pr_string_tempindex];
1109 pr_string_tempindex = (pr_string_tempindex + 1) % STRINGTEMP_BUFFERS;
1117 v = G_FLOAT(OFS_PARM0);
1119 s = PR_GetTempString();
1122 sprintf (s, "%d",(int)v);
1124 sprintf (s, "%5.1f",v);
1126 // LordHavoc: ftos improvement
1127 sprintf (s, "%g", v);
1128 G_INT(OFS_RETURN) = s - pr_strings;
1134 v = G_FLOAT(OFS_PARM0);
1135 G_FLOAT(OFS_RETURN) = fabs(v);
1141 s = PR_GetTempString();
1142 sprintf (s, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
1143 G_INT(OFS_RETURN) = s - pr_strings;
1149 s = PR_GetTempString();
1150 sprintf (s, "entity %i", G_EDICTNUM(OFS_PARM0));
1151 G_INT(OFS_RETURN) = s - pr_strings;
1154 void PF_Spawn (void)
1161 void PF_Remove (void)
1165 ed = G_EDICT(OFS_PARM0);
1166 if (ed == sv.edicts)
1167 PR_RunError("remove: tried to remove world\n");
1168 if (NUM_FOR_EDICT(ed) <= svs.maxclients)
1169 PR_RunError("remove: tried to remove a client\n");
1174 // entity (entity start, .string field, string match) find = #5;
1182 e = G_EDICTNUM(OFS_PARM0);
1183 f = G_INT(OFS_PARM1);
1184 s = G_STRING(OFS_PARM2);
1187 RETURN_EDICT(sv.edicts);
1191 for (e++ ; e < sv.num_edicts ; e++)
1206 RETURN_EDICT(sv.edicts);
1209 // LordHavoc: added this for searching float, int, and entity reference fields
1210 void PF_FindFloat (void)
1217 e = G_EDICTNUM(OFS_PARM0);
1218 f = G_INT(OFS_PARM1);
1219 s = G_FLOAT(OFS_PARM2);
1221 for (e++ ; e < sv.num_edicts ; e++)
1226 if (E_FLOAT(ed,f) == s)
1233 RETURN_EDICT(sv.edicts);
1236 // chained search for strings in entity fields
1237 // entity(.string field, string match) findchain = #402;
1238 void PF_findchain (void)
1243 edict_t *ent, *chain;
1245 chain = (edict_t *)sv.edicts;
1247 f = G_INT(OFS_PARM0);
1248 s = G_STRING(OFS_PARM1);
1251 RETURN_EDICT(sv.edicts);
1255 ent = NEXT_EDICT(sv.edicts);
1256 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1260 t = E_STRING(ent,f);
1266 ent->v.chain = EDICT_TO_PROG(chain);
1270 RETURN_EDICT(chain);
1273 // LordHavoc: chained search for float, int, and entity reference fields
1274 // entity(.string field, float match) findchainfloat = #403;
1275 void PF_findchainfloat (void)
1280 edict_t *ent, *chain;
1282 chain = (edict_t *)sv.edicts;
1284 f = G_INT(OFS_PARM0);
1285 s = G_FLOAT(OFS_PARM1);
1287 ent = NEXT_EDICT(sv.edicts);
1288 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1292 if (E_FLOAT(ent,f) != s)
1295 ent->v.chain = EDICT_TO_PROG(chain);
1299 RETURN_EDICT(chain);
1302 void PR_CheckEmptyString (char *s)
1305 PR_RunError ("Bad string");
1308 void PF_precache_file (void)
1309 { // precache_file is only used to copy files with qcc, it does nothing
1310 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1313 void PF_precache_sound (void)
1318 if (sv.state != ss_loading)
1319 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1321 s = G_STRING(OFS_PARM0);
1322 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1323 PR_CheckEmptyString (s);
1325 for (i=0 ; i<MAX_SOUNDS ; i++)
1327 if (!sv.sound_precache[i])
1329 sv.sound_precache[i] = s;
1332 if (!strcmp(sv.sound_precache[i], s))
1335 PR_RunError ("PF_precache_sound: overflow");
1338 void PF_precache_model (void)
1343 if (sv.state != ss_loading)
1344 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1346 s = G_STRING(OFS_PARM0);
1347 if (sv.worldmodel->ishlbsp && ((!s) || (!s[0])))
1349 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1350 PR_CheckEmptyString (s);
1352 for (i=0 ; i<MAX_MODELS ; i++)
1354 if (!sv.model_precache[i])
1356 sv.model_precache[i] = s;
1357 sv.models[i] = Mod_ForName (s, true, false, false);
1360 if (!strcmp(sv.model_precache[i], s))
1363 PR_RunError ("PF_precache_model: overflow");
1367 void PF_coredump (void)
1372 void PF_traceon (void)
1377 void PF_traceoff (void)
1382 void PF_eprint (void)
1384 ED_PrintNum (G_EDICTNUM(OFS_PARM0));
1391 float(float yaw, float dist) walkmove
1394 void PF_walkmove (void)
1402 ent = PROG_TO_EDICT(pr_global_struct->self);
1403 yaw = G_FLOAT(OFS_PARM0);
1404 dist = G_FLOAT(OFS_PARM1);
1406 if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1408 G_FLOAT(OFS_RETURN) = 0;
1412 yaw = yaw*M_PI*2 / 360;
1414 move[0] = cos(yaw)*dist;
1415 move[1] = sin(yaw)*dist;
1418 // save program state, because SV_movestep may call other progs
1419 oldf = pr_xfunction;
1420 oldself = pr_global_struct->self;
1422 G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
1425 // restore program state
1426 pr_xfunction = oldf;
1427 pr_global_struct->self = oldself;
1437 void PF_droptofloor (void)
1443 ent = PROG_TO_EDICT(pr_global_struct->self);
1445 VectorCopy (ent->v.origin, end);
1448 trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
1450 if (trace.fraction == 1 || trace.allsolid)
1451 G_FLOAT(OFS_RETURN) = 0;
1454 VectorCopy (trace.endpos, ent->v.origin);
1455 SV_LinkEdict (ent, false);
1456 ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
1457 ent->v.groundentity = EDICT_TO_PROG(trace.ent);
1458 G_FLOAT(OFS_RETURN) = 1;
1459 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1460 ent->suspendedinairflag = true;
1468 void(float style, string value) lightstyle
1471 void PF_lightstyle (void)
1478 style = G_FLOAT(OFS_PARM0);
1479 val = G_STRING(OFS_PARM1);
1481 // change the string in sv
1482 sv.lightstyles[style] = val;
1484 // send message to all clients on this server
1485 if (sv.state != ss_active)
1488 for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
1489 if (client->active || client->spawned)
1491 MSG_WriteChar (&client->message, svc_lightstyle);
1492 MSG_WriteChar (&client->message,style);
1493 MSG_WriteString (&client->message, val);
1500 f = G_FLOAT(OFS_PARM0);
1502 G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1504 G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1506 void PF_floor (void)
1508 G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
1512 G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
1521 void PF_checkbottom (void)
1523 G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0));
1531 void PF_pointcontents (void)
1533 G_FLOAT(OFS_RETURN) = SV_PointContents (G_VECTOR(OFS_PARM0));
1540 entity nextent(entity)
1543 void PF_nextent (void)
1548 i = G_EDICTNUM(OFS_PARM0);
1552 if (i == sv.num_edicts)
1554 RETURN_EDICT(sv.edicts);
1570 Pick a vector for the player to shoot along
1571 vector aim(entity, missilespeed)
1576 edict_t *ent, *check, *bestent;
1577 vec3_t start, dir, end, bestdir;
1580 float dist, bestdist;
1583 ent = G_EDICT(OFS_PARM0);
1584 speed = G_FLOAT(OFS_PARM1);
1586 VectorCopy (ent->v.origin, start);
1589 // try sending a trace straight
1590 VectorCopy (pr_global_struct->v_forward, dir);
1591 VectorMA (start, 2048, dir, end);
1592 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1593 if (tr.ent && tr.ent->v.takedamage == DAMAGE_AIM
1594 && (!teamplay.integer || ent->v.team <=0 || ent->v.team != tr.ent->v.team) )
1596 VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
1601 // try all possible entities
1602 VectorCopy (dir, bestdir);
1603 bestdist = sv_aim.value;
1606 check = NEXT_EDICT(sv.edicts);
1607 for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
1609 if (check->v.takedamage != DAMAGE_AIM)
1613 if (teamplay.integer && ent->v.team > 0 && ent->v.team == check->v.team)
1614 continue; // don't aim at teammate
1615 for (j=0 ; j<3 ; j++)
1616 end[j] = check->v.origin[j]
1617 + 0.5*(check->v.mins[j] + check->v.maxs[j]);
1618 VectorSubtract (end, start, dir);
1619 VectorNormalize (dir);
1620 dist = DotProduct (dir, pr_global_struct->v_forward);
1621 if (dist < bestdist)
1622 continue; // to far to turn
1623 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1624 if (tr.ent == check)
1625 { // can shoot at this one
1633 VectorSubtract (bestent->v.origin, ent->v.origin, dir);
1634 dist = DotProduct (dir, pr_global_struct->v_forward);
1635 VectorScale (pr_global_struct->v_forward, dist, end);
1637 VectorNormalize (end);
1638 VectorCopy (end, G_VECTOR(OFS_RETURN));
1642 VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
1650 This was a major timewaster in progs, so it was converted to C
1653 void PF_changeyaw (void)
1656 float ideal, current, move, speed;
1658 ent = PROG_TO_EDICT(pr_global_struct->self);
1659 current = ANGLEMOD(ent->v.angles[1]);
1660 ideal = ent->v.ideal_yaw;
1661 speed = ent->v.yaw_speed;
1663 if (current == ideal)
1665 move = ideal - current;
1666 if (ideal > current)
1687 ent->v.angles[1] = ANGLEMOD (current + move);
1695 void PF_changepitch (void)
1698 float ideal, current, move, speed;
1701 ent = G_EDICT(OFS_PARM0);
1702 current = ANGLEMOD( ent->v.angles[0] );
1703 if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
1704 ideal = val->_float;
1707 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1710 if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
1711 speed = val->_float;
1714 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1718 if (current == ideal)
1720 move = ideal - current;
1721 if (ideal > current)
1742 ent->v.angles[0] = ANGLEMOD (current + move);
1746 ===============================================================================
1750 ===============================================================================
1753 #define MSG_BROADCAST 0 // unreliable to all
1754 #define MSG_ONE 1 // reliable to one (msg_entity)
1755 #define MSG_ALL 2 // reliable to all
1756 #define MSG_INIT 3 // write to the init string
1758 sizebuf_t *WriteDest (void)
1764 dest = G_FLOAT(OFS_PARM0);
1768 return &sv.datagram;
1771 ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
1772 entnum = NUM_FOR_EDICT(ent);
1773 if (entnum < 1 || entnum > svs.maxclients)
1774 PR_RunError ("WriteDest: not a client");
1775 return &svs.clients[entnum-1].message;
1778 return &sv.reliable_datagram;
1784 PR_RunError ("WriteDest: bad destination");
1791 void PF_WriteByte (void)
1793 MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
1796 void PF_WriteChar (void)
1798 MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
1801 void PF_WriteShort (void)
1803 MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
1806 void PF_WriteLong (void)
1808 MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
1811 void PF_WriteAngle (void)
1813 MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
1816 void PF_WriteCoord (void)
1818 MSG_WriteDPCoord (WriteDest(), G_FLOAT(OFS_PARM1));
1821 void PF_WriteString (void)
1823 MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
1827 void PF_WriteEntity (void)
1829 MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
1832 //=============================================================================
1834 int SV_ModelIndex (char *name);
1836 void PF_makestatic (void)
1841 ent = G_EDICT(OFS_PARM0);
1844 if (ent->v.modelindex >= 256 || ent->v.frame >= 256)
1849 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1850 MSG_WriteShort (&sv.signon, ent->v.modelindex);
1851 MSG_WriteShort (&sv.signon, ent->v.frame);
1855 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1856 MSG_WriteByte (&sv.signon, ent->v.modelindex);
1857 MSG_WriteByte (&sv.signon, ent->v.frame);
1860 MSG_WriteByte (&sv.signon, ent->v.colormap);
1861 MSG_WriteByte (&sv.signon, ent->v.skin);
1862 for (i=0 ; i<3 ; i++)
1864 MSG_WriteDPCoord(&sv.signon, ent->v.origin[i]);
1865 MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
1868 // throw the entity away now
1872 //=============================================================================
1879 void PF_setspawnparms (void)
1885 ent = G_EDICT(OFS_PARM0);
1886 i = NUM_FOR_EDICT(ent);
1887 if (i < 1 || i > svs.maxclients)
1888 PR_RunError ("Entity is not a client");
1890 // copy spawn parms out of the client_t
1891 client = svs.clients + (i-1);
1893 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1894 (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
1902 void PF_changelevel (void)
1906 // make sure we don't issue two changelevels
1907 if (svs.changelevel_issued)
1909 svs.changelevel_issued = true;
1911 s = G_STRING(OFS_PARM0);
1912 Cbuf_AddText (va("changelevel %s\n",s));
1917 G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
1922 G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
1927 G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
1934 Returns a vector of length < 1
1939 void PF_randomvec (void)
1944 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1945 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1946 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1948 while (DotProduct(temp, temp) >= 1);
1949 VectorCopy (temp, G_VECTOR(OFS_RETURN));
1952 void SV_LightPoint (vec3_t color, vec3_t p);
1957 Returns a color vector indicating the lighting at the requested point.
1959 (Internal Operation note: actually measures the light beneath the point, just like
1960 the model lighting on the client)
1965 void PF_GetLight (void)
1969 p = G_VECTOR(OFS_PARM0);
1970 SV_LightPoint (color, p);
1971 VectorCopy (color, G_VECTOR(OFS_RETURN));
1974 #define MAX_QC_CVARS 128
1975 cvar_t qc_cvar[MAX_QC_CVARS];
1978 void PF_registercvar (void)
1982 name = G_STRING(OFS_PARM0);
1983 value = G_STRING(OFS_PARM1);
1984 G_FLOAT(OFS_RETURN) = 0;
1985 // first check to see if it has already been defined
1986 if (Cvar_FindVar (name))
1989 // check for overlap with a command
1990 if (Cmd_Exists (name))
1992 Con_Printf ("PF_registercvar: %s is a command\n", name);
1996 if (currentqc_cvar >= MAX_QC_CVARS)
1997 PR_RunError ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
1999 // copy the name and value
2000 variable = &qc_cvar[currentqc_cvar++];
2001 variable->name = Z_Malloc (strlen(name)+1);
2002 strcpy (variable->name, name);
2003 variable->string = Z_Malloc (strlen(value)+1);
2004 strcpy (variable->string, value);
2005 variable->value = atof (value);
2007 // link the variable in
2008 variable->next = cvar_vars;
2009 cvar_vars = variable;
2010 G_FLOAT(OFS_RETURN) = 1; // success
2017 returns the minimum of two supplied floats
2024 // LordHavoc: 3+ argument enhancement suggested by FrikaC
2026 G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2027 else if (pr_argc >= 3)
2030 float f = G_FLOAT(OFS_PARM0);
2031 for (i = 1;i < pr_argc;i++)
2032 if (G_FLOAT((OFS_PARM0+i*3)) < f)
2033 f = G_FLOAT((OFS_PARM0+i*3));
2034 G_FLOAT(OFS_RETURN) = f;
2037 PR_RunError("min: must supply at least 2 floats\n");
2044 returns the maximum of two supplied floats
2051 // LordHavoc: 3+ argument enhancement suggested by FrikaC
2053 G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2054 else if (pr_argc >= 3)
2057 float f = G_FLOAT(OFS_PARM0);
2058 for (i = 1;i < pr_argc;i++)
2059 if (G_FLOAT((OFS_PARM0+i*3)) > f)
2060 f = G_FLOAT((OFS_PARM0+i*3));
2061 G_FLOAT(OFS_RETURN) = f;
2064 PR_RunError("max: must supply at least 2 floats\n");
2071 returns number bounded by supplied range
2073 min(min, value, max)
2076 void PF_bound (void)
2078 G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
2085 returns a raised to power b
2092 G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2099 copies data from one entity to another
2101 copyentity(src, dst)
2104 void PF_copyentity (void)
2107 in = G_EDICT(OFS_PARM0);
2108 out = G_EDICT(OFS_PARM1);
2109 memcpy(out, in, pr_edict_size);
2116 sets the color of a client and broadcasts the update to all connected clients
2118 setcolor(clientent, value)
2121 void PF_setcolor (void)
2126 entnum = G_EDICTNUM(OFS_PARM0);
2127 i = G_FLOAT(OFS_PARM1);
2129 if (entnum < 1 || entnum > svs.maxclients)
2131 Con_Printf ("tried to setcolor a non-client\n");
2135 client = &svs.clients[entnum-1];
2137 client->edict->v.team = (i & 15) + 1;
2139 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
2140 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
2141 MSG_WriteByte (&sv.reliable_datagram, i);
2148 effect(origin, modelname, startframe, framecount, framerate)
2151 void PF_effect (void)
2154 s = G_STRING(OFS_PARM1);
2156 PR_RunError("effect: no model specified\n");
2158 SV_StartEffect(G_VECTOR(OFS_PARM0), SV_ModelIndex(s), G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
2161 void PF_te_blood (void)
2163 if (G_FLOAT(OFS_PARM2) < 1)
2165 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2166 MSG_WriteByte(&sv.datagram, TE_BLOOD);
2168 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2169 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2170 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2172 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2173 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2174 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2176 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2179 void PF_te_bloodshower (void)
2181 if (G_FLOAT(OFS_PARM3) < 1)
2183 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2184 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
2186 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2187 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2188 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2190 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2191 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2192 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2194 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
2196 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2199 void PF_te_explosionrgb (void)
2201 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2202 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
2204 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2205 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2206 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2208 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
2209 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
2210 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
2213 void PF_te_particlecube (void)
2215 if (G_FLOAT(OFS_PARM3) < 1)
2217 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2218 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
2220 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2221 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2222 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2224 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2225 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2226 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2228 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2229 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2230 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2232 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2234 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2235 // gravity true/false
2236 MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
2238 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
2241 void PF_te_particlerain (void)
2243 if (G_FLOAT(OFS_PARM3) < 1)
2245 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2246 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
2248 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2249 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2250 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2252 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2253 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2254 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2256 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2257 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2258 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2260 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2262 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2265 void PF_te_particlesnow (void)
2267 if (G_FLOAT(OFS_PARM3) < 1)
2269 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2270 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
2272 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2273 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2274 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2276 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2277 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2278 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2280 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2281 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2282 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2284 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2286 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2289 void PF_te_spark (void)
2291 if (G_FLOAT(OFS_PARM2) < 1)
2293 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2294 MSG_WriteByte(&sv.datagram, TE_SPARK);
2296 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2297 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2298 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2300 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2301 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2302 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2304 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2307 void PF_te_gunshotquad (void)
2309 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2310 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
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_spikequad (void)
2319 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2320 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
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_superspikequad (void)
2329 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2330 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
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_explosionquad (void)
2339 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2340 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
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_smallflash (void)
2349 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2350 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
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_customflash (void)
2359 if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2361 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2362 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2364 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2365 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2366 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2368 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2370 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255));
2372 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
2373 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
2374 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
2377 void PF_te_gunshot (void)
2379 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2380 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
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]);
2387 void PF_te_spike (void)
2389 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2390 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2392 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2393 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2394 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2397 void PF_te_superspike (void)
2399 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2400 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2402 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2403 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2404 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2407 void PF_te_explosion (void)
2409 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2410 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2412 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2413 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2414 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2417 void PF_te_tarexplosion (void)
2419 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2420 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2422 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2423 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2424 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2427 void PF_te_wizspike (void)
2429 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2430 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2432 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2433 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2434 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2437 void PF_te_knightspike (void)
2439 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2440 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2442 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2443 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2444 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2447 void PF_te_lavasplash (void)
2449 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2450 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2452 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2453 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2454 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2457 void PF_te_teleport (void)
2459 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2460 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2462 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2463 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2464 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2467 void PF_te_explosion2 (void)
2469 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2470 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2472 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2473 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2474 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2476 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
2479 void PF_te_lightning1 (void)
2481 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2482 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2484 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2486 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2487 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2488 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2490 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2491 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2492 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2495 void PF_te_lightning2 (void)
2497 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2498 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2500 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2502 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2503 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2504 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2506 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2507 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2508 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2511 void PF_te_lightning3 (void)
2513 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2514 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2516 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2518 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2519 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2520 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2522 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2523 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2524 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2527 void PF_te_beam (void)
2529 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2530 MSG_WriteByte(&sv.datagram, TE_BEAM);
2532 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2534 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2535 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2536 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2538 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2539 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2540 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2543 void PF_te_plasmaburn (void)
2545 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2546 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2547 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2548 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2549 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2552 void PF_Fixme (void)
2554 PR_RunError ("unimplemented builtin"); // LordHavoc: was misspelled (bulitin)
2559 builtin_t pr_builtin[] =
2562 PF_makevectors, // void(entity e) makevectors = #1;
2563 PF_setorigin, // void(entity e, vector o) setorigin = #2;
2564 PF_setmodel, // void(entity e, string m) setmodel = #3;
2565 PF_setsize, // void(entity e, vector min, vector max) setsize = #4;
2566 PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5;
2567 PF_break, // void() break = #6;
2568 PF_random, // float() random = #7;
2569 PF_sound, // void(entity e, float chan, string samp) sound = #8;
2570 PF_normalize, // vector(vector v) normalize = #9;
2571 PF_error, // void(string e) error = #10;
2572 PF_objerror, // void(string e) objerror = #11;
2573 PF_vlen, // float(vector v) vlen = #12;
2574 PF_vectoyaw, // float(vector v) vectoyaw = #13;
2575 PF_Spawn, // entity() spawn = #14;
2576 PF_Remove, // void(entity e) remove = #15;
2577 PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16;
2578 PF_checkclient, // entity() clientlist = #17;
2579 PF_Find, // entity(entity start, .string fld, string match) find = #18;
2580 PF_precache_sound, // void(string s) precache_sound = #19;
2581 PF_precache_model, // void(string s) precache_model = #20;
2582 PF_stuffcmd, // void(entity client, string s)stuffcmd = #21;
2583 PF_findradius, // entity(vector org, float rad) findradius = #22;
2584 PF_bprint, // void(string s) bprint = #23;
2585 PF_sprint, // void(entity client, string s) sprint = #24;
2586 PF_dprint, // void(string s) dprint = #25;
2587 PF_ftos, // void(string s) ftos = #26;
2588 PF_vtos, // void(string s) vtos = #27;
2592 PF_eprint, // void(entity e) debug print an entire entity
2593 PF_walkmove, // float(float yaw, float dist) walkmove
2594 PF_Fixme, // float(float yaw, float dist) walkmove
2644 PF_precache_sound, // precache_sound2 is different only for qcc
2649 PF_Fixme, // #79 LordHavoc: dunno who owns 79-89, so these are just padding
2661 PF_tracebox, // #90 LordHavoc builtin range (9x)
2662 PF_randomvec, // #91
2664 PF_registercvar, // #93
2669 PF_FindFloat, // #98
2670 PF_checkextension, // #99
2671 #define a PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme,
2672 #define aa a a a a a a a a a a
2676 PF_copyentity, // #400 LordHavoc: builtin range (4xx)
2677 PF_setcolor, // #401
2678 PF_findchain, // #402
2679 PF_findchainfloat, // #403
2681 PF_te_blood, // #405
2682 PF_te_bloodshower, // #406
2683 PF_te_explosionrgb, // #407
2684 PF_te_particlecube, // #408
2685 PF_te_particlerain, // #409
2686 PF_te_particlesnow, // #410
2687 PF_te_spark, // #411
2688 PF_te_gunshotquad, // #412
2689 PF_te_spikequad, // #413
2690 PF_te_superspikequad, // #414
2691 PF_te_explosionquad, // #415
2692 PF_te_smallflash, // #416
2693 PF_te_customflash, // #417
2694 PF_te_gunshot, // #418
2695 PF_te_spike, // #419
2696 PF_te_superspike, // #420
2697 PF_te_explosion, // #421
2698 PF_te_tarexplosion, // #422
2699 PF_te_wizspike, // #423
2700 PF_te_knightspike, // #424
2701 PF_te_lavasplash, // #425
2702 PF_te_teleport, // #426
2703 PF_te_explosion2, // #427
2704 PF_te_lightning1, // #428
2705 PF_te_lightning2, // #429
2706 PF_te_lightning3, // #430
2708 PF_vectorvectors, // #432
2709 PF_te_plasmaburn, // #433
2712 builtin_t *pr_builtins = pr_builtin;
2713 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);