mirror of
https://github.com/nzp-team/glquake.git
synced 2024-11-10 06:31:35 +00:00
Add basic builtins
This commit is contained in:
parent
eec97d147c
commit
063d9d6ed6
11 changed files with 640 additions and 175 deletions
BIN
nzportable.3dsx
BIN
nzportable.3dsx
Binary file not shown.
BIN
nzportable.elf
BIN
nzportable.elf
Binary file not shown.
|
@ -35,36 +35,45 @@ char *svc_strings[] =
|
|||
"svc_stufftext", // [string] stuffed into client's console buffer
|
||||
// the string should be \n terminated
|
||||
"svc_setangle", // [vec3] set the view angle to this absolute value
|
||||
|
||||
|
||||
"svc_serverinfo", // [long] version
|
||||
// [string] signon string
|
||||
// [string]..[0]model cache [string]...[0]sounds cache
|
||||
// [string]..[0]item cache
|
||||
"svc_lightstyle", // [byte] [string]
|
||||
"svc_updatename", // [byte] [string]
|
||||
"svc_updatefrags", // [byte] [short]
|
||||
"svc_updatepoints", // [byte] [short]
|
||||
"svc_clientdata", // <shortbits + data>
|
||||
"svc_stopsound", // <see code>
|
||||
"svc_updatecolors", // [byte] [byte]
|
||||
"", // [byte] [byte]
|
||||
"svc_particle", // [vec3] <variable>
|
||||
"svc_damage", // [byte] impact [byte] blood [vec3] from
|
||||
|
||||
|
||||
"svc_spawnstatic",
|
||||
"OBSOLETE svc_spawnbinary",
|
||||
"svc_spawnbaseline",
|
||||
|
||||
|
||||
"svc_temp_entity", // <variable>
|
||||
"svc_setpause",
|
||||
"svc_signonnum",
|
||||
"svc_centerprint",
|
||||
"svc_killedmonster",
|
||||
"svc_foundsecret",
|
||||
"svc_spawnstaticsound",
|
||||
"svc_intermission",
|
||||
"svc_finale", // [string] music [string] text
|
||||
"svc_cdtrack", // [byte] track [byte] looptrack
|
||||
"svc_sellscreen",
|
||||
"svc_cutscene"
|
||||
"svc_cutscene",
|
||||
"svc_weaponfire",
|
||||
"svc_hitmark",
|
||||
"svc_skybox", // [string] skyname
|
||||
"svc_useprint",
|
||||
"svc_updatekills",
|
||||
"svc_limbupdate",
|
||||
"svc_fog", // 41 // [byte] start [byte] end [byte] red [byte] green [byte] blue [float] time
|
||||
"svc_bspdecal", //42 // [string] name [byte] decal_size [coords] pos
|
||||
"svc_achievement", //43
|
||||
"svc_songegg", //44 [string] track name
|
||||
"svc_maxammo" //45
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
@ -710,6 +719,31 @@ void CL_ParseStaticSound (void)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
CL_ParseLimbUpdate
|
||||
===================
|
||||
*/
|
||||
void CL_ParseLimbUpdate (void)
|
||||
{
|
||||
int limb = MSG_ReadByte();
|
||||
int zombieent = MSG_ReadShort();
|
||||
int limbent = MSG_ReadShort();
|
||||
switch (limb)
|
||||
{
|
||||
case 0://head
|
||||
cl_entities[zombieent].z_head = limbent;
|
||||
break;
|
||||
case 1://larm
|
||||
cl_entities[zombieent].z_larm = limbent;
|
||||
break;
|
||||
case 2://rarm
|
||||
cl_entities[zombieent].z_rarm = limbent;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
|
||||
|
||||
/*
|
||||
|
@ -957,6 +991,10 @@ void CL_ParseServerMessage (void)
|
|||
case svc_sellscreen:
|
||||
Cmd_ExecuteString ("help", src_command);
|
||||
break;
|
||||
|
||||
case svc_limbupdate:
|
||||
CL_ParseLimbUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -395,10 +395,8 @@ void Mod_LoadTextures (lump_t *l)
|
|||
}
|
||||
else
|
||||
{
|
||||
Con_Printf("Loading texture %s\n", mt->name);
|
||||
if (loadmodel->bspversion == HL_BSPVERSION)
|
||||
{
|
||||
Con_Printf("Loading as HLBSP\n");
|
||||
if (1)//((data = WAD3_LoadTexture(mt)))
|
||||
{
|
||||
texture_mode = GL_LINEAR_MIPMAP_NEAREST;
|
||||
|
@ -414,7 +412,6 @@ void Mod_LoadTextures (lump_t *l)
|
|||
}
|
||||
else
|
||||
{
|
||||
Con_Printf("Loading as QBSP\n");
|
||||
texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR;
|
||||
tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false, 1);
|
||||
texture_mode = GL_LINEAR;
|
||||
|
|
|
@ -315,6 +315,11 @@ void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
|
|||
up[2] = cr*cp;
|
||||
}
|
||||
|
||||
float VectorLength (vec3_t v)
|
||||
{
|
||||
return sqrtf(DotProduct(v, v));
|
||||
}
|
||||
|
||||
int VectorCompare (vec3_t v1, vec3_t v2)
|
||||
{
|
||||
int i;
|
||||
|
@ -382,6 +387,13 @@ vec_t Length(vec3_t v)
|
|||
return length;
|
||||
}
|
||||
|
||||
float VecLength2(vec3_t v1, vec3_t v2)
|
||||
{
|
||||
vec3_t k;
|
||||
VectorSubtract(v1, v2, k);
|
||||
return sqrt(k[0]*k[0] + k[1]*k[1] + k[2]*k[2]);
|
||||
}
|
||||
|
||||
float VectorNormalize (vec3_t v)
|
||||
{
|
||||
float length, ilength;
|
||||
|
|
|
@ -53,6 +53,8 @@ void _VectorCopy (vec3_t in, vec3_t out);
|
|||
int VectorCompare (vec3_t v1, vec3_t v2);
|
||||
vec_t Length (vec3_t v);
|
||||
void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross);
|
||||
float VectorLength (vec3_t v);
|
||||
float VecLength2(vec3_t v1, vec3_t v2);
|
||||
float VectorNormalize (vec3_t v); // returns vector length
|
||||
void VectorInverse (vec3_t v);
|
||||
void VectorScale (vec3_t in, vec_t scale, vec3_t out);
|
||||
|
|
697
source/pr_cmds.c
697
source/pr_cmds.c
|
@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "quakedef.h"
|
||||
|
||||
#define PR_MAX_TEMPSTRING 2048 // 2001-10-25 Enhanced temp string handling by Maddes
|
||||
#define RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e))
|
||||
|
||||
/*
|
||||
|
@ -30,17 +31,32 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
===============================================================================
|
||||
*/
|
||||
|
||||
char pr_varstring_temp[PR_MAX_TEMPSTRING]; // 2001-10-25 Enhanced temp string handling by Maddes
|
||||
char *PF_VarString (int first)
|
||||
{
|
||||
int i;
|
||||
static char out[256];
|
||||
|
||||
out[0] = 0;
|
||||
for (i=first ; i<pr_argc ; i++)
|
||||
// 2001-10-25 Enhanced temp string handling by Maddes start
|
||||
int maxlen;
|
||||
char *add;
|
||||
|
||||
pr_varstring_temp[0] = 0;
|
||||
for (i=first ; i < pr_argc ; i++)
|
||||
{
|
||||
strcat (out, G_STRING((OFS_PARM0+i*3)));
|
||||
maxlen = PR_MAX_TEMPSTRING - strlen(pr_varstring_temp) - 1; // -1 is EndOfString
|
||||
add = G_STRING((OFS_PARM0+i*3));
|
||||
if (maxlen > strlen(add))
|
||||
{
|
||||
strcat (pr_varstring_temp, add);
|
||||
}
|
||||
else
|
||||
{
|
||||
strncat (pr_varstring_temp, add, maxlen);
|
||||
pr_varstring_temp[PR_MAX_TEMPSTRING-1] = 0;
|
||||
break; // can stop here
|
||||
}
|
||||
}
|
||||
return out;
|
||||
return pr_varstring_temp;
|
||||
// 2001-10-25 Enhanced temp string handling by Maddes end
|
||||
}
|
||||
|
||||
|
||||
|
@ -664,6 +680,174 @@ void PF_TraceToss (void)
|
|||
}
|
||||
#endif
|
||||
|
||||
int TraceMove(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, edict_t *ent)//engine-sides
|
||||
{
|
||||
if(start[0] == end[0] && start[1] == end[1] && start[2] == end[2])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
vec3_t forward, up;
|
||||
float HorDist;
|
||||
vec3_t HorGoal;
|
||||
vec3_t tempHorGoal;
|
||||
|
||||
up[0] = 0; up[1] = 0; up[2] = 1;
|
||||
HorGoal[0] = end[0]; HorGoal[1] = end[1]; HorGoal[2] = start[2];
|
||||
|
||||
VectorSubtract(HorGoal,start,forward);
|
||||
HorDist = VectorLength(forward);
|
||||
VectorNormalize(forward);
|
||||
|
||||
vec3_t CurrentPos;
|
||||
|
||||
VectorCopy(start,CurrentPos);
|
||||
VectorCopy(HorGoal,tempHorGoal);
|
||||
|
||||
float CurrentDist = 0;//2d distance from initial 3d positionvector
|
||||
|
||||
trace_t trace1, trace2;
|
||||
float tempDist;
|
||||
vec3_t tempVec;
|
||||
vec3_t tempVec2;
|
||||
float i;
|
||||
int STEPSIZEB = 18;//other declaration isn't declared yet
|
||||
float SLOPELEN = 10.4;//18/tan(60) = 10.4, the the length of the triangle formed by the max walkable slope of 60 degrees.
|
||||
int skip = 0;
|
||||
int LoopBreak = 0;
|
||||
|
||||
while(CurrentDist < HorDist)
|
||||
{
|
||||
if(LoopBreak > 20)//was 50, decreased this quite a bit. now it's 260 meters
|
||||
{
|
||||
//Con_Printf("AI Warning: There is a ledge that is greater than 650 meters.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
trace1 = SV_Move(CurrentPos, mins, maxs, tempHorGoal, MOVE_NOMONSTERS, ent);
|
||||
|
||||
VectorSubtract(tempHorGoal,CurrentPos,tempVec);
|
||||
tempDist = trace1.fraction * VectorLength(tempVec);
|
||||
//Check if we fell along the path
|
||||
for(i = (maxs[0] * 1); i < tempDist; i += (maxs[0] * 1))
|
||||
{
|
||||
VectorScale(forward,i,tempVec);
|
||||
VectorAdd(tempVec,CurrentPos,tempVec);
|
||||
VectorScale(up,-500,tempVec2);//500 inches is about 13 meters
|
||||
VectorAdd(tempVec,tempVec2,tempVec2);
|
||||
trace2 = SV_Move(tempVec, mins, maxs, tempVec2, MOVE_NOMONSTERS, ent);
|
||||
if(trace2.fraction > 0)
|
||||
{
|
||||
VectorScale(up,trace2.fraction * -100,tempVec2);
|
||||
VectorAdd(tempVec,tempVec2,CurrentPos);
|
||||
VectorAdd(tempHorGoal,tempVec2,tempHorGoal);
|
||||
skip = 1;
|
||||
CurrentDist += i;
|
||||
if(trace2.fraction == 1)
|
||||
{
|
||||
//We fell the full 13 meters!, we need to be careful here,
|
||||
//because if we're checking over the void, then we could be stuck in an infinite loop and crash the game
|
||||
//So we're going to keep track of how many times we fall 13 meters
|
||||
LoopBreak++;
|
||||
}
|
||||
else
|
||||
{
|
||||
LoopBreak = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
//If we fell at any location along path, then we don't try to step up
|
||||
if(skip == 1)
|
||||
{
|
||||
trace2.fraction = 0;
|
||||
skip = 0;
|
||||
continue;
|
||||
}
|
||||
//We need to advance it as much as possible along path before step up
|
||||
if(trace1.fraction > 0 && trace1.fraction < 1)
|
||||
{
|
||||
VectorCopy(trace1.endpos,CurrentPos);
|
||||
trace1.fraction = 0;
|
||||
}
|
||||
//Check step up
|
||||
if(trace1.fraction < 1)
|
||||
{
|
||||
VectorScale(up,STEPSIZEB,tempVec2);
|
||||
VectorAdd(CurrentPos,tempVec2,tempVec);
|
||||
VectorAdd(tempHorGoal,tempVec2,tempVec2);
|
||||
trace2 = SV_Move(tempVec, mins, maxs, tempVec2, MOVE_NOMONSTERS, ent);
|
||||
//10.4 is minimum length for a slope of 60 degrees, we need to at least advance this much to know the surface is walkable
|
||||
VectorSubtract(tempVec2,tempVec,tempVec2);
|
||||
if(trace2.fraction > (trace1.fraction + (SLOPELEN/VectorLength(tempVec2))) || trace2.fraction == 1)
|
||||
{
|
||||
VectorCopy(tempVec,CurrentPos);
|
||||
tempHorGoal[2] = CurrentPos[2];
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;//stepping up didn't advance so we've hit a wall, we failed
|
||||
}
|
||||
}
|
||||
if(trace1.fraction == 1)//we've made it horizontally to our goal... so check if we've made it vertically...
|
||||
{
|
||||
if((end[2] - tempHorGoal[2] < STEPSIZEB) && (end[2] - tempHorGoal[2]) > -1 * STEPSIZEB)
|
||||
return 1;
|
||||
else return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PF_tracemove(void)//progs side
|
||||
{
|
||||
float *start, *end, *mins, *maxs;
|
||||
int nomonsters;
|
||||
edict_t *ent;
|
||||
|
||||
start = G_VECTOR(OFS_PARM0);
|
||||
mins = G_VECTOR(OFS_PARM1);
|
||||
maxs = G_VECTOR(OFS_PARM2);
|
||||
end = G_VECTOR(OFS_PARM3);
|
||||
nomonsters = G_FLOAT(OFS_PARM4);
|
||||
ent = G_EDICT(OFS_PARM5);
|
||||
|
||||
Con_DPrintf ("TraceMove start, ");
|
||||
G_INT(OFS_RETURN) = TraceMove(start, mins, maxs, end,nomonsters,ent);
|
||||
Con_DPrintf ("TM end\n");
|
||||
return;
|
||||
}
|
||||
|
||||
void PF_tracebox (void)
|
||||
{
|
||||
float *v1, *v2, *mins, *maxs;
|
||||
trace_t trace;
|
||||
int nomonsters;
|
||||
edict_t *ent;
|
||||
|
||||
v1 = G_VECTOR(OFS_PARM0);
|
||||
mins = G_VECTOR(OFS_PARM1);
|
||||
maxs = G_VECTOR(OFS_PARM2);
|
||||
v2 = G_VECTOR(OFS_PARM3);
|
||||
nomonsters = G_FLOAT(OFS_PARM4);
|
||||
ent = G_EDICT(OFS_PARM5);
|
||||
|
||||
trace = SV_Move (v1, mins, maxs, 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);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -947,13 +1131,11 @@ void PF_vtos (void)
|
|||
G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
|
||||
}
|
||||
|
||||
#ifdef QUAKE2
|
||||
void PF_etos (void)
|
||||
{
|
||||
sprintf (pr_string_temp, "entity %i", G_EDICTNUM(OFS_PARM0));
|
||||
G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
|
||||
}
|
||||
#endif
|
||||
|
||||
void PF_Spawn (void)
|
||||
{
|
||||
|
@ -970,6 +1152,220 @@ void PF_Remove (void)
|
|||
ED_Free (ed);
|
||||
}
|
||||
|
||||
// 2001-09-20 QuakeC string manipulation by FrikaC/Maddes start
|
||||
/*
|
||||
=================
|
||||
PF_strzone
|
||||
|
||||
string strzone (string)
|
||||
=================
|
||||
*/
|
||||
void PF_strzone (void)
|
||||
{
|
||||
char *m, *p;
|
||||
m = G_STRING(OFS_PARM0);
|
||||
p = Z_Malloc(strlen(m) + 1);
|
||||
strcpy(p, m);
|
||||
|
||||
G_INT(OFS_RETURN) = p - pr_strings;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
PF_strunzone
|
||||
|
||||
string strunzone (string)
|
||||
=================
|
||||
*/
|
||||
void PF_strunzone (void)
|
||||
{
|
||||
Z_Free(G_STRING(OFS_PARM0));
|
||||
G_INT(OFS_PARM0) = OFS_NULL; // empty the def
|
||||
};
|
||||
|
||||
/*
|
||||
=================
|
||||
PF_strtrim
|
||||
|
||||
string strtrim (string)
|
||||
=================
|
||||
*/
|
||||
void PF_strtrim (void)
|
||||
{
|
||||
char *m;
|
||||
m = G_STRING(OFS_PARM0);
|
||||
|
||||
char *c;
|
||||
c = m;
|
||||
|
||||
while (c != '\0' && *c == ' ')
|
||||
c++;
|
||||
m = c;
|
||||
|
||||
c = m + strlen (m) - 1;
|
||||
while (c >= m)
|
||||
{
|
||||
if (*c == ' ')
|
||||
*c = '\0';
|
||||
else
|
||||
break;
|
||||
c--;
|
||||
}
|
||||
G_INT(OFS_RETURN) = m - pr_strings;
|
||||
};
|
||||
|
||||
/*
|
||||
=================
|
||||
PF_strlen
|
||||
|
||||
float strlen (string)
|
||||
=================
|
||||
*/
|
||||
void PF_strlen (void)
|
||||
{
|
||||
char *p = G_STRING(OFS_PARM0);
|
||||
G_FLOAT(OFS_RETURN) = strlen(p);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
PF_strcat
|
||||
|
||||
string strcat (string, string)
|
||||
=================
|
||||
*/
|
||||
|
||||
void PF_strcat (void)
|
||||
{
|
||||
char *s1, *s2;
|
||||
int maxlen; // 2001-10-25 Enhanced temp string handling by Maddes
|
||||
|
||||
s1 = G_STRING(OFS_PARM0);
|
||||
s2 = PF_VarString(1);
|
||||
|
||||
// 2001-10-25 Enhanced temp string handling by Maddes start
|
||||
pr_string_temp[0] = 0;
|
||||
if (strlen(s1) < PR_MAX_TEMPSTRING)
|
||||
{
|
||||
strcpy(pr_string_temp, s1);
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(pr_string_temp, s1, PR_MAX_TEMPSTRING);
|
||||
pr_string_temp[PR_MAX_TEMPSTRING-1] = 0;
|
||||
}
|
||||
|
||||
maxlen = PR_MAX_TEMPSTRING - strlen(pr_string_temp) - 1; // -1 is EndOfString
|
||||
if (maxlen > 0)
|
||||
{
|
||||
if (maxlen > strlen(s2))
|
||||
{
|
||||
strcat (pr_string_temp, s2);
|
||||
}
|
||||
else
|
||||
{
|
||||
strncat (pr_string_temp, s2, maxlen);
|
||||
pr_string_temp[PR_MAX_TEMPSTRING-1] = 0;
|
||||
}
|
||||
}
|
||||
// 2001-10-25 Enhanced temp string handling by Maddes end
|
||||
|
||||
G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
PF_substring
|
||||
|
||||
string substring (string, float, float)
|
||||
=================
|
||||
*/
|
||||
void PF_substring (void)
|
||||
{
|
||||
int offset, length;
|
||||
int maxoffset; // 2001-10-25 Enhanced temp string handling by Maddes
|
||||
char *p;
|
||||
|
||||
p = G_STRING(OFS_PARM0);
|
||||
offset = (int)G_FLOAT(OFS_PARM1); // for some reason, Quake doesn't like G_INT
|
||||
length = (int)G_FLOAT(OFS_PARM2);
|
||||
|
||||
// cap values
|
||||
maxoffset = strlen(p);
|
||||
if (offset > maxoffset)
|
||||
{
|
||||
offset = maxoffset;
|
||||
}
|
||||
if (offset < 0)
|
||||
offset = 0;
|
||||
// 2001-10-25 Enhanced temp string handling by Maddes start
|
||||
if (length >= PR_MAX_TEMPSTRING)
|
||||
length = PR_MAX_TEMPSTRING-1;
|
||||
// 2001-10-25 Enhanced temp string handling by Maddes end
|
||||
if (length < 0)
|
||||
length = 0;
|
||||
|
||||
p += offset;
|
||||
strncpy(pr_string_temp, p, length);
|
||||
pr_string_temp[length]=0;
|
||||
|
||||
G_INT(OFS_RETURN) = pr_string_temp - pr_strings;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
PF_stof
|
||||
|
||||
float stof (string)
|
||||
=================
|
||||
*/
|
||||
// thanks Zoid, taken from QuakeWorld
|
||||
void PF_stof (void)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = G_STRING(OFS_PARM0);
|
||||
G_FLOAT(OFS_RETURN) = atof(s);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
PF_stov
|
||||
|
||||
vector stov (string)
|
||||
=================
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
PF_Set_Zombie
|
||||
|
||||
void Set_Zombie (entity)
|
||||
=================
|
||||
*/
|
||||
void PF_Set_Zombie (void)
|
||||
{
|
||||
//int entitynum = G_EDICT(OFS_PARM0);
|
||||
}
|
||||
|
||||
|
||||
// entity (entity start, .string field, string match) find = #5;
|
||||
void PF_Find (void)
|
||||
|
@ -1053,6 +1449,38 @@ void PF_Find (void)
|
|||
}
|
||||
#endif
|
||||
|
||||
// entity (entity start, .float field, float match) findfloat = #98;
|
||||
void PF_FindFloat (void)
|
||||
{
|
||||
int e;
|
||||
int f;
|
||||
float s, t;
|
||||
edict_t *ed;
|
||||
|
||||
e = G_EDICTNUM(OFS_PARM0);
|
||||
f = G_INT(OFS_PARM1);
|
||||
s = G_FLOAT(OFS_PARM2);
|
||||
if (!s)
|
||||
PR_RunError ("PF_FindFloat: bad search float");
|
||||
|
||||
for (e++ ; e < sv.num_edicts ; e++)
|
||||
{
|
||||
ed = EDICT_NUM(e);
|
||||
if (ed->free)
|
||||
continue;
|
||||
t = E_FLOAT(ed,f);
|
||||
if (!t)
|
||||
continue;
|
||||
if (t == s)
|
||||
{
|
||||
RETURN_EDICT(ed);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_EDICT(sv.edicts);
|
||||
}
|
||||
|
||||
void PR_CheckEmptyString (char *s)
|
||||
{
|
||||
if (s[0] <= ' ')
|
||||
|
@ -1446,6 +1874,50 @@ void PF_changeyaw (void)
|
|||
ent->v.angles[1] = anglemod (current + move);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
PF_GetSoundLen
|
||||
|
||||
Get the lenght of the sound (useful for things like radio)
|
||||
==============
|
||||
*/
|
||||
void PF_GetSoundLen (void)
|
||||
{
|
||||
|
||||
char *name;
|
||||
|
||||
name = G_STRING(OFS_PARM0);
|
||||
|
||||
char namebuffer[256];
|
||||
byte *data;
|
||||
wavinfo_t info;
|
||||
byte stackbuf[1*1024]; // avoid dirtying the cache heap
|
||||
|
||||
//Con_Printf ("S_LoadSound: %x\n", (int)stackbuf);
|
||||
// load it in
|
||||
Q_strcpy(namebuffer, "");
|
||||
Q_strcat(namebuffer, name);
|
||||
|
||||
data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf));
|
||||
|
||||
if (!data)
|
||||
{
|
||||
Con_Printf ("Couldn't load %s\n", namebuffer);
|
||||
G_FLOAT(OFS_RETURN) = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
info = GetWavinfo (name, data, com_filesize);
|
||||
if (info.channels != 1)
|
||||
{
|
||||
Con_Printf ("%s is a stereo sample\n",name);
|
||||
G_FLOAT(OFS_RETURN) = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
G_FLOAT(OFS_RETURN) = (float)info.samples/(float)info.rate;
|
||||
}
|
||||
|
||||
#ifdef QUAKE2
|
||||
/*
|
||||
==============
|
||||
|
@ -1665,144 +2137,6 @@ void PF_changelevel (void)
|
|||
}
|
||||
|
||||
|
||||
#ifdef QUAKE2
|
||||
|
||||
#define CONTENT_WATER -3
|
||||
#define CONTENT_SLIME -4
|
||||
#define CONTENT_LAVA -5
|
||||
|
||||
#define FL_IMMUNE_WATER 131072
|
||||
#define FL_IMMUNE_SLIME 262144
|
||||
#define FL_IMMUNE_LAVA 524288
|
||||
|
||||
#define CHAN_VOICE 2
|
||||
#define CHAN_BODY 4
|
||||
|
||||
#define ATTN_NORM 1
|
||||
|
||||
void PF_WaterMove (void)
|
||||
{
|
||||
edict_t *self;
|
||||
int flags;
|
||||
int waterlevel;
|
||||
int watertype;
|
||||
float drownlevel;
|
||||
float damage = 0.0;
|
||||
|
||||
self = PROG_TO_EDICT(pr_global_struct->self);
|
||||
|
||||
if (self->v.movetype == MOVETYPE_NOCLIP)
|
||||
{
|
||||
self->v.air_finished = sv.time + 12;
|
||||
G_FLOAT(OFS_RETURN) = damage;
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->v.health < 0)
|
||||
{
|
||||
G_FLOAT(OFS_RETURN) = damage;
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->v.deadflag == DEAD_NO)
|
||||
drownlevel = 3;
|
||||
else
|
||||
drownlevel = 1;
|
||||
|
||||
flags = (int)self->v.flags;
|
||||
waterlevel = (int)self->v.waterlevel;
|
||||
watertype = (int)self->v.watertype;
|
||||
|
||||
if (!(flags & (FL_IMMUNE_WATER + FL_GODMODE)))
|
||||
if (((flags & FL_SWIM) && (waterlevel < drownlevel)) || (waterlevel >= drownlevel))
|
||||
{
|
||||
if (self->v.air_finished < sv.time)
|
||||
if (self->v.pain_finished < sv.time)
|
||||
{
|
||||
self->v.dmg = self->v.dmg + 2;
|
||||
if (self->v.dmg > 15)
|
||||
self->v.dmg = 10;
|
||||
// T_Damage (self, world, world, self.dmg, 0, FALSE);
|
||||
damage = self->v.dmg;
|
||||
self->v.pain_finished = sv.time + 1.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self->v.air_finished < sv.time)
|
||||
// sound (self, CHAN_VOICE, "player/gasp2.wav", 1, ATTN_NORM);
|
||||
SV_StartSound (self, CHAN_VOICE, "player/gasp2.wav", 255, ATTN_NORM);
|
||||
else if (self->v.air_finished < sv.time + 9)
|
||||
// sound (self, CHAN_VOICE, "player/gasp1.wav", 1, ATTN_NORM);
|
||||
SV_StartSound (self, CHAN_VOICE, "player/gasp1.wav", 255, ATTN_NORM);
|
||||
self->v.air_finished = sv.time + 12.0;
|
||||
self->v.dmg = 2;
|
||||
}
|
||||
|
||||
if (!waterlevel)
|
||||
{
|
||||
if (flags & FL_INWATER)
|
||||
{
|
||||
// play leave water sound
|
||||
// sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM);
|
||||
SV_StartSound (self, CHAN_BODY, "misc/outwater.wav", 255, ATTN_NORM);
|
||||
self->v.flags = (float)(flags &~FL_INWATER);
|
||||
}
|
||||
self->v.air_finished = sv.time + 12.0;
|
||||
G_FLOAT(OFS_RETURN) = damage;
|
||||
return;
|
||||
}
|
||||
|
||||
if (watertype == CONTENT_LAVA)
|
||||
{ // do damage
|
||||
if (!(flags & (FL_IMMUNE_LAVA + FL_GODMODE)))
|
||||
if (self->v.dmgtime < sv.time)
|
||||
{
|
||||
if (self->v.radsuit_finished < sv.time)
|
||||
self->v.dmgtime = sv.time + 0.2;
|
||||
else
|
||||
self->v.dmgtime = sv.time + 1.0;
|
||||
// T_Damage (self, world, world, 10*self.waterlevel, 0, TRUE);
|
||||
damage = (float)(10*waterlevel);
|
||||
}
|
||||
}
|
||||
else if (watertype == CONTENT_SLIME)
|
||||
{ // do damage
|
||||
if (!(flags & (FL_IMMUNE_SLIME + FL_GODMODE)))
|
||||
if (self->v.dmgtime < sv.time && self->v.radsuit_finished < sv.time)
|
||||
{
|
||||
self->v.dmgtime = sv.time + 1.0;
|
||||
// T_Damage (self, world, world, 4*self.waterlevel, 0, TRUE);
|
||||
damage = (float)(4*waterlevel);
|
||||
}
|
||||
}
|
||||
|
||||
if ( !(flags & FL_INWATER) )
|
||||
{
|
||||
|
||||
// player enter water sound
|
||||
if (watertype == CONTENT_LAVA)
|
||||
// sound (self, CHAN_BODY, "player/inlava.wav", 1, ATTN_NORM);
|
||||
SV_StartSound (self, CHAN_BODY, "player/inlava.wav", 255, ATTN_NORM);
|
||||
if (watertype == CONTENT_WATER)
|
||||
// sound (self, CHAN_BODY, "player/inh2o.wav", 1, ATTN_NORM);
|
||||
SV_StartSound (self, CHAN_BODY, "player/inh2o.wav", 255, ATTN_NORM);
|
||||
if (watertype == CONTENT_SLIME)
|
||||
// sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM);
|
||||
SV_StartSound (self, CHAN_BODY, "player/slimbrn2.wav", 255, ATTN_NORM);
|
||||
|
||||
self->v.flags = (float)(flags | FL_INWATER);
|
||||
self->v.dmgtime = 0;
|
||||
}
|
||||
|
||||
if (! (flags & FL_WATERJUMP) )
|
||||
{
|
||||
// self.velocity = self.velocity - 0.8*self.waterlevel*frametime*self.velocity;
|
||||
VectorMA (self->v.velocity, -0.8 * self->v.waterlevel * host_frametime, self->v.velocity, self->v.velocity);
|
||||
}
|
||||
|
||||
G_FLOAT(OFS_RETURN) = damage;
|
||||
}
|
||||
|
||||
|
||||
void PF_sin (void)
|
||||
|
@ -1819,13 +2153,34 @@ void PF_sqrt (void)
|
|||
{
|
||||
G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
|
||||
}
|
||||
#endif
|
||||
|
||||
void PF_Fixme (void)
|
||||
{
|
||||
PR_RunError ("unimplemented bulitin");
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
PF_updateLimb
|
||||
|
||||
updates zombies limb
|
||||
|
||||
PF_updateLimb(zombieent, value. limbent)
|
||||
=================
|
||||
*/
|
||||
void PF_updateLimb (void)
|
||||
{
|
||||
int limb;
|
||||
int zombieent, limbent;
|
||||
|
||||
zombieent = G_EDICTNUM(OFS_PARM0);
|
||||
limb = G_FLOAT(OFS_PARM1);
|
||||
limbent = G_EDICTNUM(OFS_PARM2);
|
||||
MSG_WriteByte (&sv.reliable_datagram, svc_limbupdate);
|
||||
MSG_WriteByte (&sv.reliable_datagram, limb);
|
||||
MSG_WriteShort (&sv.reliable_datagram, zombieent);
|
||||
MSG_WriteShort (&sv.reliable_datagram, limbent);
|
||||
}
|
||||
|
||||
|
||||
builtin_t pr_builtin[] =
|
||||
|
@ -1863,7 +2218,7 @@ PF_traceon,
|
|||
PF_traceoff,
|
||||
PF_eprint, // void(entity e) debug print an entire entity
|
||||
PF_walkmove, // float(float yaw, float dist) walkmove
|
||||
PF_Fixme, // float(float yaw, float dist) walkmove
|
||||
PF_updateLimb, // #33
|
||||
PF_droptofloor,
|
||||
PF_lightstyle,
|
||||
PF_rint,
|
||||
|
@ -1880,7 +2235,7 @@ PF_localcmd,
|
|||
PF_nextent,
|
||||
PF_particle,
|
||||
PF_changeyaw,
|
||||
PF_Fixme,
|
||||
PF_GetSoundLen,
|
||||
PF_vectoangles,
|
||||
|
||||
PF_WriteByte,
|
||||
|
@ -1892,30 +2247,20 @@ PF_WriteAngle,
|
|||
PF_WriteString,
|
||||
PF_WriteEntity,
|
||||
|
||||
#ifdef QUAKE2
|
||||
PF_sin,
|
||||
PF_cos,
|
||||
PF_sqrt,
|
||||
PF_changepitch,
|
||||
PF_TraceToss,
|
||||
PF_Fixme,//PF_changepitch,
|
||||
PF_Fixme,//PF_TraceToss,
|
||||
PF_etos,
|
||||
PF_WaterMove,
|
||||
#else
|
||||
PF_Fixme,
|
||||
PF_Fixme,
|
||||
PF_Fixme,
|
||||
PF_Fixme,
|
||||
PF_Fixme,
|
||||
PF_Fixme,
|
||||
PF_Fixme,
|
||||
#endif
|
||||
PF_Fixme,//PF_WaterMove,
|
||||
|
||||
SV_MoveToGoal,
|
||||
PF_precache_file,
|
||||
PF_makestatic,
|
||||
|
||||
PF_changelevel,
|
||||
PF_Fixme,
|
||||
SV_MoveToOrigin, // #71
|
||||
|
||||
PF_cvar_set,
|
||||
PF_centerprint,
|
||||
|
@ -1926,7 +2271,31 @@ PF_precache_model,
|
|||
PF_precache_sound, // precache_sound2 is different only for qcc
|
||||
PF_precache_file,
|
||||
|
||||
PF_setspawnparms
|
||||
PF_setspawnparms,
|
||||
PF_Fixme, // #79
|
||||
PF_Fixme, // #80
|
||||
PF_stof, // #81
|
||||
PF_Fixme, // #82
|
||||
PF_Fixme, // #83
|
||||
PF_Fixme, // #84
|
||||
PF_Fixme, // #86
|
||||
PF_Fixme, // #87
|
||||
PF_Fixme, // #88
|
||||
PF_Fixme, // #89
|
||||
PF_tracebox, // #90
|
||||
PF_Fixme, // #91
|
||||
PF_Fixme, // #92
|
||||
PF_Fixme, // #93
|
||||
PF_Fixme, // #94
|
||||
PF_Fixme, // #95
|
||||
PF_Fixme, // #96
|
||||
PF_Fixme, // #97
|
||||
PF_FindFloat, // #98
|
||||
PF_tracemove, // #99
|
||||
PF_Fixme, // #100
|
||||
PF_Fixme, // #101
|
||||
PF_Fixme, // #102
|
||||
PF_Fixme, // #103
|
||||
};
|
||||
|
||||
builtin_t *pr_builtins = pr_builtin;
|
||||
|
|
|
@ -129,6 +129,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define svc_sellscreen 33
|
||||
|
||||
#define svc_cutscene 34
|
||||
#define svc_weaponfire 35
|
||||
#define svc_hitmark 36
|
||||
#define svc_skybox 37 // [string] skyname
|
||||
#define svc_useprint 38 // [string] to put in center of the screen
|
||||
#define svc_updatekills 39 // [string] to put in center of the screen
|
||||
#define svc_limbupdate 40
|
||||
#define svc_fog 41 // [byte] start [byte] end [byte] red [byte] green [byte] blue [float] time
|
||||
#define svc_bspdecal 42 // [string] name [byte] decal_size [coords] pos
|
||||
#define svc_achievement 43 // [string] name [byte] decal_size [coords] pos
|
||||
#define svc_songegg 44 // [string] track name
|
||||
#define svc_maxammo 45
|
||||
|
||||
//
|
||||
// client to server
|
||||
|
|
|
@ -67,6 +67,11 @@ typedef struct entity_s
|
|||
struct mnode_s *topnode; // for bmodels, first world node
|
||||
// that splits bmodel, or NULL if
|
||||
// not split
|
||||
|
||||
int z_head;
|
||||
int z_larm;
|
||||
int z_rarm;
|
||||
|
||||
} entity_t;
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
|
|
|
@ -246,6 +246,7 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink);
|
|||
void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg);
|
||||
|
||||
void SV_MoveToGoal (void);
|
||||
void SV_MoveToOrigin (void);
|
||||
|
||||
void SV_CheckForNewClients (void);
|
||||
void SV_RunClients (void);
|
||||
|
|
|
@ -425,3 +425,33 @@ void SV_MoveToGoal (void)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
SV_MoveToOrigin
|
||||
|
||||
======================
|
||||
*/
|
||||
void SV_MoveToOrigin (void)
|
||||
{
|
||||
edict_t *ent, *goal;
|
||||
float dist;
|
||||
|
||||
ent = PROG_TO_EDICT(pr_global_struct->self);
|
||||
goal = PROG_TO_EDICT(ent->v.goalentity);
|
||||
dist = G_FLOAT(OFS_PARM0);
|
||||
|
||||
if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
|
||||
{
|
||||
G_FLOAT(OFS_RETURN) = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// if the next step hits the enemy, return immediately
|
||||
if ( PROG_TO_EDICT(ent->v.enemy) != sv.edicts && SV_CloseEnough (ent, goal, dist) )
|
||||
return;
|
||||
|
||||
// bump around...
|
||||
if ((rand()&3)==1 || !SV_StepDirection (ent, ent->v.ideal_yaw, dist))
|
||||
SV_NewChaseDir (ent, goal, dist);
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue