Did a bunch of things to/for slopes.

*The No Physics flag now works (Red, you might want to doublecheck this to see whether I haven't missed any eosteric stuff out). Going downhill is a little bumpy, and I'm not sure whether that's good or not. Someone help me out here?
*The SRB2CB typeshims are now behind #ifdef ESLOPE_TYPESHIM instead of #if 1 for easier disabling.
*Slopes' downhill thrusts are now scaled with regards to object gravity. This is actually untested in gravities other than normal and reverse normal but it's one line which can be easily reverted in that circumstance. I also checked with MI to make sure this is how it's calculated elsewhere, so fingers crossed this doesn't cause any edge cases.
*As a consequence of the above point, there's now a function in p_mobj.c/h that returns an object's internal gravity - seperated out from the logic of P_CheckGravity, which really didn't need to be so monolithic. Multiply by global gravity to get the thrust. This should probably be available to Lua somehow, but I have absolutely no idea where to start with that. Wolfs, maybe?

Non-comprehensive test file available at /toaster/slptst3.wad on the ftp.
This commit is contained in:
toasterbabe 2016-05-31 15:01:19 +01:00
parent 2c73e2a2cd
commit fa002e58ad
5 changed files with 69 additions and 29 deletions

View File

@ -431,6 +431,12 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Kalaron/Eternity Engine slope code (SRB2CB ported)
#define ESLOPE
#if defined(ESLOPE)
/// Backwards compatibility with SRB2CB's slope linedef types.
/// \note A simple shim that prints a warning.
#define ESLOPE_TYPESHIM
#endif
/// Delete file while the game is running.
/// \note EXTREMELY buggy, tends to crash game.
//#define DELFILE

View File

@ -1252,13 +1252,12 @@ static void P_PlayerFlip(mobj_t *mo)
}
//
// P_CheckGravity
// P_GetMobjGravity
//
// Checks the current gravity state
// of the object. If affect is true,
// a gravity force will be applied.
// Returns the current gravity
// value of the object.
//
void P_CheckGravity(mobj_t *mo, boolean affect)
fixed_t P_GetMobjGravity(mobj_t *mo)
{
fixed_t gravityadd = 0;
boolean no3dfloorgrav = true; // Custom gravity
@ -1400,11 +1399,25 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
if (goopgravity)
gravityadd = -gravityadd/5;
if (affect)
mo->momz += FixedMul(gravityadd, mo->scale);
if (mo->player && !!(mo->eflags & MFE_VERTICALFLIP) != wasflip)
P_PlayerFlip(mo);
return gravityadd;
}
//
// P_CheckGravity
//
// Checks the current gravity state
// of the object. If affect is true,
// a gravity force will be applied.
//
void P_CheckGravity(mobj_t *mo, boolean affect)
{
fixed_t gravityadd = P_GetMobjGravity(mo);
if (affect)
mo->momz += FixedMul(gravityadd, mo->scale);
if (mo->type == MT_SKIM && mo->z + mo->momz <= mo->watertop && mo->z >= mo->watertop)
{
@ -1480,7 +1493,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
&& abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale)
&& (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING))
#ifdef ESLOPE
&& !(player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2)
&& !(player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && (abs(player->mo->standingslope->zdelta) >= FRACUNIT/2))
#endif
)
{

View File

@ -425,6 +425,9 @@ void P_AddCachedAction(mobj_t *mobj, INT32 statenum);
// check mobj against water content, before movement code
void P_MobjCheckWater(mobj_t *mobj);
// get mobj gravity
fixed_t P_GetMobjGravity(mobj_t *mo);
// Player spawn points
void P_SpawnPlayer(INT32 playernum);
void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing);

View File

@ -16,6 +16,7 @@
#include "m_bbox.h"
#include "z_zone.h"
#include "p_local.h"
#include "p_mobj.h"
#include "p_spec.h"
#include "p_slopes.h"
#include "p_setup.h"
@ -881,7 +882,7 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum)
// Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes
void P_ResetDynamicSlopes(void) {
size_t i;
#if 1 // Rewrite old specials to new ones, and give a console warning
#ifdef ESLOPE_TYPESHIM // Rewrite old specials to new ones, and give a console warning
boolean warned = false;
#endif
@ -894,7 +895,7 @@ void P_ResetDynamicSlopes(void) {
{
switch (lines[i].special)
{
#if 1 // Rewrite old specials to new ones, and give a console warning
#ifdef ESLOPE_TYPESHIM // Rewrite old specials to new ones, and give a console warning
#define WARNME if (!warned) {warned = true; CONS_Alert(CONS_WARNING, "This level uses old slope specials.\nA conversion will be needed before 2.2's release.\n");}
case 386:
case 387:
@ -1018,6 +1019,9 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y)
// When given a vector, rotates it and aligns it to a slope
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
{
if (slope->flags & SL_NOPHYSICS)
return; // No physics, no quantizing.
vector3_t axis;
axis.x = -slope->d.y;
axis.y = slope->d.x;
@ -1032,26 +1036,37 @@ void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
// Handles slope ejection for objects
void P_SlopeLaunch(mobj_t *mo)
{
// Double the pre-rotation Z, then halve the post-rotation Z. This reduces the
// vertical launch given from slopes while increasing the horizontal launch
// given. Good for SRB2's gravity and horizontal speeds.
vector3_t slopemom;
slopemom.x = mo->momx;
slopemom.y = mo->momy;
slopemom.z = mo->momz*2;
P_QuantizeMomentumToSlope(&slopemom, mo->standingslope);
mo->momx = slopemom.x;
mo->momy = slopemom.y;
mo->momz = slopemom.z/2;
if (!(mo->standingslope->flags & SL_NOPHYSICS)) // If there's physics, time for launching.
{
// Double the pre-rotation Z, then halve the post-rotation Z. This reduces the
// vertical launch given from slopes while increasing the horizontal launch
// given. Good for SRB2's gravity and horizontal speeds.
vector3_t slopemom;
slopemom.x = mo->momx;
slopemom.y = mo->momy;
slopemom.z = mo->momz*2;
P_QuantizeMomentumToSlope(&slopemom, mo->standingslope);
mo->momx = slopemom.x;
mo->momy = slopemom.y;
mo->momz = slopemom.z/2;
}
//CONS_Printf("Launched off of slope.\n");
mo->standingslope = NULL;
}
// Function to help handle landing on slopes
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
{
{
if (slope->flags & SL_NOPHYSICS) { // No physics, no need to make anything complicated.
if (P_MobjFlip(thing)*(thing->momz) < 0) { // falling, land on slope
thing->momz = -P_MobjFlip(thing);
thing->standingslope = slope;
}
return;
}
vector3_t mom;
mom.x = thing->momx;
mom.y = thing->momy;
@ -1081,6 +1096,9 @@ void P_ButteredSlope(mobj_t *mo)
if (!mo->standingslope)
return;
if (mo->standingslope->flags & SL_NOPHYSICS)
return; // No physics, no butter.
if (mo->flags & (MF_NOCLIPHEIGHT|MF_NOGRAVITY))
return; // don't slide down slopes if you can't touch them or you're not affected by gravity
@ -1116,7 +1134,7 @@ void P_ButteredSlope(mobj_t *mo)
// This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down
// Multiply by gravity
thrust = FixedMul(thrust, gravity); // TODO account for per-sector gravity etc
thrust = FixedMul(thrust, FixedMul(gravity, abs(P_GetMobjGravity(mo)))); // Now uses the absolute of mobj gravity. You're welcome.
// Multiply by scale (gravity strength depends on mobj scale)
thrust = FixedMul(thrust, mo->scale);

View File

@ -3741,7 +3741,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
{
if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<<FRACBITS, player->mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)
#ifdef ESLOPE
&& (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
&& (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
#endif
)
{
@ -3774,7 +3774,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
else if ((cmd->buttons & BT_USE || ((twodlevel || (player->mo->flags2 & MF2_TWOD)) && cmd->forwardmove < -20))
&& !player->climbing && !player->mo->momz && onground && (player->speed > FixedMul(5<<FRACBITS, player->mo->scale)
#ifdef ESLOPE
|| (player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2)
|| (player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2)
#endif
) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING))
{
@ -3790,7 +3790,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH)
&& player->speed < FixedMul(5*FRACUNIT,player->mo->scale)
#ifdef ESLOPE
&& (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
&& (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
#endif
)
{
@ -4776,7 +4776,7 @@ static void P_3dMovement(player_t *player)
#ifdef ESLOPE
if ((totalthrust.x || totalthrust.y)
&& player->mo->standingslope && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) {
&& player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) {
// Factor thrust to slope, but only for the part pushing up it!
// The rest is unaffected.
angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection;