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 #define RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e))
27 ===============================================================================
31 ===============================================================================
35 char *PF_VarString (int first)
41 for (i=first ; i<pr_argc ; i++)
43 strcat (out, G_STRING((OFS_PARM0+i*3)));
48 char *ENGINE_EXTENSIONS = "\
51 DP_ENT_DELTACOMPRESS \
63 DP_SV_DRAWONLYTOCLIENT \
64 DP_SV_NODRAWTOCLIENT \
65 DP_SV_EXTERIORMODELTOCLIENT \
80 DP_QC_FINDCHAINFLOAT \
91 qboolean checkextension(char *name)
96 for (e = ENGINE_EXTENSIONS;*e;e++)
103 while (*e && *e != ' ')
105 if (e - start == len)
106 if (!strncasecmp(e, name, len))
116 returns true if the extension is supported by the server
118 checkextension(extensionname)
121 void PF_checkextension (void)
123 G_FLOAT(OFS_RETURN) = checkextension(G_STRING(OFS_PARM0));
130 This is a TERMINAL error, which will kill off the entire server.
142 Con_Printf ("======SERVER ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
143 ed = PROG_TO_EDICT(pr_global_struct->self);
146 Host_Error ("Program error");
153 Dumps out self, then an error message. The program is aborted and self is
154 removed, but the level can continue.
159 void PF_objerror (void)
165 Con_Printf ("======OBJECT ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
166 ed = PROG_TO_EDICT(pr_global_struct->self);
170 // LordHavoc: bug fix - no longer kills server
171 // Host_Error ("Program error");
180 Writes new values for v_forward, v_up, and v_right based on angles
184 void PF_makevectors (void)
186 AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
193 Writes new values for v_forward, v_up, and v_right based on the given forward vector
194 vectorvectors(vector, vector)
197 void PF_vectorvectors (void)
199 VectorNormalize2(G_VECTOR(OFS_PARM0), pr_global_struct->v_forward);
200 VectorVectors(pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
207 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.
209 setorigin (entity, origin)
212 void PF_setorigin (void)
217 e = G_EDICT(OFS_PARM0);
218 org = G_VECTOR(OFS_PARM1);
219 VectorCopy (org, e->v.origin);
220 SV_LinkEdict (e, false);
224 void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
230 float xvector[2], yvector[2];
232 vec3_t base, transformed;
237 for (i=0 ; i<3 ; i++)
239 PR_RunError ("backwards mins/maxs");
242 rotate = false; // FIXME: implement rotation properly again
246 VectorCopy (min, rmin);
247 VectorCopy (max, rmax);
251 // find min / max for rotations
252 angles = e->v.angles;
254 a = angles[1]/180 * M_PI;
258 yvector[0] = -sin(a);
261 VectorCopy (min, bounds[0]);
262 VectorCopy (max, bounds[1]);
264 rmin[0] = rmin[1] = rmin[2] = 9999;
265 rmax[0] = rmax[1] = rmax[2] = -9999;
267 for (i=0 ; i<= 1 ; i++)
269 base[0] = bounds[i][0];
270 for (j=0 ; j<= 1 ; j++)
272 base[1] = bounds[j][1];
273 for (k=0 ; k<= 1 ; k++)
275 base[2] = bounds[k][2];
277 // transform the point
278 transformed[0] = xvector[0]*base[0] + yvector[0]*base[1];
279 transformed[1] = xvector[1]*base[0] + yvector[1]*base[1];
280 transformed[2] = base[2];
282 for (l=0 ; l<3 ; l++)
284 if (transformed[l] < rmin[l])
285 rmin[l] = transformed[l];
286 if (transformed[l] > rmax[l])
287 rmax[l] = transformed[l];
294 // set derived values
295 VectorCopy (rmin, e->v.mins);
296 VectorCopy (rmax, e->v.maxs);
297 VectorSubtract (max, min, e->v.size);
300 // set derived values
301 VectorCopy (min, e->v.mins);
302 VectorCopy (max, e->v.maxs);
303 VectorSubtract (max, min, e->v.size);
305 SV_LinkEdict (e, false);
312 the size box is rotated by the current angle
313 LordHavoc: no it isn't...
315 setsize (entity, minvector, maxvector)
318 void PF_setsize (void)
323 e = G_EDICT(OFS_PARM0);
324 min = G_VECTOR(OFS_PARM1);
325 max = G_VECTOR(OFS_PARM2);
326 SetMinMaxSize (e, min, max, false);
334 setmodel(entity, model)
337 void PF_setmodel (void)
344 e = G_EDICT(OFS_PARM0);
345 m = G_STRING(OFS_PARM1);
347 // check to see if model was properly precached
348 for (i=0, check = sv.model_precache ; *check ; i++, check++)
349 if (!strcmp(*check, m))
353 PR_RunError ("no precache: %s\n", m);
356 e->v.model = m - pr_strings;
357 e->v.modelindex = i; //SV_ModelIndex (m);
359 mod = sv.models[ (int)e->v.modelindex]; // Mod_ForName (m, true);
363 { // LordHavoc: corrected model bounding box, but for compatibility that means I have to break it here
365 if (mod->type == ALIASTYPE_MDL)
367 min[0] = min[1] = min[2] = -16;
368 max[0] = max[1] = max[2] = 16;
369 SetMinMaxSize (e, min, max, true);
372 SetMinMaxSize (e, mod->mins, mod->maxs, true);
375 SetMinMaxSize (e, mod->mins, mod->maxs, true);
377 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
384 broadcast print to everyone on server
389 void PF_bprint (void)
394 SV_BroadcastPrintf ("%s", s);
401 single print to a specific client
403 sprint(clientent, value)
406 void PF_sprint (void)
412 entnum = G_EDICTNUM(OFS_PARM0);
415 if (entnum < 1 || entnum > svs.maxclients)
417 Con_Printf ("tried to sprint to a non-client\n");
421 client = &svs.clients[entnum-1];
423 MSG_WriteChar (&client->message,svc_print);
424 MSG_WriteString (&client->message, s );
432 single print to a specific client
434 centerprint(clientent, value)
437 void PF_centerprint (void)
443 entnum = G_EDICTNUM(OFS_PARM0);
446 if (entnum < 1 || entnum > svs.maxclients)
448 Con_Printf ("tried to sprint to a non-client\n");
452 client = &svs.clients[entnum-1];
454 MSG_WriteChar (&client->message,svc_centerprint);
455 MSG_WriteString (&client->message, s );
463 vector normalize(vector)
466 void PF_normalize (void)
472 value1 = G_VECTOR(OFS_PARM0);
474 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
478 newvalue[0] = newvalue[1] = newvalue[2] = 0;
482 newvalue[0] = value1[0] * new;
483 newvalue[1] = value1[1] * new;
484 newvalue[2] = value1[2] * new;
487 VectorCopy (newvalue, G_VECTOR(OFS_RETURN));
502 value1 = G_VECTOR(OFS_PARM0);
504 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
507 G_FLOAT(OFS_RETURN) = new;
514 float vectoyaw(vector)
517 void PF_vectoyaw (void)
522 value1 = G_VECTOR(OFS_PARM0);
524 if (value1[1] == 0 && value1[0] == 0)
528 yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
533 G_FLOAT(OFS_RETURN) = yaw;
541 vector vectoangles(vector)
544 void PF_vectoangles (void)
550 value1 = G_VECTOR(OFS_PARM0);
552 if (value1[1] == 0 && value1[0] == 0)
562 // LordHavoc: optimized a bit
565 yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
569 else if (value1[1] > 0)
574 forward = sqrt(value1[0]*value1[0] + value1[1]*value1[1]);
575 pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
580 G_FLOAT(OFS_RETURN+0) = pitch;
581 G_FLOAT(OFS_RETURN+1) = yaw;
582 G_FLOAT(OFS_RETURN+2) = 0;
589 Returns a number from 0<= num < 1
594 void PF_random (void)
598 num = (rand ()&0x7fff) / ((float)0x7fff);
600 G_FLOAT(OFS_RETURN) = num;
607 particle(origin, color, count)
610 void PF_particle (void)
616 org = G_VECTOR(OFS_PARM0);
617 dir = G_VECTOR(OFS_PARM1);
618 color = G_FLOAT(OFS_PARM2);
619 count = G_FLOAT(OFS_PARM3);
620 SV_StartParticle (org, dir, color, count);
630 void PF_ambientsound (void)
635 float vol, attenuation;
636 int i, soundnum, large;
638 pos = G_VECTOR (OFS_PARM0);
639 samp = G_STRING(OFS_PARM1);
640 vol = G_FLOAT(OFS_PARM2);
641 attenuation = G_FLOAT(OFS_PARM3);
643 // check to see if samp was properly precached
644 for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++)
645 if (!strcmp(*check,samp))
650 Con_Printf ("no precache: %s\n", samp);
658 // add an svc_spawnambient command to the level signon packet
661 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
663 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
665 for (i=0 ; i<3 ; i++)
666 MSG_WriteFloatCoord(&sv.signon, pos[i]);
669 MSG_WriteShort (&sv.signon, soundnum);
671 MSG_WriteByte (&sv.signon, soundnum);
673 MSG_WriteByte (&sv.signon, vol*255);
674 MSG_WriteByte (&sv.signon, attenuation*64);
682 Each entity can have eight independant sound sources, like voice,
685 Channel 0 is an auto-allocate channel, the others override anything
686 already running on that entity/channel pair.
688 An attenuation of 0 will play full volume everywhere in the level.
689 Larger attenuations will drop off.
701 entity = G_EDICT(OFS_PARM0);
702 channel = G_FLOAT(OFS_PARM1);
703 sample = G_STRING(OFS_PARM2);
704 volume = G_FLOAT(OFS_PARM3) * 255;
705 attenuation = G_FLOAT(OFS_PARM4);
707 if (volume < 0 || volume > 255)
708 Host_Error ("SV_StartSound: volume = %i", volume);
710 if (attenuation < 0 || attenuation > 4)
711 Host_Error ("SV_StartSound: attenuation = %f", attenuation);
713 if (channel < 0 || channel > 7)
714 Host_Error ("SV_StartSound: channel = %i", channel);
716 SV_StartSound (entity, channel, sample, volume, attenuation);
728 // Con_Printf ("break statement\n");
729 // *(int *)-4 = 0; // dump to debugger
730 PR_RunError ("break statement");
737 Used for use tracing and shot targeting
738 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
739 if the tryents flag is set.
741 traceline (vector1, vector2, tryents)
744 void PF_traceline (void)
751 v1 = G_VECTOR(OFS_PARM0);
752 v2 = G_VECTOR(OFS_PARM1);
753 nomonsters = G_FLOAT(OFS_PARM2);
754 ent = G_EDICT(OFS_PARM3);
756 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters, ent);
758 pr_global_struct->trace_allsolid = trace.allsolid;
759 pr_global_struct->trace_startsolid = trace.startsolid;
760 pr_global_struct->trace_fraction = trace.fraction;
761 pr_global_struct->trace_inwater = trace.inwater;
762 pr_global_struct->trace_inopen = trace.inopen;
763 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
764 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
765 pr_global_struct->trace_plane_dist = trace.plane.dist;
767 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
769 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
777 Used for use tracing and shot targeting
778 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
779 if the tryents flag is set.
781 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
784 // LordHavoc: added this for my own use, VERY useful, similar to traceline
785 void PF_tracebox (void)
787 float *v1, *v2, *m1, *m2;
792 v1 = G_VECTOR(OFS_PARM0);
793 m1 = G_VECTOR(OFS_PARM1);
794 m2 = G_VECTOR(OFS_PARM2);
795 v2 = G_VECTOR(OFS_PARM3);
796 nomonsters = G_FLOAT(OFS_PARM4);
797 ent = G_EDICT(OFS_PARM5);
799 trace = SV_Move (v1, m1, m2, v2, nomonsters, ent);
801 pr_global_struct->trace_allsolid = trace.allsolid;
802 pr_global_struct->trace_startsolid = trace.startsolid;
803 pr_global_struct->trace_fraction = trace.fraction;
804 pr_global_struct->trace_inwater = trace.inwater;
805 pr_global_struct->trace_inopen = trace.inopen;
806 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
807 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
808 pr_global_struct->trace_plane_dist = trace.plane.dist;
810 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
812 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
815 extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore);
816 void PF_TraceToss (void)
822 ent = G_EDICT(OFS_PARM0);
823 ignore = G_EDICT(OFS_PARM1);
825 trace = SV_Trace_Toss (ent, ignore);
827 pr_global_struct->trace_allsolid = trace.allsolid;
828 pr_global_struct->trace_startsolid = trace.startsolid;
829 pr_global_struct->trace_fraction = trace.fraction;
830 pr_global_struct->trace_inwater = trace.inwater;
831 pr_global_struct->trace_inopen = trace.inopen;
832 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
833 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
834 pr_global_struct->trace_plane_dist = trace.plane.dist;
836 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
838 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
846 Returns true if the given entity can move to the given position from it's
847 current position by walking or rolling.
849 scalar checkpos (entity, vector)
852 void PF_checkpos (void)
856 //============================================================================
858 byte checkpvs[MAX_MAP_LEAFS/8];
860 int PF_newcheckclient (int check)
868 // cycle to the next one
872 if (check > svs.maxclients)
873 check = svs.maxclients;
875 if (check == svs.maxclients)
882 if (i == svs.maxclients+1)
888 break; // didn't find anything else
892 if (ent->v.health <= 0)
894 if ((int)ent->v.flags & FL_NOTARGET)
897 // anything that is a client, or has a client as an enemy
901 // get the PVS for the entity
902 VectorAdd (ent->v.origin, ent->v.view_ofs, org);
903 leaf = Mod_PointInLeaf (org, sv.worldmodel);
904 pvs = Mod_LeafPVS (leaf, sv.worldmodel);
905 memcpy (checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 );
914 Returns a client (or object that has a client enemy) that would be a
917 If there is more than one valid option, they are cycled each frame
919 If (self.origin + self.viewofs) is not in the PVS of the current target,
920 it is not returned at all.
925 int c_invis, c_notvis;
926 void PF_checkclient (void)
933 // find a new check if on a new frame
934 if (sv.time - sv.lastchecktime >= 0.1)
936 sv.lastcheck = PF_newcheckclient (sv.lastcheck);
937 sv.lastchecktime = sv.time;
940 // return check if it might be visible
941 ent = EDICT_NUM(sv.lastcheck);
942 if (ent->free || ent->v.health <= 0)
944 RETURN_EDICT(sv.edicts);
948 // if current entity can't possibly see the check entity, return 0
949 self = PROG_TO_EDICT(pr_global_struct->self);
950 VectorAdd (self->v.origin, self->v.view_ofs, view);
951 leaf = Mod_PointInLeaf (view, sv.worldmodel);
952 l = (leaf - sv.worldmodel->leafs) - 1;
953 if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
956 RETURN_EDICT(sv.edicts);
960 // might be able to see it
965 //============================================================================
972 Sends text over to the client's execution buffer
974 stuffcmd (clientent, value)
977 void PF_stuffcmd (void)
983 entnum = G_EDICTNUM(OFS_PARM0);
984 if (entnum < 1 || entnum > svs.maxclients)
985 PR_RunError ("Parm 0 not a client");
986 str = G_STRING(OFS_PARM1);
989 host_client = &svs.clients[entnum-1];
990 Host_ClientCommands ("%s", str);
998 Sends text over to the client's execution buffer
1003 void PF_localcmd (void)
1007 str = G_STRING(OFS_PARM0);
1022 str = G_STRING(OFS_PARM0);
1024 G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str);
1034 void PF_cvar_set (void)
1038 var = G_STRING(OFS_PARM0);
1039 val = G_STRING(OFS_PARM1);
1041 Cvar_Set (var, val);
1048 Returns a chain of entities that have origins within a spherical area
1050 findradius (origin, radius)
1053 void PF_findradius (void)
1055 edict_t *ent, *chain;
1061 chain = (edict_t *)sv.edicts;
1063 org = G_VECTOR(OFS_PARM0);
1064 rad = G_FLOAT(OFS_PARM1);
1066 ent = NEXT_EDICT(sv.edicts);
1067 for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
1071 if (ent->v.solid == SOLID_NOT)
1073 for (j=0 ; j<3 ; j++)
1074 eorg[j] = org[j] - (ent->v.origin[j] + (ent->v.mins[j] + ent->v.maxs[j])*0.5);
1075 if (Length(eorg) > rad)
1078 ent->v.chain = EDICT_TO_PROG(chain);
1082 RETURN_EDICT(chain);
1091 void PF_dprint (void)
1093 Con_DPrintf ("%s",PF_VarString(0));
1096 char pr_string_temp[128];
1101 v = G_FLOAT(OFS_PARM0);
1103 // LordHavoc: ftos improvement
1104 sprintf (pr_string_temp, "%g", v);
1107 sprintf (pr_string_temp, "%d",(int)v);
1109 sprintf (pr_string_temp, "%5.1f",v);
1111 G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
1117 v = G_FLOAT(OFS_PARM0);
1118 G_FLOAT(OFS_RETURN) = fabs(v);
1123 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]);
1124 G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
1129 sprintf (pr_string_temp, "entity %i", G_EDICTNUM(OFS_PARM0));
1130 G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
1133 void PF_Spawn (void)
1140 void PF_Remove (void)
1144 ed = G_EDICT(OFS_PARM0);
1145 if (ed == sv.edicts)
1146 PR_RunError("remove: tried to remove world\n");
1147 if (NUM_FOR_EDICT(ed) <= svs.maxclients)
1148 PR_RunError("remove: tried to remove a client\n");
1153 // entity (entity start, .string field, string match) find = #5;
1161 e = G_EDICTNUM(OFS_PARM0);
1162 f = G_INT(OFS_PARM1);
1163 s = G_STRING(OFS_PARM2);
1166 RETURN_EDICT(sv.edicts);
1170 for (e++ ; e < sv.num_edicts ; e++)
1185 RETURN_EDICT(sv.edicts);
1188 // LordHavoc: added this for searching float, int, and entity reference fields
1189 void PF_FindFloat (void)
1196 e = G_EDICTNUM(OFS_PARM0);
1197 f = G_INT(OFS_PARM1);
1198 s = G_FLOAT(OFS_PARM2);
1200 for (e++ ; e < sv.num_edicts ; e++)
1205 if (E_FLOAT(ed,f) == s)
1212 RETURN_EDICT(sv.edicts);
1215 // chained search for strings in entity fields
1216 // entity(.string field, string match) findchain = #402;
1217 void PF_findchain (void)
1222 edict_t *ent, *chain;
1224 chain = (edict_t *)sv.edicts;
1226 f = G_INT(OFS_PARM0);
1227 s = G_STRING(OFS_PARM1);
1230 RETURN_EDICT(sv.edicts);
1234 ent = NEXT_EDICT(sv.edicts);
1235 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1239 t = E_STRING(ent,f);
1245 ent->v.chain = EDICT_TO_PROG(chain);
1249 RETURN_EDICT(chain);
1252 // LordHavoc: chained search for float, int, and entity reference fields
1253 // entity(.string field, float match) findchainfloat = #403;
1254 void PF_findchainfloat (void)
1259 edict_t *ent, *chain;
1261 chain = (edict_t *)sv.edicts;
1263 f = G_INT(OFS_PARM0);
1264 s = G_FLOAT(OFS_PARM1);
1266 ent = NEXT_EDICT(sv.edicts);
1267 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1271 if (E_FLOAT(ent,f) != s)
1274 ent->v.chain = EDICT_TO_PROG(chain);
1278 RETURN_EDICT(chain);
1281 void PR_CheckEmptyString (char *s)
1284 PR_RunError ("Bad string");
1287 void PF_precache_file (void)
1288 { // precache_file is only used to copy files with qcc, it does nothing
1289 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1292 void PF_precache_sound (void)
1297 if (sv.state != ss_loading)
1298 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1300 s = G_STRING(OFS_PARM0);
1301 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1302 PR_CheckEmptyString (s);
1304 for (i=0 ; i<MAX_SOUNDS ; i++)
1306 if (!sv.sound_precache[i])
1308 sv.sound_precache[i] = s;
1311 if (!strcmp(sv.sound_precache[i], s))
1314 PR_RunError ("PF_precache_sound: overflow");
1317 void PF_precache_model (void)
1322 if (sv.state != ss_loading)
1323 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1325 s = G_STRING(OFS_PARM0);
1326 if (hlbsp && ((!s) || (!s[0])))
1328 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1329 PR_CheckEmptyString (s);
1331 for (i=0 ; i<MAX_MODELS ; i++)
1333 if (!sv.model_precache[i])
1335 sv.model_precache[i] = s;
1336 sv.models[i] = Mod_ForName (s, true);
1339 if (!strcmp(sv.model_precache[i], s))
1342 PR_RunError ("PF_precache_model: overflow");
1346 void PF_coredump (void)
1351 void PF_traceon (void)
1356 void PF_traceoff (void)
1361 void PF_eprint (void)
1363 ED_PrintNum (G_EDICTNUM(OFS_PARM0));
1370 float(float yaw, float dist) walkmove
1373 void PF_walkmove (void)
1381 ent = PROG_TO_EDICT(pr_global_struct->self);
1382 yaw = G_FLOAT(OFS_PARM0);
1383 dist = G_FLOAT(OFS_PARM1);
1385 if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1387 G_FLOAT(OFS_RETURN) = 0;
1391 yaw = yaw*M_PI*2 / 360;
1393 move[0] = cos(yaw)*dist;
1394 move[1] = sin(yaw)*dist;
1397 // save program state, because SV_movestep may call other progs
1398 oldf = pr_xfunction;
1399 oldself = pr_global_struct->self;
1401 G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
1404 // restore program state
1405 pr_xfunction = oldf;
1406 pr_global_struct->self = oldself;
1416 void PF_droptofloor (void)
1422 ent = PROG_TO_EDICT(pr_global_struct->self);
1424 VectorCopy (ent->v.origin, end);
1427 trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent);
1429 if (trace.fraction == 1 || trace.allsolid)
1430 G_FLOAT(OFS_RETURN) = 0;
1433 VectorCopy (trace.endpos, ent->v.origin);
1434 SV_LinkEdict (ent, false);
1435 ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
1436 ent->v.groundentity = EDICT_TO_PROG(trace.ent);
1437 G_FLOAT(OFS_RETURN) = 1;
1445 void(float style, string value) lightstyle
1448 void PF_lightstyle (void)
1455 style = G_FLOAT(OFS_PARM0);
1456 val = G_STRING(OFS_PARM1);
1458 // change the string in sv
1459 sv.lightstyles[style] = val;
1461 // send message to all clients on this server
1462 if (sv.state != ss_active)
1465 for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
1466 if (client->active || client->spawned)
1468 MSG_WriteChar (&client->message, svc_lightstyle);
1469 MSG_WriteChar (&client->message,style);
1470 MSG_WriteString (&client->message, val);
1477 f = G_FLOAT(OFS_PARM0);
1479 G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1481 G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1483 void PF_floor (void)
1485 G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
1489 G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
1498 void PF_checkbottom (void)
1500 G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0));
1508 void PF_pointcontents (void)
1510 G_FLOAT(OFS_RETURN) = SV_PointContents (G_VECTOR(OFS_PARM0));
1517 entity nextent(entity)
1520 void PF_nextent (void)
1525 i = G_EDICTNUM(OFS_PARM0);
1529 if (i == sv.num_edicts)
1531 RETURN_EDICT(sv.edicts);
1547 Pick a vector for the player to shoot along
1548 vector aim(entity, missilespeed)
1551 cvar_t sv_aim = {"sv_aim", "0.93"};
1554 edict_t *ent, *check, *bestent;
1555 vec3_t start, dir, end, bestdir;
1558 float dist, bestdist;
1561 ent = G_EDICT(OFS_PARM0);
1562 speed = G_FLOAT(OFS_PARM1);
1564 VectorCopy (ent->v.origin, start);
1567 // try sending a trace straight
1568 VectorCopy (pr_global_struct->v_forward, dir);
1569 VectorMA (start, 2048, dir, end);
1570 tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
1571 if (tr.ent && tr.ent->v.takedamage == DAMAGE_AIM
1572 && (!teamplay.value || ent->v.team <=0 || ent->v.team != tr.ent->v.team) )
1574 VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
1579 // try all possible entities
1580 VectorCopy (dir, bestdir);
1581 bestdist = sv_aim.value;
1584 check = NEXT_EDICT(sv.edicts);
1585 for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
1587 if (check->v.takedamage != DAMAGE_AIM)
1591 if (teamplay.value && ent->v.team > 0 && ent->v.team == check->v.team)
1592 continue; // don't aim at teammate
1593 for (j=0 ; j<3 ; j++)
1594 end[j] = check->v.origin[j]
1595 + 0.5*(check->v.mins[j] + check->v.maxs[j]);
1596 VectorSubtract (end, start, dir);
1597 VectorNormalize (dir);
1598 dist = DotProduct (dir, pr_global_struct->v_forward);
1599 if (dist < bestdist)
1600 continue; // to far to turn
1601 tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
1602 if (tr.ent == check)
1603 { // can shoot at this one
1611 VectorSubtract (bestent->v.origin, ent->v.origin, dir);
1612 dist = DotProduct (dir, pr_global_struct->v_forward);
1613 VectorScale (pr_global_struct->v_forward, dist, end);
1615 VectorNormalize (end);
1616 VectorCopy (end, G_VECTOR(OFS_RETURN));
1620 VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
1628 This was a major timewaster in progs, so it was converted to C
1631 void PF_changeyaw (void)
1634 float ideal, current, move, speed;
1636 ent = PROG_TO_EDICT(pr_global_struct->self);
1637 current = ANGLEMOD(ent->v.angles[1]);
1638 ideal = ent->v.ideal_yaw;
1639 speed = ent->v.yaw_speed;
1641 if (current == ideal)
1643 move = ideal - current;
1644 if (ideal > current)
1665 ent->v.angles[1] = ANGLEMOD (current + move);
1673 void PF_changepitch (void)
1676 float ideal, current, move, speed;
1679 ent = G_EDICT(OFS_PARM0);
1680 current = ANGLEMOD( ent->v.angles[0] );
1681 if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
1682 ideal = val->_float;
1685 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1688 if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
1689 speed = val->_float;
1692 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1696 if (current == ideal)
1698 move = ideal - current;
1699 if (ideal > current)
1720 ent->v.angles[0] = ANGLEMOD (current + move);
1724 ===============================================================================
1728 ===============================================================================
1731 #define MSG_BROADCAST 0 // unreliable to all
1732 #define MSG_ONE 1 // reliable to one (msg_entity)
1733 #define MSG_ALL 2 // reliable to all
1734 #define MSG_INIT 3 // write to the init string
1736 sizebuf_t *WriteDest (void)
1742 dest = G_FLOAT(OFS_PARM0);
1746 return &sv.datagram;
1749 ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
1750 entnum = NUM_FOR_EDICT(ent);
1751 if (entnum < 1 || entnum > svs.maxclients)
1752 PR_RunError ("WriteDest: not a client");
1753 return &svs.clients[entnum-1].message;
1756 return &sv.reliable_datagram;
1762 PR_RunError ("WriteDest: bad destination");
1769 void PF_WriteByte (void)
1771 MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
1774 void PF_WriteChar (void)
1776 MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
1779 void PF_WriteShort (void)
1781 MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
1784 void PF_WriteLong (void)
1786 MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
1789 void PF_WriteAngle (void)
1791 MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
1794 void PF_WriteCoord (void)
1796 MSG_WriteFloatCoord (WriteDest(), G_FLOAT(OFS_PARM1));
1799 void PF_WriteString (void)
1801 MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
1805 void PF_WriteEntity (void)
1807 MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
1810 //=============================================================================
1812 int SV_ModelIndex (char *name);
1814 void PF_makestatic (void)
1819 ent = G_EDICT(OFS_PARM0);
1822 if (ent->v.modelindex >= 256 || ent->v.frame >= 256)
1827 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1828 MSG_WriteShort (&sv.signon, ent->v.modelindex);
1829 MSG_WriteShort (&sv.signon, ent->v.frame);
1833 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1834 MSG_WriteByte (&sv.signon, ent->v.modelindex);
1835 MSG_WriteByte (&sv.signon, ent->v.frame);
1838 MSG_WriteByte (&sv.signon, ent->v.colormap);
1839 MSG_WriteByte (&sv.signon, ent->v.skin);
1840 for (i=0 ; i<3 ; i++)
1842 MSG_WriteFloatCoord(&sv.signon, ent->v.origin[i]);
1843 MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
1846 // throw the entity away now
1850 //=============================================================================
1857 void PF_setspawnparms (void)
1863 ent = G_EDICT(OFS_PARM0);
1864 i = NUM_FOR_EDICT(ent);
1865 if (i < 1 || i > svs.maxclients)
1866 PR_RunError ("Entity is not a client");
1868 // copy spawn parms out of the client_t
1869 client = svs.clients + (i-1);
1871 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1872 (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
1880 void PF_changelevel (void)
1884 // make sure we don't issue two changelevels
1885 if (svs.changelevel_issued)
1887 svs.changelevel_issued = true;
1889 s = G_STRING(OFS_PARM0);
1890 Cbuf_AddText (va("changelevel %s\n",s));
1895 G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
1900 G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
1905 G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
1912 Returns a vector of length < 1
1917 void PF_randomvec (void)
1922 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1923 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1924 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1926 while (DotProduct(temp, temp) >= 1);
1927 VectorCopy (temp, G_VECTOR(OFS_RETURN));
1930 void SV_LightPoint (vec3_t color, vec3_t p);
1935 Returns a color vector indicating the lighting at the requested point.
1937 (Internal Operation note: actually measures the light beneath the point, just like
1938 the model lighting on the client)
1943 void PF_GetLight (void)
1947 p = G_VECTOR(OFS_PARM0);
1948 SV_LightPoint (color, p);
1949 VectorCopy (color, G_VECTOR(OFS_RETURN));
1952 #define MAX_QC_CVARS 128
1953 cvar_t qc_cvar[MAX_QC_CVARS];
1956 void PF_registercvar (void)
1960 name = G_STRING(OFS_PARM1);
1961 value = G_STRING(OFS_PARM2);
1962 G_FLOAT(OFS_RETURN) = 0;
1963 // first check to see if it has already been defined
1964 if (Cvar_FindVar (name))
1967 // check for overlap with a command
1968 if (Cmd_Exists (name))
1970 Con_Printf ("PF_registercvar: %s is a command\n", name);
1974 if (currentqc_cvar >= MAX_QC_CVARS)
1975 PR_RunError ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
1977 // copy the name and value
1978 variable = &qc_cvar[currentqc_cvar++];
1979 variable->name = Z_Malloc (strlen(name)+1);
1980 strcpy (variable->name, name);
1981 variable->string = Z_Malloc (strlen(value)+1);
1982 strcpy (variable->string, value);
1983 variable->value = atof (value);
1985 // link the variable in
1986 variable->next = cvar_vars;
1987 cvar_vars = variable;
1988 G_FLOAT(OFS_RETURN) = 1; // success
1995 returns the minimum of two supplied floats
2002 // LordHavoc: 3+ argument enhancement suggested by FrikaC
2004 G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2005 else if (pr_argc >= 3)
2008 float f = G_FLOAT(OFS_PARM0);
2009 for (i = 1;i < pr_argc;i++)
2010 if (G_FLOAT((OFS_PARM0+i*3)) < f)
2011 f = G_FLOAT((OFS_PARM0+i*3));
2012 G_FLOAT(OFS_RETURN) = f;
2015 PR_RunError("min: must supply at least 2 floats\n");
2022 returns the maximum of two supplied floats
2029 // LordHavoc: 3+ argument enhancement suggested by FrikaC
2031 G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2032 else if (pr_argc >= 3)
2035 float f = G_FLOAT(OFS_PARM0);
2036 for (i = 1;i < pr_argc;i++)
2037 if (G_FLOAT((OFS_PARM0+i*3)) > f)
2038 f = G_FLOAT((OFS_PARM0+i*3));
2039 G_FLOAT(OFS_RETURN) = f;
2042 PR_RunError("max: must supply at least 2 floats\n");
2049 returns number bounded by supplied range
2051 min(min, value, max)
2054 void PF_bound (void)
2056 G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
2063 returns a raised to power b
2070 G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2077 copies data from one entity to another
2079 copyentity(src, dst)
2082 void PF_copyentity (void)
2085 in = G_EDICT(OFS_PARM0);
2086 out = G_EDICT(OFS_PARM1);
2087 memcpy(out, in, pr_edict_size);
2094 sets the color of a client and broadcasts the update to all connected clients
2096 setcolor(clientent, value)
2099 void PF_setcolor (void)
2104 entnum = G_EDICTNUM(OFS_PARM0);
2105 i = G_FLOAT(OFS_PARM1);
2107 if (entnum < 1 || entnum > svs.maxclients)
2109 Con_Printf ("tried to setcolor a non-client\n");
2113 client = &svs.clients[entnum-1];
2115 client->edict->v.team = (i & 15) + 1;
2117 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
2118 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
2119 MSG_WriteByte (&sv.reliable_datagram, i);
2126 effect(origin, modelname, startframe, framecount, framerate)
2129 void PF_effect (void)
2132 s = G_STRING(OFS_PARM1);
2134 PR_RunError("effect: no model specified\n");
2136 SV_StartEffect(G_VECTOR(OFS_PARM0), SV_ModelIndex(s), G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
2139 void PF_te_blood (void)
2141 if (G_FLOAT(OFS_PARM2) < 1)
2143 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2144 MSG_WriteByte(&sv.datagram, TE_BLOOD);
2146 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2147 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2148 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2150 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2151 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2152 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2154 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2157 void PF_te_bloodshower (void)
2159 if (G_FLOAT(OFS_PARM3) < 1)
2161 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2162 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
2164 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2165 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2166 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2168 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2169 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2170 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2172 MSG_WriteFloatCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
2174 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2177 void PF_te_explosionrgb (void)
2179 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2180 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
2182 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2183 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2184 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2186 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
2187 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
2188 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
2191 void PF_te_particlecube (void)
2193 if (G_FLOAT(OFS_PARM3) < 1)
2195 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2196 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
2198 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2199 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2200 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2202 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2203 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2204 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2206 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2207 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2208 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2210 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2212 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2213 // gravity true/false
2214 MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
2216 MSG_WriteFloatCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
2219 void PF_te_particlerain (void)
2221 if (G_FLOAT(OFS_PARM3) < 1)
2223 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2224 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
2226 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2227 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2228 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2230 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2231 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2232 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2234 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2235 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2236 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2238 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2240 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2243 void PF_te_particlesnow (void)
2245 if (G_FLOAT(OFS_PARM3) < 1)
2247 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2248 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
2250 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2251 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2252 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2254 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2255 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2256 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2258 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2259 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2260 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2262 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2264 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2267 void PF_te_spark (void)
2269 if (G_FLOAT(OFS_PARM2) < 1)
2271 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2272 MSG_WriteByte(&sv.datagram, TE_SPARK);
2274 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2275 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2276 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2278 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2279 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2280 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2282 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2285 void PF_te_gunshotquad (void)
2287 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2288 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
2290 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2291 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2292 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2295 void PF_te_spikequad (void)
2297 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2298 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
2300 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2301 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2302 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2305 void PF_te_superspikequad (void)
2307 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2308 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
2310 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2311 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2312 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2315 void PF_te_explosionquad (void)
2317 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2318 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2320 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2321 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2322 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2325 void PF_te_smallflash (void)
2327 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2328 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2330 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2331 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2332 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2335 void PF_te_customflash (void)
2337 if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2339 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2340 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2342 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2343 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2344 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2346 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2348 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255));
2350 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
2351 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
2352 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
2355 void PF_te_gunshot (void)
2357 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2358 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2360 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2361 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2362 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2365 void PF_te_spike (void)
2367 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2368 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2370 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2371 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2372 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2375 void PF_te_superspike (void)
2377 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2378 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2380 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2381 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2382 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2385 void PF_te_explosion (void)
2387 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2388 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2390 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2391 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2392 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2395 void PF_te_tarexplosion (void)
2397 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2398 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2400 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2401 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2402 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2405 void PF_te_wizspike (void)
2407 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2408 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2410 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2411 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2412 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2415 void PF_te_knightspike (void)
2417 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2418 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2420 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2421 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2422 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2425 void PF_te_lavasplash (void)
2427 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2428 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2430 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2431 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2432 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2435 void PF_te_teleport (void)
2437 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2438 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2440 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2441 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2442 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2445 void PF_te_explosion2 (void)
2447 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2448 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2450 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2451 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2452 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2454 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
2457 void PF_te_lightning1 (void)
2459 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2460 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2462 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2464 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2465 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2466 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2468 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2469 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2470 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2473 void PF_te_lightning2 (void)
2475 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2476 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2478 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2480 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2481 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2482 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2484 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2485 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2486 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2489 void PF_te_lightning3 (void)
2491 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2492 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2494 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2496 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2497 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2498 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2500 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2501 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2502 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2505 void PF_te_beam (void)
2507 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2508 MSG_WriteByte(&sv.datagram, TE_BEAM);
2510 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2512 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2513 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2514 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2516 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2517 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2518 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2521 void PF_Fixme (void)
2523 PR_RunError ("unimplemented builtin"); // LordHavoc: was misspelled (bulitin)
2528 builtin_t pr_builtin[] =
2531 PF_makevectors, // void(entity e) makevectors = #1;
2532 PF_setorigin, // void(entity e, vector o) setorigin = #2;
2533 PF_setmodel, // void(entity e, string m) setmodel = #3;
2534 PF_setsize, // void(entity e, vector min, vector max) setsize = #4;
2535 PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5;
2536 PF_break, // void() break = #6;
2537 PF_random, // float() random = #7;
2538 PF_sound, // void(entity e, float chan, string samp) sound = #8;
2539 PF_normalize, // vector(vector v) normalize = #9;
2540 PF_error, // void(string e) error = #10;
2541 PF_objerror, // void(string e) objerror = #11;
2542 PF_vlen, // float(vector v) vlen = #12;
2543 PF_vectoyaw, // float(vector v) vectoyaw = #13;
2544 PF_Spawn, // entity() spawn = #14;
2545 PF_Remove, // void(entity e) remove = #15;
2546 PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16;
2547 PF_checkclient, // entity() clientlist = #17;
2548 PF_Find, // entity(entity start, .string fld, string match) find = #18;
2549 PF_precache_sound, // void(string s) precache_sound = #19;
2550 PF_precache_model, // void(string s) precache_model = #20;
2551 PF_stuffcmd, // void(entity client, string s)stuffcmd = #21;
2552 PF_findradius, // entity(vector org, float rad) findradius = #22;
2553 PF_bprint, // void(string s) bprint = #23;
2554 PF_sprint, // void(entity client, string s) sprint = #24;
2555 PF_dprint, // void(string s) dprint = #25;
2556 PF_ftos, // void(string s) ftos = #26;
2557 PF_vtos, // void(string s) vtos = #27;
2561 PF_eprint, // void(entity e) debug print an entire entity
2562 PF_walkmove, // float(float yaw, float dist) walkmove
2563 PF_Fixme, // float(float yaw, float dist) walkmove
2613 PF_precache_sound, // precache_sound2 is different only for qcc
2618 PF_Fixme, // #79 LordHavoc: dunno who owns 79-89, so these are just padding
2630 PF_tracebox, // #90 LordHavoc builtin range (9x)
2631 PF_randomvec, // #91
2633 PF_registercvar, // #93
2638 PF_FindFloat, // #98
2639 PF_checkextension, // #99
2640 #define a PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme,
2641 #define aa a a a a a a a a a a
2645 PF_copyentity, // #400 LordHavoc: builtin range (4xx)
2646 PF_setcolor, // #401
2647 PF_findchain, // #402
2648 PF_findchainfloat, // #403
2650 PF_te_blood, // #405
2651 PF_te_bloodshower, // #406
2652 PF_te_explosionrgb, // #407
2653 PF_te_particlecube, // #408
2654 PF_te_particlerain, // #409
2655 PF_te_particlesnow, // #410
2656 PF_te_spark, // #411
2657 PF_te_gunshotquad, // #412
2658 PF_te_spikequad, // #413
2659 PF_te_superspikequad, // #414
2660 PF_te_explosionquad, // #415
2661 PF_te_smallflash, // #416
2662 PF_te_customflash, // #417
2663 PF_te_gunshot, // #418
2664 PF_te_spike, // #419
2665 PF_te_superspike, // #420
2666 PF_te_explosion, // #421
2667 PF_te_tarexplosion, // #422
2668 PF_te_wizspike, // #423
2669 PF_te_knightspike, // #424
2670 PF_te_lavasplash, // #425
2671 PF_te_teleport, // #426
2672 PF_te_explosion2, // #427
2673 PF_te_lightning1, // #428
2674 PF_te_lightning2, // #429
2675 PF_te_lightning3, // #430
2677 PF_vectorvectors, // #432
2680 builtin_t *pr_builtins = pr_builtin;
2681 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);