2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 cvar_t sv_aim = {CVAR_SAVE, "sv_aim", "2"}; //"0.93"}; // LordHavoc: disabled autoaim by default
25 #define RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e))
29 ===============================================================================
33 ===============================================================================
37 char *PF_VarString (int first)
40 static char out[4096]; // FIXME: buffer overflow potential
43 for (i = first;i < pr_argc;i++)
44 strcat (out, G_STRING((OFS_PARM0+i*3)));
48 char *ENGINE_EXTENSIONS =
50 "DP_ENT_CUSTOMCOLORMAP "
51 "DP_ENT_EXTERIORMODELTOCLIENT "
52 "DP_ENT_LOWPRECISION "
65 "DP_QC_FINDCHAINFLOAT "
70 "DP_QC_SINCOSSQRTPOW "
73 "DP_QC_VECTORVECTORS "
78 "DP_SV_DRAWONLYTOCLIENT "
80 "DP_SV_EXTERIORMODELTOCLIENT "
81 "DP_SV_NODRAWTOCLIENT "
82 "DP_SV_PLAYERPHYSICS "
97 qboolean checkextension(char *name)
102 for (e = ENGINE_EXTENSIONS;*e;e++)
109 while (*e && *e != ' ')
111 if (e - start == len)
112 if (!strncasecmp(start, name, len))
122 returns true if the extension is supported by the server
124 checkextension(extensionname)
127 void PF_checkextension (void)
129 G_FLOAT(OFS_RETURN) = checkextension(G_STRING(OFS_PARM0));
136 This is a TERMINAL error, which will kill off the entire server.
148 Con_Printf ("======SERVER ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
149 ed = PROG_TO_EDICT(pr_global_struct->self);
152 Host_Error ("Program error");
159 Dumps out self, then an error message. The program is aborted and self is
160 removed, but the level can continue.
165 void PF_objerror (void)
171 Con_Printf ("======OBJECT ERROR in %s:\n%s\n", pr_strings + pr_xfunction->s_name, s);
172 ed = PROG_TO_EDICT(pr_global_struct->self);
182 Writes new values for v_forward, v_up, and v_right based on angles
186 void PF_makevectors (void)
188 AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
195 Writes new values for v_forward, v_up, and v_right based on the given forward vector
196 vectorvectors(vector, vector)
199 void PF_vectorvectors (void)
201 VectorNormalize2(G_VECTOR(OFS_PARM0), pr_global_struct->v_forward);
202 VectorVectors(pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
209 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.
211 setorigin (entity, origin)
214 void PF_setorigin (void)
219 e = G_EDICT(OFS_PARM0);
220 org = G_VECTOR(OFS_PARM1);
221 VectorCopy (org, e->v.origin);
222 SV_LinkEdict (e, false);
226 void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
230 for (i=0 ; i<3 ; i++)
232 PR_RunError ("backwards mins/maxs");
234 // set derived values
235 VectorCopy (min, e->v.mins);
236 VectorCopy (max, e->v.maxs);
237 VectorSubtract (max, min, e->v.size);
239 SV_LinkEdict (e, false);
246 the size box is rotated by the current angle
247 LordHavoc: no it isn't...
249 setsize (entity, minvector, maxvector)
252 void PF_setsize (void)
257 e = G_EDICT(OFS_PARM0);
258 min = G_VECTOR(OFS_PARM1);
259 max = G_VECTOR(OFS_PARM2);
260 SetMinMaxSize (e, min, max, false);
268 setmodel(entity, model)
271 void PF_setmodel (void)
278 e = G_EDICT(OFS_PARM0);
279 m = G_STRING(OFS_PARM1);
281 // check to see if model was properly precached
282 for (i=0, check = sv.model_precache ; *check ; i++, check++)
283 if (!strcmp(*check, m))
287 PR_RunError ("no precache: %s\n", m);
290 e->v.model = m - pr_strings;
293 mod = sv.models[ (int)e->v.modelindex];
296 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
298 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
305 broadcast print to everyone on server
310 void PF_bprint (void)
315 SV_BroadcastPrintf ("%s", s);
322 single print to a specific client
324 sprint(clientent, value)
327 void PF_sprint (void)
333 entnum = G_EDICTNUM(OFS_PARM0);
336 if (entnum < 1 || entnum > svs.maxclients)
338 Con_Printf ("tried to sprint to a non-client\n");
342 client = &svs.clients[entnum-1];
344 MSG_WriteChar (&client->message,svc_print);
345 MSG_WriteString (&client->message, s );
353 single print to a specific client
355 centerprint(clientent, value)
358 void PF_centerprint (void)
364 entnum = G_EDICTNUM(OFS_PARM0);
367 if (entnum < 1 || entnum > svs.maxclients)
369 Con_Printf ("tried to sprint to a non-client\n");
373 client = &svs.clients[entnum-1];
375 MSG_WriteChar (&client->message,svc_centerprint);
376 MSG_WriteString (&client->message, s );
384 vector normalize(vector)
387 void PF_normalize (void)
393 value1 = G_VECTOR(OFS_PARM0);
395 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
399 newvalue[0] = newvalue[1] = newvalue[2] = 0;
403 newvalue[0] = value1[0] * new;
404 newvalue[1] = value1[1] * new;
405 newvalue[2] = value1[2] * new;
408 VectorCopy (newvalue, G_VECTOR(OFS_RETURN));
423 value1 = G_VECTOR(OFS_PARM0);
425 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
428 G_FLOAT(OFS_RETURN) = new;
435 float vectoyaw(vector)
438 void PF_vectoyaw (void)
443 value1 = G_VECTOR(OFS_PARM0);
445 if (value1[1] == 0 && value1[0] == 0)
449 yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
454 G_FLOAT(OFS_RETURN) = yaw;
462 vector vectoangles(vector)
465 void PF_vectoangles (void)
471 value1 = G_VECTOR(OFS_PARM0);
473 if (value1[1] == 0 && value1[0] == 0)
483 // LordHavoc: optimized a bit
486 yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
490 else if (value1[1] > 0)
495 forward = sqrt(value1[0]*value1[0] + value1[1]*value1[1]);
496 pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
501 G_FLOAT(OFS_RETURN+0) = pitch;
502 G_FLOAT(OFS_RETURN+1) = yaw;
503 G_FLOAT(OFS_RETURN+2) = 0;
510 Returns a number from 0<= num < 1
515 void PF_random (void)
519 num = (rand ()&0x7fff) / ((float)0x7fff);
521 G_FLOAT(OFS_RETURN) = num;
528 particle(origin, color, count)
531 void PF_particle (void)
537 org = G_VECTOR(OFS_PARM0);
538 dir = G_VECTOR(OFS_PARM1);
539 color = G_FLOAT(OFS_PARM2);
540 count = G_FLOAT(OFS_PARM3);
541 SV_StartParticle (org, dir, color, count);
551 void PF_ambientsound (void)
556 float vol, attenuation;
557 int i, soundnum, large;
559 pos = G_VECTOR (OFS_PARM0);
560 samp = G_STRING(OFS_PARM1);
561 vol = G_FLOAT(OFS_PARM2);
562 attenuation = G_FLOAT(OFS_PARM3);
564 // check to see if samp was properly precached
565 for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++)
566 if (!strcmp(*check,samp))
571 Con_Printf ("no precache: %s\n", samp);
579 // add an svc_spawnambient command to the level signon packet
582 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
584 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
586 for (i=0 ; i<3 ; i++)
587 MSG_WriteDPCoord(&sv.signon, pos[i]);
590 MSG_WriteShort (&sv.signon, soundnum);
592 MSG_WriteByte (&sv.signon, soundnum);
594 MSG_WriteByte (&sv.signon, vol*255);
595 MSG_WriteByte (&sv.signon, attenuation*64);
603 Each entity can have eight independant sound sources, like voice,
606 Channel 0 is an auto-allocate channel, the others override anything
607 already running on that entity/channel pair.
609 An attenuation of 0 will play full volume everywhere in the level.
610 Larger attenuations will drop off.
622 entity = G_EDICT(OFS_PARM0);
623 channel = G_FLOAT(OFS_PARM1);
624 sample = G_STRING(OFS_PARM2);
625 volume = G_FLOAT(OFS_PARM3) * 255;
626 attenuation = G_FLOAT(OFS_PARM4);
628 if (volume < 0 || volume > 255)
629 Host_Error ("SV_StartSound: volume = %i", volume);
631 if (attenuation < 0 || attenuation > 4)
632 Host_Error ("SV_StartSound: attenuation = %f", attenuation);
634 if (channel < 0 || channel > 7)
635 Host_Error ("SV_StartSound: channel = %i", channel);
637 SV_StartSound (entity, channel, sample, volume, attenuation);
649 PR_RunError ("break statement");
656 Used for use tracing and shot targeting
657 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
658 if the tryents flag is set.
660 traceline (vector1, vector2, tryents)
663 void PF_traceline (void)
670 v1 = G_VECTOR(OFS_PARM0);
671 v2 = G_VECTOR(OFS_PARM1);
672 nomonsters = G_FLOAT(OFS_PARM2);
673 ent = G_EDICT(OFS_PARM3);
675 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters ? MOVE_NOMONSTERS : MOVE_NORMAL, ent);
677 pr_global_struct->trace_allsolid = trace.allsolid;
678 pr_global_struct->trace_startsolid = trace.startsolid;
679 pr_global_struct->trace_fraction = trace.fraction;
680 pr_global_struct->trace_inwater = trace.inwater;
681 pr_global_struct->trace_inopen = trace.inopen;
682 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
683 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
684 pr_global_struct->trace_plane_dist = trace.plane.dist;
686 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
688 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
689 // FIXME: add trace_endcontents
697 Used for use tracing and shot targeting
698 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
699 if the tryents flag is set.
701 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
704 // LordHavoc: added this for my own use, VERY useful, similar to traceline
705 void PF_tracebox (void)
707 float *v1, *v2, *m1, *m2;
712 v1 = G_VECTOR(OFS_PARM0);
713 m1 = G_VECTOR(OFS_PARM1);
714 m2 = G_VECTOR(OFS_PARM2);
715 v2 = G_VECTOR(OFS_PARM3);
716 nomonsters = G_FLOAT(OFS_PARM4);
717 ent = G_EDICT(OFS_PARM5);
719 trace = SV_Move (v1, m1, m2, v2, nomonsters ? MOVE_NOMONSTERS : MOVE_NORMAL, ent);
721 pr_global_struct->trace_allsolid = trace.allsolid;
722 pr_global_struct->trace_startsolid = trace.startsolid;
723 pr_global_struct->trace_fraction = trace.fraction;
724 pr_global_struct->trace_inwater = trace.inwater;
725 pr_global_struct->trace_inopen = trace.inopen;
726 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
727 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
728 pr_global_struct->trace_plane_dist = trace.plane.dist;
730 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
732 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
735 extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore);
736 void PF_TraceToss (void)
742 ent = G_EDICT(OFS_PARM0);
743 ignore = G_EDICT(OFS_PARM1);
745 trace = SV_Trace_Toss (ent, ignore);
747 pr_global_struct->trace_allsolid = trace.allsolid;
748 pr_global_struct->trace_startsolid = trace.startsolid;
749 pr_global_struct->trace_fraction = trace.fraction;
750 pr_global_struct->trace_inwater = trace.inwater;
751 pr_global_struct->trace_inopen = trace.inopen;
752 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
753 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
754 pr_global_struct->trace_plane_dist = trace.plane.dist;
756 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
758 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
766 Returns true if the given entity can move to the given position from it's
767 current position by walking or rolling.
769 scalar checkpos (entity, vector)
772 void PF_checkpos (void)
776 //============================================================================
778 qbyte checkpvs[MAX_MAP_LEAFS/8];
780 int PF_newcheckclient (int check)
788 // cycle to the next one
792 if (check > svs.maxclients)
793 check = svs.maxclients;
795 if (check == svs.maxclients)
802 if (i == svs.maxclients+1)
808 break; // didn't find anything else
812 if (ent->v.health <= 0)
814 if ((int)ent->v.flags & FL_NOTARGET)
817 // anything that is a client, or has a client as an enemy
821 // get the PVS for the entity
822 VectorAdd (ent->v.origin, ent->v.view_ofs, org);
823 leaf = Mod_PointInLeaf (org, sv.worldmodel);
824 pvs = Mod_LeafPVS (leaf, sv.worldmodel);
825 memcpy (checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 );
834 Returns a client (or object that has a client enemy) that would be a
837 If there is more than one valid option, they are cycled each frame
839 If (self.origin + self.viewofs) is not in the PVS of the current target,
840 it is not returned at all.
845 int c_invis, c_notvis;
846 void PF_checkclient (void)
853 // find a new check if on a new frame
854 if (sv.time - sv.lastchecktime >= 0.1)
856 sv.lastcheck = PF_newcheckclient (sv.lastcheck);
857 sv.lastchecktime = sv.time;
860 // return check if it might be visible
861 ent = EDICT_NUM(sv.lastcheck);
862 if (ent->free || ent->v.health <= 0)
864 RETURN_EDICT(sv.edicts);
868 // if current entity can't possibly see the check entity, return 0
869 self = PROG_TO_EDICT(pr_global_struct->self);
870 VectorAdd (self->v.origin, self->v.view_ofs, view);
871 leaf = Mod_PointInLeaf (view, sv.worldmodel);
872 l = (leaf - sv.worldmodel->leafs) - 1;
873 if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
876 RETURN_EDICT(sv.edicts);
880 // might be able to see it
885 //============================================================================
892 Sends text over to the client's execution buffer
894 stuffcmd (clientent, value)
897 void PF_stuffcmd (void)
903 entnum = G_EDICTNUM(OFS_PARM0);
904 if (entnum < 1 || entnum > svs.maxclients)
905 PR_RunError ("Parm 0 not a client");
906 str = G_STRING(OFS_PARM1);
909 host_client = &svs.clients[entnum-1];
910 Host_ClientCommands ("%s", str);
918 Sends text over to the client's execution buffer
923 void PF_localcmd (void)
927 str = G_STRING(OFS_PARM0);
942 str = G_STRING(OFS_PARM0);
944 G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str);
954 void PF_cvar_set (void)
958 var = G_STRING(OFS_PARM0);
959 val = G_STRING(OFS_PARM1);
968 Returns a chain of entities that have origins within a spherical area
970 findradius (origin, radius)
973 void PF_findradius (void)
975 edict_t *ent, *chain;
982 chain = (edict_t *)sv.edicts;
984 org = G_VECTOR(OFS_PARM0);
985 radius = G_FLOAT(OFS_PARM1);
986 radius2 = radius * radius;
988 ent = NEXT_EDICT(sv.edicts);
989 for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
993 if (ent->v.solid == SOLID_NOT)
996 // LordHavoc: compare against bounding box rather than center,
997 // and use DotProduct instead of Length, major speedup
998 eorg[0] = (org[0] - ent->v.origin[0]) - bound(ent->v.mins[0], (org[0] - ent->v.origin[0]), ent->v.maxs[0]);
999 eorg[1] = (org[1] - ent->v.origin[1]) - bound(ent->v.mins[1], (org[1] - ent->v.origin[1]), ent->v.maxs[1]);
1000 eorg[2] = (org[2] - ent->v.origin[2]) - bound(ent->v.mins[2], (org[2] - ent->v.origin[2]), ent->v.maxs[2]);
1001 if (DotProduct(eorg, eorg) > radius2)
1004 ent->v.chain = EDICT_TO_PROG(chain);
1008 RETURN_EDICT(chain);
1017 void PF_dprint (void)
1019 Con_DPrintf ("%s",PF_VarString(0));
1022 // LordHavoc: added this to semi-fix the problem of using many ftos calls in a print
1023 #define STRINGTEMP_BUFFERS 16
1024 #define STRINGTEMP_LENGTH 128
1025 static char pr_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH];
1026 static int pr_string_tempindex = 0;
1028 static char *PR_GetTempString(void)
1031 s = pr_string_temp[pr_string_tempindex];
1032 pr_string_tempindex = (pr_string_tempindex + 1) % STRINGTEMP_BUFFERS;
1040 v = G_FLOAT(OFS_PARM0);
1042 s = PR_GetTempString();
1043 // LordHavoc: ftos improvement
1044 sprintf (s, "%g", v);
1045 G_INT(OFS_RETURN) = s - pr_strings;
1051 v = G_FLOAT(OFS_PARM0);
1052 G_FLOAT(OFS_RETURN) = fabs(v);
1058 s = PR_GetTempString();
1059 sprintf (s, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
1060 G_INT(OFS_RETURN) = s - pr_strings;
1066 s = PR_GetTempString();
1067 sprintf (s, "entity %i", G_EDICTNUM(OFS_PARM0));
1068 G_INT(OFS_RETURN) = s - pr_strings;
1071 void PF_Spawn (void)
1078 void PF_Remove (void)
1082 ed = G_EDICT(OFS_PARM0);
1083 if (ed == sv.edicts)
1084 PR_RunError("remove: tried to remove world\n");
1085 if (NUM_FOR_EDICT(ed) <= svs.maxclients)
1086 PR_RunError("remove: tried to remove a client\n");
1091 // entity (entity start, .string field, string match) find = #5;
1099 e = G_EDICTNUM(OFS_PARM0);
1100 f = G_INT(OFS_PARM1);
1101 s = G_STRING(OFS_PARM2);
1104 RETURN_EDICT(sv.edicts);
1108 for (e++ ; e < sv.num_edicts ; e++)
1123 RETURN_EDICT(sv.edicts);
1126 // LordHavoc: added this for searching float, int, and entity reference fields
1127 void PF_FindFloat (void)
1134 e = G_EDICTNUM(OFS_PARM0);
1135 f = G_INT(OFS_PARM1);
1136 s = G_FLOAT(OFS_PARM2);
1138 for (e++ ; e < sv.num_edicts ; e++)
1143 if (E_FLOAT(ed,f) == s)
1150 RETURN_EDICT(sv.edicts);
1153 // chained search for strings in entity fields
1154 // entity(.string field, string match) findchain = #402;
1155 void PF_findchain (void)
1160 edict_t *ent, *chain;
1162 chain = (edict_t *)sv.edicts;
1164 f = G_INT(OFS_PARM0);
1165 s = G_STRING(OFS_PARM1);
1168 RETURN_EDICT(sv.edicts);
1172 ent = NEXT_EDICT(sv.edicts);
1173 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1177 t = E_STRING(ent,f);
1183 ent->v.chain = EDICT_TO_PROG(chain);
1187 RETURN_EDICT(chain);
1190 // LordHavoc: chained search for float, int, and entity reference fields
1191 // entity(.string field, float match) findchainfloat = #403;
1192 void PF_findchainfloat (void)
1197 edict_t *ent, *chain;
1199 chain = (edict_t *)sv.edicts;
1201 f = G_INT(OFS_PARM0);
1202 s = G_FLOAT(OFS_PARM1);
1204 ent = NEXT_EDICT(sv.edicts);
1205 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1209 if (E_FLOAT(ent,f) != s)
1212 ent->v.chain = EDICT_TO_PROG(chain);
1216 RETURN_EDICT(chain);
1219 void PR_CheckEmptyString (char *s)
1222 PR_RunError ("Bad string");
1225 void PF_precache_file (void)
1226 { // precache_file is only used to copy files with qcc, it does nothing
1227 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1230 void PF_precache_sound (void)
1235 if (sv.state != ss_loading)
1236 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1238 s = G_STRING(OFS_PARM0);
1239 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1240 PR_CheckEmptyString (s);
1242 for (i=0 ; i<MAX_SOUNDS ; i++)
1244 if (!sv.sound_precache[i])
1246 sv.sound_precache[i] = s;
1249 if (!strcmp(sv.sound_precache[i], s))
1252 PR_RunError ("PF_precache_sound: overflow");
1255 void PF_precache_model (void)
1260 if (sv.state != ss_loading)
1261 PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
1263 s = G_STRING(OFS_PARM0);
1264 if (sv.worldmodel->ishlbsp && ((!s) || (!s[0])))
1266 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1267 PR_CheckEmptyString (s);
1269 for (i=0 ; i<MAX_MODELS ; i++)
1271 if (!sv.model_precache[i])
1273 sv.model_precache[i] = s;
1274 sv.models[i] = Mod_ForName (s, true, false, false);
1277 if (!strcmp(sv.model_precache[i], s))
1280 PR_RunError ("PF_precache_model: overflow");
1284 void PF_coredump (void)
1289 void PF_traceon (void)
1294 void PF_traceoff (void)
1299 void PF_eprint (void)
1301 ED_PrintNum (G_EDICTNUM(OFS_PARM0));
1308 float(float yaw, float dist) walkmove
1311 void PF_walkmove (void)
1319 ent = PROG_TO_EDICT(pr_global_struct->self);
1320 yaw = G_FLOAT(OFS_PARM0);
1321 dist = G_FLOAT(OFS_PARM1);
1323 if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1325 G_FLOAT(OFS_RETURN) = 0;
1329 yaw = yaw*M_PI*2 / 360;
1331 move[0] = cos(yaw)*dist;
1332 move[1] = sin(yaw)*dist;
1335 // save program state, because SV_movestep may call other progs
1336 oldf = pr_xfunction;
1337 oldself = pr_global_struct->self;
1339 G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
1342 // restore program state
1343 pr_xfunction = oldf;
1344 pr_global_struct->self = oldself;
1354 void PF_droptofloor (void)
1360 ent = PROG_TO_EDICT(pr_global_struct->self);
1362 VectorCopy (ent->v.origin, end);
1365 trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
1367 if (trace.fraction == 1 || trace.allsolid)
1368 G_FLOAT(OFS_RETURN) = 0;
1371 VectorCopy (trace.endpos, ent->v.origin);
1372 SV_LinkEdict (ent, false);
1373 ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
1374 ent->v.groundentity = EDICT_TO_PROG(trace.ent);
1375 G_FLOAT(OFS_RETURN) = 1;
1376 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1377 ent->suspendedinairflag = true;
1385 void(float style, string value) lightstyle
1388 void PF_lightstyle (void)
1395 style = G_FLOAT(OFS_PARM0);
1396 val = G_STRING(OFS_PARM1);
1398 // change the string in sv
1399 sv.lightstyles[style] = val;
1401 // send message to all clients on this server
1402 if (sv.state != ss_active)
1405 for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
1406 if (client->active || client->spawned)
1408 MSG_WriteChar (&client->message, svc_lightstyle);
1409 MSG_WriteChar (&client->message,style);
1410 MSG_WriteString (&client->message, val);
1417 f = G_FLOAT(OFS_PARM0);
1419 G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1421 G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1423 void PF_floor (void)
1425 G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
1429 G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
1438 void PF_checkbottom (void)
1440 G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0));
1448 void PF_pointcontents (void)
1450 G_FLOAT(OFS_RETURN) = Mod_PointInLeaf(G_VECTOR(OFS_PARM0), sv.worldmodel)->contents;
1457 entity nextent(entity)
1460 void PF_nextent (void)
1465 i = G_EDICTNUM(OFS_PARM0);
1469 if (i == sv.num_edicts)
1471 RETURN_EDICT(sv.edicts);
1487 Pick a vector for the player to shoot along
1488 vector aim(entity, missilespeed)
1493 edict_t *ent, *check, *bestent;
1494 vec3_t start, dir, end, bestdir;
1497 float dist, bestdist;
1500 ent = G_EDICT(OFS_PARM0);
1501 speed = G_FLOAT(OFS_PARM1);
1503 VectorCopy (ent->v.origin, start);
1506 // try sending a trace straight
1507 VectorCopy (pr_global_struct->v_forward, dir);
1508 VectorMA (start, 2048, dir, end);
1509 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1510 if (tr.ent && ((edict_t *)tr.ent)->v.takedamage == DAMAGE_AIM
1511 && (!teamplay.integer || ent->v.team <=0 || ent->v.team != ((edict_t *)tr.ent)->v.team) )
1513 VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
1518 // try all possible entities
1519 VectorCopy (dir, bestdir);
1520 bestdist = sv_aim.value;
1523 check = NEXT_EDICT(sv.edicts);
1524 for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
1526 if (check->v.takedamage != DAMAGE_AIM)
1530 if (teamplay.integer && ent->v.team > 0 && ent->v.team == check->v.team)
1531 continue; // don't aim at teammate
1532 for (j=0 ; j<3 ; j++)
1533 end[j] = check->v.origin[j]
1534 + 0.5*(check->v.mins[j] + check->v.maxs[j]);
1535 VectorSubtract (end, start, dir);
1536 VectorNormalize (dir);
1537 dist = DotProduct (dir, pr_global_struct->v_forward);
1538 if (dist < bestdist)
1539 continue; // to far to turn
1540 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1541 if (tr.ent == check)
1542 { // can shoot at this one
1550 VectorSubtract (bestent->v.origin, ent->v.origin, dir);
1551 dist = DotProduct (dir, pr_global_struct->v_forward);
1552 VectorScale (pr_global_struct->v_forward, dist, end);
1554 VectorNormalize (end);
1555 VectorCopy (end, G_VECTOR(OFS_RETURN));
1559 VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
1567 This was a major timewaster in progs, so it was converted to C
1570 void PF_changeyaw (void)
1573 float ideal, current, move, speed;
1575 ent = PROG_TO_EDICT(pr_global_struct->self);
1576 current = ANGLEMOD(ent->v.angles[1]);
1577 ideal = ent->v.ideal_yaw;
1578 speed = ent->v.yaw_speed;
1580 if (current == ideal)
1582 move = ideal - current;
1583 if (ideal > current)
1604 ent->v.angles[1] = ANGLEMOD (current + move);
1612 void PF_changepitch (void)
1615 float ideal, current, move, speed;
1618 ent = G_EDICT(OFS_PARM0);
1619 current = ANGLEMOD( ent->v.angles[0] );
1620 if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
1621 ideal = val->_float;
1624 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1627 if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
1628 speed = val->_float;
1631 PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
1635 if (current == ideal)
1637 move = ideal - current;
1638 if (ideal > current)
1659 ent->v.angles[0] = ANGLEMOD (current + move);
1663 ===============================================================================
1667 ===============================================================================
1670 #define MSG_BROADCAST 0 // unreliable to all
1671 #define MSG_ONE 1 // reliable to one (msg_entity)
1672 #define MSG_ALL 2 // reliable to all
1673 #define MSG_INIT 3 // write to the init string
1675 sizebuf_t *WriteDest (void)
1681 dest = G_FLOAT(OFS_PARM0);
1685 return &sv.datagram;
1688 ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
1689 entnum = NUM_FOR_EDICT(ent);
1690 if (entnum < 1 || entnum > svs.maxclients)
1691 PR_RunError ("WriteDest: not a client");
1692 return &svs.clients[entnum-1].message;
1695 return &sv.reliable_datagram;
1701 PR_RunError ("WriteDest: bad destination");
1708 void PF_WriteByte (void)
1710 MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
1713 void PF_WriteChar (void)
1715 MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
1718 void PF_WriteShort (void)
1720 MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
1723 void PF_WriteLong (void)
1725 MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
1728 void PF_WriteAngle (void)
1730 MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
1733 void PF_WriteCoord (void)
1735 MSG_WriteDPCoord (WriteDest(), G_FLOAT(OFS_PARM1));
1738 void PF_WriteString (void)
1740 MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
1744 void PF_WriteEntity (void)
1746 MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
1749 //=============================================================================
1751 int SV_ModelIndex (char *name);
1753 void PF_makestatic (void)
1758 ent = G_EDICT(OFS_PARM0);
1761 if (ent->v.modelindex >= 256 || ent->v.frame >= 256)
1766 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1767 MSG_WriteShort (&sv.signon, ent->v.modelindex);
1768 MSG_WriteShort (&sv.signon, ent->v.frame);
1772 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1773 MSG_WriteByte (&sv.signon, ent->v.modelindex);
1774 MSG_WriteByte (&sv.signon, ent->v.frame);
1777 MSG_WriteByte (&sv.signon, ent->v.colormap);
1778 MSG_WriteByte (&sv.signon, ent->v.skin);
1779 for (i=0 ; i<3 ; i++)
1781 MSG_WriteDPCoord(&sv.signon, ent->v.origin[i]);
1782 MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
1785 // throw the entity away now
1789 //=============================================================================
1796 void PF_setspawnparms (void)
1802 ent = G_EDICT(OFS_PARM0);
1803 i = NUM_FOR_EDICT(ent);
1804 if (i < 1 || i > svs.maxclients)
1805 PR_RunError ("Entity is not a client");
1807 // copy spawn parms out of the client_t
1808 client = svs.clients + (i-1);
1810 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1811 (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
1819 void PF_changelevel (void)
1823 // make sure we don't issue two changelevels
1824 if (svs.changelevel_issued)
1826 svs.changelevel_issued = true;
1828 s = G_STRING(OFS_PARM0);
1829 Cbuf_AddText (va("changelevel %s\n",s));
1834 G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
1839 G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
1844 G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
1851 Returns a vector of length < 1
1856 void PF_randomvec (void)
1861 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1862 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1863 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1865 while (DotProduct(temp, temp) >= 1);
1866 VectorCopy (temp, G_VECTOR(OFS_RETURN));
1869 void SV_LightPoint (vec3_t color, vec3_t p);
1874 Returns a color vector indicating the lighting at the requested point.
1876 (Internal Operation note: actually measures the light beneath the point, just like
1877 the model lighting on the client)
1882 void PF_GetLight (void)
1886 p = G_VECTOR(OFS_PARM0);
1887 SV_LightPoint (color, p);
1888 VectorCopy (color, G_VECTOR(OFS_RETURN));
1891 #define MAX_QC_CVARS 128
1892 cvar_t qc_cvar[MAX_QC_CVARS];
1895 void PF_registercvar (void)
1899 name = G_STRING(OFS_PARM0);
1900 value = G_STRING(OFS_PARM1);
1901 G_FLOAT(OFS_RETURN) = 0;
1902 // first check to see if it has already been defined
1903 if (Cvar_FindVar (name))
1906 // check for overlap with a command
1907 if (Cmd_Exists (name))
1909 Con_Printf ("PF_registercvar: %s is a command\n", name);
1913 if (currentqc_cvar >= MAX_QC_CVARS)
1914 PR_RunError ("PF_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
1916 // copy the name and value
1917 variable = &qc_cvar[currentqc_cvar++];
1918 variable->name = Z_Malloc (strlen(name)+1);
1919 strcpy (variable->name, name);
1920 variable->string = Z_Malloc (strlen(value)+1);
1921 strcpy (variable->string, value);
1922 variable->value = atof (value);
1924 Cvar_RegisterVariable(variable);
1925 G_FLOAT(OFS_RETURN) = 1; // success
1932 returns the minimum of two supplied floats
1939 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1941 G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1942 else if (pr_argc >= 3)
1945 float f = G_FLOAT(OFS_PARM0);
1946 for (i = 1;i < pr_argc;i++)
1947 if (G_FLOAT((OFS_PARM0+i*3)) < f)
1948 f = G_FLOAT((OFS_PARM0+i*3));
1949 G_FLOAT(OFS_RETURN) = f;
1952 PR_RunError("min: must supply at least 2 floats\n");
1959 returns the maximum of two supplied floats
1966 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1968 G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
1969 else if (pr_argc >= 3)
1972 float f = G_FLOAT(OFS_PARM0);
1973 for (i = 1;i < pr_argc;i++)
1974 if (G_FLOAT((OFS_PARM0+i*3)) > f)
1975 f = G_FLOAT((OFS_PARM0+i*3));
1976 G_FLOAT(OFS_RETURN) = f;
1979 PR_RunError("max: must supply at least 2 floats\n");
1986 returns number bounded by supplied range
1988 min(min, value, max)
1991 void PF_bound (void)
1993 G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
2000 returns a raised to power b
2007 G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2014 copies data from one entity to another
2016 copyentity(src, dst)
2019 void PF_copyentity (void)
2022 in = G_EDICT(OFS_PARM0);
2023 out = G_EDICT(OFS_PARM1);
2024 memcpy(out, in, pr_edict_size);
2031 sets the color of a client and broadcasts the update to all connected clients
2033 setcolor(clientent, value)
2036 void PF_setcolor (void)
2041 entnum = G_EDICTNUM(OFS_PARM0);
2042 i = G_FLOAT(OFS_PARM1);
2044 if (entnum < 1 || entnum > svs.maxclients)
2046 Con_Printf ("tried to setcolor a non-client\n");
2050 client = &svs.clients[entnum-1];
2052 client->edict->v.team = (i & 15) + 1;
2054 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
2055 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
2056 MSG_WriteByte (&sv.reliable_datagram, i);
2063 effect(origin, modelname, startframe, framecount, framerate)
2066 void PF_effect (void)
2069 s = G_STRING(OFS_PARM1);
2071 PR_RunError("effect: no model specified\n");
2073 SV_StartEffect(G_VECTOR(OFS_PARM0), SV_ModelIndex(s), G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
2076 void PF_te_blood (void)
2078 if (G_FLOAT(OFS_PARM2) < 1)
2080 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2081 MSG_WriteByte(&sv.datagram, TE_BLOOD);
2083 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2084 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2085 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2087 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2088 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2089 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2091 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2094 void PF_te_bloodshower (void)
2096 if (G_FLOAT(OFS_PARM3) < 1)
2098 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2099 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
2101 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2102 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2103 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2105 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2106 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2107 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2109 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM2));
2111 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2114 void PF_te_explosionrgb (void)
2116 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2117 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
2119 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2120 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2121 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2123 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
2124 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
2125 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
2128 void PF_te_particlecube (void)
2130 if (G_FLOAT(OFS_PARM3) < 1)
2132 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2133 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
2135 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2136 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2137 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2139 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2140 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2141 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2143 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2144 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2145 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2147 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2149 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2150 // gravity true/false
2151 MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
2153 MSG_WriteDPCoord(&sv.datagram, G_FLOAT(OFS_PARM6));
2156 void PF_te_particlerain (void)
2158 if (G_FLOAT(OFS_PARM3) < 1)
2160 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2161 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
2163 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2164 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2165 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2167 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2168 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2169 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2171 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2172 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2173 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2175 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2177 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2180 void PF_te_particlesnow (void)
2182 if (G_FLOAT(OFS_PARM3) < 1)
2184 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2185 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
2187 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2188 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2189 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2191 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2192 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2193 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2195 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2196 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2197 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2199 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2201 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2204 void PF_te_spark (void)
2206 if (G_FLOAT(OFS_PARM2) < 1)
2208 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2209 MSG_WriteByte(&sv.datagram, TE_SPARK);
2211 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2212 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2213 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2215 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2216 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2217 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2219 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2222 void PF_te_gunshotquad (void)
2224 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2225 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
2227 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2228 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2229 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2232 void PF_te_spikequad (void)
2234 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2235 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
2237 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2238 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2239 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2242 void PF_te_superspikequad (void)
2244 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2245 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
2247 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2248 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2249 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2252 void PF_te_explosionquad (void)
2254 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2255 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2257 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2258 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2259 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2262 void PF_te_smallflash (void)
2264 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2265 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2267 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2268 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2269 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2272 void PF_te_customflash (void)
2274 if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2276 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2277 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2279 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2280 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2281 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2283 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2285 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255));
2287 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
2288 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
2289 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
2292 void PF_te_gunshot (void)
2294 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2295 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2297 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2298 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2299 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2302 void PF_te_spike (void)
2304 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2305 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2307 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2308 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2309 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2312 void PF_te_superspike (void)
2314 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2315 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2317 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2318 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2319 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2322 void PF_te_explosion (void)
2324 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2325 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2327 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2328 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2329 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2332 void PF_te_tarexplosion (void)
2334 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2335 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2337 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2338 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2339 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2342 void PF_te_wizspike (void)
2344 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2345 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2347 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2348 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2349 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2352 void PF_te_knightspike (void)
2354 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2355 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2357 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2358 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2359 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2362 void PF_te_lavasplash (void)
2364 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2365 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2367 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2368 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2369 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2372 void PF_te_teleport (void)
2374 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2375 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2377 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2378 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2379 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2382 void PF_te_explosion2 (void)
2384 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2385 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2387 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2388 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2389 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2391 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
2394 void PF_te_lightning1 (void)
2396 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2397 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2399 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2401 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2402 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2403 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2405 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2406 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2407 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2410 void PF_te_lightning2 (void)
2412 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2413 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2415 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2417 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2418 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2419 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2421 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2422 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2423 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2426 void PF_te_lightning3 (void)
2428 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2429 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2431 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2433 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2434 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2435 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2437 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2438 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2439 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2442 void PF_te_beam (void)
2444 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2445 MSG_WriteByte(&sv.datagram, TE_BEAM);
2447 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2449 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0]);
2450 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1]);
2451 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2]);
2453 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0]);
2454 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1]);
2455 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2]);
2458 void PF_te_plasmaburn (void)
2460 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2461 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2462 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0]);
2463 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1]);
2464 MSG_WriteDPCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2]);
2467 void PF_Fixme (void)
2469 PR_RunError ("unimplemented builtin"); // LordHavoc: was misspelled (bulitin)
2474 builtin_t pr_builtin[] =
2477 PF_makevectors, // void(entity e) makevectors = #1;
2478 PF_setorigin, // void(entity e, vector o) setorigin = #2;
2479 PF_setmodel, // void(entity e, string m) setmodel = #3;
2480 PF_setsize, // void(entity e, vector min, vector max) setsize = #4;
2481 PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5;
2482 PF_break, // void() break = #6;
2483 PF_random, // float() random = #7;
2484 PF_sound, // void(entity e, float chan, string samp) sound = #8;
2485 PF_normalize, // vector(vector v) normalize = #9;
2486 PF_error, // void(string e) error = #10;
2487 PF_objerror, // void(string e) objerror = #11;
2488 PF_vlen, // float(vector v) vlen = #12;
2489 PF_vectoyaw, // float(vector v) vectoyaw = #13;
2490 PF_Spawn, // entity() spawn = #14;
2491 PF_Remove, // void(entity e) remove = #15;
2492 PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16;
2493 PF_checkclient, // entity() clientlist = #17;
2494 PF_Find, // entity(entity start, .string fld, string match) find = #18;
2495 PF_precache_sound, // void(string s) precache_sound = #19;
2496 PF_precache_model, // void(string s) precache_model = #20;
2497 PF_stuffcmd, // void(entity client, string s)stuffcmd = #21;
2498 PF_findradius, // entity(vector org, float rad) findradius = #22;
2499 PF_bprint, // void(string s) bprint = #23;
2500 PF_sprint, // void(entity client, string s) sprint = #24;
2501 PF_dprint, // void(string s) dprint = #25;
2502 PF_ftos, // void(string s) ftos = #26;
2503 PF_vtos, // void(string s) vtos = #27;
2507 PF_eprint, // void(entity e) debug print an entire entity
2508 PF_walkmove, // float(float yaw, float dist) walkmove
2509 PF_Fixme, // float(float yaw, float dist) walkmove
2559 PF_precache_sound, // precache_sound2 is different only for qcc
2564 PF_Fixme, // #79 LordHavoc: dunno who owns 79-89, so these are just padding
2576 PF_tracebox, // #90 LordHavoc builtin range (9x)
2577 PF_randomvec, // #91
2579 PF_registercvar, // #93
2584 PF_FindFloat, // #98
2585 PF_checkextension, // #99
2586 #define a PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme,
2587 #define aa a a a a a a a a a a
2591 PF_copyentity, // #400 LordHavoc: builtin range (4xx)
2592 PF_setcolor, // #401
2593 PF_findchain, // #402
2594 PF_findchainfloat, // #403
2596 PF_te_blood, // #405
2597 PF_te_bloodshower, // #406
2598 PF_te_explosionrgb, // #407
2599 PF_te_particlecube, // #408
2600 PF_te_particlerain, // #409
2601 PF_te_particlesnow, // #410
2602 PF_te_spark, // #411
2603 PF_te_gunshotquad, // #412
2604 PF_te_spikequad, // #413
2605 PF_te_superspikequad, // #414
2606 PF_te_explosionquad, // #415
2607 PF_te_smallflash, // #416
2608 PF_te_customflash, // #417
2609 PF_te_gunshot, // #418
2610 PF_te_spike, // #419
2611 PF_te_superspike, // #420
2612 PF_te_explosion, // #421
2613 PF_te_tarexplosion, // #422
2614 PF_te_wizspike, // #423
2615 PF_te_knightspike, // #424
2616 PF_te_lavasplash, // #425
2617 PF_te_teleport, // #426
2618 PF_te_explosion2, // #427
2619 PF_te_lightning1, // #428
2620 PF_te_lightning2, // #429
2621 PF_te_lightning3, // #430
2623 PF_vectorvectors, // #432
2624 PF_te_plasmaburn, // #433
2627 builtin_t *pr_builtins = pr_builtin;
2628 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);