Rewrite pushable/mobj linedef executor trigger code

This commit is contained in:
MascaraSnake 2021-12-07 19:20:26 +01:00
parent c9ed484129
commit 3cd56e456d
3 changed files with 105 additions and 37 deletions

View file

@ -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))

View file

@ -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.

View file

@ -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);