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;
291 e->v->modelindex = i;
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 void PF_makestatic (void)
1759 ent = G_EDICT(OFS_PARM0);
1762 if (ent->v->modelindex >= 256 || ent->v->frame >= 256)
1767 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1768 MSG_WriteShort (&sv.signon, ent->v->modelindex);
1769 MSG_WriteShort (&sv.signon, ent->v->frame);
1773 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1774 MSG_WriteByte (&sv.signon, ent->v->modelindex);
1775 MSG_WriteByte (&sv.signon, ent->v->frame);
1778 MSG_WriteByte (&sv.signon, ent->v->colormap);
1779 MSG_WriteByte (&sv.signon, ent->v->skin);
1780 for (i=0 ; i<3 ; i++)
1782 MSG_WriteDPCoord(&sv.signon, ent->v->origin[i]);
1783 MSG_WriteAngle(&sv.signon, ent->v->angles[i]);
1786 // throw the entity away now
1790 //=============================================================================
1797 void PF_setspawnparms (void)
1803 ent = G_EDICT(OFS_PARM0);
1804 i = NUM_FOR_EDICT(ent);
1805 if (i < 1 || i > svs.maxclients)
1806 Host_Error ("Entity is not a client");
1808 // copy spawn parms out of the client_t
1809 client = svs.clients + (i-1);
1811 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1812 (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
1820 void PF_changelevel (void)
1824 // make sure we don't issue two changelevels
1825 if (svs.changelevel_issued)
1827 svs.changelevel_issued = true;
1829 s = G_STRING(OFS_PARM0);
1830 Cbuf_AddText (va("changelevel %s\n",s));
1835 G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
1840 G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
1845 G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
1852 Returns a vector of length < 1
1857 void PF_randomvec (void)
1862 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1863 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1864 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1866 while (DotProduct(temp, temp) >= 1);
1867 VectorCopy (temp, G_VECTOR(OFS_RETURN));
1870 void SV_LightPoint (vec3_t color, vec3_t p);
1875 Returns a color vector indicating the lighting at the requested point.
1877 (Internal Operation note: actually measures the light beneath the point, just like
1878 the model lighting on the client)
1883 void PF_GetLight (void)
1887 p = G_VECTOR(OFS_PARM0);
1888 SV_LightPoint (color, p);
1889 VectorCopy (color, G_VECTOR(OFS_RETURN));
1892 #define MAX_QC_CVARS 128
1893 cvar_t qc_cvar[MAX_QC_CVARS];
1896 void PF_registercvar (void)
1900 name = G_STRING(OFS_PARM0);
1901 value = G_STRING(OFS_PARM1);
1902 G_FLOAT(OFS_RETURN) = 0;
1903 // first check to see if it has already been defined
1904 if (Cvar_FindVar (name))
1907 // check for overlap with a command
1908 if (Cmd_Exists (name))
1910 Con_Printf ("PF_registercvar: %s is a command\n", name);
1914 if (currentqc_cvar >= MAX_QC_CVARS)
1915 Host_Error ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
1917 // copy the name and value
1918 variable = &qc_cvar[currentqc_cvar++];
1919 variable->name = Z_Malloc (strlen(name)+1);
1920 strcpy (variable->name, name);
1921 variable->string = Z_Malloc (strlen(value)+1);
1922 strcpy (variable->string, value);
1923 variable->value = atof (value);
1925 Cvar_RegisterVariable(variable);
1926 G_FLOAT(OFS_RETURN) = 1; // success
1933 returns the minimum of two supplied floats
1940 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1942 G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1943 else if (pr_argc >= 3)
1946 float f = G_FLOAT(OFS_PARM0);
1947 for (i = 1;i < pr_argc;i++)
1948 if (G_FLOAT((OFS_PARM0+i*3)) < f)
1949 f = G_FLOAT((OFS_PARM0+i*3));
1950 G_FLOAT(OFS_RETURN) = f;
1953 Host_Error("min: must supply at least 2 floats\n");
1960 returns the maximum of two supplied floats
1967 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1969 G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1970 else if (pr_argc >= 3)
1973 float f = G_FLOAT(OFS_PARM0);
1974 for (i = 1;i < pr_argc;i++)
1975 if (G_FLOAT((OFS_PARM0+i*3)) > f)
1976 f = G_FLOAT((OFS_PARM0+i*3));
1977 G_FLOAT(OFS_RETURN) = f;
1980 Host_Error("max: must supply at least 2 floats\n");
1987 returns number bounded by supplied range
1989 min(min, value, max)
1992 void PF_bound (void)
1994 G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
2001 returns a raised to power b
2008 G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2015 copies data from one entity to another
2017 copyentity(src, dst)
2020 void PF_copyentity (void)
2023 in = G_EDICT(OFS_PARM0);
2024 out = G_EDICT(OFS_PARM1);
2025 memcpy(out->v, in->v, progs->entityfields * 4);
2032 sets the color of a client and broadcasts the update to all connected clients
2034 setcolor(clientent, value)
2037 void PF_setcolor (void)
2042 entnum = G_EDICTNUM(OFS_PARM0);
2043 i = G_FLOAT(OFS_PARM1);
2045 if (entnum < 1 || entnum > svs.maxclients)
2047 Con_Printf ("tried to setcolor a non-client\n");
2051 client = &svs.clients[entnum-1];
2053 client->edict->v->team = (i & 15) + 1;
2055 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
2056 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
2057 MSG_WriteByte (&sv.reliable_datagram, i);
2064 effect(origin, modelname, startframe, framecount, framerate)
2067 void PF_effect (void)
2070 s = G_STRING(OFS_PARM1);
2072 Host_Error("effect: no model specified\n");
2074 SV_StartEffect(G_VECTOR(OFS_PARM0), SV_ModelIndex(s), G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
2077 void PF_te_blood (void)
2079 if (G_FLOAT(OFS_PARM2) < 1)
2081 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2082 MSG_WriteByte(&sv.datagram, TE_BLOOD);
2084 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2085 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2086 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2088 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2089 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2090 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2092 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2095 void PF_te_bloodshower (void)
2097 if (G_FLOAT(OFS_PARM3) < 1)
2099 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2100 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
2102 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2103 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2104 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2106 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2107 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2108 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2110 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
2112 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2115 void PF_te_explosionrgb (void)
2117 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2118 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
2120 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2121 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2122 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2124 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
2125 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
2126 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
2129 void PF_te_particlecube (void)
2131 if (G_FLOAT(OFS_PARM3) < 1)
2133 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2134 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
2136 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2137 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2138 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2140 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2141 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2142 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2144 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2145 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2146 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2148 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2150 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2151 // gravity true/false
2152 MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
2154 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
2157 void PF_te_particlerain (void)
2159 if (G_FLOAT(OFS_PARM3) < 1)
2161 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2162 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
2164 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2165 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2166 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2168 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2169 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2170 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2172 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2173 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2174 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2176 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2178 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2181 void PF_te_particlesnow (void)
2183 if (G_FLOAT(OFS_PARM3) < 1)
2185 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2186 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
2188 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2189 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2190 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2192 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2193 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2194 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2196 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2197 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2198 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2200 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2202 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2205 void PF_te_spark (void)
2207 if (G_FLOAT(OFS_PARM2) < 1)
2209 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2210 MSG_WriteByte(&sv.datagram, TE_SPARK);
2212 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2213 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2214 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2216 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2217 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2218 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2220 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2223 void PF_te_gunshotquad (void)
2225 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2226 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
2228 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2229 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2230 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2233 void PF_te_spikequad (void)
2235 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2236 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
2238 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2239 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2240 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2243 void PF_te_superspikequad (void)
2245 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2246 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
2248 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2249 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2250 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2253 void PF_te_explosionquad (void)
2255 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2256 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2258 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2259 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2260 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2263 void PF_te_smallflash (void)
2265 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2266 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2268 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2269 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2270 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2273 void PF_te_customflash (void)
2275 if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2277 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2278 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2280 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2281 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2282 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2284 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2286 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255));
2288 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
2289 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
2290 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
2293 void PF_te_gunshot (void)
2295 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2296 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2298 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2299 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2300 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2303 void PF_te_spike (void)
2305 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2306 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2308 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2309 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2310 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2313 void PF_te_superspike (void)
2315 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2316 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2318 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2319 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2320 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2323 void PF_te_explosion (void)
2325 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2326 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2328 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2329 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2330 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2333 void PF_te_tarexplosion (void)
2335 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2336 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2338 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2339 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2340 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2343 void PF_te_wizspike (void)
2345 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2346 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2348 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2349 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2350 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2353 void PF_te_knightspike (void)
2355 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2356 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2358 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2359 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2360 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2363 void PF_te_lavasplash (void)
2365 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2366 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2368 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2369 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2370 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2373 void PF_te_teleport (void)
2375 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2376 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2378 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2379 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2380 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2383 void PF_te_explosion2 (void)
2385 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2386 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2388 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2389 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2390 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2392 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
2395 void PF_te_lightning1 (void)
2397 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2398 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2400 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2402 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2403 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2404 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2406 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2407 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2408 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2411 void PF_te_lightning2 (void)
2413 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2414 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2416 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2418 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2419 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2420 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2422 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2423 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2424 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2427 void PF_te_lightning3 (void)
2429 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2430 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2432 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2434 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2435 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2436 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2438 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2439 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2440 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2443 void PF_te_beam (void)
2445 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2446 MSG_WriteByte(&sv.datagram, TE_BEAM);
2448 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2450 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2451 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2452 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2454 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2455 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2456 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2459 void PF_te_plasmaburn (void)
2461 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2462 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2463 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2464 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2465 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2468 static void clippointtosurface(msurface_t *surf, vec3_t p, vec3_t out)
2471 vec3_t v1, clipplanenormal, normal;
2472 vec_t clipplanedist, clipdist;
2474 if (surf->flags & SURF_PLANEBACK)
2475 VectorNegate(surf->plane->normal, normal);
2477 VectorCopy(surf->plane->normal, normal);
2478 for (i = 0, j = surf->poly_numverts - 1;i < surf->poly_numverts;j = i, i++)
2480 VectorSubtract(&surf->poly_verts[j * 3], &surf->poly_verts[i * 3], v1);
2481 VectorNormalizeFast(v1);
2482 CrossProduct(v1, normal, clipplanenormal);
2483 clipplanedist = DotProduct(&surf->poly_verts[i * 3], clipplanenormal);
2484 clipdist = DotProduct(out, clipplanenormal) - clipplanedist;
2487 clipdist = -clipdist;
2488 VectorMA(out, clipdist, clipplanenormal, out);
2493 static msurface_t *getsurface(edict_t *ed, int surfnum)
2497 if (!ed || ed->free)
2499 modelindex = ed->v->modelindex;
2500 if (modelindex < 1 || modelindex >= MAX_MODELS)
2502 model = sv.models[modelindex];
2503 if (model->type != mod_brush)
2505 if (surfnum < 0 || surfnum >= model->nummodelsurfaces)
2507 return model->surfaces + surfnum + model->firstmodelsurface;
2511 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2512 void PF_getsurfacenumpoints(void)
2515 // return 0 if no such surface
2516 if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1))))
2518 G_FLOAT(OFS_RETURN) = 0;
2522 G_FLOAT(OFS_RETURN) = surf->poly_numverts;
2524 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2525 void PF_getsurfacepoint(void)
2530 VectorClear(G_VECTOR(OFS_RETURN));
2531 ed = G_EDICT(OFS_PARM0);
2532 if (!ed || ed->free)
2534 if (!(surf = getsurface(ed, G_FLOAT(OFS_PARM1))))
2536 pointnum = G_FLOAT(OFS_PARM2);
2537 if (pointnum < 0 || pointnum >= surf->poly_numverts)
2539 // FIXME: implement rotation/scaling
2540 VectorAdd(&surf->poly_verts[pointnum * 3], ed->v->origin, G_VECTOR(OFS_RETURN));
2542 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2543 void PF_getsurfacenormal(void)
2546 VectorClear(G_VECTOR(OFS_RETURN));
2547 if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1))))
2549 // FIXME: implement rotation/scaling
2550 if (surf->flags & SURF_PLANEBACK)
2551 VectorNegate(surf->plane->normal, G_VECTOR(OFS_RETURN));
2553 VectorCopy(surf->plane->normal, G_VECTOR(OFS_RETURN));
2555 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2556 void PF_getsurfacetexture(void)
2559 G_INT(OFS_RETURN) = 0;
2560 if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1))))
2562 G_INT(OFS_RETURN) = surf->texinfo->texture->name - pr_strings;
2564 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2565 void PF_getsurfacenearpoint(void)
2567 int surfnum, best, modelindex;
2569 vec_t dist, bestdist;
2574 G_FLOAT(OFS_RETURN) = -1;
2575 ed = G_EDICT(OFS_PARM0);
2576 point = G_VECTOR(OFS_PARM1);
2578 if (!ed || ed->free)
2580 modelindex = ed->v->modelindex;
2581 if (modelindex < 1 || modelindex >= MAX_MODELS)
2583 model = sv.models[modelindex];
2584 if (model->type != mod_brush)
2587 // FIXME: implement rotation/scaling
2588 VectorSubtract(point, ed->v->origin, p);
2590 bestdist = 1000000000;
2591 for (surfnum = 0;surfnum < model->nummodelsurfaces;surfnum++)
2593 surf = model->surfaces + surfnum + model->firstmodelsurface;
2594 dist = PlaneDiff(p, surf->plane);
2596 if (dist < bestdist)
2598 clippointtosurface(surf, p, clipped);
2599 VectorSubtract(clipped, p, clipped);
2600 dist += DotProduct(clipped, clipped);
2601 if (dist < bestdist)
2608 G_FLOAT(OFS_RETURN) = best;
2610 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2611 void PF_getsurfaceclippedpoint(void)
2616 VectorClear(G_VECTOR(OFS_RETURN));
2617 ed = G_EDICT(OFS_PARM0);
2618 if (!ed || ed->free)
2620 if (!(surf = getsurface(ed, G_FLOAT(OFS_PARM1))))
2622 // FIXME: implement rotation/scaling
2623 VectorSubtract(G_VECTOR(OFS_PARM2), ed->v->origin, p);
2624 clippointtosurface(surf, p, out);
2625 // FIXME: implement rotation/scaling
2626 VectorAdd(out, ed->v->origin, G_VECTOR(OFS_RETURN));
2629 void PF_Fixme (void)
2631 Host_Error ("unimplemented QC builtin"); // LordHavoc: was misspelled (bulitin)
2636 builtin_t pr_builtin[] =
2639 PF_makevectors, // void(entity e) makevectors = #1;
2640 PF_setorigin, // void(entity e, vector o) setorigin = #2;
2641 PF_setmodel, // void(entity e, string m) setmodel = #3;
2642 PF_setsize, // void(entity e, vector min, vector max) setsize = #4;
2643 PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5;
2644 PF_break, // void() break = #6;
2645 PF_random, // float() random = #7;
2646 PF_sound, // void(entity e, float chan, string samp) sound = #8;
2647 PF_normalize, // vector(vector v) normalize = #9;
2648 PF_error, // void(string e) error = #10;
2649 PF_objerror, // void(string e) objerror = #11;
2650 PF_vlen, // float(vector v) vlen = #12;
2651 PF_vectoyaw, // float(vector v) vectoyaw = #13;
2652 PF_Spawn, // entity() spawn = #14;
2653 PF_Remove, // void(entity e) remove = #15;
2654 PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16;
2655 PF_checkclient, // entity() clientlist = #17;
2656 PF_Find, // entity(entity start, .string fld, string match) find = #18;
2657 PF_precache_sound, // void(string s) precache_sound = #19;
2658 PF_precache_model, // void(string s) precache_model = #20;
2659 PF_stuffcmd, // void(entity client, string s)stuffcmd = #21;
2660 PF_findradius, // entity(vector org, float rad) findradius = #22;
2661 PF_bprint, // void(string s) bprint = #23;
2662 PF_sprint, // void(entity client, string s) sprint = #24;
2663 PF_dprint, // void(string s) dprint = #25;
2664 PF_ftos, // void(string s) ftos = #26;
2665 PF_vtos, // void(string s) vtos = #27;
2669 PF_eprint, // void(entity e) debug print an entire entity
2670 PF_walkmove, // float(float yaw, float dist) walkmove
2671 PF_Fixme, // float(float yaw, float dist) walkmove
2721 PF_precache_sound, // precache_sound2 is different only for qcc
2726 PF_Fixme, // #79 LordHavoc: dunno who owns 79-89, so these are just padding
2738 PF_tracebox, // #90 LordHavoc builtin range (9x)
2739 PF_randomvec, // #91
2741 PF_registercvar, // #93
2746 PF_FindFloat, // #98
2747 PF_checkextension, // #99
2748 #define a PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme,
2749 #define aa a a a a a a a a a a
2753 PF_copyentity, // #400 LordHavoc: builtin range (4xx)
2754 PF_setcolor, // #401
2755 PF_findchain, // #402
2756 PF_findchainfloat, // #403
2758 PF_te_blood, // #405
2759 PF_te_bloodshower, // #406
2760 PF_te_explosionrgb, // #407
2761 PF_te_particlecube, // #408
2762 PF_te_particlerain, // #409
2763 PF_te_particlesnow, // #410
2764 PF_te_spark, // #411
2765 PF_te_gunshotquad, // #412
2766 PF_te_spikequad, // #413
2767 PF_te_superspikequad, // #414
2768 PF_te_explosionquad, // #415
2769 PF_te_smallflash, // #416
2770 PF_te_customflash, // #417
2771 PF_te_gunshot, // #418
2772 PF_te_spike, // #419
2773 PF_te_superspike, // #420
2774 PF_te_explosion, // #421
2775 PF_te_tarexplosion, // #422
2776 PF_te_wizspike, // #423
2777 PF_te_knightspike, // #424
2778 PF_te_lavasplash, // #425
2779 PF_te_teleport, // #426
2780 PF_te_explosion2, // #427
2781 PF_te_lightning1, // #428
2782 PF_te_lightning2, // #429
2783 PF_te_lightning3, // #430
2785 PF_vectorvectors, // #432
2786 PF_te_plasmaburn, // #433
2787 PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2788 PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2789 PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2790 PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2791 PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2792 PF_getsurfaceclippedpoint,// #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2795 builtin_t *pr_builtins = pr_builtin;
2796 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);