2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 cvar_t sv_aim = {CVAR_SAVE, "sv_aim", "2"}; //"0.93"}; // LordHavoc: disabled autoaim by default
25 #define RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e))
29 ===============================================================================
33 ===============================================================================
37 char *PF_VarString (int first)
40 static char out[4096]; // FIXME: buffer overflow potential
43 for (i = first;i < pr_argc;i++)
44 strcat (out, G_STRING((OFS_PARM0+i*3)));
48 char *ENGINE_EXTENSIONS =
50 "DP_ENT_CUSTOMCOLORMAP "
51 "DP_ENT_EXTERIORMODELTOCLIENT "
52 "DP_ENT_LOWPRECISION "
65 "DP_QC_FINDCHAINFLOAT "
70 "DP_QC_SINCOSSQRTPOW "
73 "DP_QC_VECTORVECTORS "
78 "DP_SV_DRAWONLYTOCLIENT "
80 "DP_SV_EXTERIORMODELTOCLIENT "
81 "DP_SV_NODRAWTOCLIENT "
82 "DP_SV_PLAYERPHYSICS "
97 qboolean checkextension(char *name)
102 for (e = ENGINE_EXTENSIONS;*e;e++)
109 while (*e && *e != ' ')
111 if (e - start == len)
112 if (!strncasecmp(start, name, len))
122 returns true if the extension is supported by the server
124 checkextension(extensionname)
127 void PF_checkextension (void)
129 G_FLOAT(OFS_RETURN) = checkextension(G_STRING(OFS_PARM0));
136 This is a TERMINAL error, which will kill off the entire server.
148 Con_Printf ("======SERVER ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
149 ed = PROG_TO_EDICT(pr_global_struct->self);
152 Host_Error ("Program error");
159 Dumps out self, then an error message. The program is aborted and self is
160 removed, but the level can continue.
165 void PF_objerror (void)
171 Con_Printf ("======OBJECT ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
172 ed = PROG_TO_EDICT(pr_global_struct->self);
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)
230 for (i=0 ; i<3 ; i++)
232 Host_Error ("backwards mins/maxs");
234 // set derived values
235 VectorCopy (min, e->v.mins);
236 VectorCopy (max, e->v.maxs);
237 VectorSubtract (max, min, e->v.size);
239 SV_LinkEdict (e, false);
246 the size box is rotated by the current angle
247 LordHavoc: no it isn't...
249 setsize (entity, minvector, maxvector)
252 void PF_setsize (void)
257 e = G_EDICT(OFS_PARM0);
258 min = G_VECTOR(OFS_PARM1);
259 max = G_VECTOR(OFS_PARM2);
260 SetMinMaxSize (e, min, max, false);
268 setmodel(entity, model)
271 void PF_setmodel (void)
278 e = G_EDICT(OFS_PARM0);
279 m = G_STRING(OFS_PARM1);
281 // check to see if model was properly precached
282 for (i=0, check = sv.model_precache ; *check ; i++, check++)
283 if (!strcmp(*check, m))
287 Host_Error ("no precache: %s\n", m);
290 e->v.model = m - pr_strings;
293 mod = sv.models[ (int)e->v.modelindex];
296 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
298 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
305 broadcast print to everyone on server
310 void PF_bprint (void)
315 SV_BroadcastPrintf ("%s", s);
322 single print to a specific client
324 sprint(clientent, value)
327 void PF_sprint (void)
333 entnum = G_EDICTNUM(OFS_PARM0);
336 if (entnum < 1 || entnum > svs.maxclients)
338 Con_Printf ("tried to sprint to a non-client\n");
342 client = &svs.clients[entnum-1];
344 MSG_WriteChar (&client->message,svc_print);
345 MSG_WriteString (&client->message, s );
353 single print to a specific client
355 centerprint(clientent, value)
358 void PF_centerprint (void)
364 entnum = G_EDICTNUM(OFS_PARM0);
367 if (entnum < 1 || entnum > svs.maxclients)
369 Con_Printf ("tried to sprint to a non-client\n");
373 client = &svs.clients[entnum-1];
375 MSG_WriteChar (&client->message,svc_centerprint);
376 MSG_WriteString (&client->message, s );
384 vector normalize(vector)
387 void PF_normalize (void)
393 value1 = G_VECTOR(OFS_PARM0);
395 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
399 newvalue[0] = newvalue[1] = newvalue[2] = 0;
403 newvalue[0] = value1[0] * new;
404 newvalue[1] = value1[1] * new;
405 newvalue[2] = value1[2] * new;
408 VectorCopy (newvalue, G_VECTOR(OFS_RETURN));
423 value1 = G_VECTOR(OFS_PARM0);
425 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
428 G_FLOAT(OFS_RETURN) = new;
435 float vectoyaw(vector)
438 void PF_vectoyaw (void)
443 value1 = G_VECTOR(OFS_PARM0);
445 if (value1[1] == 0 && value1[0] == 0)
449 yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
454 G_FLOAT(OFS_RETURN) = yaw;
462 vector vectoangles(vector)
465 void PF_vectoangles (void)
471 value1 = G_VECTOR(OFS_PARM0);
473 if (value1[1] == 0 && value1[0] == 0)
483 // LordHavoc: optimized a bit
486 yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
490 else if (value1[1] > 0)
495 forward = sqrt(value1[0]*value1[0] + value1[1]*value1[1]);
496 pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
501 G_FLOAT(OFS_RETURN+0) = pitch;
502 G_FLOAT(OFS_RETURN+1) = yaw;
503 G_FLOAT(OFS_RETURN+2) = 0;
510 Returns a number from 0<= num < 1
515 void PF_random (void)
519 num = (rand ()&0x7fff) / ((float)0x7fff);
521 G_FLOAT(OFS_RETURN) = num;
528 particle(origin, color, count)
531 void PF_particle (void)
537 org = G_VECTOR(OFS_PARM0);
538 dir = G_VECTOR(OFS_PARM1);
539 color = G_FLOAT(OFS_PARM2);
540 count = G_FLOAT(OFS_PARM3);
541 SV_StartParticle (org, dir, color, count);
551 void PF_ambientsound (void)
556 float vol, attenuation;
557 int i, soundnum, large;
559 pos = G_VECTOR (OFS_PARM0);
560 samp = G_STRING(OFS_PARM1);
561 vol = G_FLOAT(OFS_PARM2);
562 attenuation = G_FLOAT(OFS_PARM3);
564 // check to see if samp was properly precached
565 for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++)
566 if (!strcmp(*check,samp))
571 Con_Printf ("no precache: %s\n", samp);
579 // add an svc_spawnambient command to the level signon packet
582 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
584 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
586 for (i=0 ; i<3 ; i++)
587 MSG_WriteDPCoord(&sv.signon, pos[i]);
590 MSG_WriteShort (&sv.signon, soundnum);
592 MSG_WriteByte (&sv.signon, soundnum);
594 MSG_WriteByte (&sv.signon, vol*255);
595 MSG_WriteByte (&sv.signon, attenuation*64);
603 Each entity can have eight independant sound sources, like voice,
606 Channel 0 is an auto-allocate channel, the others override anything
607 already running on that entity/channel pair.
609 An attenuation of 0 will play full volume everywhere in the level.
610 Larger attenuations will drop off.
622 entity = G_EDICT(OFS_PARM0);
623 channel = G_FLOAT(OFS_PARM1);
624 sample = G_STRING(OFS_PARM2);
625 volume = G_FLOAT(OFS_PARM3) * 255;
626 attenuation = G_FLOAT(OFS_PARM4);
628 if (volume < 0 || volume > 255)
629 Host_Error ("SV_StartSound: volume = %i", volume);
631 if (attenuation < 0 || attenuation > 4)
632 Host_Error ("SV_StartSound: attenuation = %f", attenuation);
634 if (channel < 0 || channel > 7)
635 Host_Error ("SV_StartSound: channel = %i", channel);
637 SV_StartSound (entity, channel, sample, volume, attenuation);
649 Host_Error ("break statement");
656 Used for use tracing and shot targeting
657 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
658 if the tryents flag is set.
660 traceline (vector1, vector2, tryents)
663 void PF_traceline (void)
670 v1 = G_VECTOR(OFS_PARM0);
671 v2 = G_VECTOR(OFS_PARM1);
672 nomonsters = G_FLOAT(OFS_PARM2);
673 ent = G_EDICT(OFS_PARM3);
675 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters ? MOVE_NOMONSTERS : MOVE_NORMAL, ent);
677 pr_global_struct->trace_allsolid = trace.allsolid;
678 pr_global_struct->trace_startsolid = trace.startsolid;
679 pr_global_struct->trace_fraction = trace.fraction;
680 pr_global_struct->trace_inwater = trace.inwater;
681 pr_global_struct->trace_inopen = trace.inopen;
682 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
683 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
684 pr_global_struct->trace_plane_dist = trace.plane.dist;
686 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
688 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
689 // FIXME: add trace_endcontents
697 Used for use tracing and shot targeting
698 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
699 if the tryents flag is set.
701 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
704 // LordHavoc: added this for my own use, VERY useful, similar to traceline
705 void PF_tracebox (void)
707 float *v1, *v2, *m1, *m2;
712 v1 = G_VECTOR(OFS_PARM0);
713 m1 = G_VECTOR(OFS_PARM1);
714 m2 = G_VECTOR(OFS_PARM2);
715 v2 = G_VECTOR(OFS_PARM3);
716 nomonsters = G_FLOAT(OFS_PARM4);
717 ent = G_EDICT(OFS_PARM5);
719 trace = SV_Move (v1, m1, m2, v2, nomonsters ? MOVE_NOMONSTERS : MOVE_NORMAL, ent);
721 pr_global_struct->trace_allsolid = trace.allsolid;
722 pr_global_struct->trace_startsolid = trace.startsolid;
723 pr_global_struct->trace_fraction = trace.fraction;
724 pr_global_struct->trace_inwater = trace.inwater;
725 pr_global_struct->trace_inopen = trace.inopen;
726 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
727 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
728 pr_global_struct->trace_plane_dist = trace.plane.dist;
730 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
732 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
735 extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore);
736 void PF_TraceToss (void)
742 ent = G_EDICT(OFS_PARM0);
743 ignore = G_EDICT(OFS_PARM1);
745 trace = SV_Trace_Toss (ent, ignore);
747 pr_global_struct->trace_allsolid = trace.allsolid;
748 pr_global_struct->trace_startsolid = trace.startsolid;
749 pr_global_struct->trace_fraction = trace.fraction;
750 pr_global_struct->trace_inwater = trace.inwater;
751 pr_global_struct->trace_inopen = trace.inopen;
752 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
753 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
754 pr_global_struct->trace_plane_dist = trace.plane.dist;
756 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
758 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
766 Returns true if the given entity can move to the given position from it's
767 current position by walking or rolling.
769 scalar checkpos (entity, vector)
772 void PF_checkpos (void)
776 //============================================================================
778 qbyte checkpvs[MAX_MAP_LEAFS/8];
780 int PF_newcheckclient (int check)
788 // cycle to the next one
792 if (check > svs.maxclients)
793 check = svs.maxclients;
795 if (check == svs.maxclients)
802 if (i == svs.maxclients+1)
808 break; // didn't find anything else
812 if (ent->v.health <= 0)
814 if ((int)ent->v.flags & FL_NOTARGET)
817 // anything that is a client, or has a client as an enemy
821 // get the PVS for the entity
822 VectorAdd (ent->v.origin, ent->v.view_ofs, org);
823 leaf = Mod_PointInLeaf (org, sv.worldmodel);
824 pvs = Mod_LeafPVS (leaf, sv.worldmodel);
825 memcpy (checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 );
834 Returns a client (or object that has a client enemy) that would be a
837 If there is more than one valid option, they are cycled each frame
839 If (self.origin + self.viewofs) is not in the PVS of the current target,
840 it is not returned at all.
845 int c_invis, c_notvis;
846 void PF_checkclient (void)
853 // find a new check if on a new frame
854 if (sv.time - sv.lastchecktime >= 0.1)
856 sv.lastcheck = PF_newcheckclient (sv.lastcheck);
857 sv.lastchecktime = sv.time;
860 // return check if it might be visible
861 ent = EDICT_NUM(sv.lastcheck);
862 if (ent->free || ent->v.health <= 0)
864 RETURN_EDICT(sv.edicts);
868 // if current entity can't possibly see the check entity, return 0
869 self = PROG_TO_EDICT(pr_global_struct->self);
870 VectorAdd (self->v.origin, self->v.view_ofs, view);
871 leaf = Mod_PointInLeaf (view, sv.worldmodel);
874 l = (leaf - sv.worldmodel->leafs) - 1;
875 if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
878 RETURN_EDICT(sv.edicts);
883 // might be able to see it
888 //============================================================================
895 Sends text over to the client's execution buffer
897 stuffcmd (clientent, value)
900 void PF_stuffcmd (void)
906 entnum = G_EDICTNUM(OFS_PARM0);
907 if (entnum < 1 || entnum > svs.maxclients)
908 Host_Error ("Parm 0 not a client");
909 str = G_STRING(OFS_PARM1);
912 host_client = &svs.clients[entnum-1];
913 Host_ClientCommands ("%s", str);
921 Sends text over to the client's execution buffer
926 void PF_localcmd (void)
930 str = G_STRING(OFS_PARM0);
945 str = G_STRING(OFS_PARM0);
947 G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str);
957 void PF_cvar_set (void)
961 var = G_STRING(OFS_PARM0);
962 val = G_STRING(OFS_PARM1);
971 Returns a chain of entities that have origins within a spherical area
973 findradius (origin, radius)
976 void PF_findradius (void)
978 edict_t *ent, *chain;
985 chain = (edict_t *)sv.edicts;
987 org = G_VECTOR(OFS_PARM0);
988 radius = G_FLOAT(OFS_PARM1);
989 radius2 = radius * radius;
991 ent = NEXT_EDICT(sv.edicts);
992 for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
996 if (ent->v.solid == SOLID_NOT)
999 // LordHavoc: compare against bounding box rather than center,
1000 // and use DotProduct instead of Length, major speedup
1001 eorg[0] = (org[0] - ent->v.origin[0]) - bound(ent->v.mins[0], (org[0] - ent->v.origin[0]), ent->v.maxs[0]);
1002 eorg[1] = (org[1] - ent->v.origin[1]) - bound(ent->v.mins[1], (org[1] - ent->v.origin[1]), ent->v.maxs[1]);
1003 eorg[2] = (org[2] - ent->v.origin[2]) - bound(ent->v.mins[2], (org[2] - ent->v.origin[2]), ent->v.maxs[2]);
1004 if (DotProduct(eorg, eorg) > radius2)
1007 ent->v.chain = EDICT_TO_PROG(chain);
1011 RETURN_EDICT(chain);
1020 void PF_dprint (void)
1022 Con_DPrintf ("%s",PF_VarString(0));
1025 // LordHavoc: added this to semi-fix the problem of using many ftos calls in a print
1026 #define STRINGTEMP_BUFFERS 16
1027 #define STRINGTEMP_LENGTH 128
1028 static char pr_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH];
1029 static int pr_string_tempindex = 0;
1031 static char *PR_GetTempString(void)
1034 s = pr_string_temp[pr_string_tempindex];
1035 pr_string_tempindex = (pr_string_tempindex + 1) % STRINGTEMP_BUFFERS;
1043 v = G_FLOAT(OFS_PARM0);
1045 s = PR_GetTempString();
1046 // LordHavoc: ftos improvement
1047 sprintf (s, "%g", v);
1048 G_INT(OFS_RETURN) = s - pr_strings;
1054 v = G_FLOAT(OFS_PARM0);
1055 G_FLOAT(OFS_RETURN) = fabs(v);
1061 s = PR_GetTempString();
1062 sprintf (s, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
1063 G_INT(OFS_RETURN) = s - pr_strings;
1069 s = PR_GetTempString();
1070 sprintf (s, "entity %i", G_EDICTNUM(OFS_PARM0));
1071 G_INT(OFS_RETURN) = s - pr_strings;
1074 void PF_Spawn (void)
1081 void PF_Remove (void)
1085 ed = G_EDICT(OFS_PARM0);
1086 if (ed == sv.edicts)
1087 Host_Error("remove: tried to remove world\n");
1088 if (NUM_FOR_EDICT(ed) <= svs.maxclients)
1089 Host_Error("remove: tried to remove a client\n");
1094 // entity (entity start, .string field, string match) find = #5;
1102 e = G_EDICTNUM(OFS_PARM0);
1103 f = G_INT(OFS_PARM1);
1104 s = G_STRING(OFS_PARM2);
1107 RETURN_EDICT(sv.edicts);
1111 for (e++ ; e < sv.num_edicts ; e++)
1126 RETURN_EDICT(sv.edicts);
1129 // LordHavoc: added this for searching float, int, and entity reference fields
1130 void PF_FindFloat (void)
1137 e = G_EDICTNUM(OFS_PARM0);
1138 f = G_INT(OFS_PARM1);
1139 s = G_FLOAT(OFS_PARM2);
1141 for (e++ ; e < sv.num_edicts ; e++)
1146 if (E_FLOAT(ed,f) == s)
1153 RETURN_EDICT(sv.edicts);
1156 // chained search for strings in entity fields
1157 // entity(.string field, string match) findchain = #402;
1158 void PF_findchain (void)
1163 edict_t *ent, *chain;
1165 chain = (edict_t *)sv.edicts;
1167 f = G_INT(OFS_PARM0);
1168 s = G_STRING(OFS_PARM1);
1171 RETURN_EDICT(sv.edicts);
1175 ent = NEXT_EDICT(sv.edicts);
1176 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1180 t = E_STRING(ent,f);
1186 ent->v.chain = EDICT_TO_PROG(chain);
1190 RETURN_EDICT(chain);
1193 // LordHavoc: chained search for float, int, and entity reference fields
1194 // entity(.string field, float match) findchainfloat = #403;
1195 void PF_findchainfloat (void)
1200 edict_t *ent, *chain;
1202 chain = (edict_t *)sv.edicts;
1204 f = G_INT(OFS_PARM0);
1205 s = G_FLOAT(OFS_PARM1);
1207 ent = NEXT_EDICT(sv.edicts);
1208 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1212 if (E_FLOAT(ent,f) != s)
1215 ent->v.chain = EDICT_TO_PROG(chain);
1219 RETURN_EDICT(chain);
1222 void PR_CheckEmptyString (char *s)
1225 Host_Error ("Bad string");
1228 void PF_precache_file (void)
1229 { // precache_file is only used to copy files with qcc, it does nothing
1230 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1233 void PF_precache_sound (void)
1238 if (sv.state != ss_loading)
1239 Host_Error ("PF_Precache_*: Precache can only be done in spawn functions");
1241 s = G_STRING(OFS_PARM0);
1242 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1243 PR_CheckEmptyString (s);
1245 for (i=0 ; i<MAX_SOUNDS ; i++)
1247 if (!sv.sound_precache[i])
1249 sv.sound_precache[i] = s;
1252 if (!strcmp(sv.sound_precache[i], s))
1255 Host_Error ("PF_precache_sound: overflow");
1258 void PF_precache_model (void)
1263 if (sv.state != ss_loading)
1264 Host_Error ("PF_Precache_*: Precache can only be done in spawn functions");
1266 s = G_STRING(OFS_PARM0);
1267 if (sv.worldmodel->ishlbsp && ((!s) || (!s[0])))
1269 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1270 PR_CheckEmptyString (s);
1272 for (i=0 ; i<MAX_MODELS ; i++)
1274 if (!sv.model_precache[i])
1276 sv.model_precache[i] = s;
1277 sv.models[i] = Mod_ForName (s, true, false, false);
1280 if (!strcmp(sv.model_precache[i], s))
1283 Host_Error ("PF_precache_model: overflow");
1287 void PF_coredump (void)
1292 void PF_traceon (void)
1297 void PF_traceoff (void)
1302 void PF_eprint (void)
1304 ED_PrintNum (G_EDICTNUM(OFS_PARM0));
1311 float(float yaw, float dist) walkmove
1314 void PF_walkmove (void)
1322 ent = PROG_TO_EDICT(pr_global_struct->self);
1323 yaw = G_FLOAT(OFS_PARM0);
1324 dist = G_FLOAT(OFS_PARM1);
1326 if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1328 G_FLOAT(OFS_RETURN) = 0;
1332 yaw = yaw*M_PI*2 / 360;
1334 move[0] = cos(yaw)*dist;
1335 move[1] = sin(yaw)*dist;
1338 // save program state, because SV_movestep may call other progs
1339 oldf = pr_xfunction;
1340 oldself = pr_global_struct->self;
1342 G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
1345 // restore program state
1346 pr_xfunction = oldf;
1347 pr_global_struct->self = oldself;
1357 void PF_droptofloor (void)
1363 ent = PROG_TO_EDICT(pr_global_struct->self);
1365 VectorCopy (ent->v.origin, end);
1368 trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
1370 if (trace.fraction == 1 || trace.allsolid)
1371 G_FLOAT(OFS_RETURN) = 0;
1374 VectorCopy (trace.endpos, ent->v.origin);
1375 SV_LinkEdict (ent, false);
1376 ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
1377 ent->v.groundentity = EDICT_TO_PROG(trace.ent);
1378 G_FLOAT(OFS_RETURN) = 1;
1379 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1380 ent->suspendedinairflag = true;
1388 void(float style, string value) lightstyle
1391 void PF_lightstyle (void)
1398 style = G_FLOAT(OFS_PARM0);
1399 val = G_STRING(OFS_PARM1);
1401 // change the string in sv
1402 sv.lightstyles[style] = val;
1404 // send message to all clients on this server
1405 if (sv.state != ss_active)
1408 for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
1409 if (client->active || client->spawned)
1411 MSG_WriteChar (&client->message, svc_lightstyle);
1412 MSG_WriteChar (&client->message,style);
1413 MSG_WriteString (&client->message, val);
1420 f = G_FLOAT(OFS_PARM0);
1422 G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1424 G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1426 void PF_floor (void)
1428 G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
1432 G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
1441 void PF_checkbottom (void)
1443 G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0));
1451 void PF_pointcontents (void)
1453 G_FLOAT(OFS_RETURN) = Mod_PointContents(G_VECTOR(OFS_PARM0), sv.worldmodel);
1460 entity nextent(entity)
1463 void PF_nextent (void)
1468 i = G_EDICTNUM(OFS_PARM0);
1472 if (i == sv.num_edicts)
1474 RETURN_EDICT(sv.edicts);
1490 Pick a vector for the player to shoot along
1491 vector aim(entity, missilespeed)
1496 edict_t *ent, *check, *bestent;
1497 vec3_t start, dir, end, bestdir;
1500 float dist, bestdist;
1503 ent = G_EDICT(OFS_PARM0);
1504 speed = G_FLOAT(OFS_PARM1);
1506 VectorCopy (ent->v.origin, start);
1509 // try sending a trace straight
1510 VectorCopy (pr_global_struct->v_forward, dir);
1511 VectorMA (start, 2048, dir, end);
1512 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1513 if (tr.ent && ((edict_t *)tr.ent)->v.takedamage == DAMAGE_AIM
1514 && (!teamplay.integer || ent->v.team <=0 || ent->v.team != ((edict_t *)tr.ent)->v.team) )
1516 VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
1521 // try all possible entities
1522 VectorCopy (dir, bestdir);
1523 bestdist = sv_aim.value;
1526 check = NEXT_EDICT(sv.edicts);
1527 for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
1529 if (check->v.takedamage != DAMAGE_AIM)
1533 if (teamplay.integer && ent->v.team > 0 && ent->v.team == check->v.team)
1534 continue; // don't aim at teammate
1535 for (j=0 ; j<3 ; j++)
1536 end[j] = check->v.origin[j]
1537 + 0.5*(check->v.mins[j] + check->v.maxs[j]);
1538 VectorSubtract (end, start, dir);
1539 VectorNormalize (dir);
1540 dist = DotProduct (dir, pr_global_struct->v_forward);
1541 if (dist < bestdist)
1542 continue; // to far to turn
1543 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1544 if (tr.ent == check)
1545 { // can shoot at this one
1553 VectorSubtract (bestent->v.origin, ent->v.origin, dir);
1554 dist = DotProduct (dir, pr_global_struct->v_forward);
1555 VectorScale (pr_global_struct->v_forward, dist, end);
1557 VectorNormalize (end);
1558 VectorCopy (end, G_VECTOR(OFS_RETURN));
1562 VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
1570 This was a major timewaster in progs, so it was converted to C
1573 void PF_changeyaw (void)
1576 float ideal, current, move, speed;
1578 ent = PROG_TO_EDICT(pr_global_struct->self);
1579 current = ANGLEMOD(ent->v.angles[1]);
1580 ideal = ent->v.ideal_yaw;
1581 speed = ent->v.yaw_speed;
1583 if (current == ideal)
1585 move = ideal - current;
1586 if (ideal > current)
1607 ent->v.angles[1] = ANGLEMOD (current + move);
1615 void PF_changepitch (void)
1618 float ideal, current, move, speed;
1621 ent = G_EDICT(OFS_PARM0);
1622 current = ANGLEMOD( ent->v.angles[0] );
1623 if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
1624 ideal = val->_float;
1627 Host_Error ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1630 if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
1631 speed = val->_float;
1634 Host_Error ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1638 if (current == ideal)
1640 move = ideal - current;
1641 if (ideal > current)
1662 ent->v.angles[0] = ANGLEMOD (current + move);
1666 ===============================================================================
1670 ===============================================================================
1673 #define MSG_BROADCAST 0 // unreliable to all
1674 #define MSG_ONE 1 // reliable to one (msg_entity)
1675 #define MSG_ALL 2 // reliable to all
1676 #define MSG_INIT 3 // write to the init string
1678 sizebuf_t *WriteDest (void)
1684 dest = G_FLOAT(OFS_PARM0);
1688 return &sv.datagram;
1691 ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
1692 entnum = NUM_FOR_EDICT(ent);
1693 if (entnum < 1 || entnum > svs.maxclients)
1694 Host_Error ("WriteDest: not a client");
1695 return &svs.clients[entnum-1].message;
1698 return &sv.reliable_datagram;
1704 Host_Error ("WriteDest: bad destination");
1711 void PF_WriteByte (void)
1713 MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
1716 void PF_WriteChar (void)
1718 MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
1721 void PF_WriteShort (void)
1723 MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
1726 void PF_WriteLong (void)
1728 MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
1731 void PF_WriteAngle (void)
1733 MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
1736 void PF_WriteCoord (void)
1738 MSG_WriteDPCoord (WriteDest(), G_FLOAT(OFS_PARM1));
1741 void PF_WriteString (void)
1743 MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
1747 void PF_WriteEntity (void)
1749 MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
1752 //=============================================================================
1754 int SV_ModelIndex (char *name);
1756 void PF_makestatic (void)
1761 ent = G_EDICT(OFS_PARM0);
1764 if (ent->v.modelindex >= 256 || ent->v.frame >= 256)
1769 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1770 MSG_WriteShort (&sv.signon, ent->v.modelindex);
1771 MSG_WriteShort (&sv.signon, ent->v.frame);
1775 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1776 MSG_WriteByte (&sv.signon, ent->v.modelindex);
1777 MSG_WriteByte (&sv.signon, ent->v.frame);
1780 MSG_WriteByte (&sv.signon, ent->v.colormap);
1781 MSG_WriteByte (&sv.signon, ent->v.skin);
1782 for (i=0 ; i<3 ; i++)
1784 MSG_WriteDPCoord(&sv.signon, ent->v.origin[i]);
1785 MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
1788 // throw the entity away now
1792 //=============================================================================
1799 void PF_setspawnparms (void)
1805 ent = G_EDICT(OFS_PARM0);
1806 i = NUM_FOR_EDICT(ent);
1807 if (i < 1 || i > svs.maxclients)
1808 Host_Error ("Entity is not a client");
1810 // copy spawn parms out of the client_t
1811 client = svs.clients + (i-1);
1813 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1814 (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
1822 void PF_changelevel (void)
1826 // make sure we don't issue two changelevels
1827 if (svs.changelevel_issued)
1829 svs.changelevel_issued = true;
1831 s = G_STRING(OFS_PARM0);
1832 Cbuf_AddText (va("changelevel %s\n",s));
1837 G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
1842 G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
1847 G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
1854 Returns a vector of length < 1
1859 void PF_randomvec (void)
1864 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1865 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1866 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1868 while (DotProduct(temp, temp) >= 1);
1869 VectorCopy (temp, G_VECTOR(OFS_RETURN));
1872 void SV_LightPoint (vec3_t color, vec3_t p);
1877 Returns a color vector indicating the lighting at the requested point.
1879 (Internal Operation note: actually measures the light beneath the point, just like
1880 the model lighting on the client)
1885 void PF_GetLight (void)
1889 p = G_VECTOR(OFS_PARM0);
1890 SV_LightPoint (color, p);
1891 VectorCopy (color, G_VECTOR(OFS_RETURN));
1894 #define MAX_QC_CVARS 128
1895 cvar_t qc_cvar[MAX_QC_CVARS];
1898 void PF_registercvar (void)
1902 name = G_STRING(OFS_PARM0);
1903 value = G_STRING(OFS_PARM1);
1904 G_FLOAT(OFS_RETURN) = 0;
1905 // first check to see if it has already been defined
1906 if (Cvar_FindVar (name))
1909 // check for overlap with a command
1910 if (Cmd_Exists (name))
1912 Con_Printf ("PF_registercvar: %s is a command\n", name);
1916 if (currentqc_cvar >= MAX_QC_CVARS)
1917 Host_Error ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
1919 // copy the name and value
1920 variable = &qc_cvar[currentqc_cvar++];
1921 variable->name = Z_Malloc (strlen(name)+1);
1922 strcpy (variable->name, name);
1923 variable->string = Z_Malloc (strlen(value)+1);
1924 strcpy (variable->string, value);
1925 variable->value = atof (value);
1927 Cvar_RegisterVariable(variable);
1928 G_FLOAT(OFS_RETURN) = 1; // success
1935 returns the minimum of two supplied floats
1942 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1944 G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1945 else if (pr_argc >= 3)
1948 float f = G_FLOAT(OFS_PARM0);
1949 for (i = 1;i < pr_argc;i++)
1950 if (G_FLOAT((OFS_PARM0+i*3)) < f)
1951 f = G_FLOAT((OFS_PARM0+i*3));
1952 G_FLOAT(OFS_RETURN) = f;
1955 Host_Error("min: must supply at least 2 floats\n");
1962 returns the maximum of two supplied floats
1969 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1971 G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1972 else if (pr_argc >= 3)
1975 float f = G_FLOAT(OFS_PARM0);
1976 for (i = 1;i < pr_argc;i++)
1977 if (G_FLOAT((OFS_PARM0+i*3)) > f)
1978 f = G_FLOAT((OFS_PARM0+i*3));
1979 G_FLOAT(OFS_RETURN) = f;
1982 Host_Error("max: must supply at least 2 floats\n");
1989 returns number bounded by supplied range
1991 min(min, value, max)
1994 void PF_bound (void)
1996 G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
2003 returns a raised to power b
2010 G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2017 copies data from one entity to another
2019 copyentity(src, dst)
2022 void PF_copyentity (void)
2025 in = G_EDICT(OFS_PARM0);
2026 out = G_EDICT(OFS_PARM1);
2027 memcpy(out, in, pr_edict_size);
2034 sets the color of a client and broadcasts the update to all connected clients
2036 setcolor(clientent, value)
2039 void PF_setcolor (void)
2044 entnum = G_EDICTNUM(OFS_PARM0);
2045 i = G_FLOAT(OFS_PARM1);
2047 if (entnum < 1 || entnum > svs.maxclients)
2049 Con_Printf ("tried to setcolor a non-client\n");
2053 client = &svs.clients[entnum-1];
2055 client->edict->v.team = (i & 15) + 1;
2057 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
2058 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
2059 MSG_WriteByte (&sv.reliable_datagram, i);
2066 effect(origin, modelname, startframe, framecount, framerate)
2069 void PF_effect (void)
2072 s = G_STRING(OFS_PARM1);
2074 Host_Error("effect: no model specified\n");
2076 SV_StartEffect(G_VECTOR(OFS_PARM0), SV_ModelIndex(s), G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
2079 void PF_te_blood (void)
2081 if (G_FLOAT(OFS_PARM2) < 1)
2083 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2084 MSG_WriteByte(&sv.datagram, TE_BLOOD);
2086 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2087 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2088 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2090 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2091 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2092 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2094 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2097 void PF_te_bloodshower (void)
2099 if (G_FLOAT(OFS_PARM3) < 1)
2101 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2102 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
2104 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2105 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2106 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2108 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2109 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2110 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2112 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
2114 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2117 void PF_te_explosionrgb (void)
2119 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2120 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
2122 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2123 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2124 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2126 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
2127 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
2128 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
2131 void PF_te_particlecube (void)
2133 if (G_FLOAT(OFS_PARM3) < 1)
2135 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2136 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
2138 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2139 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2140 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2142 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2143 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2144 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2146 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2147 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2148 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2150 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2152 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2153 // gravity true/false
2154 MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
2156 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
2159 void PF_te_particlerain (void)
2161 if (G_FLOAT(OFS_PARM3) < 1)
2163 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2164 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
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_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2171 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2172 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2174 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2175 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2176 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2178 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2180 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2183 void PF_te_particlesnow (void)
2185 if (G_FLOAT(OFS_PARM3) < 1)
2187 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2188 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
2190 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2191 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2192 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2194 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2195 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2196 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2198 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2199 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2200 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2202 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2204 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2207 void PF_te_spark (void)
2209 if (G_FLOAT(OFS_PARM2) < 1)
2211 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2212 MSG_WriteByte(&sv.datagram, TE_SPARK);
2214 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2215 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2216 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2218 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2219 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2220 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2222 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2225 void PF_te_gunshotquad (void)
2227 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2228 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
2230 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2231 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2232 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2235 void PF_te_spikequad (void)
2237 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2238 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
2240 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2241 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2242 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2245 void PF_te_superspikequad (void)
2247 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2248 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
2250 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2251 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2252 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2255 void PF_te_explosionquad (void)
2257 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2258 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2260 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2261 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2262 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2265 void PF_te_smallflash (void)
2267 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2268 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
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]);
2275 void PF_te_customflash (void)
2277 if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2279 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2280 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2282 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2283 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2284 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2286 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2288 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255));
2290 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
2291 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
2292 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
2295 void PF_te_gunshot (void)
2297 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2298 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2300 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2301 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2302 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2305 void PF_te_spike (void)
2307 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2308 MSG_WriteByte(&sv.datagram, TE_SPIKE);
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_superspike (void)
2317 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2318 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
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_explosion (void)
2327 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2328 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
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_tarexplosion (void)
2337 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2338 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
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_wizspike (void)
2347 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2348 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
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_knightspike (void)
2357 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2358 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2360 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2361 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2362 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2365 void PF_te_lavasplash (void)
2367 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2368 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2370 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2371 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2372 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2375 void PF_te_teleport (void)
2377 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2378 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
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_explosion2 (void)
2387 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2388 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
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]);
2394 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
2397 void PF_te_lightning1 (void)
2399 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2400 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2402 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2404 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2405 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2406 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2408 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2409 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2410 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2413 void PF_te_lightning2 (void)
2415 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2416 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2418 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2420 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2421 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2422 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2424 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2425 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2426 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2429 void PF_te_lightning3 (void)
2431 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2432 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2434 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2436 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2437 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2438 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2440 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2441 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2442 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2445 void PF_te_beam (void)
2447 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2448 MSG_WriteByte(&sv.datagram, TE_BEAM);
2450 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2452 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2453 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2454 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2456 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2457 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2458 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2461 void PF_te_plasmaburn (void)
2463 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2464 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2465 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2466 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2467 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2470 static void clippointtosurface(msurface_t *surf, vec3_t p, vec3_t out)
2473 vec3_t v1, clipplanenormal, normal;
2474 vec_t clipplanedist, clipdist;
2476 if (surf->flags & SURF_PLANEBACK)
2477 VectorNegate(surf->plane->normal, normal);
2479 VectorCopy(surf->plane->normal, normal);
2480 for (i = 0, j = surf->poly_numverts - 1;i < surf->poly_numverts;j = i, i++)
2482 VectorSubtract(&surf->poly_verts[j * 3], &surf->poly_verts[i * 3], v1);
2483 VectorNormalizeFast(v1);
2484 CrossProduct(v1, normal, clipplanenormal);
2485 clipplanedist = DotProduct(&surf->poly_verts[i * 3], clipplanenormal);
2486 clipdist = DotProduct(out, clipplanenormal) - clipplanedist;
2489 clipdist = -clipdist;
2490 VectorMA(out, clipdist, clipplanenormal, out);
2495 static msurface_t *getsurface(edict_t *ed, int surfnum)
2499 if (!ed || ed->free)
2501 modelindex = ed->v.modelindex;
2502 if (modelindex < 1 || modelindex >= MAX_MODELS)
2504 model = sv.models[modelindex];
2505 if (model->type != mod_brush)
2507 if (surfnum < 0 || surfnum >= model->nummodelsurfaces)
2509 return model->surfaces + surfnum + model->firstmodelsurface;
2513 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2514 void PF_getsurfacenumpoints(void)
2517 // return 0 if no such surface
2518 if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1))))
2520 G_FLOAT(OFS_RETURN) = 0;
2524 G_FLOAT(OFS_RETURN) = surf->poly_numverts;
2526 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2527 void PF_getsurfacepoint(void)
2532 VectorClear(G_VECTOR(OFS_RETURN));
2533 ed = G_EDICT(OFS_PARM0);
2534 if (!ed || ed->free)
2536 if (!(surf = getsurface(ed, G_FLOAT(OFS_PARM1))))
2538 pointnum = G_FLOAT(OFS_PARM2);
2539 if (pointnum < 0 || pointnum >= surf->poly_numverts)
2541 // FIXME: implement rotation/scaling
2542 VectorAdd(&surf->poly_verts[pointnum * 3], ed->v.origin, G_VECTOR(OFS_RETURN));
2544 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2545 void PF_getsurfacenormal(void)
2548 VectorClear(G_VECTOR(OFS_RETURN));
2549 if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1))))
2551 // FIXME: implement rotation/scaling
2552 if (surf->flags & SURF_PLANEBACK)
2553 VectorNegate(surf->plane->normal, G_VECTOR(OFS_RETURN));
2555 VectorCopy(surf->plane->normal, G_VECTOR(OFS_RETURN));
2557 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2558 void PF_getsurfacetexture(void)
2561 G_INT(OFS_RETURN) = 0;
2562 if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1))))
2564 G_INT(OFS_RETURN) = surf->texinfo->texture->name - pr_strings;
2566 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2567 void PF_getsurfacenearpoint(void)
2569 int surfnum, best, modelindex;
2571 vec_t dist, bestdist;
2576 G_FLOAT(OFS_RETURN) = -1;
2577 ed = G_EDICT(OFS_PARM0);
2578 point = G_VECTOR(OFS_PARM1);
2580 if (!ed || ed->free)
2582 modelindex = ed->v.modelindex;
2583 if (modelindex < 1 || modelindex >= MAX_MODELS)
2585 model = sv.models[modelindex];
2586 if (model->type != mod_brush)
2589 // FIXME: implement rotation/scaling
2590 VectorSubtract(point, ed->v.origin, p);
2592 bestdist = 1000000000;
2593 for (surfnum = 0;surfnum < model->nummodelsurfaces;surfnum++)
2595 surf = model->surfaces + surfnum + model->firstmodelsurface;
2596 dist = PlaneDiff(p, surf->plane);
2598 if (dist < bestdist)
2600 clippointtosurface(surf, p, clipped);
2601 VectorSubtract(clipped, p, clipped);
2602 dist += DotProduct(clipped, clipped);
2603 if (dist < bestdist)
2610 G_FLOAT(OFS_RETURN) = best;
2612 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2613 void PF_getsurfaceclippedpoint(void)
2618 VectorClear(G_VECTOR(OFS_RETURN));
2619 ed = G_EDICT(OFS_PARM0);
2620 if (!ed || ed->free)
2622 if (!(surf = getsurface(ed, G_FLOAT(OFS_PARM1))))
2624 // FIXME: implement rotation/scaling
2625 VectorSubtract(G_VECTOR(OFS_PARM2), ed->v.origin, p);
2626 clippointtosurface(surf, p, out);
2627 // FIXME: implement rotation/scaling
2628 VectorAdd(out, ed->v.origin, G_VECTOR(OFS_RETURN));
2631 void PF_Fixme (void)
2633 Host_Error ("unimplemented QC builtin"); // LordHavoc: was misspelled (bulitin)
2638 builtin_t pr_builtin[] =
2641 PF_makevectors, // void(entity e) makevectors = #1;
2642 PF_setorigin, // void(entity e, vector o) setorigin = #2;
2643 PF_setmodel, // void(entity e, string m) setmodel = #3;
2644 PF_setsize, // void(entity e, vector min, vector max) setsize = #4;
2645 PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5;
2646 PF_break, // void() break = #6;
2647 PF_random, // float() random = #7;
2648 PF_sound, // void(entity e, float chan, string samp) sound = #8;
2649 PF_normalize, // vector(vector v) normalize = #9;
2650 PF_error, // void(string e) error = #10;
2651 PF_objerror, // void(string e) objerror = #11;
2652 PF_vlen, // float(vector v) vlen = #12;
2653 PF_vectoyaw, // float(vector v) vectoyaw = #13;
2654 PF_Spawn, // entity() spawn = #14;
2655 PF_Remove, // void(entity e) remove = #15;
2656 PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16;
2657 PF_checkclient, // entity() clientlist = #17;
2658 PF_Find, // entity(entity start, .string fld, string match) find = #18;
2659 PF_precache_sound, // void(string s) precache_sound = #19;
2660 PF_precache_model, // void(string s) precache_model = #20;
2661 PF_stuffcmd, // void(entity client, string s)stuffcmd = #21;
2662 PF_findradius, // entity(vector org, float rad) findradius = #22;
2663 PF_bprint, // void(string s) bprint = #23;
2664 PF_sprint, // void(entity client, string s) sprint = #24;
2665 PF_dprint, // void(string s) dprint = #25;
2666 PF_ftos, // void(string s) ftos = #26;
2667 PF_vtos, // void(string s) vtos = #27;
2671 PF_eprint, // void(entity e) debug print an entire entity
2672 PF_walkmove, // float(float yaw, float dist) walkmove
2673 PF_Fixme, // float(float yaw, float dist) walkmove
2723 PF_precache_sound, // precache_sound2 is different only for qcc
2728 PF_Fixme, // #79 LordHavoc: dunno who owns 79-89, so these are just padding
2740 PF_tracebox, // #90 LordHavoc builtin range (9x)
2741 PF_randomvec, // #91
2743 PF_registercvar, // #93
2748 PF_FindFloat, // #98
2749 PF_checkextension, // #99
2750 #define a PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme,
2751 #define aa a a a a a a a a a a
2755 PF_copyentity, // #400 LordHavoc: builtin range (4xx)
2756 PF_setcolor, // #401
2757 PF_findchain, // #402
2758 PF_findchainfloat, // #403
2760 PF_te_blood, // #405
2761 PF_te_bloodshower, // #406
2762 PF_te_explosionrgb, // #407
2763 PF_te_particlecube, // #408
2764 PF_te_particlerain, // #409
2765 PF_te_particlesnow, // #410
2766 PF_te_spark, // #411
2767 PF_te_gunshotquad, // #412
2768 PF_te_spikequad, // #413
2769 PF_te_superspikequad, // #414
2770 PF_te_explosionquad, // #415
2771 PF_te_smallflash, // #416
2772 PF_te_customflash, // #417
2773 PF_te_gunshot, // #418
2774 PF_te_spike, // #419
2775 PF_te_superspike, // #420
2776 PF_te_explosion, // #421
2777 PF_te_tarexplosion, // #422
2778 PF_te_wizspike, // #423
2779 PF_te_knightspike, // #424
2780 PF_te_lavasplash, // #425
2781 PF_te_teleport, // #426
2782 PF_te_explosion2, // #427
2783 PF_te_lightning1, // #428
2784 PF_te_lightning2, // #429
2785 PF_te_lightning3, // #430
2787 PF_vectorvectors, // #432
2788 PF_te_plasmaburn, // #433
2789 PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2790 PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2791 PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2792 PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2793 PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2794 PF_getsurfaceclippedpoint,// #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2797 builtin_t *pr_builtins = pr_builtin;
2798 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);