Merge branch 'fury-gh/slopes' into angles

Conflicts:
	src/p_maputl.c
This commit is contained in:
RedEnchilada 2015-04-19 15:56:55 -05:00
commit 923fae476e
20 changed files with 3449 additions and 129 deletions

View file

@ -436,6 +436,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/m_misc.o \
$(OBJDIR)/m_random.o \
$(OBJDIR)/m_queue.o \
$(OBJDIR)/m_vector.o \
$(OBJDIR)/info.o \
$(OBJDIR)/p_ceilng.o \
$(OBJDIR)/p_enemy.o \
@ -454,6 +455,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/p_telept.o \
$(OBJDIR)/p_tick.o \
$(OBJDIR)/p_user.o \
$(OBJDIR)/p_slopes.o \
$(OBJDIR)/tables.o \
$(OBJDIR)/r_bsp.o \
$(OBJDIR)/r_data.o \

View file

@ -439,6 +439,14 @@ extern const char *compdate, *comptime, *comprevision;
/// Fun experimental slope stuff!
//#define SLOPENESS
/// Kalaron/Eternity Engine slope code (SRB2CB ported)
/// Depends on NEED_FIXED_VECTORS? for a few functions.
/// However, uses own vector types for math.
#define ESLOPE
/// Fixed and float point types
//#define NEED_FIXED_VECTOR
/// Delete file while the game is running.
/// \note EXTREMELY buggy, tends to crash game.
//#define DELFILE

View file

@ -357,6 +357,29 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRound(fixed_t x)
return INT32_MAX;
}
/*!
\brief convert a fixed_t number into double floating number
*/
#define FIXED_TO_DOUBLE(f) ((double)((f) / FRACUNIT))
/*!
\brief convert a double floating number into fixed_t number
*/
#define DOUBLE_TO_FIXED(f) ((fixed_t)((f) * FRACUNIT))
/*!
\brief convert a integer into fixed_t number
*/
#define INT_TO_FIXED(x) ((int)((x) * FRACUNIT))
/*!
\brief convert a fixed_t number into integer
*/
#define FIXED_TO_INT(x) (((int)(x)) / (FRACUNIT))
static inline int DivScale32 (fixed_t a, fixed_t b) { return (fixed_t)(((INT64)a << 32) / b); }
#ifdef NEED_FIXED_VECTOR
typedef struct

1160
src/m_vector.c Normal file

File diff suppressed because it is too large Load diff

123
src/m_vector.h Normal file
View file

@ -0,0 +1,123 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright(C) 2004 Stephen McGranahan
//
// This program is free software; 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
//
//--------------------------------------------------------------------------
//
// DESCRIPTION:
// Vectors
// SoM created 05/18/09
//
//-----------------------------------------------------------------------------
#ifndef M_VECTOR_H__
#define M_VECTOR_H__
#ifdef ESLOPE
#include "m_fixed.h"
#include "tables.h"
#define TWOPI M_PI*2.0
#define HALFPI M_PI*0.5
#define QUARTERPI M_PI*0.25
#define EPSILON 0.000001f
#define OMEGA 10000000.0f
typedef struct
{
fixed_t x, y, z;
} v3fixed_t;
typedef struct
{
fixed_t x, y;
} v2fixed_t;
typedef struct
{
float x, y, z;
} v3float_t;
typedef struct
{
float yaw, pitch, roll;
} angles3d_t;
typedef struct
{
double x, y, z;
} v3double_t;
typedef struct
{
float x, y;
} v2float_t;
v3fixed_t *M_MakeVec3(const v3fixed_t *point1, const v3fixed_t *point2, v3fixed_t *a_o);
v3float_t *M_MakeVec3f(const v3float_t *point1, const v3float_t *point2, v3float_t *a_o);
void M_TranslateVec3(v3fixed_t *vec);
void M_TranslateVec3f(v3float_t *vec);
void M_AddVec3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2);
void M_AddVec3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2);
void M_SubVec3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2);
void M_SubVec3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2);
fixed_t M_DotVec3(const v3fixed_t *v1, const v3fixed_t *v2);
float M_DotVec3f(const v3float_t *v1, const v3float_t *v2);
#ifdef SESLOPE
v3double_t *M_MakeVec3d(const v3double_t *point1, const v3double_t *point2, v3double_t *a_o);
double M_DotVec3d(const v3double_t *v1, const v3double_t *v2);
void M_TranslateVec3d(v3double_t *vec);
#endif
void M_CrossProduct3(v3fixed_t *dest, const v3fixed_t *v1, const v3fixed_t *v2);
void M_CrossProduct3f(v3float_t *dest, const v3float_t *v1, const v3float_t *v2);
fixed_t FV_Magnitude(const v3fixed_t *a_normal);
float FV_Magnitudef(const v3float_t *a_normal);
fixed_t FV_NormalizeO(const v3fixed_t *a_normal, v3fixed_t *a_o);
float FV_NormalizeOf(const v3float_t *a_normal, v3float_t *a_o);
fixed_t FV_Normalize(v3fixed_t *a_normal);
fixed_t FV_Normalizef(v3float_t *a_normal);
void FV_Normal(const v3fixed_t *a_triangle, v3fixed_t *a_normal);
void FV_Normalf(const v3float_t *a_triangle, v3float_t *a_normal);
v3fixed_t *M_LoadVec(v3fixed_t *vec, fixed_t x, fixed_t y, fixed_t z);
v3fixed_t *M_CopyVec(v3fixed_t *a_o, const v3fixed_t *a_i);
v3float_t *M_LoadVecf(v3float_t *vec, float x, float y, float z);
v3float_t *M_CopyVecf(v3float_t *a_o, const v3float_t *a_i);
v3fixed_t *FV_Midpoint(const v3fixed_t *a_1, const v3fixed_t *a_2, v3fixed_t *a_o);
fixed_t FV_Distance(const v3fixed_t *p1, const v3fixed_t *p2);
v3float_t *FV_Midpointf(const v3float_t *a_1, const v3float_t *a_2, v3float_t *a_o);
angle_t FV_AngleBetweenVectors(const v3fixed_t *Vector1, const v3fixed_t *Vector2);
float FV_AngleBetweenVectorsf(const v3float_t *Vector1, const v3float_t *Vector2);
float FV_Distancef(const v3float_t *p1, const v3float_t *p2);
// Kalaron: something crazy, vector physics
float M_VectorYaw(v3float_t v);
float M_VectorPitch(v3float_t v);
angles3d_t *M_VectorAlignTo(float Pitch, float Yaw, float Roll, v3float_t v, byte AngleAxis, float Rate);
#endif
// EOF
#endif // #ifdef ESLOPE

View file

@ -28,6 +28,10 @@
#include "hardware/hw3sound.h"
#endif
#ifdef ESLOPE
#include "p_slopes.h"
#endif
#ifdef HAVE_BLUA
boolean LUA_CallAction(const char *action, mobj_t *actor);
#endif
@ -5606,8 +5610,17 @@ void A_MixUp(mobj_t *actor)
P_SetThingPosition(players[i].mo);
#ifdef ESLOPE
players[i].mo->floorz = (players[i].mo->subsector->sector->f_slope ?
P_GetZAt(players[i].mo->subsector->sector->f_slope, players[i].mo->x, players[i].mo->y) :
players[i].mo->subsector->sector->floorheight);
players[i].mo->ceilingz = (players[i].mo->subsector->sector->c_slope ?
P_GetZAt(players[i].mo->subsector->sector->c_slope, players[i].mo->x, players[i].mo->y) :
players[i].mo->subsector->sector->ceilingheight);
#else
players[i].mo->floorz = players[i].mo->subsector->sector->floorheight;
players[i].mo->ceilingz = players[i].mo->subsector->sector->ceilingheight;
#endif
P_CheckPosition(players[i].mo, players[i].mo->x, players[i].mo->y);
}

View file

@ -19,6 +19,9 @@
#include "z_zone.h"
#include "g_game.h"
#include "r_main.h"
#ifdef ESLOPE
#include "p_slopes.h"
#endif
// ==========================================================================
// FLOORS
@ -1174,12 +1177,18 @@ void T_SpikeSector(levelspecthink_t *spikes)
if (affectsec == spikes->sector) // Applied to an actual sector
{
fixed_t affectpoint = affectsec->floorheight;
#ifdef ESLOPE
if (affectsec->f_slope)
affectpoint = P_GetZAt(affectsec->f_slope, thing->x, thing->y);
#endif
if (affectsec->flags & SF_FLIPSPECIAL_FLOOR)
{
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0)
continue;
if (thing->z == affectsec->floorheight)
if (thing->z == affectpoint)
dothepain = true;
}

View file

@ -53,6 +53,15 @@
// above this, a height difference is considered as a 'dropoff'
#define MAXSTEPMOVE (24*FRACUNIT)
#ifdef ESLOPE
// [RH] Minimum floorplane.c value for walking
// The lower the value, the steeper the slope is
#define SECPLANESTEEPSLOPE 46000
// ESLOPE stuff - a slope of 4 or lower is so level, treat it as flat
#define LEVELSLOPE 4
#define STEEPSLOPE 65
#endif
#define USERANGE (64*FRACUNIT)
#define MELEERANGE (64*FRACUNIT)
#define MISSILERANGE (32*64*FRACUNIT)
@ -138,6 +147,12 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec);
boolean P_InSpaceSector(mobj_t *mo);
boolean P_InQuicksand(mobj_t *mo);
#ifdef ESLOPE
boolean P_IsObjectOnSlope(mobj_t *mo, boolean ceiling);
boolean P_SlopeGreaterThan(mobj_t *mo, boolean ceiling, int value);
boolean P_SlopeLessThan(mobj_t *mo, boolean ceiling, int value);
#endif
void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative);
void P_RestoreMusic(player_t *player);
void P_SpawnShieldOrb(player_t *player);

View file

@ -27,6 +27,10 @@
#include "r_splats.h"
#ifdef ESLOPE
#include "p_slopes.h"
#endif
#include "z_zone.h"
#include "lua_hook.h"
@ -1204,8 +1208,21 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
// that contains the point.
// Any contacted lines the step closer together
// will adjust them.
#ifdef ESLOPE
if (newsubsec->sector->f_slope)
{
tmfloorz = tmdropoffz = P_GetZAt(newsubsec->sector->f_slope, thing->x, thing->y);
}
else
#endif
tmfloorz = tmdropoffz = newsubsec->sector->floorheight;
tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight;
#ifdef ESLOPE
if (newsubsec->sector->c_slope)
tmceilingz = P_GetZAt(newsubsec->sector->c_slope, thing->x, thing->y);
else
#endif
tmceilingz = newsubsec->sector->ceilingheight;
// Check list of fake floors and see if tmfloorz/tmceilingz need to be altered.
if (newsubsec->sector->ffloors)
@ -1219,32 +1236,42 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
if (!(rover->flags & FF_EXISTS))
continue;
fixed_t topheight = *rover->topheight;
fixed_t bottomheight = *rover->bottomheight;
/*#ifdef ESLOPE
if (rover->t_slope)
topheight = P_GetZAt(rover->t_slope, thing->x, thing->y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, thing->x, thing->y);
#endif*/
if (rover->flags & FF_GOOWATER && !(thing->flags & MF_NOGRAVITY))
{
// If you're inside goowater and slowing down
fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale);
fixed_t minspeed = FixedMul(thing->info->height/12, thing->scale);
if (thing->z < *rover->topheight && *rover->bottomheight < thingtop
if (thing->z < topheight && bottomheight < thingtop
&& abs(thing->momz) < minspeed)
{
// Oh no! The object is stick in between the surface of the goo and sinklevel! help them out!
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z > *rover->topheight - sinklevel
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z > topheight - sinklevel
&& thing->momz >= 0 && thing->momz < (minspeed>>2))
thing->momz += minspeed>>2;
else if (thing->eflags & MFE_VERTICALFLIP && thingtop < *rover->bottomheight + sinklevel
else if (thing->eflags & MFE_VERTICALFLIP && thingtop < bottomheight + sinklevel
&& thing->momz <= 0 && thing->momz > -(minspeed>>2))
thing->momz -= minspeed>>2;
// Land on the top or the bottom, depending on gravity flip.
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z >= *rover->topheight - sinklevel && thing->momz <= 0)
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z >= topheight - sinklevel && thing->momz <= 0)
{
if (tmfloorz < *rover->topheight - sinklevel)
tmfloorz = *rover->topheight - sinklevel;
if (tmfloorz < topheight - sinklevel)
tmfloorz = topheight - sinklevel;
}
else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= *rover->bottomheight + sinklevel && thing->momz >= 0)
else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= bottomheight + sinklevel && thing->momz >= 0)
{
if (tmceilingz > *rover->bottomheight + sinklevel)
tmceilingz = *rover->bottomheight + sinklevel;
if (tmceilingz > bottomheight + sinklevel)
tmceilingz = bottomheight + sinklevel;
}
}
continue;
@ -1261,7 +1288,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
if (rover->flags & FF_QUICKSAND)
{
if (thing->z < *rover->topheight && *rover->bottomheight < thingtop)
if (thing->z < topheight && bottomheight < thingtop)
{
if (tmfloorz < thing->z)
tmfloorz = thing->z;
@ -1270,21 +1297,21 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
continue;
}
delta1 = thing->z - (*rover->bottomheight
+ ((*rover->topheight - *rover->bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight
+ ((*rover->topheight - *rover->bottomheight)/2));
delta1 = thing->z - (bottomheight
+ ((topheight - bottomheight)/2));
delta2 = thingtop - (bottomheight
+ ((topheight - bottomheight)/2));
if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2)
if (topheight > tmfloorz && abs(delta1) < abs(delta2)
&& !(rover->flags & FF_REVERSEPLATFORM))
{
tmfloorz = tmdropoffz = *rover->topheight;
tmfloorz = tmdropoffz = topheight;
}
if (*rover->bottomheight < tmceilingz && abs(delta1) >= abs(delta2)
if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2)
&& !(rover->flags & FF_PLATFORM)
&& !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)))
{
tmceilingz = tmdrpoffceilz = *rover->bottomheight;
tmceilingz = tmdrpoffceilz = bottomheight;
}
}
}
@ -1463,8 +1490,21 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
// that contains the point.
// Any contacted lines the step closer together
// will adjust them.
#ifdef ESLOPE
if (newsubsec->sector->f_slope)
{
tmfloorz = tmdropoffz = P_GetZAt(newsubsec->sector->f_slope, thiscam->x, thiscam->y);
}
else
#endif
tmfloorz = tmdropoffz = newsubsec->sector->floorheight;
tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight;
#ifdef ESLOPE
if (newsubsec->sector->c_slope)
tmceilingz = P_GetZAt(newsubsec->sector->c_slope, thiscam->x, thiscam->y);
else
#endif
tmceilingz = newsubsec->sector->ceilingheight;
// Cameras use the heightsec's heights rather then the actual sector heights.
// If you can see through it, why not move the camera through it too?
@ -1493,17 +1533,27 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
continue;
delta1 = thiscam->z - (*rover->bottomheight
+ ((*rover->topheight - *rover->bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight
+ ((*rover->topheight - *rover->bottomheight)/2));
if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2))
fixed_t topheight = *rover->topheight;
fixed_t bottomheight = *rover->bottomheight;
/*#ifdef ESLOPE
if (rover->t_slope)
topheight = P_GetZAt(rover->t_slope, thiscam->x, thiscam->y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, thiscam->x, thiscam->y);
#endif*/
delta1 = thiscam->z - (bottomheight
+ ((topheight - bottomheight)/2));
delta2 = thingtop - (bottomheight
+ ((topheight - bottomheight)/2));
if (topheight > tmfloorz && abs(delta1) < abs(delta2))
{
tmfloorz = tmdropoffz = *rover->topheight;
tmfloorz = tmdropoffz = topheight;
}
if (*rover->bottomheight < tmceilingz && abs(delta1) >= abs(delta2))
if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2))
{
tmceilingz = tmdrpoffceilz = *rover->bottomheight;
tmceilingz = tmdrpoffceilz = bottomheight;
}
}
}
@ -1698,7 +1748,29 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
}
else
{
#ifdef ESLOPE // SRB2CBTODO: Checking the things momx/y help with collision issues, but makes going done slopes not as smooth
if (thiscam->subsector->sector && thiscam->subsector->sector->f_slope)
{
// SRB2CBTODO: Support a mobj's gravity for this too
if (P_GetZAt(thiscam->subsector->sector->f_slope, thiscam->x+thiscam->momx, thiscam->y+thiscam->momy) > P_GetZAt(thiscam->subsector->sector->f_slope, thiscam->x, thiscam->y))
thiscam->floorz = P_GetZAt(thiscam->subsector->sector->f_slope, thiscam->x+thiscam->momx, thiscam->y+thiscam->momy);
else
thiscam->floorz = P_GetZAt(thiscam->subsector->sector->f_slope, thiscam->x, thiscam->y);
}
else
#endif
tmfloorz = thiscam->subsector->sector->floorheight;
#ifdef ESLOPE
if (thiscam->subsector->sector && thiscam->subsector->sector->c_slope)
{
// SRB2CBTODO: Support a mobj's gravity for this too
if (P_GetZAt(thiscam->subsector->sector->c_slope, thiscam->x+thiscam->momx, thiscam->y+thiscam->momy) < P_GetZAt(thiscam->subsector->sector->c_slope, thiscam->x, thiscam->y))
thiscam->ceilingz = P_GetZAt(thiscam->subsector->sector->c_slope, thiscam->x, thiscam->y);
else
thiscam->ceilingz = P_GetZAt(thiscam->subsector->sector->c_slope, thiscam->x+thiscam->momx, thiscam->y+thiscam->momy);
}
else
#endif
tmceilingz = thiscam->subsector->sector->ceilingheight;
}
@ -1961,7 +2033,110 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
// Link the thing into its new position
P_UnsetThingPosition(thing);
#ifdef ESLOPE
// By virtue of being derived from SRB2 code, Kalaron's physics are GPL.
if (P_IsObjectOnSlope(thing, false))
{
fixed_t thingspeed = P_AproxDistance(thing->momx, thing->momy);
fixed_t predictmomx = x+(thing->momx/2);
fixed_t predictmomy = y+(thing->momy/2);
sector_t *nextsector = R_PointInSubsector(predictmomx, predictmomy)->sector;
sector_t *currentsector = R_PointInSubsector(thing->x, thing->y)->sector;
fixed_t zthrust = 0;
fixed_t slopeang = currentsector->f_slope->zangle;
fixed_t nextz = nextsector->floorheight;
if (nextsector->f_slope)
nextz = P_GetZAt(nextsector->f_slope, thing->x+predictmomx+thing->momx, thing->y+predictmomy+thing->momy);
if (nextsector != currentsector)
{
// Give a boost up from the slope you came if the next sector is lower than the first
// If your next sector does not have a slope and you're comming off of one
if (currentsector->f_slope)
if (P_GetZAt(currentsector->f_slope, thing->x, thing->y)/FRACUNIT > (nextz/FRACUNIT)+(slopeang*3))
//&& !nextsector->f_slope // TODO: VPHYSICS height check, not this hacky check? Or is this good enough?
if (currentsector->f_slope->zangle > 9)
{
fixed_t currentz = P_GetZAt(currentsector->f_slope, thing->x, thing->y);
fixed_t predictz = P_GetZAt(currentsector->f_slope, thing->x+thing->momx, thing->y+thing->momy);
predictz += (((thing->pitchangle/(ANGLE_45/45))+90)/70.0f)+thingspeed/9;
// Make sure that the z doesn't go too high for steep slopes
predictz -= ((currentsector->f_slope->zangle)/4)*FRACUNIT;
if (currentsector->f_slope->zangle > 60) // really steep
{
predictz -= ((currentsector->f_slope->zangle)/2)*FRACUNIT;
}
zthrust = (predictz - currentz)/2;
if (zthrust > (30*thing->scale/100)*FRACUNIT)
zthrust = (30*thing->scale/100)*FRACUNIT;
if (zthrust < -(30*thing->scale/100)*FRACUNIT)
zthrust = -(30*thing->scale/100)*FRACUNIT;
if (currentz/FRACUNIT > (nextz/FRACUNIT)+(slopeang*3))
{
// Now even out the momx/momy when catapulting off a steep slope
if (currentsector->f_slope->zangle > 65)
{
thing->momx /= 4.0f;
thing->momy /= 4.0f;
}
else if (currentsector->f_slope->zangle > 60)
{
thing->momx /= 3.5f;
thing->momy /= 3.5f;
}
else if (currentsector->f_slope->zangle > 50)
{
thing->momx /= 3.4f;
thing->momy /= 3.4f;
}
else if (currentsector->f_slope->zangle > 40)
{
thing->momx /= 3.3f;
thing->momy /= 3.3f;
}
}
thing->momz += zthrust; // VPHYSICS TODO: Make a real formula for z trajectory going off a slope
/*CONS_Printf("CurZ %i, PredictZ %i\n", currentz/FRACUNIT, predictz/FRACUNIT);
CONS_Printf("Pitch: %i\n", thing->pitchangle/(ANG45/45)+90);
CONS_Printf("ZThrust: %i\n", zthrust/FRACUNIT);*/
}
}
}
#endif
// P_CheckPosition sets the tmfloorz with slopes, but after P_UnsetThingPosition, recheck the function here
// TODO: Make a function for floor/ceilingz auto check with slopes?
#ifdef ESLOPE
if (thing->subsector->sector->f_slope)
{
// TODO: Support a mobj's gravity for this too
if (P_GetZAt(thing->subsector->sector->f_slope, thing->x+thing->momx, thing->y+thing->momy) > P_GetZAt(thing->subsector->sector->f_slope, thing->x, thing->y))
thing->floorz = P_GetZAt(thing->subsector->sector->f_slope, thing->x+thing->momx, thing->y+thing->momy);
else
thing->floorz = P_GetZAt(thing->subsector->sector->f_slope, thing->x, thing->y);
}
else
#endif
thing->floorz = tmfloorz;
#ifdef ESLOPE
if (thing->subsector->sector->c_slope)
{
// SRB2CBTODO: Support a mobj's gravity for this too
if (P_GetZAt(thing->subsector->sector->c_slope, thing->x+thing->momx, thing->y+thing->momy) < P_GetZAt(thing->subsector->sector->c_slope, thing->x, thing->y))
thing->ceilingz = P_GetZAt(thing->subsector->sector->c_slope, thing->x, thing->y);
else
thing->ceilingz = P_GetZAt(thing->subsector->sector->c_slope, thing->x+thing->momx, thing->y+thing->momy);
}
else
#endif
thing->ceilingz = tmceilingz;
thing->x = x;
thing->y = y;
@ -1978,6 +2153,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
{
fixed_t tryx, tryy;
tryx = thing->x;
tryy = thing->y;
do {
@ -1999,7 +2175,15 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
if (!(thing->flags & MF_NOCLIP))
{
const fixed_t maxstep = MAXSTEPMOVE;
fixed_t maxstep = MAXSTEPMOVE;
#ifdef ESLOPE // TODO: Make this collosion better
// Maxstepmove = 0 means the object bounces like a nut while going down a slope
if (thing->subsector->sector->f_slope)
{
maxstep *= thing->subsector->sector->f_slope->zangle;
}
#endif
if (tmceilingz - tmfloorz < thing->height)
return false; // doesn't fit
@ -2303,12 +2487,24 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
{
fixed_t platx, platy;
subsector_t *glidesector;
fixed_t floorz, ceilingz;
platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy);
floorz = glidesector->sector->floorheight;
#ifdef ESLOPE
if (glidesector->sector->f_slope)
floorz = P_GetZAt(glidesector->sector->f_slope, player->mo->x + platx, player->mo->y + platy);
#endif
ceilingz = glidesector->sector->ceilingheight;
#ifdef ESLOPE
if (glidesector->sector->c_slope)
ceilingz = P_GetZAt(glidesector->sector->c_slope, player->mo->x + platx, player->mo->y + platy);
#endif
if (glidesector->sector != player->mo->subsector->sector)
{
boolean floorclimb = false;
@ -2321,34 +2517,44 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
continue;
fixed_t topheight = *rover->topheight;
fixed_t bottomheight = *rover->bottomheight;
/*#ifdef ESLOPE
if (rover->t_slope)
topheight = P_GetZAt(rover->t_slope, player->mo->x, player->mo->y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, player->mo->x, player->mo->y);
#endif*/
floorclimb = true;
if (player->mo->eflags & MFE_VERTICALFLIP)
{
if ((*rover->topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < *rover->topheight))
if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight))
{
floorclimb = true;
}
if (*rover->topheight < player->mo->z) // Waaaay below the ledge.
if (topheight < player->mo->z) // Waaaay below the ledge.
{
floorclimb = false;
}
if (*rover->bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale))
if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale))
{
floorclimb = false;
}
}
else
{
if ((*rover->bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > *rover->bottomheight))
if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight))
{
floorclimb = true;
}
if (*rover->bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge.
if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge.
{
floorclimb = false;
}
if (*rover->topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale))
if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale))
{
floorclimb = false;
}
@ -2361,30 +2567,30 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
if (player->mo->eflags & MFE_VERTICALFLIP)
{
if ((glidesector->sector->floorheight <= player->mo->z + player->mo->height)
&& ((player->mo->z + player->mo->height - player->mo->momz) <= glidesector->sector->floorheight))
if ((floorz <= player->mo->z + player->mo->height)
&& ((player->mo->z + player->mo->height - player->mo->momz) <= floorz))
floorclimb = true;
if ((glidesector->sector->floorheight > player->mo->z)
if ((floorz > player->mo->z)
&& glidesector->sector->floorpic == skyflatnum)
return false;
if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > glidesector->sector->ceilingheight)
|| (player->mo->z + player->mo->height <= glidesector->sector->floorheight))
if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz)
|| (player->mo->z + player->mo->height <= floorz))
floorclimb = true;
}
else
{
if ((glidesector->sector->ceilingheight >= player->mo->z)
&& ((player->mo->z - player->mo->momz) >= glidesector->sector->ceilingheight))
if ((ceilingz >= player->mo->z)
&& ((player->mo->z - player->mo->momz) >= ceilingz))
floorclimb = true;
if ((glidesector->sector->ceilingheight < player->mo->z+player->mo->height)
if ((ceilingz < player->mo->z+player->mo->height)
&& glidesector->sector->ceilingpic == skyflatnum)
return false;
if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < glidesector->sector->floorheight)
|| (player->mo->z >= glidesector->sector->ceilingheight))
if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < ceilingz)
|| (player->mo->z >= ceilingz))
floorclimb = true;
}
@ -2403,6 +2609,7 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
static boolean PTR_SlideTraverse(intercept_t *in)
{
line_t *li;
fixed_t maxstep;
I_Assert(in->isaline);
@ -2435,7 +2642,17 @@ static boolean PTR_SlideTraverse(intercept_t *in)
if (opentop - slidemo->z < slidemo->height)
goto isblocking; // mobj is too high
if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, slidemo->scale))
maxstep = FixedMul(MAXSTEPMOVE, slidemo->scale);
#ifdef ESLOPE // TODO: Make this collosion better
// Maxstepmove = 0 means the object bounces like a nut while going down a slope
if (slidemo->subsector->sector->f_slope)
{
maxstep *= slidemo->subsector->sector->f_slope->zangle;
}
#endif
if (openbottom - slidemo->z > maxstep)
goto isblocking; // too big a step up
// this line doesn't block movement
@ -2471,13 +2688,23 @@ isblocking:
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue;
if (*rover->topheight < slidemo->z)
fixed_t topheight = *rover->topheight;
fixed_t bottomheight = *rover->bottomheight;
/*#ifdef ESLOPE
if (rover->t_slope)
topheight = P_GetZAt(rover->t_slope, slidemo->x, slidemo->y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, slidemo->x, slidemo->y);
#endif*/
if (topheight < slidemo->z)
continue;
if (*rover->bottomheight > slidemo->z + slidemo->height)
if (bottomheight > slidemo->z + slidemo->height)
continue;
// Got this far, so I guess it's climbable.
// Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this?
if (rover->master->flags & ML_TFERLINE)
{
size_t linenum = li-checksector->lines[0];
@ -3106,9 +3333,19 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
|| ((rover->flags & FF_BLOCKOTHERS) && !thing->player)) || !(rover->flags & FF_EXISTS))
continue;
delta1 = thing->z - (*rover->bottomheight + *rover->topheight)/2;
delta2 = thingtop - (*rover->bottomheight + *rover->topheight)/2;
if (*rover->bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2))
fixed_t topheight = *rover->topheight;
fixed_t bottomheight = *rover->bottomheight;
/*#ifdef ESLOPE
if (rover->t_slope)
topheight = P_GetZAt(rover->t_slope, thing->x, thing->y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, thing->x, thing->y);
#endif*/
delta1 = thing->z - (bottomheight + topheight)/2;
delta2 = thingtop - (bottomheight + topheight)/2;
if (bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2))
{
if (thing->flags & MF_PUSHABLE)
{
@ -3786,7 +4023,7 @@ void P_MapEnd(void)
}
// P_FloorzAtPos
// Returns the floorz of the XYZ position
// Returns the floorz of the XYZ position // TODO: Need ceilingpos function too
// Tails 05-26-2003
fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
{
@ -3807,9 +4044,19 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE)))
continue;
fixed_t topheight = *rover->topheight;
fixed_t bottomheight = *rover->bottomheight;
/*#ifdef ESLOPE
if (rover->t_slope)
topheight = P_GetZAt(rover->t_slope, x, y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, x, y);
#endif*/
if (rover->flags & FF_QUICKSAND)
{
if (z < *rover->topheight && *rover->bottomheight < thingtop)
if (z < topheight && bottomheight < thingtop)
{
if (floorz < z)
floorz = z;
@ -3817,10 +4064,10 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
continue;
}
delta1 = z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
if (*rover->topheight > floorz && abs(delta1) < abs(delta2))
floorz = *rover->topheight;
delta1 = z - (bottomheight + ((topheight - bottomheight)/2));
delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2));
if (topheight > floorz && abs(delta1) < abs(delta2))
floorz = topheight;
}
}

View file

@ -21,6 +21,9 @@
#include "p_maputl.h"
#include "p_polyobj.h"
#include "z_zone.h"
#ifdef ESLOPE
#include "p_slopes.h"
#endif
//
// P_AproxDistance
@ -348,31 +351,68 @@ void P_CameraLineOpening(line_t *linedef)
{
frontfloor = sectors[front->camsec].floorheight;
frontceiling = sectors[front->camsec].ceilingheight;
#ifdef ESLOPE
if (sectors[front->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[front->camsec].f_slope, camera.x, camera.y);
if (sectors[front->camsec].c_slope)
frontceiling = P_GetZAt(sectors[front->camsec].c_slope, camera.x, camera.y);
#endif
}
else if (front->heightsec >= 0)
{
frontfloor = sectors[front->heightsec].floorheight;
frontceiling = sectors[front->heightsec].ceilingheight;
#ifdef ESLOPE
if (sectors[front->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[front->heightsec].f_slope, camera.x, camera.y);
if (sectors[front->heightsec].c_slope)
frontceiling = P_GetZAt(sectors[front->heightsec].c_slope, camera.x, camera.y);
#endif
}
else
{
frontfloor = front->floorheight;
frontceiling = front->ceilingheight;
#ifdef ESLOPE
if (front->f_slope)
frontfloor = P_GetZAt(front->f_slope, camera.x, camera.y);
if (front->c_slope)
frontceiling = P_GetZAt(front->c_slope, camera.x, camera.y);
#endif
}
if (back->camsec >= 0)
{
backfloor = sectors[back->camsec].floorheight;
backceiling = sectors[back->camsec].ceilingheight;
#ifdef ESLOPE
if (sectors[back->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[back->camsec].f_slope, camera.x, camera.y);
if (sectors[back->camsec].c_slope)
frontceiling = P_GetZAt(sectors[back->camsec].c_slope, camera.x, camera.y);
#endif
}
else if (back->heightsec >= 0)
{
backfloor = sectors[back->heightsec].floorheight;
backceiling = sectors[back->heightsec].ceilingheight;
#ifdef ESLOPE
if (sectors[back->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[back->heightsec].f_slope, camera.x, camera.y);
if (sectors[back->heightsec].c_slope)
frontceiling = P_GetZAt(sectors[back->heightsec].c_slope, camera.x, camera.y);
#endif
}
else
{
backfloor = back->floorheight;
backceiling = back->ceilingheight;
#ifdef ESLOPE
if (back->f_slope)
frontfloor = P_GetZAt(back->f_slope, camera.x, camera.y);
if (back->c_slope)
frontceiling = P_GetZAt(back->c_slope, camera.x, camera.y);
#endif
}
{
@ -417,17 +457,28 @@ void P_CameraLineOpening(line_t *linedef)
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
continue;
delta1 = abs(mapcampointer->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
if (*rover->bottomheight < lowestceiling && delta1 >= delta2)
lowestceiling = *rover->bottomheight;
else if (*rover->bottomheight < highestceiling && delta1 >= delta2)
highestceiling = *rover->bottomheight;
fixed_t topheight = *rover->topheight;
fixed_t bottomheight = *rover->bottomheight;
if (*rover->topheight > highestfloor && delta1 < delta2)
highestfloor = *rover->topheight;
else if (*rover->topheight > lowestfloor && delta1 < delta2)
lowestfloor = *rover->topheight;
/*#ifdef ESLOPE
if (rover->t_slope)
topheight = P_GetZAt(rover->t_slope, camera.x, camera.y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, camera.x, camera.y);
#endif // ESLOPE*/
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (bottomheight < lowestceiling && delta1 >= delta2)
lowestceiling = bottomheight;
else if (bottomheight < highestceiling && delta1 >= delta2)
highestceiling = bottomheight;
if (topheight > highestfloor && delta1 < delta2)
highestfloor = topheight;
else if (topheight > lowestfloor && delta1 < delta2)
lowestfloor = topheight;
}
// Check for backsectors fake floors
@ -437,17 +488,28 @@ void P_CameraLineOpening(line_t *linedef)
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
continue;
delta1 = abs(mapcampointer->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
if (*rover->bottomheight < lowestceiling && delta1 >= delta2)
lowestceiling = *rover->bottomheight;
else if (*rover->bottomheight < highestceiling && delta1 >= delta2)
highestceiling = *rover->bottomheight;
fixed_t topheight = *rover->topheight;
fixed_t bottomheight = *rover->bottomheight;
if (*rover->topheight > highestfloor && delta1 < delta2)
highestfloor = *rover->topheight;
else if (*rover->topheight > lowestfloor && delta1 < delta2)
lowestfloor = *rover->topheight;
/*#ifdef ESLOPE
if (rover->t_slope)
topheight = P_GetZAt(rover->t_slope, camera.x, camera.y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, camera.x, camera.y);
#endif // ESLOPE*/
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (bottomheight < lowestceiling && delta1 >= delta2)
lowestceiling = bottomheight;
else if (bottomheight < highestceiling && delta1 >= delta2)
highestceiling = bottomheight;
if (topheight > highestfloor && delta1 < delta2)
highestfloor = topheight;
else if (topheight > lowestfloor && delta1 < delta2)
lowestfloor = topheight;
}
if (highestceiling < highceiling)
@ -565,6 +627,32 @@ void P_LineOpening(line_t *linedef)
openbottom = textop;
}
}
#ifdef ESLOPE
// I suspect the math here is wrong and we should be comparing the slope Zs
// if either are slopes.
// -- Fury
if (front->c_slope && front->ceilingheight < back->ceilingheight)
{
opentop = P_GetZAt(front->c_slope, tmthing->x, tmthing->y);
if (back->c_slope) highceiling = P_GetZAt(back->c_slope, tmthing->x, tmthing->y);
}
else if (back->c_slope && front->ceilingheight >= back->ceilingheight)
{
opentop = P_GetZAt(back->c_slope, tmthing->x, tmthing->y);
if (front->c_slope) highceiling = P_GetZAt(front->c_slope, tmthing->x, tmthing->y);
}
if (front->c_slope && front->floorheight < back->floorheight)
{
openbottom = P_GetZAt(front->f_slope, tmthing->x, tmthing->y);
if (back->f_slope) lowfloor = P_GetZAt(back->f_slope, tmthing->x, tmthing->y);
}
if (back->f_slope && front->floorheight >= back->floorheight)
{
openbottom = P_GetZAt(back->f_slope, tmthing->x, tmthing->y);
if (front->f_slope) lowfloor = P_GetZAt(back->f_slope, tmthing->x, tmthing->y);
}
#endif
// Check for fake floors in the sector.
if (front->ffloors || back->ffloors
@ -593,23 +681,34 @@ void P_LineOpening(line_t *linedef)
|| (rover->flags & FF_BLOCKOTHERS && !tmthing->player)))
continue;
delta1 = abs(tmthing->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
fixed_t topheight = *rover->topheight;
fixed_t bottomheight = *rover->bottomheight;
/*#ifdef ESLOPE
if (rover->t_slope)
topheight = P_GetZAt(rover->t_slope, camera.x, camera.y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, camera.x, camera.y);
#endif*/
delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
{
if (*rover->bottomheight < lowestceiling)
lowestceiling = *rover->bottomheight;
else if (*rover->bottomheight < highestceiling)
highestceiling = *rover->bottomheight;
if (bottomheight < lowestceiling)
lowestceiling = bottomheight;
else if (bottomheight < highestceiling)
highestceiling = bottomheight;
}
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
{
if (*rover->topheight > highestfloor)
highestfloor = *rover->topheight;
else if (*rover->topheight > lowestfloor)
lowestfloor = *rover->topheight;
if (topheight > highestfloor)
highestfloor = topheight;
else if (topheight > lowestfloor)
lowestfloor = topheight;
}
}
@ -625,23 +724,34 @@ void P_LineOpening(line_t *linedef)
|| (rover->flags & FF_BLOCKOTHERS && !tmthing->player)))
continue;
delta1 = abs(tmthing->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)));
fixed_t topheight = *rover->topheight;
fixed_t bottomheight = *rover->bottomheight;
/*#ifdef ESLOPE
if (rover->t_slope)
topheight = P_GetZAt(rover->t_slope, tmthing->x, tmthing->y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, tmthing->x, tmthing->y);
#endif*/
delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
{
if (*rover->bottomheight < lowestceiling)
lowestceiling = *rover->bottomheight;
else if (*rover->bottomheight < highestceiling)
highestceiling = *rover->bottomheight;
if (bottomheight < lowestceiling)
lowestceiling = bottomheight;
else if (bottomheight < highestceiling)
highestceiling = bottomheight;
}
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
{
if (*rover->topheight > highestfloor)
highestfloor = *rover->topheight;
else if (*rover->topheight > lowestfloor)
lowestfloor = *rover->topheight;
if (topheight > highestfloor)
highestfloor = topheight;
else if (topheight > lowestfloor)
lowestfloor = topheight;
}
}
@ -778,6 +888,16 @@ void P_SetThingPosition(mobj_t *thing)
ss = thing->subsector = R_PointInSubsector(thing->x, thing->y);
fixed_t tfloorz, tceilz;
tfloorz = ss->sector->floorheight;
tceilz = ss->sector->ceilingheight;
#ifdef ESLOPE
if (ss->sector->f_slope)
tfloorz = P_GetZAt(ss->sector->f_slope, thing->x, thing->y);
if (ss->sector->c_slope)
tceilz = P_GetZAt(ss->sector->c_slope, thing->x, thing->y);
#endif
if (!(thing->flags & MF_NOSECTOR))
{
// invisible things don't go into the sector links
@ -840,10 +960,10 @@ void P_SetThingPosition(mobj_t *thing)
{
if (thing->eflags & MFE_VERTICALFLIP)
{
if (thing->z + thing->height >= thing->subsector->sector->ceilingheight)
if (thing->z + thing->height >= tceilz)
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
else if (thing->z <= thing->subsector->sector->floorheight)
else if (thing->z <= tfloorz)
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
}

View file

@ -31,6 +31,9 @@
#include "i_video.h"
#include "lua_hook.h"
#include "b_bot.h"
#ifdef ESLOPE
#include "p_slopes.h"
#endif
// protos.
static CV_PossibleValue_t viewheight_cons_t[] = {{16, "MIN"}, {56, "MAX"}, {0, NULL}};
@ -700,15 +703,75 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover)
|| ((rover->flags & FF_BLOCKOTHERS) && !mobj->player)))
return false;
if (mobj->z > *rover->topheight)
fixed_t topheight = *rover->topheight;
fixed_t bottomheight = *rover->bottomheight;
/*#ifdef ESLOPE
if (rover->t_slope)
topheight = P_GetZAt(rover->t_slope, mobj->x, mobj->y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, mobj->x, mobj->y);
#endif*/
if (mobj->z > topheight)
return false;
if (mobj->z + mobj->height < *rover->bottomheight)
if (mobj->z + mobj->height < bottomheight)
return false;
return true;
}
fixed_t P_GetMobjZAtSecF(mobj_t *mobj, sector_t *sector) // SRB2CBTODO: This needs to be over all the code
{
I_Assert(mobj != NULL);
#ifdef ESLOPE
if (sector->f_slope)
return P_GetZAt(sector->f_slope, mobj->x, mobj->y);
else
#endif
return sector->floorheight;
}
fixed_t P_GetMobjZAtF(mobj_t *mobj) // SRB2CBTODO: This needs to be over all the code
{
I_Assert(mobj != NULL);
sector_t *sector;
sector = R_PointInSubsector(mobj->x, mobj->y)->sector;
#ifdef ESLOPE
if (sector->f_slope)
return P_GetZAt(sector->f_slope, mobj->x, mobj->y);
else
#endif
return sector->floorheight;
}
fixed_t P_GetMobjZAtSecC(mobj_t *mobj, sector_t *sector) // SRB2CBTODO: This needs to be over all the code
{
I_Assert(mobj != NULL);
#ifdef ESLOPE
if (sector->c_slope)
return P_GetZAt(sector->c_slope, mobj->x, mobj->y);
else
#endif
return sector->ceilingheight;
}
fixed_t P_GetMobjZAtC(mobj_t *mobj) // SRB2CBTODO: This needs to be over all the code
{
I_Assert(mobj != NULL);
sector_t *sector;
sector = R_PointInSubsector(mobj->x, mobj->y)->sector;
#ifdef ESLOPE
if (sector->c_slope)
return P_GetZAt(sector->c_slope, mobj->x, mobj->y);
else
#endif
return sector->ceilingheight;
}
static void P_PlayerFlip(mobj_t *mo)
{
if (!mo->player)
@ -2431,6 +2494,11 @@ void P_MobjCheckWater(mobj_t *mobj)
// Default if no water exists.
mobj->watertop = mobj->waterbottom = mobj->subsector->sector->floorheight - 1000*FRACUNIT;
#ifdef ESLOPE // Set the correct waterbottom/top to be below the lowest point of the slope
if (mobj->subsector->sector->f_slope)
mobj->watertop = mobj->waterbottom = mobj->subsector->sector->f_slope->lowz - 1000*FRACUNIT;
#endif
// Reset water state.
mobj->eflags &= ~(MFE_UNDERWATER|MFE_TOUCHWATER|MFE_GOOWATER);
@ -2441,34 +2509,45 @@ void P_MobjCheckWater(mobj_t *mobj)
|| ((rover->flags & FF_BLOCKOTHERS) && !mobj->player)))
continue;
fixed_t topheight = *rover->topheight;
fixed_t bottomheight = *rover->bottomheight;
/*#ifdef ESLOPE
if (rover->t_slope)
topheight = P_GetZAt(rover->t_slope, mobj->x, mobj->y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, mobj->x, mobj->y);
#endif*/
if (mobj->eflags & MFE_VERTICALFLIP)
{
if (*rover->topheight < (thingtop - FixedMul(mobj->info->height/2, mobj->scale))
|| *rover->bottomheight > thingtop)
if (topheight < (thingtop - FixedMul(mobj->info->height/2, mobj->scale))
|| bottomheight > thingtop)
continue;
}
else
{
if (*rover->topheight < mobj->z
|| *rover->bottomheight > (mobj->z + FixedMul(mobj->info->height/2, mobj->scale)))
if (topheight < mobj->z
|| bottomheight > (mobj->z + FixedMul(mobj->info->height/2, mobj->scale)))
continue;
}
// Set the watertop and waterbottom
mobj->watertop = *rover->topheight;
mobj->waterbottom = *rover->bottomheight;
mobj->watertop = topheight;
mobj->waterbottom = bottomheight;
// Just touching the water?
if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height, mobj->scale) < *rover->bottomheight)
|| (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height, mobj->scale) > *rover->topheight))
if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height, mobj->scale) < bottomheight)
|| (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height, mobj->scale) > topheight))
{
mobj->eflags |= MFE_TOUCHWATER;
if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY))
mobj->eflags |= MFE_GOOWATER;
}
// Actually in the water?
if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height/2, mobj->scale) > *rover->bottomheight)
|| (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height/2, mobj->scale) < *rover->topheight))
if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height/2, mobj->scale) > bottomheight)
|| (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height/2, mobj->scale) < topheight))
{
mobj->eflags |= MFE_UNDERWATER;
if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY))

View file

@ -28,6 +28,11 @@
// Needs precompiled tables/data structures.
#include "info.h"
// For slope code, we need v3float_t
#ifdef ESLOPE
#include "m_vector.h"
#endif
//
// NOTES: mobj_t
//
@ -352,6 +357,11 @@ typedef struct mobj_s
INT32 cusval;
INT32 cvmem;
#ifdef ESLOPE
angle_t pitchangle;
v3float_t vector;
#endif
// WARNING: New fields must be added separately to savegame and Lua.
} mobj_t;

1211
src/p_slopes.c Normal file

File diff suppressed because it is too large Load diff

84
src/p_slopes.h Normal file
View file

@ -0,0 +1,84 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright(C) 2004 Stephen McGranahan
//
// This program is free software; 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
//
//--------------------------------------------------------------------------
//
// DESCRIPTION:
// Slopes
// SoM created 05/10/09
//
//-----------------------------------------------------------------------------
#ifndef P_SLOPES_H__
#define P_SLOPES_H__
#ifdef ESLOPE
// P_MakeLineNormal
// Calculates a 2D normal for the given line and stores it in the line
void P_MakeLineNormal(line_t *line);
// P_SpawnSlope_Line
// Creates one or more slopes based on the given line type and front/back
// sectors.
void P_SpawnSlope_Line(int linenum);
// Loads just map objects that make slopes,
// terrain affecting objects have to be spawned first
void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum);
typedef enum
{
THING_SlopeFloorPointLine = 9500,
THING_SlopeCeilingPointLine = 9501,
THING_SetFloorSlope = 9502,
THING_SetCeilingSlope = 9503,
THING_CopyFloorPlane = 9510,
THING_CopyCeilingPlane = 9511,
THING_VavoomFloor=1500,
THING_VavoomCeiling=1501,
THING_VertexFloorZ=1504,
THING_VertexCeilingZ=1505,
} slopething_e;
//
// P_CopySectorSlope
//
// Searches through tagged sectors and copies
//
void P_CopySectorSlope(line_t *line);
// Returns the height of the sloped plane at (x, y) as a fixed_t
fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y);
// Returns the height of the sloped plane at (x, y) as a float
float P_GetZAtf(pslope_t *slope, float x, float y);
// Returns the distance of the given point from the given origin and normal.
float P_DistFromPlanef(const v3float_t *point, const v3float_t *pori,
const v3float_t *pnormal);
#endif
// EOF
#endif // #ifdef ESLOPE

View file

@ -33,6 +33,9 @@
#include "m_misc.h"
#include "m_cond.h" //unlock triggers
#include "lua_hook.h" // LUAh_LinedefExecute
#ifdef ESLOPE
#include "p_slopes.h"
#endif
#ifdef HW3SOUND
#include "hardware/hw3sound.h"
@ -4581,16 +4584,27 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
return;
}
fixed_t f_affectpoint = sector->floorheight;
fixed_t c_affectpoint = sector->ceilingheight;
#ifdef ESLOPE
if (sector->f_slope)
f_affectpoint = P_GetZAt(sector->f_slope, player->mo->x, player->mo->y);
if (sector->c_slope)
c_affectpoint = P_GetZAt(sector->c_slope, player->mo->x, player->mo->y);
#endif
// Only go further if on the ground
if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != sector->floorheight)
if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != f_affectpoint)
return;
if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != sector->ceilingheight)
if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != c_affectpoint)
return;
if ((sector->flags & SF_FLIPSPECIAL_BOTH)
&& player->mo->z != sector->floorheight
&& player->mo->z + player->mo->height != sector->ceilingheight)
&& player->mo->z != f_affectpoint
&& player->mo->z + player->mo->height != c_affectpoint)
return;
P_ProcessSpecialSector(player, sector, NULL);
@ -4751,6 +4765,9 @@ void P_UpdateSpecials(void)
// POINT LIMIT
P_CheckPointLimit();
// Kalaron: ...We...have dynamic slopes *YESSSS*
P_SpawnDeferredSpecials();
// ANIMATE TEXTURES
for (anim = anims; anim < lastanim; anim++)
{
@ -6464,6 +6481,63 @@ void P_SpawnSpecials(INT32 fromnetsave)
P_RunLevelLoadExecutors();
}
#ifdef ESLOPE
//
// P_SpawnDeferredSpecials
//
// SoM: Specials that copy slopes, ect., need to be collected in a separate
// pass
// NOTE: SRB2CBTODO: A new function, P_SpawnDeferredSpecials is needed if objects
// are to be needed in this function, because this function currently needs to be
// done before 'things' are loaded, because slopes are part of this function,
// and slope height adjustments are needed for spawning objects
void P_SpawnDeferredSpecials(void)
{
size_t i;
line_t *line;
for(i = 0; i < numlines; i++)
{
line = lines + i;
switch(line->special)
{
// Slopes, Eternity engine
/*{ 386, "Slope_FrontsectorFloor" },
{ 387, "Slope_FrontsectorCeiling" },
{ 388, "Slope_FrontsectorFloorAndCeiling" },
{ 389, "Slope_BacksectorFloor" },
{ 390, "Slope_BacksectorCeiling" },
{ 391, "Slope_BacksectorFloorAndCeiling" },
{ 392, "Slope_BackFloorAndFrontCeiling" },
{ 393, "Slope_BackCeilingAndFrontFloor" },
{ 394, "Slope_FrontFloorToTaggedSlope" },
{ 395, "Slope_FrontCeilingToTaggedSlope" },
{ 396, "Slope_FrontFloorAndCeilingToTaggedSlope" },*/
// SoM 05/10/09: Slopes // SRB2CBTODO:!
case 386:
case 387:
case 388:
case 389:
case 390:
case 391:
case 392:
case 393:
P_SpawnSlope_Line(i);
break;
// SoM: Copy slopes
case 394:
case 395:
case 396:
P_CopySectorSlope(line);
break;
}
}
}
#endif
/** Adds 3Dfloors as appropriate based on a common control linedef.
*
* \param line Control linedef to use.
@ -7363,8 +7437,12 @@ void T_Pusher(pusher_t *p)
|| GETSECSPECIAL(referrer->special, 3) == 3)
foundfloor = true;
}
else if (!(GETSECSPECIAL(sec->special, 3) == 2
|| GETSECSPECIAL(sec->special, 3) == 3))
else if (
#ifdef ESLOPE
(!sec->f_slope) &&
#endif
(!(GETSECSPECIAL(sec->special, 3) == 2
|| GETSECSPECIAL(sec->special, 3) == 3)))
return;
if (p->roverpusher && foundfloor == false) // Not even a 3d floor has the PUSH_MASK.

View file

@ -36,6 +36,11 @@ void P_SpawnSpecials(INT32 fromnetsave);
// every tic
void P_UpdateSpecials(void);
#ifdef ESLOPE
void P_SpawnDeferredSpecials(void);
#endif
sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number);
void P_PlayerInSpecialSector(player_t *player);
void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector);

View file

@ -1197,6 +1197,87 @@ boolean P_IsObjectOnGround(mobj_t *mo)
return false;
}
#ifdef ESLOPE
//
// P_IsObjectOnSlope
//
// Returns true if the player is
// on a slope. Takes reverse
// gravity into account.
//
boolean P_IsObjectOnSlope(mobj_t *mo, boolean ceiling)
{
if (ceiling && (mo->eflags & MFE_VERTICALFLIP))
{
if ((mo->z + mo->height >= mo->ceilingz) && mo->subsector->sector->c_slope) // SRB2CBTODO: allow being on underside of mobj too?
return true;
}
else
{
if (mo->z <= mo->floorz && mo->subsector->sector->f_slope)
return true;
}
return false;
}
//
// P_SlopeGreaterThan
//
// Returns true if the object is on a slope
// that has an angle greater than the value
//
boolean P_SlopeGreaterThan(mobj_t *mo, boolean ceiling, int value)
{
if (ceiling && (mo->eflags & MFE_VERTICALFLIP))
{
if ((mo->z + mo->height >= mo->ceilingz) && mo->subsector->sector->c_slope)
{
if (value < mo->subsector->sector->c_slope->zangle)
return true;
}
}
else
{
if (mo->z <= mo->floorz && mo->subsector->sector->f_slope)
{
if (value < mo->subsector->sector->f_slope->zangle)
return true;
}
}
return false;
}
//
// P_SlopeLessThan
//
// Returns true if the object is on a slope
// that has an angle less than the value
//
boolean P_SlopeLessThan(mobj_t *mo, boolean ceiling, int value)
{
if (ceiling && (mo->eflags & MFE_VERTICALFLIP))
{
if ((mo->z + mo->height >= mo->ceilingz) && mo->subsector->sector->c_slope)
{
if (value < mo->subsector->sector->c_slope->zangle)
return true;
}
}
else
{
if (mo->z <= mo->floorz && mo->subsector->sector->f_slope)
{
if (value < mo->subsector->sector->f_slope->zangle)
return true;
}
}
return false;
}
#endif
//
// P_IsObjectOnGroundIn
//

View file

@ -224,6 +224,49 @@ typedef struct secplane_t
fixed_t a, b, c, d, ic;
} secplane_t;
// Kalaron Slopes
#ifdef ESLOPE
#include "m_vector.h"
typedef struct
{
// --- Information used in clipping/projection ---
// Origin vector for the plane
// NOTE: All similarly named entries in this struct do the same thing,
// differing with just 'f' in the name for float:
// o = of, d = df, zdelta = zdeltaf; the only difference is that one's fixed,
// and the one with the 'f' is floating point, for easier reference elsewhere in the code
v3fixed_t o;
v3float_t of;
// The normal of the 3d plane the slope creates.
v3float_t normalf;
// 2-Dimentional vector (x, y) normalized. Used to determine distance from
// the origin in 2d mapspace.
v2fixed_t d;
v2float_t df;
// The rate at which z changes based on distance from the origin plane.
fixed_t zdelta;
float zdeltaf;
// For comparing when a slope should be rendered
fixed_t lowz;
fixed_t highz;
// SRB2CBTODO: This could be used for something?
// Determining the relative z values in a slope?
struct line_s *sourceline;
// This values only check and must be updated if the slope itself is modified
USHORT zangle; // Angle of the plane going up from the ground (not mesured in degrees)
angle_t xydirection; // The direction the slope is facing (north, west, south, etc.)
secplane_t secplane; // Extra data for collision and stuff
} pslope_t;
#endif
typedef enum
{
SF_FLIPSPECIAL_FLOOR = 1,
@ -337,6 +380,11 @@ typedef struct sector_s
precipmobj_t *preciplist;
struct mprecipsecnode_s *touching_preciplist;
#ifdef ESLOPE
// Eternity engine slope
pslope_t *f_slope; // floor slope
pslope_t *c_slope; // ceiling slope
#endif
// these are saved for netgames, so do not let Lua touch these!
// offsets sector spawned with (via linedef type 7)
@ -396,6 +444,12 @@ typedef struct line_s
char *text; // a concatination of all front and back texture names, for linedef specials that require a string.
INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0
#ifdef ESLOPE
// SoM 05/11/09: Pre-calculated 2D normal for the line
float nx, ny;
float len;
#endif
} line_t;
//

View file

@ -2225,9 +2225,6 @@ angle_t tantoangle[2049] =
536870912
};
#ifdef NEED_FIXED_VECTOR
static angle_t fineacon[65536*2] = {
ANGLE_MAX, 2143707442, 2142143280, 2140943052, 2139931208, 2139039753, 2138233813, 2137492672, 2136802831, 2136154917, 2135542102, 2134959233, 2134402306, 2133868139, 2133354148, 2132858208,
2132378539, 2131913638, 2131462220, 2131023174, 2130595537, 2130178462, 2129771202, 2129373097, 2128983555, 2128602046, 2128228092, 2127861261, 2127501162, 2127147436, 2126799757, 2126457825,
@ -10429,6 +10426,8 @@ FUNCMATH angle_t FixedAcos(fixed_t x)
return fineacon[((x<<(FINE_FRACBITS-FRACBITS)))+FRACUNIT];
}
#ifdef NEED_FIXED_VECTOR
//
// AngleBetweenVectors
//

View file

@ -96,12 +96,11 @@ FUNCMATH angle_t FixedAngle(fixed_t fa);
// and with a factor, with +factor for (fa/factor) and -factor for (fa*factor)
FUNCMATH angle_t FixedAngleC(fixed_t fa, fixed_t factor);
#ifdef NEED_FIXED_VECTOR
/// The FixedAcos function
FUNCMATH angle_t FixedAcos(fixed_t x);
#ifdef NEED_FIXED_VECTOR
/// Fixed Point Vector functions
angle_t FV2_AngleBetweenVectors(const vector2_t *Vector1, const vector2_t *Vector2);
angle_t FV3_AngleBetweenVectors(const vector3_t *Vector1, const vector3_t *Vector2);