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 void PF_precache_model (void)
1306 if (sv.state != ss_loading)
1307 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1309 s = G_STRING(OFS_PARM0);
1310 if (hlbsp && ((!s) || (!s[0])))
1312 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1313 PR_CheckEmptyString (s);
1315 for (i=0 ; i<MAX_MODELS ; i++)
1317 if (!sv.model_precache[i])
1319 sv.model_precache[i] = s;
1320 sv.models[i] = Mod_ForName (s, true);
1323 if (!strcmp(sv.model_precache[i], s))
1326 PR_RunError ("PF_precache_model: overflow");
1330 void PF_coredump (void)
1335 void PF_traceon (void)
1340 void PF_traceoff (void)
1345 void PF_eprint (void)
1347 ED_PrintNum (G_EDICTNUM(OFS_PARM0));
1354 float(float yaw, float dist) walkmove
1357 void PF_walkmove (void)
1365 ent = PROG_TO_EDICT(pr_global_struct->self);
1366 yaw = G_FLOAT(OFS_PARM0);
1367 dist = G_FLOAT(OFS_PARM1);
1369 if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1371 G_FLOAT(OFS_RETURN) = 0;
1375 yaw = yaw*M_PI*2 / 360;
1377 move[0] = cos(yaw)*dist;
1378 move[1] = sin(yaw)*dist;
1381 // save program state, because SV_movestep may call other progs
1382 oldf = pr_xfunction;
1383 oldself = pr_global_struct->self;
1385 G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
1388 // restore program state
1389 pr_xfunction = oldf;
1390 pr_global_struct->self = oldself;
1400 void PF_droptofloor (void)
1406 ent = PROG_TO_EDICT(pr_global_struct->self);
1408 VectorCopy (ent->v.origin, end);
1411 trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent);
1413 if (trace.fraction == 1 || trace.allsolid)
1414 G_FLOAT(OFS_RETURN) = 0;
1417 VectorCopy (trace.endpos, ent->v.origin);
1418 SV_LinkEdict (ent, false);
1419 ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
1420 ent->v.groundentity = EDICT_TO_PROG(trace.ent);
1421 G_FLOAT(OFS_RETURN) = 1;
1429 void(float style, string value) lightstyle
1432 void PF_lightstyle (void)
1439 style = G_FLOAT(OFS_PARM0);
1440 val = G_STRING(OFS_PARM1);
1442 // change the string in sv
1443 sv.lightstyles[style] = val;
1445 // send message to all clients on this server
1446 if (sv.state != ss_active)
1449 for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
1450 if (client->active || client->spawned)
1452 MSG_WriteChar (&client->message, svc_lightstyle);
1453 MSG_WriteChar (&client->message,style);
1454 MSG_WriteString (&client->message, val);
1461 f = G_FLOAT(OFS_PARM0);
1463 G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1465 G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1467 void PF_floor (void)
1469 G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
1473 G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
1482 void PF_checkbottom (void)
1484 G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0));
1492 void PF_pointcontents (void)
1494 G_FLOAT(OFS_RETURN) = SV_PointContents (G_VECTOR(OFS_PARM0));
1501 entity nextent(entity)
1504 void PF_nextent (void)
1509 i = G_EDICTNUM(OFS_PARM0);
1513 if (i == sv.num_edicts)
1515 RETURN_EDICT(sv.edicts);
1531 Pick a vector for the player to shoot along
1532 vector aim(entity, missilespeed)
1535 cvar_t sv_aim = {"sv_aim", "0.93"};
1538 edict_t *ent, *check, *bestent;
1539 vec3_t start, dir, end, bestdir;
1542 float dist, bestdist;
1545 ent = G_EDICT(OFS_PARM0);
1546 speed = G_FLOAT(OFS_PARM1);
1548 VectorCopy (ent->v.origin, start);
1551 // try sending a trace straight
1552 VectorCopy (pr_global_struct->v_forward, dir);
1553 VectorMA (start, 2048, dir, end);
1554 tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
1555 if (tr.ent && tr.ent->v.takedamage == DAMAGE_AIM
1556 && (!teamplay.value || ent->v.team <=0 || ent->v.team != tr.ent->v.team) )
1558 VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
1563 // try all possible entities
1564 VectorCopy (dir, bestdir);
1565 bestdist = sv_aim.value;
1568 check = NEXT_EDICT(sv.edicts);
1569 for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
1571 if (check->v.takedamage != DAMAGE_AIM)
1575 if (teamplay.value && ent->v.team > 0 && ent->v.team == check->v.team)
1576 continue; // don't aim at teammate
1577 for (j=0 ; j<3 ; j++)
1578 end[j] = check->v.origin[j]
1579 + 0.5*(check->v.mins[j] + check->v.maxs[j]);
1580 VectorSubtract (end, start, dir);
1581 VectorNormalize (dir);
1582 dist = DotProduct (dir, pr_global_struct->v_forward);
1583 if (dist < bestdist)
1584 continue; // to far to turn
1585 tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
1586 if (tr.ent == check)
1587 { // can shoot at this one
1595 VectorSubtract (bestent->v.origin, ent->v.origin, dir);
1596 dist = DotProduct (dir, pr_global_struct->v_forward);
1597 VectorScale (pr_global_struct->v_forward, dist, end);
1599 VectorNormalize (end);
1600 VectorCopy (end, G_VECTOR(OFS_RETURN));
1604 VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
1612 This was a major timewaster in progs, so it was converted to C
1615 void PF_changeyaw (void)
1618 float ideal, current, move, speed;
1620 ent = PROG_TO_EDICT(pr_global_struct->self);
1621 current = ANGLEMOD(ent->v.angles[1]);
1622 ideal = ent->v.ideal_yaw;
1623 speed = ent->v.yaw_speed;
1625 if (current == ideal)
1627 move = ideal - current;
1628 if (ideal > current)
1649 ent->v.angles[1] = ANGLEMOD (current + move);
1657 void PF_changepitch (void)
1660 float ideal, current, move, speed;
1663 ent = G_EDICT(OFS_PARM0);
1664 current = ANGLEMOD( ent->v.angles[0] );
1665 if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
1666 ideal = val->_float;
1669 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1672 if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
1673 speed = val->_float;
1676 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1680 if (current == ideal)
1682 move = ideal - current;
1683 if (ideal > current)
1704 ent->v.angles[0] = ANGLEMOD (current + move);
1708 ===============================================================================
1712 ===============================================================================
1715 #define MSG_BROADCAST 0 // unreliable to all
1716 #define MSG_ONE 1 // reliable to one (msg_entity)
1717 #define MSG_ALL 2 // reliable to all
1718 #define MSG_INIT 3 // write to the init string
1720 sizebuf_t *WriteDest (void)
1726 dest = G_FLOAT(OFS_PARM0);
1730 return &sv.datagram;
1733 ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
1734 entnum = NUM_FOR_EDICT(ent);
1735 if (entnum < 1 || entnum > svs.maxclients)
1736 PR_RunError ("WriteDest: not a client");
1737 return &svs.clients[entnum-1].message;
1740 return &sv.reliable_datagram;
1746 PR_RunError ("WriteDest: bad destination");
1753 void PF_WriteByte (void)
1755 MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
1758 void PF_WriteChar (void)
1760 MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
1763 void PF_WriteShort (void)
1765 MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
1768 void PF_WriteLong (void)
1770 MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
1773 void PF_WriteAngle (void)
1775 MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
1778 void PF_WriteCoord (void)
1780 MSG_WriteFloatCoord (WriteDest(), G_FLOAT(OFS_PARM1));
1783 void PF_WriteString (void)
1785 MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
1789 void PF_WriteEntity (void)
1791 MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
1794 //=============================================================================
1796 int SV_ModelIndex (char *name);
1798 void PF_makestatic (void)
1803 ent = G_EDICT(OFS_PARM0);
1805 i = SV_ModelIndex(pr_strings + ent->v.model);
1808 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1809 MSG_WriteShort (&sv.signon, i);
1813 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1814 MSG_WriteByte (&sv.signon, i);
1817 MSG_WriteByte (&sv.signon, ent->v.frame);
1818 MSG_WriteByte (&sv.signon, ent->v.colormap);
1819 MSG_WriteByte (&sv.signon, ent->v.skin);
1820 for (i=0 ; i<3 ; i++)
1822 MSG_WriteFloatCoord(&sv.signon, ent->v.origin[i]);
1823 MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
1826 // throw the entity away now
1830 //=============================================================================
1837 void PF_setspawnparms (void)
1843 ent = G_EDICT(OFS_PARM0);
1844 i = NUM_FOR_EDICT(ent);
1845 if (i < 1 || i > svs.maxclients)
1846 PR_RunError ("Entity is not a client");
1848 // copy spawn parms out of the client_t
1849 client = svs.clients + (i-1);
1851 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1852 (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
1860 void PF_changelevel (void)
1864 // make sure we don't issue two changelevels
1865 if (svs.changelevel_issued)
1867 svs.changelevel_issued = true;
1869 s = G_STRING(OFS_PARM0);
1870 Cbuf_AddText (va("changelevel %s\n",s));
1875 G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
1880 G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
1885 G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
1892 Returns a vector of length < 1
1897 void PF_randomvec (void)
1902 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1903 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1904 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1906 while (DotProduct(temp, temp) >= 1);
1907 VectorCopy (temp, G_VECTOR(OFS_RETURN));
1910 void SV_LightPoint (vec3_t color, vec3_t p);
1915 Returns a color vector indicating the lighting at the requested point.
1917 (Internal Operation note: actually measures the light beneath the point, just like
1918 the model lighting on the client)
1923 void PF_GetLight (void)
1927 p = G_VECTOR(OFS_PARM0);
1928 SV_LightPoint (color, p);
1929 VectorCopy (color, G_VECTOR(OFS_RETURN));
1932 #define MAX_QC_CVARS 128
1933 cvar_t qc_cvar[MAX_QC_CVARS];
1936 void PF_registercvar (void)
1940 name = G_STRING(OFS_PARM1);
1941 value = G_STRING(OFS_PARM2);
1942 G_FLOAT(OFS_RETURN) = 0;
1943 // first check to see if it has already been defined
1944 if (Cvar_FindVar (name))
1947 // check for overlap with a command
1948 if (Cmd_Exists (name))
1950 Con_Printf ("PF_registercvar: %s is a command\n", name);
1954 if (currentqc_cvar >= MAX_QC_CVARS)
1955 PR_RunError ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
1957 // copy the name and value
1958 variable = &qc_cvar[currentqc_cvar++];
1959 variable->name = Z_Malloc (strlen(name)+1);
1960 strcpy (variable->name, name);
1961 variable->string = Z_Malloc (strlen(value)+1);
1962 strcpy (variable->string, value);
1963 variable->value = atof (value);
1965 // link the variable in
1966 variable->next = cvar_vars;
1967 cvar_vars = variable;
1968 G_FLOAT(OFS_RETURN) = 1; // success
1975 returns the minimum of two supplied floats
1982 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1984 G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1985 else if (pr_argc >= 3)
1988 float f = G_FLOAT(OFS_PARM0);
1989 for (i = 1;i < pr_argc;i++)
1990 if (G_FLOAT((OFS_PARM0+i*3)) < f)
1991 f = G_FLOAT((OFS_PARM0+i*3));
1992 G_FLOAT(OFS_RETURN) = f;
1995 PR_RunError("min: must supply at least 2 floats\n");
2002 returns the maximum of two supplied floats
2009 // LordHavoc: 3+ argument enhancement suggested by FrikaC
2011 G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2012 else if (pr_argc >= 3)
2015 float f = G_FLOAT(OFS_PARM0);
2016 for (i = 1;i < pr_argc;i++)
2017 if (G_FLOAT((OFS_PARM0+i*3)) > f)
2018 f = G_FLOAT((OFS_PARM0+i*3));
2019 G_FLOAT(OFS_RETURN) = f;
2022 PR_RunError("max: must supply at least 2 floats\n");
2029 returns number bounded by supplied range
2031 min(min, value, max)
2034 void PF_bound (void)
2036 G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
2043 returns a raised to power b
2050 G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2057 copies data from one entity to another
2059 copyentity(src, dst)
2062 void PF_copyentity (void)
2065 in = G_EDICT(OFS_PARM0);
2066 out = G_EDICT(OFS_PARM1);
2067 memcpy(out, in, pr_edict_size);
2074 sets the color of a client and broadcasts the update to all connected clients
2076 setcolor(clientent, value)
2079 void PF_setcolor (void)
2084 entnum = G_EDICTNUM(OFS_PARM0);
2085 i = G_FLOAT(OFS_PARM1);
2087 if (entnum < 1 || entnum > svs.maxclients)
2089 Con_Printf ("tried to setcolor a non-client\n");
2093 client = &svs.clients[entnum-1];
2095 client->edict->v.team = (i & 15) + 1;
2097 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
2098 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
2099 MSG_WriteByte (&sv.reliable_datagram, i);
2106 effect(origin, modelname, startframe, framecount, framerate)
2109 void PF_effect (void)
2112 s = G_STRING(OFS_PARM1);
2114 PR_RunError("effect: no model specified\n");
2116 SV_StartEffect(G_VECTOR(OFS_PARM0), SV_ModelIndex(s), G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
2119 void PF_te_blood (void)
2121 if (G_FLOAT(OFS_PARM2) < 1)
2123 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2124 MSG_WriteByte(&sv.datagram, TE_BLOOD);
2126 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2127 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2128 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2130 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2131 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2132 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2134 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2137 void PF_te_bloodshower (void)
2139 if (G_FLOAT(OFS_PARM3) < 1)
2141 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2142 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
2144 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2145 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2146 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2148 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2149 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2150 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2152 MSG_WriteFloatCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
2154 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2157 void PF_te_explosionrgb (void)
2159 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2160 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
2162 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2163 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2164 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2166 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
2167 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
2168 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
2171 void PF_te_particlecube (void)
2173 if (G_FLOAT(OFS_PARM3) < 1)
2175 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2176 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
2178 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2179 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2180 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2182 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2183 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2184 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2186 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2187 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2188 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2190 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2192 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2193 // gravity true/false
2194 MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
2196 MSG_WriteFloatCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
2199 void PF_te_particlerain (void)
2201 if (G_FLOAT(OFS_PARM3) < 1)
2203 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2204 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
2206 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2207 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2208 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2210 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2211 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2212 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2214 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2215 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2216 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2218 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2220 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2223 void PF_te_particlesnow (void)
2225 if (G_FLOAT(OFS_PARM3) < 1)
2227 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2228 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
2230 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2231 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2232 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2234 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2235 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2236 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2238 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2239 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2240 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2242 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2244 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2247 void PF_te_spark (void)
2249 if (G_FLOAT(OFS_PARM2) < 1)
2251 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2252 MSG_WriteByte(&sv.datagram, TE_SPARK);
2254 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2255 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2256 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2258 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2259 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2260 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2262 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2265 void PF_te_gunshotquad (void)
2267 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2268 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
2270 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2271 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2272 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2275 void PF_te_spikequad (void)
2277 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2278 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
2280 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2281 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2282 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2285 void PF_te_superspikequad (void)
2287 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2288 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
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_explosionquad (void)
2297 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2298 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
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_smallflash (void)
2307 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2308 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
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_customflash (void)
2317 if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2319 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2320 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2322 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2323 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2324 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2326 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2328 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255));
2330 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
2331 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
2332 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
2335 void PF_te_gunshot (void)
2337 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2338 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2340 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2341 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2342 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2345 void PF_te_spike (void)
2347 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2348 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2350 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2351 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2352 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2355 void PF_te_superspike (void)
2357 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2358 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
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_explosion (void)
2367 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2368 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
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_tarexplosion (void)
2377 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2378 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
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_wizspike (void)
2387 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2388 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
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_knightspike (void)
2397 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2398 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
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_lavasplash (void)
2407 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2408 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
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_teleport (void)
2417 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2418 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
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_explosion2 (void)
2427 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2428 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
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]);
2434 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
2437 void PF_te_lightning1 (void)
2439 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2440 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2442 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2444 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2445 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2446 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2448 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2449 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2450 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2453 void PF_te_lightning2 (void)
2455 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2456 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2458 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2460 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2461 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2462 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2464 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2465 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2466 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2469 void PF_te_lightning3 (void)
2471 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2472 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2474 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2476 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2477 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2478 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2480 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2481 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2482 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2485 void PF_te_beam (void)
2487 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2488 MSG_WriteByte(&sv.datagram, TE_BEAM);
2490 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2492 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2493 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2494 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2496 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2497 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2498 MSG_WriteFloatCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2501 void PF_Fixme (void)
2503 PR_RunError ("unimplemented builtin"); // LordHavoc: was misspelled (bulitin)
2508 builtin_t pr_builtin[] =
2511 PF_makevectors, // void(entity e) makevectors = #1;
2512 PF_setorigin, // void(entity e, vector o) setorigin = #2;
2513 PF_setmodel, // void(entity e, string m) setmodel = #3;
2514 PF_setsize, // void(entity e, vector min, vector max) setsize = #4;
2515 PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5;
2516 PF_break, // void() break = #6;
2517 PF_random, // float() random = #7;
2518 PF_sound, // void(entity e, float chan, string samp) sound = #8;
2519 PF_normalize, // vector(vector v) normalize = #9;
2520 PF_error, // void(string e) error = #10;
2521 PF_objerror, // void(string e) objerror = #11;
2522 PF_vlen, // float(vector v) vlen = #12;
2523 PF_vectoyaw, // float(vector v) vectoyaw = #13;
2524 PF_Spawn, // entity() spawn = #14;
2525 PF_Remove, // void(entity e) remove = #15;
2526 PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16;
2527 PF_checkclient, // entity() clientlist = #17;
2528 PF_Find, // entity(entity start, .string fld, string match) find = #18;
2529 PF_precache_sound, // void(string s) precache_sound = #19;
2530 PF_precache_model, // void(string s) precache_model = #20;
2531 PF_stuffcmd, // void(entity client, string s)stuffcmd = #21;
2532 PF_findradius, // entity(vector org, float rad) findradius = #22;
2533 PF_bprint, // void(string s) bprint = #23;
2534 PF_sprint, // void(entity client, string s) sprint = #24;
2535 PF_dprint, // void(string s) dprint = #25;
2536 PF_ftos, // void(string s) ftos = #26;
2537 PF_vtos, // void(string s) vtos = #27;
2541 PF_eprint, // void(entity e) debug print an entire entity
2542 PF_walkmove, // float(float yaw, float dist) walkmove
2543 PF_Fixme, // float(float yaw, float dist) walkmove
2593 PF_precache_sound, // precache_sound2 is different only for qcc
2598 PF_Fixme, // #79 LordHavoc: dunno who owns 79-89, so these are just padding
2610 PF_tracebox, // #90 LordHavoc builtin range (9x)
2611 PF_randomvec, // #91
2613 PF_registercvar, // #93
2618 PF_FindFloat, // #98
2619 PF_checkextension, // #99
2620 #define a PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme,
2621 #define aa a a a a a a a a a a
2625 PF_copyentity, // #400 LordHavoc: builtin range (4xx)
2626 PF_setcolor, // #401
2627 PF_findchain, // #402
2628 PF_findchainfloat, // #403
2630 PF_te_blood, // #405
2631 PF_te_bloodshower, // #406
2632 PF_te_explosionrgb, // #407
2633 PF_te_particlecube, // #408
2634 PF_te_particlerain, // #409
2635 PF_te_particlesnow, // #410
2636 PF_te_spark, // #411
2637 PF_te_gunshotquad, // #412
2638 PF_te_spikequad, // #413
2639 PF_te_superspikequad, // #414
2640 PF_te_explosionquad, // #415
2641 PF_te_smallflash, // #416
2642 PF_te_customflash, // #417
2643 PF_te_gunshot, // #418
2644 PF_te_spike, // #419
2645 PF_te_superspike, // #420
2646 PF_te_explosion, // #421
2647 PF_te_tarexplosion, // #422
2648 PF_te_wizspike, // #423
2649 PF_te_knightspike, // #424
2650 PF_te_lavasplash, // #425
2651 PF_te_teleport, // #426
2652 PF_te_explosion2, // #427
2653 PF_te_lightning1, // #428
2654 PF_te_lightning2, // #429
2655 PF_te_lightning3, // #430
2657 PF_vectorvectors, // #432
2660 builtin_t *pr_builtins = pr_builtin;
2661 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);