2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 cvar_t sv_aim = {CVAR_SAVE, "sv_aim", "2"}; //"0.93"}; // LordHavoc: disabled autoaim by default
25 #define RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e))
29 ===============================================================================
33 ===============================================================================
37 char *PF_VarString (int first)
40 static char out[4096]; // FIXME: buffer overflow potential
43 for (i = first;i < pr_argc;i++)
44 strcat (out, G_STRING((OFS_PARM0+i*3)));
48 char *ENGINE_EXTENSIONS =
50 "DP_ENT_CUSTOMCOLORMAP "
51 "DP_ENT_EXTERIORMODELTOCLIENT "
52 "DP_ENT_LOWPRECISION "
65 "DP_QC_FINDCHAINFLOAT "
70 "DP_QC_SINCOSSQRTPOW "
73 "DP_QC_VECTORVECTORS "
78 "DP_SV_DRAWONLYTOCLIENT "
80 "DP_SV_EXTERIORMODELTOCLIENT "
81 "DP_SV_NODRAWTOCLIENT "
82 "DP_SV_PLAYERPHYSICS "
96 qboolean checkextension(char *name)
101 for (e = ENGINE_EXTENSIONS;*e;e++)
108 while (*e && *e != ' ')
110 if (e - start == len)
111 if (!strncasecmp(start, name, len))
121 returns true if the extension is supported by the server
123 checkextension(extensionname)
126 void PF_checkextension (void)
128 G_FLOAT(OFS_RETURN) = checkextension(G_STRING(OFS_PARM0));
135 This is a TERMINAL error, which will kill off the entire server.
147 Con_Printf ("======SERVER ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
148 ed = PROG_TO_EDICT(pr_global_struct->self);
151 Host_Error ("Program error");
158 Dumps out self, then an error message. The program is aborted and self is
159 removed, but the level can continue.
164 void PF_objerror (void)
170 Con_Printf ("======OBJECT ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
171 ed = PROG_TO_EDICT(pr_global_struct->self);
181 Writes new values for v_forward, v_up, and v_right based on angles
185 void PF_makevectors (void)
187 AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
194 Writes new values for v_forward, v_up, and v_right based on the given forward vector
195 vectorvectors(vector, vector)
198 void PF_vectorvectors (void)
200 VectorNormalize2(G_VECTOR(OFS_PARM0), pr_global_struct->v_forward);
201 VectorVectors(pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
208 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.
210 setorigin (entity, origin)
213 void PF_setorigin (void)
218 e = G_EDICT(OFS_PARM0);
219 org = G_VECTOR(OFS_PARM1);
220 VectorCopy (org, e->v.origin);
221 SV_LinkEdict (e, false);
225 void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
229 for (i=0 ; i<3 ; i++)
231 PR_RunError ("backwards mins/maxs");
233 // set derived values
234 VectorCopy (min, e->v.mins);
235 VectorCopy (max, e->v.maxs);
236 VectorSubtract (max, min, e->v.size);
238 SV_LinkEdict (e, false);
245 the size box is rotated by the current angle
246 LordHavoc: no it isn't...
248 setsize (entity, minvector, maxvector)
251 void PF_setsize (void)
256 e = G_EDICT(OFS_PARM0);
257 min = G_VECTOR(OFS_PARM1);
258 max = G_VECTOR(OFS_PARM2);
259 SetMinMaxSize (e, min, max, false);
267 setmodel(entity, model)
270 void PF_setmodel (void)
277 e = G_EDICT(OFS_PARM0);
278 m = G_STRING(OFS_PARM1);
280 // check to see if model was properly precached
281 for (i=0, check = sv.model_precache ; *check ; i++, check++)
282 if (!strcmp(*check, m))
286 PR_RunError ("no precache: %s\n", m);
289 e->v.model = m - pr_strings;
292 mod = sv.models[ (int)e->v.modelindex];
295 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
297 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
304 broadcast print to everyone on server
309 void PF_bprint (void)
314 SV_BroadcastPrintf ("%s", s);
321 single print to a specific client
323 sprint(clientent, value)
326 void PF_sprint (void)
332 entnum = G_EDICTNUM(OFS_PARM0);
335 if (entnum < 1 || entnum > svs.maxclients)
337 Con_Printf ("tried to sprint to a non-client\n");
341 client = &svs.clients[entnum-1];
343 MSG_WriteChar (&client->message,svc_print);
344 MSG_WriteString (&client->message, s );
352 single print to a specific client
354 centerprint(clientent, value)
357 void PF_centerprint (void)
363 entnum = G_EDICTNUM(OFS_PARM0);
366 if (entnum < 1 || entnum > svs.maxclients)
368 Con_Printf ("tried to sprint to a non-client\n");
372 client = &svs.clients[entnum-1];
374 MSG_WriteChar (&client->message,svc_centerprint);
375 MSG_WriteString (&client->message, s );
383 vector normalize(vector)
386 void PF_normalize (void)
392 value1 = G_VECTOR(OFS_PARM0);
394 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
398 newvalue[0] = newvalue[1] = newvalue[2] = 0;
402 newvalue[0] = value1[0] * new;
403 newvalue[1] = value1[1] * new;
404 newvalue[2] = value1[2] * new;
407 VectorCopy (newvalue, G_VECTOR(OFS_RETURN));
422 value1 = G_VECTOR(OFS_PARM0);
424 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
427 G_FLOAT(OFS_RETURN) = new;
434 float vectoyaw(vector)
437 void PF_vectoyaw (void)
442 value1 = G_VECTOR(OFS_PARM0);
444 if (value1[1] == 0 && value1[0] == 0)
448 yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
453 G_FLOAT(OFS_RETURN) = yaw;
461 vector vectoangles(vector)
464 void PF_vectoangles (void)
470 value1 = G_VECTOR(OFS_PARM0);
472 if (value1[1] == 0 && value1[0] == 0)
482 // LordHavoc: optimized a bit
485 yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
489 else if (value1[1] > 0)
494 forward = sqrt(value1[0]*value1[0] + value1[1]*value1[1]);
495 pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
500 G_FLOAT(OFS_RETURN+0) = pitch;
501 G_FLOAT(OFS_RETURN+1) = yaw;
502 G_FLOAT(OFS_RETURN+2) = 0;
509 Returns a number from 0<= num < 1
514 void PF_random (void)
518 num = (rand ()&0x7fff) / ((float)0x7fff);
520 G_FLOAT(OFS_RETURN) = num;
527 particle(origin, color, count)
530 void PF_particle (void)
536 org = G_VECTOR(OFS_PARM0);
537 dir = G_VECTOR(OFS_PARM1);
538 color = G_FLOAT(OFS_PARM2);
539 count = G_FLOAT(OFS_PARM3);
540 SV_StartParticle (org, dir, color, count);
550 void PF_ambientsound (void)
555 float vol, attenuation;
556 int i, soundnum, large;
558 pos = G_VECTOR (OFS_PARM0);
559 samp = G_STRING(OFS_PARM1);
560 vol = G_FLOAT(OFS_PARM2);
561 attenuation = G_FLOAT(OFS_PARM3);
563 // check to see if samp was properly precached
564 for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++)
565 if (!strcmp(*check,samp))
570 Con_Printf ("no precache: %s\n", samp);
578 // add an svc_spawnambient command to the level signon packet
581 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
583 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
585 for (i=0 ; i<3 ; i++)
586 MSG_WriteDPCoord(&sv.signon, pos[i]);
589 MSG_WriteShort (&sv.signon, soundnum);
591 MSG_WriteByte (&sv.signon, soundnum);
593 MSG_WriteByte (&sv.signon, vol*255);
594 MSG_WriteByte (&sv.signon, attenuation*64);
602 Each entity can have eight independant sound sources, like voice,
605 Channel 0 is an auto-allocate channel, the others override anything
606 already running on that entity/channel pair.
608 An attenuation of 0 will play full volume everywhere in the level.
609 Larger attenuations will drop off.
621 entity = G_EDICT(OFS_PARM0);
622 channel = G_FLOAT(OFS_PARM1);
623 sample = G_STRING(OFS_PARM2);
624 volume = G_FLOAT(OFS_PARM3) * 255;
625 attenuation = G_FLOAT(OFS_PARM4);
627 if (volume < 0 || volume > 255)
628 Host_Error ("SV_StartSound: volume = %i", volume);
630 if (attenuation < 0 || attenuation > 4)
631 Host_Error ("SV_StartSound: attenuation = %f", attenuation);
633 if (channel < 0 || channel > 7)
634 Host_Error ("SV_StartSound: channel = %i", channel);
636 SV_StartSound (entity, channel, sample, volume, attenuation);
648 PR_RunError ("break statement");
655 Used for use tracing and shot targeting
656 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
657 if the tryents flag is set.
659 traceline (vector1, vector2, tryents)
662 void PF_traceline (void)
669 v1 = G_VECTOR(OFS_PARM0);
670 v2 = G_VECTOR(OFS_PARM1);
671 nomonsters = G_FLOAT(OFS_PARM2);
672 ent = G_EDICT(OFS_PARM3);
674 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters ? MOVE_NOMONSTERS : MOVE_NORMAL, ent);
676 pr_global_struct->trace_allsolid = trace.allsolid;
677 pr_global_struct->trace_startsolid = trace.startsolid;
678 pr_global_struct->trace_fraction = trace.fraction;
679 pr_global_struct->trace_inwater = trace.inwater;
680 pr_global_struct->trace_inopen = trace.inopen;
681 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
682 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
683 pr_global_struct->trace_plane_dist = trace.plane.dist;
685 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
687 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
688 // FIXME: add trace_endcontents
696 Used for use tracing and shot targeting
697 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
698 if the tryents flag is set.
700 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
703 // LordHavoc: added this for my own use, VERY useful, similar to traceline
704 void PF_tracebox (void)
706 float *v1, *v2, *m1, *m2;
711 v1 = G_VECTOR(OFS_PARM0);
712 m1 = G_VECTOR(OFS_PARM1);
713 m2 = G_VECTOR(OFS_PARM2);
714 v2 = G_VECTOR(OFS_PARM3);
715 nomonsters = G_FLOAT(OFS_PARM4);
716 ent = G_EDICT(OFS_PARM5);
718 trace = SV_Move (v1, m1, m2, v2, nomonsters ? MOVE_NOMONSTERS : MOVE_NORMAL, ent);
720 pr_global_struct->trace_allsolid = trace.allsolid;
721 pr_global_struct->trace_startsolid = trace.startsolid;
722 pr_global_struct->trace_fraction = trace.fraction;
723 pr_global_struct->trace_inwater = trace.inwater;
724 pr_global_struct->trace_inopen = trace.inopen;
725 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
726 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
727 pr_global_struct->trace_plane_dist = trace.plane.dist;
729 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
731 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
734 extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore);
735 void PF_TraceToss (void)
741 ent = G_EDICT(OFS_PARM0);
742 ignore = G_EDICT(OFS_PARM1);
744 trace = SV_Trace_Toss (ent, ignore);
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 Returns true if the given entity can move to the given position from it's
766 current position by walking or rolling.
768 scalar checkpos (entity, vector)
771 void PF_checkpos (void)
775 //============================================================================
777 qbyte checkpvs[MAX_MAP_LEAFS/8];
779 int PF_newcheckclient (int check)
787 // cycle to the next one
791 if (check > svs.maxclients)
792 check = svs.maxclients;
794 if (check == svs.maxclients)
801 if (i == svs.maxclients+1)
807 break; // didn't find anything else
811 if (ent->v.health <= 0)
813 if ((int)ent->v.flags & FL_NOTARGET)
816 // anything that is a client, or has a client as an enemy
820 // get the PVS for the entity
821 VectorAdd (ent->v.origin, ent->v.view_ofs, org);
822 leaf = Mod_PointInLeaf (org, sv.worldmodel);
823 pvs = Mod_LeafPVS (leaf, sv.worldmodel);
824 memcpy (checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 );
833 Returns a client (or object that has a client enemy) that would be a
836 If there is more than one valid option, they are cycled each frame
838 If (self.origin + self.viewofs) is not in the PVS of the current target,
839 it is not returned at all.
844 int c_invis, c_notvis;
845 void PF_checkclient (void)
852 // find a new check if on a new frame
853 if (sv.time - sv.lastchecktime >= 0.1)
855 sv.lastcheck = PF_newcheckclient (sv.lastcheck);
856 sv.lastchecktime = sv.time;
859 // return check if it might be visible
860 ent = EDICT_NUM(sv.lastcheck);
861 if (ent->free || ent->v.health <= 0)
863 RETURN_EDICT(sv.edicts);
867 // if current entity can't possibly see the check entity, return 0
868 self = PROG_TO_EDICT(pr_global_struct->self);
869 VectorAdd (self->v.origin, self->v.view_ofs, view);
870 leaf = Mod_PointInLeaf (view, sv.worldmodel);
871 l = (leaf - sv.worldmodel->leafs) - 1;
872 if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
875 RETURN_EDICT(sv.edicts);
879 // might be able to see it
884 //============================================================================
891 Sends text over to the client's execution buffer
893 stuffcmd (clientent, value)
896 void PF_stuffcmd (void)
902 entnum = G_EDICTNUM(OFS_PARM0);
903 if (entnum < 1 || entnum > svs.maxclients)
904 PR_RunError ("Parm 0 not a client");
905 str = G_STRING(OFS_PARM1);
908 host_client = &svs.clients[entnum-1];
909 Host_ClientCommands ("%s", str);
917 Sends text over to the client's execution buffer
922 void PF_localcmd (void)
926 str = G_STRING(OFS_PARM0);
941 str = G_STRING(OFS_PARM0);
943 G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str);
953 void PF_cvar_set (void)
957 var = G_STRING(OFS_PARM0);
958 val = G_STRING(OFS_PARM1);
967 Returns a chain of entities that have origins within a spherical area
969 findradius (origin, radius)
972 void PF_findradius (void)
974 edict_t *ent, *chain;
981 chain = (edict_t *)sv.edicts;
983 org = G_VECTOR(OFS_PARM0);
984 radius = G_FLOAT(OFS_PARM1);
985 radius2 = radius * radius;
987 ent = NEXT_EDICT(sv.edicts);
988 for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
992 if (ent->v.solid == SOLID_NOT)
995 // LordHavoc: compare against bounding box rather than center,
996 // and use DotProduct instead of Length, major speedup
997 eorg[0] = (org[0] - ent->v.origin[0]) - bound(ent->v.mins[0], (org[0] - ent->v.origin[0]), ent->v.maxs[0]);
998 eorg[1] = (org[1] - ent->v.origin[1]) - bound(ent->v.mins[1], (org[1] - ent->v.origin[1]), ent->v.maxs[1]);
999 eorg[2] = (org[2] - ent->v.origin[2]) - bound(ent->v.mins[2], (org[2] - ent->v.origin[2]), ent->v.maxs[2]);
1000 if (DotProduct(eorg, eorg) > radius2)
1003 ent->v.chain = EDICT_TO_PROG(chain);
1007 RETURN_EDICT(chain);
1016 void PF_dprint (void)
1018 Con_DPrintf ("%s",PF_VarString(0));
1021 // LordHavoc: added this to semi-fix the problem of using many ftos calls in a print
1022 #define STRINGTEMP_BUFFERS 16
1023 #define STRINGTEMP_LENGTH 128
1024 static char pr_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH];
1025 static int pr_string_tempindex = 0;
1027 static char *PR_GetTempString(void)
1030 s = pr_string_temp[pr_string_tempindex];
1031 pr_string_tempindex = (pr_string_tempindex + 1) % STRINGTEMP_BUFFERS;
1039 v = G_FLOAT(OFS_PARM0);
1041 s = PR_GetTempString();
1042 // LordHavoc: ftos improvement
1043 sprintf (s, "%g", v);
1044 G_INT(OFS_RETURN) = s - pr_strings;
1050 v = G_FLOAT(OFS_PARM0);
1051 G_FLOAT(OFS_RETURN) = fabs(v);
1057 s = PR_GetTempString();
1058 sprintf (s, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
1059 G_INT(OFS_RETURN) = s - pr_strings;
1065 s = PR_GetTempString();
1066 sprintf (s, "entity %i", G_EDICTNUM(OFS_PARM0));
1067 G_INT(OFS_RETURN) = s - pr_strings;
1070 void PF_Spawn (void)
1077 void PF_Remove (void)
1081 ed = G_EDICT(OFS_PARM0);
1082 if (ed == sv.edicts)
1083 PR_RunError("remove: tried to remove world\n");
1084 if (NUM_FOR_EDICT(ed) <= svs.maxclients)
1085 PR_RunError("remove: tried to remove a client\n");
1090 // entity (entity start, .string field, string match) find = #5;
1098 e = G_EDICTNUM(OFS_PARM0);
1099 f = G_INT(OFS_PARM1);
1100 s = G_STRING(OFS_PARM2);
1103 RETURN_EDICT(sv.edicts);
1107 for (e++ ; e < sv.num_edicts ; e++)
1122 RETURN_EDICT(sv.edicts);
1125 // LordHavoc: added this for searching float, int, and entity reference fields
1126 void PF_FindFloat (void)
1133 e = G_EDICTNUM(OFS_PARM0);
1134 f = G_INT(OFS_PARM1);
1135 s = G_FLOAT(OFS_PARM2);
1137 for (e++ ; e < sv.num_edicts ; e++)
1142 if (E_FLOAT(ed,f) == s)
1149 RETURN_EDICT(sv.edicts);
1152 // chained search for strings in entity fields
1153 // entity(.string field, string match) findchain = #402;
1154 void PF_findchain (void)
1159 edict_t *ent, *chain;
1161 chain = (edict_t *)sv.edicts;
1163 f = G_INT(OFS_PARM0);
1164 s = G_STRING(OFS_PARM1);
1167 RETURN_EDICT(sv.edicts);
1171 ent = NEXT_EDICT(sv.edicts);
1172 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1176 t = E_STRING(ent,f);
1182 ent->v.chain = EDICT_TO_PROG(chain);
1186 RETURN_EDICT(chain);
1189 // LordHavoc: chained search for float, int, and entity reference fields
1190 // entity(.string field, float match) findchainfloat = #403;
1191 void PF_findchainfloat (void)
1196 edict_t *ent, *chain;
1198 chain = (edict_t *)sv.edicts;
1200 f = G_INT(OFS_PARM0);
1201 s = G_FLOAT(OFS_PARM1);
1203 ent = NEXT_EDICT(sv.edicts);
1204 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1208 if (E_FLOAT(ent,f) != s)
1211 ent->v.chain = EDICT_TO_PROG(chain);
1215 RETURN_EDICT(chain);
1218 void PR_CheckEmptyString (char *s)
1221 PR_RunError ("Bad string");
1224 void PF_precache_file (void)
1225 { // precache_file is only used to copy files with qcc, it does nothing
1226 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1229 void PF_precache_sound (void)
1234 if (sv.state != ss_loading)
1235 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1237 s = G_STRING(OFS_PARM0);
1238 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1239 PR_CheckEmptyString (s);
1241 for (i=0 ; i<MAX_SOUNDS ; i++)
1243 if (!sv.sound_precache[i])
1245 sv.sound_precache[i] = s;
1248 if (!strcmp(sv.sound_precache[i], s))
1251 PR_RunError ("PF_precache_sound: overflow");
1254 void PF_precache_model (void)
1259 if (sv.state != ss_loading)
1260 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1262 s = G_STRING(OFS_PARM0);
1263 if (sv.worldmodel->ishlbsp && ((!s) || (!s[0])))
1265 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1266 PR_CheckEmptyString (s);
1268 for (i=0 ; i<MAX_MODELS ; i++)
1270 if (!sv.model_precache[i])
1272 sv.model_precache[i] = s;
1273 sv.models[i] = Mod_ForName (s, true, false, false);
1276 if (!strcmp(sv.model_precache[i], s))
1279 PR_RunError ("PF_precache_model: overflow");
1283 void PF_coredump (void)
1288 void PF_traceon (void)
1293 void PF_traceoff (void)
1298 void PF_eprint (void)
1300 ED_PrintNum (G_EDICTNUM(OFS_PARM0));
1307 float(float yaw, float dist) walkmove
1310 void PF_walkmove (void)
1318 ent = PROG_TO_EDICT(pr_global_struct->self);
1319 yaw = G_FLOAT(OFS_PARM0);
1320 dist = G_FLOAT(OFS_PARM1);
1322 if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1324 G_FLOAT(OFS_RETURN) = 0;
1328 yaw = yaw*M_PI*2 / 360;
1330 move[0] = cos(yaw)*dist;
1331 move[1] = sin(yaw)*dist;
1334 // save program state, because SV_movestep may call other progs
1335 oldf = pr_xfunction;
1336 oldself = pr_global_struct->self;
1338 G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
1341 // restore program state
1342 pr_xfunction = oldf;
1343 pr_global_struct->self = oldself;
1353 void PF_droptofloor (void)
1359 ent = PROG_TO_EDICT(pr_global_struct->self);
1361 VectorCopy (ent->v.origin, end);
1364 trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
1366 if (trace.fraction == 1 || trace.allsolid)
1367 G_FLOAT(OFS_RETURN) = 0;
1370 VectorCopy (trace.endpos, ent->v.origin);
1371 SV_LinkEdict (ent, false);
1372 ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
1373 ent->v.groundentity = EDICT_TO_PROG(trace.ent);
1374 G_FLOAT(OFS_RETURN) = 1;
1375 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1376 ent->suspendedinairflag = true;
1384 void(float style, string value) lightstyle
1387 void PF_lightstyle (void)
1394 style = G_FLOAT(OFS_PARM0);
1395 val = G_STRING(OFS_PARM1);
1397 // change the string in sv
1398 sv.lightstyles[style] = val;
1400 // send message to all clients on this server
1401 if (sv.state != ss_active)
1404 for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
1405 if (client->active || client->spawned)
1407 MSG_WriteChar (&client->message, svc_lightstyle);
1408 MSG_WriteChar (&client->message,style);
1409 MSG_WriteString (&client->message, val);
1416 f = G_FLOAT(OFS_PARM0);
1418 G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1420 G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1422 void PF_floor (void)
1424 G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
1428 G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
1437 void PF_checkbottom (void)
1439 G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0));
1447 void PF_pointcontents (void)
1449 G_FLOAT(OFS_RETURN) = Mod_PointInLeaf(G_VECTOR(OFS_PARM0), sv.worldmodel)->contents;
1456 entity nextent(entity)
1459 void PF_nextent (void)
1464 i = G_EDICTNUM(OFS_PARM0);
1468 if (i == sv.num_edicts)
1470 RETURN_EDICT(sv.edicts);
1486 Pick a vector for the player to shoot along
1487 vector aim(entity, missilespeed)
1492 edict_t *ent, *check, *bestent;
1493 vec3_t start, dir, end, bestdir;
1496 float dist, bestdist;
1499 ent = G_EDICT(OFS_PARM0);
1500 speed = G_FLOAT(OFS_PARM1);
1502 VectorCopy (ent->v.origin, start);
1505 // try sending a trace straight
1506 VectorCopy (pr_global_struct->v_forward, dir);
1507 VectorMA (start, 2048, dir, end);
1508 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1509 if (tr.ent && ((edict_t *)tr.ent)->v.takedamage == DAMAGE_AIM
1510 && (!teamplay.integer || ent->v.team <=0 || ent->v.team != ((edict_t *)tr.ent)->v.team) )
1512 VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
1517 // try all possible entities
1518 VectorCopy (dir, bestdir);
1519 bestdist = sv_aim.value;
1522 check = NEXT_EDICT(sv.edicts);
1523 for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
1525 if (check->v.takedamage != DAMAGE_AIM)
1529 if (teamplay.integer && ent->v.team > 0 && ent->v.team == check->v.team)
1530 continue; // don't aim at teammate
1531 for (j=0 ; j<3 ; j++)
1532 end[j] = check->v.origin[j]
1533 + 0.5*(check->v.mins[j] + check->v.maxs[j]);
1534 VectorSubtract (end, start, dir);
1535 VectorNormalize (dir);
1536 dist = DotProduct (dir, pr_global_struct->v_forward);
1537 if (dist < bestdist)
1538 continue; // to far to turn
1539 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1540 if (tr.ent == check)
1541 { // can shoot at this one
1549 VectorSubtract (bestent->v.origin, ent->v.origin, dir);
1550 dist = DotProduct (dir, pr_global_struct->v_forward);
1551 VectorScale (pr_global_struct->v_forward, dist, end);
1553 VectorNormalize (end);
1554 VectorCopy (end, G_VECTOR(OFS_RETURN));
1558 VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
1566 This was a major timewaster in progs, so it was converted to C
1569 void PF_changeyaw (void)
1572 float ideal, current, move, speed;
1574 ent = PROG_TO_EDICT(pr_global_struct->self);
1575 current = ANGLEMOD(ent->v.angles[1]);
1576 ideal = ent->v.ideal_yaw;
1577 speed = ent->v.yaw_speed;
1579 if (current == ideal)
1581 move = ideal - current;
1582 if (ideal > current)
1603 ent->v.angles[1] = ANGLEMOD (current + move);
1611 void PF_changepitch (void)
1614 float ideal, current, move, speed;
1617 ent = G_EDICT(OFS_PARM0);
1618 current = ANGLEMOD( ent->v.angles[0] );
1619 if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
1620 ideal = val->_float;
1623 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1626 if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
1627 speed = val->_float;
1630 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1634 if (current == ideal)
1636 move = ideal - current;
1637 if (ideal > current)
1658 ent->v.angles[0] = ANGLEMOD (current + move);
1662 ===============================================================================
1666 ===============================================================================
1669 #define MSG_BROADCAST 0 // unreliable to all
1670 #define MSG_ONE 1 // reliable to one (msg_entity)
1671 #define MSG_ALL 2 // reliable to all
1672 #define MSG_INIT 3 // write to the init string
1674 sizebuf_t *WriteDest (void)
1680 dest = G_FLOAT(OFS_PARM0);
1684 return &sv.datagram;
1687 ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
1688 entnum = NUM_FOR_EDICT(ent);
1689 if (entnum < 1 || entnum > svs.maxclients)
1690 PR_RunError ("WriteDest: not a client");
1691 return &svs.clients[entnum-1].message;
1694 return &sv.reliable_datagram;
1700 PR_RunError ("WriteDest: bad destination");
1707 void PF_WriteByte (void)
1709 MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
1712 void PF_WriteChar (void)
1714 MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
1717 void PF_WriteShort (void)
1719 MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
1722 void PF_WriteLong (void)
1724 MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
1727 void PF_WriteAngle (void)
1729 MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
1732 void PF_WriteCoord (void)
1734 MSG_WriteDPCoord (WriteDest(), G_FLOAT(OFS_PARM1));
1737 void PF_WriteString (void)
1739 MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
1743 void PF_WriteEntity (void)
1745 MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
1748 //=============================================================================
1750 int SV_ModelIndex (char *name);
1752 void PF_makestatic (void)
1757 ent = G_EDICT(OFS_PARM0);
1760 if (ent->v.modelindex >= 256 || ent->v.frame >= 256)
1765 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1766 MSG_WriteShort (&sv.signon, ent->v.modelindex);
1767 MSG_WriteShort (&sv.signon, ent->v.frame);
1771 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1772 MSG_WriteByte (&sv.signon, ent->v.modelindex);
1773 MSG_WriteByte (&sv.signon, ent->v.frame);
1776 MSG_WriteByte (&sv.signon, ent->v.colormap);
1777 MSG_WriteByte (&sv.signon, ent->v.skin);
1778 for (i=0 ; i<3 ; i++)
1780 MSG_WriteDPCoord(&sv.signon, ent->v.origin[i]);
1781 MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
1784 // throw the entity away now
1788 //=============================================================================
1795 void PF_setspawnparms (void)
1801 ent = G_EDICT(OFS_PARM0);
1802 i = NUM_FOR_EDICT(ent);
1803 if (i < 1 || i > svs.maxclients)
1804 PR_RunError ("Entity is not a client");
1806 // copy spawn parms out of the client_t
1807 client = svs.clients + (i-1);
1809 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1810 (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
1818 void PF_changelevel (void)
1822 // make sure we don't issue two changelevels
1823 if (svs.changelevel_issued)
1825 svs.changelevel_issued = true;
1827 s = G_STRING(OFS_PARM0);
1828 Cbuf_AddText (va("changelevel %s\n",s));
1833 G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
1838 G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
1843 G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
1850 Returns a vector of length < 1
1855 void PF_randomvec (void)
1860 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1861 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1862 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1864 while (DotProduct(temp, temp) >= 1);
1865 VectorCopy (temp, G_VECTOR(OFS_RETURN));
1868 void SV_LightPoint (vec3_t color, vec3_t p);
1873 Returns a color vector indicating the lighting at the requested point.
1875 (Internal Operation note: actually measures the light beneath the point, just like
1876 the model lighting on the client)
1881 void PF_GetLight (void)
1885 p = G_VECTOR(OFS_PARM0);
1886 SV_LightPoint (color, p);
1887 VectorCopy (color, G_VECTOR(OFS_RETURN));
1890 #define MAX_QC_CVARS 128
1891 cvar_t qc_cvar[MAX_QC_CVARS];
1894 void PF_registercvar (void)
1898 name = G_STRING(OFS_PARM0);
1899 value = G_STRING(OFS_PARM1);
1900 G_FLOAT(OFS_RETURN) = 0;
1901 // first check to see if it has already been defined
1902 if (Cvar_FindVar (name))
1905 // check for overlap with a command
1906 if (Cmd_Exists (name))
1908 Con_Printf ("PF_registercvar: %s is a command\n", name);
1912 if (currentqc_cvar >= MAX_QC_CVARS)
1913 PR_RunError ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
1915 // copy the name and value
1916 variable = &qc_cvar[currentqc_cvar++];
1917 variable->name = Z_Malloc (strlen(name)+1);
1918 strcpy (variable->name, name);
1919 variable->string = Z_Malloc (strlen(value)+1);
1920 strcpy (variable->string, value);
1921 variable->value = atof (value);
1923 Cvar_RegisterVariable(variable);
1924 G_FLOAT(OFS_RETURN) = 1; // success
1931 returns the minimum of two supplied floats
1938 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1940 G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1941 else if (pr_argc >= 3)
1944 float f = G_FLOAT(OFS_PARM0);
1945 for (i = 1;i < pr_argc;i++)
1946 if (G_FLOAT((OFS_PARM0+i*3)) < f)
1947 f = G_FLOAT((OFS_PARM0+i*3));
1948 G_FLOAT(OFS_RETURN) = f;
1951 PR_RunError("min: must supply at least 2 floats\n");
1958 returns the maximum of two supplied floats
1965 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1967 G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1968 else if (pr_argc >= 3)
1971 float f = G_FLOAT(OFS_PARM0);
1972 for (i = 1;i < pr_argc;i++)
1973 if (G_FLOAT((OFS_PARM0+i*3)) > f)
1974 f = G_FLOAT((OFS_PARM0+i*3));
1975 G_FLOAT(OFS_RETURN) = f;
1978 PR_RunError("max: must supply at least 2 floats\n");
1985 returns number bounded by supplied range
1987 min(min, value, max)
1990 void PF_bound (void)
1992 G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
1999 returns a raised to power b
2006 G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2013 copies data from one entity to another
2015 copyentity(src, dst)
2018 void PF_copyentity (void)
2021 in = G_EDICT(OFS_PARM0);
2022 out = G_EDICT(OFS_PARM1);
2023 memcpy(out, in, pr_edict_size);
2030 sets the color of a client and broadcasts the update to all connected clients
2032 setcolor(clientent, value)
2035 void PF_setcolor (void)
2040 entnum = G_EDICTNUM(OFS_PARM0);
2041 i = G_FLOAT(OFS_PARM1);
2043 if (entnum < 1 || entnum > svs.maxclients)
2045 Con_Printf ("tried to setcolor a non-client\n");
2049 client = &svs.clients[entnum-1];
2051 client->edict->v.team = (i & 15) + 1;
2053 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
2054 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
2055 MSG_WriteByte (&sv.reliable_datagram, i);
2062 effect(origin, modelname, startframe, framecount, framerate)
2065 void PF_effect (void)
2068 s = G_STRING(OFS_PARM1);
2070 PR_RunError("effect: no model specified\n");
2072 SV_StartEffect(G_VECTOR(OFS_PARM0), SV_ModelIndex(s), G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
2075 void PF_te_blood (void)
2077 if (G_FLOAT(OFS_PARM2) < 1)
2079 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2080 MSG_WriteByte(&sv.datagram, TE_BLOOD);
2082 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2083 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2084 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2086 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2087 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2088 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2090 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2093 void PF_te_bloodshower (void)
2095 if (G_FLOAT(OFS_PARM3) < 1)
2097 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2098 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
2100 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2101 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2102 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2104 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2105 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2106 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2108 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
2110 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2113 void PF_te_explosionrgb (void)
2115 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2116 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
2118 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2119 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2120 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2122 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
2123 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
2124 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
2127 void PF_te_particlecube (void)
2129 if (G_FLOAT(OFS_PARM3) < 1)
2131 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2132 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
2134 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2135 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2136 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2138 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2139 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2140 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2142 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2143 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2144 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2146 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2148 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2149 // gravity true/false
2150 MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
2152 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
2155 void PF_te_particlerain (void)
2157 if (G_FLOAT(OFS_PARM3) < 1)
2159 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2160 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
2162 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2163 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2164 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2166 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2167 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2168 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2170 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2171 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2172 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2174 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2176 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2179 void PF_te_particlesnow (void)
2181 if (G_FLOAT(OFS_PARM3) < 1)
2183 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2184 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
2186 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2187 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2188 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2190 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2191 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2192 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2194 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2195 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2196 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2198 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2200 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2203 void PF_te_spark (void)
2205 if (G_FLOAT(OFS_PARM2) < 1)
2207 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2208 MSG_WriteByte(&sv.datagram, TE_SPARK);
2210 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2211 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2212 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2214 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2215 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2216 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2218 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2221 void PF_te_gunshotquad (void)
2223 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2224 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
2226 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2227 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2228 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2231 void PF_te_spikequad (void)
2233 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2234 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
2236 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2237 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2238 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2241 void PF_te_superspikequad (void)
2243 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2244 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
2246 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2247 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2248 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2251 void PF_te_explosionquad (void)
2253 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2254 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2256 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2257 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2258 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2261 void PF_te_smallflash (void)
2263 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2264 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2266 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2267 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2268 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2271 void PF_te_customflash (void)
2273 if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2275 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2276 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2278 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2279 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2280 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2282 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2284 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255));
2286 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
2287 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
2288 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
2291 void PF_te_gunshot (void)
2293 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2294 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2296 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2297 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2298 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2301 void PF_te_spike (void)
2303 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2304 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2306 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2307 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2308 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2311 void PF_te_superspike (void)
2313 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2314 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2316 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2317 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2318 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2321 void PF_te_explosion (void)
2323 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2324 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2326 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2327 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2328 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2331 void PF_te_tarexplosion (void)
2333 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2334 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2336 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2337 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2338 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2341 void PF_te_wizspike (void)
2343 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2344 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2346 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2347 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2348 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2351 void PF_te_knightspike (void)
2353 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2354 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2356 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2357 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2358 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2361 void PF_te_lavasplash (void)
2363 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2364 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2366 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2367 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2368 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2371 void PF_te_teleport (void)
2373 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2374 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2376 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2377 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2378 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2381 void PF_te_explosion2 (void)
2383 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2384 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2386 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2387 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2388 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2390 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
2393 void PF_te_lightning1 (void)
2395 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2396 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2398 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2400 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2401 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2402 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2404 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2405 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2406 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2409 void PF_te_lightning2 (void)
2411 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2412 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2414 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2416 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2417 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2418 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2420 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2421 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2422 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2425 void PF_te_lightning3 (void)
2427 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2428 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2430 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2432 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2433 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2434 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2436 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2437 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2438 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2441 void PF_te_beam (void)
2443 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2444 MSG_WriteByte(&sv.datagram, TE_BEAM);
2446 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2448 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2449 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2450 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2452 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2453 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2454 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2457 void PF_te_plasmaburn (void)
2459 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2460 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2461 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2462 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2463 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2466 void PF_Fixme (void)
2468 PR_RunError ("unimplemented builtin"); // LordHavoc: was misspelled (bulitin)
2473 builtin_t pr_builtin[] =
2476 PF_makevectors, // void(entity e) makevectors = #1;
2477 PF_setorigin, // void(entity e, vector o) setorigin = #2;
2478 PF_setmodel, // void(entity e, string m) setmodel = #3;
2479 PF_setsize, // void(entity e, vector min, vector max) setsize = #4;
2480 PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5;
2481 PF_break, // void() break = #6;
2482 PF_random, // float() random = #7;
2483 PF_sound, // void(entity e, float chan, string samp) sound = #8;
2484 PF_normalize, // vector(vector v) normalize = #9;
2485 PF_error, // void(string e) error = #10;
2486 PF_objerror, // void(string e) objerror = #11;
2487 PF_vlen, // float(vector v) vlen = #12;
2488 PF_vectoyaw, // float(vector v) vectoyaw = #13;
2489 PF_Spawn, // entity() spawn = #14;
2490 PF_Remove, // void(entity e) remove = #15;
2491 PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16;
2492 PF_checkclient, // entity() clientlist = #17;
2493 PF_Find, // entity(entity start, .string fld, string match) find = #18;
2494 PF_precache_sound, // void(string s) precache_sound = #19;
2495 PF_precache_model, // void(string s) precache_model = #20;
2496 PF_stuffcmd, // void(entity client, string s)stuffcmd = #21;
2497 PF_findradius, // entity(vector org, float rad) findradius = #22;
2498 PF_bprint, // void(string s) bprint = #23;
2499 PF_sprint, // void(entity client, string s) sprint = #24;
2500 PF_dprint, // void(string s) dprint = #25;
2501 PF_ftos, // void(string s) ftos = #26;
2502 PF_vtos, // void(string s) vtos = #27;
2506 PF_eprint, // void(entity e) debug print an entire entity
2507 PF_walkmove, // float(float yaw, float dist) walkmove
2508 PF_Fixme, // float(float yaw, float dist) walkmove
2558 PF_precache_sound, // precache_sound2 is different only for qcc
2563 PF_Fixme, // #79 LordHavoc: dunno who owns 79-89, so these are just padding
2575 PF_tracebox, // #90 LordHavoc builtin range (9x)
2576 PF_randomvec, // #91
2578 PF_registercvar, // #93
2583 PF_FindFloat, // #98
2584 PF_checkextension, // #99
2585 #define a PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme,
2586 #define aa a a a a a a a a a a
2590 PF_copyentity, // #400 LordHavoc: builtin range (4xx)
2591 PF_setcolor, // #401
2592 PF_findchain, // #402
2593 PF_findchainfloat, // #403
2595 PF_te_blood, // #405
2596 PF_te_bloodshower, // #406
2597 PF_te_explosionrgb, // #407
2598 PF_te_particlecube, // #408
2599 PF_te_particlerain, // #409
2600 PF_te_particlesnow, // #410
2601 PF_te_spark, // #411
2602 PF_te_gunshotquad, // #412
2603 PF_te_spikequad, // #413
2604 PF_te_superspikequad, // #414
2605 PF_te_explosionquad, // #415
2606 PF_te_smallflash, // #416
2607 PF_te_customflash, // #417
2608 PF_te_gunshot, // #418
2609 PF_te_spike, // #419
2610 PF_te_superspike, // #420
2611 PF_te_explosion, // #421
2612 PF_te_tarexplosion, // #422
2613 PF_te_wizspike, // #423
2614 PF_te_knightspike, // #424
2615 PF_te_lavasplash, // #425
2616 PF_te_teleport, // #426
2617 PF_te_explosion2, // #427
2618 PF_te_lightning1, // #428
2619 PF_te_lightning2, // #429
2620 PF_te_lightning3, // #430
2622 PF_vectorvectors, // #432
2623 PF_te_plasmaburn, // #433
2626 builtin_t *pr_builtins = pr_builtin;
2627 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);