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 \
79 DP_QC_FINDCHAINFLOAT \
90 qboolean checkextension(char *name)
95 for (e = ENGINE_EXTENSIONS;*e;e++)
102 while (*e && *e != ' ')
104 if (e - start == len)
105 if (!strncasecmp(e, name, len))
115 returns true if the extension is supported by the server
117 checkextension(extensionname)
120 void PF_checkextension (void)
122 G_FLOAT(OFS_RETURN) = checkextension(G_STRING(OFS_PARM0));
129 This is a TERMINAL error, which will kill off the entire server.
141 Con_Printf ("======SERVER ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
142 ed = PROG_TO_EDICT(pr_global_struct->self);
145 Host_Error ("Program error");
152 Dumps out self, then an error message. The program is aborted and self is
153 removed, but the level can continue.
158 void PF_objerror (void)
164 Con_Printf ("======OBJECT ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
165 ed = PROG_TO_EDICT(pr_global_struct->self);
169 // LordHavoc: bug fix - no longer kills server
170 // Host_Error ("Program error");
179 Writes new values for v_forward, v_up, and v_right based on angles
183 void PF_makevectors (void)
185 AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
192 Writes new values for v_forward, v_up, and v_right based on the given forward vector
193 vectorvectors(vector, vector)
196 void PF_vectorvectors (void)
198 VectorNormalize2(G_VECTOR(OFS_PARM0), pr_global_struct->v_forward);
199 VectorVectors(pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
206 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.
208 setorigin (entity, origin)
211 void PF_setorigin (void)
216 e = G_EDICT(OFS_PARM0);
217 org = G_VECTOR(OFS_PARM1);
218 VectorCopy (org, e->v.origin);
219 SV_LinkEdict (e, false);
223 void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
229 float xvector[2], yvector[2];
231 vec3_t base, transformed;
236 for (i=0 ; i<3 ; i++)
238 PR_RunError ("backwards mins/maxs");
241 rotate = false; // FIXME: implement rotation properly again
245 VectorCopy (min, rmin);
246 VectorCopy (max, rmax);
250 // find min / max for rotations
251 angles = e->v.angles;
253 a = angles[1]/180 * M_PI;
257 yvector[0] = -sin(a);
260 VectorCopy (min, bounds[0]);
261 VectorCopy (max, bounds[1]);
263 rmin[0] = rmin[1] = rmin[2] = 9999;
264 rmax[0] = rmax[1] = rmax[2] = -9999;
266 for (i=0 ; i<= 1 ; i++)
268 base[0] = bounds[i][0];
269 for (j=0 ; j<= 1 ; j++)
271 base[1] = bounds[j][1];
272 for (k=0 ; k<= 1 ; k++)
274 base[2] = bounds[k][2];
276 // transform the point
277 transformed[0] = xvector[0]*base[0] + yvector[0]*base[1];
278 transformed[1] = xvector[1]*base[0] + yvector[1]*base[1];
279 transformed[2] = base[2];
281 for (l=0 ; l<3 ; l++)
283 if (transformed[l] < rmin[l])
284 rmin[l] = transformed[l];
285 if (transformed[l] > rmax[l])
286 rmax[l] = transformed[l];
293 // set derived values
294 VectorCopy (rmin, e->v.mins);
295 VectorCopy (rmax, e->v.maxs);
296 VectorSubtract (max, min, e->v.size);
299 // set derived values
300 VectorCopy (min, e->v.mins);
301 VectorCopy (max, e->v.maxs);
302 VectorSubtract (max, min, e->v.size);
304 SV_LinkEdict (e, false);
311 the size box is rotated by the current angle
312 LordHavoc: no it isn't...
314 setsize (entity, minvector, maxvector)
317 void PF_setsize (void)
322 e = G_EDICT(OFS_PARM0);
323 min = G_VECTOR(OFS_PARM1);
324 max = G_VECTOR(OFS_PARM2);
325 SetMinMaxSize (e, min, max, false);
333 setmodel(entity, model)
336 void PF_setmodel (void)
343 e = G_EDICT(OFS_PARM0);
344 m = G_STRING(OFS_PARM1);
346 // check to see if model was properly precached
347 for (i=0, check = sv.model_precache ; *check ; i++, check++)
348 if (!strcmp(*check, m))
352 PR_RunError ("no precache: %s\n", m);
355 e->v.model = m - pr_strings;
356 e->v.modelindex = i; //SV_ModelIndex (m);
358 mod = sv.models[ (int)e->v.modelindex]; // Mod_ForName (m, true);
362 { // LordHavoc: corrected model bounding box, but for compatibility that means I have to break it here
364 if (mod->type == ALIASTYPE_MDL)
366 min[0] = min[1] = min[2] = -16;
367 max[0] = max[1] = max[2] = 16;
368 SetMinMaxSize (e, min, max, true);
371 SetMinMaxSize (e, mod->mins, mod->maxs, true);
374 SetMinMaxSize (e, mod->mins, mod->maxs, true);
376 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
383 broadcast print to everyone on server
388 void PF_bprint (void)
393 SV_BroadcastPrintf ("%s", s);
400 single print to a specific client
402 sprint(clientent, value)
405 void PF_sprint (void)
411 entnum = G_EDICTNUM(OFS_PARM0);
414 if (entnum < 1 || entnum > svs.maxclients)
416 Con_Printf ("tried to sprint to a non-client\n");
420 client = &svs.clients[entnum-1];
422 MSG_WriteChar (&client->message,svc_print);
423 MSG_WriteString (&client->message, s );
431 single print to a specific client
433 centerprint(clientent, value)
436 void PF_centerprint (void)
442 entnum = G_EDICTNUM(OFS_PARM0);
445 if (entnum < 1 || entnum > svs.maxclients)
447 Con_Printf ("tried to sprint to a non-client\n");
451 client = &svs.clients[entnum-1];
453 MSG_WriteChar (&client->message,svc_centerprint);
454 MSG_WriteString (&client->message, s );
462 vector normalize(vector)
465 void PF_normalize (void)
471 value1 = G_VECTOR(OFS_PARM0);
473 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
477 newvalue[0] = newvalue[1] = newvalue[2] = 0;
481 newvalue[0] = value1[0] * new;
482 newvalue[1] = value1[1] * new;
483 newvalue[2] = value1[2] * new;
486 VectorCopy (newvalue, G_VECTOR(OFS_RETURN));
501 value1 = G_VECTOR(OFS_PARM0);
503 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
506 G_FLOAT(OFS_RETURN) = new;
513 float vectoyaw(vector)
516 void PF_vectoyaw (void)
521 value1 = G_VECTOR(OFS_PARM0);
523 if (value1[1] == 0 && value1[0] == 0)
527 yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
532 G_FLOAT(OFS_RETURN) = yaw;
540 vector vectoangles(vector)
543 void PF_vectoangles (void)
549 value1 = G_VECTOR(OFS_PARM0);
551 if (value1[1] == 0 && value1[0] == 0)
561 // LordHavoc: optimized a bit
564 yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
568 else if (value1[1] > 0)
573 forward = sqrt(value1[0]*value1[0] + value1[1]*value1[1]);
574 pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
579 G_FLOAT(OFS_RETURN+0) = pitch;
580 G_FLOAT(OFS_RETURN+1) = yaw;
581 G_FLOAT(OFS_RETURN+2) = 0;
588 Returns a number from 0<= num < 1
593 void PF_random (void)
597 num = (rand ()&0x7fff) / ((float)0x7fff);
599 G_FLOAT(OFS_RETURN) = num;
606 particle(origin, color, count)
609 void PF_particle (void)
615 org = G_VECTOR(OFS_PARM0);
616 dir = G_VECTOR(OFS_PARM1);
617 color = G_FLOAT(OFS_PARM2);
618 count = G_FLOAT(OFS_PARM3);
619 SV_StartParticle (org, dir, color, count);
629 void PF_ambientsound (void)
634 float vol, attenuation;
637 pos = G_VECTOR (OFS_PARM0);
638 samp = G_STRING(OFS_PARM1);
639 vol = G_FLOAT(OFS_PARM2);
640 attenuation = G_FLOAT(OFS_PARM3);
642 // check to see if samp was properly precached
643 for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++)
644 if (!strcmp(*check,samp))
649 Con_Printf ("no precache: %s\n", samp);
653 // add an svc_spawnambient command to the level signon packet
655 MSG_WriteByte (&sv.signon,svc_spawnstaticsound);
656 for (i=0 ; i<3 ; i++)
657 MSG_WriteFloatCoord(&sv.signon, pos[i]);
659 MSG_WriteByte (&sv.signon, soundnum);
661 MSG_WriteByte (&sv.signon, vol*255);
662 MSG_WriteByte (&sv.signon, attenuation*64);
670 Each entity can have eight independant sound sources, like voice,
673 Channel 0 is an auto-allocate channel, the others override anything
674 already running on that entity/channel pair.
676 An attenuation of 0 will play full volume everywhere in the level.
677 Larger attenuations will drop off.
689 entity = G_EDICT(OFS_PARM0);
690 channel = G_FLOAT(OFS_PARM1);
691 sample = G_STRING(OFS_PARM2);
692 volume = G_FLOAT(OFS_PARM3) * 255;
693 attenuation = G_FLOAT(OFS_PARM4);
695 if (volume < 0 || volume > 255)
696 Host_Error ("SV_StartSound: volume = %i", volume);
698 if (attenuation < 0 || attenuation > 4)
699 Host_Error ("SV_StartSound: attenuation = %f", attenuation);
701 if (channel < 0 || channel > 7)
702 Host_Error ("SV_StartSound: channel = %i", channel);
704 SV_StartSound (entity, channel, sample, volume, attenuation);
716 // Con_Printf ("break statement\n");
717 // *(int *)-4 = 0; // dump to debugger
718 PR_RunError ("break statement");
725 Used for use tracing and shot targeting
726 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
727 if the tryents flag is set.
729 traceline (vector1, vector2, tryents)
732 void PF_traceline (void)
739 v1 = G_VECTOR(OFS_PARM0);
740 v2 = G_VECTOR(OFS_PARM1);
741 nomonsters = G_FLOAT(OFS_PARM2);
742 ent = G_EDICT(OFS_PARM3);
744 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters, ent);
746 pr_global_struct->trace_allsolid = trace.allsolid;
747 pr_global_struct->trace_startsolid = trace.startsolid;
748 pr_global_struct->trace_fraction = trace.fraction;
749 pr_global_struct->trace_inwater = trace.inwater;
750 pr_global_struct->trace_inopen = trace.inopen;
751 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
752 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
753 pr_global_struct->trace_plane_dist = trace.plane.dist;
755 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
757 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
765 Used for use tracing and shot targeting
766 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
767 if the tryents flag is set.
769 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
772 // LordHavoc: added this for my own use, VERY useful, similar to traceline
773 void PF_tracebox (void)
775 float *v1, *v2, *m1, *m2;
780 v1 = G_VECTOR(OFS_PARM0);
781 m1 = G_VECTOR(OFS_PARM1);
782 m2 = G_VECTOR(OFS_PARM2);
783 v2 = G_VECTOR(OFS_PARM3);
784 nomonsters = G_FLOAT(OFS_PARM4);
785 ent = G_EDICT(OFS_PARM5);
787 trace = SV_Move (v1, m1, m2, v2, nomonsters, ent);
789 pr_global_struct->trace_allsolid = trace.allsolid;
790 pr_global_struct->trace_startsolid = trace.startsolid;
791 pr_global_struct->trace_fraction = trace.fraction;
792 pr_global_struct->trace_inwater = trace.inwater;
793 pr_global_struct->trace_inopen = trace.inopen;
794 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
795 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
796 pr_global_struct->trace_plane_dist = trace.plane.dist;
798 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
800 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
803 extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore);
804 void PF_TraceToss (void)
810 ent = G_EDICT(OFS_PARM0);
811 ignore = G_EDICT(OFS_PARM1);
813 trace = SV_Trace_Toss (ent, ignore);
815 pr_global_struct->trace_allsolid = trace.allsolid;
816 pr_global_struct->trace_startsolid = trace.startsolid;
817 pr_global_struct->trace_fraction = trace.fraction;
818 pr_global_struct->trace_inwater = trace.inwater;
819 pr_global_struct->trace_inopen = trace.inopen;
820 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
821 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
822 pr_global_struct->trace_plane_dist = trace.plane.dist;
824 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
826 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
834 Returns true if the given entity can move to the given position from it's
835 current position by walking or rolling.
837 scalar checkpos (entity, vector)
840 void PF_checkpos (void)
844 //============================================================================
846 byte checkpvs[MAX_MAP_LEAFS/8];
848 int PF_newcheckclient (int check)
856 // cycle to the next one
860 if (check > svs.maxclients)
861 check = svs.maxclients;
863 if (check == svs.maxclients)
870 if (i == svs.maxclients+1)
876 break; // didn't find anything else
880 if (ent->v.health <= 0)
882 if ((int)ent->v.flags & FL_NOTARGET)
885 // anything that is a client, or has a client as an enemy
889 // get the PVS for the entity
890 VectorAdd (ent->v.origin, ent->v.view_ofs, org);
891 leaf = Mod_PointInLeaf (org, sv.worldmodel);
892 pvs = Mod_LeafPVS (leaf, sv.worldmodel);
893 memcpy (checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 );
902 Returns a client (or object that has a client enemy) that would be a
905 If there is more than one valid option, they are cycled each frame
907 If (self.origin + self.viewofs) is not in the PVS of the current target,
908 it is not returned at all.
913 int c_invis, c_notvis;
914 void PF_checkclient (void)
921 // find a new check if on a new frame
922 if (sv.time - sv.lastchecktime >= 0.1)
924 sv.lastcheck = PF_newcheckclient (sv.lastcheck);
925 sv.lastchecktime = sv.time;
928 // return check if it might be visible
929 ent = EDICT_NUM(sv.lastcheck);
930 if (ent->free || ent->v.health <= 0)
932 RETURN_EDICT(sv.edicts);
936 // if current entity can't possibly see the check entity, return 0
937 self = PROG_TO_EDICT(pr_global_struct->self);
938 VectorAdd (self->v.origin, self->v.view_ofs, view);
939 leaf = Mod_PointInLeaf (view, sv.worldmodel);
940 l = (leaf - sv.worldmodel->leafs) - 1;
941 if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
944 RETURN_EDICT(sv.edicts);
948 // might be able to see it
953 //============================================================================
960 Sends text over to the client's execution buffer
962 stuffcmd (clientent, value)
965 void PF_stuffcmd (void)
971 entnum = G_EDICTNUM(OFS_PARM0);
972 if (entnum < 1 || entnum > svs.maxclients)
973 PR_RunError ("Parm 0 not a client");
974 str = G_STRING(OFS_PARM1);
977 host_client = &svs.clients[entnum-1];
978 Host_ClientCommands ("%s", str);
986 Sends text over to the client's execution buffer
991 void PF_localcmd (void)
995 str = G_STRING(OFS_PARM0);
1010 str = G_STRING(OFS_PARM0);
1012 G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str);
1022 void PF_cvar_set (void)
1026 var = G_STRING(OFS_PARM0);
1027 val = G_STRING(OFS_PARM1);
1029 Cvar_Set (var, val);
1036 Returns a chain of entities that have origins within a spherical area
1038 findradius (origin, radius)
1041 void PF_findradius (void)
1043 edict_t *ent, *chain;
1049 chain = (edict_t *)sv.edicts;
1051 org = G_VECTOR(OFS_PARM0);
1052 rad = G_FLOAT(OFS_PARM1);
1054 ent = NEXT_EDICT(sv.edicts);
1055 for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
1059 if (ent->v.solid == SOLID_NOT)
1061 for (j=0 ; j<3 ; j++)
1062 eorg[j] = org[j] - (ent->v.origin[j] + (ent->v.mins[j] + ent->v.maxs[j])*0.5);
1063 if (Length(eorg) > rad)
1066 ent->v.chain = EDICT_TO_PROG(chain);
1070 RETURN_EDICT(chain);
1079 void PF_dprint (void)
1081 Con_DPrintf ("%s",PF_VarString(0));
1084 char pr_string_temp[128];
1089 v = G_FLOAT(OFS_PARM0);
1091 // LordHavoc: ftos improvement
1092 sprintf (pr_string_temp, "%g", v);
1095 sprintf (pr_string_temp, "%d",(int)v);
1097 sprintf (pr_string_temp, "%5.1f",v);
1099 G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
1105 v = G_FLOAT(OFS_PARM0);
1106 G_FLOAT(OFS_RETURN) = fabs(v);
1111 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]);
1112 G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
1117 sprintf (pr_string_temp, "entity %i", G_EDICTNUM(OFS_PARM0));
1118 G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
1121 void PF_Spawn (void)
1128 void PF_Remove (void)
1132 ed = G_EDICT(OFS_PARM0);
1137 // entity (entity start, .string field, string match) find = #5;
1145 e = G_EDICTNUM(OFS_PARM0);
1146 f = G_INT(OFS_PARM1);
1147 s = G_STRING(OFS_PARM2);
1150 RETURN_EDICT(sv.edicts);
1154 for (e++ ; e < sv.num_edicts ; e++)
1169 RETURN_EDICT(sv.edicts);
1172 // LordHavoc: added this for searching float, int, and entity reference fields
1173 void PF_FindFloat (void)
1180 e = G_EDICTNUM(OFS_PARM0);
1181 f = G_INT(OFS_PARM1);
1182 s = G_FLOAT(OFS_PARM2);
1184 for (e++ ; e < sv.num_edicts ; e++)
1189 if (E_FLOAT(ed,f) == s)
1196 RETURN_EDICT(sv.edicts);
1199 // chained search for strings in entity fields
1200 // entity(.string field, string match) findchain = #402;
1201 void PF_findchain (void)
1206 edict_t *ent, *chain;
1208 chain = (edict_t *)sv.edicts;
1210 f = G_INT(OFS_PARM0);
1211 s = G_STRING(OFS_PARM1);
1214 RETURN_EDICT(sv.edicts);
1218 ent = NEXT_EDICT(sv.edicts);
1219 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1223 t = E_STRING(ent,f);
1229 ent->v.chain = EDICT_TO_PROG(chain);
1233 RETURN_EDICT(chain);
1236 // LordHavoc: chained search for float, int, and entity reference fields
1237 // entity(.string field, float match) findchainfloat = #403;
1238 void PF_findchainfloat (void)
1243 edict_t *ent, *chain;
1245 chain = (edict_t *)sv.edicts;
1247 f = G_INT(OFS_PARM0);
1248 s = G_FLOAT(OFS_PARM1);
1250 ent = NEXT_EDICT(sv.edicts);
1251 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1255 if (E_FLOAT(ent,f) != s)
1258 ent->v.chain = EDICT_TO_PROG(chain);
1262 RETURN_EDICT(chain);
1265 void PR_CheckEmptyString (char *s)
1268 PR_RunError ("Bad string");
1271 void PF_precache_file (void)
1272 { // precache_file is only used to copy files with qcc, it does nothing
1273 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1276 void PF_precache_sound (void)
1281 if (sv.state != ss_loading)
1282 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1284 s = G_STRING(OFS_PARM0);
1285 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1286 PR_CheckEmptyString (s);
1288 for (i=0 ; i<MAX_SOUNDS ; i++)
1290 if (!sv.sound_precache[i])
1292 sv.sound_precache[i] = s;
1295 if (!strcmp(sv.sound_precache[i], s))
1298 PR_RunError ("PF_precache_sound: overflow");
1301 extern qboolean hlbsp;
1302 void PF_precache_model (void)
1307 if (sv.state != ss_loading)
1308 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1310 s = G_STRING(OFS_PARM0);
1311 if (hlbsp && ((!s) || (!s[0])))
1313 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1314 PR_CheckEmptyString (s);
1316 for (i=0 ; i<MAX_MODELS ; i++)
1318 if (!sv.model_precache[i])
1320 sv.model_precache[i] = s;
1321 sv.models[i] = Mod_ForName (s, true);
1324 if (!strcmp(sv.model_precache[i], s))
1327 PR_RunError ("PF_precache_model: overflow");
1331 void PF_coredump (void)
1336 void PF_traceon (void)
1341 void PF_traceoff (void)
1346 void PF_eprint (void)
1348 ED_PrintNum (G_EDICTNUM(OFS_PARM0));
1355 float(float yaw, float dist) walkmove
1358 void PF_walkmove (void)
1366 ent = PROG_TO_EDICT(pr_global_struct->self);
1367 yaw = G_FLOAT(OFS_PARM0);
1368 dist = G_FLOAT(OFS_PARM1);
1370 if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1372 G_FLOAT(OFS_RETURN) = 0;
1376 yaw = yaw*M_PI*2 / 360;
1378 move[0] = cos(yaw)*dist;
1379 move[1] = sin(yaw)*dist;
1382 // save program state, because SV_movestep may call other progs
1383 oldf = pr_xfunction;
1384 oldself = pr_global_struct->self;
1386 G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
1389 // restore program state
1390 pr_xfunction = oldf;
1391 pr_global_struct->self = oldself;
1401 void PF_droptofloor (void)
1407 ent = PROG_TO_EDICT(pr_global_struct->self);
1409 VectorCopy (ent->v.origin, end);
1412 trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent);
1414 if (trace.fraction == 1 || trace.allsolid)
1415 G_FLOAT(OFS_RETURN) = 0;
1418 VectorCopy (trace.endpos, ent->v.origin);
1419 SV_LinkEdict (ent, false);
1420 ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
1421 ent->v.groundentity = EDICT_TO_PROG(trace.ent);
1422 G_FLOAT(OFS_RETURN) = 1;
1430 void(float style, string value) lightstyle
1433 void PF_lightstyle (void)
1440 style = G_FLOAT(OFS_PARM0);
1441 val = G_STRING(OFS_PARM1);
1443 // change the string in sv
1444 sv.lightstyles[style] = val;
1446 // send message to all clients on this server
1447 if (sv.state != ss_active)
1450 for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
1451 if (client->active || client->spawned)
1453 MSG_WriteChar (&client->message, svc_lightstyle);
1454 MSG_WriteChar (&client->message,style);
1455 MSG_WriteString (&client->message, val);
1462 f = G_FLOAT(OFS_PARM0);
1464 G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1466 G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1468 void PF_floor (void)
1470 G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
1474 G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
1483 void PF_checkbottom (void)
1485 G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0));
1493 void PF_pointcontents (void)
1495 G_FLOAT(OFS_RETURN) = SV_PointContents (G_VECTOR(OFS_PARM0));
1502 entity nextent(entity)
1505 void PF_nextent (void)
1510 i = G_EDICTNUM(OFS_PARM0);
1514 if (i == sv.num_edicts)
1516 RETURN_EDICT(sv.edicts);
1532 Pick a vector for the player to shoot along
1533 vector aim(entity, missilespeed)
1536 cvar_t sv_aim = {"sv_aim", "0.93"};
1539 edict_t *ent, *check, *bestent;
1540 vec3_t start, dir, end, bestdir;
1543 float dist, bestdist;
1546 ent = G_EDICT(OFS_PARM0);
1547 speed = G_FLOAT(OFS_PARM1);
1549 VectorCopy (ent->v.origin, start);
1552 // try sending a trace straight
1553 VectorCopy (pr_global_struct->v_forward, dir);
1554 VectorMA (start, 2048, dir, end);
1555 tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
1556 if (tr.ent && tr.ent->v.takedamage == DAMAGE_AIM
1557 && (!teamplay.value || ent->v.team <=0 || ent->v.team != tr.ent->v.team) )
1559 VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
1564 // try all possible entities
1565 VectorCopy (dir, bestdir);
1566 bestdist = sv_aim.value;
1569 check = NEXT_EDICT(sv.edicts);
1570 for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
1572 if (check->v.takedamage != DAMAGE_AIM)
1576 if (teamplay.value && ent->v.team > 0 && ent->v.team == check->v.team)
1577 continue; // don't aim at teammate
1578 for (j=0 ; j<3 ; j++)
1579 end[j] = check->v.origin[j]
1580 + 0.5*(check->v.mins[j] + check->v.maxs[j]);
1581 VectorSubtract (end, start, dir);
1582 VectorNormalize (dir);
1583 dist = DotProduct (dir, pr_global_struct->v_forward);
1584 if (dist < bestdist)
1585 continue; // to far to turn
1586 tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
1587 if (tr.ent == check)
1588 { // can shoot at this one
1596 VectorSubtract (bestent->v.origin, ent->v.origin, dir);
1597 dist = DotProduct (dir, pr_global_struct->v_forward);
1598 VectorScale (pr_global_struct->v_forward, dist, end);
1600 VectorNormalize (end);
1601 VectorCopy (end, G_VECTOR(OFS_RETURN));
1605 VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
1613 This was a major timewaster in progs, so it was converted to C
1616 void PF_changeyaw (void)
1619 float ideal, current, move, speed;
1621 ent = PROG_TO_EDICT(pr_global_struct->self);
1622 current = anglemod( ent->v.angles[1] );
1623 ideal = ent->v.ideal_yaw;
1624 speed = ent->v.yaw_speed;
1626 if (current == ideal)
1628 move = ideal - current;
1629 if (ideal > current)
1650 ent->v.angles[1] = anglemod (current + move);
1658 void PF_changepitch (void)
1661 float ideal, current, move, speed;
1664 ent = G_EDICT(OFS_PARM0);
1665 current = anglemod( ent->v.angles[0] );
1666 if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
1667 ideal = val->_float;
1670 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1673 if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
1674 speed = val->_float;
1677 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1681 if (current == ideal)
1683 move = ideal - current;
1684 if (ideal > current)
1705 ent->v.angles[0] = anglemod (current + move);
1709 ===============================================================================
1713 ===============================================================================
1716 #define MSG_BROADCAST 0 // unreliable to all
1717 #define MSG_ONE 1 // reliable to one (msg_entity)
1718 #define MSG_ALL 2 // reliable to all
1719 #define MSG_INIT 3 // write to the init string
1721 sizebuf_t *WriteDest (void)
1727 dest = G_FLOAT(OFS_PARM0);
1731 return &sv.datagram;
1734 ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
1735 entnum = NUM_FOR_EDICT(ent);
1736 if (entnum < 1 || entnum > svs.maxclients)
1737 PR_RunError ("WriteDest: not a client");
1738 return &svs.clients[entnum-1].message;
1741 return &sv.reliable_datagram;
1747 PR_RunError ("WriteDest: bad destination");
1754 void PF_WriteByte (void)
1756 MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
1759 void PF_WriteChar (void)
1761 MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
1764 void PF_WriteShort (void)
1766 MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
1769 void PF_WriteLong (void)
1771 MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
1774 void PF_WriteAngle (void)
1776 MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
1779 void PF_WriteCoord (void)
1781 MSG_WriteFloatCoord (WriteDest(), G_FLOAT(OFS_PARM1));
1784 void PF_WriteString (void)
1786 MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
1790 void PF_WriteEntity (void)
1792 MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
1795 //=============================================================================
1797 int SV_ModelIndex (char *name);
1799 void PF_makestatic (void)
1804 ent = G_EDICT(OFS_PARM0);
1806 i = SV_ModelIndex(pr_strings + ent->v.model);
1809 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1810 MSG_WriteShort (&sv.signon, i);
1814 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1815 MSG_WriteByte (&sv.signon, i);
1818 MSG_WriteByte (&sv.signon, ent->v.frame);
1819 MSG_WriteByte (&sv.signon, ent->v.colormap);
1820 MSG_WriteByte (&sv.signon, ent->v.skin);
1821 for (i=0 ; i<3 ; i++)
1823 MSG_WriteFloatCoord(&sv.signon, ent->v.origin[i]);
1824 MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
1827 // throw the entity away now
1831 //=============================================================================
1838 void PF_setspawnparms (void)
1844 ent = G_EDICT(OFS_PARM0);
1845 i = NUM_FOR_EDICT(ent);
1846 if (i < 1 || i > svs.maxclients)
1847 PR_RunError ("Entity is not a client");
1849 // copy spawn parms out of the client_t
1850 client = svs.clients + (i-1);
1852 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1853 (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
1861 void PF_changelevel (void)
1865 // make sure we don't issue two changelevels
1866 if (svs.changelevel_issued)
1868 svs.changelevel_issued = true;
1870 s = G_STRING(OFS_PARM0);
1871 Cbuf_AddText (va("changelevel %s\n",s));
1876 G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
1881 G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
1886 G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
1893 Returns a vector of length < 1
1898 void PF_randomvec (void)
1903 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1904 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1905 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1907 while (DotProduct(temp, temp) >= 1);
1908 VectorCopy (temp, G_VECTOR(OFS_RETURN));
1911 void SV_LightPoint (vec3_t color, vec3_t p);
1916 Returns a color vector indicating the lighting at the requested point.
1918 (Internal Operation note: actually measures the light beneath the point, just like
1919 the model lighting on the client)
1924 void PF_GetLight (void)
1928 p = G_VECTOR(OFS_PARM0);
1929 SV_LightPoint (color, p);
1930 VectorCopy (color, G_VECTOR(OFS_RETURN));
1933 #define MAX_QC_CVARS 128
1934 cvar_t qc_cvar[MAX_QC_CVARS];
1937 void PF_registercvar (void)
1941 name = G_STRING(OFS_PARM1);
1942 value = G_STRING(OFS_PARM2);
1943 G_FLOAT(OFS_RETURN) = 0;
1944 // first check to see if it has already been defined
1945 if (Cvar_FindVar (name))
1948 // check for overlap with a command
1949 if (Cmd_Exists (name))
1951 Con_Printf ("PF_registercvar: %s is a command\n", name);
1955 if (currentqc_cvar >= MAX_QC_CVARS)
1956 PR_RunError ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
1958 // copy the name and value
1959 variable = &qc_cvar[currentqc_cvar++];
1960 variable->name = Z_Malloc (strlen(name)+1);
1961 strcpy (variable->name, name);
1962 variable->string = Z_Malloc (strlen(value)+1);
1963 strcpy (variable->string, value);
1964 variable->value = atof (value);
1966 // link the variable in
1967 variable->next = cvar_vars;
1968 cvar_vars = variable;
1969 G_FLOAT(OFS_RETURN) = 1; // success
1976 returns the minimum of two supplied floats
1983 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1985 G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1986 else if (pr_argc >= 3)
1989 float f = G_FLOAT(OFS_PARM0);
1990 for (i = 1;i < pr_argc;i++)
1991 if (G_FLOAT((OFS_PARM0+i*3)) < f)
1992 f = G_FLOAT((OFS_PARM0+i*3));
1993 G_FLOAT(OFS_RETURN) = f;
1996 PR_RunError("min: must supply at least 2 floats\n");
2003 returns the maximum of two supplied floats
2010 // LordHavoc: 3+ argument enhancement suggested by FrikaC
2012 G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2013 else if (pr_argc >= 3)
2016 float f = G_FLOAT(OFS_PARM0);
2017 for (i = 1;i < pr_argc;i++)
2018 if (G_FLOAT((OFS_PARM0+i*3)) > f)
2019 f = G_FLOAT((OFS_PARM0+i*3));
2020 G_FLOAT(OFS_RETURN) = f;
2023 PR_RunError("max: must supply at least 2 floats\n");
2030 returns number bounded by supplied range
2032 min(min, value, max)
2035 void PF_bound (void)
2037 G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
2044 returns a raised to power b
2051 G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2058 copies data from one entity to another
2060 copyentity(src, dst)
2063 void PF_copyentity (void)
2066 in = G_EDICT(OFS_PARM0);
2067 out = G_EDICT(OFS_PARM1);
2068 memcpy(out, in, pr_edict_size);
2075 sets the color of a client and broadcasts the update to all connected clients
2077 setcolor(clientent, value)
2080 void PF_setcolor (void)
2085 entnum = G_EDICTNUM(OFS_PARM0);
2086 i = G_FLOAT(OFS_PARM1);
2088 if (entnum < 1 || entnum > svs.maxclients)
2090 Con_Printf ("tried to setcolor a non-client\n");
2094 client = &svs.clients[entnum-1];
2096 client->edict->v.team = (i & 15) + 1;
2098 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
2099 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
2100 MSG_WriteByte (&sv.reliable_datagram, i);
2107 effect(origin, modelname, startframe, framecount, framerate)
2110 void PF_effect (void)
2113 s = G_STRING(OFS_PARM1);
2115 PR_RunError("effect: no model specified\n");
2117 SV_StartEffect(G_VECTOR(OFS_PARM0), SV_ModelIndex(s), G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
2120 void PF_te_blood (void)
2122 if (G_FLOAT(OFS_PARM2) < 1)
2124 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2125 MSG_WriteByte(&sv.datagram, TE_BLOOD);
2127 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2128 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2129 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2131 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2132 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2133 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2135 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2138 void PF_te_bloodshower (void)
2140 if (G_FLOAT(OFS_PARM3) < 1)
2142 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2143 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
2145 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2146 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2147 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2149 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2150 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2151 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2153 MSG_WriteFloatCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
2155 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2158 void PF_te_explosionrgb (void)
2160 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2161 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
2163 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2164 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2165 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2167 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
2168 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
2169 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
2172 void PF_te_particlecube (void)
2174 if (G_FLOAT(OFS_PARM3) < 1)
2176 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2177 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
2179 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2180 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2181 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2183 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2184 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2185 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2187 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2188 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2189 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2191 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2193 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2194 // gravity true/false
2195 MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
2197 MSG_WriteFloatCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
2200 void PF_te_particlerain (void)
2202 if (G_FLOAT(OFS_PARM3) < 1)
2204 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2205 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
2207 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2208 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2209 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2211 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2212 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2213 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2215 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2216 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2217 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2219 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2221 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2224 void PF_te_particlesnow (void)
2226 if (G_FLOAT(OFS_PARM3) < 1)
2228 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2229 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
2231 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2232 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2233 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2235 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2236 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2237 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2239 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2240 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2241 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2243 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2245 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2248 void PF_te_spark (void)
2250 if (G_FLOAT(OFS_PARM2) < 1)
2252 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2253 MSG_WriteByte(&sv.datagram, TE_SPARK);
2255 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2256 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2257 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2259 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2260 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2261 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2263 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2266 void PF_te_gunshotquad (void)
2268 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2269 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
2271 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2272 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2273 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2276 void PF_te_spikequad (void)
2278 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2279 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
2281 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2282 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2283 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2286 void PF_te_superspikequad (void)
2288 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2289 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
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_explosionquad (void)
2298 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2299 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
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_smallflash (void)
2308 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2309 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
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_customflash (void)
2318 if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2320 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2321 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2323 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2324 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2325 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2327 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2329 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255));
2331 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
2332 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
2333 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
2336 void PF_te_gunshot (void)
2338 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2339 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2341 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2342 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2343 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2346 void PF_te_spike (void)
2348 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2349 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2351 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2352 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2353 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2356 void PF_te_superspike (void)
2358 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2359 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
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_explosion (void)
2368 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2369 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
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_tarexplosion (void)
2378 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2379 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
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_wizspike (void)
2388 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2389 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
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_knightspike (void)
2398 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2399 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
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_lavasplash (void)
2408 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2409 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
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_teleport (void)
2418 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2419 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
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_explosion2 (void)
2428 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2429 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
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]);
2435 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
2438 void PF_te_lightning1 (void)
2440 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2441 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2443 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2445 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2446 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2447 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2449 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2450 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2451 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2454 void PF_te_lightning2 (void)
2456 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2457 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2459 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2461 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2462 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2463 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2465 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2466 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2467 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2470 void PF_te_lightning3 (void)
2472 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2473 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2475 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2477 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2478 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2479 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2481 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2482 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2483 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2486 void PF_te_beam (void)
2488 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2489 MSG_WriteByte(&sv.datagram, TE_BEAM);
2491 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2493 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2494 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2495 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2497 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2498 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2499 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2502 void PF_Fixme (void)
2504 PR_RunError ("unimplemented builtin"); // LordHavoc: was misspelled (bulitin)
2509 builtin_t pr_builtin[] =
2512 PF_makevectors, // void(entity e) makevectors = #1;
2513 PF_setorigin, // void(entity e, vector o) setorigin = #2;
2514 PF_setmodel, // void(entity e, string m) setmodel = #3;
2515 PF_setsize, // void(entity e, vector min, vector max) setsize = #4;
2516 PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5;
2517 PF_break, // void() break = #6;
2518 PF_random, // float() random = #7;
2519 PF_sound, // void(entity e, float chan, string samp) sound = #8;
2520 PF_normalize, // vector(vector v) normalize = #9;
2521 PF_error, // void(string e) error = #10;
2522 PF_objerror, // void(string e) objerror = #11;
2523 PF_vlen, // float(vector v) vlen = #12;
2524 PF_vectoyaw, // float(vector v) vectoyaw = #13;
2525 PF_Spawn, // entity() spawn = #14;
2526 PF_Remove, // void(entity e) remove = #15;
2527 PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16;
2528 PF_checkclient, // entity() clientlist = #17;
2529 PF_Find, // entity(entity start, .string fld, string match) find = #18;
2530 PF_precache_sound, // void(string s) precache_sound = #19;
2531 PF_precache_model, // void(string s) precache_model = #20;
2532 PF_stuffcmd, // void(entity client, string s)stuffcmd = #21;
2533 PF_findradius, // entity(vector org, float rad) findradius = #22;
2534 PF_bprint, // void(string s) bprint = #23;
2535 PF_sprint, // void(entity client, string s) sprint = #24;
2536 PF_dprint, // void(string s) dprint = #25;
2537 PF_ftos, // void(string s) ftos = #26;
2538 PF_vtos, // void(string s) vtos = #27;
2542 PF_eprint, // void(entity e) debug print an entire entity
2543 PF_walkmove, // float(float yaw, float dist) walkmove
2544 PF_Fixme, // float(float yaw, float dist) walkmove
2594 PF_precache_sound, // precache_sound2 is different only for qcc
2599 PF_Fixme, // #79 LordHavoc: dunno who owns 79-89, so these are just padding
2611 PF_tracebox, // #90 LordHavoc builtin range (9x)
2612 PF_randomvec, // #91
2614 PF_registercvar, // #93
2619 PF_FindFloat, // #98
2620 PF_checkextension, // #99
2621 #define a PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme,
2622 #define aa a a a a a a a a a a
2626 PF_copyentity, // #400 LordHavoc: builtin range (4xx)
2627 PF_setcolor, // #401
2628 PF_findchain, // #402
2629 PF_findchainfloat, // #403
2631 PF_te_blood, // #405
2632 PF_te_bloodshower, // #406
2633 PF_te_explosionrgb, // #407
2634 PF_te_particlecube, // #408
2635 PF_te_particlerain, // #409
2636 PF_te_particlesnow, // #410
2637 PF_te_spark, // #411
2638 PF_te_gunshotquad, // #412
2639 PF_te_spikequad, // #413
2640 PF_te_superspikequad, // #414
2641 PF_te_explosionquad, // #415
2642 PF_te_smallflash, // #416
2643 PF_te_customflash, // #417
2644 PF_te_gunshot, // #418
2645 PF_te_spike, // #419
2646 PF_te_superspike, // #420
2647 PF_te_explosion, // #421
2648 PF_te_tarexplosion, // #422
2649 PF_te_wizspike, // #423
2650 PF_te_knightspike, // #424
2651 PF_te_lavasplash, // #425
2652 PF_te_teleport, // #426
2653 PF_te_explosion2, // #427
2654 PF_te_lightning1, // #428
2655 PF_te_lightning2, // #429
2656 PF_te_lightning3, // #430
2658 PF_vectorvectors, // #432
2661 builtin_t *pr_builtins = pr_builtin;
2662 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);