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
24 cvar_t pr_zone_min_strings = {0, "pr_zone_min_strings", "64"};
26 mempool_t *pr_strings_mempool;
28 // LordHavoc: added this to semi-fix the problem of using many ftos calls in a print
29 #define STRINGTEMP_BUFFERS 16
30 #define STRINGTEMP_LENGTH 4096
31 static char pr_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH];
32 static int pr_string_tempindex = 0;
34 static char *PR_GetTempString(void)
37 s = pr_string_temp[pr_string_tempindex];
38 pr_string_tempindex = (pr_string_tempindex + 1) % STRINGTEMP_BUFFERS;
42 #define RETURN_EDICT(e) (G_INT(OFS_RETURN) = EDICT_TO_PROG(e))
43 #define PF_WARNING(s) do{Con_Printf(s);PR_PrintState();return;}while(0)
44 #define PF_ERROR(s) do{Host_Error(s);return;}while(0)
48 ===============================================================================
52 ===============================================================================
56 void PF_VarString(int first, char *out, int outlength)
62 outend = out + outlength - 1;
63 for (i = first;i < pr_argc && out < outend;i++)
65 s = G_STRING((OFS_PARM0+i*3));
66 while (out < outend && *s)
72 char *ENGINE_EXTENSIONS =
83 "DP_ENT_CUSTOMCOLORMAP "
84 "DP_ENT_EXTERIORMODELTOCLIENT "
86 "DP_ENT_LOWPRECISION "
89 "DP_GFX_EXTERNALTEXTURES "
91 "DP_GFX_QUAKE3MODELTAGS "
95 "DP_HALFLIFE_MAP_CVAR "
99 "DP_MOVETYPEBOUNCEMISSILE "
106 "DP_QC_FINDCHAINFLAGS "
107 "DP_QC_FINDCHAINFLOAT "
110 "DP_QC_FS_SEARCH " // Black: same as in the menu qc
114 "DP_QC_MULTIPLETEMPSTRINGS "
116 "DP_QC_SINCOSSQRTPOW "
119 "DP_QC_TRACE_MOVETYPE_HITMODEL "
120 "DP_QC_TRACE_MOVETYPE_WORLDONLY "
121 "DP_QC_VECTORVECTORS "
125 "DP_SND_DIRECTIONLESSATTNNONE "
130 "DP_SV_DRAWONLYTOCLIENT "
132 "DP_SV_EXTERIORMODELTOCLIENT "
133 "DP_SV_NODRAWTOCLIENT "
134 "DP_SV_PLAYERPHYSICS "
135 "DP_SV_ROTATINGBMODEL "
141 "DP_TE_EXPLOSIONRGB "
143 "DP_TE_PARTICLECUBE "
144 "DP_TE_PARTICLERAIN "
145 "DP_TE_PARTICLESNOW "
147 "DP_TE_QUADEFFECTS1 "
150 "DP_TE_STANDARDEFFECTBUILTINS "
153 "KRIMZON_SV_PARSECLIENTCOMMAND "
156 "TENEBRAE_GFX_DLIGHTS "
160 qboolean checkextension(char *name)
165 for (e = ENGINE_EXTENSIONS;*e;e++)
172 while (*e && *e != ' ')
174 if (e - start == len)
175 if (!strncasecmp(start, name, len))
185 returns true if the extension is supported by the server
187 checkextension(extensionname)
190 void PF_checkextension (void)
192 G_FLOAT(OFS_RETURN) = checkextension(G_STRING(OFS_PARM0));
199 This is a TERMINAL error, which will kill off the entire server.
208 char string[STRINGTEMP_LENGTH];
210 PF_VarString(0, string, sizeof(string));
211 Con_Printf("======SERVER ERROR in %s:\n%s\n", PR_GetString(pr_xfunction->s_name), string);
212 ed = PROG_TO_EDICT(pr_global_struct->self);
215 PF_ERROR("Program error");
222 Dumps out self, then an error message. The program is aborted and self is
223 removed, but the level can continue.
228 void PF_objerror (void)
231 char string[STRINGTEMP_LENGTH];
233 PF_VarString(0, string, sizeof(string));
234 Con_Printf("======OBJECT ERROR in %s:\n%s\n", PR_GetString(pr_xfunction->s_name), string);
235 ed = PROG_TO_EDICT(pr_global_struct->self);
245 Writes new values for v_forward, v_up, and v_right based on angles
249 void PF_makevectors (void)
251 AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
258 Writes new values for v_forward, v_up, and v_right based on the given forward vector
259 vectorvectors(vector, vector)
262 void PF_vectorvectors (void)
264 VectorNormalize2(G_VECTOR(OFS_PARM0), pr_global_struct->v_forward);
265 VectorVectors(pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
272 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.
274 setorigin (entity, origin)
277 void PF_setorigin (void)
282 e = G_EDICT(OFS_PARM0);
284 PF_WARNING("setorigin: can not modify world entity\n");
286 PF_WARNING("setorigin: can not modify free entity\n");
287 org = G_VECTOR(OFS_PARM1);
288 VectorCopy (org, e->v->origin);
289 SV_LinkEdict (e, false);
293 void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
297 for (i=0 ; i<3 ; i++)
299 PF_ERROR("SetMinMaxSize: backwards mins/maxs\n");
301 // set derived values
302 VectorCopy (min, e->v->mins);
303 VectorCopy (max, e->v->maxs);
304 VectorSubtract (max, min, e->v->size);
306 SV_LinkEdict (e, false);
313 the size box is rotated by the current angle
314 LordHavoc: no it isn't...
316 setsize (entity, minvector, maxvector)
319 void PF_setsize (void)
324 e = G_EDICT(OFS_PARM0);
326 PF_WARNING("setsize: can not modify world entity\n");
328 PF_WARNING("setsize: can not modify free entity\n");
329 min = G_VECTOR(OFS_PARM1);
330 max = G_VECTOR(OFS_PARM2);
331 SetMinMaxSize (e, min, max, false);
339 setmodel(entity, model)
342 void PF_setmodel (void)
349 e = G_EDICT(OFS_PARM0);
351 PF_WARNING("setmodel: can not modify world entity\n");
353 PF_WARNING("setmodel: can not modify free entity\n");
354 m = G_STRING(OFS_PARM1);
356 // check to see if model was properly precached
357 for (i=0, check = sv.model_precache ; *check ; i++, check++)
358 if (!strcmp(*check, m))
362 PF_WARNING("setmodel: no precache\n");
365 e->v->model = PR_SetString(*check);
366 e->v->modelindex = i;
368 mod = sv.models[ (int)e->v->modelindex];
371 SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
373 SetMinMaxSize (e, vec3_origin, vec3_origin, true);
380 broadcast print to everyone on server
385 void PF_bprint (void)
387 char string[STRINGTEMP_LENGTH];
388 PF_VarString(0, string, sizeof(string));
389 SV_BroadcastPrint(string);
396 single print to a specific client
398 sprint(clientent, value)
401 void PF_sprint (void)
405 char string[STRINGTEMP_LENGTH];
407 entnum = G_EDICTNUM(OFS_PARM0);
409 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
411 Con_Print("tried to sprint to a non-client\n");
415 client = svs.clients + entnum-1;
416 if (!client->netconnection)
418 PF_VarString(1, string, sizeof(string));
419 MSG_WriteChar(&client->message,svc_print);
420 MSG_WriteString(&client->message, string);
428 single print to a specific client
430 centerprint(clientent, value)
433 void PF_centerprint (void)
437 char string[STRINGTEMP_LENGTH];
439 entnum = G_EDICTNUM(OFS_PARM0);
441 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
443 Con_Print("tried to sprint to a non-client\n");
447 client = svs.clients + entnum-1;
448 if (!client->netconnection)
450 PF_VarString(1, string, sizeof(string));
451 MSG_WriteChar(&client->message,svc_centerprint);
452 MSG_WriteString(&client->message, string);
460 vector normalize(vector)
463 void PF_normalize (void)
469 value1 = G_VECTOR(OFS_PARM0);
471 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
475 newvalue[0] = newvalue[1] = newvalue[2] = 0;
479 newvalue[0] = value1[0] * new;
480 newvalue[1] = value1[1] * new;
481 newvalue[2] = value1[2] * new;
484 VectorCopy (newvalue, G_VECTOR(OFS_RETURN));
499 value1 = G_VECTOR(OFS_PARM0);
501 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
504 G_FLOAT(OFS_RETURN) = new;
511 float vectoyaw(vector)
514 void PF_vectoyaw (void)
519 value1 = G_VECTOR(OFS_PARM0);
521 if (value1[1] == 0 && value1[0] == 0)
525 yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
530 G_FLOAT(OFS_RETURN) = yaw;
538 vector vectoangles(vector)
541 void PF_vectoangles (void)
543 double value1[3], forward, yaw, pitch;
545 VectorCopy(G_VECTOR(OFS_PARM0), value1);
547 if (value1[1] == 0 && value1[0] == 0)
557 // LordHavoc: optimized a bit
560 yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
564 else if (value1[1] > 0)
569 forward = sqrt(value1[0]*value1[0] + value1[1]*value1[1]);
570 pitch = (atan2(value1[2], forward) * 180 / M_PI);
575 VectorSet(G_VECTOR(OFS_RETURN), pitch, yaw, 0);
582 Returns a number from 0<= num < 1
587 void PF_random (void)
591 num = (rand ()&0x7fff) / ((float)0x7fff);
593 G_FLOAT(OFS_RETURN) = num;
600 particle(origin, color, count)
603 void PF_particle (void)
609 org = G_VECTOR(OFS_PARM0);
610 dir = G_VECTOR(OFS_PARM1);
611 color = G_FLOAT(OFS_PARM2);
612 count = G_FLOAT(OFS_PARM3);
613 SV_StartParticle (org, dir, color, count);
623 void PF_ambientsound (void)
628 float vol, attenuation;
631 pos = G_VECTOR (OFS_PARM0);
632 samp = G_STRING(OFS_PARM1);
633 vol = G_FLOAT(OFS_PARM2);
634 attenuation = G_FLOAT(OFS_PARM3);
636 // check to see if samp was properly precached
637 for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++)
638 if (!strcmp(*check,samp))
643 Con_Printf("no precache: %s\n", samp);
651 // add an svc_spawnambient command to the level signon packet
654 MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
656 MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
658 MSG_WriteVector(&sv.signon, pos, sv.protocol);
661 MSG_WriteShort (&sv.signon, soundnum);
663 MSG_WriteByte (&sv.signon, soundnum);
665 MSG_WriteByte (&sv.signon, vol*255);
666 MSG_WriteByte (&sv.signon, attenuation*64);
674 Each entity can have eight independant sound sources, like voice,
677 Channel 0 is an auto-allocate channel, the others override anything
678 already running on that entity/channel pair.
680 An attenuation of 0 will play full volume everywhere in the level.
681 Larger attenuations will drop off.
693 entity = G_EDICT(OFS_PARM0);
694 channel = G_FLOAT(OFS_PARM1);
695 sample = G_STRING(OFS_PARM2);
696 volume = G_FLOAT(OFS_PARM3) * 255;
697 attenuation = G_FLOAT(OFS_PARM4);
699 if (volume < 0 || volume > 255)
700 PF_WARNING("SV_StartSound: volume must be in range 0-1\n");
702 if (attenuation < 0 || attenuation > 4)
703 PF_WARNING("SV_StartSound: attenuation must be in range 0-4\n");
705 if (channel < 0 || channel > 7)
706 PF_WARNING("SV_StartSound: channel must be in range 0-7\n");
708 SV_StartSound (entity, channel, sample, volume, attenuation);
720 PF_ERROR("break: break statement\n");
727 Used for use tracing and shot targeting
728 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
729 if the tryents flag is set.
731 traceline (vector1, vector2, tryents)
734 void PF_traceline (void)
741 pr_xfunction->builtinsprofile += 30;
743 v1 = G_VECTOR(OFS_PARM0);
744 v2 = G_VECTOR(OFS_PARM1);
745 move = G_FLOAT(OFS_PARM2);
746 ent = G_EDICT(OFS_PARM3);
748 trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent);
750 pr_global_struct->trace_allsolid = trace.allsolid;
751 pr_global_struct->trace_startsolid = trace.startsolid;
752 pr_global_struct->trace_fraction = trace.fraction;
753 pr_global_struct->trace_inwater = trace.inwater;
754 pr_global_struct->trace_inopen = trace.inopen;
755 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
756 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
757 pr_global_struct->trace_plane_dist = trace.plane.dist;
759 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
761 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
762 // FIXME: add trace_endcontents
770 Used for use tracing and shot targeting
771 Traces are blocked by bbox and exact bsp entityes, and also slide box entities
772 if the tryents flag is set.
774 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
777 // LordHavoc: added this for my own use, VERY useful, similar to traceline
778 void PF_tracebox (void)
780 float *v1, *v2, *m1, *m2;
785 pr_xfunction->builtinsprofile += 30;
787 v1 = G_VECTOR(OFS_PARM0);
788 m1 = G_VECTOR(OFS_PARM1);
789 m2 = G_VECTOR(OFS_PARM2);
790 v2 = G_VECTOR(OFS_PARM3);
791 move = G_FLOAT(OFS_PARM4);
792 ent = G_EDICT(OFS_PARM5);
794 trace = SV_Move (v1, m1, m2, v2, move, ent);
796 pr_global_struct->trace_allsolid = trace.allsolid;
797 pr_global_struct->trace_startsolid = trace.startsolid;
798 pr_global_struct->trace_fraction = trace.fraction;
799 pr_global_struct->trace_inwater = trace.inwater;
800 pr_global_struct->trace_inopen = trace.inopen;
801 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
802 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
803 pr_global_struct->trace_plane_dist = trace.plane.dist;
805 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
807 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
810 extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore);
811 void PF_TraceToss (void)
817 pr_xfunction->builtinsprofile += 600;
819 ent = G_EDICT(OFS_PARM0);
820 if (ent == sv.edicts)
821 PF_WARNING("tracetoss: can not use world entity\n");
822 ignore = G_EDICT(OFS_PARM1);
824 trace = SV_Trace_Toss (ent, ignore);
826 pr_global_struct->trace_allsolid = trace.allsolid;
827 pr_global_struct->trace_startsolid = trace.startsolid;
828 pr_global_struct->trace_fraction = trace.fraction;
829 pr_global_struct->trace_inwater = trace.inwater;
830 pr_global_struct->trace_inopen = trace.inopen;
831 VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
832 VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
833 pr_global_struct->trace_plane_dist = trace.plane.dist;
835 pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
837 pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
845 Returns true if the given entity can move to the given position from it's
846 current position by walking or rolling.
848 scalar checkpos (entity, vector)
851 void PF_checkpos (void)
855 //============================================================================
858 qbyte checkpvs[MAX_MAP_LEAFS/8];
860 int PF_newcheckclient (int check)
866 // cycle to the next one
868 check = bound(1, check, svs.maxclients);
869 if (check == svs.maxclients)
877 pr_xfunction->builtinsprofile++;
879 if (i == svs.maxclients+1)
881 // look up the client's edict
883 // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
884 if (i != check && (ent->e->free || ent->v->health <= 0 || ((int)ent->v->flags & FL_NOTARGET)))
886 // found a valid client (possibly the same one again)
890 // get the PVS for the entity
891 VectorAdd(ent->v->origin, ent->v->view_ofs, org);
893 if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
894 checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
903 Returns a client (or object that has a client enemy) that would be a
906 If there is more than one valid option, they are cycled each frame
908 If (self.origin + self.viewofs) is not in the PVS of the current target,
909 it is not returned at all.
914 int c_invis, c_notvis;
915 void PF_checkclient (void)
920 // find a new check if on a new frame
921 if (sv.time - sv.lastchecktime >= 0.1)
923 sv.lastcheck = PF_newcheckclient (sv.lastcheck);
924 sv.lastchecktime = sv.time;
927 // return check if it might be visible
928 ent = EDICT_NUM(sv.lastcheck);
929 if (ent->e->free || ent->v->health <= 0)
931 RETURN_EDICT(sv.edicts);
935 // if current entity can't possibly see the check entity, return 0
936 self = PROG_TO_EDICT(pr_global_struct->self);
937 VectorAdd(self->v->origin, self->v->view_ofs, view);
938 if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
941 RETURN_EDICT(sv.edicts);
945 // might be able to see it
950 //============================================================================
957 Sends text over to the client's execution buffer
959 stuffcmd (clientent, value)
962 void PF_stuffcmd (void)
968 entnum = G_EDICTNUM(OFS_PARM0);
969 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
971 Con_Print("Can't stuffcmd to a non-client\n");
974 str = G_STRING(OFS_PARM1);
977 if ((host_client = svs.clients + entnum-1) && host_client->netconnection)
978 Host_ClientCommands ("%s", str);
986 Sends text to server console
991 void PF_localcmd (void)
993 Cbuf_AddText(G_STRING(OFS_PARM0));
1005 G_FLOAT(OFS_RETURN) = Cvar_VariableValue(G_STRING(OFS_PARM0));
1015 void PF_cvar_set (void)
1017 Cvar_Set(G_STRING(OFS_PARM0), G_STRING(OFS_PARM1));
1024 Returns a chain of entities that have origins within a spherical area
1026 findradius (origin, radius)
1029 void PF_findradius (void)
1031 edict_t *ent, *chain;
1038 chain = (edict_t *)sv.edicts;
1040 org = G_VECTOR(OFS_PARM0);
1041 radius = G_FLOAT(OFS_PARM1);
1042 radius2 = radius * radius;
1044 ent = NEXT_EDICT(sv.edicts);
1045 for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
1047 pr_xfunction->builtinsprofile++;
1050 if (ent->v->solid == SOLID_NOT)
1053 // LordHavoc: compare against bounding box rather than center,
1054 // and use DotProduct instead of Length, major speedup
1055 eorg[0] = (org[0] - ent->v->origin[0]) - bound(ent->v->mins[0], (org[0] - ent->v->origin[0]), ent->v->maxs[0]);
1056 eorg[1] = (org[1] - ent->v->origin[1]) - bound(ent->v->mins[1], (org[1] - ent->v->origin[1]), ent->v->maxs[1]);
1057 eorg[2] = (org[2] - ent->v->origin[2]) - bound(ent->v->mins[2], (org[2] - ent->v->origin[2]), ent->v->maxs[2]);
1058 if (DotProduct(eorg, eorg) > radius2)
1061 ent->v->chain = EDICT_TO_PROG(chain);
1065 RETURN_EDICT(chain);
1074 void PF_dprint (void)
1076 char string[STRINGTEMP_LENGTH];
1077 if (developer.integer)
1079 PF_VarString(0, string, sizeof(string));
1088 v = G_FLOAT(OFS_PARM0);
1090 s = PR_GetTempString();
1091 if ((float)((int)v) == v)
1092 sprintf(s, "%i", (int)v);
1094 sprintf(s, "%f", v);
1095 G_INT(OFS_RETURN) = PR_SetString(s);
1101 v = G_FLOAT(OFS_PARM0);
1102 G_FLOAT(OFS_RETURN) = fabs(v);
1108 s = PR_GetTempString();
1109 sprintf (s, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
1110 G_INT(OFS_RETURN) = PR_SetString(s);
1116 s = PR_GetTempString();
1117 sprintf (s, "entity %i", G_EDICTNUM(OFS_PARM0));
1118 G_INT(OFS_RETURN) = PR_SetString(s);
1121 void PF_Spawn (void)
1124 pr_xfunction->builtinsprofile += 20;
1129 void PF_Remove (void)
1132 pr_xfunction->builtinsprofile += 20;
1134 ed = G_EDICT(OFS_PARM0);
1135 if (ed == sv.edicts)
1136 PF_WARNING("remove: tried to remove world\n");
1137 if (NUM_FOR_EDICT(ed) <= svs.maxclients)
1138 PF_WARNING("remove: tried to remove a client\n");
1139 // LordHavoc: not an error because id1 progs did this in some cases (killtarget removes entities, even if they are already removed in some cases...)
1140 if (ed->e->free && developer.integer)
1141 PF_WARNING("remove: tried to remove an entity that was already removed\n");
1146 // entity (entity start, .string field, string match) find = #5;
1154 e = G_EDICTNUM(OFS_PARM0);
1155 f = G_INT(OFS_PARM1);
1156 s = G_STRING(OFS_PARM2);
1159 RETURN_EDICT(sv.edicts);
1163 for (e++ ; e < sv.num_edicts ; e++)
1165 pr_xfunction->builtinsprofile++;
1179 RETURN_EDICT(sv.edicts);
1182 // LordHavoc: added this for searching float, int, and entity reference fields
1183 void PF_FindFloat (void)
1190 e = G_EDICTNUM(OFS_PARM0);
1191 f = G_INT(OFS_PARM1);
1192 s = G_FLOAT(OFS_PARM2);
1194 for (e++ ; e < sv.num_edicts ; e++)
1196 pr_xfunction->builtinsprofile++;
1200 if (E_FLOAT(ed,f) == s)
1207 RETURN_EDICT(sv.edicts);
1210 // chained search for strings in entity fields
1211 // entity(.string field, string match) findchain = #402;
1212 void PF_findchain (void)
1217 edict_t *ent, *chain;
1219 chain = (edict_t *)sv.edicts;
1221 f = G_INT(OFS_PARM0);
1222 s = G_STRING(OFS_PARM1);
1225 RETURN_EDICT(sv.edicts);
1229 ent = NEXT_EDICT(sv.edicts);
1230 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1232 pr_xfunction->builtinsprofile++;
1235 t = E_STRING(ent,f);
1241 ent->v->chain = EDICT_TO_PROG(chain);
1245 RETURN_EDICT(chain);
1248 // LordHavoc: chained search for float, int, and entity reference fields
1249 // entity(.string field, float match) findchainfloat = #403;
1250 void PF_findchainfloat (void)
1255 edict_t *ent, *chain;
1257 chain = (edict_t *)sv.edicts;
1259 f = G_INT(OFS_PARM0);
1260 s = G_FLOAT(OFS_PARM1);
1262 ent = NEXT_EDICT(sv.edicts);
1263 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1265 pr_xfunction->builtinsprofile++;
1268 if (E_FLOAT(ent,f) != s)
1271 ent->v->chain = EDICT_TO_PROG(chain);
1275 RETURN_EDICT(chain);
1278 // LordHavoc: search for flags in float fields
1279 void PF_findflags (void)
1286 e = G_EDICTNUM(OFS_PARM0);
1287 f = G_INT(OFS_PARM1);
1288 s = (int)G_FLOAT(OFS_PARM2);
1290 for (e++ ; e < sv.num_edicts ; e++)
1292 pr_xfunction->builtinsprofile++;
1296 if ((int)E_FLOAT(ed,f) & s)
1303 RETURN_EDICT(sv.edicts);
1306 // LordHavoc: chained search for flags in float fields
1307 void PF_findchainflags (void)
1312 edict_t *ent, *chain;
1314 chain = (edict_t *)sv.edicts;
1316 f = G_INT(OFS_PARM0);
1317 s = (int)G_FLOAT(OFS_PARM1);
1319 ent = NEXT_EDICT(sv.edicts);
1320 for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
1322 pr_xfunction->builtinsprofile++;
1325 if (!((int)E_FLOAT(ent,f) & s))
1328 ent->v->chain = EDICT_TO_PROG(chain);
1332 RETURN_EDICT(chain);
1335 void PR_CheckEmptyString (char *s)
1338 PF_ERROR("Bad string");
1341 void PF_precache_file (void)
1342 { // precache_file is only used to copy files with qcc, it does nothing
1343 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1346 void PF_precache_sound (void)
1350 int limit = (sv.protocol == PROTOCOL_QUAKE ? 256 : MAX_SOUNDS);
1352 if (sv.state != ss_loading)
1353 PF_ERROR("PF_Precache_*: Precache can only be done in spawn functions");
1355 s = G_STRING(OFS_PARM0);
1356 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1357 PR_CheckEmptyString (s);
1359 for (i=0 ; i<limit ; i++)
1361 if (!sv.sound_precache[i])
1363 sv.sound_precache[i] = s;
1366 if (!strcmp(sv.sound_precache[i], s))
1369 PF_ERROR("PF_precache_sound: overflow");
1372 void PF_precache_model (void)
1376 int limit = (sv.protocol == PROTOCOL_QUAKE ? 256 : MAX_MODELS);
1378 if (sv.state != ss_loading)
1379 PF_ERROR("PF_Precache_*: Precache can only be done in spawn functions");
1381 s = G_STRING(OFS_PARM0);
1382 if (sv.worldmodel->brush.ishlbsp && ((!s) || (!s[0])))
1384 G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
1385 PR_CheckEmptyString (s);
1387 for (i = 0;i < limit;i++)
1389 if (!sv.model_precache[i])
1391 sv.model_precache[i] = s;
1392 sv.models[i] = Mod_ForName (s, true, false, false);
1395 if (!strcmp(sv.model_precache[i], s))
1398 PF_ERROR("PF_precache_model: overflow");
1402 void PF_coredump (void)
1407 void PF_traceon (void)
1412 void PF_traceoff (void)
1417 void PF_eprint (void)
1419 ED_PrintNum (G_EDICTNUM(OFS_PARM0));
1426 float(float yaw, float dist) walkmove
1429 void PF_walkmove (void)
1437 // assume failure if it returns early
1438 G_FLOAT(OFS_RETURN) = 0;
1440 ent = PROG_TO_EDICT(pr_global_struct->self);
1441 if (ent == sv.edicts)
1442 PF_WARNING("walkmove: can not modify world entity\n");
1444 PF_WARNING("walkmove: can not modify free entity\n");
1445 yaw = G_FLOAT(OFS_PARM0);
1446 dist = G_FLOAT(OFS_PARM1);
1448 if ( !( (int)ent->v->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
1451 yaw = yaw*M_PI*2 / 360;
1453 move[0] = cos(yaw)*dist;
1454 move[1] = sin(yaw)*dist;
1457 // save program state, because SV_movestep may call other progs
1458 oldf = pr_xfunction;
1459 oldself = pr_global_struct->self;
1461 G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
1464 // restore program state
1465 pr_xfunction = oldf;
1466 pr_global_struct->self = oldself;
1476 void PF_droptofloor (void)
1482 // assume failure if it returns early
1483 G_FLOAT(OFS_RETURN) = 0;
1485 ent = PROG_TO_EDICT(pr_global_struct->self);
1486 if (ent == sv.edicts)
1487 PF_WARNING("droptofloor: can not modify world entity\n");
1489 PF_WARNING("droptofloor: can not modify free entity\n");
1491 VectorCopy (ent->v->origin, end);
1494 trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent);
1496 if (trace.fraction != 1)
1498 VectorCopy (trace.endpos, ent->v->origin);
1499 SV_LinkEdict (ent, false);
1500 ent->v->flags = (int)ent->v->flags | FL_ONGROUND;
1501 ent->v->groundentity = EDICT_TO_PROG(trace.ent);
1502 G_FLOAT(OFS_RETURN) = 1;
1503 // if support is destroyed, keep suspended (gross hack for floating items in various maps)
1504 ent->e->suspendedinairflag = true;
1512 void(float style, string value) lightstyle
1515 void PF_lightstyle (void)
1522 style = G_FLOAT(OFS_PARM0);
1523 val = G_STRING(OFS_PARM1);
1525 // change the string in sv
1526 sv.lightstyles[style] = val;
1528 // send message to all clients on this server
1529 if (sv.state != ss_active)
1532 for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
1534 if (client->netconnection)
1536 MSG_WriteChar (&client->message, svc_lightstyle);
1537 MSG_WriteChar (&client->message,style);
1538 MSG_WriteString (&client->message, val);
1546 f = G_FLOAT(OFS_PARM0);
1548 G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1550 G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1552 void PF_floor (void)
1554 G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
1558 G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
1567 void PF_checkbottom (void)
1569 G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0));
1577 void PF_pointcontents (void)
1579 G_FLOAT(OFS_RETURN) = SV_PointQ1Contents(G_VECTOR(OFS_PARM0));
1586 entity nextent(entity)
1589 void PF_nextent (void)
1594 i = G_EDICTNUM(OFS_PARM0);
1597 pr_xfunction->builtinsprofile++;
1599 if (i == sv.num_edicts)
1601 RETURN_EDICT(sv.edicts);
1617 Pick a vector for the player to shoot along
1618 vector aim(entity, missilespeed)
1623 edict_t *ent, *check, *bestent;
1624 vec3_t start, dir, end, bestdir;
1627 float dist, bestdist;
1630 // assume failure if it returns early
1631 VectorClear(G_VECTOR(OFS_RETURN));
1633 ent = G_EDICT(OFS_PARM0);
1634 if (ent == sv.edicts)
1635 PF_WARNING("aim: can not use world entity\n");
1637 PF_WARNING("aim: can not use free entity\n");
1638 speed = G_FLOAT(OFS_PARM1);
1640 VectorCopy (ent->v->origin, start);
1643 // try sending a trace straight
1644 VectorCopy (pr_global_struct->v_forward, dir);
1645 VectorMA (start, 2048, dir, end);
1646 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1647 if (tr.ent && ((edict_t *)tr.ent)->v->takedamage == DAMAGE_AIM
1648 && (!teamplay.integer || ent->v->team <=0 || ent->v->team != ((edict_t *)tr.ent)->v->team) )
1650 VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
1655 // try all possible entities
1656 VectorCopy (dir, bestdir);
1657 bestdist = sv_aim.value;
1660 check = NEXT_EDICT(sv.edicts);
1661 for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
1663 pr_xfunction->builtinsprofile++;
1664 if (check->v->takedamage != DAMAGE_AIM)
1668 if (teamplay.integer && ent->v->team > 0 && ent->v->team == check->v->team)
1669 continue; // don't aim at teammate
1670 for (j=0 ; j<3 ; j++)
1671 end[j] = check->v->origin[j]
1672 + 0.5*(check->v->mins[j] + check->v->maxs[j]);
1673 VectorSubtract (end, start, dir);
1674 VectorNormalize (dir);
1675 dist = DotProduct (dir, pr_global_struct->v_forward);
1676 if (dist < bestdist)
1677 continue; // to far to turn
1678 tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
1679 if (tr.ent == check)
1680 { // can shoot at this one
1688 VectorSubtract (bestent->v->origin, ent->v->origin, dir);
1689 dist = DotProduct (dir, pr_global_struct->v_forward);
1690 VectorScale (pr_global_struct->v_forward, dist, end);
1692 VectorNormalize (end);
1693 VectorCopy (end, G_VECTOR(OFS_RETURN));
1697 VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
1705 This was a major timewaster in progs, so it was converted to C
1708 void PF_changeyaw (void)
1711 float ideal, current, move, speed;
1713 ent = PROG_TO_EDICT(pr_global_struct->self);
1714 if (ent == sv.edicts)
1715 PF_WARNING("changeyaw: can not modify world entity\n");
1717 PF_WARNING("changeyaw: can not modify free entity\n");
1718 current = ANGLEMOD(ent->v->angles[1]);
1719 ideal = ent->v->ideal_yaw;
1720 speed = ent->v->yaw_speed;
1722 if (current == ideal)
1724 move = ideal - current;
1725 if (ideal > current)
1746 ent->v->angles[1] = ANGLEMOD (current + move);
1754 void PF_changepitch (void)
1757 float ideal, current, move, speed;
1760 ent = G_EDICT(OFS_PARM0);
1761 if (ent == sv.edicts)
1762 PF_WARNING("changepitch: can not modify world entity\n");
1764 PF_WARNING("changepitch: can not modify free entity\n");
1765 current = ANGLEMOD( ent->v->angles[0] );
1766 if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
1767 ideal = val->_float;
1770 PF_WARNING("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch\n");
1773 if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
1774 speed = val->_float;
1777 PF_WARNING("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch\n");
1781 if (current == ideal)
1783 move = ideal - current;
1784 if (ideal > current)
1805 ent->v->angles[0] = ANGLEMOD (current + move);
1809 ===============================================================================
1813 ===============================================================================
1816 #define MSG_BROADCAST 0 // unreliable to all
1817 #define MSG_ONE 1 // reliable to one (msg_entity)
1818 #define MSG_ALL 2 // reliable to all
1819 #define MSG_INIT 3 // write to the init string
1821 sizebuf_t *WriteDest (void)
1827 dest = G_FLOAT(OFS_PARM0);
1831 return &sv.datagram;
1834 ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
1835 entnum = NUM_FOR_EDICT(ent);
1836 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1837 Host_Error("WriteDest: tried to write to non-client\n");
1838 return &svs.clients[entnum-1].message;
1841 return &sv.reliable_datagram;
1847 Host_Error("WriteDest: bad destination");
1854 void PF_WriteByte (void)
1856 MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
1859 void PF_WriteChar (void)
1861 MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
1864 void PF_WriteShort (void)
1866 MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
1869 void PF_WriteLong (void)
1871 MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
1874 void PF_WriteAngle (void)
1876 if (sv.protocol == PROTOCOL_DARKPLACES5)
1877 MSG_WriteAngle16i (WriteDest(), G_FLOAT(OFS_PARM1));
1879 MSG_WriteAngle8i (WriteDest(), G_FLOAT(OFS_PARM1));
1882 void PF_WriteCoord (void)
1884 MSG_WriteCoord (WriteDest(), G_FLOAT(OFS_PARM1), sv.protocol);
1887 void PF_WriteString (void)
1889 MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
1893 void PF_WriteEntity (void)
1895 MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
1898 //=============================================================================
1900 void PF_makestatic (void)
1905 ent = G_EDICT(OFS_PARM0);
1906 if (ent == sv.edicts)
1907 PF_WARNING("makestatic: can not modify world entity\n");
1909 PF_WARNING("makestatic: can not modify free entity\n");
1912 if (ent->v->modelindex >= 256 || ent->v->frame >= 256)
1917 MSG_WriteByte (&sv.signon,svc_spawnstatic2);
1918 MSG_WriteShort (&sv.signon, ent->v->modelindex);
1919 MSG_WriteShort (&sv.signon, ent->v->frame);
1923 MSG_WriteByte (&sv.signon,svc_spawnstatic);
1924 MSG_WriteByte (&sv.signon, ent->v->modelindex);
1925 MSG_WriteByte (&sv.signon, ent->v->frame);
1928 MSG_WriteByte (&sv.signon, ent->v->colormap);
1929 MSG_WriteByte (&sv.signon, ent->v->skin);
1930 for (i=0 ; i<3 ; i++)
1932 MSG_WriteCoord(&sv.signon, ent->v->origin[i], sv.protocol);
1933 MSG_WriteAngle8i(&sv.signon, ent->v->angles[i]);
1936 // throw the entity away now
1940 //=============================================================================
1947 void PF_setspawnparms (void)
1953 ent = G_EDICT(OFS_PARM0);
1954 i = NUM_FOR_EDICT(ent);
1955 if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
1957 Con_Print("tried to setspawnparms on a non-client\n");
1961 // copy spawn parms out of the client_t
1962 client = svs.clients + i-1;
1963 for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1964 (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
1972 void PF_changelevel (void)
1976 // make sure we don't issue two changelevels
1977 if (svs.changelevel_issued)
1979 svs.changelevel_issued = true;
1981 s = G_STRING(OFS_PARM0);
1982 Cbuf_AddText (va("changelevel %s\n",s));
1987 G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
1992 G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
1997 G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
2004 Returns a vector of length < 1
2009 void PF_randomvec (void)
2014 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
2015 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
2016 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
2018 while (DotProduct(temp, temp) >= 1);
2019 VectorCopy (temp, G_VECTOR(OFS_RETURN));
2026 Returns a color vector indicating the lighting at the requested point.
2028 (Internal Operation note: actually measures the light beneath the point, just like
2029 the model lighting on the client)
2034 void PF_GetLight (void)
2036 vec3_t ambientcolor, diffusecolor, diffusenormal;
2038 p = G_VECTOR(OFS_PARM0);
2039 VectorClear(ambientcolor);
2040 VectorClear(diffusecolor);
2041 VectorClear(diffusenormal);
2042 if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
2043 sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
2044 VectorMA(ambientcolor, 0.5, diffusecolor, G_VECTOR(OFS_RETURN));
2047 #define MAX_QC_CVARS 128
2048 cvar_t qc_cvar[MAX_QC_CVARS];
2051 void PF_registercvar (void)
2055 name = G_STRING(OFS_PARM0);
2056 value = G_STRING(OFS_PARM1);
2057 G_FLOAT(OFS_RETURN) = 0;
2058 // first check to see if it has already been defined
2059 if (Cvar_FindVar (name))
2062 // check for overlap with a command
2063 if (Cmd_Exists (name))
2065 Con_Printf("PF_registercvar: %s is a command\n", name);
2069 if (currentqc_cvar >= MAX_QC_CVARS)
2070 PF_ERROR("PF_registercvar: ran out of cvar slots\n");
2072 // copy the name and value
2073 variable = &qc_cvar[currentqc_cvar++];
2074 variable->name = Z_Malloc (strlen(name)+1);
2075 strcpy (variable->name, name);
2076 variable->string = Z_Malloc (strlen(value)+1);
2077 strcpy (variable->string, value);
2078 variable->value = atof (value);
2080 Cvar_RegisterVariable(variable);
2081 G_FLOAT(OFS_RETURN) = 1; // success
2088 returns the minimum of two supplied floats
2095 // LordHavoc: 3+ argument enhancement suggested by FrikaC
2097 G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2098 else if (pr_argc >= 3)
2101 float f = G_FLOAT(OFS_PARM0);
2102 for (i = 1;i < pr_argc;i++)
2103 if (G_FLOAT((OFS_PARM0+i*3)) < f)
2104 f = G_FLOAT((OFS_PARM0+i*3));
2105 G_FLOAT(OFS_RETURN) = f;
2109 G_FLOAT(OFS_RETURN) = 0;
2110 PF_WARNING("min: must supply at least 2 floats\n");
2118 returns the maximum of two supplied floats
2125 // LordHavoc: 3+ argument enhancement suggested by FrikaC
2127 G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2128 else if (pr_argc >= 3)
2131 float f = G_FLOAT(OFS_PARM0);
2132 for (i = 1;i < pr_argc;i++)
2133 if (G_FLOAT((OFS_PARM0+i*3)) > f)
2134 f = G_FLOAT((OFS_PARM0+i*3));
2135 G_FLOAT(OFS_RETURN) = f;
2139 G_FLOAT(OFS_RETURN) = 0;
2140 PF_WARNING("max: must supply at least 2 floats\n");
2148 returns number bounded by supplied range
2150 min(min, value, max)
2153 void PF_bound (void)
2155 G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
2162 returns a raised to power b
2169 G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
2176 copies data from one entity to another
2178 copyentity(src, dst)
2181 void PF_copyentity (void)
2184 in = G_EDICT(OFS_PARM0);
2185 if (in == sv.edicts)
2186 PF_WARNING("copyentity: can not read world entity\n");
2188 PF_WARNING("copyentity: can not read free entity\n");
2189 out = G_EDICT(OFS_PARM1);
2190 if (out == sv.edicts)
2191 PF_WARNING("copyentity: can not modify world entity\n");
2193 PF_WARNING("copyentity: can not modify free entity\n");
2194 memcpy(out->v, in->v, progs->entityfields * 4);
2201 sets the color of a client and broadcasts the update to all connected clients
2203 setcolor(clientent, value)
2206 void PF_setcolor (void)
2212 entnum = G_EDICTNUM(OFS_PARM0);
2213 i = G_FLOAT(OFS_PARM1);
2215 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
2217 Con_Print("tried to setcolor a non-client\n");
2221 client = svs.clients + entnum-1;
2222 if ((val = GETEDICTFIELDVALUE(client->edict, eval_clientcolors)))
2225 client->old_colors = i;
2226 client->edict->v->team = (i & 15) + 1;
2228 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
2229 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
2230 MSG_WriteByte (&sv.reliable_datagram, i);
2237 effect(origin, modelname, startframe, framecount, framerate)
2240 void PF_effect (void)
2244 s = G_STRING(OFS_PARM1);
2246 PF_WARNING("effect: no model specified\n");
2248 i = SV_ModelIndex(s);
2250 PF_WARNING("effect: model not precached\n");
2251 SV_StartEffect(G_VECTOR(OFS_PARM0), i, G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
2254 void PF_te_blood (void)
2256 if (G_FLOAT(OFS_PARM2) < 1)
2258 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2259 MSG_WriteByte(&sv.datagram, TE_BLOOD);
2261 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2262 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2263 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2265 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2266 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2267 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2269 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2272 void PF_te_bloodshower (void)
2274 if (G_FLOAT(OFS_PARM3) < 1)
2276 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2277 MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
2279 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2280 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2281 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2283 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
2284 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
2285 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
2287 MSG_WriteCoord(&sv.datagram, G_FLOAT(OFS_PARM2), sv.protocol);
2289 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2292 void PF_te_explosionrgb (void)
2294 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2295 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
2297 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2298 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2299 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2301 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
2302 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
2303 MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
2306 void PF_te_particlecube (void)
2308 if (G_FLOAT(OFS_PARM3) < 1)
2310 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2311 MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
2313 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2314 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2315 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2317 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
2318 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
2319 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
2321 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol);
2322 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol);
2323 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol);
2325 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2327 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2328 // gravity true/false
2329 MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
2331 MSG_WriteCoord(&sv.datagram, G_FLOAT(OFS_PARM6), sv.protocol);
2334 void PF_te_particlerain (void)
2336 if (G_FLOAT(OFS_PARM3) < 1)
2338 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2339 MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
2341 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2342 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2343 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2345 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
2346 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
2347 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
2349 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol);
2350 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol);
2351 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol);
2353 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2355 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2358 void PF_te_particlesnow (void)
2360 if (G_FLOAT(OFS_PARM3) < 1)
2362 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2363 MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
2365 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2366 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2367 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2369 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
2370 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
2371 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
2373 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol);
2374 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol);
2375 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol);
2377 MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
2379 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
2382 void PF_te_spark (void)
2384 if (G_FLOAT(OFS_PARM2) < 1)
2386 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2387 MSG_WriteByte(&sv.datagram, TE_SPARK);
2389 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2390 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2391 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2393 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
2394 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
2395 MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
2397 MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
2400 void PF_te_gunshotquad (void)
2402 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2403 MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
2405 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2406 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2407 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2410 void PF_te_spikequad (void)
2412 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2413 MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
2415 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2416 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2417 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2420 void PF_te_superspikequad (void)
2422 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2423 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
2425 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2426 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2427 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2430 void PF_te_explosionquad (void)
2432 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2433 MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
2435 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2436 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2437 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2440 void PF_te_smallflash (void)
2442 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2443 MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
2445 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2446 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2447 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2450 void PF_te_customflash (void)
2452 if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
2454 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2455 MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
2457 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2458 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2459 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2461 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
2463 MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) / 256 - 1, 255));
2465 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
2466 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
2467 MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
2470 void PF_te_gunshot (void)
2472 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2473 MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
2475 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2476 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2477 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2480 void PF_te_spike (void)
2482 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2483 MSG_WriteByte(&sv.datagram, TE_SPIKE);
2485 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2486 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2487 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2490 void PF_te_superspike (void)
2492 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2493 MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
2495 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2496 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2497 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2500 void PF_te_explosion (void)
2502 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2503 MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
2505 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2506 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2507 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2510 void PF_te_tarexplosion (void)
2512 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2513 MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
2515 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2516 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2517 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2520 void PF_te_wizspike (void)
2522 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2523 MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
2525 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2526 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2527 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2530 void PF_te_knightspike (void)
2532 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2533 MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
2535 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2536 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2537 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2540 void PF_te_lavasplash (void)
2542 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2543 MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
2545 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2546 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2547 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2550 void PF_te_teleport (void)
2552 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2553 MSG_WriteByte(&sv.datagram, TE_TELEPORT);
2555 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2556 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2557 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2560 void PF_te_explosion2 (void)
2562 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2563 MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
2565 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2566 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2567 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2569 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
2570 MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM2));
2573 void PF_te_lightning1 (void)
2575 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2576 MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
2578 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2580 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
2581 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
2582 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
2584 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol);
2585 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol);
2586 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol);
2589 void PF_te_lightning2 (void)
2591 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2592 MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
2594 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2596 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
2597 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
2598 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
2600 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol);
2601 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol);
2602 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol);
2605 void PF_te_lightning3 (void)
2607 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2608 MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
2610 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2612 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
2613 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
2614 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
2616 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol);
2617 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol);
2618 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol);
2621 void PF_te_beam (void)
2623 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2624 MSG_WriteByte(&sv.datagram, TE_BEAM);
2626 MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
2628 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
2629 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
2630 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
2632 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol);
2633 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol);
2634 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol);
2637 void PF_te_plasmaburn (void)
2639 MSG_WriteByte(&sv.datagram, svc_temp_entity);
2640 MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
2641 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
2642 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
2643 MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
2646 static void clippointtosurface(msurface_t *surf, vec3_t p, vec3_t out)
2649 vec3_t v1, clipplanenormal, normal;
2650 vec_t clipplanedist, clipdist;
2652 if (surf->flags & SURF_PLANEBACK)
2653 VectorNegate(surf->plane->normal, normal);
2655 VectorCopy(surf->plane->normal, normal);
2656 for (i = 0, j = surf->poly_numverts - 1;i < surf->poly_numverts;j = i, i++)
2658 VectorSubtract(&surf->poly_verts[j * 3], &surf->poly_verts[i * 3], v1);
2659 VectorNormalizeFast(v1);
2660 CrossProduct(v1, normal, clipplanenormal);
2661 clipplanedist = DotProduct(&surf->poly_verts[i * 3], clipplanenormal);
2662 clipdist = DotProduct(out, clipplanenormal) - clipplanedist;
2665 clipdist = -clipdist;
2666 VectorMA(out, clipdist, clipplanenormal, out);
2671 static msurface_t *getsurface(edict_t *ed, int surfnum)
2675 if (!ed || ed->e->free)
2677 modelindex = ed->v->modelindex;
2678 if (modelindex < 1 || modelindex >= MAX_MODELS)
2680 model = sv.models[modelindex];
2681 if (surfnum < 0 || surfnum >= model->nummodelsurfaces)
2683 return model->brushq1.surfaces + surfnum + model->firstmodelsurface;
2687 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
2688 void PF_getsurfacenumpoints(void)
2691 // return 0 if no such surface
2692 if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1))))
2694 G_FLOAT(OFS_RETURN) = 0;
2698 G_FLOAT(OFS_RETURN) = surf->poly_numverts;
2700 //PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
2701 void PF_getsurfacepoint(void)
2706 VectorClear(G_VECTOR(OFS_RETURN));
2707 ed = G_EDICT(OFS_PARM0);
2708 if (!ed || ed->e->free)
2710 if (!(surf = getsurface(ed, G_FLOAT(OFS_PARM1))))
2712 pointnum = G_FLOAT(OFS_PARM2);
2713 if (pointnum < 0 || pointnum >= surf->poly_numverts)
2715 // FIXME: implement rotation/scaling
2716 VectorAdd(&surf->poly_verts[pointnum * 3], ed->v->origin, G_VECTOR(OFS_RETURN));
2718 //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436;
2719 void PF_getsurfacenormal(void)
2722 VectorClear(G_VECTOR(OFS_RETURN));
2723 if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1))))
2725 // FIXME: implement rotation/scaling
2726 if (surf->flags & SURF_PLANEBACK)
2727 VectorNegate(surf->plane->normal, G_VECTOR(OFS_RETURN));
2729 VectorCopy(surf->plane->normal, G_VECTOR(OFS_RETURN));
2731 //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437;
2732 void PF_getsurfacetexture(void)
2735 G_INT(OFS_RETURN) = 0;
2736 if (!(surf = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1))))
2738 G_INT(OFS_RETURN) = PR_SetString(surf->texinfo->texture->name);
2740 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
2741 void PF_getsurfacenearpoint(void)
2743 int surfnum, best, modelindex;
2745 vec_t dist, bestdist;
2750 G_FLOAT(OFS_RETURN) = -1;
2751 ed = G_EDICT(OFS_PARM0);
2752 point = G_VECTOR(OFS_PARM1);
2754 if (!ed || ed->e->free)
2756 modelindex = ed->v->modelindex;
2757 if (modelindex < 1 || modelindex >= MAX_MODELS)
2759 model = sv.models[modelindex];
2760 if (!model->brushq1.numsurfaces)
2763 // FIXME: implement rotation/scaling
2764 VectorSubtract(point, ed->v->origin, p);
2766 bestdist = 1000000000;
2767 for (surfnum = 0;surfnum < model->nummodelsurfaces;surfnum++)
2769 surf = model->brushq1.surfaces + surfnum + model->firstmodelsurface;
2770 dist = PlaneDiff(p, surf->plane);
2772 if (dist < bestdist)
2774 clippointtosurface(surf, p, clipped);
2775 VectorSubtract(clipped, p, clipped);
2776 dist += DotProduct(clipped, clipped);
2777 if (dist < bestdist)
2784 G_FLOAT(OFS_RETURN) = best;
2786 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
2787 void PF_getsurfaceclippedpoint(void)
2792 VectorClear(G_VECTOR(OFS_RETURN));
2793 ed = G_EDICT(OFS_PARM0);
2794 if (!ed || ed->e->free)
2796 if (!(surf = getsurface(ed, G_FLOAT(OFS_PARM1))))
2798 // FIXME: implement rotation/scaling
2799 VectorSubtract(G_VECTOR(OFS_PARM2), ed->v->origin, p);
2800 clippointtosurface(surf, p, out);
2801 // FIXME: implement rotation/scaling
2802 VectorAdd(out, ed->v->origin, G_VECTOR(OFS_RETURN));
2805 #define MAX_PRFILES 256
2807 qfile_t *pr_files[MAX_PRFILES];
2809 void PR_Files_Init(void)
2811 memset(pr_files, 0, sizeof(pr_files));
2814 void PR_Files_CloseAll(void)
2817 for (i = 0;i < MAX_PRFILES;i++)
2820 FS_Close(pr_files[i]);
2825 //float(string s) stof = #81; // get numerical value from a string
2828 char string[STRINGTEMP_LENGTH];
2829 PF_VarString(0, string, sizeof(string));
2830 G_FLOAT(OFS_RETURN) = atof(string);
2833 //float(string filename, float mode) fopen = #110; // opens a file inside quake/gamedir/data/ (mode is FILE_READ, FILE_APPEND, or FILE_WRITE), returns fhandle >= 0 if successful, or fhandle < 0 if unable to open file for any reason
2836 int filenum, mode, i;
2837 char *modestring, *filename;
2838 for (filenum = 0;filenum < MAX_PRFILES;filenum++)
2839 if (pr_files[filenum] == NULL)
2841 if (filenum >= MAX_PRFILES)
2843 Con_Printf("PF_fopen: ran out of file handles (%i)\n", MAX_PRFILES);
2844 G_FLOAT(OFS_RETURN) = -2;
2847 mode = G_FLOAT(OFS_PARM1);
2850 case 0: // FILE_READ
2853 case 1: // FILE_APPEND
2856 case 2: // FILE_WRITE
2860 Con_Printf("PF_fopen: no such mode %i (valid: 0 = read, 1 = append, 2 = write)\n", mode);
2861 G_FLOAT(OFS_RETURN) = -3;
2864 filename = G_STRING(OFS_PARM0);
2865 // control characters do not cause issues with any platforms I know of, but they are usually annoying to deal with
2866 // ../ is parent directory on many platforms
2867 // // is parent directory on Amiga
2868 // / at the beginning of a path is root on unix, and parent directory on Amiga
2869 // : is root of drive on Amiga (also used as a directory separator on Mac, but / works there too, so that's a bad idea)
2870 // \ is a windows-ism (so it's naughty to use it, / works on all platforms)
2871 for (i = 0;filename[i];i++)
2873 if (filename[i] < ' ' || (filename[i] == '/' && filename[i+1] == '/') || (filename[i] == '.' && filename[i+1] == '.') || filename[i] == ':' || filename[i] == '\\' || filename[0] == '/')
2875 Con_Printf("PF_fopen: dangerous/confusing/annoying/non-portable filename \"%s\" not allowed. (contains control characters or // or .. or : or \\ or begins with /)\n", filename);
2876 G_FLOAT(OFS_RETURN) = -4;
2880 pr_files[filenum] = FS_Open(va("data/%s", filename), modestring, false);
2882 if (pr_files[filenum] == NULL && modestring == "rb")
2883 pr_files[filenum] = FS_Open(filename, modestring, false);
2885 if (pr_files[filenum] == NULL)
2886 G_FLOAT(OFS_RETURN) = -1;
2888 G_FLOAT(OFS_RETURN) = filenum;
2891 //void(float fhandle) fclose = #111; // closes a file
2892 void PF_fclose(void)
2894 int filenum = G_FLOAT(OFS_PARM0);
2895 if (filenum < 0 || filenum >= MAX_PRFILES)
2897 Con_Printf("PF_fclose: invalid file handle %i\n", filenum);
2900 if (pr_files[filenum] == NULL)
2902 Con_Printf("PF_fclose: no such file handle %i (or file has been closed)\n", filenum);
2905 FS_Close(pr_files[filenum]);
2906 pr_files[filenum] = NULL;
2909 //string(float fhandle) fgets = #112; // reads a line of text from the file and returns as a tempstring
2913 static char string[STRINGTEMP_LENGTH];
2914 int filenum = G_FLOAT(OFS_PARM0);
2915 if (filenum < 0 || filenum >= MAX_PRFILES)
2917 Con_Printf("PF_fgets: invalid file handle %i\n", filenum);
2920 if (pr_files[filenum] == NULL)
2922 Con_Printf("PF_fgets: no such file handle %i (or file has been closed)\n", filenum);
2928 c = FS_Getc(pr_files[filenum]);
2929 if (c == '\r' || c == '\n' || c < 0)
2931 if (end < STRINGTEMP_LENGTH - 1)
2935 // remove \n following \r
2937 c = FS_Getc(pr_files[filenum]);
2938 if (developer.integer)
2939 Con_Printf("fgets: %s\n", string);
2941 G_INT(OFS_RETURN) = PR_SetString(string);
2943 G_INT(OFS_RETURN) = 0;
2946 //void(float fhandle, string s) fputs = #113; // writes a line of text to the end of the file
2950 char string[STRINGTEMP_LENGTH];
2951 int filenum = G_FLOAT(OFS_PARM0);
2952 if (filenum < 0 || filenum >= MAX_PRFILES)
2954 Con_Printf("PF_fputs: invalid file handle %i\n", filenum);
2957 if (pr_files[filenum] == NULL)
2959 Con_Printf("PF_fputs: no such file handle %i (or file has been closed)\n", filenum);
2962 PF_VarString(1, string, sizeof(string));
2963 if ((stringlength = strlen(string)))
2964 FS_Write(pr_files[filenum], string, stringlength);
2965 if (developer.integer)
2966 Con_Printf("fputs: %s\n", string);
2969 //float(string s) strlen = #114; // returns how many characters are in a string
2970 void PF_strlen(void)
2973 s = G_STRING(OFS_PARM0);
2975 G_FLOAT(OFS_RETURN) = strlen(s);
2977 G_FLOAT(OFS_RETURN) = 0;
2980 //string(string s1, string s2) strcat = #115; // concatenates two strings (for example "abc", "def" would return "abcdef") and returns as a tempstring
2981 void PF_strcat(void)
2983 char *s = PR_GetTempString();
2984 PF_VarString(0, s, STRINGTEMP_LENGTH);
2985 G_INT(OFS_RETURN) = PR_SetString(s);
2988 //string(string s, float start, float length) substring = #116; // returns a section of a string as a tempstring
2989 void PF_substring(void)
2991 int i, start, length;
2992 char *s, *string = PR_GetTempString();
2993 s = G_STRING(OFS_PARM0);
2994 start = G_FLOAT(OFS_PARM1);
2995 length = G_FLOAT(OFS_PARM2);
2998 for (i = 0;i < start && *s;i++, s++);
2999 for (i = 0;i < STRINGTEMP_LENGTH - 1 && *s && i < length;i++, s++)
3002 G_INT(OFS_RETURN) = PR_SetString(string);
3005 //vector(string s) stov = #117; // returns vector value from a string
3008 char string[STRINGTEMP_LENGTH];
3009 PF_VarString(0, string, sizeof(string));
3010 Math_atov(string, G_VECTOR(OFS_RETURN));
3013 //string(string s) strzone = #118; // makes a copy of a string into the string zone and returns it, this is often used to keep around a tempstring for longer periods of time (tempstrings are replaced often)
3014 void PF_strzone(void)
3017 in = G_STRING(OFS_PARM0);
3018 out = Mem_Alloc(pr_strings_mempool, strlen(in) + 1);
3020 G_INT(OFS_RETURN) = PR_SetString(out);
3023 //void(string s) strunzone = #119; // removes a copy of a string from the string zone (you can not use that string again or it may crash!!!)
3024 void PF_strunzone(void)
3026 Mem_Free(G_STRING(OFS_PARM0));
3029 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
3030 //this function originally written by KrimZon, made shorter by LordHavoc
3031 void PF_clientcommand (void)
3033 client_t *temp_client;
3036 //find client for this entity
3037 i = (NUM_FOR_EDICT(G_EDICT(OFS_PARM0)) - 1);
3038 if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
3040 Con_Print("PF_clientcommand: entity is not a client\n");
3044 temp_client = host_client;
3045 host_client = svs.clients + i;
3046 Cmd_ExecuteString (G_STRING(OFS_PARM1), src_client);
3047 host_client = temp_client;
3050 //float(string s) tokenize = #441; // takes apart a string into individal words (access them with argv), returns how many
3051 //this function originally written by KrimZon, made shorter by LordHavoc
3052 //20040203: rewritten by LordHavoc (no longer uses allocations)
3054 char *tokens[256], tokenbuf[4096];
3055 void PF_tokenize (void)
3059 p = G_STRING(OFS_PARM0);
3063 while(COM_ParseToken(&p, false))
3065 if (num_tokens >= (int)(sizeof(tokens)/sizeof(tokens[0])))
3067 if (pos + strlen(com_token) + 1 > sizeof(tokenbuf))
3069 tokens[num_tokens++] = tokenbuf + pos;
3070 strcpy(tokenbuf + pos, com_token);
3071 pos += strlen(com_token) + 1;
3074 G_FLOAT(OFS_RETURN) = num_tokens;
3077 //string(float n) argv = #442; // returns a word from the tokenized string (returns nothing for an invalid index)
3078 //this function originally written by KrimZon, made shorter by LordHavoc
3081 int token_num = G_FLOAT(OFS_PARM0);
3082 if (token_num >= 0 && token_num < num_tokens)
3083 G_INT(OFS_RETURN) = PR_SetString(tokens[token_num]);
3085 G_INT(OFS_RETURN) = PR_SetString("");
3088 //void(entity e, entity tagentity, string tagname) setattachment = #443; // attachs e to a tag on tagentity (note: use "" to attach to entity origin/angles instead of a tag)
3089 void PF_setattachment (void)
3091 edict_t *e = G_EDICT(OFS_PARM0);
3092 edict_t *tagentity = G_EDICT(OFS_PARM1);
3093 char *tagname = G_STRING(OFS_PARM2);
3099 PF_WARNING("setattachment: can not modify world entity\n");
3101 PF_WARNING("setattachment: can not modify free entity\n");
3103 if (tagentity == NULL)
3104 tagentity = sv.edicts;
3106 v = GETEDICTFIELDVALUE(e, eval_tag_entity);
3108 v->edict = EDICT_TO_PROG(tagentity);
3110 v = GETEDICTFIELDVALUE(e, eval_tag_index);
3113 if (tagentity != NULL && tagentity != sv.edicts && tagname && tagname[0])
3115 modelindex = (int)tagentity->v->modelindex;
3116 if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
3118 if (model->data_overridetagnamesforskin && (unsigned int)tagentity->v->skin < (unsigned int)model->numskins && model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames)
3119 for (i = 0;i < model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames;i++)
3120 if (!strcmp(tagname, model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].data_overridetagnames[i].name))
3122 // FIXME: use a model function to get tag info (need to handle skeletal)
3123 if (v->_float == 0 && model->alias.aliasnum_tags)
3124 for (i = 0;i < model->alias.aliasnum_tags;i++)
3125 if (!strcmp(tagname, model->alias.aliasdata_tags[i].name))
3128 Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(e), NUM_FOR_EDICT(tagentity), tagname, tagname, NUM_FOR_EDICT(tagentity), model->name);
3131 Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", NUM_FOR_EDICT(e), NUM_FOR_EDICT(tagentity), tagname, tagname, NUM_FOR_EDICT(tagentity));
3136 /////////////////////////////////////////
3137 // DP_QC_FS_SEARCH extension
3139 // qc fs search handling
3140 #define MAX_SEARCHES 128
3142 fssearch_t *pr_fssearchlist[MAX_SEARCHES];
3144 void PR_Search_Init(void)
3146 memset(pr_fssearchlist,0,sizeof(pr_fssearchlist));
3149 void PR_Search_Reset(void)
3152 // reset the fssearch list
3153 for(i = 0; i < MAX_SEARCHES; i++)
3154 if(pr_fssearchlist[i])
3155 FS_FreeSearch(pr_fssearchlist[i]);
3156 memset(pr_fssearchlist,0,sizeof(pr_fssearchlist));
3163 float search_begin(string pattern, float caseinsensitive, float quiet)
3166 void PF_search_begin(void)
3170 int caseinsens, quiet;
3172 pattern = G_STRING(OFS_PARM0);
3174 PR_CheckEmptyString(pattern);
3176 caseinsens = G_FLOAT(OFS_PARM1);
3177 quiet = G_FLOAT(OFS_PARM2);
3179 for(handle = 0; handle < MAX_SEARCHES; handle++)
3180 if(!pr_fssearchlist[handle])
3183 if(handle >= MAX_SEARCHES)
3185 Con_Printf("PR_search_begin: ran out of search handles (%i)\n", MAX_SEARCHES);
3186 G_FLOAT(OFS_RETURN) = -2;
3190 if(!(pr_fssearchlist[handle] = FS_Search(pattern,caseinsens, quiet)))
3191 G_FLOAT(OFS_RETURN) = -1;
3193 G_FLOAT(OFS_RETURN) = handle;
3200 void search_end(float handle)
3203 void PF_search_end(void)
3207 handle = G_FLOAT(OFS_PARM0);
3209 if(handle < 0 || handle >= MAX_SEARCHES)
3211 Con_Printf("PF_search_end: invalid handle %i\n", handle);
3214 if(pr_fssearchlist[handle] == NULL)
3216 Con_Printf("PF_search_end: no such handle %i\n", handle);
3220 FS_FreeSearch(pr_fssearchlist[handle]);
3221 pr_fssearchlist[handle] = NULL;
3228 float search_getsize(float handle)
3231 void PF_search_getsize(void)
3235 handle = G_FLOAT(OFS_PARM0);
3237 if(handle < 0 || handle >= MAX_SEARCHES)
3239 Con_Printf("PF_search_getsize: invalid handle %i\n", handle);
3242 if(pr_fssearchlist[handle] == NULL)
3244 Con_Printf("PF_search_getsize: no such handle %i\n", handle);
3248 G_FLOAT(OFS_RETURN) = pr_fssearchlist[handle]->numfilenames;
3253 VM_search_getfilename
3255 string search_getfilename(float handle, float num)
3258 void PF_search_getfilename(void)
3260 int handle, filenum;
3263 handle = G_FLOAT(OFS_PARM0);
3264 filenum = G_FLOAT(OFS_PARM1);
3266 if(handle < 0 || handle >= MAX_SEARCHES)
3268 Con_Printf("PF_search_getfilename: invalid handle %i\n", handle);
3271 if(pr_fssearchlist[handle] == NULL)
3273 Con_Printf("PF_search_getfilename: no such handle %i\n", handle);
3276 if(filenum < 0 || filenum >= pr_fssearchlist[handle]->numfilenames)
3278 Con_Printf("PF_search_getfilename: invalid filenum %i\n", filenum);
3282 tmp = PR_GetTempString();
3283 strcpy(tmp, pr_fssearchlist[handle]->filenames[filenum]);
3285 G_INT(OFS_RETURN) = PR_SetString(tmp);
3288 void PF_cvar_string (void)
3294 str = G_STRING(OFS_PARM0);
3295 var = Cvar_FindVar (str);
3297 tmp = PR_GetTempString();
3298 strcpy(tmp, var->string);
3300 G_INT(OFS_RETURN) = PR_SetString(tmp);
3305 builtin_t pr_builtin[] =
3308 PF_makevectors, // #1 void(entity e) makevectors
3309 PF_setorigin, // #2 void(entity e, vector o) setorigin
3310 PF_setmodel, // #3 void(entity e, string m) setmodel
3311 PF_setsize, // #4 void(entity e, vector min, vector max) setsize
3312 NULL, // #5 void(entity e, vector min, vector max) setabssize
3313 PF_break, // #6 void() break
3314 PF_random, // #7 float() random
3315 PF_sound, // #8 void(entity e, float chan, string samp) sound
3316 PF_normalize, // #9 vector(vector v) normalize
3317 PF_error, // #10 void(string e) error
3318 PF_objerror, // #11 void(string e) objerror
3319 PF_vlen, // #12 float(vector v) vlen
3320 PF_vectoyaw, // #13 float(vector v) vectoyaw
3321 PF_Spawn, // #14 entity() spawn
3322 PF_Remove, // #15 void(entity e) remove
3323 PF_traceline, // #16 float(vector v1, vector v2, float tryents) traceline
3324 PF_checkclient, // #17 entity() clientlist
3325 PF_Find, // #18 entity(entity start, .string fld, string match) find
3326 PF_precache_sound, // #19 void(string s) precache_sound
3327 PF_precache_model, // #20 void(string s) precache_model
3328 PF_stuffcmd, // #21 void(entity client, string s)stuffcmd
3329 PF_findradius, // #22 entity(vector org, float rad) findradius
3330 PF_bprint, // #23 void(string s) bprint
3331 PF_sprint, // #24 void(entity client, string s) sprint
3332 PF_dprint, // #25 void(string s) dprint
3333 PF_ftos, // #26 void(string s) ftos
3334 PF_vtos, // #27 void(string s) vtos
3335 PF_coredump, // #28 void() coredump
3336 PF_traceon, // #29 void() traceon
3337 PF_traceoff, // #30 void() traceoff
3338 PF_eprint, // #31 void(entity e) eprint
3339 PF_walkmove, // #32 float(float yaw, float dist) walkmove
3341 PF_droptofloor, // #34 float() droptofloor
3342 PF_lightstyle, // #35 void(float style, string value) lightstyle
3343 PF_rint, // #36 float(float v) rint
3344 PF_floor, // #37 float(float v) floor
3345 PF_ceil, // #38 float(float v) ceil
3347 PF_checkbottom, // #40 float(entity e) checkbottom
3348 PF_pointcontents , // #41 float(vector v) pointcontents
3350 PF_fabs, // #43 float(float f) fabs
3351 PF_aim, // #44 vector(entity e, float speed) aim
3352 PF_cvar, // #45 float(string s) cvar
3353 PF_localcmd, // #46 void(string s) localcmd
3354 PF_nextent, // #47 entity(entity e) nextent
3355 PF_particle, // #48 void(vector o, vector d, float color, float count) particle
3356 PF_changeyaw, // #49 void() ChangeYaw
3358 PF_vectoangles, // #51 vector(vector v) vectoangles
3359 PF_WriteByte, // #52 void(float to, float f) WriteByte
3360 PF_WriteChar, // #53 void(float to, float f) WriteChar
3361 PF_WriteShort, // #54 void(float to, float f) WriteShort
3362 PF_WriteLong, // #55 void(float to, float f) WriteLong
3363 PF_WriteCoord, // #56 void(float to, float f) WriteCoord
3364 PF_WriteAngle, // #57 void(float to, float f) WriteAngle
3365 PF_WriteString, // #58 void(float to, string s) WriteString
3366 PF_WriteEntity, // #59 void(float to, entity e) WriteEntity
3367 PF_sin, // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW)
3368 PF_cos, // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW)
3369 PF_sqrt, // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW)
3370 PF_changepitch, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH)
3371 PF_TraceToss, // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS)
3372 PF_etos, // #65 string(entity ent) etos (DP_QC_ETOS)
3374 SV_MoveToGoal, // #67 void(float step) movetogoal
3375 PF_precache_file, // #68 string(string s) precache_file
3376 PF_makestatic, // #69 void(entity e) makestatic
3377 PF_changelevel, // #70 void(string s) changelevel
3379 PF_cvar_set, // #72 void(string var, string val) cvar_set
3380 PF_centerprint, // #73 void(entity client, strings) centerprint
3381 PF_ambientsound, // #74 void(vector pos, string samp, float vol, float atten) ambientsound
3382 PF_precache_model, // #75 string(string s) precache_model2
3383 PF_precache_sound, // #76 string(string s) precache_sound2
3384 PF_precache_file, // #77 string(string s) precache_file2
3385 PF_setspawnparms, // #78 void(entity e) setspawnparms
3388 PF_stof, // #81 float(string s) stof (FRIK_FILE)
3397 PF_tracebox, // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
3398 PF_randomvec, // #91 vector() randomvec (DP_QC_RANDOMVEC)
3399 PF_GetLight, // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
3400 PF_registercvar, // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
3401 PF_min, // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
3402 PF_max, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
3403 PF_bound, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
3404 PF_pow, // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
3405 PF_FindFloat, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
3406 PF_checkextension, // #99 float(string s) checkextension (the basis of the extension system)
3417 PF_fopen, // #110 float(string filename, float mode) fopen (FRIK_FILE)
3418 PF_fclose, // #111 void(float fhandle) fclose (FRIK_FILE)
3419 PF_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
3420 PF_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
3421 PF_strlen, // #114 float(string s) strlen (FRIK_FILE)
3422 PF_strcat, // #115 string(string s1, string s2) strcat (FRIK_FILE)
3423 PF_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
3424 PF_stov, // #117 vector(string) stov (FRIK_FILE)
3425 PF_strzone, // #118 string(string s) strzone (FRIK_FILE)
3426 PF_strunzone, // #119 void(string s) strunzone (FRIK_FILE)
3427 #define a NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
3428 a a a a a a a a // #120-199
3429 a a a a a a a a a a // #200-299
3430 a a a a a a a a a a // #300-399
3431 PF_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
3432 PF_setcolor, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
3433 PF_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
3434 PF_findchainfloat, // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
3435 PF_effect, // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
3436 PF_te_blood, // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
3437 PF_te_bloodshower, // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
3438 PF_te_explosionrgb, // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
3439 PF_te_particlecube, // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE)
3440 PF_te_particlerain, // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
3441 PF_te_particlesnow, // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
3442 PF_te_spark, // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
3443 PF_te_gunshotquad, // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
3444 PF_te_spikequad, // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
3445 PF_te_superspikequad, // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
3446 PF_te_explosionquad, // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
3447 PF_te_smallflash, // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
3448 PF_te_customflash, // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
3449 PF_te_gunshot, // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
3450 PF_te_spike, // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
3451 PF_te_superspike, // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
3452 PF_te_explosion, // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
3453 PF_te_tarexplosion, // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
3454 PF_te_wizspike, // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
3455 PF_te_knightspike, // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
3456 PF_te_lavasplash, // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
3457 PF_te_teleport, // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
3458 PF_te_explosion2, // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
3459 PF_te_lightning1, // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
3460 PF_te_lightning2, // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
3461 PF_te_lightning3, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
3462 PF_te_beam, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
3463 PF_vectorvectors, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
3464 PF_te_plasmaburn, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
3465 PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
3466 PF_getsurfacepoint, // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
3467 PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
3468 PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
3469 PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
3470 PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
3471 PF_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
3472 PF_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
3473 PF_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
3474 PF_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
3475 PF_search_begin, // #444
3476 PF_search_end, // #445
3477 PF_search_getsize, // #446
3478 PF_search_getfilename, // #447
3479 PF_cvar_string, // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
3480 PF_findflags, // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
3481 PF_findchainflags, // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
3491 a a a a // #460-499 (LordHavoc)
3494 builtin_t *pr_builtins = pr_builtin;
3495 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);
3497 void PR_Cmd_Init(void)
3499 pr_strings_mempool = Mem_AllocPool("pr_stringszone", 0, NULL);
3504 void PR_Cmd_Reset(void)
3506 Mem_EmptyPool(pr_strings_mempool);
3508 PR_Files_CloseAll();