Rotating BSP fixes, hexen2 fixes, and a few extra bugs...

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2134 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2006-03-23 19:22:12 +00:00
parent 43872108b9
commit b5b74f2529
21 changed files with 203 additions and 69 deletions

View File

@ -1742,7 +1742,8 @@ void CL_LinkPacketEntities (void)
}
VectorCopy(angles, ent->angles);
angles[0]*=-1;
if (model && model->type == mod_alias)
angles[0]*=-1; //carmack screwed up when he added alias models - they pitch the wrong way.
AngleVectors(angles, ent->axis[0], ent->axis[1], ent->axis[2]);
VectorInverse(ent->axis[1]);

View File

@ -544,6 +544,9 @@ void PF_CL_drawgetimagesize (progfuncs_t *prinst, struct globalvars_s *pr_global
float *ret = G_VECTOR(OFS_RETURN);
if (!p)
p = Draw_SafeCachePic(va("%s.tga", picname));
if (p)
{
ret[0] = p->width;

View File

@ -686,7 +686,7 @@ cvar_t *Cvar_SetCore (cvar_t *var, const char *value, qboolean force)
}
#endif
latch = var->string;
latch = var->string;//save off the old value (so cvar_set(var, var->string) works)
var->string = (char*)Z_Malloc (Q_strlen(value)+1);
Q_strcpy (var->string, value);
@ -920,13 +920,19 @@ void Cvar_RegisterVariable (cvar_t *variable)
cvar_t *Cvar_Get(const char *name, const char *defaultvalue, int flags, const char *group)
{
cvar_t *var;
int old;
var = Cvar_FindVar(name);
if (var)
{
//allow this to change all < cvar_latch values.
//this allows q2 dlls to apply different flags to a cvar without destroying our important ones (like cheat).
old = var->flags;
var->flags = (var->flags & ~(CVAR_NOSET)) | (flags & (CVAR_NOSET|CVAR_SERVERINFO|CVAR_USERINFO|CVAR_ARCHIVE));
if (old != var->flags)
{
Cvar_Set(var, var->string);
}
return var;
}

View File

@ -1765,24 +1765,26 @@ vfsfile_t *FS_OpenTCP(char *name)
{
tcpfile_t *newf;
int sock;
netadr_t adr;
if (!NET_StringToAdr(name, &adr))
netadr_t adr = {0};
if (NET_StringToAdr(name, &adr))
{
sock = TCP_OpenStream(adr);
if (sock == INVALID_SOCKET)
return NULL;
newf = Z_Malloc(sizeof(*newf));
newf->sock = sock;
newf->funcs.Close = VFSTCP_Close;
newf->funcs.Flush = NULL;
newf->funcs.GetLen = VFSTCP_GetLen;
newf->funcs.ReadBytes = VFSTCP_ReadBytes;
newf->funcs.Seek = VFSTCP_Seek;
newf->funcs.Tell = VFSTCP_Tell;
newf->funcs.WriteBytes = VFSTCP_WriteBytes;
newf->funcs.seekingisabadplan = true;
return &newf->funcs;
}
else
return NULL;
sock = TCP_OpenStream(adr);
if (sock == INVALID_SOCKET)
return NULL;
newf = Z_Malloc(sizeof(*newf));
newf->sock = sock;
newf->funcs.Close = VFSTCP_Close;
newf->funcs.Flush = NULL;
newf->funcs.GetLen = VFSTCP_GetLen;
newf->funcs.ReadBytes = VFSTCP_ReadBytes;
newf->funcs.Seek = VFSTCP_Seek;
newf->funcs.Tell = VFSTCP_Tell;
newf->funcs.WriteBytes = VFSTCP_WriteBytes;
newf->funcs.seekingisabadplan = true;
return &newf->funcs;
}

View File

@ -199,9 +199,9 @@ qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t end, trac
if (trace->fraction != 1.0)
{
a[0] = angles[0];
a[1] = angles[1];
a[2] = angles[2];
a[0] = -angles[0];
a[1] = -angles[1];
a[2] = -angles[2];
AngleVectors (a, forward, right, up);
VectorCopy (trace->plane.normal, temp);

View File

@ -3064,6 +3064,8 @@ SOURCE=..\gl\gl_bloom.c
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# PROP Exclude_From_Build 1

View File

@ -2194,7 +2194,7 @@ qboolean GLMod_LoadClipnodes (lump_t *l)
hull->planes = loadmodel->planes;
hull->clip_mins[0] = -48;
hull->clip_mins[1] = -48;
hull->clip_mins[2] = -50;
hull->clip_mins[2] = -50 - 24;
hull->clip_maxs[0] = 48;
hull->clip_maxs[1] = 48;
hull->clip_maxs[2] = 50;

View File

@ -1731,12 +1731,25 @@ void PPL_BaseBModelTextures(entity_t *e)
currentmodel = model = e->model;
s = model->surfaces+model->firstmodelsurface;
GL_TexEnv(GL_MODULATE);
if (currententity->drawflags & DRF_TRANSLUCENT)
currententity->shaderRGBAf[3]=0.5;
if ((currententity->drawflags & MLS_ABSLIGHT) == MLS_ABSLIGHT)
{
currententity->shaderRGBAf[0] =
currententity->shaderRGBAf[1] =
currententity->shaderRGBAf[2] = currententity->abslight/255.0f;
}
if (currententity->shaderRGBAf[3]<1)
{
GL_TexEnv(GL_MODULATE);
qglEnable(GL_BLEND);
}
else
{
GL_TexEnv(GL_REPLACE);
qglDisable(GL_BLEND);
}
qglColor4fv(currententity->shaderRGBAf);

View File

@ -711,6 +711,13 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
float scale;
int maps;
if (!cl.worldmodel->lightdata)
{
l[0]=255;l[1]=255;l[2]=255;
l[3]=0;l[4]=1;l[5]=1;
return l;
}
if (cl.worldmodel->fromgame == fg_quake2)
{
if (node->contents != -1)

View File

@ -259,6 +259,18 @@ void GLR_AddStain(vec3_t org, float red, float green, float blue, float radius)
parms[1] = org[0] - pe->origin[0];
parms[2] = org[1] - pe->origin[1];
parms[3] = org[2] - pe->origin[2];
if (pe->angles[0] || pe->angles[1] || pe->angles[2])
{
vec3_t f, r, u, temp;
AngleVectors(pe->angles, f, r, u);
VectorCopy((parms+1), temp);
parms[1] = DotProduct(temp, f);
parms[2] = -DotProduct(temp, r);
parms[3] = DotProduct(temp, u);
}
pe->model->funcs.StainNode(pe->model->nodes+pe->model->hulls[0].firstclipnode, parms);
}
}

View File

@ -2674,9 +2674,13 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
e = QCC_PR_Statement(pr_opcodes+OP_CONV_FTOI, e, NULL, NULL);
else if (p->type == ev_float && e->type->type == ev_integer) //convert float -> int... is this a constant?
e = QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, e, NULL, NULL);
else if (p->type == ev_function && e->type->type == ev_integer && e->constant && !((int*)qcc_pr_globals)[e->ofs])
{ //you're allowed to use int 0 to pass a null function pointer
//this is basically because __NULL__ is defined as ~0 (int 0)
}
else if (p->type != ev_variant) //can cast to variant whatever happens
{
if (flag_laxcasts)
if (flag_laxcasts || (p->type == ev_function && e->type->type == ev_function))
{
QCC_PR_ParseWarning(WARN_LAXCAST, "type mismatch on parm %i - (%s should be %s)", arg+1, TypeName(e->type), TypeName(p));
QCC_PR_ParsePrintDef(WARN_LAXCAST, func);

View File

@ -162,18 +162,34 @@ void QCC_FindBestInclude(char *newfile, char *currentfile, char *rootpath)
{
char fullname[10248];
char *stripfrom;
int doubledots;
char *end = fullname;
if (!*newfile)
return;
doubledots = 0;
while(!strncmp(newfile, "../", 3) || !strncmp(newfile, "..\\", 3))
{
newfile+=3;
doubledots++;
}
currentfile += strlen(rootpath); //could this be bad?
for(stripfrom = currentfile+strlen(currentfile)-1; stripfrom>currentfile; stripfrom--)
{
if (*stripfrom == '/' || *stripfrom == '\\')
break;
{
if (doubledots>0)
doubledots--;
else
{
stripfrom++;
break;
}
}
}
strcpy(end, rootpath); end = end+strlen(end);
if (*fullname && end[-1] != '/')

View File

@ -114,6 +114,7 @@ func_t pr_SV_ShouldPause;
func_t SV_PlayerPhysicsQC; //DP's DP_SV_PLAYERPHYSICS extension
func_t EndFrameQC;
func_t pr_ClassChangeWeapon;
qboolean pr_items2;
@ -540,6 +541,7 @@ void PR_LoadGlabalStruct(void)
pr_SV_PausedTic = PR_FindFunction(svprogfuncs, "SV_PausedTic", PR_ANY);
pr_SV_ShouldPause = PR_FindFunction(svprogfuncs, "SV_ShouldPause", PR_ANY);
pr_ClassChangeWeapon = PR_FindFunction(svprogfuncs, "ClassChangeWeapon", PR_ANY);
if (pr_no_playerphysics.value)
SV_PlayerPhysicsQC = 0;
@ -1262,7 +1264,7 @@ void Q_InitProgs(void)
if (f)
{
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
G_INT(OFS_PARM0) = (int)PR_SetString(svprogfuncs, as);
G_INT(OFS_PARM0) = (int)PR_SetString(svprogfuncs, sv_addon[i2].string);
PR_ExecuteProgram (svprogfuncs, f);
}
else
@ -1328,7 +1330,7 @@ qboolean PR_ShouldTogglePause(client_t *initiator, qboolean newpaused)
globalvars_t *pr_globals;
if (!svprogfuncs || !pr_SV_ShouldPause)
return false;
return true;
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
@ -7478,6 +7480,32 @@ void PF_advanceweaponframe (progfuncs_t *prinst, struct globalvars_s *pr_globals
G_FLOAT(OFS_RETURN) = state;
}
void PR_SetPlayerClass(client_t *cl, int classnum, qboolean fromqc)
{
char temp[16];
if (classnum < 1)
return; //reject it (it would crash the (standard hexen2) mod)
if (classnum > 5)
return;
if (cl->playerclass != classnum)
{
cl->edict->v->playerclass = classnum;
cl->playerclass = classnum;
sprintf(temp,"%i",(int)classnum);
Info_SetValueForKey (cl->userinfo, "cl_playerclass", temp, sizeof(cl->userinfo));
if (!fromqc)
{
cl->sendinfo = true;
if (cl->state == cs_spawned && pr_ClassChangeWeapon)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
PR_ExecuteProgram (svprogfuncs, pr_ClassChangeWeapon);
}
}
}
}
void PF_setclass (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{

View File

@ -129,7 +129,7 @@ typedef enum {
// ClientCommand and ServerCommand parameter access
G_ARGV, // ( int n, char *buffer, int bufferLength );
//10
G_FS_FOPEN_FILE, // ( const char *qpath, fileHandle_t *file, fsMode_t mode );
G_FS_READ, // ( void *buffer, int len, fileHandle_t f );
G_FS_WRITE, // ( const void *buffer, int len, fileHandle_t f );
@ -162,7 +162,7 @@ typedef enum {
// All confgstrings are cleared at each level start.
G_GET_CONFIGSTRING, // ( int num, char *buffer, int bufferSize );
//20
G_GET_USERINFO, // ( int num, char *buffer, int bufferSize );
// userinfo strings are maintained by the server system, so they
// are persistant across level loads, while all other game visible
@ -189,7 +189,7 @@ typedef enum {
G_ADJUST_AREA_PORTAL_STATE, // ( gentity_t *ent, qboolean open );
G_AREAS_CONNECTED, // ( int area1, int area2 );
//30
G_LINKENTITY, // ( gentity_t *ent );
// an entity will never be sent to a client or used for collision
// if it is not passed to linkentity. If the size, position, or
@ -219,6 +219,7 @@ typedef enum {
G_FS_GETFILELIST,
G_DEBUG_POLYGON_CREATE,
//40
G_DEBUG_POLYGON_DELETE,
G_REAL_TIME,
G_SNAPVECTOR,

View File

@ -119,7 +119,10 @@ void Chat_GetTag(char *filename, float tag, char **text, char **condition, char
}
}
}
Sys_Error("Tag %f not found in file %s", tag, host_client->chat.filename);
*text = va("Chat Tag %f not found in file %s", tag, host_client->chat.filename);
*condition = "";
*options = "";
return;
}
chatvar_t *SV_ChatFindVariable(char *name)

View File

@ -2546,8 +2546,6 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
state->modelindex = SV_ModelIndex(modname);
}
}
if (/*progstype == PROG_H2 &&*/ ent->v->solid == SOLID_BSP)
state->angles[0]*=-1;
if (state->effects & EF_FULLBRIGHT)
{

View File

@ -1022,6 +1022,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
if (progstype == PROG_H2)
{
cvar_t *cv;
if (coop.value)
{
eval = PR_FindGlobal(svprogfuncs, "coop", 0);
@ -1032,11 +1033,13 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
eval = PR_FindGlobal(svprogfuncs, "deathmatch", 0);
if (eval) eval->_float = deathmatch.value;
}
cv = Cvar_Get("randomclass", "0", CVAR_LATCH, "Hexen2");
eval = PR_FindGlobal(svprogfuncs, "randomclass", 0);
if (eval) eval->_float = Cvar_Get("randomclass", "1", CVAR_LATCH, "Hexen2 rules")->value;
if (eval && cv) eval->_float = cv->value;
cv = Cvar_Get("cl_playerclass", "1", CVAR_USERINFO|CVAR_ARCHIVE, "Hexen2");
eval = PR_FindGlobal(svprogfuncs, "cl_playerclass", 0);
if (eval) eval->_float = 1;
if (eval && cv) eval->_float = cv->value;
}
else
{
@ -1078,6 +1081,8 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
spawnflagmask |= SPAWNFLAG_NOT_H2HARD;
else
spawnflagmask |= SPAWNFLAG_NOT_H2MEDIUM;
//don't filter based on player class. we're lame and don't have any real concept of player classes.
}
else if (!deathmatch.value) //decide if we are to inhibit single player game ents instead
{

View File

@ -3721,6 +3721,12 @@ void SV_ExtractFromUserinfo (client_t *cl)
else
cl->drate = 0; //0 disables the downloading check
val = Info_ValueForKey (cl->userinfo, "cl_playerclass");
if (val)
{
PR_SetPlayerClass(cl, atoi(val), false);
}
// msg command
val = Info_ValueForKey (cl->userinfo, "msg");
if (strlen(val))

View File

@ -72,7 +72,10 @@ realcheck:
start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
stop[2] = start[2] - 2*pm_stepheight;
savedhull = ent->v->hull;
ent->v->hull = 0;
trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, ent);
ent->v->hull = savedhull;
if (trace.fraction == 1.0)
return false;

View File

@ -114,13 +114,13 @@ void DestFlush(qboolean compleate)
break;
case DEST_STREAM:
if (d->cacheused)
if (d->cacheused && !d->error)
{
len = send(d->socket, d->cache, d->cacheused, 0);
if (len == 0) //client died
d->error = true;
else if (len > 0) //error of some kind
{
else if (len > 0) //we put some data through
{ //move up the buffer
d->cacheused -= len;
memmove(d->cache, d->cache+len, d->cacheused);
}

View File

@ -389,26 +389,42 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
if (ent->v->solid == SOLID_BSP &&
(ent->v->angles[0] || ent->v->angles[1] || ent->v->angles[2]) )
{ // expand for rotation
#if 1
int i;
float v;
float max, min;
//q2 method
max = 0;
for (i=0 ; i<3 ; i++)
{
v =fabs( ent->v->mins[i]);
if (v > max)
max = v;
v =fabs( ent->v->maxs[i]);
if (v > max)
max = v;
}
for (i=0 ; i<3 ; i++)
{
ent->v->absmin[i] = ent->v->origin[i] - max;
ent->v->absmax[i] = ent->v->origin[i] + max;
}
#else
int i;
vec3_t f, r, u;
vec3_t mn, mx;
//we need to link to the correct leaves
if (progstype == PROG_H2)
{
ent->v->angles[0]*=-1;
AngleVectors(ent->v->angles, f,r,u);
ent->v->angles[0]*=-1;
}
else
AngleVectors(ent->v->angles, f,r,u);
AngleVectors(ent->v->angles, f,r,u);
mn[0] = DotProduct(ent->v->mins, f);
mn[1] = -DotProduct(ent->v->mins, r);
mn[2] = DotProduct(ent->v->mins, u);
mx[0] = DotProduct(ent->v->maxs, f);
mx[1] = -DotProduct(ent->v->maxs, r);
mx[2] = DotProduct(ent->v->maxs, u);
@ -425,6 +441,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
ent->v->absmax[i] = ent->v->origin[i]+mn[i]+0.1;
}
}
#endif
}
else
{
@ -959,22 +976,29 @@ qboolean TransformedTrace (struct model_s *model, int hulloverride, int frame, v
if (rotated)
{
// FIXME: figure out how to do this with existing angles
// VectorNegate (angles, a);
a[0] = -angles[0];
a[1] = -angles[1];
a[2] = -angles[2];
AngleVectors (a, forward, right, up);
VectorCopy (trace->plane.normal, temp);
trace->plane.normal[0] = DotProduct (temp, forward);
trace->plane.normal[1] = -DotProduct (temp, right);
trace->plane.normal[2] = DotProduct (temp, up);
if (trace->fraction != 1)
{
VectorNegate (angles, a);
AngleVectors (a, forward, right, up);
trace->endpos[0] = start[0] + trace->fraction * (end[0] - start[0]);
trace->endpos[1] = start[1] + trace->fraction * (end[1] - start[1]);
trace->endpos[2] = start[2] + trace->fraction * (end[2] - start[2]);
VectorCopy (trace->plane.normal, temp);
trace->plane.normal[0] = DotProduct (temp, forward);
trace->plane.normal[1] = -DotProduct (temp, right);
trace->plane.normal[2] = DotProduct (temp, up);
trace->endpos[0] = start[0] + trace->fraction * (end[0] - start[0]);
trace->endpos[1] = start[1] + trace->fraction * (end[1] - start[1]);
trace->endpos[2] = start[2] + trace->fraction * (end[2] - start[2]);
}
else
{
VectorCopy (end, trace->endpos);
}
}
VectorAdd (trace->endpos, origin, trace->endpos);
else
VectorAdd (trace->endpos, origin, trace->endpos);
}
else
{
@ -1115,15 +1139,15 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max
}
// trace a line through the apropriate clipping hull
if (progstype == PROG_H2 && ent->v->solid == SOLID_BSP)
if (ent->v->solid != SOLID_BSP)
{
ent->v->angles[0]*=-1;
TransformedTrace(model, 0, ent->v->frame, start, end, mins, maxs, &trace, ent->v->origin, ent->v->angles);
ent->v->angles[0]*=-1; //carmack made bsp models rotate wrongly.
TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, ent->v->origin, ent->v->angles);
ent->v->angles[0]*=-1;
}
else
{
TransformedTrace(model, 0, ent->v->frame, start, end, mins, maxs, &trace, ent->v->origin, ent->v->angles);
TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, ent->v->origin, ent->v->angles);
}
// fix trace up by the offset
@ -1146,7 +1170,7 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max
if (model && model->funcs.Trace)
{
//do the second trace
TransformedTrace(model, 0, ent->v->frame, start, end, mins, maxs, &trace, ent->v->origin, ent->v->angles);
TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, ent->v->origin, ent->v->angles);
}
}