diff --git a/src/k_kart.c b/src/k_kart.c index 6c268269d..cb82dba93 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1542,7 +1542,7 @@ static UINT8 K_CheckOffroadCollide(mobj_t *mo) for (i = 2; i < 5; i++) { - if (P_MobjTouchingSectorSpecial(mo, 1, i)) + if (P_MobjTouchingSectorSpecial(mo, 1, i, true)) return i-1; } diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 3d836dad2..bb7d1111b 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1318,10 +1318,11 @@ static int lib_pMobjTouchingSectorSpecial(lua_State *L) mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); INT32 section = (INT32)luaL_checkinteger(L, 2); INT32 number = (INT32)luaL_checkinteger(L, 3); + boolean touchground = lua_optboolean(L, 4); //HUDSAFE if (!mo) return LUA_ErrInvalid(L, "mobj_t"); - LUA_PushUserdata(L, P_MobjTouchingSectorSpecial(mo, section, number), META_SECTOR); + LUA_PushUserdata(L, P_MobjTouchingSectorSpecial(mo, section, number, touchground), META_SECTOR); return 1; } diff --git a/src/p_floor.c b/src/p_floor.c index a4e4f2747..3621e0886 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2275,7 +2275,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) continue; if (!(players[i].mo->subsector->sector == sec - || P_MobjTouchingSectorSpecial(players[i].mo, 2, (GETSECSPECIAL(sec->special, 2))) == sec)) + || P_MobjTouchingSectorSpecial(players[i].mo, 2, (GETSECSPECIAL(sec->special, 2)), false) == sec)) continue; if (floortouch == true && P_IsObjectOnRealGround(players[i].mo, sec)) diff --git a/src/p_inter.c b/src/p_inter.c index a1a44c998..b81d3296d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -925,7 +925,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->fuse = 1; special->flags2 |= MF2_JUSTATTACKED; - if (!P_MobjTouchingSectorSpecial(player->mo, 4, 2 + flagteam)) + if (!P_MobjTouchingSectorSpecial(player->mo, 4, 2 + flagteam, false)) { CONS_Printf(M_GetText("%s returned the %c%s%c to base.\n"), plname, flagcolor, flagtext, 0x80); diff --git a/src/p_map.c b/src/p_map.c index 22e624311..19006fe49 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2790,10 +2790,10 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale); // If using type Section1:13, double the maxstep. - if (P_MobjTouchingSectorSpecial(thing, 1, 13)) + if (P_MobjTouchingSectorSpecial(thing, 1, 13, false)) maxstep <<= 1; // If using type Section1:12, no maxstep. For short walls, like Egg Zeppelin - else if (P_MobjTouchingSectorSpecial(thing, 1, 12)) + else if (P_MobjTouchingSectorSpecial(thing, 1, 12, false)) maxstep = 0; if (thing->type == MT_SKIM) @@ -2817,7 +2817,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) return false; // mobj must lower itself to fit // Ramp test - if ((maxstep > 0) && !(P_MobjTouchingSectorSpecial(thing, 1, 14))) + if ((maxstep > 0) && !(P_MobjTouchingSectorSpecial(thing, 1, 14, false))) { // If the floor difference is MAXSTEPMOVE or less, and the sector isn't Section1:14, ALWAYS // step down! Formerly required a Section1:13 sector for the full MAXSTEPMOVE, but no more. diff --git a/src/p_mobj.c b/src/p_mobj.c index 1fd846ff1..2bb445e73 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8355,7 +8355,7 @@ void P_MobjThinker(mobj_t *mobj) P_Thrust(mobj, mobj->angle, thrustamount); - if (P_MobjTouchingSectorSpecial(mobj, 3, 1)) + if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) K_DoPogoSpring(mobj, 0, 1); if (mobj->threshold > 0) @@ -8385,7 +8385,7 @@ void P_MobjThinker(mobj_t *mobj) K_DriftDustHandling(mobj); - if (P_MobjTouchingSectorSpecial(mobj, 3, 1)) + if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) K_DoPogoSpring(mobj, 0, 1); break; @@ -8437,14 +8437,8 @@ void P_MobjThinker(mobj_t *mobj) mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); P_Thrust(mobj, mobj->angle, thrustamount); - if (grounded) - { - sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) - || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) - && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) - K_DoPogoSpring(mobj, 0, 1); - } + if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) + K_DoPogoSpring(mobj, 0, 1); if (mobj->threshold > 0) mobj->threshold--; @@ -9592,7 +9586,7 @@ void P_MobjThinker(mobj_t *mobj) break; case MT_BLUEFLAG: case MT_REDFLAG: - if (P_MobjTouchingSectorSpecial(mobj, 4, 2)) + if (P_MobjTouchingSectorSpecial(mobj, 4, 2, false)) mobj->fuse = 1; // Return to base. break; case MT_CANNONBALL: diff --git a/src/p_spec.c b/src/p_spec.c index 7786329ec..9ce9c9faf 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3371,11 +3371,12 @@ boolean P_IsFlagAtBase(mobjtype_t flag) // the particular type that it finds. // Returns NULL if it doesn't find it. // -// Sal: There was absolutely no reason for -// this to be a player_t only function. +// Sal: Couldn't see a reason for this to +// be a player_t only function. // -sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number) +sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number, boolean touchground) { + fixed_t topheight, bottomheight; msecnode_t *node; ffloor_t *rover; @@ -3384,13 +3385,34 @@ sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number) // Check default case first if (GETSECSPECIAL(mo->subsector->sector->special, section) == number) - return mo->subsector->sector; + { + if (touchground) + { + topheight = P_GetSpecialTopZ(mo, mo->subsector->sector, mo->subsector->sector); + bottomheight = P_GetSpecialBottomZ(mo, mo->subsector->sector, mo->subsector->sector); + + // Thing must be on top of the floor to be affected... + if (mo->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR) + { + if (!(mo->eflags & MFE_VERTICALFLIP) && mo->z <= bottomheight) + return mo->subsector->sector; + } + + if (mo->subsector->sector->flags & SF_FLIPSPECIAL_CEILING) + { + if ((mo->eflags & MFE_VERTICALFLIP) && mo->z + mo->height >= topheight) + return mo->subsector->sector; + } + } + else + { + return mo->subsector->sector; + } + } // Hmm.. maybe there's a FOF that has it... for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) { - fixed_t topheight, bottomheight; - if (GETSECSPECIAL(rover->master->frontsector->special, section) != number) continue; @@ -3444,14 +3466,35 @@ sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number) // are we allowed to touch it? if (node->m_sector == mo->subsector->sector || (node->m_sector->flags & SF_TRIGGERSPECIAL_TOUCH)) - return node->m_sector; + { + if (touchground) + { + topheight = P_GetSpecialTopZ(mo, node->m_sector, node->m_sector); + bottomheight = P_GetSpecialBottomZ(mo, node->m_sector, node->m_sector); + + // Thing must be on top of the floor to be affected... + if (node->m_sector->flags & SF_FLIPSPECIAL_FLOOR) + { + if (!(mo->eflags & MFE_VERTICALFLIP) && mo->z <= bottomheight) + return node->m_sector; + } + + if (node->m_sector->flags & SF_FLIPSPECIAL_CEILING) + { + if ((mo->eflags & MFE_VERTICALFLIP) && mo->z + mo->height >= topheight) + return node->m_sector; + } + } + else + { + return node->m_sector; + } + } } // Hmm.. maybe there's a FOF that has it... for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - fixed_t topheight, bottomheight; - if (GETSECSPECIAL(rover->master->frontsector->special, section) != number) continue; diff --git a/src/p_spec.h b/src/p_spec.h index 8431fcc75..eff7463ca 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -37,7 +37,7 @@ void P_SpawnSpecials(INT32 fromnetsave); // every tic void P_UpdateSpecials(void); -sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number); +sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number, boolean touchground); void P_PlayerInSpecialSector(player_t *player); void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector);