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 \
66 DP_QC_FINDCHAINFLOAT \
78 DP_SV_DRAWONLYTOCLIENT \
80 DP_SV_EXTERIORMODELTOCLIENT \
81 DP_SV_NODRAWTOCLIENT \
94 qboolean checkextension(char *name)
99 for (e = ENGINE_EXTENSIONS;*e;e++)
106 while (*e && *e != ' ')
108 if (e - start == len)
109 if (!strncasecmp(start, name, len))
119 returns true if the extension is supported by the server
121 checkextension(extensionname)
124 void PF_checkextension (void)
126 G_FLOAT(OFS_RETURN) = checkextension(G_STRING(OFS_PARM0));
133 This is a TERMINAL error, which will kill off the entire server.
145 Con_Printf ("======SERVER ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
146 ed = PROG_TO_EDICT(pr_global_struct->self);
149 Host_Error ("Program error");
156 Dumps out self, then an error message. The program is aborted and self is
157 removed, but the level can continue.
162 void PF_objerror (void)
168 Con_Printf ("======OBJECT ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
169 ed = PROG_TO_EDICT(pr_global_struct->self);
179 Writes new values for v_forward, v_up, and v_right based on angles
183 void PF_makevectors (void)
185 AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
192 Writes new values for v_forward, v_up, and v_right based on the given forward vector
193 vectorvectors(vector, vector)
196 void PF_vectorvectors (void)
198 VectorNormalize2(G_VECTOR(OFS_PARM0), pr_global_struct->v_forward);
199 VectorVectors(pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
206 This is the only valid way to move an object without using the physics of the world (setting velocity and waiting). Directly changing origin will not set internal links correctly, so clipping would be messed up. This should be called when an object is spawned, and then only if it is teleported.
208 setorigin (entity, origin)
211 void PF_setorigin (void)
216 e = G_EDICT(OFS_PARM0);
217 org = G_VECTOR(OFS_PARM1);
218 VectorCopy (org, e->v.origin);
219 SV_LinkEdict (e, false);
223 void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
227 for (i=0 ; i<3 ; i++)
229 PR_RunError ("backwards mins/maxs");
231 // set derived values
232 VectorCopy (min, e->v.mins);
233 VectorCopy (max, e->v.maxs);
234 VectorSubtract (max, min, e->v.size);
236 SV_LinkEdict (e, false);
243 the size box is rotated by the current angle
244 LordHavoc: no it isn't...
246 setsize (entity, minvector, maxvector)
249 void PF_setsize (void)
254 e = G_EDICT(OFS_PARM0);
255 min = G_VECTOR(OFS_PARM1);
256 max = G_VECTOR(OFS_PARM2);
257 SetMinMaxSize (e, min, max, false);
265 setmodel(entity, model)
268 void PF_setmodel (void)
275 e = G_EDICT(OFS_PARM0);
276 m = G_STRING(OFS_PARM1);
278 // check to see if model was properly precached
279 for (i=0, check = sv.model_precache ; *check ; i++, check++)
280 if (!strcmp(*check, m))
284 PR_RunError ("no precache: %s\n", m);
287 e->v.model = m - pr_strings;
290 mod = sv.models[ (int)e->v.modelindex];
293 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
295 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
302 broadcast print to everyone on server
307 void PF_bprint (void)
312 SV_BroadcastPrintf ("%s", s);
319 single print to a specific client
321 sprint(clientent, value)
324 void PF_sprint (void)
330 entnum = G_EDICTNUM(OFS_PARM0);
333 if (entnum < 1 || entnum > svs.maxclients)
335 Con_Printf ("tried to sprint to a non-client\n");
339 client = &svs.clients[entnum-1];
341 MSG_WriteChar (&client->message,svc_print);
342 MSG_WriteString (&client->message, s );
350 single print to a specific client
352 centerprint(clientent, value)
355 void PF_centerprint (void)
361 entnum = G_EDICTNUM(OFS_PARM0);
364 if (entnum < 1 || entnum > svs.maxclients)
366 Con_Printf ("tried to sprint to a non-client\n");
370 client = &svs.clients[entnum-1];
372 MSG_WriteChar (&client->message,svc_centerprint);
373 MSG_WriteString (&client->message, s );
381 vector normalize(vector)
384 void PF_normalize (void)
390 value1 = G_VECTOR(OFS_PARM0);
392 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
396 newvalue[0] = newvalue[1] = newvalue[2] = 0;
400 newvalue[0] = value1[0] * new;
401 newvalue[1] = value1[1] * new;
402 newvalue[2] = value1[2] * new;
405 VectorCopy (newvalue, G_VECTOR(OFS_RETURN));
420 value1 = G_VECTOR(OFS_PARM0);
422 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
425 G_FLOAT(OFS_RETURN) = new;
432 float vectoyaw(vector)
435 void PF_vectoyaw (void)
440 value1 = G_VECTOR(OFS_PARM0);
442 if (value1[1] == 0 && value1[0] == 0)
446 yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
451 G_FLOAT(OFS_RETURN) = yaw;
459 vector vectoangles(vector)
462 void PF_vectoangles (void)
468 value1 = G_VECTOR(OFS_PARM0);
470 if (value1[1] == 0 && value1[0] == 0)
480 // LordHavoc: optimized a bit
483 yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
487 else if (value1[1] > 0)
492 forward = sqrt(value1[0]*value1[0] + value1[1]*value1[1]);
493 pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
498 G_FLOAT(OFS_RETURN+0) = pitch;
499 G_FLOAT(OFS_RETURN+1) = yaw;
500 G_FLOAT(OFS_RETURN+2) = 0;
507 Returns a number from 0<= num < 1
512 void PF_random (void)
516 num = (rand ()&0x7fff) / ((float)0x7fff);
518 G_FLOAT(OFS_RETURN) = num;
525 particle(origin, color, count)
528 void PF_particle (void)
534 org = G_VECTOR(OFS_PARM0);
535 dir = G_VECTOR(OFS_PARM1);
536 color = G_FLOAT(OFS_PARM2);
537 count = G_FLOAT(OFS_PARM3);
538 SV_StartParticle (org, dir, color, count);
548 void PF_ambientsound (void)
553 float vol, attenuation;
554 int i, soundnum, large;
556 pos = G_VECTOR (OFS_PARM0);
557 samp = G_STRING(OFS_PARM1);
558 vol = G_FLOAT(OFS_PARM2);
559 attenuation = G_FLOAT(OFS_PARM3);
561 // check to see if samp was properly precached
562 for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++)
563 if (!strcmp(*check,samp))
568 Con_Printf ("no precache: %s\n", samp);
576 // add an svc_spawnambient command to the level signon packet
579 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
581 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
583 for (i=0 ; i<3 ; i++)
584 MSG_WriteDPCoord(&sv.signon, pos[i]);
587 MSG_WriteShort (&sv.signon, soundnum);
589 MSG_WriteByte (&sv.signon, soundnum);
591 MSG_WriteByte (&sv.signon, vol*255);
592 MSG_WriteByte (&sv.signon, attenuation*64);
600 Each entity can have eight independant sound sources, like voice,
603 Channel 0 is an auto-allocate channel, the others override anything
604 already running on that entity/channel pair.
606 An attenuation of 0 will play full volume everywhere in the level.
607 Larger attenuations will drop off.
619 entity = G_EDICT(OFS_PARM0);
620 channel = G_FLOAT(OFS_PARM1);
621 sample = G_STRING(OFS_PARM2);
622 volume = G_FLOAT(OFS_PARM3) * 255;
623 attenuation = G_FLOAT(OFS_PARM4);
625 if (volume < 0 || volume > 255)
626 Host_Error ("SV_StartSound: volume = %i", volume);
628 if (attenuation < 0 || attenuation > 4)
629 Host_Error ("SV_StartSound: attenuation = %f", attenuation);
631 if (channel < 0 || channel > 7)
632 Host_Error ("SV_StartSound: channel = %i", channel);
634 SV_StartSound (entity, channel, sample, volume, attenuation);
646 PR_RunError ("break statement");
653 Used for use tracing and shot targeting
654 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
655 if the tryents flag is set.
657 traceline (vector1, vector2, tryents)
660 void PF_traceline (void)
667 v1 = G_VECTOR(OFS_PARM0);
668 v2 = G_VECTOR(OFS_PARM1);
669 nomonsters = G_FLOAT(OFS_PARM2);
670 ent = G_EDICT(OFS_PARM3);
672 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters ? MOVE_NOMONSTERS : MOVE_NORMAL, ent);
674 pr_global_struct->trace_allsolid = trace.allsolid;
675 pr_global_struct->trace_startsolid = trace.startsolid;
676 pr_global_struct->trace_fraction = trace.fraction;
677 pr_global_struct->trace_inwater = trace.inwater;
678 pr_global_struct->trace_inopen = trace.inopen;
679 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
680 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
681 pr_global_struct->trace_plane_dist = trace.plane.dist;
683 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
685 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
686 // FIXME: add trace_endcontents
694 Used for use tracing and shot targeting
695 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
696 if the tryents flag is set.
698 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
701 // LordHavoc: added this for my own use, VERY useful, similar to traceline
702 void PF_tracebox (void)
704 float *v1, *v2, *m1, *m2;
709 v1 = G_VECTOR(OFS_PARM0);
710 m1 = G_VECTOR(OFS_PARM1);
711 m2 = G_VECTOR(OFS_PARM2);
712 v2 = G_VECTOR(OFS_PARM3);
713 nomonsters = G_FLOAT(OFS_PARM4);
714 ent = G_EDICT(OFS_PARM5);
716 trace = SV_Move (v1, m1, m2, v2, nomonsters ? MOVE_NOMONSTERS : MOVE_NORMAL, ent);
718 pr_global_struct->trace_allsolid = trace.allsolid;
719 pr_global_struct->trace_startsolid = trace.startsolid;
720 pr_global_struct->trace_fraction = trace.fraction;
721 pr_global_struct->trace_inwater = trace.inwater;
722 pr_global_struct->trace_inopen = trace.inopen;
723 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
724 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
725 pr_global_struct->trace_plane_dist = trace.plane.dist;
727 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
729 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
732 extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore);
733 void PF_TraceToss (void)
739 ent = G_EDICT(OFS_PARM0);
740 ignore = G_EDICT(OFS_PARM1);
742 trace = SV_Trace_Toss (ent, ignore);
744 pr_global_struct->trace_allsolid = trace.allsolid;
745 pr_global_struct->trace_startsolid = trace.startsolid;
746 pr_global_struct->trace_fraction = trace.fraction;
747 pr_global_struct->trace_inwater = trace.inwater;
748 pr_global_struct->trace_inopen = trace.inopen;
749 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
750 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
751 pr_global_struct->trace_plane_dist = trace.plane.dist;
753 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
755 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
763 Returns true if the given entity can move to the given position from it's
764 current position by walking or rolling.
766 scalar checkpos (entity, vector)
769 void PF_checkpos (void)
773 //============================================================================
775 qbyte checkpvs[MAX_MAP_LEAFS/8];
777 int PF_newcheckclient (int check)
785 // cycle to the next one
789 if (check > svs.maxclients)
790 check = svs.maxclients;
792 if (check == svs.maxclients)
799 if (i == svs.maxclients+1)
805 break; // didn't find anything else
809 if (ent->v.health <= 0)
811 if ((int)ent->v.flags & FL_NOTARGET)
814 // anything that is a client, or has a client as an enemy
818 // get the PVS for the entity
819 VectorAdd (ent->v.origin, ent->v.view_ofs, org);
820 leaf = Mod_PointInLeaf (org, sv.worldmodel);
821 pvs = Mod_LeafPVS (leaf, sv.worldmodel);
822 memcpy (checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 );
831 Returns a client (or object that has a client enemy) that would be a
834 If there is more than one valid option, they are cycled each frame
836 If (self.origin + self.viewofs) is not in the PVS of the current target,
837 it is not returned at all.
842 int c_invis, c_notvis;
843 void PF_checkclient (void)
850 // find a new check if on a new frame
851 if (sv.time - sv.lastchecktime >= 0.1)
853 sv.lastcheck = PF_newcheckclient (sv.lastcheck);
854 sv.lastchecktime = sv.time;
857 // return check if it might be visible
858 ent = EDICT_NUM(sv.lastcheck);
859 if (ent->free || ent->v.health <= 0)
861 RETURN_EDICT(sv.edicts);
865 // if current entity can't possibly see the check entity, return 0
866 self = PROG_TO_EDICT(pr_global_struct->self);
867 VectorAdd (self->v.origin, self->v.view_ofs, view);
868 leaf = Mod_PointInLeaf (view, sv.worldmodel);
869 l = (leaf - sv.worldmodel->leafs) - 1;
870 if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
873 RETURN_EDICT(sv.edicts);
877 // might be able to see it
882 //============================================================================
889 Sends text over to the client's execution buffer
891 stuffcmd (clientent, value)
894 void PF_stuffcmd (void)
900 entnum = G_EDICTNUM(OFS_PARM0);
901 if (entnum < 1 || entnum > svs.maxclients)
902 PR_RunError ("Parm 0 not a client");
903 str = G_STRING(OFS_PARM1);
906 host_client = &svs.clients[entnum-1];
907 Host_ClientCommands ("%s", str);
915 Sends text over to the client's execution buffer
920 void PF_localcmd (void)
924 str = G_STRING(OFS_PARM0);
939 str = G_STRING(OFS_PARM0);
941 G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str);
951 void PF_cvar_set (void)
955 var = G_STRING(OFS_PARM0);
956 val = G_STRING(OFS_PARM1);
965 Returns a chain of entities that have origins within a spherical area
967 findradius (origin, radius)
970 void PF_findradius (void)
972 edict_t *ent, *chain;
979 chain = (edict_t *)sv.edicts;
981 org = G_VECTOR(OFS_PARM0);
982 radius = G_FLOAT(OFS_PARM1);
983 radius2 = radius * radius;
985 ent = NEXT_EDICT(sv.edicts);
986 for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
990 if (ent->v.solid == SOLID_NOT)
993 // LordHavoc: compare against bounding box rather than center,
994 // and use DotProduct instead of Length, major speedup
995 eorg[0] = (org[0] - ent->v.origin[0]) - bound(ent->v.mins[0], (org[0] - ent->v.origin[0]), ent->v.maxs[0]);
996 eorg[1] = (org[1] - ent->v.origin[1]) - bound(ent->v.mins[1], (org[1] - ent->v.origin[1]), ent->v.maxs[1]);
997 eorg[2] = (org[2] - ent->v.origin[2]) - bound(ent->v.mins[2], (org[2] - ent->v.origin[2]), ent->v.maxs[2]);
998 if (DotProduct(eorg, eorg) > radius2)
1001 ent->v.chain = EDICT_TO_PROG(chain);
1005 RETURN_EDICT(chain);
1014 void PF_dprint (void)
1016 Con_DPrintf ("%s",PF_VarString(0));
1019 // LordHavoc: added this to semi-fix the problem of using many ftos calls in a print
1020 #define STRINGTEMP_BUFFERS 16
1021 #define STRINGTEMP_LENGTH 128
1022 static char pr_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH];
1023 static int pr_string_tempindex = 0;
1025 static char *PR_GetTempString(void)
1028 s = pr_string_temp[pr_string_tempindex];
1029 pr_string_tempindex = (pr_string_tempindex + 1) % STRINGTEMP_BUFFERS;
1037 v = G_FLOAT(OFS_PARM0);
1039 s = PR_GetTempString();
1040 // LordHavoc: ftos improvement
1041 sprintf (s, "%g", v);
1042 G_INT(OFS_RETURN) = s - pr_strings;
1048 v = G_FLOAT(OFS_PARM0);
1049 G_FLOAT(OFS_RETURN) = fabs(v);
1055 s = PR_GetTempString();
1056 sprintf (s, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
1057 G_INT(OFS_RETURN) = s - pr_strings;
1063 s = PR_GetTempString();
1064 sprintf (s, "entity %i", G_EDICTNUM(OFS_PARM0));
1065 G_INT(OFS_RETURN) = s - pr_strings;
1068 void PF_Spawn (void)
1075 void PF_Remove (void)
1079 ed = G_EDICT(OFS_PARM0);
1080 if (ed == sv.edicts)
1081 PR_RunError("remove: tried to remove world\n");
1082 if (NUM_FOR_EDICT(ed) <= svs.maxclients)
1083 PR_RunError("remove: tried to remove a client\n");
1088 // entity (entity start, .string field, string match) find = #5;
1096 e = G_EDICTNUM(OFS_PARM0);
1097 f = G_INT(OFS_PARM1);
1098 s = G_STRING(OFS_PARM2);
1101 RETURN_EDICT(sv.edicts);
1105 for (e++ ; e < sv.num_edicts ; e++)
1120 RETURN_EDICT(sv.edicts);
1123 // LordHavoc: added this for searching float, int, and entity reference fields
1124 void PF_FindFloat (void)
1131 e = G_EDICTNUM(OFS_PARM0);
1132 f = G_INT(OFS_PARM1);
1133 s = G_FLOAT(OFS_PARM2);
1135 for (e++ ; e < sv.num_edicts ; e++)
1140 if (E_FLOAT(ed,f) == s)
1147 RETURN_EDICT(sv.edicts);
1150 // chained search for strings in entity fields
1151 // entity(.string field, string match) findchain = #402;
1152 void PF_findchain (void)
1157 edict_t *ent, *chain;
1159 chain = (edict_t *)sv.edicts;
1161 f = G_INT(OFS_PARM0);
1162 s = G_STRING(OFS_PARM1);
1165 RETURN_EDICT(sv.edicts);
1169 ent = NEXT_EDICT(sv.edicts);
1170 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1174 t = E_STRING(ent,f);
1180 ent->v.chain = EDICT_TO_PROG(chain);
1184 RETURN_EDICT(chain);
1187 // LordHavoc: chained search for float, int, and entity reference fields
1188 // entity(.string field, float match) findchainfloat = #403;
1189 void PF_findchainfloat (void)
1194 edict_t *ent, *chain;
1196 chain = (edict_t *)sv.edicts;
1198 f = G_INT(OFS_PARM0);
1199 s = G_FLOAT(OFS_PARM1);
1201 ent = NEXT_EDICT(sv.edicts);
1202 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1206 if (E_FLOAT(ent,f) != s)
1209 ent->v.chain = EDICT_TO_PROG(chain);
1213 RETURN_EDICT(chain);
1216 void PR_CheckEmptyString (char *s)
1219 PR_RunError ("Bad string");
1222 void PF_precache_file (void)
1223 { // precache_file is only used to copy files with qcc, it does nothing
1224 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1227 void PF_precache_sound (void)
1232 if (sv.state != ss_loading)
1233 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1235 s = G_STRING(OFS_PARM0);
1236 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1237 PR_CheckEmptyString (s);
1239 for (i=0 ; i<MAX_SOUNDS ; i++)
1241 if (!sv.sound_precache[i])
1243 sv.sound_precache[i] = s;
1246 if (!strcmp(sv.sound_precache[i], s))
1249 PR_RunError ("PF_precache_sound: overflow");
1252 void PF_precache_model (void)
1257 if (sv.state != ss_loading)
1258 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1260 s = G_STRING(OFS_PARM0);
1261 if (sv.worldmodel->ishlbsp && ((!s) || (!s[0])))
1263 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1264 PR_CheckEmptyString (s);
1266 for (i=0 ; i<MAX_MODELS ; i++)
1268 if (!sv.model_precache[i])
1270 sv.model_precache[i] = s;
1271 sv.models[i] = Mod_ForName (s, true, false, false);
1274 if (!strcmp(sv.model_precache[i], s))
1277 PR_RunError ("PF_precache_model: overflow");
1281 void PF_coredump (void)
1286 void PF_traceon (void)
1291 void PF_traceoff (void)
1296 void PF_eprint (void)
1298 ED_PrintNum (G_EDICTNUM(OFS_PARM0));
1305 float(float yaw, float dist) walkmove
1308 void PF_walkmove (void)
1316 ent = PROG_TO_EDICT(pr_global_struct->self);
1317 yaw = G_FLOAT(OFS_PARM0);
1318 dist = G_FLOAT(OFS_PARM1);
1320 if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1322 G_FLOAT(OFS_RETURN) = 0;
1326 yaw = yaw*M_PI*2 / 360;
1328 move[0] = cos(yaw)*dist;
1329 move[1] = sin(yaw)*dist;
1332 // save program state, because SV_movestep may call other progs
1333 oldf = pr_xfunction;
1334 oldself = pr_global_struct->self;
1336 G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
1339 // restore program state
1340 pr_xfunction = oldf;
1341 pr_global_struct->self = oldself;
1351 void PF_droptofloor (void)
1357 ent = PROG_TO_EDICT(pr_global_struct->self);
1359 VectorCopy (ent->v.origin, end);
1362 trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
1364 if (trace.fraction == 1 || trace.allsolid)
1365 G_FLOAT(OFS_RETURN) = 0;
1368 VectorCopy (trace.endpos, ent->v.origin);
1369 SV_LinkEdict (ent, false);
1370 ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
1371 ent->v.groundentity = EDICT_TO_PROG(trace.ent);
1372 G_FLOAT(OFS_RETURN) = 1;
1373 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1374 ent->suspendedinairflag = true;
1382 void(float style, string value) lightstyle
1385 void PF_lightstyle (void)
1392 style = G_FLOAT(OFS_PARM0);
1393 val = G_STRING(OFS_PARM1);
1395 // change the string in sv
1396 sv.lightstyles[style] = val;
1398 // send message to all clients on this server
1399 if (sv.state != ss_active)
1402 for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
1403 if (client->active || client->spawned)
1405 MSG_WriteChar (&client->message, svc_lightstyle);
1406 MSG_WriteChar (&client->message,style);
1407 MSG_WriteString (&client->message, val);
1414 f = G_FLOAT(OFS_PARM0);
1416 G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1418 G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1420 void PF_floor (void)
1422 G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
1426 G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
1435 void PF_checkbottom (void)
1437 G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0));
1445 void PF_pointcontents (void)
1447 G_FLOAT(OFS_RETURN) = Mod_PointInLeaf(G_VECTOR(OFS_PARM0), sv.worldmodel)->contents;
1454 entity nextent(entity)
1457 void PF_nextent (void)
1462 i = G_EDICTNUM(OFS_PARM0);
1466 if (i == sv.num_edicts)
1468 RETURN_EDICT(sv.edicts);
1484 Pick a vector for the player to shoot along
1485 vector aim(entity, missilespeed)
1490 edict_t *ent, *check, *bestent;
1491 vec3_t start, dir, end, bestdir;
1494 float dist, bestdist;
1497 ent = G_EDICT(OFS_PARM0);
1498 speed = G_FLOAT(OFS_PARM1);
1500 VectorCopy (ent->v.origin, start);
1503 // try sending a trace straight
1504 VectorCopy (pr_global_struct->v_forward, dir);
1505 VectorMA (start, 2048, dir, end);
1506 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1507 if (tr.ent && ((edict_t *)tr.ent)->v.takedamage == DAMAGE_AIM
1508 && (!teamplay.integer || ent->v.team <=0 || ent->v.team != ((edict_t *)tr.ent)->v.team) )
1510 VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
1515 // try all possible entities
1516 VectorCopy (dir, bestdir);
1517 bestdist = sv_aim.value;
1520 check = NEXT_EDICT(sv.edicts);
1521 for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
1523 if (check->v.takedamage != DAMAGE_AIM)
1527 if (teamplay.integer && ent->v.team > 0 && ent->v.team == check->v.team)
1528 continue; // don't aim at teammate
1529 for (j=0 ; j<3 ; j++)
1530 end[j] = check->v.origin[j]
1531 + 0.5*(check->v.mins[j] + check->v.maxs[j]);
1532 VectorSubtract (end, start, dir);
1533 VectorNormalize (dir);
1534 dist = DotProduct (dir, pr_global_struct->v_forward);
1535 if (dist < bestdist)
1536 continue; // to far to turn
1537 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1538 if (tr.ent == check)
1539 { // can shoot at this one
1547 VectorSubtract (bestent->v.origin, ent->v.origin, dir);
1548 dist = DotProduct (dir, pr_global_struct->v_forward);
1549 VectorScale (pr_global_struct->v_forward, dist, end);
1551 VectorNormalize (end);
1552 VectorCopy (end, G_VECTOR(OFS_RETURN));
1556 VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
1564 This was a major timewaster in progs, so it was converted to C
1567 void PF_changeyaw (void)
1570 float ideal, current, move, speed;
1572 ent = PROG_TO_EDICT(pr_global_struct->self);
1573 current = ANGLEMOD(ent->v.angles[1]);
1574 ideal = ent->v.ideal_yaw;
1575 speed = ent->v.yaw_speed;
1577 if (current == ideal)
1579 move = ideal - current;
1580 if (ideal > current)
1601 ent->v.angles[1] = ANGLEMOD (current + move);
1609 void PF_changepitch (void)
1612 float ideal, current, move, speed;
1615 ent = G_EDICT(OFS_PARM0);
1616 current = ANGLEMOD( ent->v.angles[0] );
1617 if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
1618 ideal = val->_float;
1621 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1624 if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
1625 speed = val->_float;
1628 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1632 if (current == ideal)
1634 move = ideal - current;
1635 if (ideal > current)
1656 ent->v.angles[0] = ANGLEMOD (current + move);
1660 ===============================================================================
1664 ===============================================================================
1667 #define MSG_BROADCAST 0 // unreliable to all
1668 #define MSG_ONE 1 // reliable to one (msg_entity)
1669 #define MSG_ALL 2 // reliable to all
1670 #define MSG_INIT 3 // write to the init string
1672 sizebuf_t *WriteDest (void)
1678 dest = G_FLOAT(OFS_PARM0);
1682 return &sv.datagram;
1685 ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
1686 entnum = NUM_FOR_EDICT(ent);
1687 if (entnum < 1 || entnum > svs.maxclients)
1688 PR_RunError ("WriteDest: not a client");
1689 return &svs.clients[entnum-1].message;
1692 return &sv.reliable_datagram;
1698 PR_RunError ("WriteDest: bad destination");
1705 void PF_WriteByte (void)
1707 MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
1710 void PF_WriteChar (void)
1712 MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
1715 void PF_WriteShort (void)
1717 MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
1720 void PF_WriteLong (void)
1722 MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
1725 void PF_WriteAngle (void)
1727 MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
1730 void PF_WriteCoord (void)
1732 MSG_WriteDPCoord (WriteDest(), G_FLOAT(OFS_PARM1));
1735 void PF_WriteString (void)
1737 MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
1741 void PF_WriteEntity (void)
1743 MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
1746 //=============================================================================
1748 int SV_ModelIndex (char *name);
1750 void PF_makestatic (void)
1755 ent = G_EDICT(OFS_PARM0);
1758 if (ent->v.modelindex >= 256 || ent->v.frame >= 256)
1763 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1764 MSG_WriteShort (&sv.signon, ent->v.modelindex);
1765 MSG_WriteShort (&sv.signon, ent->v.frame);
1769 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1770 MSG_WriteByte (&sv.signon, ent->v.modelindex);
1771 MSG_WriteByte (&sv.signon, ent->v.frame);
1774 MSG_WriteByte (&sv.signon, ent->v.colormap);
1775 MSG_WriteByte (&sv.signon, ent->v.skin);
1776 for (i=0 ; i<3 ; i++)
1778 MSG_WriteDPCoord(&sv.signon, ent->v.origin[i]);
1779 MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
1782 // throw the entity away now
1786 //=============================================================================
1793 void PF_setspawnparms (void)
1799 ent = G_EDICT(OFS_PARM0);
1800 i = NUM_FOR_EDICT(ent);
1801 if (i < 1 || i > svs.maxclients)
1802 PR_RunError ("Entity is not a client");
1804 // copy spawn parms out of the client_t
1805 client = svs.clients + (i-1);
1807 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1808 (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
1816 void PF_changelevel (void)
1820 // make sure we don't issue two changelevels
1821 if (svs.changelevel_issued)
1823 svs.changelevel_issued = true;
1825 s = G_STRING(OFS_PARM0);
1826 Cbuf_AddText (va("changelevel %s\n",s));
1831 G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
1836 G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
1841 G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
1848 Returns a vector of length < 1
1853 void PF_randomvec (void)
1858 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1859 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1860 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1862 while (DotProduct(temp, temp) >= 1);
1863 VectorCopy (temp, G_VECTOR(OFS_RETURN));
1866 void SV_LightPoint (vec3_t color, vec3_t p);
1871 Returns a color vector indicating the lighting at the requested point.
1873 (Internal Operation note: actually measures the light beneath the point, just like
1874 the model lighting on the client)
1879 void PF_GetLight (void)
1883 p = G_VECTOR(OFS_PARM0);
1884 SV_LightPoint (color, p);
1885 VectorCopy (color, G_VECTOR(OFS_RETURN));
1888 #define MAX_QC_CVARS 128
1889 cvar_t qc_cvar[MAX_QC_CVARS];
1892 void PF_registercvar (void)
1896 name = G_STRING(OFS_PARM0);
1897 value = G_STRING(OFS_PARM1);
1898 G_FLOAT(OFS_RETURN) = 0;
1899 // first check to see if it has already been defined
1900 if (Cvar_FindVar (name))
1903 // check for overlap with a command
1904 if (Cmd_Exists (name))
1906 Con_Printf ("PF_registercvar: %s is a command\n", name);
1910 if (currentqc_cvar >= MAX_QC_CVARS)
1911 PR_RunError ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
1913 // copy the name and value
1914 variable = &qc_cvar[currentqc_cvar++];
1915 variable->name = Z_Malloc (strlen(name)+1);
1916 strcpy (variable->name, name);
1917 variable->string = Z_Malloc (strlen(value)+1);
1918 strcpy (variable->string, value);
1919 variable->value = atof (value);
1921 // link the variable in
1922 variable->next = cvar_vars;
1923 cvar_vars = 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]);