4333 lines
86 KiB
C
4333 lines
86 KiB
C
/*
|
|
Copyright (C) 1996-1997 Id Software, Inc.
|
|
|
|
This program is free softwasre; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include "quakedef.h"
|
|
|
|
#define RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e))
|
|
|
|
char pr_string_temp[128];
|
|
|
|
int SV_HullPointContents (hull_t *hull, int num, vec3_t p);
|
|
|
|
|
|
//Tei guislots
|
|
|
|
#define RETURNFLOAT(o) {Con_Printf("res:%f\n",o);G_FLOAT(OFS_RETURN) = o;return;}
|
|
|
|
// Tei new lmp
|
|
#define ORG_NW 0
|
|
#define ORG_NE 1
|
|
#define ORG_SW 2
|
|
#define ORG_SE 3
|
|
#define ORG_CC 4
|
|
#define ORG_CN 5
|
|
#define ORG_CS 6
|
|
#define ORG_CW 7
|
|
#define ORG_CE 8
|
|
|
|
#define CNT_ARRAY 1
|
|
#define CNT_STRING 2
|
|
#define CNT_ALPHA 3
|
|
#define CNT_DEFAULT 0
|
|
// Tei new lmp
|
|
|
|
// Tei regparsing
|
|
|
|
// Tei read register
|
|
extern int eval_parse0;
|
|
extern int eval_parse1;
|
|
extern int eval_parse2;
|
|
extern int eval_parse3;
|
|
extern int eval_parse4;
|
|
extern int eval_parse5;
|
|
extern int eval_parse6;
|
|
extern int eval_parse7;
|
|
// Tei read register
|
|
|
|
|
|
#ifdef SINGLEPLAYER
|
|
int singleplayer = true;
|
|
#define DOSINGLE (!(cls.demorecording))
|
|
#else
|
|
int singleplayer = false;
|
|
//#define DOSINGLE (!(cls.state == ca_dedicated)|| !cls.demorecording || (!singleplayer && !( deathmatch.value || coop.value)))
|
|
|
|
#define ISADEMO cls.demorecording
|
|
#define DEDICATED cls.state == ca_dedicated
|
|
#define MULTI (coop.value || deathmatch.value)
|
|
|
|
#define DOSINGLE (!(ISADEMO) && !(DEDICATED) && !(MULTI))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Tei regparsing
|
|
|
|
|
|
void ParamNegateFix ( float * xx, float * yy, int Zone )
|
|
{
|
|
float x,y;
|
|
x = xx[0];
|
|
y = yy[0];
|
|
|
|
if (Zone == ORG_CC || ORG_CW == Zone || ORG_CE == Zone )
|
|
y = y + 8000;
|
|
|
|
if (Zone == ORG_CC || ORG_CN == Zone || ORG_CS == Zone )
|
|
x = x + 8000;
|
|
|
|
xx[0] = x;
|
|
yy[0] = y;
|
|
}
|
|
|
|
void PR_ShowPic(void)
|
|
{
|
|
char *slot = G_STRING(OFS_PARM0);
|
|
char *picname = G_STRING(OFS_PARM1);
|
|
float x = G_FLOAT(OFS_PARM2);
|
|
float y = G_FLOAT(OFS_PARM3);
|
|
float zone = G_FLOAT(OFS_PARM4);
|
|
|
|
ParamNegateFix( &x, &y, zone );
|
|
|
|
if (sv.datagram.cursize > MAX_DATAGRAM-16)
|
|
return;
|
|
|
|
MSG_WriteByte (&sv.datagram, svc_showlmp2);
|
|
MSG_WriteByte (&sv.datagram, zone);//zone
|
|
MSG_WriteString(&sv.datagram, slot);//lmp label
|
|
MSG_WriteString(&sv.datagram, picname);//picname
|
|
|
|
MSG_WriteShort (&sv.datagram, x);
|
|
MSG_WriteShort (&sv.datagram, y);
|
|
};
|
|
|
|
void PR_ShowPicEnt(void)
|
|
{
|
|
char *slot = G_STRING(OFS_PARM0);
|
|
char *picname = G_STRING(OFS_PARM1);
|
|
float x = G_FLOAT(OFS_PARM2);
|
|
float y = G_FLOAT(OFS_PARM3);
|
|
float zone = G_FLOAT(OFS_PARM4);
|
|
edict_t * to= G_EDICT(OFS_PARM5);
|
|
int entnum;//, ent;
|
|
|
|
|
|
ParamNegateFix( &x, &y, zone );
|
|
|
|
if (sv.datagram.cursize > MAX_DATAGRAM-16)
|
|
return;
|
|
|
|
//ent = PROG_TO_EDICT(to);
|
|
entnum = NUM_FOR_EDICT(to);//ent);
|
|
|
|
if (entnum < 1 || entnum > svs.maxclients)
|
|
PR_RunError ("WriteDest: not a client");
|
|
|
|
MSG_WriteByte (&svs.clients[entnum-1].message, svc_showlmp2);
|
|
MSG_WriteByte (&svs.clients[entnum-1].message, zone);//zone
|
|
MSG_WriteString(&svs.clients[entnum-1].message, slot);//lmp label
|
|
MSG_WriteString(&svs.clients[entnum-1].message, picname);//picname
|
|
|
|
MSG_WriteShort (&svs.clients[entnum-1].message, x);
|
|
MSG_WriteShort (&svs.clients[entnum-1].message, y);
|
|
};
|
|
|
|
void PR_HidePic(void)
|
|
{
|
|
char *slot = G_STRING(OFS_PARM0);
|
|
|
|
if (sv.datagram.cursize > MAX_DATAGRAM-16)
|
|
return;
|
|
|
|
MSG_WriteByte (&sv.datagram, svc_hidelmp);
|
|
MSG_WriteString(&sv.datagram, slot);//lmp label
|
|
};
|
|
|
|
void PR_HidePicEnt(void)
|
|
{
|
|
char *slot = G_STRING(OFS_PARM0);
|
|
edict_t * to= G_EDICT(OFS_PARM1);
|
|
int entnum = NUM_FOR_EDICT(to);
|
|
|
|
if (sv.datagram.cursize > MAX_DATAGRAM-16)
|
|
return;
|
|
|
|
MSG_WriteByte (&svs.clients[entnum-1].message, svc_hidelmp);
|
|
MSG_WriteString(&svs.clients[entnum-1].message, slot);//lmp label
|
|
|
|
};
|
|
|
|
|
|
void PR_MovePic(void)
|
|
{
|
|
char *slot = G_STRING(OFS_PARM0);
|
|
float x = G_FLOAT(OFS_PARM1);
|
|
float y = G_FLOAT(OFS_PARM2);
|
|
float zone = G_FLOAT(OFS_PARM3);
|
|
|
|
ParamNegateFix( &x, &y, zone );
|
|
|
|
if (sv.datagram.cursize > MAX_DATAGRAM-16)
|
|
return;
|
|
|
|
MSG_WriteByte (&sv.datagram, svc_movelmp);
|
|
MSG_WriteString(&sv.datagram, slot);
|
|
MSG_WriteByte (&sv.datagram, zone);
|
|
MSG_WriteShort (&sv.datagram, x);
|
|
MSG_WriteShort (&sv.datagram, y);
|
|
};
|
|
|
|
void PR_MovePicEnt(void)
|
|
{
|
|
char *slot = G_STRING(OFS_PARM0);
|
|
float x = G_FLOAT(OFS_PARM1);
|
|
float y = G_FLOAT(OFS_PARM2);
|
|
float zone = G_FLOAT(OFS_PARM3);
|
|
edict_t * to= G_EDICT(OFS_PARM4);
|
|
int entnum = NUM_FOR_EDICT(to);
|
|
|
|
ParamNegateFix( &x, &y, zone );
|
|
|
|
if (sv.datagram.cursize > MAX_DATAGRAM-16)
|
|
return;
|
|
|
|
MSG_WriteByte (&svs.clients[entnum-1].message, svc_movelmp);
|
|
MSG_WriteString(&svs.clients[entnum-1].message, slot);
|
|
MSG_WriteByte (&svs.clients[entnum-1].message, zone);
|
|
MSG_WriteShort (&svs.clients[entnum-1].message, x);
|
|
MSG_WriteShort (&svs.clients[entnum-1].message, y);
|
|
};
|
|
|
|
|
|
void PR_ChangePic(void)
|
|
{
|
|
char *slot = G_STRING(OFS_PARM0);
|
|
char *newpic= G_STRING(OFS_PARM1);
|
|
|
|
if (sv.datagram.cursize > MAX_DATAGRAM-16)
|
|
return;
|
|
|
|
MSG_WriteByte (&sv.datagram, svc_updatelmp);
|
|
MSG_WriteString(&sv.datagram, slot);
|
|
MSG_WriteString(&sv.datagram, newpic);
|
|
|
|
};
|
|
|
|
|
|
void PR_ChangePicEnt(void)
|
|
{
|
|
|
|
char *slot = G_STRING(OFS_PARM0);
|
|
char *newpic= G_STRING(OFS_PARM1);
|
|
edict_t * to= G_EDICT(OFS_PARM2);
|
|
int entnum = NUM_FOR_EDICT(to);
|
|
|
|
if (sv.datagram.cursize > MAX_DATAGRAM-16)
|
|
return;
|
|
|
|
MSG_WriteByte (&svs.clients[entnum-1].message, svc_updatelmp);
|
|
MSG_WriteString(&svs.clients[entnum-1].message, slot);
|
|
MSG_WriteString(&svs.clients[entnum-1].message, newpic);
|
|
|
|
};
|
|
|
|
|
|
|
|
//Tei guislots
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
BUILT-IN FUNCTIONS
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
char *PF_VarString (int first)
|
|
{
|
|
int i;
|
|
static char out[256];
|
|
|
|
out[0] = 0;
|
|
for (i=first ; i<pr_argc ; i++)
|
|
{
|
|
strcat (out, G_STRING((OFS_PARM0+i*3)));
|
|
}
|
|
return out;
|
|
}
|
|
|
|
#if 1 //Complete Implementation
|
|
char *QSG_EXTENSIONS = "\
|
|
TQ_DLIGHTS \
|
|
TQ_RAIN \
|
|
TQ_SNOW \
|
|
TQ_RAILTRAIL \
|
|
TQ_PLASMA \
|
|
TQ_SLOWMO \
|
|
DP_ENT_ALPHA \
|
|
DP_ENT_SCALE \
|
|
DP_QUAKE2_MODEL \
|
|
DP_HALFLIFE_MAP \
|
|
DP_SV_DRAWONLYTOCLIENT \
|
|
DP_SV_NODRAWTOCLIENT \
|
|
DP_MONSTERWALK \
|
|
DP_MOVETYPE_BOUNCEMISSILE \
|
|
DP_MOVETYPEFOLLOW \
|
|
DP_SOLIDCORPSE \
|
|
DP_SV_SLOWMO \
|
|
NEH_RESTOREGAME \
|
|
TEI_MD3_MODEL \
|
|
TEI_EF_EXTRA \
|
|
TEI_EF2_EXTRA \
|
|
TEI_EF3_EXTRA \
|
|
TEI_MOVMAGNETIC \
|
|
TEI_MOVMAGNETICFOLLOW \
|
|
TEI_MOVRELATIVESTATIC \
|
|
TEI_MOD_PROGS \
|
|
TEI_AUTORAIN \
|
|
TEI_AUTOZING \
|
|
TEI_AUTOSNOW \
|
|
TEI_AUTOLIGHTDAY \
|
|
TEI_AUTOLAVA \
|
|
TEI_AUTOFLUOR \
|
|
TEI_AUTOFOGWATER \
|
|
TEI_AUTOFOOT \
|
|
TEI_BOB2 \
|
|
TEI_STATICFX \
|
|
TEI_MODPREDATOR \
|
|
TEI_TPAKLOAD \
|
|
TEI_MAPMODELS \
|
|
TEI_THEMEFOLDER \
|
|
TEI_SVSKY \
|
|
TEI_MENU_MISC2 \
|
|
TEI_STEPSIZE \
|
|
TEI_AUTOANIMATION \
|
|
TEI_AUTOVANISH \
|
|
TEI_TE_PARTICLEBLAST \
|
|
TEI_TE_IMPLOSIONFX \
|
|
TEI_TE_STATICFOG \
|
|
TEI_TE_LIGHTNINGX \
|
|
TEI_TE_LIGHTNING4 \
|
|
TEI_TE_TRAILS \
|
|
TEI_TE_ALIENEXPLOSION \
|
|
TEI_TE_EXPLOSIONSMALL3 \
|
|
TEI_TE_EXPLOSIONSMALL2 \
|
|
TEI_TE_EXPLOSIONSMALL \
|
|
TEI_TE_CUSTOMFX \
|
|
TEI_SHOWLMP2 \
|
|
TEI_SHOWLMP3 \
|
|
TEI_STATCOUNT \
|
|
TEI_HUDMANAGER \
|
|
TEI_ZONEFOGS \
|
|
TEI_LOCALMENUS1 \
|
|
TEI_LOCALMENUS2 \
|
|
TEI_SUN \
|
|
TEI_MOVPREDATOR \
|
|
TEI_MOVCHASECAM \
|
|
TEI_MOVWATERFLOAT \
|
|
TEI_ENGINEVERSION \
|
|
\0";
|
|
#else //actual broken implementation (underscore to deactivate)
|
|
char *QSG_EXTENSIONS = "\
|
|
TQ_DLIGHTS \
|
|
TQ_RAIN \
|
|
TQ_SNOW \
|
|
TQ_RAILTRAIL \
|
|
TQ_PLASMA \
|
|
TQ_SLOWMO \
|
|
_DP_ENT_ALPHA \
|
|
_DP_ENT_SCALE \
|
|
DP_QUAKE2_MODEL \
|
|
DP_HALFLIFE_MAP \
|
|
_DP_SV_DRAWONLYTOCLIENT \
|
|
_DP_SV_NODRAWTOCLIENT \
|
|
_TEI_EF_EXTRA \
|
|
_TEI_EF2_EXTRA \
|
|
_TEI_EF3_EXTRA \
|
|
TEI_MOVMAGNETIC \
|
|
TEI_MOVMAGNETICFOLLOW \
|
|
TEI_MOVRELATIVESTATIC \
|
|
TEI_MOD_PROGS \
|
|
TEI_AUTORAIN \
|
|
TEI_AUTOZING \
|
|
TEI_AUTOSNOW \
|
|
TEI_AUTOLIGHTDAY \
|
|
TEI_AUTOLAVA \
|
|
TEI_AUTOFLUOR \
|
|
TEI_AUTOFOGWATER \
|
|
TEI_BOB2 \
|
|
TEI_STATICFX \
|
|
TEI_MODPREDATOR \
|
|
TEI_TPAKLOAD \
|
|
TEI_MAPMODELS \
|
|
TEI_THEMEFOLDER \
|
|
TEI_SVSKY \
|
|
TEI_MENU_MISC2 \
|
|
TEI_STEPSIZE \
|
|
TEI_AUTOANIMATION \
|
|
TEI_AUTOVANISH \
|
|
TEI_TE_PARTICLEBLAST \
|
|
TEI_TE_IMPLOSIONFX \
|
|
TEI_TE_STATICFOG \
|
|
TEI_TE_LIGHTNINGX \
|
|
TEI_TE_LIGHTNING4 \
|
|
TEI_TE_TRAILS \
|
|
TEI_TE_ALIENEXPLOSION \
|
|
TEI_TE_EXPLOSIONSMALL3 \
|
|
TEI_TE_EXPLOSIONSMALL2 \
|
|
TEI_TE_EXPLOSIONSMALL \
|
|
TEI_TE_CUSTOMFX \
|
|
TEI_SHOWLMP2 \
|
|
TEI_SHOWLMP3 \
|
|
TEI_STATCOUNT \
|
|
TEI_HUDMANAGER \
|
|
TEI_ZONEFOGS \
|
|
TEI_LOCALMENUS1 \
|
|
TEI_LOCALMENUS2 \
|
|
TEI_RSKYBOX \
|
|
TEI_LOADHUDCONSOLE \
|
|
\0";
|
|
|
|
#endif
|
|
|
|
/*
|
|
*/
|
|
|
|
qboolean checkextension(char *name)
|
|
{
|
|
int len;
|
|
char *e;
|
|
len = strlen(name);
|
|
for (e = QSG_EXTENSIONS;*e;e++)
|
|
{
|
|
while (*e == ' ')
|
|
e++;
|
|
if (!*e)
|
|
break;
|
|
if (!Q_strncasecmp(e, name, len))
|
|
return true;
|
|
while (*e && *e != ' ')
|
|
e++;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_checkextension
|
|
|
|
returns true if the extension is supported by the server
|
|
|
|
checkextension(extensionname)
|
|
=================
|
|
*/
|
|
void PF_checkextension (void)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = checkextension(G_STRING(OFS_PARM0));
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_errror
|
|
|
|
This is a TERMINAL error, which will kill off the entire server.
|
|
Dumps self.
|
|
|
|
error(value)
|
|
=================
|
|
*/
|
|
void PF_error (void)
|
|
{
|
|
char *s;
|
|
edict_t *ed;
|
|
|
|
s = PF_VarString(0);
|
|
Con_Printf ("======SERVER ERROR in %s:\n%s\n"
|
|
,pr_strings + pr_xfunction->s_name,s);
|
|
ed = PROG_TO_EDICT(pr_global_struct->self);
|
|
ED_Print (ed);
|
|
|
|
Host_Error ("Program error");
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_objerror
|
|
|
|
Dumps out self, then an error message. The program is aborted and self is
|
|
removed, but the level can continue.
|
|
|
|
objerror(value)
|
|
=================
|
|
*/
|
|
void PF_objerror (void)
|
|
{
|
|
char *s;
|
|
edict_t *ed;
|
|
|
|
s = PF_VarString(0);
|
|
Con_Printf ("======OBJECT ERROR in %s:\n%s\n"
|
|
,pr_strings + pr_xfunction->s_name,s);
|
|
ed = PROG_TO_EDICT(pr_global_struct->self);
|
|
ED_Print (ed);
|
|
ED_Free (ed);
|
|
|
|
Host_Error ("Program error");
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
==============
|
|
PF_makevectors
|
|
|
|
Writes new values for v_forward, v_up, and v_right based on angles
|
|
makevectors(vector)
|
|
==============
|
|
*/
|
|
void PF_makevectors (void)
|
|
{
|
|
AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_setorigin
|
|
|
|
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.
|
|
|
|
setorigin (entity, origin)
|
|
=================
|
|
*/
|
|
|
|
void setorigin (edict_t *e, vec3_t org)
|
|
{
|
|
VectorCopy (org, e->v.origin);
|
|
SV_LinkEdict (e, false);
|
|
}
|
|
|
|
void PF_setorigin (void)
|
|
{
|
|
edict_t *e;
|
|
float *org;
|
|
|
|
e = G_EDICT(OFS_PARM0);
|
|
org = G_VECTOR(OFS_PARM1);
|
|
VectorCopy (org, e->v.origin);
|
|
SV_LinkEdict (e, false);
|
|
}
|
|
|
|
|
|
void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
|
|
{
|
|
float *angles;
|
|
vec3_t rmin, rmax;
|
|
#ifdef SINGLEPLAYER
|
|
vec3_t tmp;
|
|
|
|
#endif
|
|
float bounds[2][3];
|
|
float xvector[2], yvector[2];
|
|
float a;
|
|
vec3_t base, transformed;
|
|
int i, j, k, l;
|
|
|
|
for (i=0 ; i<3 ; i++)
|
|
if (min[i] > max[i])
|
|
{
|
|
#ifdef SINGLEPLAYER
|
|
VectorCopy(min,tmp);
|
|
VectorCopy(max,min);
|
|
VectorCopy(tmp,max);
|
|
break;
|
|
#else
|
|
PR_RunError ("backwards mins/maxs");
|
|
#endif
|
|
}
|
|
|
|
rotate = false; // FIXME: implement rotation properly again
|
|
|
|
if (!rotate)
|
|
{
|
|
VectorCopy (min, rmin);
|
|
VectorCopy (max, rmax);
|
|
}
|
|
else
|
|
{
|
|
// find min / max for rotations
|
|
angles = e->v.angles;
|
|
|
|
a = angles[1]/180 * M_PI;
|
|
|
|
xvector[0] = cos(a);
|
|
xvector[1] = sin(a);
|
|
yvector[0] = -sin(a);
|
|
yvector[1] = cos(a);
|
|
|
|
VectorCopy (min, bounds[0]);
|
|
VectorCopy (max, bounds[1]);
|
|
|
|
rmin[0] = rmin[1] = rmin[2] = 9999;
|
|
rmax[0] = rmax[1] = rmax[2] = -9999;
|
|
|
|
for (i=0 ; i<= 1 ; i++)
|
|
{
|
|
base[0] = bounds[i][0];
|
|
for (j=0 ; j<= 1 ; j++)
|
|
{
|
|
base[1] = bounds[j][1];
|
|
for (k=0 ; k<= 1 ; k++)
|
|
{
|
|
base[2] = bounds[k][2];
|
|
|
|
// transform the point
|
|
transformed[0] = xvector[0]*base[0] + yvector[0]*base[1];
|
|
transformed[1] = xvector[1]*base[0] + yvector[1]*base[1];
|
|
transformed[2] = base[2];
|
|
|
|
for (l=0 ; l<3 ; l++)
|
|
{
|
|
if (transformed[l] < rmin[l])
|
|
rmin[l] = transformed[l];
|
|
if (transformed[l] > rmax[l])
|
|
rmax[l] = transformed[l];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// set derived values
|
|
VectorCopy (rmin, e->v.mins);
|
|
VectorCopy (rmax, e->v.maxs);
|
|
VectorSubtract (max, min, e->v.size);
|
|
|
|
SV_LinkEdict (e, false);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_setsize
|
|
|
|
the size box is rotated by the current angle
|
|
|
|
setsize (entity, minvector, maxvector)
|
|
=================
|
|
*/
|
|
void PF_setsize (void)
|
|
{
|
|
edict_t *e;
|
|
float *min, *max;
|
|
|
|
e = G_EDICT(OFS_PARM0);
|
|
min = G_VECTOR(OFS_PARM1);
|
|
max = G_VECTOR(OFS_PARM2);
|
|
SetMinMaxSize (e, min, max, false);
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
PF_setmodel
|
|
|
|
setmodel(entity, model)
|
|
=================
|
|
*/
|
|
|
|
|
|
|
|
|
|
void setmodel (edict_t* e,int im)
|
|
{
|
|
|
|
|
|
char *m, **check;
|
|
model_t *mod;
|
|
int i;
|
|
|
|
|
|
m = G_STRING(im);
|
|
|
|
//Fix no existant fire model
|
|
|
|
if (gl_particle_fire.value)
|
|
{
|
|
if (!strcmp (m, "progs/flame.mdl"))
|
|
{
|
|
for (i=0, check = sv.model_precache ; *check ; i++, check++)
|
|
if (!strcmp(*check, "progs/fire.mdl"))
|
|
{
|
|
m = "progs/fire.mdl";
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if (!strcmp (m, "progs/flame2.mdl") ||
|
|
!strcmp (m, "progs/flame3.mdl"))
|
|
for (i=0, check = sv.model_precache ; *check ; i++, check++)
|
|
{
|
|
if (!strcmp(*check, "progs/fire2.mdl"))
|
|
{
|
|
m = "progs/fire2.mdl";
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//Fix no existant fire model
|
|
|
|
// check to see if model was properly precached
|
|
for (i=0, check = sv.model_precache ; *check ; i++, check++)
|
|
if (!strcmp(*check, m))
|
|
break;
|
|
|
|
if (!*check)
|
|
{
|
|
PR_RunError ("no precache: %s\n", m);
|
|
}
|
|
|
|
|
|
e->v.model = m - pr_strings;
|
|
e->v.modelindex = i; //SV_ModelIndex (m);
|
|
|
|
mod = sv.models[ (int)e->v.modelindex]; // Mod_ForName (m, true);
|
|
|
|
if (mod)
|
|
SetMinMaxSize (e, mod->mins, mod->maxs, true);
|
|
else
|
|
SetMinMaxSize (e, vec3_origin, vec3_origin, true);
|
|
}
|
|
|
|
|
|
void PF_setmodel (void)
|
|
{
|
|
/*
|
|
static char *oldmodel;
|
|
static model_t *oldmod;
|
|
static int oldi;
|
|
*/
|
|
|
|
edict_t *e;
|
|
char *m, **check;
|
|
model_t *mod;
|
|
int i;
|
|
|
|
|
|
e = G_EDICT(OFS_PARM0);
|
|
m = G_STRING(OFS_PARM1);
|
|
|
|
/*
|
|
if (strcmp(oldmodel, m))
|
|
{*/
|
|
//Fix no existant fire model
|
|
|
|
if (gl_particle_fire.value)
|
|
{
|
|
if (!strcmp (m, "progs/flame.mdl"))
|
|
{
|
|
for (i=0, check = sv.model_precache ; *check ; i++, check++)
|
|
if (!strcmp(*check, "progs/fire.mdl"))
|
|
{
|
|
m = "progs/fire.mdl";
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if (!strcmp (m, "progs/flame2.mdl") ||
|
|
!strcmp (m, "progs/flame3.mdl"))
|
|
for (i=0, check = sv.model_precache ; *check ; i++, check++)
|
|
{
|
|
if (!strcmp(*check, "progs/fire2.mdl"))
|
|
{
|
|
m = "progs/fire2.mdl";
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//Fix no existant fire model
|
|
|
|
// check to see if model was properly precached
|
|
for (i=0, check = sv.model_precache ; *check ; i++, check++)
|
|
if (!strcmp(*check, m))
|
|
break;
|
|
|
|
if (!*check)
|
|
{
|
|
PR_RunError ("no precache: %s\n", m);
|
|
}
|
|
|
|
/*
|
|
oldmodel = m;
|
|
oldi = i;
|
|
}
|
|
else
|
|
{
|
|
m = oldmodel;
|
|
i = oldi;
|
|
}*/
|
|
|
|
e->v.model = m - pr_strings;
|
|
e->v.modelindex = i; //SV_ModelIndex (m);
|
|
|
|
mod = sv.models[ (int)e->v.modelindex]; // Mod_ForName (m, true);
|
|
|
|
if (mod)
|
|
SetMinMaxSize (e, mod->mins, mod->maxs, true);
|
|
else
|
|
SetMinMaxSize (e, vec3_origin, vec3_origin, true);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_bprint
|
|
|
|
broadcast print to everyone on server
|
|
|
|
bprint(value)
|
|
=================
|
|
*/
|
|
void PF_bprint (void)
|
|
{
|
|
char *s;
|
|
|
|
s = PF_VarString(0);
|
|
|
|
//Tei speed
|
|
if (!DOSINGLE)
|
|
SV_BroadcastPrintf ("%s", s);
|
|
else
|
|
Con_Printf ("%s", s);
|
|
|
|
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_sprint
|
|
|
|
single print to a specific client
|
|
|
|
sprint(clientent, value)
|
|
=================
|
|
*/
|
|
void PF_sprint (void)
|
|
{
|
|
char *s;
|
|
client_t *client;
|
|
int entnum;
|
|
|
|
entnum = G_EDICTNUM(OFS_PARM0);
|
|
s = PF_VarString(1);
|
|
|
|
if (entnum < 1 || entnum > svs.maxclients)
|
|
{
|
|
Con_Printf ("tried to sprint to a non-client\n");
|
|
return;
|
|
}
|
|
|
|
client = &svs.clients[entnum-1];
|
|
|
|
//Tei SPE stuff
|
|
if (!DOSINGLE)
|
|
{
|
|
MSG_WriteChar (&client->message,svc_print);
|
|
MSG_WriteString (&client->message, s );
|
|
}
|
|
else
|
|
{
|
|
Con_Printf ("%s", s);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
PF_centerprint
|
|
|
|
single print to a specific client
|
|
|
|
centerprint(clientent, value)
|
|
=================
|
|
*/
|
|
void PF_centerprint (void)
|
|
{
|
|
char *s;
|
|
client_t *client;
|
|
int entnum;
|
|
|
|
entnum = G_EDICTNUM(OFS_PARM0);
|
|
s = PF_VarString(1);
|
|
|
|
if (entnum < 1 || entnum > svs.maxclients)
|
|
{
|
|
Con_Printf ("tried to sprint to a non-client\n");
|
|
return;
|
|
}
|
|
|
|
client = &svs.clients[entnum-1];
|
|
|
|
if (!DOSINGLE) //Tei spe-for telejano
|
|
{
|
|
MSG_WriteChar (&client->message,svc_centerprint);
|
|
MSG_WriteString (&client->message, s );
|
|
}
|
|
else
|
|
SCR_CenterPrint (s);
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
PF_normalize
|
|
|
|
vector normalize(vector)
|
|
=================
|
|
*/
|
|
void PF_normalize (void)
|
|
{
|
|
float *value1;
|
|
vec3_t newvalue;
|
|
float new;
|
|
|
|
value1 = G_VECTOR(OFS_PARM0);
|
|
|
|
new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
|
|
new = sqrt(new);
|
|
|
|
if (new == 0)
|
|
newvalue[0] = newvalue[1] = newvalue[2] = 0;
|
|
else
|
|
{
|
|
new = 1/new;
|
|
newvalue[0] = value1[0] * new;
|
|
newvalue[1] = value1[1] * new;
|
|
newvalue[2] = value1[2] * new;
|
|
}
|
|
|
|
VectorCopy (newvalue, G_VECTOR(OFS_RETURN));
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_vlen
|
|
|
|
scalar vlen(vector)
|
|
=================
|
|
*/
|
|
void PF_vlen (void)
|
|
{
|
|
float *value1;
|
|
float new;
|
|
|
|
value1 = G_VECTOR(OFS_PARM0);
|
|
|
|
new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
|
|
new = sqrt(new);
|
|
|
|
G_FLOAT(OFS_RETURN) = new;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_vectoyaw
|
|
|
|
float vectoyaw(vector)
|
|
=================
|
|
*/
|
|
void PF_vectoyaw (void)
|
|
{
|
|
float *value1;
|
|
float yaw;
|
|
|
|
value1 = G_VECTOR(OFS_PARM0);
|
|
|
|
if (value1[1] == 0 && value1[0] == 0)
|
|
yaw = 0;
|
|
else
|
|
{
|
|
yaw = (int) (atan2(value1[1], value1[0]) * 57.295779513082320); // Tomaz Speed
|
|
if (yaw < 0)
|
|
yaw += 360;
|
|
}
|
|
|
|
G_FLOAT(OFS_RETURN) = yaw;
|
|
}
|
|
|
|
float vectoyaw (vec3_t value1)
|
|
{
|
|
float yaw;
|
|
|
|
if (value1[1] == 0 && value1[0] == 0)
|
|
yaw = 0;
|
|
else
|
|
{
|
|
yaw = (int) (atan2(value1[1], value1[0]) * 57.295779513082320); // Tomaz Speed
|
|
if (yaw < 0)
|
|
yaw += 360;
|
|
}
|
|
|
|
return yaw;
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
PF_vectoangles
|
|
|
|
vector vectoangles(vector)
|
|
=================
|
|
*/
|
|
|
|
void vectoangles (vec3_t value1,vec3_t out)
|
|
{
|
|
float forward;
|
|
float yaw, pitch;
|
|
|
|
if (value1[1] == 0 && value1[0] == 0)
|
|
{
|
|
yaw = 0;
|
|
if (value1[2] > 0)
|
|
pitch = 90;
|
|
else
|
|
pitch = 270;
|
|
}
|
|
else
|
|
{
|
|
yaw = (int) (atan2(value1[1], value1[0]) * 57.295779513082320); // Tomaz Speed
|
|
if (yaw < 0)
|
|
yaw += 360;
|
|
|
|
forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]);
|
|
pitch = (int) (atan2(value1[2], forward) * 57.295779513082320); // Tomaz Speed
|
|
if (pitch < 0)
|
|
pitch += 360;
|
|
}
|
|
|
|
out[0] = pitch;
|
|
out[1] = yaw;
|
|
out[2] = 0;
|
|
}
|
|
|
|
void PF_vectoangles (void)
|
|
{
|
|
float *value1;
|
|
float forward;
|
|
float yaw, pitch;
|
|
|
|
value1 = G_VECTOR(OFS_PARM0);
|
|
|
|
if (value1[1] == 0 && value1[0] == 0)
|
|
{
|
|
yaw = 0;
|
|
if (value1[2] > 0)
|
|
pitch = 90;
|
|
else
|
|
pitch = 270;
|
|
}
|
|
else
|
|
{
|
|
yaw = (int) (atan2(value1[1], value1[0]) * 57.295779513082320); // Tomaz Speed
|
|
if (yaw < 0)
|
|
yaw += 360;
|
|
|
|
forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]);
|
|
pitch = (int) (atan2(value1[2], forward) * 57.295779513082320); // Tomaz Speed
|
|
if (pitch < 0)
|
|
pitch += 360;
|
|
}
|
|
|
|
G_FLOAT(OFS_RETURN+0) = pitch;
|
|
G_FLOAT(OFS_RETURN+1) = yaw;
|
|
G_FLOAT(OFS_RETURN+2) = 0;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_Random
|
|
|
|
Returns a number from 0<= num < 1
|
|
|
|
random()
|
|
=================
|
|
*/
|
|
void PF_random (void)
|
|
{
|
|
float num;
|
|
|
|
num = (rand ()&0x7fff) / ((float)0x7fff);
|
|
|
|
G_FLOAT(OFS_RETURN) = num;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_particle
|
|
|
|
particle(origin, color, count)
|
|
=================
|
|
*/
|
|
void PF_particle (void)
|
|
{
|
|
float *org, *dir;
|
|
float color;
|
|
float count;
|
|
|
|
org = G_VECTOR(OFS_PARM0);
|
|
dir = G_VECTOR(OFS_PARM1);
|
|
color = G_FLOAT(OFS_PARM2);
|
|
count = G_FLOAT(OFS_PARM3);
|
|
|
|
if (!DOSINGLE) //Tei spe-for telejano
|
|
SV_StartParticle (org, dir, color, count);
|
|
else
|
|
R_RunParticleEffect (org, dir, color, count);
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
PF_ambientsound
|
|
|
|
=================
|
|
*/
|
|
|
|
int IsPrecacheSound( char * samp)
|
|
{
|
|
char **check;
|
|
int soundnum;
|
|
|
|
// check to see if samp was properly precached
|
|
for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++)
|
|
if (!strcmp(*check,samp))
|
|
return soundnum;
|
|
|
|
return false;
|
|
}
|
|
|
|
void PF_ambientsound (void)
|
|
{
|
|
char **check;
|
|
char *samp;
|
|
float *pos;
|
|
float vol, attenuation;
|
|
int i, soundnum;
|
|
|
|
pos = G_VECTOR (OFS_PARM0);
|
|
samp = G_STRING(OFS_PARM1);
|
|
vol = G_FLOAT(OFS_PARM2);
|
|
attenuation = G_FLOAT(OFS_PARM3);
|
|
|
|
// check to see if samp was properly precached
|
|
for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++)
|
|
if (!strcmp(*check,samp))
|
|
break;
|
|
|
|
if (!*check)
|
|
{
|
|
Con_Printf ("no precache: %s\n", samp);
|
|
return;
|
|
}
|
|
|
|
// add an svc_spawnambient command to the level signon packet
|
|
// if (!deathmatch.value && !coop.value) //Tei spe-for telejano
|
|
// S_StaticSound (cl.sound_precache[soundnum], pos, vol*255, attenuation*64);
|
|
// else
|
|
// {
|
|
MSG_WriteByte (&sv.signon,svc_spawnstaticsound);
|
|
for (i=0 ; i<3 ; i++)
|
|
MSG_WriteCoord(&sv.signon, pos[i]);
|
|
|
|
MSG_WriteByte (&sv.signon, soundnum);
|
|
|
|
MSG_WriteByte (&sv.signon, vol*255);
|
|
MSG_WriteByte (&sv.signon, attenuation*64);
|
|
//}
|
|
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_sound
|
|
|
|
Each entity can have eight independant sound sources, like voice,
|
|
weapon, feet, etc.
|
|
|
|
Channel 0 is an auto-allocate channel, the others override anything
|
|
allready running on that entity/channel pair.
|
|
|
|
An attenuation of 0 will play full volume everywhere in the level.
|
|
Larger attenuations will drop off.
|
|
|
|
=================
|
|
*/
|
|
|
|
extern cvar_t sp_nofarsound;
|
|
void PF_sound (void)
|
|
{
|
|
char *sample;
|
|
int channel;
|
|
edict_t *entity;
|
|
int volume, sound_num;
|
|
float attenuation;
|
|
vec3_t pos, dis;
|
|
int ent;
|
|
|
|
|
|
|
|
|
|
entity = G_EDICT(OFS_PARM0);
|
|
channel = G_FLOAT(OFS_PARM1);
|
|
sample = G_STRING(OFS_PARM2);
|
|
volume = G_FLOAT(OFS_PARM3) * 255;
|
|
attenuation = G_FLOAT(OFS_PARM4);
|
|
|
|
channel %= 8;
|
|
volume %= 256;
|
|
|
|
if (attenuation < 0 || attenuation > 4)
|
|
{
|
|
if (!DOSINGLE)
|
|
Sys_Error ("S_StartSound: attenuation = %f", attenuation);
|
|
else
|
|
Sys_Error ("SV_StartSound: attenuation = %f", attenuation);
|
|
}
|
|
|
|
if (!DOSINGLE) //Tei spe-for telejano
|
|
{
|
|
SV_StartSound (entity, channel, sample, volume, attenuation);//from server
|
|
}
|
|
else
|
|
{
|
|
for (sound_num=1 ; sound_num<MAX_SOUNDS
|
|
&& sv.sound_precache[sound_num] ; sound_num++)
|
|
if (!strcmp(sample, sv.sound_precache[sound_num]))
|
|
break;
|
|
|
|
if ( sound_num == MAX_SOUNDS || !sv.sound_precache[sound_num] )
|
|
{
|
|
Con_Printf ("S_StartSound: %s not precacheed\n", sample);
|
|
return;
|
|
}
|
|
pos[0] = entity->v.origin[0]+0.5*(entity->v.mins[0]+entity->v.maxs[0]);
|
|
pos[1] = entity->v.origin[1]+0.5*(entity->v.mins[1]+entity->v.maxs[1]);
|
|
pos[2] = entity->v.origin[2]+0.5*(entity->v.mins[2]+entity->v.maxs[2]);
|
|
|
|
|
|
if (sp_nofarsound.value)
|
|
{
|
|
|
|
VectorSubtract(pos, cl_entities[cl.viewentity].origin,dis);
|
|
if (Length( dis ) > 1000)
|
|
{
|
|
//Con_Printf("Optimized out...\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
ent = NUM_FOR_EDICT(entity);
|
|
S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);//SPE
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_break
|
|
|
|
break()
|
|
=================
|
|
*/
|
|
void PF_break (void)
|
|
{
|
|
Con_Printf ("break statement\n");
|
|
*(int *)-4 = 0; // dump to debugger
|
|
// PR_RunError ("break statement");
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_traceline
|
|
|
|
Used for use tracing and shot targeting
|
|
Traces are blocked by bbox and exact bsp entityes, and also slide box entities
|
|
if the tryents flag is set.
|
|
|
|
traceline (vector1, vector2, tryents)
|
|
=================
|
|
*/
|
|
void PF_traceline (void)
|
|
{
|
|
float *v1, *v2;
|
|
trace_t trace;
|
|
int nomonsters;
|
|
edict_t *ent;
|
|
|
|
v1 = G_VECTOR(OFS_PARM0);
|
|
v2 = G_VECTOR(OFS_PARM1);
|
|
nomonsters = G_FLOAT(OFS_PARM2);
|
|
ent = G_EDICT(OFS_PARM3);
|
|
|
|
trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters, ent);
|
|
|
|
pr_global_struct->trace_allsolid = trace.allsolid;
|
|
pr_global_struct->trace_startsolid = trace.startsolid;
|
|
pr_global_struct->trace_fraction = trace.fraction;
|
|
pr_global_struct->trace_inwater = trace.inwater;
|
|
pr_global_struct->trace_inopen = trace.inopen;
|
|
VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
|
|
VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
|
|
pr_global_struct->trace_plane_dist = trace.plane.dist;
|
|
if (trace.ent)
|
|
pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
|
|
else
|
|
pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
|
|
}
|
|
|
|
// Tei traceline
|
|
void PR_traceline ( vec3_t v1, vec3_t v2, float nomonsters, edict_t * ent)
|
|
{
|
|
trace_t trace;
|
|
|
|
|
|
trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters, ent);
|
|
|
|
pr_global_struct->trace_allsolid = trace.allsolid;
|
|
pr_global_struct->trace_startsolid = trace.startsolid;
|
|
pr_global_struct->trace_fraction = trace.fraction;
|
|
pr_global_struct->trace_inwater = trace.inwater;
|
|
pr_global_struct->trace_inopen = trace.inopen;
|
|
VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
|
|
VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
|
|
pr_global_struct->trace_plane_dist = trace.plane.dist;
|
|
if (trace.ent)
|
|
pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
|
|
else
|
|
pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
|
|
}
|
|
// Tei traceline
|
|
|
|
/*
|
|
float (entity targ) visible =
|
|
{
|
|
local vector spot1, spot2;
|
|
|
|
spot1 = self.origin + self.view_ofs;
|
|
spot2 = targ.origin + (targ.mins + targ.maxs) * 0.5 + targ.view_ofs;
|
|
|
|
traceline (spot1, spot2, TRUE, self); // see through other monsters
|
|
|
|
if (trace_inopen && trace_inwater)
|
|
{
|
|
return FALSE; // sight line crossed contents
|
|
}
|
|
|
|
if (trace_ent == targ)
|
|
return TRUE;
|
|
|
|
if (trace_fraction == 1)
|
|
return TRUE;
|
|
return FALSE;
|
|
};
|
|
*/
|
|
//*
|
|
|
|
//Tei visible
|
|
|
|
void PF_VisibleEnt (void)
|
|
{
|
|
vec3_t v1, v2;
|
|
trace_t trace;
|
|
//int out;
|
|
edict_t *ent;
|
|
edict_t *eself;
|
|
|
|
|
|
|
|
|
|
ent = G_EDICT(OFS_PARM0);
|
|
eself = G_EDICT(OFS_PARM1);//PROG_TO_EDICT(pr_global_struct->self);
|
|
|
|
|
|
|
|
|
|
VectorCopy ( eself->v.origin, v1 );
|
|
VectorCopy ( ent->v.origin, v2 );
|
|
|
|
//return;
|
|
//trace = SV_Move (v1, vec3_origin, vec3_origin, v2, 1, ent);
|
|
trace = SV_Move ( v1, vec3_origin, vec3_origin,v2, 1, ent);
|
|
|
|
//out = 1;
|
|
|
|
if ( trace.inwater && trace.inopen ) {
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
return;
|
|
}
|
|
|
|
|
|
if ( trace.ent == ent ) {
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
return;
|
|
}
|
|
|
|
if (trace.fraction > 0.99999) {
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
return;
|
|
}
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void PF_Visible (void)
|
|
{
|
|
vec3_t v1, v2;
|
|
trace_t trace;
|
|
//int out;
|
|
edict_t *ent;
|
|
edict_t *eself;
|
|
|
|
|
|
|
|
|
|
ent = G_EDICT(OFS_PARM0);
|
|
eself = PROG_TO_EDICT(pr_global_struct->self);
|
|
|
|
|
|
|
|
|
|
VectorCopy ( eself->v.origin, v1 );
|
|
VectorCopy ( ent->v.origin, v2 );
|
|
|
|
//return;
|
|
//trace = SV_Move (v1, vec3_origin, vec3_origin, v2, 1, ent);
|
|
trace = SV_Move ( v1, vec3_origin, vec3_origin,v2, 1, ent);
|
|
|
|
//out = 1;
|
|
|
|
if ( trace.inwater && trace.inopen ) {
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
return;
|
|
}
|
|
|
|
|
|
if ( trace.ent == ent ) {
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
return;
|
|
}
|
|
|
|
if (trace.fraction > 0.99999) {
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
return;
|
|
}
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
return;
|
|
}
|
|
|
|
// Tei visible
|
|
|
|
/*
|
|
|
|
float(float v) anglemod =
|
|
{
|
|
while (v >= 360)
|
|
v = v - 360;
|
|
while (v < 0)
|
|
v = v + 360;
|
|
return v;
|
|
};
|
|
|
|
*/
|
|
|
|
void PF_AngleMod (void)
|
|
{
|
|
float v;
|
|
|
|
v = G_FLOAT(OFS_PARM0);
|
|
|
|
v = anglemod( v );
|
|
|
|
G_FLOAT(OFS_RETURN) = v;
|
|
}
|
|
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
byte checkpvs[MAX_MAP_LEAFS/8];
|
|
|
|
int PF_newcheckclient (int check)
|
|
{
|
|
int i;
|
|
byte *pvs;
|
|
edict_t *ent;
|
|
mleaf_t *leaf;
|
|
vec3_t org;
|
|
|
|
// cycle to the next one
|
|
|
|
if (check < 1)
|
|
check = 1;
|
|
if (check > svs.maxclients)
|
|
check = svs.maxclients;
|
|
|
|
if (check == svs.maxclients)
|
|
i = 1;
|
|
else
|
|
i = check + 1;
|
|
|
|
for ( ; ; i++)
|
|
{
|
|
if (i == svs.maxclients+1)
|
|
i = 1;
|
|
|
|
ent = EDICT_NUM(i);
|
|
|
|
if (i == check)
|
|
break; // didn't find anything else
|
|
|
|
if (ent->free)
|
|
continue;
|
|
if (ent->v.health <= 0)
|
|
continue;
|
|
if ((int)ent->v.flags & FL_NOTARGET)
|
|
continue;
|
|
|
|
// anything that is a client, or has a client as an enemy
|
|
break;
|
|
}
|
|
|
|
// get the PVS for the entity
|
|
VectorAdd (ent->v.origin, ent->v.view_ofs, org);
|
|
leaf = Mod_PointInLeaf (org, sv.worldmodel);
|
|
pvs = Mod_LeafPVS (leaf, sv.worldmodel);
|
|
memcpy (checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 );
|
|
|
|
return i;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_checkclient
|
|
|
|
Returns a client (or object that has a client enemy) that would be a
|
|
valid target.
|
|
|
|
If there are more than one valid options, they are cycled each frame
|
|
|
|
If (self.origin + self.viewofs) is not in the PVS of the current target,
|
|
it is not returned at all.
|
|
|
|
name checkclient ()
|
|
=================
|
|
*/
|
|
#define MAX_CHECK 16
|
|
int c_invis, c_notvis;
|
|
void PF_checkclient (void)
|
|
{
|
|
edict_t *ent, *self;
|
|
mleaf_t *leaf;
|
|
int l;
|
|
vec3_t view;
|
|
|
|
// find a new check if on a new frame
|
|
if (sv.time - sv.lastchecktime >= 0.1)
|
|
{
|
|
sv.lastcheck = PF_newcheckclient (sv.lastcheck);
|
|
sv.lastchecktime = sv.time;
|
|
}
|
|
|
|
// return check if it might be visible
|
|
ent = EDICT_NUM(sv.lastcheck);
|
|
if (ent->free || ent->v.health <= 0)
|
|
{
|
|
RETURN_EDICT(sv.edicts);
|
|
return;
|
|
}
|
|
|
|
// if current entity can't possibly see the check entity, return 0
|
|
self = PROG_TO_EDICT(pr_global_struct->self);
|
|
VectorAdd (self->v.origin, self->v.view_ofs, view);
|
|
leaf = Mod_PointInLeaf (view, sv.worldmodel);
|
|
l = (leaf - sv.worldmodel->leafs) - 1;
|
|
if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
|
|
{
|
|
c_notvis++;
|
|
RETURN_EDICT(sv.edicts);
|
|
return;
|
|
}
|
|
|
|
// might be able to see it
|
|
c_invis++;
|
|
RETURN_EDICT(ent);
|
|
}
|
|
|
|
//============================================================================
|
|
|
|
|
|
/*
|
|
=================
|
|
PF_stuffcmd
|
|
|
|
Sends text over to the client's execution buffer
|
|
|
|
stuffcmd (clientent, value)
|
|
=================
|
|
*/
|
|
void PF_stuffcmd (void)
|
|
{
|
|
int entnum;
|
|
char *str;
|
|
client_t *old;
|
|
|
|
entnum = G_EDICTNUM(OFS_PARM0);
|
|
if (entnum < 1 || entnum > svs.maxclients)
|
|
PR_RunError ("Parm 0 not a client");
|
|
str = G_STRING(OFS_PARM1);
|
|
|
|
old = host_client;
|
|
host_client = &svs.clients[entnum-1];
|
|
Host_ClientCommands ("%s", str);
|
|
host_client = old;
|
|
}
|
|
|
|
// Tei rexec good
|
|
void Host_ClientCommands2 (char *fmt, ...);
|
|
|
|
void PF_stuffcmd2 (void)
|
|
{
|
|
int entnum;
|
|
char *str;
|
|
client_t *old;
|
|
|
|
entnum = G_EDICTNUM(OFS_PARM0);
|
|
if (entnum < 1 || entnum > svs.maxclients)
|
|
PR_RunError ("Parm 0 not a client");
|
|
str = G_STRING(OFS_PARM1);
|
|
|
|
old = host_client;
|
|
host_client = &svs.clients[entnum-1];
|
|
Host_ClientCommands2 ("%s", str);
|
|
host_client = old;
|
|
}
|
|
// Tei rexec good
|
|
|
|
// Tei changefov
|
|
void PF_SetFov (void)
|
|
{
|
|
int entnum;
|
|
char val;
|
|
client_t *old;
|
|
|
|
entnum = G_EDICTNUM(OFS_PARM0);
|
|
if (entnum < 1 || entnum > svs.maxclients)
|
|
PR_RunError ("Parm 0 not a client");
|
|
val = G_FLOAT(OFS_PARM1);
|
|
|
|
old = host_client;
|
|
host_client = &svs.clients[entnum-1];
|
|
|
|
MSG_WriteByte (&host_client->message, svc_changefov);
|
|
MSG_WriteByte (&host_client->message, val);
|
|
|
|
host_client = old;
|
|
}
|
|
// Tei changefov
|
|
|
|
|
|
|
|
/*
|
|
=================
|
|
PF_localcmd
|
|
|
|
Sends text over to the client's execution buffer
|
|
|
|
localcmd (string)
|
|
=================
|
|
*/
|
|
void PF_localcmd (void)
|
|
{
|
|
char *str;
|
|
|
|
str = G_STRING(OFS_PARM0);
|
|
Cbuf_AddText (str);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_cvar
|
|
|
|
float cvar (string)
|
|
=================
|
|
*/
|
|
void PF_cvar (void)
|
|
{
|
|
char *str;
|
|
|
|
str = G_STRING(OFS_PARM0);
|
|
|
|
G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str);
|
|
}
|
|
|
|
|
|
void PF_cvarstring (void)
|
|
{
|
|
char *str;
|
|
char * d;
|
|
|
|
d = pr_string_temp;
|
|
memset(d, 0, 127);
|
|
|
|
str = G_STRING(OFS_PARM0);
|
|
|
|
|
|
Q_strcpy(pr_string_temp, Cvar_VariableString (str));
|
|
|
|
G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
=================
|
|
PF_cvar_set
|
|
|
|
float cvar (string)
|
|
=================
|
|
*/
|
|
void PF_cvar_set (void)
|
|
{
|
|
char *var, *val;
|
|
|
|
var = G_STRING(OFS_PARM0);
|
|
val = G_STRING(OFS_PARM1);
|
|
|
|
Cvar_Set (var, val);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PF_findradius
|
|
|
|
Returns a chain of entities that have origins within a spherical area
|
|
|
|
findradius (origin, radius)
|
|
=================
|
|
*/
|
|
void PF_findradius (void)
|
|
{
|
|
edict_t *ent, *chain;
|
|
float rad;
|
|
float *org;
|
|
vec3_t eorg;
|
|
int i, j;
|
|
|
|
chain = (edict_t *)sv.edicts;
|
|
|
|
org = G_VECTOR(OFS_PARM0);
|
|
rad = G_FLOAT(OFS_PARM1);
|
|
|
|
ent = NEXT_EDICT(sv.edicts);
|
|
for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
|
|
{
|
|
if (ent->free)
|
|
continue;
|
|
if (ent->v.solid == SOLID_NOT)
|
|
continue;
|
|
for (j=0 ; j<3 ; j++)
|
|
eorg[j] = org[j] - (ent->v.origin[j] + (ent->v.mins[j] + ent->v.maxs[j])*0.5);
|
|
if (Length(eorg) > rad)
|
|
continue;
|
|
|
|
ent->v.chain = EDICT_TO_PROG(chain);
|
|
chain = ent;
|
|
}
|
|
|
|
RETURN_EDICT(chain);
|
|
}
|
|
|
|
|
|
/*
|
|
=========
|
|
PF_dprint
|
|
=========
|
|
*/
|
|
void PF_dprint (void)
|
|
{
|
|
Con_DPrintf ("%s",PF_VarString(0));
|
|
}
|
|
|
|
|
|
void PF_ftos (void)
|
|
{
|
|
float v;
|
|
int i;
|
|
|
|
v = G_FLOAT(OFS_PARM0);
|
|
|
|
if (v == (int)v)
|
|
sprintf (pr_string_temp, "%d",(int)v);
|
|
else
|
|
{
|
|
sprintf (pr_string_temp, "%1f", v);
|
|
for (i=Q_strlen(pr_string_temp)-1 ; i>0 && pr_string_temp[i]=='0' && pr_string_temp[i-1]!='.' ; i--)
|
|
{
|
|
pr_string_temp[i] = 0;
|
|
}
|
|
}
|
|
G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
|
|
}
|
|
|
|
void PF_fabs (void)
|
|
{
|
|
float v;
|
|
v = G_FLOAT(OFS_PARM0);
|
|
G_FLOAT(OFS_RETURN) = fabs(v);
|
|
}
|
|
|
|
void PF_vtos (void)
|
|
{
|
|
sprintf (pr_string_temp, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
|
|
G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
|
|
}
|
|
|
|
void PF_Spawn (void)
|
|
{
|
|
edict_t *ed;
|
|
char *p = (char *)0;
|
|
|
|
ed = ED_Alloc();
|
|
RETURN_EDICT(ed);
|
|
}
|
|
|
|
void PF_Remove (void)
|
|
{
|
|
edict_t *ed;
|
|
|
|
ed = G_EDICT(OFS_PARM0);
|
|
|
|
if ( !G_FLOAT(OFS_PARM0))
|
|
{
|
|
Con_Printf("Tries to remove world!\n" );
|
|
PF_error();
|
|
}
|
|
|
|
ED_Free (ed);
|
|
}
|
|
|
|
|
|
// entity (entity start, .string field, string match) find = #5;
|
|
void PF_Find (void)
|
|
{
|
|
int e;
|
|
int f;
|
|
char *s, *t;
|
|
edict_t *ed;
|
|
|
|
e = G_EDICTNUM(OFS_PARM0);
|
|
f = G_INT(OFS_PARM1);
|
|
s = G_STRING(OFS_PARM2);
|
|
if (!s)
|
|
PR_RunError ("PF_Find: bad search string");
|
|
|
|
for (e++ ; e < sv.num_edicts ; e++)
|
|
{
|
|
ed = EDICT_NUM(e);
|
|
if (ed->free)
|
|
continue;
|
|
t = E_STRING(ed,f);
|
|
if (!t)
|
|
continue;
|
|
if (!strcmp(t,s))
|
|
{
|
|
RETURN_EDICT(ed);
|
|
return;
|
|
}
|
|
}
|
|
|
|
RETURN_EDICT(sv.edicts);
|
|
}
|
|
|
|
void PR_CheckEmptyString (char *s)
|
|
{
|
|
if (s[0] <= ' ')
|
|
PR_RunError ("Bad string");
|
|
}
|
|
|
|
void PF_precache_file (void)
|
|
{ // precache_file is only used to copy files with qcc, it does nothing
|
|
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
|
|
}
|
|
|
|
void PF_precache_sound (void)
|
|
{
|
|
char *s;
|
|
int i;
|
|
|
|
if (sv.state != ss_loading)
|
|
PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
|
|
|
|
s = G_STRING(OFS_PARM0);
|
|
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
|
|
PR_CheckEmptyString (s);
|
|
|
|
for (i=0 ; i<MAX_SOUNDS ; i++)
|
|
{
|
|
if (!sv.sound_precache[i])
|
|
{
|
|
sv.sound_precache[i] = s;
|
|
return;
|
|
}
|
|
if (!strcmp(sv.sound_precache[i], s))
|
|
return;
|
|
}
|
|
PR_RunError ("PF_precache_sound: overflow");
|
|
}
|
|
|
|
void PF_precache_model (void)
|
|
{
|
|
char *s;
|
|
int i;
|
|
|
|
if (sv.state != ss_loading)
|
|
PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
|
|
|
|
s = G_STRING(OFS_PARM0);
|
|
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
|
|
PR_CheckEmptyString (s);
|
|
|
|
if (gl_particle_fire.value)
|
|
{
|
|
if (!strcmp (s, "progs/flame.mdl"))
|
|
s = "progs/fire.mdl";
|
|
|
|
if (!strcmp (s, "progs/flame2.mdl") ||
|
|
!strcmp (s, "progs/flame3.mdl"))
|
|
s = "progs/fire2.mdl";
|
|
}
|
|
|
|
for (i=0 ; i<MAX_MODELS ; i++)
|
|
{
|
|
if (!sv.model_precache[i])
|
|
{
|
|
sv.model_precache[i] = s;
|
|
sv.models[i] = Mod_ForName (s, true);
|
|
return;
|
|
}
|
|
if (!strcmp(sv.model_precache[i], s))
|
|
return;
|
|
}
|
|
PR_RunError ("PF_precache_model: overflow");
|
|
}
|
|
|
|
void PF_coredump (void)
|
|
{
|
|
ED_PrintEdicts ();
|
|
}
|
|
|
|
void PF_traceon (void)
|
|
{
|
|
pr_trace = true;
|
|
}
|
|
|
|
void PF_traceoff (void)
|
|
{
|
|
pr_trace = false;
|
|
}
|
|
|
|
void PF_eprint (void)
|
|
{
|
|
ED_PrintNum (G_EDICTNUM(OFS_PARM0));
|
|
}
|
|
|
|
/*
|
|
===============
|
|
PF_walkmove
|
|
|
|
float(float yaw, float dist) walkmove
|
|
===============
|
|
*/
|
|
void PF_walkmove (void)
|
|
{
|
|
edict_t *ent;
|
|
float yaw, dist;
|
|
vec3_t move, forward,right,up;
|
|
dfunction_t *oldf;
|
|
int oldself;
|
|
|
|
ent = PROG_TO_EDICT(pr_global_struct->self);
|
|
yaw = G_FLOAT(OFS_PARM0);
|
|
dist = G_FLOAT(OFS_PARM1);
|
|
|
|
if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
|
|
{
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
return;
|
|
}
|
|
|
|
yaw = yaw*6.283186307179586 / 360; // Tomaz Speed
|
|
|
|
move[0] = cos(yaw)*dist;
|
|
move[1] = sin(yaw)*dist;
|
|
move[2] = 0;
|
|
|
|
// save program state, because SV_movestep may call other progs
|
|
oldf = pr_xfunction;
|
|
oldself = pr_global_struct->self;
|
|
|
|
//if (lhrandom(0,100)<90)
|
|
G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
|
|
/*
|
|
else
|
|
if (!SV_movestep(ent, move, true))
|
|
{
|
|
AngleVectors(move,forward,right,up);
|
|
if( SV_movestep(ent, right, true) )
|
|
{
|
|
//ent->v.ideal_yaw = vectoyaw(right);
|
|
return true;
|
|
}
|
|
}
|
|
return false;*/
|
|
|
|
|
|
// restore program state
|
|
pr_xfunction = oldf;
|
|
pr_global_struct->self = oldself;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
PF_droptofloor
|
|
|
|
void() droptofloor
|
|
===============
|
|
*/
|
|
void PF_droptofloor (void)
|
|
{
|
|
edict_t *ent;
|
|
vec3_t end;
|
|
trace_t trace;
|
|
|
|
ent = PROG_TO_EDICT(pr_global_struct->self);
|
|
|
|
VectorCopy (ent->v.origin, end);
|
|
end[2] -= 256;
|
|
|
|
trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent);
|
|
|
|
if (trace.fraction == 1 || trace.allsolid)
|
|
G_FLOAT(OFS_RETURN) = 0;
|
|
else
|
|
{
|
|
VectorCopy (trace.endpos, ent->v.origin);
|
|
SV_LinkEdict (ent, false);
|
|
ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
|
|
ent->v.groundentity = EDICT_TO_PROG(trace.ent);
|
|
G_FLOAT(OFS_RETURN) = 1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
===============
|
|
PF_lightstyle
|
|
|
|
void(float style, string value) lightstyle
|
|
===============
|
|
*/
|
|
void PF_lightstyle (void)
|
|
{
|
|
int style;
|
|
char *val;
|
|
client_t *client;
|
|
int j;
|
|
|
|
style = G_FLOAT(OFS_PARM0);
|
|
val = G_STRING(OFS_PARM1);
|
|
|
|
// change the string in sv
|
|
sv.lightstyles[style] = val;
|
|
|
|
// send message to all clients on this server
|
|
if (sv.state != ss_active)
|
|
return;
|
|
|
|
for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
|
|
if (client->active || client->spawned)
|
|
{
|
|
MSG_WriteChar (&client->message, svc_lightstyle);
|
|
MSG_WriteChar (&client->message,style);
|
|
MSG_WriteString (&client->message, val);
|
|
}
|
|
}
|
|
|
|
void PF_rint (void)
|
|
{
|
|
float f;
|
|
f = G_FLOAT(OFS_PARM0);
|
|
if (f > 0)
|
|
G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
|
|
else
|
|
G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
|
|
}
|
|
void PF_floor (void)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
|
|
}
|
|
void PF_ceil (void)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
|
|
}
|
|
|
|
|
|
/*
|
|
=============
|
|
PF_checkbottom
|
|
=============
|
|
*/
|
|
void PF_checkbottom (void)
|
|
{
|
|
edict_t *ent;
|
|
|
|
ent = G_EDICT(OFS_PARM0);
|
|
|
|
G_FLOAT(OFS_RETURN) = SV_CheckBottom (ent);
|
|
}
|
|
|
|
/*
|
|
=============
|
|
PF_pointcontents
|
|
=============
|
|
*/
|
|
void PF_pointcontents (void)
|
|
{
|
|
float *v;
|
|
|
|
v = G_VECTOR(OFS_PARM0);
|
|
|
|
G_FLOAT(OFS_RETURN) = SV_PointContents (v);
|
|
}
|
|
|
|
|
|
/*
|
|
=============
|
|
PF_nextent
|
|
|
|
entity nextent(entity)
|
|
=============
|
|
*/
|
|
void PF_nextent (void)
|
|
{
|
|
int i;
|
|
edict_t *ent;
|
|
|
|
i = G_EDICTNUM(OFS_PARM0);
|
|
while (1)
|
|
{
|
|
i++;
|
|
if (i == sv.num_edicts)
|
|
{
|
|
RETURN_EDICT(sv.edicts);
|
|
return;
|
|
}
|
|
ent = EDICT_NUM(i);
|
|
if (!ent->free)
|
|
{
|
|
RETURN_EDICT(ent);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
=============
|
|
PF_aim
|
|
|
|
Pick a vector for the player to shoot along
|
|
vector aim(entity, missilespeed)
|
|
=============
|
|
*/
|
|
cvar_t sv_aim = {"sv_aim", "1000"};
|
|
void PF_aim (void)
|
|
{
|
|
edict_t *ent, *check, *bestent;
|
|
vec3_t start, dir, end, bestdir;
|
|
int i, j;
|
|
trace_t tr;
|
|
float dist, bestdist;
|
|
float speed;
|
|
|
|
ent = G_EDICT(OFS_PARM0);
|
|
speed = G_FLOAT(OFS_PARM1);
|
|
|
|
VectorCopy (ent->v.origin, start);
|
|
start[2] += 20;
|
|
|
|
// try sending a trace straight
|
|
VectorCopy (pr_global_struct->v_forward, dir);
|
|
VectorMA (start, 2048, dir, end);
|
|
tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
|
|
if (tr.ent && tr.ent->v.takedamage == DAMAGE_AIM
|
|
&& (!teamplay.value || ent->v.team <=0 || ent->v.team != tr.ent->v.team) )
|
|
{
|
|
VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
|
|
return;
|
|
}
|
|
|
|
|
|
// try all possible entities
|
|
VectorCopy (dir, bestdir);
|
|
bestdist = sv_aim.value;
|
|
bestent = NULL;
|
|
|
|
check = NEXT_EDICT(sv.edicts);
|
|
for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
|
|
{
|
|
if (check->v.takedamage != DAMAGE_AIM)
|
|
continue;
|
|
if (check == ent)
|
|
continue;
|
|
if (teamplay.value && ent->v.team > 0 && ent->v.team == check->v.team)
|
|
continue; // don't aim at teammate
|
|
for (j=0 ; j<3 ; j++)
|
|
end[j] = check->v.origin[j]
|
|
+ 0.5*(check->v.mins[j] + check->v.maxs[j]);
|
|
VectorSubtract (end, start, dir);
|
|
VectorNormalize (dir);
|
|
dist = DotProduct (dir, pr_global_struct->v_forward);
|
|
if (dist < bestdist)
|
|
continue; // to far to turn
|
|
tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
|
|
if (tr.ent == check)
|
|
{ // can shoot at this one
|
|
bestdist = dist;
|
|
bestent = check;
|
|
}
|
|
}
|
|
|
|
if (bestent)
|
|
{
|
|
VectorSubtract (bestent->v.origin, ent->v.origin, dir);
|
|
dist = DotProduct (dir, pr_global_struct->v_forward);
|
|
VectorScale (pr_global_struct->v_forward, dist, end);
|
|
end[2] = dir[2];
|
|
VectorNormalize (end);
|
|
VectorCopy (end, G_VECTOR(OFS_RETURN));
|
|
}
|
|
else
|
|
{
|
|
VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
|
|
}
|
|
}
|
|
|
|
/*
|
|
==============
|
|
PF_changeyaw
|
|
|
|
This was a major timewaster in progs, so it was converted to C
|
|
==============
|
|
*/
|
|
|
|
|
|
void PF_changeyaw (void)
|
|
{
|
|
edict_t *ent;
|
|
float ideal, current, move, speed;
|
|
|
|
ent = PROG_TO_EDICT(pr_global_struct->self);
|
|
current = anglemod( ent->v.angles[1] );
|
|
ideal = ent->v.ideal_yaw;
|
|
speed = ent->v.yaw_speed;
|
|
|
|
if (current == ideal)
|
|
return;
|
|
move = ideal - current;
|
|
if (ideal > current)
|
|
{
|
|
if (move >= 180)
|
|
move = move - 360;
|
|
}
|
|
else
|
|
{
|
|
if (move <= -180)
|
|
move = move + 360;
|
|
}
|
|
|
|
if (move > 0)
|
|
{
|
|
if (move > speed)
|
|
move = speed;
|
|
}
|
|
else
|
|
{
|
|
if (move < -speed)
|
|
move = -speed;
|
|
}
|
|
|
|
ent->v.angles[1] = anglemod (current + move);
|
|
}
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
MESSAGE WRITING
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
#define MSG_BROADCAST 0 // unreliable to all
|
|
#define MSG_ONE 1 // reliable to one (msg_entity)
|
|
#define MSG_ALL 2 // reliable to all
|
|
#define MSG_INIT 3 // write to the init string
|
|
|
|
sizebuf_t *WriteDest (void)
|
|
{
|
|
int entnum;
|
|
int dest;
|
|
edict_t *ent;
|
|
|
|
dest = G_FLOAT(OFS_PARM0);
|
|
switch (dest)
|
|
{
|
|
case MSG_BROADCAST:
|
|
return &sv.datagram;
|
|
|
|
case MSG_ONE:
|
|
ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
|
|
entnum = NUM_FOR_EDICT(ent);
|
|
if (entnum < 1 || entnum > svs.maxclients)
|
|
PR_RunError ("WriteDest: not a client");
|
|
return &svs.clients[entnum-1].message;
|
|
|
|
case MSG_ALL:
|
|
return &sv.reliable_datagram;
|
|
|
|
case MSG_INIT:
|
|
return &sv.signon;
|
|
|
|
default:
|
|
PR_RunError ("WriteDest: bad destination");
|
|
break;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void PF_WriteByte (void)
|
|
{
|
|
MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
|
|
}
|
|
|
|
void PF_WriteChar (void)
|
|
{
|
|
MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
|
|
}
|
|
|
|
void PF_WriteShort (void)
|
|
{
|
|
MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
|
|
}
|
|
|
|
void PF_WriteLong (void)
|
|
{
|
|
MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
|
|
}
|
|
|
|
void PF_WriteAngle (void)
|
|
{
|
|
MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1));
|
|
}
|
|
|
|
void PF_WriteCoord (void)
|
|
{
|
|
MSG_WriteCoord (WriteDest(), G_FLOAT(OFS_PARM1));
|
|
}
|
|
|
|
void PF_WriteString (void)
|
|
{
|
|
MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
|
|
}
|
|
|
|
|
|
void PF_WriteEntity (void)
|
|
{
|
|
MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
|
|
}
|
|
|
|
//=============================================================================
|
|
|
|
int SV_ModelIndex (char *name);
|
|
|
|
void PF_makestatic (void)
|
|
{
|
|
edict_t *ent;
|
|
int i;
|
|
|
|
|
|
ent = G_EDICT(OFS_PARM0);
|
|
|
|
MSG_WriteByte (&sv.signon,svc_spawnstatic);
|
|
|
|
//MSG_WriteModel (&sv.signon, SV_ModelIndex(pr_strings + ent->v.model));
|
|
MSG_WriteByte (&sv.signon, SV_ModelIndex(pr_strings + ent->v.model));
|
|
|
|
//MSG_WriteFrame (&sv.signon, ent->v.frame);
|
|
MSG_WriteByte (&sv.signon, ent->v.frame);
|
|
MSG_WriteByte (&sv.signon, ent->v.colormap);
|
|
// MSG_WriteSkin (&sv.signon, ent->v.skin);
|
|
MSG_WriteByte (&sv.signon, ent->v.skin);
|
|
for (i=0 ; i<3 ; i++)
|
|
{
|
|
MSG_WriteCoord(&sv.signon, ent->v.origin[i]);
|
|
MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
|
|
}
|
|
|
|
// throw the entity away now
|
|
ED_Free (ent);
|
|
}
|
|
|
|
//=============================================================================
|
|
|
|
/*
|
|
==============
|
|
PF_setspawnparms
|
|
==============
|
|
*/
|
|
void PF_setspawnparms (void)
|
|
{
|
|
edict_t *ent;
|
|
int i;
|
|
client_t *client;
|
|
|
|
ent = G_EDICT(OFS_PARM0);
|
|
i = NUM_FOR_EDICT(ent);
|
|
if (i < 1 || i > svs.maxclients)
|
|
PR_RunError ("Entity is not a client");
|
|
|
|
// copy spawn parms out of the client_t
|
|
client = svs.clients + (i-1);
|
|
|
|
for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
|
|
(&pr_global_struct->parm1)[i] = client->spawn_parms[i];
|
|
}
|
|
|
|
/*
|
|
==============
|
|
PF_changelevel
|
|
==============
|
|
*/
|
|
void PF_changelevel (void)
|
|
{
|
|
char *s;
|
|
|
|
// make sure we don't issue two changelevels
|
|
if (svs.changelevel_issued)
|
|
return;
|
|
svs.changelevel_issued = true;
|
|
|
|
s = G_STRING(OFS_PARM0);
|
|
Cbuf_AddText (va("changelevel %s\n",s));
|
|
}
|
|
|
|
void PF_Fixme (void)
|
|
{
|
|
//PR_RunError ("unimplemented bulitin");
|
|
PR_RunError ("unimplemented builtin");//Tei typo fix.
|
|
}
|
|
|
|
// Tomaz - QuakeC String Manipulation Begin
|
|
void PF_zone (void)
|
|
{
|
|
char *m, *p;
|
|
m = G_STRING(OFS_PARM0);
|
|
p = Z_Malloc(Q_strlen(m) + 1);
|
|
Q_strcpy(p, m);
|
|
|
|
G_INT(OFS_RETURN) = p - pr_strings;
|
|
}
|
|
|
|
|
|
void PF_unzone (void)
|
|
{
|
|
|
|
Z_Free(G_STRING(OFS_PARM0));
|
|
G_INT(OFS_PARM0) = OFS_NULL; // empty the def
|
|
};
|
|
|
|
void PF_strlen (void)
|
|
{
|
|
|
|
char *p = G_STRING(OFS_PARM0);
|
|
G_FLOAT(OFS_RETURN) = strlen(p);
|
|
}
|
|
|
|
char pr_strcat_buf [128]; // need this becuase pr_string_temp sucks
|
|
|
|
void PF_strcat (void)
|
|
{
|
|
char *s1, *s2;
|
|
|
|
memset(pr_strcat_buf, 0, 127);
|
|
s1 = G_STRING(OFS_PARM0);
|
|
s2 = PF_VarString(1);
|
|
strcpy(pr_strcat_buf, s1);
|
|
strcat(pr_strcat_buf, s2);
|
|
G_INT(OFS_RETURN) = pr_strcat_buf - pr_strings;
|
|
}
|
|
|
|
void PF_substring (void)
|
|
{
|
|
|
|
int ltwo, start;
|
|
char *p, *d;
|
|
d = pr_string_temp;
|
|
|
|
p = G_STRING(OFS_PARM0);
|
|
start = (int)G_FLOAT(OFS_PARM1); // for some reason, Quake doesn't like G_INT
|
|
ltwo = (int)G_FLOAT(OFS_PARM2);
|
|
if ((unsigned)start > strlen(p))
|
|
start = strlen(p) - 1;
|
|
|
|
// cap values
|
|
if (start < 0)
|
|
start = 0;
|
|
if (ltwo < 0)
|
|
ltwo = 0;
|
|
|
|
p += start;
|
|
Q_strncpy(d, p, ltwo);
|
|
G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
|
|
|
|
}
|
|
|
|
// thanks zoid
|
|
void PF_stof (void)
|
|
{
|
|
char *s;
|
|
|
|
s = G_STRING(OFS_PARM0);
|
|
G_FLOAT(OFS_RETURN) = atof(s);
|
|
}
|
|
|
|
void PF_stov (void)
|
|
{
|
|
char *v;
|
|
int i;
|
|
vec3_t d;
|
|
|
|
v = G_STRING(OFS_PARM0);
|
|
|
|
for (i=0; i<3; i++)
|
|
{
|
|
while(v && (v[0] == ' ' || v[0] == '\'')) //skip unneeded data
|
|
v++;
|
|
d[i] = atof(v);
|
|
while (v && v[0] != ' ') // skip to next space
|
|
v++;
|
|
}
|
|
VectorCopy (d, G_VECTOR(OFS_RETURN));
|
|
}
|
|
// Tomaz - QuakeC String Manipulation End
|
|
|
|
// Tomaz - QuakeC File System Begin
|
|
void PF_open (void)
|
|
{
|
|
char *p = G_STRING(OFS_PARM0);
|
|
char *ftemp;
|
|
int fmode = G_FLOAT(OFS_PARM1);
|
|
int h = 0, fsize = 0;
|
|
|
|
switch (fmode)
|
|
{
|
|
case 0: // read
|
|
Sys_FileOpenRead (va("%s/%s",com_gamedir, p), &h);
|
|
G_FLOAT(OFS_RETURN) = (float) h;
|
|
return;
|
|
case 1: // append -- this is nasty
|
|
// copy whole file into the zone
|
|
fsize = Sys_FileOpenRead(va("%s/%s",com_gamedir, p), &h);
|
|
if (h == -1)
|
|
{
|
|
h = Sys_FileOpenWrite(va("%s/%s",com_gamedir, p));
|
|
G_FLOAT(OFS_RETURN) = (float) h;
|
|
return;
|
|
}
|
|
ftemp = Z_Malloc(fsize + 1);
|
|
Sys_FileRead(h, ftemp, fsize);
|
|
Sys_FileClose(h);
|
|
// spit it back out
|
|
h = Sys_FileOpenWrite(va("%s/%s",com_gamedir, p));
|
|
Sys_FileWrite(h, ftemp, fsize);
|
|
Z_Free(ftemp); // free it from memory
|
|
G_FLOAT(OFS_RETURN) = (float) h; // return still open handle
|
|
return;
|
|
default: // write
|
|
h = Sys_FileOpenWrite (va("%s/%s", com_gamedir, p));
|
|
G_FLOAT(OFS_RETURN) = (float) h;
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
void PF_close (void)
|
|
{
|
|
int h = (int)G_FLOAT(OFS_PARM0);
|
|
Sys_FileClose(h);
|
|
}
|
|
|
|
void PF_read (void)
|
|
{
|
|
// reads one line (to a \n) into a string
|
|
int h = (int)G_FLOAT(OFS_PARM0);
|
|
int test;
|
|
char *p;
|
|
|
|
memset(pr_string_temp, 0, 127);
|
|
p = pr_string_temp;
|
|
Sys_FileRead(h, p, 1);
|
|
while (p && p[0] != '\n')
|
|
{
|
|
*p++;
|
|
test = Sys_FileRead(h, p, 1);
|
|
if (p[0] == 13) // carriage return
|
|
Sys_FileRead(h, p, 1); // skip
|
|
if (!test)
|
|
break;
|
|
};
|
|
p[0] = 0;
|
|
if (strlen(pr_string_temp) == 0)
|
|
G_INT(OFS_RETURN) = OFS_NULL;
|
|
else
|
|
G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
|
|
}
|
|
|
|
void PF_write (void)
|
|
{
|
|
// writes to file, like bprint
|
|
float handle = G_FLOAT(OFS_PARM0);
|
|
char *str = PF_VarString(1);
|
|
float len;
|
|
len = strlen(str);
|
|
if (!len)
|
|
Sys_FileWrite (handle, "", 0);
|
|
else
|
|
Sys_FileWrite (handle, str, len);
|
|
}
|
|
// Tomaz - QuakeC File System End
|
|
|
|
// Tei random vector PF
|
|
/*
|
|
=================
|
|
PF_rvector
|
|
|
|
Returns a vector from 0<= num < 1
|
|
|
|
rvector()
|
|
=================
|
|
*/
|
|
void PF_rvector (void)
|
|
{
|
|
G_FLOAT(OFS_RETURN+0) = ((rand ()&0x7fff) / ((float)0x7fff))*2 - 1;;
|
|
G_FLOAT(OFS_RETURN+1) = ((rand ()&0x7fff) / ((float)0x7fff))*2 - 1;;
|
|
G_FLOAT(OFS_RETURN+2) = ((rand ()&0x7fff) / ((float)0x7fff))*2 - 1;;
|
|
|
|
}
|
|
// Tei random vector PF
|
|
|
|
|
|
// Tei stat counter PF
|
|
/*
|
|
=================
|
|
PF_statcount
|
|
|
|
Returns stats of entities
|
|
|
|
statcount()
|
|
=================
|
|
*/
|
|
void PF_statcount (void)
|
|
{
|
|
int i;
|
|
edict_t *ent;
|
|
int active, models, solid, step;
|
|
int option = (int)G_FLOAT(OFS_PARM0);
|
|
|
|
|
|
active = models = solid = step = 0;
|
|
for (i=0 ; i<sv.num_edicts ; i++)
|
|
{
|
|
ent = EDICT_NUM(i);
|
|
if (ent->free)
|
|
continue;
|
|
active++;
|
|
if (ent->v.solid)
|
|
solid++;
|
|
if (ent->v.model)
|
|
models++;
|
|
if (ent->v.movetype == MOVETYPE_STEP)
|
|
step++;
|
|
}
|
|
|
|
switch (option)
|
|
{
|
|
case 0:
|
|
G_FLOAT(OFS_RETURN+0) = sv.num_edicts;
|
|
return;
|
|
case 1:
|
|
G_FLOAT(OFS_RETURN+0) = active;
|
|
return;
|
|
case 2:
|
|
G_FLOAT(OFS_RETURN+0) = models;
|
|
return;
|
|
case 3:
|
|
G_FLOAT(OFS_RETURN+0) = solid;
|
|
return;
|
|
default:
|
|
G_FLOAT(OFS_RETURN+0) = step;
|
|
return;
|
|
}
|
|
}
|
|
// Tei stat counter PF
|
|
|
|
|
|
|
|
// Tei keytest manipulation
|
|
/*
|
|
=================
|
|
PF_keytest
|
|
|
|
Returns existence of string in "begin" string
|
|
|
|
statcount()
|
|
=================
|
|
*/
|
|
|
|
void PF_keytest (void)
|
|
{
|
|
char *str;
|
|
char *key;
|
|
int equ, lenkey, offset,i;
|
|
|
|
str = G_STRING(OFS_PARM0);
|
|
key = G_STRING(OFS_PARM1);
|
|
lenkey = strlen(key);
|
|
offset = 0;
|
|
|
|
|
|
while(str[offset] && (str[offset] == ' ' || str[offset] == '\t')) //skip unneeded data
|
|
offset++;
|
|
|
|
equ = 1;
|
|
for ( i=0; i<lenkey; i++)
|
|
if (str[offset+i] != key[i] ) equ = 0;
|
|
|
|
|
|
|
|
G_FLOAT(OFS_RETURN) = equ;
|
|
}
|
|
// Tei keytest manipulation
|
|
|
|
// Tei PF_sscanf
|
|
/*
|
|
=================
|
|
PF_sscanf
|
|
|
|
Scan string
|
|
|
|
vector sscanf(string src, string format)
|
|
=================
|
|
*/
|
|
void PF_sscanf (void)
|
|
{
|
|
float e1 = 0;
|
|
float e2 = 0;
|
|
float e3 = 0;
|
|
|
|
char * src = G_STRING(OFS_PARM0);
|
|
char * format = G_STRING(OFS_PARM1);
|
|
|
|
sscanf(src,format,&e1,&e2,&e3);
|
|
|
|
G_INT(OFS_RETURN + 0) = (float)e1;
|
|
G_INT(OFS_RETURN + 1) = (float)e2;
|
|
G_INT(OFS_RETURN + 2) = (float)e3;
|
|
}
|
|
// Tei PF_sscanf
|
|
|
|
// Tei hvstring, ThunderCats use that
|
|
void PF_hvstring (void)
|
|
{
|
|
|
|
int l,i;
|
|
char *p, *d;
|
|
|
|
|
|
d = pr_string_temp;
|
|
memset(d, 0, 127);
|
|
|
|
p = G_STRING(OFS_PARM0);
|
|
|
|
l = strlen(p);
|
|
for (i=0;i<l;i++){
|
|
d[i*2+0]=p[i];
|
|
d[i*2+1]='\n';
|
|
d[i*2+2]=0;
|
|
}
|
|
|
|
G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
|
|
}
|
|
// Tei hv string
|
|
|
|
|
|
ddef_t *ED_FindGlobal (char *name);
|
|
qboolean ED_ParseEpair (void *base, ddef_t *key, char *s);
|
|
|
|
// Tei setarray
|
|
void PF_SetArray (void)
|
|
{
|
|
//char *s1, *s2;
|
|
ddef_t *key;
|
|
int val, len;
|
|
float ret;
|
|
char *p, *d, *valstring;
|
|
//char tmp[200];
|
|
|
|
|
|
d = pr_string_temp;
|
|
memset(d, 0, 127);
|
|
|
|
p = G_STRING(OFS_PARM0);
|
|
val = floor(G_FLOAT(OFS_PARM1));
|
|
valstring = G_STRING(OFS_PARM2);
|
|
|
|
len = strlen(p);
|
|
Q_strncpy(pr_string_temp, p, len);
|
|
|
|
d[len+0 ] = (val/ 10)%10 + '0';
|
|
d[len+1] = (val )%10 + '0';
|
|
d[len+2] = 0;
|
|
|
|
//ED_FindGlobal (new)
|
|
key = ED_FindGlobal (d);
|
|
if (key!=NULL)
|
|
ret = ED_ParseEpair ((void *)pr_globals, key, valstring);
|
|
|
|
G_FLOAT(OFS_RETURN) = (key!=NULL);
|
|
}
|
|
// Tei array
|
|
|
|
|
|
// Tei getarray
|
|
void PF_GetArray (void)
|
|
{
|
|
//To do
|
|
}
|
|
// Tei getarray
|
|
|
|
|
|
|
|
// Tei fx
|
|
/*
|
|
=================
|
|
PF_setfx
|
|
|
|
Set render fx flags.
|
|
|
|
setfx(entity,flags)
|
|
=================
|
|
*/
|
|
/*
|
|
void PF_setfx (void)
|
|
{
|
|
edict_t *ent;
|
|
int i;
|
|
|
|
ent = G_EDICT(OFS_PARM0);
|
|
i = G_INT (OFS_PARM1);
|
|
|
|
ent->v.fx = i;
|
|
}
|
|
// Tei fx
|
|
*/
|
|
/*
|
|
float(entity targ, entity inflictor) CanDamage =
|
|
{
|
|
// bmodels need special checking because their origin is 0,0,0
|
|
if (targ.movetype == MOVETYPE_PUSH)
|
|
{
|
|
traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
|
|
if (trace_fraction == 1)
|
|
return TRUE;
|
|
if (trace_ent == targ)
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
traceline(inflictor.origin, targ.origin, TRUE, self);
|
|
if (trace_fraction == 1)
|
|
return TRUE;
|
|
traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
|
|
if (trace_fraction == 1)
|
|
return TRUE;
|
|
traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
|
|
if (trace_fraction == 1)
|
|
return TRUE;
|
|
traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
|
|
if (trace_fraction == 1)
|
|
return TRUE;
|
|
traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
|
|
if (trace_fraction == 1)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
};
|
|
*/
|
|
|
|
int PF_CanDamage ( edict_t * targ, edict_t * inflictor )
|
|
{
|
|
trace_t trace;
|
|
vec3_t v1,v2;
|
|
edict_t * self = PROG_TO_EDICT(pr_global_struct->self);
|
|
|
|
VectorCopy( targ->v.origin , v1 );
|
|
VectorCopy( inflictor->v.origin , v2 );
|
|
|
|
|
|
if (targ->v.movetype == MOVETYPE_PUSH )
|
|
{
|
|
//visible (,);??
|
|
trace = SV_Move (v1, vec3_origin, vec3_origin, v2 , 1 , self);
|
|
if (trace.fraction == 1 )
|
|
return true;
|
|
if (trace.ent == targ )
|
|
return true;
|
|
}
|
|
|
|
trace = SV_Move ( v1, targ->v.mins, targ->v.maxs, v2, 1, self );
|
|
|
|
if (trace.fraction == 1)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
|
|
{
|
|
local float points;
|
|
local entity head;
|
|
local vector org;
|
|
|
|
head = findradius(inflictor.origin, damage+40);
|
|
|
|
while (head)
|
|
{
|
|
if (head != ignore)
|
|
{
|
|
if (head.takedamage)
|
|
{
|
|
org = head.origin + (head.mins + head.maxs)*0.5;
|
|
points = 0.5*vlen (inflictor.origin - org);
|
|
if (points < 0)
|
|
points = 0;
|
|
points = damage - points;
|
|
if (head == attacker)
|
|
points = points * 0.5;
|
|
if (points > 0)
|
|
{
|
|
if (CanDamage (head, inflictor))
|
|
{ // shambler takes half damage from all explosions
|
|
if (head.classname == "monster_shambler")
|
|
T_Damage (head, inflictor, attacker, points*0.5);
|
|
else
|
|
T_Damage (head, inflictor, attacker, points);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
head = head.chain;
|
|
}
|
|
};
|
|
*/
|
|
|
|
|
|
//dont work, crap
|
|
void PR_T_RadiusDamage (void)
|
|
{
|
|
// For TRD
|
|
|
|
edict_t * inflictor = G_EDICT(OFS_PARM0);
|
|
edict_t * attacker = G_EDICT(OFS_PARM1);
|
|
int damage = G_FLOAT(OFS_PARM2);
|
|
edict_t * ignore = G_EDICT(OFS_PARM3);
|
|
float T_Damage = G_FLOAT(OFS_PARM4);
|
|
|
|
int dist;
|
|
int points;
|
|
|
|
// For RD
|
|
|
|
edict_t *ent, *chain;
|
|
float rad;
|
|
vec3_t org;
|
|
vec3_t eorg;
|
|
int i, j;
|
|
|
|
chain = (edict_t *)sv.edicts;
|
|
|
|
VectorCopy (inflictor->v.origin, org);
|
|
rad = damage + 40;
|
|
|
|
ent = NEXT_EDICT(sv.edicts);
|
|
for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
|
|
{
|
|
if (ent->free)
|
|
continue;
|
|
if (ent->v.solid == SOLID_NOT)
|
|
continue;
|
|
for (j=0 ; j<3 ; j++)
|
|
eorg[j] = org[j] - (ent->v.origin[j] + (ent->v.mins[j] + ent->v.maxs[j])*0.5);
|
|
dist = Length(eorg);
|
|
if ( dist > rad)
|
|
continue;
|
|
|
|
points = damage - (0.5 * dist);
|
|
|
|
if ( ent == attacker )
|
|
points *= 0.5;
|
|
|
|
if (points > 0) {
|
|
if ( PF_CanDamage( ent, inflictor ) ) {
|
|
if (!strcmp( (char *)(pr_strings + ent->v.classname), "monster_shambler" ) )
|
|
points *= 0.5;
|
|
// head inflictor attacker points
|
|
//G_EDICT(OFS_PARM0) = ent;
|
|
//G_EDICT(OFS_PARM1) = inflictor;
|
|
//G_EDICT(OFS_PARM2) = attacker;
|
|
//G_FLOAT(OFS_PARM3) = points;
|
|
Con_Printf("T_Damage %f\n", T_Damage);
|
|
|
|
pr_globals[OFS_PARM0] = EDICT_TO_PROG(ent);
|
|
pr_globals[OFS_PARM1] = EDICT_TO_PROG(inflictor);
|
|
pr_globals[OFS_PARM2] = EDICT_TO_PROG(attacker);
|
|
pr_globals[OFS_PARM3] = points;
|
|
|
|
PR_ExecuteProgram (T_Damage);
|
|
}
|
|
}
|
|
ent->v.chain = EDICT_TO_PROG(chain);
|
|
chain = ent;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* crap function that read a string, then put values in
|
|
* pr_tempreg1 arrays.
|
|
*
|
|
*/
|
|
|
|
|
|
//Tei ini support
|
|
|
|
void PF_ReadRegister (void)
|
|
{
|
|
|
|
FILE* f;
|
|
char *errormsg = "error";
|
|
|
|
|
|
qboolean sectionok = false;
|
|
|
|
char *p = G_STRING (OFS_PARM0);
|
|
char *section = G_STRING (OFS_PARM1);
|
|
char *key = G_STRING (OFS_PARM2);
|
|
|
|
|
|
COM_FOpenFile(p, &f);
|
|
|
|
if (!f || feof(f))
|
|
{
|
|
G_INT(OFS_RETURN) = errormsg - pr_strings;
|
|
return;
|
|
}
|
|
|
|
do
|
|
{
|
|
fscanf(f,"%s",pr_string_temp);
|
|
//Con_Printf("%s det %s busca\n",pr_string_temp, key);
|
|
|
|
if ( !_stricmp(pr_string_temp,section) && !feof(f))
|
|
{
|
|
sectionok = true;
|
|
}
|
|
else
|
|
if ( !_stricmp(pr_string_temp,key) && !feof(f) && sectionok)
|
|
{
|
|
fscanf(f,"%s",pr_string_temp);
|
|
//Con_Printf("%s final\n",pr_string_temp);
|
|
break;
|
|
}
|
|
|
|
//Mark for end of section
|
|
if ( !_stricmp(pr_string_temp,"[EndSection]") )
|
|
{
|
|
if( sectionok )
|
|
{
|
|
G_INT(OFS_RETURN) = errormsg - pr_strings;
|
|
return;
|
|
}
|
|
}
|
|
//else
|
|
// Con_Printf("%s != %s, %d,%d \n",pr_string_temp, key, strlen(pr_string_temp), strlen(key));
|
|
|
|
}
|
|
while( !feof(f) );
|
|
|
|
//Con_Printf("Endhere..\n");
|
|
G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
|
|
|
|
fclose(f);//????????????????
|
|
}
|
|
//Tei ini support
|
|
|
|
#if 0
|
|
|
|
void PF_LoadLexer (void) {};
|
|
|
|
#else
|
|
|
|
//TELEJANO
|
|
#define MAX_LEXER 16536*32
|
|
|
|
char lexer[MAX_LEXER];
|
|
long sizeoflexer;
|
|
|
|
void PF_LoadLexer (void)
|
|
{
|
|
FILE* f;
|
|
char *p = G_STRING (OFS_PARM0);
|
|
|
|
COM_FOpenFile(p, &f);
|
|
|
|
if (!f || feof(f))
|
|
{
|
|
G_INT(OFS_RETURN) = 0.0f; //Error!
|
|
return;
|
|
}
|
|
|
|
sizeoflexer = fread( (void*) lexer,1,MAX_LEXER, f);
|
|
|
|
if (lexer)
|
|
Con_Printf("%d : %s\n",sizeoflexer, lexer);
|
|
|
|
fclose(f);
|
|
};
|
|
|
|
|
|
#endif
|
|
|
|
void PF_IndexFromLexer (void)
|
|
{
|
|
int offset;
|
|
int i = 0;
|
|
qboolean nofind = true;
|
|
char *findtxt = G_STRING (OFS_PARM0);
|
|
int lenfind = strlen( findtxt );
|
|
|
|
G_INT(OFS_RETURN) = 0;//No found
|
|
|
|
Con_Printf("%s, %d \n", findtxt, lenfind);
|
|
|
|
offset = &lexer[0] - pr_strings;
|
|
|
|
while(i < MAX_LEXER ) {
|
|
|
|
if (!Q_strncmp( findtxt, lexer+i, lenfind ) ){
|
|
Con_Printf("Lo he encontrado?.. %d - %d\n", i, offset);
|
|
G_INT(OFS_RETURN) = offset + i ;//Found!
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
};
|
|
|
|
//Tei gLine
|
|
void R_BeamColor (vec3_t origin, vec3_t end,vec3_t color); //Red raw line
|
|
void PR_gLine(void)
|
|
{
|
|
float *org = G_VECTOR(OFS_PARM0);
|
|
float *end = G_VECTOR(OFS_PARM1);
|
|
float *color = G_VECTOR(OFS_PARM2);
|
|
|
|
if ((!coop.value && !deathmatch.value) || singleplayer)
|
|
{
|
|
R_BeamColor(org,end,color);
|
|
}
|
|
};
|
|
//Tei gLine
|
|
|
|
void GetMenuSelect( int i, cvar_t ** menu, cvar_t **xmenu);
|
|
|
|
void PR_LocalMenu(void)
|
|
{
|
|
int i;
|
|
cvar_t * menu, *xmenu;
|
|
char *label = G_STRING(OFS_PARM0);
|
|
char *comand = G_STRING(OFS_PARM1);
|
|
float color = G_FLOAT(OFS_PARM2);
|
|
|
|
|
|
GetMenuSelect( i = color, &menu,&xmenu) ;
|
|
|
|
Cvar_Set( menu->name,(char *)label);
|
|
Cvar_Set( xmenu->name,(char *)comand);
|
|
};
|
|
|
|
|
|
//Tei particleevent
|
|
void PR_RunParticleEvent(void)
|
|
{
|
|
float *org = G_VECTOR(OFS_PARM0);
|
|
float *end = G_VECTOR(OFS_PARM1);
|
|
float type = G_FLOAT(OFS_PARM3);
|
|
float tlife = G_FLOAT(OFS_PARM4);
|
|
float dead = G_FLOAT(OFS_PARM5);
|
|
float scale = G_FLOAT(OFS_PARM6);
|
|
float key = G_FLOAT(OFS_PARM7);
|
|
|
|
if (sv.datagram.cursize > MAX_DATAGRAM-16)
|
|
return;
|
|
|
|
MSG_WriteByte (&sv.datagram, svc_temp_entity );
|
|
MSG_WriteByte (&sv.datagram, 49);
|
|
MSG_WriteByte (&sv.datagram, 1); //Static protocol v1.0
|
|
|
|
MSG_WriteCoord (&sv.datagram, org[0]);
|
|
MSG_WriteCoord (&sv.datagram, org[1]);
|
|
MSG_WriteCoord (&sv.datagram, org[2]);
|
|
|
|
MSG_WriteCoord (&sv.datagram, end[0]);
|
|
MSG_WriteCoord (&sv.datagram, end[1]);
|
|
MSG_WriteCoord (&sv.datagram, end[2]);
|
|
|
|
MSG_WriteByte (&sv.datagram, type);
|
|
MSG_WriteByte (&sv.datagram, tlife);
|
|
MSG_WriteByte (&sv.datagram, dead);
|
|
MSG_WriteByte (&sv.datagram, scale);
|
|
MSG_WriteByte (&sv.datagram, key);
|
|
};
|
|
//Tei particle event
|
|
|
|
void MSG_WriteCoord3 (vec3_t org)
|
|
{
|
|
MSG_WriteCoord (&sv.datagram, org[0]);
|
|
MSG_WriteCoord (&sv.datagram, org[1]);
|
|
MSG_WriteCoord (&sv.datagram, org[2]);
|
|
}
|
|
|
|
void PR_TempEntity( void)
|
|
{
|
|
|
|
float type = G_FLOAT(OFS_PARM0);
|
|
float *org = G_VECTOR(OFS_PARM1);
|
|
float *end;// = G_VECTOR(OFS_PARM2);
|
|
float *vec;// = G_VECTOR(OFS_PARM2);
|
|
float param1;// = G_VECTOR(OFS_PARM2);
|
|
float param2;// = G_VECTOR(OFS_PARM2);
|
|
char * string;
|
|
|
|
if (sv.datagram.cursize > MAX_DATAGRAM-16)
|
|
return;
|
|
|
|
MSG_WriteByte (&sv.datagram, svc_temp_entity );
|
|
MSG_WriteByte (&sv.datagram, type);
|
|
|
|
MSG_WriteCoord3(org);
|
|
|
|
switch( (int)type )
|
|
{
|
|
case TE_RAIN:
|
|
case TE_SNOW:
|
|
vec = G_VECTOR(OFS_PARM2);
|
|
param1 = G_FLOAT(OFS_PARM3);
|
|
MSG_WriteCoord3 (vec);
|
|
MSG_WriteShort (&sv.datagram, param1);
|
|
break;
|
|
|
|
case TE_LIGHTNING2 :
|
|
case TE_LIGHTNING3 :
|
|
case TE_LIGHTNING4:
|
|
case TE_LIGHTNING1 :
|
|
case TE_BEAM:
|
|
vec = G_VECTOR(OFS_PARM2);
|
|
MSG_WriteCoord3 (vec);
|
|
break;
|
|
case TE_LIGHTNINGX :
|
|
vec = G_VECTOR(OFS_PARM2);
|
|
param1 = G_FLOAT(OFS_PARM3);
|
|
string = G_STRING(OFS_PARM4);
|
|
MSG_WriteCoord3 (vec);//end
|
|
MSG_WriteByte (&sv.datagram, param1);//style
|
|
MSG_WriteString(&sv.datagram, string);//name
|
|
break;
|
|
case TE_EXPLOSION2:
|
|
/*
|
|
colorStart = MSG_ReadByte ();
|
|
colorLength = MSG_ReadByte ();*/
|
|
param1 = G_FLOAT(OFS_PARM2);
|
|
param2 = G_FLOAT(OFS_PARM3);
|
|
MSG_WriteByte (&sv.datagram, param1);
|
|
MSG_WriteByte (&sv.datagram, param2);
|
|
break;
|
|
case TE_TRAILS:
|
|
case TE_RAILTRAIL:
|
|
/*...
|
|
pos2[0] = MSG_ReadCoord();
|
|
pos2[1] = MSG_ReadCoord();
|
|
pos2[2] = MSG_ReadCoord();
|
|
angle[0] = MSG_ReadCoord();
|
|
angle[1] = MSG_ReadCoord();
|
|
angle[2] = MSG_ReadCoord();*/
|
|
|
|
end = G_VECTOR(OFS_PARM2);
|
|
vec = G_VECTOR(OFS_PARM3);
|
|
MSG_WriteCoord3(end);
|
|
MSG_WriteCoord3(vec);
|
|
break;
|
|
case TE_PARTICLEBLAST:
|
|
/*
|
|
pos2[0] = MSG_ReadCoord();
|
|
pos2[1] = MSG_ReadCoord();
|
|
pos2[2] = MSG_ReadCoord();
|
|
|
|
angle[0] = MSG_ReadCoord();
|
|
angle[1] = MSG_ReadCoord();
|
|
angle[2] = MSG_ReadCoord();
|
|
|
|
num = MSG_ReadByte ();
|
|
|
|
scale = MSG_ReadByte ();*/
|
|
end = G_VECTOR(OFS_PARM2);
|
|
vec = G_VECTOR(OFS_PARM3);
|
|
param1 = G_FLOAT(OFS_PARM4);
|
|
param2 = G_FLOAT(OFS_PARM5);
|
|
|
|
MSG_WriteCoord3(end);
|
|
MSG_WriteCoord3(vec);
|
|
MSG_WriteByte (&sv.datagram, param1);
|
|
MSG_WriteByte (&sv.datagram, param2);
|
|
break;
|
|
case TE_IMPLOSIONFX:
|
|
case TE_STATICFOG:
|
|
case TE_ALIENEXPLOSION:
|
|
case TE_EXPLOSIONSMALL3:
|
|
case TE_EXPLOSIONSMALL2:
|
|
case TE_EXPLOSIONSMALL:
|
|
case TE_TELEPORT:
|
|
case TE_LAVASPLASH:
|
|
case TE_TAREXPLOSION:
|
|
case TE_EXPLOSION:
|
|
case TE_GUNSHOT:
|
|
case TE_SUPERSPIKE:
|
|
case TE_PLASMA:
|
|
case TE_SPIKE:
|
|
case TE_KNIGHTSPIKE:
|
|
case TE_WIZSPIKE:
|
|
//Implemented.
|
|
break;
|
|
|
|
default:
|
|
//Do nothing
|
|
Con_Printf("Unimplemented Builtin handling\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void PR_Cvar_Set (void)
|
|
{
|
|
char * m = G_STRING(OFS_PARM0);
|
|
char * m2 = G_STRING(OFS_PARM1);
|
|
Cvar_Set(m,m2);
|
|
};
|
|
|
|
void PR_Cvar_Setf (void)
|
|
{
|
|
char * m = G_STRING(OFS_PARM0);
|
|
float f = G_FLOAT(OFS_PARM1);
|
|
Cvar_Set(m,va("%f",f));
|
|
};
|
|
|
|
|
|
void PR_Exec (void)
|
|
{
|
|
char * m = G_STRING(OFS_PARM0);
|
|
|
|
Cbuf_Execute();
|
|
Cbuf_AddText(m);
|
|
Cbuf_Execute();
|
|
};
|
|
|
|
void PR_LocalSound(void)
|
|
{
|
|
static int hash=345;
|
|
int i;
|
|
sfx_t *sfx;
|
|
|
|
char * s = G_STRING(OFS_PARM0);
|
|
float chan = G_FLOAT(OFS_PARM1);
|
|
float vol = G_FLOAT(OFS_PARM2);
|
|
|
|
sfx = S_PrecacheSound(s);
|
|
S_StartSound(cl.viewentity, chan, sfx, listener_origin, vol, 0.0);
|
|
|
|
};
|
|
|
|
void PR_Con_Print(void)
|
|
{
|
|
Con_Printf("%s",G_STRING(OFS_PARM0));
|
|
};
|
|
|
|
|
|
extern progs_t *active_pr;
|
|
|
|
void PR_GameString(void)
|
|
{
|
|
char * s;
|
|
|
|
|
|
// GameString("doc");
|
|
|
|
char * pr_strings_actual = &active_pr->progs + active_pr->progs->ofs_strings;
|
|
char * pr_strings_game = &cl_progs.progs + cl_progs.progs->ofs_strings;
|
|
char * pr_strings_server = &sv_progs.progs + sv_progs.progs->ofs_strings;
|
|
|
|
if (active_pr == &sv_progs)
|
|
{
|
|
Con_Printf("Invocation error\n");
|
|
G_INT(OFS_RETURN) = pr_string_temp - pr_strings_server;
|
|
return;
|
|
}
|
|
|
|
|
|
G_INT(OFS_RETURN) = ((int)pr_globals[OFS_PARM0] + (pr_strings_actual - pr_strings_server) + &sv_progs) - pr_strings_server;
|
|
};
|
|
|
|
//Xsniper - PF Functions Moved From Eternal War
|
|
|
|
//begin new image precaching / loading code -Xsniper
|
|
|
|
//QC Draw System
|
|
//new global variables
|
|
int qc_current; //current item in array
|
|
float qc_num_img; // if this gets close to MAX_QC_IMAGES then deny new ones
|
|
float qc_x[MAX_QC_IMAGES]; // x coordinate for image
|
|
float qc_y[MAX_QC_IMAGES]; // y coordinate for image
|
|
float qc_mode[MAX_QC_IMAGES]; // draw mode data, 0 for center screen, 1 for coord
|
|
char *qcimg[MAX_QC_IMAGES]; // paths to images
|
|
float qc_num_string; // number of strings on screen
|
|
float qc_sx[MAX_QC_IMAGES]; // x coordinate for string
|
|
float qc_sy[MAX_QC_IMAGES]; // y coordinate for string
|
|
char *qcstring[MAX_QC_IMAGES]; // string to be drawn to screen
|
|
|
|
void QC_Draw (void)
|
|
{
|
|
int i, j;
|
|
qpic_t *p;
|
|
|
|
//initialize i and j
|
|
i = 0;
|
|
j = qc_num_img;
|
|
|
|
//do images first
|
|
while (i < j)
|
|
{
|
|
//set up the pic
|
|
p = Draw_CachePic (qcimg[i]);
|
|
|
|
//draw based on qc_mode
|
|
if (qc_mode[i] == 0) //draw center
|
|
Draw_Pic(((vid.width - p->width)>>1),((vid.height - p->height)>>1), p);
|
|
else //draw coord
|
|
Draw_Pic(qc_x[i],qc_y[i],p);
|
|
|
|
//increment i
|
|
i = i + 1;
|
|
}
|
|
|
|
//reset i and j
|
|
i = 0;
|
|
j = qc_num_string;
|
|
|
|
//now draw text on top of the images
|
|
while (i < j)
|
|
{
|
|
//draw the text at the specified x and y coordinate
|
|
Draw_String (qc_sx[i], qc_sy[i], qcstring[i], 0);
|
|
|
|
//increment i
|
|
i = i + 1;
|
|
}
|
|
}
|
|
|
|
void PF_CoordPrint (void)
|
|
{
|
|
//make sure we haven't loaded more than MAX_QC_IMAGES
|
|
if (qc_num_string >= MAX_QC_IMAGES)
|
|
PR_RunError ("PF_CoordPrint: Too Many Strings!");
|
|
|
|
//set qc_current equal to the first parameter
|
|
qc_current = G_FLOAT(OFS_PARM0);
|
|
|
|
//set qc_sx and qc_sy equal to parameter 2 and 3
|
|
qc_sx[qc_current] = G_FLOAT(OFS_PARM1);
|
|
qc_sy[qc_current] = G_FLOAT(OFS_PARM2);
|
|
|
|
//set qcstring equal to the fourth parameter
|
|
qcstring[qc_current] = G_STRING(OFS_PARM3);
|
|
|
|
//increment qc_num_string
|
|
qc_num_string = qc_num_string + 1;
|
|
}
|
|
|
|
void PF_draw_coord (void)
|
|
{
|
|
//make sure we haven't loaded more than MAX_QC_IMAGES
|
|
if (qc_num_img >= MAX_QC_IMAGES)
|
|
PR_RunError ("PF_draw_coord: Too Many Images!");
|
|
|
|
//set qc_current equal to the first parameter
|
|
qc_current = G_FLOAT(OFS_PARM0);
|
|
|
|
//set qc_mode to 1
|
|
qc_mode[qc_current] = 1;
|
|
|
|
//set qc_x and qc_y equal to parameter 2 and 3
|
|
qc_x[qc_current] = G_FLOAT(OFS_PARM1);
|
|
qc_y[qc_current] = G_FLOAT(OFS_PARM2);
|
|
|
|
//set qcimg equal to the fourth parameter
|
|
qcimg[qc_current] = G_STRING(OFS_PARM3);
|
|
|
|
//increment qc_num_img
|
|
qc_num_img = qc_num_img + 1;
|
|
}
|
|
|
|
void PF_draw_center (void)
|
|
{
|
|
//make sure we haven't loaded more than MAX_QC_IMAGES
|
|
if (qc_num_img >= MAX_QC_IMAGES)
|
|
PR_RunError ("PF_draw_center: Too Many Images!");
|
|
|
|
//set qc_current equal to the first parameter
|
|
qc_current = G_FLOAT(OFS_PARM0);
|
|
|
|
//set qc_mode to 0
|
|
qc_mode[qc_current] = 0;
|
|
|
|
//set qcimg equal to the second parameter
|
|
qcimg[qc_current] = G_STRING(OFS_PARM1);
|
|
|
|
//increment qc_num_img
|
|
qc_num_img = qc_num_img + 1;
|
|
}
|
|
|
|
/*
|
|
========================
|
|
PF_init_draw
|
|
|
|
Turns on QC Image drawing mode.
|
|
All images stored in array qcimg will appear on screen.
|
|
All text stored in array qcstring will appear on screen.
|
|
========================
|
|
*/
|
|
void PF_init_draw (void)
|
|
{
|
|
//turn on QC Image drawing mode
|
|
qc_image = 1;
|
|
}
|
|
|
|
/*
|
|
========================
|
|
PF_stop_draw
|
|
|
|
Turns off QC Image drawing mode.
|
|
========================
|
|
*/
|
|
void PF_stop_draw (void)
|
|
{
|
|
int i, j;
|
|
|
|
//turn off QC Image drawing mode
|
|
qc_image = 0;
|
|
|
|
//need to reset our variables
|
|
|
|
//initialize i and j
|
|
i = 0;
|
|
j = qc_num_img;
|
|
|
|
//reset images first
|
|
while (i < j)
|
|
{
|
|
//reset qc_mode
|
|
qc_mode[i] = 0;
|
|
|
|
//reset qc_x and qc_y
|
|
qc_x[i] = 0;
|
|
qc_y[i] = 0;
|
|
|
|
//reset qcimg
|
|
qcimg[i] = "";
|
|
|
|
//increment i
|
|
i = i + 1;
|
|
}
|
|
|
|
//reset i and j
|
|
i = 0;
|
|
j = qc_num_string;
|
|
|
|
//now reset strings
|
|
while (i < j)
|
|
{
|
|
//reset qc_sx and qc_sy
|
|
qc_sx[i] = 0;
|
|
qc_sy[i] = 0;
|
|
|
|
//reset qcstring
|
|
qcstring[i] = "";
|
|
|
|
//increment i
|
|
i = i + 1;
|
|
}
|
|
|
|
//reset qc_num_img
|
|
qc_num_img = 0;
|
|
|
|
//reset qc_num_string
|
|
qc_num_string = 0;
|
|
}
|
|
|
|
//HUD Draw System
|
|
//new global variables
|
|
int hud_current; //current item in array
|
|
float hud_num_img; // if this gets close to MAX_QC_IMAGES then deny new ones
|
|
float hud_x[MAX_HUD_IMAGES]; // x coordinate for image
|
|
float hud_y[MAX_HUD_IMAGES]; // y coordinate for image
|
|
float hud_mode[MAX_HUD_IMAGES]; // draw mode data, 0 for center screen, 1 for coord
|
|
char *hudimg[MAX_HUD_IMAGES]; // paths to images
|
|
float hud_num_string; // number of strings on screen
|
|
float hud_sx[MAX_HUD_IMAGES]; // x coordinate for string
|
|
float hud_sy[MAX_HUD_IMAGES]; // y coordinate for string
|
|
char *hudstring[MAX_HUD_IMAGES]; // string to be drawn to screen
|
|
|
|
void HUD_Draw (void)
|
|
{
|
|
int i, j;
|
|
qpic_t *p;
|
|
|
|
//initialize i and j
|
|
i = 0;
|
|
j = hud_num_img;
|
|
|
|
//do images first
|
|
while (i < j)
|
|
{
|
|
//set up the pic
|
|
p = Draw_CachePic (hudimg[i]);
|
|
|
|
//draw based on qc_mode
|
|
if (hud_mode[i] == 0) //draw center
|
|
Draw_Pic(((vid.width - p->width)>>1),((vid.height - p->height)>>1), p);
|
|
else //draw coord
|
|
Draw_Pic(hud_x[i],hud_y[i],p);
|
|
|
|
//increment i
|
|
i = i + 1;
|
|
}
|
|
|
|
//reset i and j
|
|
i = 0;
|
|
j = hud_num_string;
|
|
|
|
//now draw text on top of the images
|
|
while (i < j)
|
|
{
|
|
//draw the text at the specified x and y coordinate
|
|
Draw_String (hud_sx[i], hud_sy[i], hudstring[i], 0);
|
|
|
|
//increment i
|
|
i = i + 1;
|
|
}
|
|
}
|
|
|
|
void PF_HUD_CoordPrint (void)
|
|
{
|
|
//make sure we haven't loaded more than MAX_HUD_IMAGES
|
|
if (hud_num_string >= MAX_HUD_IMAGES)
|
|
PR_RunError ("PF_HUD_CoordPrint: Too Many Strings!");
|
|
|
|
//set hud_current equal to the first parameter
|
|
hud_current = G_FLOAT(OFS_PARM0);
|
|
|
|
//set hud_sx and hud_sy equal to parameter 2 and 3
|
|
hud_sx[hud_current] = G_FLOAT(OFS_PARM1);
|
|
hud_sy[hud_current] = G_FLOAT(OFS_PARM2);
|
|
|
|
//set hudstring equal to the fourth parameter
|
|
hudstring[hud_current] = G_STRING(OFS_PARM3);
|
|
|
|
//increment hud_num_string
|
|
hud_num_string = hud_num_string + 1;
|
|
}
|
|
|
|
void PF_HUD_draw_coord (void)
|
|
{
|
|
//make sure we haven't loaded more than MAX_HUD_IMAGES
|
|
if (hud_num_img >= MAX_HUD_IMAGES)
|
|
PR_RunError ("PF_HUD_draw_coord: Too Many Images!");
|
|
|
|
//set hud_current equal to the first parameter
|
|
hud_current = G_FLOAT(OFS_PARM0);
|
|
|
|
//set hud_mode to 1
|
|
hud_mode[hud_current] = 1;
|
|
|
|
//set hud_x and hud_y equal to parameter 2 and 3
|
|
hud_x[hud_current] = G_FLOAT(OFS_PARM1);
|
|
hud_y[hud_current] = G_FLOAT(OFS_PARM2);
|
|
|
|
//set hudimg equal to the fourth parameter
|
|
hudimg[hud_current] = G_STRING(OFS_PARM3);
|
|
|
|
//increment hud_num_img
|
|
hud_num_img = hud_num_img + 1;
|
|
}
|
|
|
|
void PF_HUD_draw_center (void)
|
|
{
|
|
//make sure we haven't loaded more than MAX_HUD_IMAGES
|
|
if (hud_num_img >= MAX_HUD_IMAGES)
|
|
PR_RunError ("PF_HUD_draw_center: Too Many Images!");
|
|
|
|
//set hud_current equal to the first parameter
|
|
hud_current = G_FLOAT(OFS_PARM0);
|
|
|
|
//set hud_mode to 0
|
|
hud_mode[hud_current] = 0;
|
|
|
|
//set hudimg equal to the second parameter
|
|
hudimg[hud_current] = G_STRING(OFS_PARM1);
|
|
|
|
//increment hud_num_img
|
|
hud_num_img = hud_num_img + 1;
|
|
}
|
|
|
|
/*
|
|
========================
|
|
PF_init_hud_draw
|
|
|
|
Turns on HUD Image drawing mode.
|
|
All images stored in array hudimg will appear on screen.
|
|
All text stored in array hudstring will appear on screen.
|
|
========================
|
|
*/
|
|
void PF_init_hud_draw (void)
|
|
{
|
|
//turn on HUD Image drawing mode
|
|
hud_image = 1;
|
|
}
|
|
|
|
/*
|
|
========================
|
|
PF_stop_hud_draw
|
|
|
|
Turns off HUD Image drawing mode.
|
|
========================
|
|
*/
|
|
void PF_stop_hud_draw (void)
|
|
{
|
|
int i, j;
|
|
|
|
//turn off HUD Image drawing mode
|
|
hud_image = 0;
|
|
|
|
//need to reset our variables
|
|
|
|
//initialize i and j
|
|
i = 0;
|
|
j = hud_num_img;
|
|
|
|
//reset images first
|
|
while (i < j)
|
|
{
|
|
//reset hud_mode
|
|
hud_mode[i] = 0;
|
|
|
|
//reset hud_x and hud_y
|
|
hud_x[i] = 0;
|
|
hud_y[i] = 0;
|
|
|
|
//reset hudimg
|
|
hudimg[i] = "";
|
|
|
|
//increment i
|
|
i = i + 1;
|
|
}
|
|
|
|
//reset i and j
|
|
i = 0;
|
|
j = hud_num_string;
|
|
|
|
//now reset strings
|
|
while (i < j)
|
|
{
|
|
//reset hud_sx and hud_sy
|
|
hud_sx[i] = 0;
|
|
hud_sy[i] = 0;
|
|
|
|
//reset hudstring
|
|
hudstring[i] = "";
|
|
|
|
//increment i
|
|
i = i + 1;
|
|
}
|
|
|
|
//reset hud_num_img
|
|
hud_num_img = 0;
|
|
|
|
//reset hud_num_string
|
|
hud_num_string = 0;
|
|
}
|
|
|
|
//end new image precaching / loading code -Xsniper
|
|
|
|
// Xsniper - Added Bot Support
|
|
|
|
/*
|
|
==========================
|
|
PF_get_numbots
|
|
|
|
Called from qc to get number of bots.
|
|
==========================
|
|
*/
|
|
void PF_get_numbots (void)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = numbots;
|
|
}
|
|
|
|
/*
|
|
==========================
|
|
PF_set_numbots
|
|
|
|
Called from qc to set the number of bots.
|
|
==========================
|
|
*/
|
|
void PF_set_numbots (void)
|
|
{
|
|
numbots = G_FLOAT(OFS_PARM0);
|
|
}
|
|
|
|
// Xsniper Added Width and Height Commands
|
|
|
|
/*
|
|
==========================
|
|
PF_get_vid_width
|
|
|
|
Called from qc to get width of the screen.
|
|
==========================
|
|
*/
|
|
void PF_get_vid_width (void)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = vid.width;
|
|
}
|
|
|
|
/*
|
|
==========================
|
|
PF_get_vid_height
|
|
|
|
Called from qc to get height of the screen.
|
|
==========================
|
|
*/
|
|
void PF_get_vid_height (void)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = vid.height;
|
|
}
|
|
|
|
/*
|
|
==========================
|
|
PF_get_engine_version
|
|
|
|
Called from qc to get the current engine version.
|
|
|
|
0: MQ
|
|
1: HQ
|
|
==========================
|
|
*/
|
|
void PF_get_engine_version (void)
|
|
{
|
|
G_FLOAT(OFS_RETURN) = ENGINE_VERSION;
|
|
}
|
|
|
|
//Xsniper - End
|
|
|
|
void R_RayFieldParticles(vec3_t org);
|
|
void R_ParticleExplosion(vec3_t org);
|
|
void R_ParticleExplosionX(vec3_t org);
|
|
void R_ParticleTeExplosion(vec3_t org);
|
|
void R_ParticleImplosion(vec3_t org);
|
|
void R_ParticleImplosionHaze(vec3_t org);
|
|
void R_ParticleSuperHazes(vec3_t org);
|
|
void R_ParticleImplosionXray(vec3_t org);
|
|
void R_ParticleIstar(vec3_t org);
|
|
void R_ParticleFog(vec3_t org);
|
|
void R_ParticleFog2(vec3_t org);
|
|
void R_ParticleFogLava(vec3_t org);
|
|
void R_ParticleDay(vec3_t org);
|
|
void R_ParticleImplosionSutil(vec3_t org);
|
|
void R_ParticleExplosion3(vec3_t org);
|
|
void R_ParticleGround(vec3_t org);
|
|
void R_Decal(vec3_t org);
|
|
void R_ParticleExplosion5(vec3_t org);
|
|
void R_BlobExplosion(vec3_t org);
|
|
void R_FogSplashLite(vec3_t org);
|
|
void R_FogSplash(vec3_t org);
|
|
void R_FogChof(vec3_t org);
|
|
void R_LavaSplash(vec3_t org);
|
|
void R_TeleportSplash(vec3_t org);
|
|
void R_RocketTrailX(vec3_t org);
|
|
void R_WaterFallParticles(vec3_t org);
|
|
void R_ParticleSnow(vec3_t org);
|
|
void R_ParticleRain(vec3_t org);
|
|
void R_ParticleMeteor(vec3_t org);
|
|
void R_ParticleMeteorNormal(vec3_t org);
|
|
void R_ParticleDream(vec3_t org);
|
|
void R_FireStaticFog(vec3_t org);
|
|
void R_AlienBloodExplosion(vec3_t org);
|
|
void R_AlienBoltExplosion(vec3_t org);
|
|
void R_AlienBlood(vec3_t org);
|
|
void R_AlienBlood2(vec3_t org);
|
|
void R_LightParticles(vec3_t org);
|
|
void R_ParticleBubble(vec3_t org);
|
|
void R_ParticleBubbleGib(vec3_t org);
|
|
void R_ParticleExplosionAlien(vec3_t org);
|
|
void R_ParticleExplosionSmoke(vec3_t org);
|
|
void R_ParticleCircle(vec3_t org);
|
|
void XR_BlobExplosion(vec3_t org);
|
|
void XR_BlobExplosion2(vec3_t org);
|
|
void XR_BlobExplosion3(vec3_t org);
|
|
void XR_LavaSplash(vec3_t org);
|
|
void XR_TeleportSplash(vec3_t org);
|
|
void R_FlameSmokes(vec3_t org);
|
|
void R_ZerstorerRain(vec3_t org);
|
|
|
|
//#define MAKEPR_ORG(namefunc) Con_Printf("%d - 10\n", t_##namefunc);
|
|
|
|
#define MAKEPR_ORG(namefunc) void PR_##namefunc(void)\
|
|
{\
|
|
float * org = G_VECTOR(OFS_PARM0);\
|
|
##namefunc(org);\
|
|
};
|
|
|
|
MAKEPR_ORG(R_ParticleImpSuperSpike);
|
|
MAKEPR_ORG(R_Decal2);
|
|
MAKEPR_ORG(R_ParticleExplosion4);
|
|
MAKEPR_ORG(R_RayFieldParticles);
|
|
MAKEPR_ORG(R_ParticleExplosion);
|
|
MAKEPR_ORG(R_ParticleExplosionX);
|
|
MAKEPR_ORG(R_ParticleTeExplosion);
|
|
MAKEPR_ORG(R_ParticleImplosion);
|
|
MAKEPR_ORG(R_ParticleImplosionHaze);
|
|
MAKEPR_ORG(R_ParticleSuperHazes);
|
|
MAKEPR_ORG(R_ParticleImplosionXray);
|
|
MAKEPR_ORG(R_ParticleIstar);
|
|
MAKEPR_ORG(R_ParticleFog);
|
|
MAKEPR_ORG(R_ParticleFog2);
|
|
MAKEPR_ORG(R_ParticleFogLava);
|
|
MAKEPR_ORG(R_ParticleDay);
|
|
MAKEPR_ORG(R_ParticleImplosionSutil);
|
|
MAKEPR_ORG(R_ParticleExplosion3);
|
|
MAKEPR_ORG(R_ParticleGround);
|
|
MAKEPR_ORG(R_Decal);
|
|
MAKEPR_ORG(R_ParticleExplosion5);
|
|
MAKEPR_ORG(R_BlobExplosion);
|
|
MAKEPR_ORG(R_FogSplashLite);
|
|
MAKEPR_ORG(R_FogSplash);
|
|
MAKEPR_ORG(R_FogChof);
|
|
MAKEPR_ORG(R_LavaSplash);
|
|
MAKEPR_ORG(R_TeleportSplash);
|
|
MAKEPR_ORG(R_RocketTrailX);
|
|
MAKEPR_ORG(R_WaterFallParticles);
|
|
MAKEPR_ORG(R_ParticleSnow);
|
|
MAKEPR_ORG(R_ParticleRain);
|
|
MAKEPR_ORG(R_ParticleMeteor);
|
|
MAKEPR_ORG(R_ParticleMeteorNormal);
|
|
MAKEPR_ORG(R_ParticleDream);
|
|
MAKEPR_ORG(R_FireStaticFog);
|
|
MAKEPR_ORG(R_AlienBloodExplosion);
|
|
MAKEPR_ORG(R_AlienBoltExplosion);
|
|
MAKEPR_ORG(R_AlienBlood);
|
|
MAKEPR_ORG(R_AlienBlood2);
|
|
MAKEPR_ORG(R_LightParticles);
|
|
MAKEPR_ORG(R_ParticleBubble);
|
|
MAKEPR_ORG(R_ParticleBubbleGib);
|
|
MAKEPR_ORG(R_ParticleExplosionAlien);
|
|
MAKEPR_ORG(R_ParticleExplosionSmoke);
|
|
MAKEPR_ORG(R_ParticleCircle);
|
|
MAKEPR_ORG(XR_BlobExplosion);
|
|
MAKEPR_ORG(XR_BlobExplosion2);
|
|
MAKEPR_ORG(XR_BlobExplosion3);
|
|
MAKEPR_ORG(XR_LavaSplash);
|
|
MAKEPR_ORG(XR_TeleportSplash);
|
|
MAKEPR_ORG(R_FlameSmokes);
|
|
MAKEPR_ORG(R_ZerstorerRain);
|
|
|
|
void PR_AddCommand (void);
|
|
|
|
/*
|
|
void PR_R_ParticleImpSuperSpike(void)
|
|
{
|
|
int t_s = 10;
|
|
float * org = G_VECTOR(OFS_PARM0);
|
|
R_ParticleImpSuperSpike(org);
|
|
|
|
MAKEPR_ORG(s);
|
|
};*/
|
|
|
|
// Tei:
|
|
// QuakeC Delegates
|
|
//
|
|
// This function is called from QuakeC has a builtin for diferent purposes
|
|
// .weapon identify the purpose
|
|
|
|
void PR_SelfCall(void );
|
|
|
|
|
|
builtin_t pr_builtin[] =
|
|
{
|
|
PF_Fixme,
|
|
PF_makevectors, // #1 void(entity e) makevectors
|
|
PF_setorigin, // #2 void(entity e, vector o) setorigin
|
|
PF_setmodel, // #3 void(entity e, string m) setmodel
|
|
PF_setsize, // #4 void(entity e, vector min, vector max) setsize
|
|
PF_Fixme, // #5
|
|
PF_break, // #6 void() break
|
|
PF_random, // #7 float() random
|
|
PF_sound, // #8 void(entity e, float chan, string samp) sound
|
|
PF_normalize, // #9 vector(vector v) normalize
|
|
|
|
PF_error, // #10 void(string e) error
|
|
PF_objerror, // #11 void(string e) objerror
|
|
PF_vlen, // #12 float(vector v) vlen
|
|
PF_vectoyaw, // #13 float(vector v) vectoyaw
|
|
PF_Spawn, // #14 entity() spawn
|
|
PF_Remove, // #15 void(entity e) remove
|
|
PF_traceline, // #16 float(vector v1, vector v2, float tryents) traceline
|
|
PF_checkclient, // #17 entity() clientlist
|
|
PF_Find, // #18 entity(entity start, .string fld, string match) find
|
|
PF_precache_sound, // #19 void(string s) precache_sound
|
|
|
|
PF_precache_model, // #20 void(string s) precache_model
|
|
PF_stuffcmd, // #21 void(entity client, string s)stuffcmd
|
|
PF_findradius, // #22 entity(vector org, float rad) findradius
|
|
PF_bprint, // #23 void(string s) bprint
|
|
PF_sprint, // #24 void(entity client, string s) sprint
|
|
PF_dprint, // #25 void(string s) dprint
|
|
PF_ftos, // #26 void(string s) ftos
|
|
PF_vtos, // #27 void(string s) vtos
|
|
PF_coredump, // #28
|
|
PF_traceon, // #29
|
|
|
|
PF_traceoff, // #30
|
|
PF_eprint, // #31 void(entity e) debug print an entire entity
|
|
PF_walkmove, // #32 float(float yaw, float dist) walkmove
|
|
PF_Fixme, // #33 float(float yaw, float dist) walkmove
|
|
PF_droptofloor, // #34
|
|
PF_lightstyle, // #35
|
|
PF_rint, // #36
|
|
PF_floor, // #37
|
|
PF_ceil, // #38
|
|
PF_Fixme, // #39
|
|
|
|
PF_checkbottom, // #40
|
|
PF_pointcontents, // #41
|
|
PF_Fixme, // #42
|
|
PF_fabs, // #43
|
|
PF_aim, // #44
|
|
PF_cvar, // #45
|
|
PF_localcmd, // #46
|
|
PF_nextent, // #47
|
|
PF_particle, // #48
|
|
PF_changeyaw, // #49
|
|
|
|
PF_Fixme, // #50
|
|
PF_vectoangles, // #51
|
|
PF_WriteByte, // #52
|
|
PF_WriteChar, // #53
|
|
PF_WriteShort, // #54
|
|
PF_WriteLong, // #55
|
|
PF_WriteCoord, // #56
|
|
PF_WriteAngle, // #57
|
|
PF_WriteString, // #58
|
|
PF_WriteEntity, // #59
|
|
|
|
PF_Fixme, // #60
|
|
PF_Fixme, // #61
|
|
PF_Fixme, // #62
|
|
PF_Fixme, // #63
|
|
PF_Fixme, // #64
|
|
PF_Fixme, // #65
|
|
PF_Fixme, // #66
|
|
SV_MoveToGoal, // #67
|
|
PF_precache_file, // #68
|
|
PF_makestatic, // #69
|
|
|
|
PF_changelevel, // #70
|
|
PF_Fixme, // #71
|
|
PF_cvar_set, // #72
|
|
PF_centerprint, // #73
|
|
PF_ambientsound, // #74
|
|
PF_precache_model, // #75
|
|
PF_precache_sound, // #76
|
|
PF_precache_file, // #77
|
|
PF_setspawnparms, // #78
|
|
|
|
// Tomaz - QuakeC String Manipulation Begin
|
|
PF_zone, // #79
|
|
|
|
PF_unzone, // #80
|
|
PF_strlen, // #81
|
|
PF_strcat, // #82
|
|
PF_substring, // #83
|
|
PF_stof, // #84
|
|
PF_stov, // #85
|
|
// Tomaz - QuakeC String Manipulation End
|
|
|
|
// Tomaz - QuakeC File System Begin
|
|
PF_open, // #86
|
|
PF_close, // #87
|
|
PF_read, // #88
|
|
PF_write, // #89
|
|
// Tomaz - QuakeC File System End
|
|
|
|
// Tei - QC extras
|
|
PF_rvector, // #90 random vector
|
|
PF_statcount, // #91 stats counter
|
|
PF_keytest, // #92 key parsing
|
|
PF_sscanf, // #93 scan string
|
|
PF_hvstring, // #94 hello -> h\ne\nl\nl\no
|
|
PF_SetArray, // #95
|
|
PF_stuffcmd2, // #96 tei good stuff
|
|
|
|
PF_cvarstring, // #97 cvarstring
|
|
|
|
// Tei - QC extras
|
|
|
|
PF_Fixme, // #98
|
|
PF_checkextension, // #99
|
|
PF_VisibleEnt, // #100
|
|
PF_Visible, // #101
|
|
PF_AngleMod, // #102
|
|
PR_T_RadiusDamage, // #103
|
|
PR_ShowPic, // #104
|
|
PR_HidePic, // #105
|
|
PR_MovePic, // #106
|
|
PR_ChangePic, // #107
|
|
PR_ShowPicEnt, // #108
|
|
PR_HidePicEnt, // #109
|
|
PR_MovePicEnt, // #110
|
|
PR_ChangePicEnt, // #111
|
|
PF_ReadRegister, // #112
|
|
PR_RunParticleEvent, // #113
|
|
PF_LoadLexer, // #114
|
|
PF_IndexFromLexer, // #115
|
|
PR_TempEntity, // #116
|
|
PR_gLine, // #117
|
|
PR_LocalMenu, // #118
|
|
PF_Fixme, // #119
|
|
PR_SelfCall, // #120
|
|
PR_R_ParticleImpSuperSpike, // #121
|
|
PR_R_Decal2, // #122
|
|
PR_R_ParticleExplosion4, //#123
|
|
PR_R_RayFieldParticles, // #124
|
|
PR_R_ParticleExplosion, // #125
|
|
PR_R_ParticleExplosionX, // #126
|
|
PR_R_ParticleTeExplosion, // #127
|
|
PR_R_ParticleImplosion, // #128
|
|
PR_R_ParticleImplosionHaze, // #129
|
|
PR_R_ParticleSuperHazes, // #130
|
|
PR_R_ParticleImplosionXray, // #131
|
|
PR_R_ParticleIstar, // #132
|
|
PR_R_ParticleFog, // #133
|
|
PR_R_ParticleFog2, // #134
|
|
PR_R_ParticleFogLava, // #135
|
|
PR_R_ParticleDay, // #136
|
|
PR_R_ParticleImplosionSutil, // #137
|
|
PR_R_ParticleExplosion3, // #138
|
|
PR_R_ParticleGround, // #139
|
|
PR_R_Decal, // #140
|
|
PR_R_ParticleExplosion5, // #141
|
|
PR_R_BlobExplosion, // #142
|
|
PR_R_FogSplashLite, // #143
|
|
PR_R_FogSplash, // #144
|
|
PR_R_FogChof, // #145
|
|
PR_R_LavaSplash, // #146
|
|
PR_R_TeleportSplash, // #147
|
|
PR_R_RocketTrailX, // #148
|
|
PR_R_WaterFallParticles, // #149
|
|
PR_R_ParticleSnow, // #150
|
|
PR_R_ParticleRain, // #151
|
|
PR_R_ParticleMeteor, // #152
|
|
PR_R_ParticleMeteorNormal, // #153
|
|
PR_R_ParticleDream, // #154
|
|
PR_R_FireStaticFog, // #155
|
|
PR_R_AlienBloodExplosion, // #156
|
|
PR_R_AlienBoltExplosion, // #157
|
|
PR_R_AlienBlood, // #158
|
|
PR_R_AlienBlood2, // #159
|
|
PR_R_LightParticles, // #160
|
|
PR_R_ParticleBubble, // #161
|
|
PR_R_ParticleBubbleGib, // #162
|
|
PR_R_ParticleExplosionAlien, // #163
|
|
PR_R_ParticleExplosionSmoke, // #164
|
|
PR_R_ParticleCircle, // #165
|
|
PR_XR_BlobExplosion, // #166
|
|
PR_XR_BlobExplosion2, // #167
|
|
PR_XR_BlobExplosion3, // #168
|
|
PR_XR_LavaSplash, // #169
|
|
PR_XR_TeleportSplash, // #170
|
|
PR_R_FlameSmokes, // #171
|
|
PR_R_ZerstorerRain, // #172
|
|
PR_AddCommand, //#173
|
|
PR_Cvar_Set, //#174
|
|
PR_Exec, //#175
|
|
PR_Cvar_Setf, //#176
|
|
PR_LocalSound, //#177
|
|
PR_Con_Print, //#178
|
|
|
|
//PF commands from EW - Xsniper
|
|
PF_init_draw, //#179
|
|
PF_stop_draw, //#180
|
|
PF_draw_coord, //#181
|
|
PF_draw_center, //#182
|
|
PF_CoordPrint, //#183
|
|
PF_Fixme, //#184
|
|
PF_get_numbots, //#185
|
|
PF_set_numbots, //#186
|
|
PF_init_hud_draw, //#187
|
|
PF_stop_hud_draw, //#188
|
|
PF_HUD_draw_coord, //#189
|
|
PF_HUD_draw_center, //#190
|
|
PF_HUD_CoordPrint, //#191
|
|
PF_get_vid_width, //#192
|
|
PF_get_vid_height, //#193
|
|
//Xsniper - End
|
|
|
|
// Xsniper - Added Engine Version Checking
|
|
PF_get_engine_version, //#194
|
|
// Xsniper - End
|
|
};
|
|
|
|
builtin_t *pr_builtins = pr_builtin;
|
|
int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);
|
|
|
|
/*
|
|
|
|
#!perl
|
|
|
|
open (FF, "e:/proc.txt") or die ("Cant!");
|
|
|
|
$num = 123;
|
|
|
|
foreach $data (<FF>)
|
|
{
|
|
$num++;
|
|
chomp($data);
|
|
print "MAKEPR_ORG($data);\n" ;
|
|
};
|
|
|
|
close(FF);
|
|
|
|
|
|
open (FF, "e:/proc.txt") or die ("Cant!");
|
|
|
|
$num = 123;
|
|
|
|
foreach $data (<FF>)
|
|
{
|
|
$num++;
|
|
chomp($data);
|
|
print "PR_$data, // #$num\n" ;
|
|
};
|
|
|
|
close(FF);
|
|
|
|
|
|
open (FF, "e:/proc.txt") or die ("Cant!");
|
|
|
|
$num = 123;
|
|
|
|
foreach $data (<FF>)
|
|
{
|
|
$num++;
|
|
chomp($data);
|
|
print "void $data(vec3_t org); \n" ;
|
|
};
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|