2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 cvar_t sv_aim = {CVAR_SAVE, "sv_aim", "2"}; //"0.93"}; // LordHavoc: disabled autoaim by default
25 #define RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e))
29 ===============================================================================
33 ===============================================================================
37 char *PF_VarString (int first)
43 for (i=first ; i<pr_argc ; i++)
45 strcat (out, G_STRING((OFS_PARM0+i*3)));
50 char *ENGINE_EXTENSIONS = "\
53 DP_ENT_DELTACOMPRESS \
65 DP_SV_DRAWONLYTOCLIENT \
66 DP_SV_NODRAWTOCLIENT \
67 DP_SV_EXTERIORMODELTOCLIENT \
82 DP_QC_FINDCHAINFLOAT \
93 qboolean checkextension(char *name)
98 for (e = ENGINE_EXTENSIONS;*e;e++)
105 while (*e && *e != ' ')
107 if (e - start == len)
108 if (!strncasecmp(start, name, len))
118 returns true if the extension is supported by the server
120 checkextension(extensionname)
123 void PF_checkextension (void)
125 G_FLOAT(OFS_RETURN) = checkextension(G_STRING(OFS_PARM0));
132 This is a TERMINAL error, which will kill off the entire server.
144 Con_Printf ("======SERVER ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
145 ed = PROG_TO_EDICT(pr_global_struct->self);
148 Host_Error ("Program error");
155 Dumps out self, then an error message. The program is aborted and self is
156 removed, but the level can continue.
161 void PF_objerror (void)
167 Con_Printf ("======OBJECT ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
168 ed = PROG_TO_EDICT(pr_global_struct->self);
178 Writes new values for v_forward, v_up, and v_right based on angles
182 void PF_makevectors (void)
184 AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
191 Writes new values for v_forward, v_up, and v_right based on the given forward vector
192 vectorvectors(vector, vector)
195 void PF_vectorvectors (void)
197 VectorNormalize2(G_VECTOR(OFS_PARM0), pr_global_struct->v_forward);
198 VectorVectors(pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
205 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.
207 setorigin (entity, origin)
210 void PF_setorigin (void)
215 e = G_EDICT(OFS_PARM0);
216 org = G_VECTOR(OFS_PARM1);
217 VectorCopy (org, e->v.origin);
218 SV_LinkEdict (e, false);
222 void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
226 for (i=0 ; i<3 ; i++)
228 PR_RunError ("backwards mins/maxs");
230 // set derived values
231 VectorCopy (min, e->v.mins);
232 VectorCopy (max, e->v.maxs);
233 VectorSubtract (max, min, e->v.size);
235 SV_LinkEdict (e, false);
242 the size box is rotated by the current angle
243 LordHavoc: no it isn't...
245 setsize (entity, minvector, maxvector)
248 void PF_setsize (void)
253 e = G_EDICT(OFS_PARM0);
254 min = G_VECTOR(OFS_PARM1);
255 max = G_VECTOR(OFS_PARM2);
256 SetMinMaxSize (e, min, max, false);
264 setmodel(entity, model)
267 void PF_setmodel (void)
274 e = G_EDICT(OFS_PARM0);
275 m = G_STRING(OFS_PARM1);
277 // check to see if model was properly precached
278 for (i=0, check = sv.model_precache ; *check ; i++, check++)
279 if (!strcmp(*check, m))
283 PR_RunError ("no precache: %s\n", m);
286 e->v.model = m - pr_strings;
289 mod = sv.models[ (int)e->v.modelindex];
292 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
294 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
301 broadcast print to everyone on server
306 void PF_bprint (void)
311 SV_BroadcastPrintf ("%s", s);
318 single print to a specific client
320 sprint(clientent, value)
323 void PF_sprint (void)
329 entnum = G_EDICTNUM(OFS_PARM0);
332 if (entnum < 1 || entnum > svs.maxclients)
334 Con_Printf ("tried to sprint to a non-client\n");
338 client = &svs.clients[entnum-1];
340 MSG_WriteChar (&client->message,svc_print);
341 MSG_WriteString (&client->message, s );
349 single print to a specific client
351 centerprint(clientent, value)
354 void PF_centerprint (void)
360 entnum = G_EDICTNUM(OFS_PARM0);
363 if (entnum < 1 || entnum > svs.maxclients)
365 Con_Printf ("tried to sprint to a non-client\n");
369 client = &svs.clients[entnum-1];
371 MSG_WriteChar (&client->message,svc_centerprint);
372 MSG_WriteString (&client->message, s );
380 vector normalize(vector)
383 void PF_normalize (void)
389 value1 = G_VECTOR(OFS_PARM0);
391 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
395 newvalue[0] = newvalue[1] = newvalue[2] = 0;
399 newvalue[0] = value1[0] * new;
400 newvalue[1] = value1[1] * new;
401 newvalue[2] = value1[2] * new;
404 VectorCopy (newvalue, G_VECTOR(OFS_RETURN));
419 value1 = G_VECTOR(OFS_PARM0);
421 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
424 G_FLOAT(OFS_RETURN) = new;
431 float vectoyaw(vector)
434 void PF_vectoyaw (void)
439 value1 = G_VECTOR(OFS_PARM0);
441 if (value1[1] == 0 && value1[0] == 0)
445 yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
450 G_FLOAT(OFS_RETURN) = yaw;
458 vector vectoangles(vector)
461 void PF_vectoangles (void)
467 value1 = G_VECTOR(OFS_PARM0);
469 if (value1[1] == 0 && value1[0] == 0)
479 // LordHavoc: optimized a bit
482 yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
486 else if (value1[1] > 0)
491 forward = sqrt(value1[0]*value1[0] + value1[1]*value1[1]);
492 pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
497 G_FLOAT(OFS_RETURN+0) = pitch;
498 G_FLOAT(OFS_RETURN+1) = yaw;
499 G_FLOAT(OFS_RETURN+2) = 0;
506 Returns a number from 0<= num < 1
511 void PF_random (void)
515 num = (rand ()&0x7fff) / ((float)0x7fff);
517 G_FLOAT(OFS_RETURN) = num;
524 particle(origin, color, count)
527 void PF_particle (void)
533 org = G_VECTOR(OFS_PARM0);
534 dir = G_VECTOR(OFS_PARM1);
535 color = G_FLOAT(OFS_PARM2);
536 count = G_FLOAT(OFS_PARM3);
537 SV_StartParticle (org, dir, color, count);
547 void PF_ambientsound (void)
552 float vol, attenuation;
553 int i, soundnum, large;
555 pos = G_VECTOR (OFS_PARM0);
556 samp = G_STRING(OFS_PARM1);
557 vol = G_FLOAT(OFS_PARM2);
558 attenuation = G_FLOAT(OFS_PARM3);
560 // check to see if samp was properly precached
561 for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++)
562 if (!strcmp(*check,samp))
567 Con_Printf ("no precache: %s\n", samp);
575 // add an svc_spawnambient command to the level signon packet
578 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
580 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
582 for (i=0 ; i<3 ; i++)
583 MSG_WriteDPCoord(&sv.signon, pos[i]);
586 MSG_WriteShort (&sv.signon, soundnum);
588 MSG_WriteByte (&sv.signon, soundnum);
590 MSG_WriteByte (&sv.signon, vol*255);
591 MSG_WriteByte (&sv.signon, attenuation*64);
599 Each entity can have eight independant sound sources, like voice,
602 Channel 0 is an auto-allocate channel, the others override anything
603 already running on that entity/channel pair.
605 An attenuation of 0 will play full volume everywhere in the level.
606 Larger attenuations will drop off.
618 entity = G_EDICT(OFS_PARM0);
619 channel = G_FLOAT(OFS_PARM1);
620 sample = G_STRING(OFS_PARM2);
621 volume = G_FLOAT(OFS_PARM3) * 255;
622 attenuation = G_FLOAT(OFS_PARM4);
624 if (volume < 0 || volume > 255)
625 Host_Error ("SV_StartSound: volume = %i", volume);
627 if (attenuation < 0 || attenuation > 4)
628 Host_Error ("SV_StartSound: attenuation = %f", attenuation);
630 if (channel < 0 || channel > 7)
631 Host_Error ("SV_StartSound: channel = %i", channel);
633 SV_StartSound (entity, channel, sample, volume, attenuation);
645 PR_RunError ("break statement");
652 Used for use tracing and shot targeting
653 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
654 if the tryents flag is set.
656 traceline (vector1, vector2, tryents)
659 void PF_traceline (void)
666 v1 = G_VECTOR(OFS_PARM0);
667 v2 = G_VECTOR(OFS_PARM1);
668 nomonsters = G_FLOAT(OFS_PARM2);
669 ent = G_EDICT(OFS_PARM3);
671 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters ? MOVE_NOMONSTERS : MOVE_NORMAL, ent);
673 pr_global_struct->trace_allsolid = trace.allsolid;
674 pr_global_struct->trace_startsolid = trace.startsolid;
675 pr_global_struct->trace_fraction = trace.fraction;
676 pr_global_struct->trace_inwater = trace.inwater;
677 pr_global_struct->trace_inopen = trace.inopen;
678 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
679 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
680 pr_global_struct->trace_plane_dist = trace.plane.dist;
682 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
684 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
685 // FIXME: add trace_endcontents
693 Used for use tracing and shot targeting
694 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
695 if the tryents flag is set.
697 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
700 // LordHavoc: added this for my own use, VERY useful, similar to traceline
701 void PF_tracebox (void)
703 float *v1, *v2, *m1, *m2;
708 v1 = G_VECTOR(OFS_PARM0);
709 m1 = G_VECTOR(OFS_PARM1);
710 m2 = G_VECTOR(OFS_PARM2);
711 v2 = G_VECTOR(OFS_PARM3);
712 nomonsters = G_FLOAT(OFS_PARM4);
713 ent = G_EDICT(OFS_PARM5);
715 trace = SV_Move (v1, m1, m2, v2, nomonsters ? MOVE_NOMONSTERS : MOVE_NORMAL, ent);
717 pr_global_struct->trace_allsolid = trace.allsolid;
718 pr_global_struct->trace_startsolid = trace.startsolid;
719 pr_global_struct->trace_fraction = trace.fraction;
720 pr_global_struct->trace_inwater = trace.inwater;
721 pr_global_struct->trace_inopen = trace.inopen;
722 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
723 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
724 pr_global_struct->trace_plane_dist = trace.plane.dist;
726 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
728 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
731 extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore);
732 void PF_TraceToss (void)
738 ent = G_EDICT(OFS_PARM0);
739 ignore = G_EDICT(OFS_PARM1);
741 trace = SV_Trace_Toss (ent, ignore);
743 pr_global_struct->trace_allsolid = trace.allsolid;
744 pr_global_struct->trace_startsolid = trace.startsolid;
745 pr_global_struct->trace_fraction = trace.fraction;
746 pr_global_struct->trace_inwater = trace.inwater;
747 pr_global_struct->trace_inopen = trace.inopen;
748 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
749 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
750 pr_global_struct->trace_plane_dist = trace.plane.dist;
752 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
754 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
762 Returns true if the given entity can move to the given position from it's
763 current position by walking or rolling.
765 scalar checkpos (entity, vector)
768 void PF_checkpos (void)
772 //============================================================================
774 qbyte checkpvs[MAX_MAP_LEAFS/8];
776 int PF_newcheckclient (int check)
784 // cycle to the next one
788 if (check > svs.maxclients)
789 check = svs.maxclients;
791 if (check == svs.maxclients)
798 if (i == svs.maxclients+1)
804 break; // didn't find anything else
808 if (ent->v.health <= 0)
810 if ((int)ent->v.flags & FL_NOTARGET)
813 // anything that is a client, or has a client as an enemy
817 // get the PVS for the entity
818 VectorAdd (ent->v.origin, ent->v.view_ofs, org);
819 leaf = Mod_PointInLeaf (org, sv.worldmodel);
820 pvs = Mod_LeafPVS (leaf, sv.worldmodel);
821 memcpy (checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 );
830 Returns a client (or object that has a client enemy) that would be a
833 If there is more than one valid option, they are cycled each frame
835 If (self.origin + self.viewofs) is not in the PVS of the current target,
836 it is not returned at all.
841 int c_invis, c_notvis;
842 void PF_checkclient (void)
849 // find a new check if on a new frame
850 if (sv.time - sv.lastchecktime >= 0.1)
852 sv.lastcheck = PF_newcheckclient (sv.lastcheck);
853 sv.lastchecktime = sv.time;
856 // return check if it might be visible
857 ent = EDICT_NUM(sv.lastcheck);
858 if (ent->free || ent->v.health <= 0)
860 RETURN_EDICT(sv.edicts);
864 // if current entity can't possibly see the check entity, return 0
865 self = PROG_TO_EDICT(pr_global_struct->self);
866 VectorAdd (self->v.origin, self->v.view_ofs, view);
867 leaf = Mod_PointInLeaf (view, sv.worldmodel);
868 l = (leaf - sv.worldmodel->leafs) - 1;
869 if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
872 RETURN_EDICT(sv.edicts);
876 // might be able to see it
881 //============================================================================
888 Sends text over to the client's execution buffer
890 stuffcmd (clientent, value)
893 void PF_stuffcmd (void)
899 entnum = G_EDICTNUM(OFS_PARM0);
900 if (entnum < 1 || entnum > svs.maxclients)
901 PR_RunError ("Parm 0 not a client");
902 str = G_STRING(OFS_PARM1);
905 host_client = &svs.clients[entnum-1];
906 Host_ClientCommands ("%s", str);
914 Sends text over to the client's execution buffer
919 void PF_localcmd (void)
923 str = G_STRING(OFS_PARM0);
938 str = G_STRING(OFS_PARM0);
940 G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str);
950 void PF_cvar_set (void)
954 var = G_STRING(OFS_PARM0);
955 val = G_STRING(OFS_PARM1);
964 Returns a chain of entities that have origins within a spherical area
966 findradius (origin, radius)
969 void PF_findradius (void)
971 edict_t *ent, *chain;
978 chain = (edict_t *)sv.edicts;
980 org = G_VECTOR(OFS_PARM0);
981 radius = G_FLOAT(OFS_PARM1);
982 radius2 = radius * radius;
984 ent = NEXT_EDICT(sv.edicts);
985 for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
989 if (ent->v.solid == SOLID_NOT)
992 // LordHavoc: compare against bounding box rather than center,
993 // and use DotProduct instead of Length, major speedup
994 eorg[0] = (org[0] - ent->v.origin[0]) - bound(ent->v.mins[0], (org[0] - ent->v.origin[0]), ent->v.maxs[0]);
995 eorg[1] = (org[1] - ent->v.origin[1]) - bound(ent->v.mins[1], (org[1] - ent->v.origin[1]), ent->v.maxs[1]);
996 eorg[2] = (org[2] - ent->v.origin[2]) - bound(ent->v.mins[2], (org[2] - ent->v.origin[2]), ent->v.maxs[2]);
997 if (DotProduct(eorg, eorg) > radius2)
1000 ent->v.chain = EDICT_TO_PROG(chain);
1004 RETURN_EDICT(chain);
1013 void PF_dprint (void)
1015 Con_DPrintf ("%s",PF_VarString(0));
1018 // LordHavoc: added this to semi-fix the problem of using many ftos calls in a print
1019 #define STRINGTEMP_BUFFERS 16
1020 #define STRINGTEMP_LENGTH 128
1021 static char pr_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH];
1022 static int pr_string_tempindex = 0;
1024 static char *PR_GetTempString(void)
1027 s = pr_string_temp[pr_string_tempindex];
1028 pr_string_tempindex = (pr_string_tempindex + 1) % STRINGTEMP_BUFFERS;
1036 v = G_FLOAT(OFS_PARM0);
1038 s = PR_GetTempString();
1039 // LordHavoc: ftos improvement
1040 sprintf (s, "%g", v);
1041 G_INT(OFS_RETURN) = s - pr_strings;
1047 v = G_FLOAT(OFS_PARM0);
1048 G_FLOAT(OFS_RETURN) = fabs(v);
1054 s = PR_GetTempString();
1055 sprintf (s, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
1056 G_INT(OFS_RETURN) = s - pr_strings;
1062 s = PR_GetTempString();
1063 sprintf (s, "entity %i", G_EDICTNUM(OFS_PARM0));
1064 G_INT(OFS_RETURN) = s - pr_strings;
1067 void PF_Spawn (void)
1074 void PF_Remove (void)
1078 ed = G_EDICT(OFS_PARM0);
1079 if (ed == sv.edicts)
1080 PR_RunError("remove: tried to remove world\n");
1081 if (NUM_FOR_EDICT(ed) <= svs.maxclients)
1082 PR_RunError("remove: tried to remove a client\n");
1087 // entity (entity start, .string field, string match) find = #5;
1095 e = G_EDICTNUM(OFS_PARM0);
1096 f = G_INT(OFS_PARM1);
1097 s = G_STRING(OFS_PARM2);
1100 RETURN_EDICT(sv.edicts);
1104 for (e++ ; e < sv.num_edicts ; e++)
1119 RETURN_EDICT(sv.edicts);
1122 // LordHavoc: added this for searching float, int, and entity reference fields
1123 void PF_FindFloat (void)
1130 e = G_EDICTNUM(OFS_PARM0);
1131 f = G_INT(OFS_PARM1);
1132 s = G_FLOAT(OFS_PARM2);
1134 for (e++ ; e < sv.num_edicts ; e++)
1139 if (E_FLOAT(ed,f) == s)
1146 RETURN_EDICT(sv.edicts);
1149 // chained search for strings in entity fields
1150 // entity(.string field, string match) findchain = #402;
1151 void PF_findchain (void)
1156 edict_t *ent, *chain;
1158 chain = (edict_t *)sv.edicts;
1160 f = G_INT(OFS_PARM0);
1161 s = G_STRING(OFS_PARM1);
1164 RETURN_EDICT(sv.edicts);
1168 ent = NEXT_EDICT(sv.edicts);
1169 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1173 t = E_STRING(ent,f);
1179 ent->v.chain = EDICT_TO_PROG(chain);
1183 RETURN_EDICT(chain);
1186 // LordHavoc: chained search for float, int, and entity reference fields
1187 // entity(.string field, float match) findchainfloat = #403;
1188 void PF_findchainfloat (void)
1193 edict_t *ent, *chain;
1195 chain = (edict_t *)sv.edicts;
1197 f = G_INT(OFS_PARM0);
1198 s = G_FLOAT(OFS_PARM1);
1200 ent = NEXT_EDICT(sv.edicts);
1201 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1205 if (E_FLOAT(ent,f) != s)
1208 ent->v.chain = EDICT_TO_PROG(chain);
1212 RETURN_EDICT(chain);
1215 void PR_CheckEmptyString (char *s)
1218 PR_RunError ("Bad string");
1221 void PF_precache_file (void)
1222 { // precache_file is only used to copy files with qcc, it does nothing
1223 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1226 void PF_precache_sound (void)
1231 if (sv.state != ss_loading)
1232 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1234 s = G_STRING(OFS_PARM0);
1235 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1236 PR_CheckEmptyString (s);
1238 for (i=0 ; i<MAX_SOUNDS ; i++)
1240 if (!sv.sound_precache[i])
1242 sv.sound_precache[i] = s;
1245 if (!strcmp(sv.sound_precache[i], s))
1248 PR_RunError ("PF_precache_sound: overflow");
1251 void PF_precache_model (void)
1256 if (sv.state != ss_loading)
1257 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1259 s = G_STRING(OFS_PARM0);
1260 if (sv.worldmodel->ishlbsp && ((!s) || (!s[0])))
1262 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1263 PR_CheckEmptyString (s);
1265 for (i=0 ; i<MAX_MODELS ; i++)
1267 if (!sv.model_precache[i])
1269 sv.model_precache[i] = s;
1270 sv.models[i] = Mod_ForName (s, true, false, false);
1273 if (!strcmp(sv.model_precache[i], s))
1276 PR_RunError ("PF_precache_model: overflow");
1280 void PF_coredump (void)
1285 void PF_traceon (void)
1290 void PF_traceoff (void)
1295 void PF_eprint (void)
1297 ED_PrintNum (G_EDICTNUM(OFS_PARM0));
1304 float(float yaw, float dist) walkmove
1307 void PF_walkmove (void)
1315 ent = PROG_TO_EDICT(pr_global_struct->self);
1316 yaw = G_FLOAT(OFS_PARM0);
1317 dist = G_FLOAT(OFS_PARM1);
1319 if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1321 G_FLOAT(OFS_RETURN) = 0;
1325 yaw = yaw*M_PI*2 / 360;
1327 move[0] = cos(yaw)*dist;
1328 move[1] = sin(yaw)*dist;
1331 // save program state, because SV_movestep may call other progs
1332 oldf = pr_xfunction;
1333 oldself = pr_global_struct->self;
1335 G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
1338 // restore program state
1339 pr_xfunction = oldf;
1340 pr_global_struct->self = oldself;
1350 void PF_droptofloor (void)
1356 ent = PROG_TO_EDICT(pr_global_struct->self);
1358 VectorCopy (ent->v.origin, end);
1361 trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
1363 if (trace.fraction == 1 || trace.allsolid)
1364 G_FLOAT(OFS_RETURN) = 0;
1367 VectorCopy (trace.endpos, ent->v.origin);
1368 SV_LinkEdict (ent, false);
1369 ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
1370 ent->v.groundentity = EDICT_TO_PROG(trace.ent);
1371 G_FLOAT(OFS_RETURN) = 1;
1372 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1373 ent->suspendedinairflag = true;
1381 void(float style, string value) lightstyle
1384 void PF_lightstyle (void)
1391 style = G_FLOAT(OFS_PARM0);
1392 val = G_STRING(OFS_PARM1);
1394 // change the string in sv
1395 sv.lightstyles[style] = val;
1397 // send message to all clients on this server
1398 if (sv.state != ss_active)
1401 for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
1402 if (client->active || client->spawned)
1404 MSG_WriteChar (&client->message, svc_lightstyle);
1405 MSG_WriteChar (&client->message,style);
1406 MSG_WriteString (&client->message, val);
1413 f = G_FLOAT(OFS_PARM0);
1415 G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1417 G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1419 void PF_floor (void)
1421 G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
1425 G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
1434 void PF_checkbottom (void)
1436 G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0));
1444 void PF_pointcontents (void)
1446 G_FLOAT(OFS_RETURN) = Mod_PointInLeaf(G_VECTOR(OFS_PARM0), sv.worldmodel)->contents;
1453 entity nextent(entity)
1456 void PF_nextent (void)
1461 i = G_EDICTNUM(OFS_PARM0);
1465 if (i == sv.num_edicts)
1467 RETURN_EDICT(sv.edicts);
1483 Pick a vector for the player to shoot along
1484 vector aim(entity, missilespeed)
1489 edict_t *ent, *check, *bestent;
1490 vec3_t start, dir, end, bestdir;
1493 float dist, bestdist;
1496 ent = G_EDICT(OFS_PARM0);
1497 speed = G_FLOAT(OFS_PARM1);
1499 VectorCopy (ent->v.origin, start);
1502 // try sending a trace straight
1503 VectorCopy (pr_global_struct->v_forward, dir);
1504 VectorMA (start, 2048, dir, end);
1505 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1506 if (tr.ent && ((edict_t *)tr.ent)->v.takedamage == DAMAGE_AIM
1507 && (!teamplay.integer || ent->v.team <=0 || ent->v.team != ((edict_t *)tr.ent)->v.team) )
1509 VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
1514 // try all possible entities
1515 VectorCopy (dir, bestdir);
1516 bestdist = sv_aim.value;
1519 check = NEXT_EDICT(sv.edicts);
1520 for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
1522 if (check->v.takedamage != DAMAGE_AIM)
1526 if (teamplay.integer && ent->v.team > 0 && ent->v.team == check->v.team)
1527 continue; // don't aim at teammate
1528 for (j=0 ; j<3 ; j++)
1529 end[j] = check->v.origin[j]
1530 + 0.5*(check->v.mins[j] + check->v.maxs[j]);
1531 VectorSubtract (end, start, dir);
1532 VectorNormalize (dir);
1533 dist = DotProduct (dir, pr_global_struct->v_forward);
1534 if (dist < bestdist)
1535 continue; // to far to turn
1536 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1537 if (tr.ent == check)
1538 { // can shoot at this one
1546 VectorSubtract (bestent->v.origin, ent->v.origin, dir);
1547 dist = DotProduct (dir, pr_global_struct->v_forward);
1548 VectorScale (pr_global_struct->v_forward, dist, end);
1550 VectorNormalize (end);
1551 VectorCopy (end, G_VECTOR(OFS_RETURN));
1555 VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
1563 This was a major timewaster in progs, so it was converted to C
1566 void PF_changeyaw (void)
1569 float ideal, current, move, speed;
1571 ent = PROG_TO_EDICT(pr_global_struct->self);
1572 current = ANGLEMOD(ent->v.angles[1]);
1573 ideal = ent->v.ideal_yaw;
1574 speed = ent->v.yaw_speed;
1576 if (current == ideal)
1578 move = ideal - current;
1579 if (ideal > current)
1600 ent->v.angles[1] = ANGLEMOD (current + move);
1608 void PF_changepitch (void)
1611 float ideal, current, move, speed;
1614 ent = G_EDICT(OFS_PARM0);
1615 current = ANGLEMOD( ent->v.angles[0] );
1616 if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
1617 ideal = val->_float;
1620 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1623 if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
1624 speed = val->_float;
1627 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1631 if (current == ideal)
1633 move = ideal - current;
1634 if (ideal > current)
1655 ent->v.angles[0] = ANGLEMOD (current + move);
1659 ===============================================================================
1663 ===============================================================================
1666 #define MSG_BROADCAST 0 // unreliable to all
1667 #define MSG_ONE 1 // reliable to one (msg_entity)
1668 #define MSG_ALL 2 // reliable to all
1669 #define MSG_INIT 3 // write to the init string
1671 sizebuf_t *WriteDest (void)
1677 dest = G_FLOAT(OFS_PARM0);
1681 return &sv.datagram;
1684 ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
1685 entnum = NUM_FOR_EDICT(ent);
1686 if (entnum < 1 || entnum > svs.maxclients)
1687 PR_RunError ("WriteDest: not a client");
1688 return &svs.clients[entnum-1].message;
1691 return &sv.reliable_datagram;
1697 PR_RunError ("WriteDest: bad destination");
1704 void PF_WriteByte (void)
1706 MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
1709 void PF_WriteChar (void)
1711 MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
1714 void PF_WriteShort (void)
1716 MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
1719 void PF_WriteLong (void)
1721 MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
1724 void PF_WriteAngle (void)
1726 MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
1729 void PF_WriteCoord (void)
1731 MSG_WriteDPCoord (WriteDest(), G_FLOAT(OFS_PARM1));
1734 void PF_WriteString (void)
1736 MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
1740 void PF_WriteEntity (void)
1742 MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
1745 //=============================================================================
1747 int SV_ModelIndex (char *name);
1749 void PF_makestatic (void)
1754 ent = G_EDICT(OFS_PARM0);
1757 if (ent->v.modelindex >= 256 || ent->v.frame >= 256)
1762 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1763 MSG_WriteShort (&sv.signon, ent->v.modelindex);
1764 MSG_WriteShort (&sv.signon, ent->v.frame);
1768 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1769 MSG_WriteByte (&sv.signon, ent->v.modelindex);
1770 MSG_WriteByte (&sv.signon, ent->v.frame);
1773 MSG_WriteByte (&sv.signon, ent->v.colormap);
1774 MSG_WriteByte (&sv.signon, ent->v.skin);
1775 for (i=0 ; i<3 ; i++)
1777 MSG_WriteDPCoord(&sv.signon, ent->v.origin[i]);
1778 MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
1781 // throw the entity away now
1785 //=============================================================================
1792 void PF_setspawnparms (void)
1798 ent = G_EDICT(OFS_PARM0);
1799 i = NUM_FOR_EDICT(ent);
1800 if (i < 1 || i > svs.maxclients)
1801 PR_RunError ("Entity is not a client");
1803 // copy spawn parms out of the client_t
1804 client = svs.clients + (i-1);
1806 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1807 (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
1815 void PF_changelevel (void)
1819 // make sure we don't issue two changelevels
1820 if (svs.changelevel_issued)
1822 svs.changelevel_issued = true;
1824 s = G_STRING(OFS_PARM0);
1825 Cbuf_AddText (va("changelevel %s\n",s));
1830 G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
1835 G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
1840 G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
1847 Returns a vector of length < 1
1852 void PF_randomvec (void)
1857 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1858 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1859 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1861 while (DotProduct(temp, temp) >= 1);
1862 VectorCopy (temp, G_VECTOR(OFS_RETURN));
1865 void SV_LightPoint (vec3_t color, vec3_t p);
1870 Returns a color vector indicating the lighting at the requested point.
1872 (Internal Operation note: actually measures the light beneath the point, just like
1873 the model lighting on the client)
1878 void PF_GetLight (void)
1882 p = G_VECTOR(OFS_PARM0);
1883 SV_LightPoint (color, p);
1884 VectorCopy (color, G_VECTOR(OFS_RETURN));
1887 #define MAX_QC_CVARS 128
1888 cvar_t qc_cvar[MAX_QC_CVARS];
1891 void PF_registercvar (void)
1895 name = G_STRING(OFS_PARM0);
1896 value = G_STRING(OFS_PARM1);
1897 G_FLOAT(OFS_RETURN) = 0;
1898 // first check to see if it has already been defined
1899 if (Cvar_FindVar (name))
1902 // check for overlap with a command
1903 if (Cmd_Exists (name))
1905 Con_Printf ("PF_registercvar: %s is a command\n", name);
1909 if (currentqc_cvar >= MAX_QC_CVARS)
1910 PR_RunError ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
1912 // copy the name and value
1913 variable = &qc_cvar[currentqc_cvar++];
1914 variable->name = Z_Malloc (strlen(name)+1);
1915 strcpy (variable->name, name);
1916 variable->string = Z_Malloc (strlen(value)+1);
1917 strcpy (variable->string, value);
1918 variable->value = atof (value);
1920 // link the variable in
1921 variable->next = cvar_vars;
1922 cvar_vars = variable;
1923 G_FLOAT(OFS_RETURN) = 1; // success
1930 returns the minimum of two supplied floats
1937 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1939 G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1940 else if (pr_argc >= 3)
1943 float f = G_FLOAT(OFS_PARM0);
1944 for (i = 1;i < pr_argc;i++)
1945 if (G_FLOAT((OFS_PARM0+i*3)) < f)
1946 f = G_FLOAT((OFS_PARM0+i*3));
1947 G_FLOAT(OFS_RETURN) = f;
1950 PR_RunError("min: must supply at least 2 floats\n");
1957 returns the maximum of two supplied floats
1964 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1966 G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1967 else if (pr_argc >= 3)
1970 float f = G_FLOAT(OFS_PARM0);
1971 for (i = 1;i < pr_argc;i++)
1972 if (G_FLOAT((OFS_PARM0+i*3)) > f)
1973 f = G_FLOAT((OFS_PARM0+i*3));
1974 G_FLOAT(OFS_RETURN) = f;
1977 PR_RunError("max: must supply at least 2 floats\n");
1984 returns number bounded by supplied range
1986 min(min, value, max)
1989 void PF_bound (void)
1991 G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
1998 returns a raised to power b
2005 G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2012 copies data from one entity to another
2014 copyentity(src, dst)
2017 void PF_copyentity (void)
2020 in = G_EDICT(OFS_PARM0);
2021 out = G_EDICT(OFS_PARM1);
2022 memcpy(out, in, pr_edict_size);
2029 sets the color of a client and broadcasts the update to all connected clients
2031 setcolor(clientent, value)
2034 void PF_setcolor (void)
2039 entnum = G_EDICTNUM(OFS_PARM0);
2040 i = G_FLOAT(OFS_PARM1);
2042 if (entnum < 1 || entnum > svs.maxclients)
2044 Con_Printf ("tried to setcolor a non-client\n");
2048 client = &svs.clients[entnum-1];
2050 client->edict->v.team = (i & 15) + 1;
2052 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
2053 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
2054 MSG_WriteByte (&sv.reliable_datagram, i);
2061 effect(origin, modelname, startframe, framecount, framerate)
2064 void PF_effect (void)
2067 s = G_STRING(OFS_PARM1);
2069 PR_RunError("effect: no model specified\n");
2071 SV_StartEffect(G_VECTOR(OFS_PARM0), SV_ModelIndex(s), G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
2074 void PF_te_blood (void)
2076 if (G_FLOAT(OFS_PARM2) < 1)
2078 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2079 MSG_WriteByte(&sv.datagram, TE_BLOOD);
2081 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2082 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2083 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2085 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2086 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2087 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2089 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2092 void PF_te_bloodshower (void)
2094 if (G_FLOAT(OFS_PARM3) < 1)
2096 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2097 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
2099 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2100 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2101 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2103 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2104 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2105 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2107 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
2109 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2112 void PF_te_explosionrgb (void)
2114 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2115 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
2117 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2118 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2119 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2121 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
2122 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
2123 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
2126 void PF_te_particlecube (void)
2128 if (G_FLOAT(OFS_PARM3) < 1)
2130 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2131 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
2133 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2134 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2135 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2137 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2138 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2139 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2141 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2142 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2143 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2145 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2147 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2148 // gravity true/false
2149 MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
2151 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
2154 void PF_te_particlerain (void)
2156 if (G_FLOAT(OFS_PARM3) < 1)
2158 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2159 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
2161 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2162 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2163 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2165 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2166 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2167 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2169 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2170 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2171 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2173 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2175 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2178 void PF_te_particlesnow (void)
2180 if (G_FLOAT(OFS_PARM3) < 1)
2182 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2183 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
2185 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2186 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2187 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2189 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2190 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2191 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2193 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2194 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2195 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2197 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2199 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2202 void PF_te_spark (void)
2204 if (G_FLOAT(OFS_PARM2) < 1)
2206 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2207 MSG_WriteByte(&sv.datagram, TE_SPARK);
2209 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2210 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2211 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2213 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2214 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2215 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2217 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2220 void PF_te_gunshotquad (void)
2222 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2223 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
2225 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2226 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2227 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2230 void PF_te_spikequad (void)
2232 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2233 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
2235 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2236 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2237 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2240 void PF_te_superspikequad (void)
2242 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2243 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
2245 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2246 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2247 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2250 void PF_te_explosionquad (void)
2252 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2253 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2255 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2256 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2257 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2260 void PF_te_smallflash (void)
2262 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2263 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2265 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2266 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2267 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2270 void PF_te_customflash (void)
2272 if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2274 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2275 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2277 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2278 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2279 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2281 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2283 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255));
2285 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
2286 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
2287 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
2290 void PF_te_gunshot (void)
2292 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2293 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2295 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2296 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2297 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2300 void PF_te_spike (void)
2302 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2303 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2305 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2306 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2307 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2310 void PF_te_superspike (void)
2312 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2313 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2315 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2316 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2317 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2320 void PF_te_explosion (void)
2322 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2323 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2325 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2326 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2327 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2330 void PF_te_tarexplosion (void)
2332 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2333 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2335 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2336 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2337 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2340 void PF_te_wizspike (void)
2342 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2343 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2345 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2346 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2347 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2350 void PF_te_knightspike (void)
2352 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2353 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2355 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2356 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2357 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2360 void PF_te_lavasplash (void)
2362 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2363 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2365 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2366 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2367 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2370 void PF_te_teleport (void)
2372 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2373 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2375 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2376 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2377 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2380 void PF_te_explosion2 (void)
2382 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2383 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2385 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2386 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2387 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2389 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
2392 void PF_te_lightning1 (void)
2394 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2395 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2397 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2399 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2400 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2401 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2403 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2404 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2405 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2408 void PF_te_lightning2 (void)
2410 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2411 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2413 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2415 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2416 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2417 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2419 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2420 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2421 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2424 void PF_te_lightning3 (void)
2426 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2427 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2429 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2431 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2432 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2433 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2435 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2436 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2437 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2440 void PF_te_beam (void)
2442 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2443 MSG_WriteByte(&sv.datagram, TE_BEAM);
2445 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2447 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2448 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2449 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2451 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2452 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2453 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2456 void PF_te_plasmaburn (void)
2458 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2459 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2460 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2461 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2462 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2465 void PF_Fixme (void)
2467 PR_RunError ("unimplemented builtin"); // LordHavoc: was misspelled (bulitin)
2472 builtin_t pr_builtin[] =
2475 PF_makevectors, // void(entity e) makevectors = #1;
2476 PF_setorigin, // void(entity e, vector o) setorigin = #2;
2477 PF_setmodel, // void(entity e, string m) setmodel = #3;
2478 PF_setsize, // void(entity e, vector min, vector max) setsize = #4;
2479 PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5;
2480 PF_break, // void() break = #6;
2481 PF_random, // float() random = #7;
2482 PF_sound, // void(entity e, float chan, string samp) sound = #8;
2483 PF_normalize, // vector(vector v) normalize = #9;
2484 PF_error, // void(string e) error = #10;
2485 PF_objerror, // void(string e) objerror = #11;
2486 PF_vlen, // float(vector v) vlen = #12;
2487 PF_vectoyaw, // float(vector v) vectoyaw = #13;
2488 PF_Spawn, // entity() spawn = #14;
2489 PF_Remove, // void(entity e) remove = #15;
2490 PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16;
2491 PF_checkclient, // entity() clientlist = #17;
2492 PF_Find, // entity(entity start, .string fld, string match) find = #18;
2493 PF_precache_sound, // void(string s) precache_sound = #19;
2494 PF_precache_model, // void(string s) precache_model = #20;
2495 PF_stuffcmd, // void(entity client, string s)stuffcmd = #21;
2496 PF_findradius, // entity(vector org, float rad) findradius = #22;
2497 PF_bprint, // void(string s) bprint = #23;
2498 PF_sprint, // void(entity client, string s) sprint = #24;
2499 PF_dprint, // void(string s) dprint = #25;
2500 PF_ftos, // void(string s) ftos = #26;
2501 PF_vtos, // void(string s) vtos = #27;
2505 PF_eprint, // void(entity e) debug print an entire entity
2506 PF_walkmove, // float(float yaw, float dist) walkmove
2507 PF_Fixme, // float(float yaw, float dist) walkmove
2557 PF_precache_sound, // precache_sound2 is different only for qcc
2562 PF_Fixme, // #79 LordHavoc: dunno who owns 79-89, so these are just padding
2574 PF_tracebox, // #90 LordHavoc builtin range (9x)
2575 PF_randomvec, // #91
2577 PF_registercvar, // #93
2582 PF_FindFloat, // #98
2583 PF_checkextension, // #99
2584 #define a PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme,
2585 #define aa a a a a a a a a a a
2589 PF_copyentity, // #400 LordHavoc: builtin range (4xx)
2590 PF_setcolor, // #401
2591 PF_findchain, // #402
2592 PF_findchainfloat, // #403
2594 PF_te_blood, // #405
2595 PF_te_bloodshower, // #406
2596 PF_te_explosionrgb, // #407
2597 PF_te_particlecube, // #408
2598 PF_te_particlerain, // #409
2599 PF_te_particlesnow, // #410
2600 PF_te_spark, // #411
2601 PF_te_gunshotquad, // #412
2602 PF_te_spikequad, // #413
2603 PF_te_superspikequad, // #414
2604 PF_te_explosionquad, // #415
2605 PF_te_smallflash, // #416
2606 PF_te_customflash, // #417
2607 PF_te_gunshot, // #418
2608 PF_te_spike, // #419
2609 PF_te_superspike, // #420
2610 PF_te_explosion, // #421
2611 PF_te_tarexplosion, // #422
2612 PF_te_wizspike, // #423
2613 PF_te_knightspike, // #424
2614 PF_te_lavasplash, // #425
2615 PF_te_teleport, // #426
2616 PF_te_explosion2, // #427
2617 PF_te_lightning1, // #428
2618 PF_te_lightning2, // #429
2619 PF_te_lightning3, // #430
2621 PF_vectorvectors, // #432
2622 PF_te_plasmaburn, // #433
2625 builtin_t *pr_builtins = pr_builtin;
2626 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);