Activate sector each time / once actions when mobj touches the ground

Before

- Each time / once only activates when the mobj's sector
  changes
- The activation may depend on the mobj touching the floor
- If the mobj is in the air when the sector changes, the
  action will never be activated

After

- Each time / once actions that require floor touching
  also activate every time the mobj lands on the ground
  from the air (regardless of whether the sector changed)
This commit is contained in:
James R 2024-02-01 18:51:07 -08:00
parent ebbe8203a2
commit c0fff1a0c4
5 changed files with 57 additions and 21 deletions

View file

@ -103,6 +103,9 @@ camera_t *mapcampointer;
//
static boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
{
boolean startingonground = P_IsObjectOnGround(thing);
sector_t *oldsector = thing->subsector->sector;
numspechit = 0U;
// the move is ok,
@ -132,6 +135,8 @@ static boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
thing->floorrover = tm.floorrover;
thing->ceilingrover = tm.ceilingrover;
P_CheckSectorTransitionalEffects(thing, oldsector, startingonground);
return true;
}
@ -3106,6 +3111,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff, Try
fixed_t startingonground = P_IsObjectOnGround(thing);
fixed_t stairjank = 0;
pslope_t *oldslope = thing->standingslope;
sector_t *oldsector = thing->subsector->sector;
// Is the move OK?
if (increment_move(thing, x, y, allowdropoff, &stairjank, result) == false)
@ -3243,6 +3249,8 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff, Try
P_SetThingPosition(thing);
P_CheckSectorTransitionalEffects(thing, oldsector, startingonground);
// remove any duplicates that may be in spechitint
spechitint_removedups();

View file

@ -1199,7 +1199,6 @@ static void P_LinkToBlockMap(mobj_t *thing, mobj_t **bmap)
void P_SetThingPosition(mobj_t *thing)
{ // link into subsector
subsector_t *ss;
sector_t *prevsec = NULL;
sector_t *oldsec = NULL;
fixed_t tfloorz, tceilz;
@ -1212,11 +1211,6 @@ void P_SetThingPosition(mobj_t *thing)
oldsec = thing->subsector->sector;
}
if (thing->subsector)
{
prevsec = thing->subsector->sector;
}
ss = thing->subsector = R_PointInSubsector(thing->x, thing->y);
if (!(thing->flags & MF_NOSECTOR))
@ -1273,12 +1267,6 @@ void P_SetThingPosition(mobj_t *thing)
else if (thing->z <= tfloorz)
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
if (udmf && prevsec != thing->subsector->sector)
{
// Check for each time / once sector special actions
P_CheckMobjTouchingSectorActions(thing, false);
}
}
//

View file

@ -2233,10 +2233,13 @@ boolean P_ZMovement(mobj_t *mo)
{
fixed_t dist, delta;
boolean onground;
boolean wasonground;
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
wasonground = P_IsObjectOnGround(mo);
// Intercept the stupid 'fall through 3dfloors' bug
if (mo->subsector->sector->ffloors)
P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0);
@ -2773,6 +2776,8 @@ boolean P_ZMovement(mobj_t *mo)
}
}
P_CheckSectorTransitionalEffects(mo, mo->subsector->sector, wasonground);
return true;
}
@ -2869,6 +2874,7 @@ static boolean P_PlayerPolyObjectZMovement(mobj_t *mo)
void P_PlayerZMovement(mobj_t *mo)
{
boolean onground;
boolean wasonground;
angle_t oldPitch, oldRoll;
I_Assert(mo != NULL);
@ -2877,6 +2883,7 @@ void P_PlayerZMovement(mobj_t *mo)
if (!mo->player)
return;
wasonground = P_IsObjectOnGround(mo);
oldPitch = mo->pitch;
oldRoll = mo->roll;
@ -3061,6 +3068,8 @@ void P_PlayerZMovement(mobj_t *mo)
K_SpawnBumpEffect(mo);
}
}
P_CheckSectorTransitionalEffects(mo, mo->subsector->sector, wasonground);
}
boolean P_SceneryZMovement(mobj_t *mo)
@ -10569,7 +10578,7 @@ void P_MobjThinker(mobj_t *mobj)
if (udmf)
{
// Check for continuous sector special actions
P_CheckMobjTouchingSectorActions(mobj, true);
P_CheckMobjTouchingSectorActions(mobj, true, true);
}
else
{

View file

@ -5691,7 +5691,7 @@ static boolean P_AllowSpecialCeiling(sector_t *sec, mobj_t *thing)
return false;
}
static void P_CheckMobj3DFloorAction(mobj_t *mo, sector_t *sec, boolean continuous)
static void P_CheckMobj3DFloorAction(mobj_t *mo, sector_t *sec, boolean continuous, boolean sectorchanged)
{
sector_t *originalsector = mo->subsector->sector;
ffloor_t *rover;
@ -5750,6 +5750,10 @@ static void P_CheckMobj3DFloorAction(mobj_t *mo, sector_t *sec, boolean continuo
continue;
}
}
else if (sectorchanged == false)
{
continue;
}
activator = Z_Calloc(sizeof(activator_t), PU_LEVEL, NULL);
I_Assert(activator != NULL);
@ -5771,7 +5775,7 @@ static void P_CheckMobj3DFloorAction(mobj_t *mo, sector_t *sec, boolean continuo
}
}
static void P_CheckMobjPolyobjAction(mobj_t *mo, boolean continuous)
static void P_CheckMobjPolyobjAction(mobj_t *mo, boolean continuous, boolean sectorchanged)
{
sector_t *originalsector = mo->subsector->sector;
polyobj_t *po;
@ -5826,6 +5830,10 @@ static void P_CheckMobjPolyobjAction(mobj_t *mo, boolean continuous)
continue;
}
}
else if (sectorchanged == false)
{
continue;
}
activator = Z_Calloc(sizeof(activator_t), PU_LEVEL, NULL);
I_Assert(activator != NULL);
@ -5847,7 +5855,7 @@ static void P_CheckMobjPolyobjAction(mobj_t *mo, boolean continuous)
}
}
static void P_CheckMobjSectorAction(mobj_t *mo, sector_t *sec, boolean continuous)
static void P_CheckMobjSectorAction(mobj_t *mo, sector_t *sec, boolean continuous, boolean sectorchanged)
{
activator_t *activator = NULL;
boolean result = false;
@ -5884,6 +5892,10 @@ static void P_CheckMobjSectorAction(mobj_t *mo, sector_t *sec, boolean continuou
return;
}
}
else if (sectorchanged == false)
{
return;
}
activator = Z_Calloc(sizeof(activator_t), PU_LEVEL, NULL);
I_Assert(activator != NULL);
@ -5902,7 +5914,7 @@ static void P_CheckMobjSectorAction(mobj_t *mo, sector_t *sec, boolean continuou
}
}
void P_CheckMobjTouchingSectorActions(mobj_t *mobj, boolean continuous)
void P_CheckMobjTouchingSectorActions(mobj_t *mobj, boolean continuous, boolean sectorchanged)
{
sector_t *originalsector;
@ -5928,13 +5940,13 @@ void P_CheckMobjTouchingSectorActions(mobj_t *mobj, boolean continuous)
}
}
P_CheckMobj3DFloorAction(mobj, originalsector, continuous);
P_CheckMobj3DFloorAction(mobj, originalsector, continuous, sectorchanged);
if TELEPORTED(mobj) return;
P_CheckMobjPolyobjAction(mobj, continuous);
P_CheckMobjPolyobjAction(mobj, continuous, sectorchanged);
if TELEPORTED(mobj) return;
P_CheckMobjSectorAction(mobj, originalsector, continuous);
P_CheckMobjSectorAction(mobj, originalsector, continuous, sectorchanged);
}
#undef TELEPORTED
@ -9559,3 +9571,21 @@ void P_FreeQuake(quake_t *remove)
Z_Free(remove);
}
void P_CheckSectorTransitionalEffects(mobj_t *thing, sector_t *prevsec, boolean wasgrounded)
{
if (!udmf)
{
return;
}
boolean sectorchanged = (prevsec != thing->subsector->sector);
if (!sectorchanged && wasgrounded == P_IsObjectOnGround(thing))
{
return;
}
// Check for each time / once sector special actions
P_CheckMobjTouchingSectorActions(thing, false, sectorchanged);
}

View file

@ -587,11 +587,12 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
sector_t *P_PlayerTouchingSectorSpecialFlag(player_t *player, sectorspecialflags_t flag);
void P_PlayerInSpecialSector(player_t *player);
void P_CheckMobjTrigger(mobj_t *mobj, boolean pushable);
void P_CheckMobjTouchingSectorActions(mobj_t *mobj, boolean continuous);
void P_CheckMobjTouchingSectorActions(mobj_t *mobj, boolean continuous, boolean sectorchanged);
sector_t *P_FindPlayerTrigger(player_t *player, line_t *sourceline);
boolean P_IsPlayerValid(size_t playernum);
boolean P_CanPlayerTrigger(size_t playernum);
void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector);
void P_CheckSectorTransitionalEffects(mobj_t *thing, sector_t *prevsec, boolean wasgrounded);
fixed_t P_FindLowestFloorSurrounding(sector_t *sec);
fixed_t P_FindHighestFloorSurrounding(sector_t *sec);