2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 cvar_t sv_aim = {CVAR_SAVE, "sv_aim", "2"}; //"0.93"}; // LordHavoc: disabled autoaim by default
25 #define RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e))
29 ===============================================================================
33 ===============================================================================
37 char *PF_VarString (int first)
43 for (i=first ; i<pr_argc ; i++)
45 strcat (out, G_STRING((OFS_PARM0+i*3)));
50 char *ENGINE_EXTENSIONS = "\
53 DP_ENT_DELTACOMPRESS \
65 DP_SV_DRAWONLYTOCLIENT \
66 DP_SV_NODRAWTOCLIENT \
67 DP_SV_EXTERIORMODELTOCLIENT \
82 DP_QC_FINDCHAINFLOAT \
93 qboolean checkextension(char *name)
98 for (e = ENGINE_EXTENSIONS;*e;e++)
105 while (*e && *e != ' ')
107 if (e - start == len)
108 if (!strncasecmp(e, name, len))
118 returns true if the extension is supported by the server
120 checkextension(extensionname)
123 void PF_checkextension (void)
125 G_FLOAT(OFS_RETURN) = checkextension(G_STRING(OFS_PARM0));
132 This is a TERMINAL error, which will kill off the entire server.
144 Con_Printf ("======SERVER ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
145 ed = PROG_TO_EDICT(pr_global_struct->self);
148 Host_Error ("Program error");
155 Dumps out self, then an error message. The program is aborted and self is
156 removed, but the level can continue.
161 void PF_objerror (void)
167 Con_Printf ("======OBJECT ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
168 ed = PROG_TO_EDICT(pr_global_struct->self);
172 // LordHavoc: bug fix - no longer kills server
173 // Host_Error ("Program error");
182 Writes new values for v_forward, v_up, and v_right based on angles
186 void PF_makevectors (void)
188 AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
195 Writes new values for v_forward, v_up, and v_right based on the given forward vector
196 vectorvectors(vector, vector)
199 void PF_vectorvectors (void)
201 VectorNormalize2(G_VECTOR(OFS_PARM0), pr_global_struct->v_forward);
202 VectorVectors(pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
209 This is the only valid way to move an object without using the physics of the world (setting velocity and waiting). Directly changing origin will not set internal links correctly, so clipping would be messed up. This should be called when an object is spawned, and then only if it is teleported.
211 setorigin (entity, origin)
214 void PF_setorigin (void)
219 e = G_EDICT(OFS_PARM0);
220 org = G_VECTOR(OFS_PARM1);
221 VectorCopy (org, e->v.origin);
222 SV_LinkEdict (e, false);
226 void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
232 float xvector[2], yvector[2];
234 vec3_t base, transformed;
239 for (i=0 ; i<3 ; i++)
241 PR_RunError ("backwards mins/maxs");
244 rotate = false; // FIXME: implement rotation properly again
248 VectorCopy (min, rmin);
249 VectorCopy (max, rmax);
253 // find min / max for rotations
254 angles = e->v.angles;
256 a = angles[1]/180 * M_PI;
260 yvector[0] = -sin(a);
263 VectorCopy (min, bounds[0]);
264 VectorCopy (max, bounds[1]);
266 rmin[0] = rmin[1] = rmin[2] = 9999;
267 rmax[0] = rmax[1] = rmax[2] = -9999;
269 for (i=0 ; i<= 1 ; i++)
271 base[0] = bounds[i][0];
272 for (j=0 ; j<= 1 ; j++)
274 base[1] = bounds[j][1];
275 for (k=0 ; k<= 1 ; k++)
277 base[2] = bounds[k][2];
279 // transform the point
280 transformed[0] = xvector[0]*base[0] + yvector[0]*base[1];
281 transformed[1] = xvector[1]*base[0] + yvector[1]*base[1];
282 transformed[2] = base[2];
284 for (l=0 ; l<3 ; l++)
286 if (transformed[l] < rmin[l])
287 rmin[l] = transformed[l];
288 if (transformed[l] > rmax[l])
289 rmax[l] = transformed[l];
296 // set derived values
297 VectorCopy (rmin, e->v.mins);
298 VectorCopy (rmax, e->v.maxs);
299 VectorSubtract (max, min, e->v.size);
302 // set derived values
303 VectorCopy (min, e->v.mins);
304 VectorCopy (max, e->v.maxs);
305 VectorSubtract (max, min, e->v.size);
307 SV_LinkEdict (e, false);
314 the size box is rotated by the current angle
315 LordHavoc: no it isn't...
317 setsize (entity, minvector, maxvector)
320 void PF_setsize (void)
325 e = G_EDICT(OFS_PARM0);
326 min = G_VECTOR(OFS_PARM1);
327 max = G_VECTOR(OFS_PARM2);
328 SetMinMaxSize (e, min, max, false);
336 setmodel(entity, model)
339 void PF_setmodel (void)
346 e = G_EDICT(OFS_PARM0);
347 m = G_STRING(OFS_PARM1);
349 // check to see if model was properly precached
350 for (i=0, check = sv.model_precache ; *check ; i++, check++)
351 if (!strcmp(*check, m))
355 PR_RunError ("no precache: %s\n", m);
358 e->v.model = m - pr_strings;
359 e->v.modelindex = i; //SV_ModelIndex (m);
361 mod = sv.models[ (int)e->v.modelindex]; // Mod_ForName (m, true);
365 { // LordHavoc: corrected model bounding box, but for compatibility that means I have to break it here
367 if (mod->type == ALIASTYPE_MDL)
369 min[0] = min[1] = min[2] = -16;
370 max[0] = max[1] = max[2] = 16;
371 SetMinMaxSize (e, min, max, true);
374 SetMinMaxSize (e, mod->mins, mod->maxs, true);
377 SetMinMaxSize (e, mod->mins, mod->maxs, true);
379 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
386 broadcast print to everyone on server
391 void PF_bprint (void)
396 SV_BroadcastPrintf ("%s", s);
403 single print to a specific client
405 sprint(clientent, value)
408 void PF_sprint (void)
414 entnum = G_EDICTNUM(OFS_PARM0);
417 if (entnum < 1 || entnum > svs.maxclients)
419 Con_Printf ("tried to sprint to a non-client\n");
423 client = &svs.clients[entnum-1];
425 MSG_WriteChar (&client->message,svc_print);
426 MSG_WriteString (&client->message, s );
434 single print to a specific client
436 centerprint(clientent, value)
439 void PF_centerprint (void)
445 entnum = G_EDICTNUM(OFS_PARM0);
448 if (entnum < 1 || entnum > svs.maxclients)
450 Con_Printf ("tried to sprint to a non-client\n");
454 client = &svs.clients[entnum-1];
456 MSG_WriteChar (&client->message,svc_centerprint);
457 MSG_WriteString (&client->message, s );
465 vector normalize(vector)
468 void PF_normalize (void)
474 value1 = G_VECTOR(OFS_PARM0);
476 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
480 newvalue[0] = newvalue[1] = newvalue[2] = 0;
484 newvalue[0] = value1[0] * new;
485 newvalue[1] = value1[1] * new;
486 newvalue[2] = value1[2] * new;
489 VectorCopy (newvalue, G_VECTOR(OFS_RETURN));
504 value1 = G_VECTOR(OFS_PARM0);
506 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
509 G_FLOAT(OFS_RETURN) = new;
516 float vectoyaw(vector)
519 void PF_vectoyaw (void)
524 value1 = G_VECTOR(OFS_PARM0);
526 if (value1[1] == 0 && value1[0] == 0)
530 yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
535 G_FLOAT(OFS_RETURN) = yaw;
543 vector vectoangles(vector)
546 void PF_vectoangles (void)
552 value1 = G_VECTOR(OFS_PARM0);
554 if (value1[1] == 0 && value1[0] == 0)
564 // LordHavoc: optimized a bit
567 yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
571 else if (value1[1] > 0)
576 forward = sqrt(value1[0]*value1[0] + value1[1]*value1[1]);
577 pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
582 G_FLOAT(OFS_RETURN+0) = pitch;
583 G_FLOAT(OFS_RETURN+1) = yaw;
584 G_FLOAT(OFS_RETURN+2) = 0;
591 Returns a number from 0<= num < 1
596 void PF_random (void)
600 num = (rand ()&0x7fff) / ((float)0x7fff);
602 G_FLOAT(OFS_RETURN) = num;
609 particle(origin, color, count)
612 void PF_particle (void)
618 org = G_VECTOR(OFS_PARM0);
619 dir = G_VECTOR(OFS_PARM1);
620 color = G_FLOAT(OFS_PARM2);
621 count = G_FLOAT(OFS_PARM3);
622 SV_StartParticle (org, dir, color, count);
632 void PF_ambientsound (void)
637 float vol, attenuation;
638 int i, soundnum, large;
640 pos = G_VECTOR (OFS_PARM0);
641 samp = G_STRING(OFS_PARM1);
642 vol = G_FLOAT(OFS_PARM2);
643 attenuation = G_FLOAT(OFS_PARM3);
645 // check to see if samp was properly precached
646 for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++)
647 if (!strcmp(*check,samp))
652 Con_Printf ("no precache: %s\n", samp);
660 // add an svc_spawnambient command to the level signon packet
663 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
665 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
667 for (i=0 ; i<3 ; i++)
668 MSG_WriteFloatCoord(&sv.signon, pos[i]);
671 MSG_WriteShort (&sv.signon, soundnum);
673 MSG_WriteByte (&sv.signon, soundnum);
675 MSG_WriteByte (&sv.signon, vol*255);
676 MSG_WriteByte (&sv.signon, attenuation*64);
684 Each entity can have eight independant sound sources, like voice,
687 Channel 0 is an auto-allocate channel, the others override anything
688 already running on that entity/channel pair.
690 An attenuation of 0 will play full volume everywhere in the level.
691 Larger attenuations will drop off.
703 entity = G_EDICT(OFS_PARM0);
704 channel = G_FLOAT(OFS_PARM1);
705 sample = G_STRING(OFS_PARM2);
706 volume = G_FLOAT(OFS_PARM3) * 255;
707 attenuation = G_FLOAT(OFS_PARM4);
709 if (volume < 0 || volume > 255)
710 Host_Error ("SV_StartSound: volume = %i", volume);
712 if (attenuation < 0 || attenuation > 4)
713 Host_Error ("SV_StartSound: attenuation = %f", attenuation);
715 if (channel < 0 || channel > 7)
716 Host_Error ("SV_StartSound: channel = %i", channel);
718 SV_StartSound (entity, channel, sample, volume, attenuation);
730 // Con_Printf ("break statement\n");
731 // *(int *)-4 = 0; // dump to debugger
732 PR_RunError ("break statement");
739 Used for use tracing and shot targeting
740 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
741 if the tryents flag is set.
743 traceline (vector1, vector2, tryents)
746 void PF_traceline (void)
753 v1 = G_VECTOR(OFS_PARM0);
754 v2 = G_VECTOR(OFS_PARM1);
755 nomonsters = G_FLOAT(OFS_PARM2);
756 ent = G_EDICT(OFS_PARM3);
758 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters, ent);
760 pr_global_struct->trace_allsolid = trace.allsolid;
761 pr_global_struct->trace_startsolid = trace.startsolid;
762 pr_global_struct->trace_fraction = trace.fraction;
763 pr_global_struct->trace_inwater = trace.inwater;
764 pr_global_struct->trace_inopen = trace.inopen;
765 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
766 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
767 pr_global_struct->trace_plane_dist = trace.plane.dist;
769 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
771 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
779 Used for use tracing and shot targeting
780 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
781 if the tryents flag is set.
783 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
786 // LordHavoc: added this for my own use, VERY useful, similar to traceline
787 void PF_tracebox (void)
789 float *v1, *v2, *m1, *m2;
794 v1 = G_VECTOR(OFS_PARM0);
795 m1 = G_VECTOR(OFS_PARM1);
796 m2 = G_VECTOR(OFS_PARM2);
797 v2 = G_VECTOR(OFS_PARM3);
798 nomonsters = G_FLOAT(OFS_PARM4);
799 ent = G_EDICT(OFS_PARM5);
801 trace = SV_Move (v1, m1, m2, v2, nomonsters, ent);
803 pr_global_struct->trace_allsolid = trace.allsolid;
804 pr_global_struct->trace_startsolid = trace.startsolid;
805 pr_global_struct->trace_fraction = trace.fraction;
806 pr_global_struct->trace_inwater = trace.inwater;
807 pr_global_struct->trace_inopen = trace.inopen;
808 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
809 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
810 pr_global_struct->trace_plane_dist = trace.plane.dist;
812 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
814 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
817 extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore);
818 void PF_TraceToss (void)
824 ent = G_EDICT(OFS_PARM0);
825 ignore = G_EDICT(OFS_PARM1);
827 trace = SV_Trace_Toss (ent, ignore);
829 pr_global_struct->trace_allsolid = trace.allsolid;
830 pr_global_struct->trace_startsolid = trace.startsolid;
831 pr_global_struct->trace_fraction = trace.fraction;
832 pr_global_struct->trace_inwater = trace.inwater;
833 pr_global_struct->trace_inopen = trace.inopen;
834 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
835 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
836 pr_global_struct->trace_plane_dist = trace.plane.dist;
838 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
840 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
848 Returns true if the given entity can move to the given position from it's
849 current position by walking or rolling.
851 scalar checkpos (entity, vector)
854 void PF_checkpos (void)
858 //============================================================================
860 byte checkpvs[MAX_MAP_LEAFS/8];
862 int PF_newcheckclient (int check)
870 // cycle to the next one
874 if (check > svs.maxclients)
875 check = svs.maxclients;
877 if (check == svs.maxclients)
884 if (i == svs.maxclients+1)
890 break; // didn't find anything else
894 if (ent->v.health <= 0)
896 if ((int)ent->v.flags & FL_NOTARGET)
899 // anything that is a client, or has a client as an enemy
903 // get the PVS for the entity
904 VectorAdd (ent->v.origin, ent->v.view_ofs, org);
905 leaf = Mod_PointInLeaf (org, sv.worldmodel);
906 pvs = Mod_LeafPVS (leaf, sv.worldmodel);
907 memcpy (checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 );
916 Returns a client (or object that has a client enemy) that would be a
919 If there is more than one valid option, they are cycled each frame
921 If (self.origin + self.viewofs) is not in the PVS of the current target,
922 it is not returned at all.
927 int c_invis, c_notvis;
928 void PF_checkclient (void)
935 // find a new check if on a new frame
936 if (sv.time - sv.lastchecktime >= 0.1)
938 sv.lastcheck = PF_newcheckclient (sv.lastcheck);
939 sv.lastchecktime = sv.time;
942 // return check if it might be visible
943 ent = EDICT_NUM(sv.lastcheck);
944 if (ent->free || ent->v.health <= 0)
946 RETURN_EDICT(sv.edicts);
950 // if current entity can't possibly see the check entity, return 0
951 self = PROG_TO_EDICT(pr_global_struct->self);
952 VectorAdd (self->v.origin, self->v.view_ofs, view);
953 leaf = Mod_PointInLeaf (view, sv.worldmodel);
954 l = (leaf - sv.worldmodel->leafs) - 1;
955 if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
958 RETURN_EDICT(sv.edicts);
962 // might be able to see it
967 //============================================================================
974 Sends text over to the client's execution buffer
976 stuffcmd (clientent, value)
979 void PF_stuffcmd (void)
985 entnum = G_EDICTNUM(OFS_PARM0);
986 if (entnum < 1 || entnum > svs.maxclients)
987 PR_RunError ("Parm 0 not a client");
988 str = G_STRING(OFS_PARM1);
991 host_client = &svs.clients[entnum-1];
992 Host_ClientCommands ("%s", str);
1000 Sends text over to the client's execution buffer
1005 void PF_localcmd (void)
1009 str = G_STRING(OFS_PARM0);
1024 str = G_STRING(OFS_PARM0);
1026 G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str);
1036 void PF_cvar_set (void)
1040 var = G_STRING(OFS_PARM0);
1041 val = G_STRING(OFS_PARM1);
1043 Cvar_Set (var, val);
1050 Returns a chain of entities that have origins within a spherical area
1052 findradius (origin, radius)
1055 void PF_findradius (void)
1057 edict_t *ent, *chain;
1063 chain = (edict_t *)sv.edicts;
1065 org = G_VECTOR(OFS_PARM0);
1066 rad = G_FLOAT(OFS_PARM1);
1068 ent = NEXT_EDICT(sv.edicts);
1069 for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
1073 if (ent->v.solid == SOLID_NOT)
1075 for (j=0 ; j<3 ; j++)
1076 eorg[j] = org[j] - (ent->v.origin[j] + (ent->v.mins[j] + ent->v.maxs[j])*0.5);
1077 if (Length(eorg) > rad)
1080 ent->v.chain = EDICT_TO_PROG(chain);
1084 RETURN_EDICT(chain);
1093 void PF_dprint (void)
1095 Con_DPrintf ("%s",PF_VarString(0));
1098 char pr_string_temp[128];
1103 v = G_FLOAT(OFS_PARM0);
1105 // LordHavoc: ftos improvement
1106 sprintf (pr_string_temp, "%g", v);
1109 sprintf (pr_string_temp, "%d",(int)v);
1111 sprintf (pr_string_temp, "%5.1f",v);
1113 G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
1119 v = G_FLOAT(OFS_PARM0);
1120 G_FLOAT(OFS_RETURN) = fabs(v);
1125 sprintf (pr_string_temp, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
1126 G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
1131 sprintf (pr_string_temp, "entity %i", G_EDICTNUM(OFS_PARM0));
1132 G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
1135 void PF_Spawn (void)
1142 void PF_Remove (void)
1146 ed = G_EDICT(OFS_PARM0);
1147 if (ed == sv.edicts)
1148 PR_RunError("remove: tried to remove world\n");
1149 if (NUM_FOR_EDICT(ed) <= svs.maxclients)
1150 PR_RunError("remove: tried to remove a client\n");
1155 // entity (entity start, .string field, string match) find = #5;
1163 e = G_EDICTNUM(OFS_PARM0);
1164 f = G_INT(OFS_PARM1);
1165 s = G_STRING(OFS_PARM2);
1168 RETURN_EDICT(sv.edicts);
1172 for (e++ ; e < sv.num_edicts ; e++)
1187 RETURN_EDICT(sv.edicts);
1190 // LordHavoc: added this for searching float, int, and entity reference fields
1191 void PF_FindFloat (void)
1198 e = G_EDICTNUM(OFS_PARM0);
1199 f = G_INT(OFS_PARM1);
1200 s = G_FLOAT(OFS_PARM2);
1202 for (e++ ; e < sv.num_edicts ; e++)
1207 if (E_FLOAT(ed,f) == s)
1214 RETURN_EDICT(sv.edicts);
1217 // chained search for strings in entity fields
1218 // entity(.string field, string match) findchain = #402;
1219 void PF_findchain (void)
1224 edict_t *ent, *chain;
1226 chain = (edict_t *)sv.edicts;
1228 f = G_INT(OFS_PARM0);
1229 s = G_STRING(OFS_PARM1);
1232 RETURN_EDICT(sv.edicts);
1236 ent = NEXT_EDICT(sv.edicts);
1237 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1241 t = E_STRING(ent,f);
1247 ent->v.chain = EDICT_TO_PROG(chain);
1251 RETURN_EDICT(chain);
1254 // LordHavoc: chained search for float, int, and entity reference fields
1255 // entity(.string field, float match) findchainfloat = #403;
1256 void PF_findchainfloat (void)
1261 edict_t *ent, *chain;
1263 chain = (edict_t *)sv.edicts;
1265 f = G_INT(OFS_PARM0);
1266 s = G_FLOAT(OFS_PARM1);
1268 ent = NEXT_EDICT(sv.edicts);
1269 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1273 if (E_FLOAT(ent,f) != s)
1276 ent->v.chain = EDICT_TO_PROG(chain);
1280 RETURN_EDICT(chain);
1283 void PR_CheckEmptyString (char *s)
1286 PR_RunError ("Bad string");
1289 void PF_precache_file (void)
1290 { // precache_file is only used to copy files with qcc, it does nothing
1291 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1294 void PF_precache_sound (void)
1299 if (sv.state != ss_loading)
1300 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1302 s = G_STRING(OFS_PARM0);
1303 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1304 PR_CheckEmptyString (s);
1306 for (i=0 ; i<MAX_SOUNDS ; i++)
1308 if (!sv.sound_precache[i])
1310 sv.sound_precache[i] = s;
1313 if (!strcmp(sv.sound_precache[i], s))
1316 PR_RunError ("PF_precache_sound: overflow");
1319 void PF_precache_model (void)
1324 if (sv.state != ss_loading)
1325 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1327 s = G_STRING(OFS_PARM0);
1328 if (hlbsp && ((!s) || (!s[0])))
1330 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1331 PR_CheckEmptyString (s);
1333 for (i=0 ; i<MAX_MODELS ; i++)
1335 if (!sv.model_precache[i])
1337 sv.model_precache[i] = s;
1338 sv.models[i] = Mod_ForName (s, true);
1341 if (!strcmp(sv.model_precache[i], s))
1344 PR_RunError ("PF_precache_model: overflow");
1348 void PF_coredump (void)
1353 void PF_traceon (void)
1358 void PF_traceoff (void)
1363 void PF_eprint (void)
1365 ED_PrintNum (G_EDICTNUM(OFS_PARM0));
1372 float(float yaw, float dist) walkmove
1375 void PF_walkmove (void)
1383 ent = PROG_TO_EDICT(pr_global_struct->self);
1384 yaw = G_FLOAT(OFS_PARM0);
1385 dist = G_FLOAT(OFS_PARM1);
1387 if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1389 G_FLOAT(OFS_RETURN) = 0;
1393 yaw = yaw*M_PI*2 / 360;
1395 move[0] = cos(yaw)*dist;
1396 move[1] = sin(yaw)*dist;
1399 // save program state, because SV_movestep may call other progs
1400 oldf = pr_xfunction;
1401 oldself = pr_global_struct->self;
1403 G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
1406 // restore program state
1407 pr_xfunction = oldf;
1408 pr_global_struct->self = oldself;
1418 void PF_droptofloor (void)
1424 ent = PROG_TO_EDICT(pr_global_struct->self);
1426 VectorCopy (ent->v.origin, end);
1429 trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent);
1431 if (trace.fraction == 1 || trace.allsolid)
1432 G_FLOAT(OFS_RETURN) = 0;
1435 VectorCopy (trace.endpos, ent->v.origin);
1436 SV_LinkEdict (ent, false);
1437 ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
1438 ent->v.groundentity = EDICT_TO_PROG(trace.ent);
1439 G_FLOAT(OFS_RETURN) = 1;
1447 void(float style, string value) lightstyle
1450 void PF_lightstyle (void)
1457 style = G_FLOAT(OFS_PARM0);
1458 val = G_STRING(OFS_PARM1);
1460 // change the string in sv
1461 sv.lightstyles[style] = val;
1463 // send message to all clients on this server
1464 if (sv.state != ss_active)
1467 for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
1468 if (client->active || client->spawned)
1470 MSG_WriteChar (&client->message, svc_lightstyle);
1471 MSG_WriteChar (&client->message,style);
1472 MSG_WriteString (&client->message, val);
1479 f = G_FLOAT(OFS_PARM0);
1481 G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1483 G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1485 void PF_floor (void)
1487 G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
1491 G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
1500 void PF_checkbottom (void)
1502 G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0));
1510 void PF_pointcontents (void)
1512 G_FLOAT(OFS_RETURN) = SV_PointContents (G_VECTOR(OFS_PARM0));
1519 entity nextent(entity)
1522 void PF_nextent (void)
1527 i = G_EDICTNUM(OFS_PARM0);
1531 if (i == sv.num_edicts)
1533 RETURN_EDICT(sv.edicts);
1549 Pick a vector for the player to shoot along
1550 vector aim(entity, missilespeed)
1555 edict_t *ent, *check, *bestent;
1556 vec3_t start, dir, end, bestdir;
1559 float dist, bestdist;
1562 ent = G_EDICT(OFS_PARM0);
1563 speed = G_FLOAT(OFS_PARM1);
1565 VectorCopy (ent->v.origin, start);
1568 // try sending a trace straight
1569 VectorCopy (pr_global_struct->v_forward, dir);
1570 VectorMA (start, 2048, dir, end);
1571 tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
1572 if (tr.ent && tr.ent->v.takedamage == DAMAGE_AIM
1573 && (!teamplay.value || ent->v.team <=0 || ent->v.team != tr.ent->v.team) )
1575 VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
1580 // try all possible entities
1581 VectorCopy (dir, bestdir);
1582 bestdist = sv_aim.value;
1585 check = NEXT_EDICT(sv.edicts);
1586 for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
1588 if (check->v.takedamage != DAMAGE_AIM)
1592 if (teamplay.value && ent->v.team > 0 && ent->v.team == check->v.team)
1593 continue; // don't aim at teammate
1594 for (j=0 ; j<3 ; j++)
1595 end[j] = check->v.origin[j]
1596 + 0.5*(check->v.mins[j] + check->v.maxs[j]);
1597 VectorSubtract (end, start, dir);
1598 VectorNormalize (dir);
1599 dist = DotProduct (dir, pr_global_struct->v_forward);
1600 if (dist < bestdist)
1601 continue; // to far to turn
1602 tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
1603 if (tr.ent == check)
1604 { // can shoot at this one
1612 VectorSubtract (bestent->v.origin, ent->v.origin, dir);
1613 dist = DotProduct (dir, pr_global_struct->v_forward);
1614 VectorScale (pr_global_struct->v_forward, dist, end);
1616 VectorNormalize (end);
1617 VectorCopy (end, G_VECTOR(OFS_RETURN));
1621 VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
1629 This was a major timewaster in progs, so it was converted to C
1632 void PF_changeyaw (void)
1635 float ideal, current, move, speed;
1637 ent = PROG_TO_EDICT(pr_global_struct->self);
1638 current = ANGLEMOD(ent->v.angles[1]);
1639 ideal = ent->v.ideal_yaw;
1640 speed = ent->v.yaw_speed;
1642 if (current == ideal)
1644 move = ideal - current;
1645 if (ideal > current)
1666 ent->v.angles[1] = ANGLEMOD (current + move);
1674 void PF_changepitch (void)
1677 float ideal, current, move, speed;
1680 ent = G_EDICT(OFS_PARM0);
1681 current = ANGLEMOD( ent->v.angles[0] );
1682 if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
1683 ideal = val->_float;
1686 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1689 if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
1690 speed = val->_float;
1693 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1697 if (current == ideal)
1699 move = ideal - current;
1700 if (ideal > current)
1721 ent->v.angles[0] = ANGLEMOD (current + move);
1725 ===============================================================================
1729 ===============================================================================
1732 #define MSG_BROADCAST 0 // unreliable to all
1733 #define MSG_ONE 1 // reliable to one (msg_entity)
1734 #define MSG_ALL 2 // reliable to all
1735 #define MSG_INIT 3 // write to the init string
1737 sizebuf_t *WriteDest (void)
1743 dest = G_FLOAT(OFS_PARM0);
1747 return &sv.datagram;
1750 ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
1751 entnum = NUM_FOR_EDICT(ent);
1752 if (entnum < 1 || entnum > svs.maxclients)
1753 PR_RunError ("WriteDest: not a client");
1754 return &svs.clients[entnum-1].message;
1757 return &sv.reliable_datagram;
1763 PR_RunError ("WriteDest: bad destination");
1770 void PF_WriteByte (void)
1772 MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
1775 void PF_WriteChar (void)
1777 MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
1780 void PF_WriteShort (void)
1782 MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
1785 void PF_WriteLong (void)
1787 MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
1790 void PF_WriteAngle (void)
1792 MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
1795 void PF_WriteCoord (void)
1797 MSG_WriteFloatCoord (WriteDest(), G_FLOAT(OFS_PARM1));
1800 void PF_WriteString (void)
1802 MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
1806 void PF_WriteEntity (void)
1808 MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
1811 //=============================================================================
1813 int SV_ModelIndex (char *name);
1815 void PF_makestatic (void)
1820 ent = G_EDICT(OFS_PARM0);
1823 if (ent->v.modelindex >= 256 || ent->v.frame >= 256)
1828 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1829 MSG_WriteShort (&sv.signon, ent->v.modelindex);
1830 MSG_WriteShort (&sv.signon, ent->v.frame);
1834 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1835 MSG_WriteByte (&sv.signon, ent->v.modelindex);
1836 MSG_WriteByte (&sv.signon, ent->v.frame);
1839 MSG_WriteByte (&sv.signon, ent->v.colormap);
1840 MSG_WriteByte (&sv.signon, ent->v.skin);
1841 for (i=0 ; i<3 ; i++)
1843 MSG_WriteFloatCoord(&sv.signon, ent->v.origin[i]);
1844 MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
1847 // throw the entity away now
1851 //=============================================================================
1858 void PF_setspawnparms (void)
1864 ent = G_EDICT(OFS_PARM0);
1865 i = NUM_FOR_EDICT(ent);
1866 if (i < 1 || i > svs.maxclients)
1867 PR_RunError ("Entity is not a client");
1869 // copy spawn parms out of the client_t
1870 client = svs.clients + (i-1);
1872 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1873 (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
1881 void PF_changelevel (void)
1885 // make sure we don't issue two changelevels
1886 if (svs.changelevel_issued)
1888 svs.changelevel_issued = true;
1890 s = G_STRING(OFS_PARM0);
1891 Cbuf_AddText (va("changelevel %s\n",s));
1896 G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
1901 G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
1906 G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
1913 Returns a vector of length < 1
1918 void PF_randomvec (void)
1923 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1924 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1925 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1927 while (DotProduct(temp, temp) >= 1);
1928 VectorCopy (temp, G_VECTOR(OFS_RETURN));
1931 void SV_LightPoint (vec3_t color, vec3_t p);
1936 Returns a color vector indicating the lighting at the requested point.
1938 (Internal Operation note: actually measures the light beneath the point, just like
1939 the model lighting on the client)
1944 void PF_GetLight (void)
1948 p = G_VECTOR(OFS_PARM0);
1949 SV_LightPoint (color, p);
1950 VectorCopy (color, G_VECTOR(OFS_RETURN));
1953 #define MAX_QC_CVARS 128
1954 cvar_t qc_cvar[MAX_QC_CVARS];
1957 void PF_registercvar (void)
1961 name = G_STRING(OFS_PARM1);
1962 value = G_STRING(OFS_PARM2);
1963 G_FLOAT(OFS_RETURN) = 0;
1964 // first check to see if it has already been defined
1965 if (Cvar_FindVar (name))
1968 // check for overlap with a command
1969 if (Cmd_Exists (name))
1971 Con_Printf ("PF_registercvar: %s is a command\n", name);
1975 if (currentqc_cvar >= MAX_QC_CVARS)
1976 PR_RunError ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
1978 // copy the name and value
1979 variable = &qc_cvar[currentqc_cvar++];
1980 variable->name = Z_Malloc (strlen(name)+1);
1981 strcpy (variable->name, name);
1982 variable->string = Z_Malloc (strlen(value)+1);
1983 strcpy (variable->string, value);
1984 variable->value = atof (value);
1986 // link the variable in
1987 variable->next = cvar_vars;
1988 cvar_vars = variable;
1989 G_FLOAT(OFS_RETURN) = 1; // success
1996 returns the minimum of two supplied floats
2003 // LordHavoc: 3+ argument enhancement suggested by FrikaC
2005 G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2006 else if (pr_argc >= 3)
2009 float f = G_FLOAT(OFS_PARM0);
2010 for (i = 1;i < pr_argc;i++)
2011 if (G_FLOAT((OFS_PARM0+i*3)) < f)
2012 f = G_FLOAT((OFS_PARM0+i*3));
2013 G_FLOAT(OFS_RETURN) = f;
2016 PR_RunError("min: must supply at least 2 floats\n");
2023 returns the maximum of two supplied floats
2030 // LordHavoc: 3+ argument enhancement suggested by FrikaC
2032 G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2033 else if (pr_argc >= 3)
2036 float f = G_FLOAT(OFS_PARM0);
2037 for (i = 1;i < pr_argc;i++)
2038 if (G_FLOAT((OFS_PARM0+i*3)) > f)
2039 f = G_FLOAT((OFS_PARM0+i*3));
2040 G_FLOAT(OFS_RETURN) = f;
2043 PR_RunError("max: must supply at least 2 floats\n");
2050 returns number bounded by supplied range
2052 min(min, value, max)
2055 void PF_bound (void)
2057 G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
2064 returns a raised to power b
2071 G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2078 copies data from one entity to another
2080 copyentity(src, dst)
2083 void PF_copyentity (void)
2086 in = G_EDICT(OFS_PARM0);
2087 out = G_EDICT(OFS_PARM1);
2088 memcpy(out, in, pr_edict_size);
2095 sets the color of a client and broadcasts the update to all connected clients
2097 setcolor(clientent, value)
2100 void PF_setcolor (void)
2105 entnum = G_EDICTNUM(OFS_PARM0);
2106 i = G_FLOAT(OFS_PARM1);
2108 if (entnum < 1 || entnum > svs.maxclients)
2110 Con_Printf ("tried to setcolor a non-client\n");
2114 client = &svs.clients[entnum-1];
2116 client->edict->v.team = (i & 15) + 1;
2118 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
2119 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
2120 MSG_WriteByte (&sv.reliable_datagram, i);
2127 effect(origin, modelname, startframe, framecount, framerate)
2130 void PF_effect (void)
2133 s = G_STRING(OFS_PARM1);
2135 PR_RunError("effect: no model specified\n");
2137 SV_StartEffect(G_VECTOR(OFS_PARM0), SV_ModelIndex(s), G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
2140 void PF_te_blood (void)
2142 if (G_FLOAT(OFS_PARM2) < 1)
2144 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2145 MSG_WriteByte(&sv.datagram, TE_BLOOD);
2147 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2148 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2149 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2151 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2152 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2153 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2155 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2158 void PF_te_bloodshower (void)
2160 if (G_FLOAT(OFS_PARM3) < 1)
2162 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2163 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
2165 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2166 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2167 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2169 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2170 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2171 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2173 MSG_WriteFloatCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
2175 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2178 void PF_te_explosionrgb (void)
2180 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2181 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
2183 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2184 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2185 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2187 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
2188 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
2189 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
2192 void PF_te_particlecube (void)
2194 if (G_FLOAT(OFS_PARM3) < 1)
2196 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2197 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
2199 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2200 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2201 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2203 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2204 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2205 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2207 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2208 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2209 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2211 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2213 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2214 // gravity true/false
2215 MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
2217 MSG_WriteFloatCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
2220 void PF_te_particlerain (void)
2222 if (G_FLOAT(OFS_PARM3) < 1)
2224 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2225 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
2227 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2228 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2229 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2231 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2232 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2233 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2235 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2236 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2237 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2239 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2241 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2244 void PF_te_particlesnow (void)
2246 if (G_FLOAT(OFS_PARM3) < 1)
2248 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2249 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
2251 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2252 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2253 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2255 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2256 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2257 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2259 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2260 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2261 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2263 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2265 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2268 void PF_te_spark (void)
2270 if (G_FLOAT(OFS_PARM2) < 1)
2272 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2273 MSG_WriteByte(&sv.datagram, TE_SPARK);
2275 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2276 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2277 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2279 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2280 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2281 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2283 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2286 void PF_te_gunshotquad (void)
2288 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2289 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
2291 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2292 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2293 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2296 void PF_te_spikequad (void)
2298 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2299 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
2301 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2302 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2303 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2306 void PF_te_superspikequad (void)
2308 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2309 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
2311 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2312 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2313 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2316 void PF_te_explosionquad (void)
2318 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2319 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2321 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2322 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2323 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2326 void PF_te_smallflash (void)
2328 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2329 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2331 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2332 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2333 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2336 void PF_te_customflash (void)
2338 if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2340 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2341 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2343 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2344 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2345 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2347 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2349 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255));
2351 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
2352 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
2353 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
2356 void PF_te_gunshot (void)
2358 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2359 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2361 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2362 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2363 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2366 void PF_te_spike (void)
2368 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2369 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2371 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2372 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2373 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2376 void PF_te_superspike (void)
2378 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2379 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2381 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2382 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2383 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2386 void PF_te_explosion (void)
2388 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2389 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2391 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2392 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2393 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2396 void PF_te_tarexplosion (void)
2398 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2399 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2401 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2402 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2403 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2406 void PF_te_wizspike (void)
2408 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2409 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2411 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2412 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2413 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2416 void PF_te_knightspike (void)
2418 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2419 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2421 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2422 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2423 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2426 void PF_te_lavasplash (void)
2428 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2429 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2431 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2432 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2433 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2436 void PF_te_teleport (void)
2438 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2439 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2441 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2442 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2443 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2446 void PF_te_explosion2 (void)
2448 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2449 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2451 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2452 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2453 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2455 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
2458 void PF_te_lightning1 (void)
2460 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2461 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2463 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2465 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2466 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2467 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2469 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2470 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2471 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2474 void PF_te_lightning2 (void)
2476 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2477 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2479 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2481 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2482 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2483 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2485 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2486 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2487 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2490 void PF_te_lightning3 (void)
2492 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2493 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2495 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2497 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2498 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2499 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2501 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2502 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2503 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2506 void PF_te_beam (void)
2508 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2509 MSG_WriteByte(&sv.datagram, TE_BEAM);
2511 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2513 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2514 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2515 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2517 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2518 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2519 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2522 void PF_Fixme (void)
2524 PR_RunError ("unimplemented builtin"); // LordHavoc: was misspelled (bulitin)
2529 builtin_t pr_builtin[] =
2532 PF_makevectors, // void(entity e) makevectors = #1;
2533 PF_setorigin, // void(entity e, vector o) setorigin = #2;
2534 PF_setmodel, // void(entity e, string m) setmodel = #3;
2535 PF_setsize, // void(entity e, vector min, vector max) setsize = #4;
2536 PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5;
2537 PF_break, // void() break = #6;
2538 PF_random, // float() random = #7;
2539 PF_sound, // void(entity e, float chan, string samp) sound = #8;
2540 PF_normalize, // vector(vector v) normalize = #9;
2541 PF_error, // void(string e) error = #10;
2542 PF_objerror, // void(string e) objerror = #11;
2543 PF_vlen, // float(vector v) vlen = #12;
2544 PF_vectoyaw, // float(vector v) vectoyaw = #13;
2545 PF_Spawn, // entity() spawn = #14;
2546 PF_Remove, // void(entity e) remove = #15;
2547 PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16;
2548 PF_checkclient, // entity() clientlist = #17;
2549 PF_Find, // entity(entity start, .string fld, string match) find = #18;
2550 PF_precache_sound, // void(string s) precache_sound = #19;
2551 PF_precache_model, // void(string s) precache_model = #20;
2552 PF_stuffcmd, // void(entity client, string s)stuffcmd = #21;
2553 PF_findradius, // entity(vector org, float rad) findradius = #22;
2554 PF_bprint, // void(string s) bprint = #23;
2555 PF_sprint, // void(entity client, string s) sprint = #24;
2556 PF_dprint, // void(string s) dprint = #25;
2557 PF_ftos, // void(string s) ftos = #26;
2558 PF_vtos, // void(string s) vtos = #27;
2562 PF_eprint, // void(entity e) debug print an entire entity
2563 PF_walkmove, // float(float yaw, float dist) walkmove
2564 PF_Fixme, // float(float yaw, float dist) walkmove
2614 PF_precache_sound, // precache_sound2 is different only for qcc
2619 PF_Fixme, // #79 LordHavoc: dunno who owns 79-89, so these are just padding
2631 PF_tracebox, // #90 LordHavoc builtin range (9x)
2632 PF_randomvec, // #91
2634 PF_registercvar, // #93
2639 PF_FindFloat, // #98
2640 PF_checkextension, // #99
2641 #define a PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme,
2642 #define aa a a a a a a a a a a
2646 PF_copyentity, // #400 LordHavoc: builtin range (4xx)
2647 PF_setcolor, // #401
2648 PF_findchain, // #402
2649 PF_findchainfloat, // #403
2651 PF_te_blood, // #405
2652 PF_te_bloodshower, // #406
2653 PF_te_explosionrgb, // #407
2654 PF_te_particlecube, // #408
2655 PF_te_particlerain, // #409
2656 PF_te_particlesnow, // #410
2657 PF_te_spark, // #411
2658 PF_te_gunshotquad, // #412
2659 PF_te_spikequad, // #413
2660 PF_te_superspikequad, // #414
2661 PF_te_explosionquad, // #415
2662 PF_te_smallflash, // #416
2663 PF_te_customflash, // #417
2664 PF_te_gunshot, // #418
2665 PF_te_spike, // #419
2666 PF_te_superspike, // #420
2667 PF_te_explosion, // #421
2668 PF_te_tarexplosion, // #422
2669 PF_te_wizspike, // #423
2670 PF_te_knightspike, // #424
2671 PF_te_lavasplash, // #425
2672 PF_te_teleport, // #426
2673 PF_te_explosion2, // #427
2674 PF_te_lightning1, // #428
2675 PF_te_lightning2, // #429
2676 PF_te_lightning3, // #430
2678 PF_vectorvectors, // #432
2681 builtin_t *pr_builtins = pr_builtin;
2682 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);