From 3cd56e456dc8dd52d185e0e5048feede9af34b18 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 7 Dec 2021 19:20:26 +0100 Subject: [PATCH] Rewrite pushable/mobj linedef executor trigger code --- src/p_mobj.c | 30 +------------- src/p_spec.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++----- src/p_spec.h | 2 + 3 files changed, 105 insertions(+), 37 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index fa1ed2443..2c6315271 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10048,15 +10048,7 @@ void P_MobjThinker(mobj_t *mobj) tmfloorthing = tmhitthing = NULL; // Sector special (2,8) allows ANY mobj to trigger a linedef exec - if (mobj->subsector && GETSECSPECIAL(mobj->subsector->sector->special, 2) == 8) - { - sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj); - if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1) - { - mtag_t tag = Tag_FGet(&sec2->tags); - P_LinedefExecute(tag, mobj, sec2); - } - } + P_CheckMobjTrigger(mobj); if (mobj->scale != mobj->destscale) P_MobjScaleThink(mobj); // Slowly scale up/down to reach your destscale. @@ -10271,28 +10263,10 @@ boolean P_RailThinker(mobj_t *mobj) // Unquick, unoptimized function for pushables void P_PushableThinker(mobj_t *mobj) { - sector_t *sec; - I_Assert(mobj != NULL); I_Assert(!P_MobjWasRemoved(mobj)); - sec = mobj->subsector->sector; - - if (GETSECSPECIAL(sec->special, 2) == 1 && mobj->z == sec->floorheight) - { - mtag_t tag = Tag_FGet(&sec->tags); - P_LinedefExecute(tag, mobj, sec); - } - -// else if (GETSECSPECIAL(sec->special, 2) == 8) - { - sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj); - if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1) - { - mtag_t tag = Tag_FGet(&sec2->tags); - P_LinedefExecute(tag, mobj, sec2); - } - } + P_CheckPushableTrigger(mobj, mobj->subsector->sector); // it has to be pushable RIGHT NOW for this part to happen if (mobj->flags & MF_PUSHABLE && !(mobj->momx || mobj->momy)) diff --git a/src/p_spec.c b/src/p_spec.c index feab9f2b6..f4e0648f7 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4811,7 +4811,7 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo) return NULL; } -#define TELEPORTED (player->mo->subsector->sector != originalsector) +#define TELEPORTED(mo) (mo->subsector->sector != originalsector) /** Checks if a player is standing on or is inside a 3D floor (e.g. water) and * applies any specials. @@ -4840,7 +4840,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector) || (rover->master->frontsector->flags & SF_TRIGGERSPECIAL_TOUCH)) { P_ProcessSpecialSector(player, rover->master->frontsector, sector); - if TELEPORTED return; + if TELEPORTED(player->mo) return; } } } @@ -4874,7 +4874,7 @@ static void P_PlayerOnSpecialPolyobj(player_t *player, sector_t *sector) continue; P_ProcessSpecialSector(player, polysec, sector); - if TELEPORTED return; + if TELEPORTED(player->mo) return; } } @@ -4965,14 +4965,14 @@ void P_PlayerInSpecialSector(player_t *player) originalsector = player->mo->subsector->sector; P_PlayerOnSpecial3DFloor(player, originalsector); // Handle FOFs first. - if TELEPORTED return; + if TELEPORTED(player->mo) return; // Allow sector specials to be applied to polyobjects! P_PlayerOnSpecialPolyobj(player, originalsector); - if TELEPORTED return; + if TELEPORTED(player->mo) return; P_RunSpecialSectorCheck(player, originalsector); - if TELEPORTED return; + if TELEPORTED(player->mo) return; // Iterate through touching_sectorlist for SF_TRIGGERSPECIAL_TOUCH for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next) @@ -4984,20 +4984,112 @@ void P_PlayerInSpecialSector(player_t *player) // Check 3D floors... P_PlayerOnSpecial3DFloor(player, loopsector); - if TELEPORTED return; + if TELEPORTED(player->mo) return; // Check polyobjects... P_PlayerOnSpecialPolyobj(player, loopsector); - if TELEPORTED return; + if TELEPORTED(player->mo) return; if (!(loopsector->flags & SF_TRIGGERSPECIAL_TOUCH)) continue; P_RunSpecialSectorCheck(player, loopsector); - if TELEPORTED return; + if TELEPORTED(player->mo) return; } } +static void P_CheckMobj3DFloorTrigger(mobj_t *mo) +{ + sector_t *originalsector = mo->subsector->sector; + ffloor_t *rover; + mtag_t tag; + + for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) + { + if (GETSECSPECIAL(rover->master->frontsector->special, 2) != 1) + continue; + + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!P_IsMobjTouching3DFloor(mo, rover, mo->subsector->sector)) + continue; + + tag = Tag_FGet(&rover->master->frontsector->tags); + P_LinedefExecute(tag, mo, rover->master->frontsector); + if TELEPORTED(mo) return; + } +} + +static void P_CheckMobjPolyobjTrigger(mobj_t *mo) +{ + sector_t *originalsector = mo->subsector->sector; + polyobj_t *po; + sector_t *polysec; + boolean touching = false; + boolean inside = false; + mtag_t tag; + + for (po = mo->subsector->polyList; po; po = (polyobj_t *)(po->link.next)) + { + if (po->flags & POF_NOSPECIALS) + continue; + + polysec = po->lines[0]->backsector; + + if (!polysec->special) + continue; + + touching = (polysec->flags & SF_TRIGGERSPECIAL_TOUCH) && P_MobjTouchingPolyobj(po, mo); + inside = P_MobjInsidePolyobj(po, mo); + + if (!(inside || touching)) + continue; + + if (!P_IsMobjTouchingPolyobj(mo, po, polysec)) + continue; + + tag = Tag_FGet(&polysec->tags); + P_LinedefExecute(tag, mo, polysec); + if TELEPORTED(mo) return; + } +} + +void P_CheckPushableTrigger(mobj_t *mobj, sector_t *sec) +{ + sector_t *originalsector = mobj->subsector->sector; + + P_CheckMobj3DFloorTrigger(mobj); + if TELEPORTED(mobj) return; + + P_CheckMobjPolyobjTrigger(mobj); + if TELEPORTED(mobj) return; + + if (GETSECSPECIAL(sec->special, 2) == 1 && P_IsMobjTouchingSectorPlane(mobj, sec)) + { + mtag_t tag = Tag_FGet(&sec->tags); + P_LinedefExecute(tag, mobj, sec); + } +} + +void P_CheckMobjTrigger(mobj_t *mobj) +{ + sector_t *originalsector; + + if (!mobj->subsector) + return; + + originalsector = mobj->subsector->sector; + + if (GETSECSPECIAL(originalsector->special, 2) != 8) + return; + + P_CheckMobj3DFloorTrigger(mobj); + if TELEPORTED(mobj) return; + + P_CheckMobjPolyobjTrigger(mobj); +} + #undef TELEPORTED /** Animate planes, scroll walls, etc. and keeps track of level timelimit and exits if time is up. diff --git a/src/p_spec.h b/src/p_spec.h index 5e79e9737..50387fbd8 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -322,6 +322,8 @@ void P_SpawnSpecials(boolean fromnetsave); void P_UpdateSpecials(void); sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number); void P_PlayerInSpecialSector(player_t *player); +void P_CheckPushableTrigger(mobj_t *mobj, sector_t *sec); +void P_CheckMobjTrigger(mobj_t *mobj); void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector); fixed_t P_FindLowestFloorSurrounding(sector_t *sec);