- fixed potential infinite loop in Hexen-style stair builder.

This commit is contained in:
Christoph Oelckers 2022-01-07 00:09:59 +01:00
parent e6403197eb
commit 63fa01205f
4 changed files with 32 additions and 11 deletions

View file

@ -781,7 +781,6 @@ public:
bool IsLinked(sector_t *other, bool ceiling) const;
sector_t *NextSpecialSector (int type, sector_t *prev) const; // [RH]
void RemoveForceField();
int Index() const { return sectornum; }
@ -1726,6 +1725,8 @@ int GetCeilingLight(const sector_t *);
double GetFriction(const sector_t *self, int plane, double *movefac);
double HighestCeilingAt(sector_t *sec, double x, double y, sector_t **resultsec = nullptr);
double LowestFloorAt(sector_t *sec, double x, double y, sector_t **resultsec = nullptr);
sector_t* P_NextSpecialSector(sector_t* sect, int type, sector_t* prev);
sector_t* P_NextSpecialSectorVC(sector_t* sect, int type); // uses validcount
inline void sector_t::RemoveForceField() { return ::RemoveForceField(this); }
inline bool sector_t::PlaneMoving(int pos) { return !!::PlaneMoving(this, pos); }

View file

@ -40,6 +40,7 @@
#include "r_data/r_interpolate.h"
#include "g_levellocals.h"
#include "vm.h"
#include "r_utility.h"
//==========================================================================
//
@ -661,6 +662,7 @@ bool FLevelLocals::EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, d
// 1. Find 2-sided line with same sector side[0] (lowest numbered)
// 2. Other side is the next sector to raise
// 3. Unless already moving, or different texture, then stop building
validcount++;
do
{
ok = 0;
@ -668,12 +670,13 @@ bool FLevelLocals::EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, d
if (usespecials & DFloor::stairUseSpecials)
{
// [RH] Find the next sector by scanning for Stairs_Special?
tsec = sec->NextSpecialSector (
tsec = P_NextSpecialSectorVC(sec,
sec->special == Stairs_Special1 ?
Stairs_Special2 : Stairs_Special1, prev);
Stairs_Special2 : Stairs_Special1);
if ( (ok = (tsec != NULL)) )
if ( (ok = (tsec != nullptr)) )
{
tsec->validcount = validcount;
height += stairstep;
// if sector's floor already moving, look for another

View file

@ -521,7 +521,7 @@ int DPhased::PhaseHelper (sector_t *sector, int index, int light, sector_t *prev
else
l = Level->CreateThinker<DPhased> (sector, baselevel);
int numsteps = PhaseHelper (sector->NextSpecialSector (
int numsteps = PhaseHelper (P_NextSpecialSector (sector,
sector->special == LightSequenceSpecial1 ?
LightSequenceSpecial2 : LightSequenceSpecial1, prev),
index + 1, l->m_BaseLevel, sector);

View file

@ -89,27 +89,44 @@ CUSTOM_CVAR(Int, r_fakecontrast, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
//
// Returns the next special sector attached to this sector
// with a certain special.
sector_t *sector_t::NextSpecialSector (int type, sector_t *nogood) const
sector_t* P_NextSpecialSectorVC(sector_t* sec, int type)
{
sector_t* tsec;
for (auto ln : sec->Lines)
{
if (nullptr != (tsec = getNextSector(ln, sec)) &&
tsec->validcount != validcount &&
tsec->special == type)
{
return tsec;
}
}
return nullptr;
}
sector_t *P_NextSpecialSector (sector_t* sec, int type, sector_t *nogood)
{
sector_t *tsec;
for (auto ln : Lines)
for (auto ln : sec->Lines)
{
if (NULL != (tsec = getNextSector (ln, this)) &&
if (nullptr != (tsec = getNextSector (ln, sec)) &&
tsec != nogood &&
tsec->special == type)
{
return tsec;
}
}
return NULL;
return nullptr;
}
DEFINE_ACTION_FUNCTION(_Sector, NextSpecialSector)
DEFINE_ACTION_FUNCTION_NATIVE(_Sector, NextSpecialSector, P_NextSpecialSector)
{
PARAM_SELF_STRUCT_PROLOGUE(sector_t);
PARAM_INT(type);
PARAM_POINTER(nogood, sector_t);
ACTION_RETURN_POINTER(self->NextSpecialSector(type, nogood));
ACTION_RETURN_POINTER(P_NextSpecialSector(self, type, nogood));
}
//