From 150faf9de67dfdb8a106233d6595e09a7ee471fb Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 9 Dec 2021 00:56:05 -0500 Subject: [PATCH] Add terrain pointer to mobj_t --- src/k_kart.c | 1 + src/k_terrain.c | 88 ++++++++++++++++++++++++++++++++++++++++--------- src/k_terrain.h | 14 ++++++++ src/p_inter.c | 1 + src/p_local.h | 1 + src/p_map.c | 51 +++++++++++++++++++++++++--- src/p_maputl.c | 8 +++++ src/p_maputl.h | 1 + src/p_mobj.c | 79 ++++++++++++++++++++++++++++++-------------- src/p_mobj.h | 1 + src/p_slopes.c | 1 + 11 files changed, 203 insertions(+), 43 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 73661c018..cf51e3646 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5176,6 +5176,7 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) return; mo->standingslope = NULL; + mo->terrain = NULL; mo->eflags |= MFE_SPRUNG; diff --git a/src/k_terrain.c b/src/k_terrain.c index 77537f0f3..fabc89882 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -14,9 +14,13 @@ #include "k_terrain.h" #include "dehacked.h" // get_number +#include "doomdata.h" +#include "doomdef.h" #include "doomtype.h" #include "fastcmp.h" #include "m_fixed.h" +#include "p_local.h" +#include "p_mobj.h" #include "r_textures.h" #include "w_wad.h" #include "z_zone.h" @@ -120,10 +124,51 @@ terrain_t *K_GetTerrainForTextureName(const char *checkName) return K_GetTerrainForTextureNum( R_CheckTextureNumForName(checkName) ); } +void K_UpdateMobjTerrain(mobj_t *mo, INT32 flatID) +{ + levelflat_t *levelFlat = NULL; + + if (mo == NULL || P_MobjWasRemoved(mo) == true) + { + // Invalid object. + return; + } + + if (flatID < 0 || flatID >= (signed)numlevelflats) + { + // Clearly invalid floor... + mo->terrain = NULL; + return; + } + + if (mo->flags & MF_NOCLIPHEIGHT) + { + // You can't collide with floors anyway! + mo->terrain = NULL; + return; + } + + // Update the object's terrain pointer. + levelFlat = &levelflats[flatID]; + mo->terrain = K_GetTerrainForTextureName(levelFlat->name); +} + // // Parser code starts here. // +static void K_FlagBoolean(UINT32 *inputFlags, UINT32 newFlag, char *val) +{ + if (stricmp(val, "true") == 0) + { + *inputFlags |= newFlag; + } + else if (stricmp(val, "false") == 0) + { + *inputFlags &= ~newFlag; + } +} + static void K_TerrainDefaults(terrain_t *terrain) { terrain->splashID = UINT16_MAX; @@ -132,6 +177,8 @@ static void K_TerrainDefaults(terrain_t *terrain) terrain->friction = FRACUNIT; terrain->offroad = 0; terrain->damageType = -1; + terrain->trickPanel = 0; + terrain->flags = 0; } static void K_NewTerrainDefs(void) @@ -159,12 +206,24 @@ static void K_ParseTerrainParameter(UINT32 i, char *param, char *val) } else if (stricmp(param, "offroad") == 0) { - terrain->offroad = (UINT8)get_number(val); + terrain->offroad = (UINT8)get_number(val); // offroad strength enum? } else if (stricmp(param, "damageType") == 0) { terrain->damageType = (INT16)get_number(val); } + else if (stricmp(param, "trickPanel") == 0) + { + terrain->trickPanel = (UINT8)get_number(val); // trick panel strength enum? + } + else if (stricmp(param, "liquid") == 0) + { + K_FlagBoolean(&terrain->flags, TRF_LIQUID, val); + } + else if (stricmp(param, "sneakerPanel") == 0) + { + K_FlagBoolean(&terrain->flags, TRF_SNEAKERPANEL, val); + } } static boolean K_DoTERRAINLumpParse(size_t num, void (*parser)(UINT32, char *, char *)) @@ -210,14 +269,13 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) while (tkn && (pos = M_GetTokenPos()) < size) { - boolean result = true; + boolean valid = true; // Avoid anything inside bracketed stuff, only look for external keywords. if (fastcmp(tkn, "{") || fastcmp(tkn, "}")) { CONS_Alert(CONS_ERROR, "Rogue bracket detected in TERRAIN lump.\n"); - Z_Free(tkn); - return false; + valid = false; } // Check for valid fields. else if (stricmp(tkn, "terrain") == 0) @@ -249,28 +307,28 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) CONS_Printf("Created new Terrain type '%s'\n", t->name); } - result = K_DoTERRAINLumpParse(i, K_ParseTerrainParameter); + valid = K_DoTERRAINLumpParse(i, K_ParseTerrainParameter); } // TODO: the other block types! else { - CONS_Alert(CONS_NOTICE, "No terrain type name.\n"); + CONS_Alert(CONS_ERROR, "No terrain type name.\n"); + valid = false; } } else { - CONS_Alert(CONS_NOTICE, "Unknown field '%s' found in TERRAIN lump.\n", tkn); - Z_Free(tkn); - return false; - } - - if (result == false) - { - Z_Free(tkn); - return false; + CONS_Alert(CONS_ERROR, "Unknown field '%s' found in TERRAIN lump.\n", tkn); + valid = false; } Z_Free(tkn); + + if (valid == false) + { + return false; + } + tkn = M_GetToken(NULL); } diff --git a/src/k_terrain.h b/src/k_terrain.h index d774fa130..94db49dfb 100644 --- a/src/k_terrain.h +++ b/src/k_terrain.h @@ -14,8 +14,11 @@ #ifndef __K_TERRAIN_H__ #define __K_TERRAIN_H__ +#include "doomdata.h" +#include "doomdef.h" #include "doomtype.h" #include "m_fixed.h" +#include "p_mobj.h" #define TERRAIN_NAME_LEN 32 @@ -41,6 +44,13 @@ typedef struct t_footstep_s UINT16 sound; // Sound to play. } t_footstep_t; +typedef enum +{ + // Terrain flag values. + TRF_LIQUID = 1, // Texture water properties (wavy, slippery, etc) + TRF_SNEAKERPANEL = 1<<1 // Texture is a booster +} terrain_flags_t; + typedef struct terrain_s { // Terrain definition. @@ -57,6 +67,8 @@ typedef struct terrain_s fixed_t friction; // The default friction of this texture. UINT8 offroad; // The default offroad level of this texture. INT16 damageType; // The default damage type of this texture. (Negative means no damage). + UINT8 trickPanel; // Trick panel strength + UINT32 flags; // Flag values (see: terrain_flags_t) } terrain_t; // Arrays for all terrain definitions. @@ -78,6 +90,8 @@ terrain_t *K_GetDefaultTerrain(void); terrain_t *K_GetTerrainForTextureNum(INT32 textureNum); terrain_t *K_GetTerrainForTextureName(const char *checkName); +void K_UpdateMobjTerrain(mobj_t *mo, INT32 flatID); + void K_InitTerrain(UINT16 wadNum); #endif // __K_TERRAIN_H__ diff --git a/src/p_inter.c b/src/p_inter.c index 0a2bb4e13..e0171522e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1061,6 +1061,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; P_SetThingPosition(target); target->standingslope = NULL; + target->terrain = NULL; target->pmomz = 0; target->player->playerstate = PST_DEAD; diff --git a/src/p_local.h b/src/p_local.h index 61a8cf3a0..fa6e39670 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -384,6 +384,7 @@ extern camera_t *mapcampointer; extern fixed_t tmx; extern fixed_t tmy; extern pslope_t *tmfloorslope, *tmceilingslope; +extern INT32 tmfloorpic, tmceilingpic; /* cphipps 2004/08/30 */ extern void P_MapStart(void); diff --git a/src/p_map.c b/src/p_map.c index d0716790b..36ec3ef0a 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -24,12 +24,13 @@ #include "r_sky.h" #include "s_sound.h" #include "w_wad.h" + #include "k_kart.h" // SRB2kart 011617 #include "k_collide.h" #include "k_respawn.h" - #include "hu_stuff.h" // SRB2kart #include "i_system.h" // SRB2kart +#include "k_terrain.h" #include "r_splats.h" @@ -60,6 +61,7 @@ mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz mobj_t *tmhitthing; // the solid thing you bumped into (for collisions) ffloor_t *tmfloorrover, *tmceilingrover; pslope_t *tmfloorslope, *tmceilingslope; +INT32 tmfloorpic, tmceilingpic; static fixed_t tmfloorstep; static fixed_t tmceilingstep; @@ -303,6 +305,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) } object->standingslope = NULL; // Okay, now we know it's not going to be relevant - no launching off at silly angles for you. + object->terrain = NULL; object->eflags |= MFE_SPRUNG; // apply this flag asap! spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify @@ -441,6 +444,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) } object->standingslope = NULL; // No launching off at silly angles for you. + object->terrain = NULL; switch (spring->type) { @@ -1427,6 +1431,7 @@ static boolean PIT_CheckThing(mobj_t *thing) tmfloorz = thing->z + thing->height; tmfloorrover = NULL; tmfloorslope = NULL; + tmfloorpic = -1; } return true; } @@ -1446,6 +1451,7 @@ static boolean PIT_CheckThing(mobj_t *thing) tmfloorz = tmceilingz = topz; // block while in air tmceilingrover = NULL; tmceilingslope = NULL; + tmceilingpic = -1; tmfloorthing = thing; // needed for side collision } else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height) @@ -1453,6 +1459,7 @@ static boolean PIT_CheckThing(mobj_t *thing) tmceilingz = topz; tmceilingrover = NULL; tmceilingslope = NULL; + tmceilingpic = -1; tmfloorthing = thing; // thing we may stand on } } @@ -1468,6 +1475,7 @@ static boolean PIT_CheckThing(mobj_t *thing) tmceilingz = thing->z; tmceilingrover = NULL; tmceilingslope = NULL; + tmceilingpic = -1; } return true; } @@ -1487,6 +1495,7 @@ static boolean PIT_CheckThing(mobj_t *thing) tmfloorz = tmceilingz = topz; // block while in air tmfloorrover = NULL; tmfloorslope = NULL; + tmfloorpic = -1; tmfloorthing = thing; // needed for side collision } else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z) @@ -1494,6 +1503,7 @@ static boolean PIT_CheckThing(mobj_t *thing) tmfloorz = topz; tmfloorrover = NULL; tmfloorslope = NULL; + tmfloorpic = -1; tmfloorthing = thing; // thing we may stand on } } @@ -1673,6 +1683,7 @@ static boolean PIT_CheckLine(line_t *ld) ceilingline = ld; tmceilingrover = openceilingrover; tmceilingslope = opentopslope; + tmceilingpic = opentoppic; tmceilingstep = openceilingstep; if (thingtop == tmthing->ceilingz) { @@ -1685,6 +1696,7 @@ static boolean PIT_CheckLine(line_t *ld) tmfloorz = openbottom; tmfloorrover = openfloorrover; tmfloorslope = openbottomslope; + tmfloorpic = openbottompic; tmfloorstep = openfloorstep; if (tmthing->z == tmthing->floorz) { @@ -1781,6 +1793,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) tmceilingrover = NULL; tmfloorslope = newsubsec->sector->f_slope; tmceilingslope = newsubsec->sector->c_slope; + tmfloorpic = newsubsec->sector->floorpic; + tmceilingpic = newsubsec->sector->ceilingpic; tmfloorstep = 0; tmceilingstep = 0; @@ -1834,6 +1848,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) tmfloorz = topheight - sinklevel; tmfloorrover = rover; tmfloorslope = *rover->t_slope; + tmfloorpic = *rover->toppic; } } else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= bottomheight + sinklevel && thing->momz >= 0) @@ -1842,6 +1857,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) tmceilingz = bottomheight + sinklevel; tmceilingrover = rover; tmceilingslope = *rover->b_slope; + tmceilingpic = *rover->bottompic; } } } @@ -1865,6 +1881,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) tmfloorz = thing->z; tmfloorrover = rover; tmfloorslope = NULL; + tmfloorpic = *rover->toppic; } } // Quicksand blocks never change heights otherwise. @@ -1882,6 +1899,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) tmfloorz = tmdropoffz = topheight; tmfloorrover = rover; tmfloorslope = *rover->t_slope; + tmfloorpic = *rover->toppic; } if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2) && !(rover->flags & FF_PLATFORM) @@ -1890,6 +1908,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) tmceilingz = tmdrpoffceilz = bottomheight; tmceilingrover = rover; tmceilingslope = *rover->b_slope; + tmceilingpic = *rover->bottompic; } } } @@ -1964,12 +1983,14 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) tmfloorz = tmdropoffz = polytop; tmfloorslope = NULL; tmfloorrover = NULL; + tmfloorpic = polysec->ceilingpic; } if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) { tmceilingz = tmdrpoffceilz = polybottom; tmceilingslope = NULL; tmceilingrover = NULL; + tmceilingpic = polysec->floorpic; } } plink = (polymaplink_t *)(plink->link.next); @@ -2387,6 +2408,8 @@ boolean PIT_PushableMoved(mobj_t *thing) ffloor_t *oldceilrover = tmceilingrover; pslope_t *oldfslope = tmfloorslope; pslope_t *oldcslope = tmceilingslope; + INT32 oldfpic = tmfloorpic; + INT32 oldcpic = tmceilingpic; // Move the player P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true); @@ -2403,6 +2426,8 @@ boolean PIT_PushableMoved(mobj_t *thing) tmceilingrover = oldceilrover; tmfloorslope = oldfslope; tmceilingslope = oldcslope; + tmfloorpic = oldfpic; + tmceilingpic = oldcpic; thing->momz = stand->momz; } else @@ -2616,9 +2641,14 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (!(thing->flags & MF_NOCLIPHEIGHT)) { // Assign thing's standingslope if needed - if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) { + if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) + { + K_UpdateMobjTerrain(thing, tmfloorpic); + if (!startingonground && tmfloorslope) + { P_HandleSlopeLanding(thing, tmfloorslope); + } if (thing->momz <= 0) { @@ -2626,12 +2656,19 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) P_SetPitchRollFromSlope(thing, thing->standingslope); if (thing->momz == 0 && thing->player && !startingonground) + { P_PlayerHitFloor(thing->player, true); + } } } - else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) { + else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) + { + K_UpdateMobjTerrain(thing, tmceilingpic); + if (!startingonground && tmceilingslope) + { P_HandleSlopeLanding(thing, tmceilingslope); + } if (thing->momz >= 0) { @@ -2639,12 +2676,18 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) P_SetPitchRollFromSlope(thing, thing->standingslope); if (thing->momz == 0 && thing->player && !startingonground) + { P_PlayerHitFloor(thing->player, true); + } } } } - else // don't set standingslope if you're not going to clip against it + else + { + // don't set standingslope if you're not going to clip against it thing->standingslope = NULL; + thing->terrain = NULL; + } /* FIXME: slope step down (even up) has some false positives, so just ignore them entirely. */ diff --git a/src/p_maputl.c b/src/p_maputl.c index 2e21f5ee3..e30c0e0da 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -342,6 +342,7 @@ fixed_t openceilingstep; fixed_t openceilingdrop; fixed_t openfloorstep; fixed_t openfloordrop; +INT32 opentoppic, openbottompic; // P_CameraLineOpening // P_LineOpening, but for camera @@ -537,6 +538,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) highceiling = INT32_MIN; lowfloor = INT32_MAX; opentopslope = openbottomslope = NULL; + opentoppic = openbottompic = -1; openceilingstep = 0; openceilingdrop = 0; openfloorstep = 0; @@ -556,6 +558,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) opentop = height[lo]; highceiling = height[hi]; opentopslope = sector[lo]->c_slope; + opentoppic = sector[lo]->ceilingpic; if (mobj) { @@ -575,6 +578,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) openbottom = height[hi]; lowfloor = height[lo]; openbottomslope = sector[hi]->f_slope; + openbottompic = sector[hi]->floorpic; if (mobj) { @@ -747,6 +751,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if (bottomheight < open[FRONT].top) { open[FRONT].top = bottomheight; opentopslope = *rover->b_slope; + opentoppic = *rover->bottompic; open[FRONT].ceilingrover = rover; } else if (bottomheight < highceiling) @@ -758,6 +763,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if (topheight > open[FRONT].bottom) { open[FRONT].bottom = topheight; openbottomslope = *rover->t_slope; + openbottompic = *rover->toppic; open[FRONT].floorrover = rover; } else if (topheight > lowfloor) @@ -789,6 +795,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if (bottomheight < open[BACK].top) { open[BACK].top = bottomheight; opentopslope = *rover->b_slope; + opentoppic = *rover->bottompic; open[BACK].ceilingrover = rover; } else if (bottomheight < highceiling) @@ -800,6 +807,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if (topheight > open[BACK].bottom) { open[BACK].bottom = topheight; openbottomslope = *rover->t_slope; + openbottompic = *rover->toppic; open[BACK].floorrover = rover; } else if (topheight > lowfloor) diff --git a/src/p_maputl.h b/src/p_maputl.h index 6f0c1f8ad..43a7fb507 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -63,6 +63,7 @@ extern fixed_t openceilingstep; extern fixed_t openceilingdrop; extern fixed_t openfloorstep; extern fixed_t openfloordrop; +extern INT32 opentoppic, openbottompic; void P_LineOpening(line_t *plinedef, mobj_t *mobj); diff --git a/src/p_mobj.c b/src/p_mobj.c index b066e2a1c..46394dd24 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -40,6 +40,7 @@ #include "k_color.h" #include "k_respawn.h" #include "k_bot.h" +#include "k_terrain.h" static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}}; consvar_t cv_movebob = CVAR_INIT ("movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL); @@ -1505,7 +1506,10 @@ void P_XYMovement(mobj_t *mo) oldy = mo->y; if (mo->flags & MF_NOCLIPHEIGHT) + { mo->standingslope = NULL; + mo->terrain = NULL; + } // adjust various things based on slope if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) { @@ -1671,6 +1675,7 @@ void P_XYMovement(mobj_t *mo) { mo->momz = transfermomz; mo->standingslope = NULL; + mo->terrain = NULL; P_SetPitchRoll(mo, ANGLE_90, transferslope->xydirection + (transferslope->zangle @@ -1782,6 +1787,7 @@ void P_XYMovement(mobj_t *mo) mo->momz = P_MobjFlip(mo)*FRACUNIT/2; mo->z = predictedz + P_MobjFlip(mo); mo->standingslope = NULL; + mo->terrain = NULL; //CONS_Printf("Launched off of flat surface running into downward slope\n"); } } @@ -2274,6 +2280,8 @@ boolean P_ZMovement(mobj_t *mo) } P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly + K_UpdateMobjTerrain(mo, ((mo->eflags & MFE_VERTICALFLIP) ? tmceilingpic : tmfloorpic)); + if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM)) { mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; @@ -2503,12 +2511,17 @@ boolean P_ZMovement(mobj_t *mo) if (mo->type == MT_STEAM) return true; } - else if (!(mo->flags & MF_NOGRAVITY)) // Gravity here! + else { - /// \todo may not be needed (done in P_MobjThinker normally) - mo->eflags &= ~MFE_JUSTHITFLOOR; + mo->terrain = NULL; - P_CheckGravity(mo, true); + if (!(mo->flags & MF_NOGRAVITY)) // Gravity here! + { + /// \todo may not be needed (done in P_MobjThinker normally) + mo->eflags &= ~MFE_JUSTHITFLOOR; + + P_CheckGravity(mo, true); + } } if (((mo->z + mo->height > mo->ceilingz && !(mo->eflags & MFE_VERTICALFLIP)) @@ -2712,20 +2725,29 @@ void P_PlayerZMovement(mobj_t *mo) if (onground && !(mo->flags & MF_NOCLIPHEIGHT)) { if (mo->eflags & MFE_VERTICALFLIP) + { mo->z = mo->ceilingz - mo->height; + } else + { mo->z = mo->floorz; + } + + K_UpdateMobjTerrain(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingpic : tmfloorpic)); // Get up if you fell. if (mo->player->panim == PA_HURT && mo->player->spinouttimer == 0 && mo->player->tumbleBounces == 0) + { P_SetPlayerMobjState(mo, S_KART_STILL); + } - if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) { + if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) + { // Handle landing on slope during Z movement P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)); } - if (P_MobjFlip(mo)*mo->momz < 0) // falling + if (P_MobjFlip(mo) * mo->momz < 0) // falling { boolean clipmomz = !(P_CheckDeathPitCollide(mo)); @@ -2736,29 +2758,38 @@ void P_PlayerZMovement(mobj_t *mo) P_PlayerPolyObjectZMovement(mo); if (clipmomz) + { mo->momz = (tmfloorthing ? tmfloorthing->momz : 0); + } } else if (tmfloorthing) - mo->momz = tmfloorthing->momz; - } - else if (!(mo->flags & MF_NOGRAVITY)) // Gravity here! - { - if (P_IsObjectInGoop(mo) && !(mo->flags & MF_NOCLIPHEIGHT)) { - if (mo->z < mo->floorz) - { - mo->z = mo->floorz; - mo->momz = 0; - } - else if (mo->z + mo->height > mo->ceilingz) - { - mo->z = mo->ceilingz - mo->height; - mo->momz = 0; - } + mo->momz = tmfloorthing->momz; + } + } + else + { + mo->terrain = NULL; + + if (!(mo->flags & MF_NOGRAVITY)) // Gravity here! + { + if (P_IsObjectInGoop(mo) && !(mo->flags & MF_NOCLIPHEIGHT)) + { + if (mo->z < mo->floorz) + { + mo->z = mo->floorz; + mo->momz = 0; + } + else if (mo->z + mo->height > mo->ceilingz) + { + mo->z = mo->ceilingz - mo->height; + mo->momz = 0; + } + } + /// \todo may not be needed (done in P_MobjThinker normally) + mo->eflags &= ~MFE_JUSTHITFLOOR; + P_CheckGravity(mo, true); } - /// \todo may not be needed (done in P_MobjThinker normally) - mo->eflags &= ~MFE_JUSTHITFLOOR; - P_CheckGravity(mo, true); } if (((mo->eflags & MFE_VERTICALFLIP && mo->z < mo->floorz) || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z + mo->height > mo->ceilingz)) diff --git a/src/p_mobj.h b/src/p_mobj.h index 2373bdca4..9d73c433b 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -395,6 +395,7 @@ typedef struct mobj_s fixed_t sprxoff, spryoff, sprzoff; // Sprite offsets in real space, does NOT affect position or collision + struct terrain_s *terrain; // Terrain definition of the floor this object last hit. NULL when in the air. INT32 hitlag; // Sal-style hit lag, straight from Captain Fetch's jowls // WARNING: New fields must be added separately to savegame and Lua. diff --git a/src/p_slopes.c b/src/p_slopes.c index 1bde8f4ee..6c660ad0f 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -850,6 +850,7 @@ void P_SlopeLaunch(mobj_t *mo) //CONS_Printf("Launched off of slope.\n"); mo->standingslope = NULL; + mo->terrain = NULL; if (mo->player) {