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_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 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 // 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;
1466 void(float style, string value) lightstyle
1469 void PF_lightstyle (void)
1476 style = G_FLOAT(OFS_PARM0);
1477 val = G_STRING(OFS_PARM1);
1479 // change the string in sv
1480 sv.lightstyles[style] = val;
1482 // send message to all clients on this server
1483 if (sv.state != ss_active)
1486 for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
1487 if (client->active || client->spawned)
1489 MSG_WriteChar (&client->message, svc_lightstyle);
1490 MSG_WriteChar (&client->message,style);
1491 MSG_WriteString (&client->message, val);
1498 f = G_FLOAT(OFS_PARM0);
1500 G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1502 G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1504 void PF_floor (void)
1506 G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
1510 G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
1519 void PF_checkbottom (void)
1521 G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0));
1529 void PF_pointcontents (void)
1531 G_FLOAT(OFS_RETURN) = SV_PointContents (G_VECTOR(OFS_PARM0));
1538 entity nextent(entity)
1541 void PF_nextent (void)
1546 i = G_EDICTNUM(OFS_PARM0);
1550 if (i == sv.num_edicts)
1552 RETURN_EDICT(sv.edicts);
1568 Pick a vector for the player to shoot along
1569 vector aim(entity, missilespeed)
1574 edict_t *ent, *check, *bestent;
1575 vec3_t start, dir, end, bestdir;
1578 float dist, bestdist;
1581 ent = G_EDICT(OFS_PARM0);
1582 speed = G_FLOAT(OFS_PARM1);
1584 VectorCopy (ent->v.origin, start);
1587 // try sending a trace straight
1588 VectorCopy (pr_global_struct->v_forward, dir);
1589 VectorMA (start, 2048, dir, end);
1590 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1591 if (tr.ent && tr.ent->v.takedamage == DAMAGE_AIM
1592 && (!teamplay.integer || ent->v.team <=0 || ent->v.team != tr.ent->v.team) )
1594 VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
1599 // try all possible entities
1600 VectorCopy (dir, bestdir);
1601 bestdist = sv_aim.value;
1604 check = NEXT_EDICT(sv.edicts);
1605 for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
1607 if (check->v.takedamage != DAMAGE_AIM)
1611 if (teamplay.integer && ent->v.team > 0 && ent->v.team == check->v.team)
1612 continue; // don't aim at teammate
1613 for (j=0 ; j<3 ; j++)
1614 end[j] = check->v.origin[j]
1615 + 0.5*(check->v.mins[j] + check->v.maxs[j]);
1616 VectorSubtract (end, start, dir);
1617 VectorNormalize (dir);
1618 dist = DotProduct (dir, pr_global_struct->v_forward);
1619 if (dist < bestdist)
1620 continue; // to far to turn
1621 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1622 if (tr.ent == check)
1623 { // can shoot at this one
1631 VectorSubtract (bestent->v.origin, ent->v.origin, dir);
1632 dist = DotProduct (dir, pr_global_struct->v_forward);
1633 VectorScale (pr_global_struct->v_forward, dist, end);
1635 VectorNormalize (end);
1636 VectorCopy (end, G_VECTOR(OFS_RETURN));
1640 VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
1648 This was a major timewaster in progs, so it was converted to C
1651 void PF_changeyaw (void)
1654 float ideal, current, move, speed;
1656 ent = PROG_TO_EDICT(pr_global_struct->self);
1657 current = ANGLEMOD(ent->v.angles[1]);
1658 ideal = ent->v.ideal_yaw;
1659 speed = ent->v.yaw_speed;
1661 if (current == ideal)
1663 move = ideal - current;
1664 if (ideal > current)
1685 ent->v.angles[1] = ANGLEMOD (current + move);
1693 void PF_changepitch (void)
1696 float ideal, current, move, speed;
1699 ent = G_EDICT(OFS_PARM0);
1700 current = ANGLEMOD( ent->v.angles[0] );
1701 if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
1702 ideal = val->_float;
1705 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1708 if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
1709 speed = val->_float;
1712 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1716 if (current == ideal)
1718 move = ideal - current;
1719 if (ideal > current)
1740 ent->v.angles[0] = ANGLEMOD (current + move);
1744 ===============================================================================
1748 ===============================================================================
1751 #define MSG_BROADCAST 0 // unreliable to all
1752 #define MSG_ONE 1 // reliable to one (msg_entity)
1753 #define MSG_ALL 2 // reliable to all
1754 #define MSG_INIT 3 // write to the init string
1756 sizebuf_t *WriteDest (void)
1762 dest = G_FLOAT(OFS_PARM0);
1766 return &sv.datagram;
1769 ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
1770 entnum = NUM_FOR_EDICT(ent);
1771 if (entnum < 1 || entnum > svs.maxclients)
1772 PR_RunError ("WriteDest: not a client");
1773 return &svs.clients[entnum-1].message;
1776 return &sv.reliable_datagram;
1782 PR_RunError ("WriteDest: bad destination");
1789 void PF_WriteByte (void)
1791 MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
1794 void PF_WriteChar (void)
1796 MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
1799 void PF_WriteShort (void)
1801 MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
1804 void PF_WriteLong (void)
1806 MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
1809 void PF_WriteAngle (void)
1811 MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
1814 void PF_WriteCoord (void)
1816 MSG_WriteDPCoord (WriteDest(), G_FLOAT(OFS_PARM1));
1819 void PF_WriteString (void)
1821 MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
1825 void PF_WriteEntity (void)
1827 MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
1830 //=============================================================================
1832 int SV_ModelIndex (char *name);
1834 void PF_makestatic (void)
1839 ent = G_EDICT(OFS_PARM0);
1842 if (ent->v.modelindex >= 256 || ent->v.frame >= 256)
1847 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1848 MSG_WriteShort (&sv.signon, ent->v.modelindex);
1849 MSG_WriteShort (&sv.signon, ent->v.frame);
1853 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1854 MSG_WriteByte (&sv.signon, ent->v.modelindex);
1855 MSG_WriteByte (&sv.signon, ent->v.frame);
1858 MSG_WriteByte (&sv.signon, ent->v.colormap);
1859 MSG_WriteByte (&sv.signon, ent->v.skin);
1860 for (i=0 ; i<3 ; i++)
1862 MSG_WriteDPCoord(&sv.signon, ent->v.origin[i]);
1863 MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
1866 // throw the entity away now
1870 //=============================================================================
1877 void PF_setspawnparms (void)
1883 ent = G_EDICT(OFS_PARM0);
1884 i = NUM_FOR_EDICT(ent);
1885 if (i < 1 || i > svs.maxclients)
1886 PR_RunError ("Entity is not a client");
1888 // copy spawn parms out of the client_t
1889 client = svs.clients + (i-1);
1891 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1892 (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
1900 void PF_changelevel (void)
1904 // make sure we don't issue two changelevels
1905 if (svs.changelevel_issued)
1907 svs.changelevel_issued = true;
1909 s = G_STRING(OFS_PARM0);
1910 Cbuf_AddText (va("changelevel %s\n",s));
1915 G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
1920 G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
1925 G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
1932 Returns a vector of length < 1
1937 void PF_randomvec (void)
1942 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1943 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1944 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1946 while (DotProduct(temp, temp) >= 1);
1947 VectorCopy (temp, G_VECTOR(OFS_RETURN));
1950 void SV_LightPoint (vec3_t color, vec3_t p);
1955 Returns a color vector indicating the lighting at the requested point.
1957 (Internal Operation note: actually measures the light beneath the point, just like
1958 the model lighting on the client)
1963 void PF_GetLight (void)
1967 p = G_VECTOR(OFS_PARM0);
1968 SV_LightPoint (color, p);
1969 VectorCopy (color, G_VECTOR(OFS_RETURN));
1972 #define MAX_QC_CVARS 128
1973 cvar_t qc_cvar[MAX_QC_CVARS];
1976 void PF_registercvar (void)
1980 name = G_STRING(OFS_PARM1);
1981 value = G_STRING(OFS_PARM2);
1982 G_FLOAT(OFS_RETURN) = 0;
1983 // first check to see if it has already been defined
1984 if (Cvar_FindVar (name))
1987 // check for overlap with a command
1988 if (Cmd_Exists (name))
1990 Con_Printf ("PF_registercvar: %s is a command\n", name);
1994 if (currentqc_cvar >= MAX_QC_CVARS)
1995 PR_RunError ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
1997 // copy the name and value
1998 variable = &qc_cvar[currentqc_cvar++];
1999 variable->name = Z_Malloc (strlen(name)+1);
2000 strcpy (variable->name, name);
2001 variable->string = Z_Malloc (strlen(value)+1);
2002 strcpy (variable->string, value);
2003 variable->value = atof (value);
2005 // link the variable in
2006 variable->next = cvar_vars;
2007 cvar_vars = variable;
2008 G_FLOAT(OFS_RETURN) = 1; // success
2015 returns the minimum of two supplied floats
2022 // LordHavoc: 3+ argument enhancement suggested by FrikaC
2024 G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2025 else if (pr_argc >= 3)
2028 float f = G_FLOAT(OFS_PARM0);
2029 for (i = 1;i < pr_argc;i++)
2030 if (G_FLOAT((OFS_PARM0+i*3)) < f)
2031 f = G_FLOAT((OFS_PARM0+i*3));
2032 G_FLOAT(OFS_RETURN) = f;
2035 PR_RunError("min: must supply at least 2 floats\n");
2042 returns the maximum of two supplied floats
2049 // LordHavoc: 3+ argument enhancement suggested by FrikaC
2051 G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2052 else if (pr_argc >= 3)
2055 float f = G_FLOAT(OFS_PARM0);
2056 for (i = 1;i < pr_argc;i++)
2057 if (G_FLOAT((OFS_PARM0+i*3)) > f)
2058 f = G_FLOAT((OFS_PARM0+i*3));
2059 G_FLOAT(OFS_RETURN) = f;
2062 PR_RunError("max: must supply at least 2 floats\n");
2069 returns number bounded by supplied range
2071 min(min, value, max)
2074 void PF_bound (void)
2076 G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
2083 returns a raised to power b
2090 G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2097 copies data from one entity to another
2099 copyentity(src, dst)
2102 void PF_copyentity (void)
2105 in = G_EDICT(OFS_PARM0);
2106 out = G_EDICT(OFS_PARM1);
2107 memcpy(out, in, pr_edict_size);
2114 sets the color of a client and broadcasts the update to all connected clients
2116 setcolor(clientent, value)
2119 void PF_setcolor (void)
2124 entnum = G_EDICTNUM(OFS_PARM0);
2125 i = G_FLOAT(OFS_PARM1);
2127 if (entnum < 1 || entnum > svs.maxclients)
2129 Con_Printf ("tried to setcolor a non-client\n");
2133 client = &svs.clients[entnum-1];
2135 client->edict->v.team = (i & 15) + 1;
2137 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
2138 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
2139 MSG_WriteByte (&sv.reliable_datagram, i);
2146 effect(origin, modelname, startframe, framecount, framerate)
2149 void PF_effect (void)
2152 s = G_STRING(OFS_PARM1);
2154 PR_RunError("effect: no model specified\n");
2156 SV_StartEffect(G_VECTOR(OFS_PARM0), SV_ModelIndex(s), G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
2159 void PF_te_blood (void)
2161 if (G_FLOAT(OFS_PARM2) < 1)
2163 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2164 MSG_WriteByte(&sv.datagram, TE_BLOOD);
2166 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2167 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2168 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2170 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2171 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2172 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2174 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2177 void PF_te_bloodshower (void)
2179 if (G_FLOAT(OFS_PARM3) < 1)
2181 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2182 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
2184 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2185 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2186 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2188 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2189 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2190 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2192 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
2194 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2197 void PF_te_explosionrgb (void)
2199 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2200 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
2202 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2203 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2204 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2206 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
2207 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
2208 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
2211 void PF_te_particlecube (void)
2213 if (G_FLOAT(OFS_PARM3) < 1)
2215 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2216 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
2218 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2219 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2220 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2222 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2223 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2224 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2226 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2227 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2228 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2230 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2232 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2233 // gravity true/false
2234 MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
2236 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
2239 void PF_te_particlerain (void)
2241 if (G_FLOAT(OFS_PARM3) < 1)
2243 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2244 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
2246 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2247 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2248 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2250 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2251 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2252 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2254 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2255 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2256 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2258 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2260 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2263 void PF_te_particlesnow (void)
2265 if (G_FLOAT(OFS_PARM3) < 1)
2267 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2268 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
2270 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2271 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2272 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2274 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2275 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2276 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2278 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2279 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2280 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2282 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2284 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2287 void PF_te_spark (void)
2289 if (G_FLOAT(OFS_PARM2) < 1)
2291 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2292 MSG_WriteByte(&sv.datagram, TE_SPARK);
2294 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2295 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2296 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2298 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2299 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2300 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2302 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2305 void PF_te_gunshotquad (void)
2307 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2308 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
2310 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2311 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2312 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2315 void PF_te_spikequad (void)
2317 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2318 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
2320 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2321 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2322 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2325 void PF_te_superspikequad (void)
2327 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2328 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
2330 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2331 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2332 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2335 void PF_te_explosionquad (void)
2337 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2338 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2340 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2341 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2342 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2345 void PF_te_smallflash (void)
2347 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2348 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2350 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2351 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2352 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2355 void PF_te_customflash (void)
2357 if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2359 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2360 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2362 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2363 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2364 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2366 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2368 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255));
2370 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
2371 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
2372 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
2375 void PF_te_gunshot (void)
2377 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2378 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2380 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2381 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2382 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2385 void PF_te_spike (void)
2387 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2388 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2390 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2391 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2392 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2395 void PF_te_superspike (void)
2397 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2398 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2400 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2401 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2402 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2405 void PF_te_explosion (void)
2407 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2408 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2410 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2411 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2412 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2415 void PF_te_tarexplosion (void)
2417 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2418 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2420 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2421 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2422 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2425 void PF_te_wizspike (void)
2427 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2428 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2430 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2431 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2432 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2435 void PF_te_knightspike (void)
2437 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2438 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2440 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2441 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2442 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2445 void PF_te_lavasplash (void)
2447 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2448 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2450 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2451 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2452 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2455 void PF_te_teleport (void)
2457 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2458 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2460 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2461 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2462 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2465 void PF_te_explosion2 (void)
2467 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2468 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2470 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2471 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2472 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2474 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
2477 void PF_te_lightning1 (void)
2479 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2480 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2482 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2484 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2485 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2486 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2488 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2489 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2490 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2493 void PF_te_lightning2 (void)
2495 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2496 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2498 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2500 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2501 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2502 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2504 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2505 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2506 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2509 void PF_te_lightning3 (void)
2511 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2512 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2514 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2516 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2517 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2518 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2520 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2521 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2522 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2525 void PF_te_beam (void)
2527 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2528 MSG_WriteByte(&sv.datagram, TE_BEAM);
2530 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2532 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2533 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2534 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2536 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2537 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2538 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2541 void PF_te_plasmaburn (void)
2543 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2544 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2545 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2546 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2547 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2550 void PF_Fixme (void)
2552 PR_RunError ("unimplemented builtin"); // LordHavoc: was misspelled (bulitin)
2557 builtin_t pr_builtin[] =
2560 PF_makevectors, // void(entity e) makevectors = #1;
2561 PF_setorigin, // void(entity e, vector o) setorigin = #2;
2562 PF_setmodel, // void(entity e, string m) setmodel = #3;
2563 PF_setsize, // void(entity e, vector min, vector max) setsize = #4;
2564 PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5;
2565 PF_break, // void() break = #6;
2566 PF_random, // float() random = #7;
2567 PF_sound, // void(entity e, float chan, string samp) sound = #8;
2568 PF_normalize, // vector(vector v) normalize = #9;
2569 PF_error, // void(string e) error = #10;
2570 PF_objerror, // void(string e) objerror = #11;
2571 PF_vlen, // float(vector v) vlen = #12;
2572 PF_vectoyaw, // float(vector v) vectoyaw = #13;
2573 PF_Spawn, // entity() spawn = #14;
2574 PF_Remove, // void(entity e) remove = #15;
2575 PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16;
2576 PF_checkclient, // entity() clientlist = #17;
2577 PF_Find, // entity(entity start, .string fld, string match) find = #18;
2578 PF_precache_sound, // void(string s) precache_sound = #19;
2579 PF_precache_model, // void(string s) precache_model = #20;
2580 PF_stuffcmd, // void(entity client, string s)stuffcmd = #21;
2581 PF_findradius, // entity(vector org, float rad) findradius = #22;
2582 PF_bprint, // void(string s) bprint = #23;
2583 PF_sprint, // void(entity client, string s) sprint = #24;
2584 PF_dprint, // void(string s) dprint = #25;
2585 PF_ftos, // void(string s) ftos = #26;
2586 PF_vtos, // void(string s) vtos = #27;
2590 PF_eprint, // void(entity e) debug print an entire entity
2591 PF_walkmove, // float(float yaw, float dist) walkmove
2592 PF_Fixme, // float(float yaw, float dist) walkmove
2642 PF_precache_sound, // precache_sound2 is different only for qcc
2647 PF_Fixme, // #79 LordHavoc: dunno who owns 79-89, so these are just padding
2659 PF_tracebox, // #90 LordHavoc builtin range (9x)
2660 PF_randomvec, // #91
2662 PF_registercvar, // #93
2667 PF_FindFloat, // #98
2668 PF_checkextension, // #99
2669 #define a PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme,
2670 #define aa a a a a a a a a a a
2674 PF_copyentity, // #400 LordHavoc: builtin range (4xx)
2675 PF_setcolor, // #401
2676 PF_findchain, // #402
2677 PF_findchainfloat, // #403
2679 PF_te_blood, // #405
2680 PF_te_bloodshower, // #406
2681 PF_te_explosionrgb, // #407
2682 PF_te_particlecube, // #408
2683 PF_te_particlerain, // #409
2684 PF_te_particlesnow, // #410
2685 PF_te_spark, // #411
2686 PF_te_gunshotquad, // #412
2687 PF_te_spikequad, // #413
2688 PF_te_superspikequad, // #414
2689 PF_te_explosionquad, // #415
2690 PF_te_smallflash, // #416
2691 PF_te_customflash, // #417
2692 PF_te_gunshot, // #418
2693 PF_te_spike, // #419
2694 PF_te_superspike, // #420
2695 PF_te_explosion, // #421
2696 PF_te_tarexplosion, // #422
2697 PF_te_wizspike, // #423
2698 PF_te_knightspike, // #424
2699 PF_te_lavasplash, // #425
2700 PF_te_teleport, // #426
2701 PF_te_explosion2, // #427
2702 PF_te_lightning1, // #428
2703 PF_te_lightning2, // #429
2704 PF_te_lightning3, // #430
2706 PF_vectorvectors, // #432
2707 PF_te_plasmaburn, // #433
2710 builtin_t *pr_builtins = pr_builtin;
2711 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);