- separated splash detection from water level setting.

This could cause problems if 3D floors with different properties for slashing and waterlevel were occupied at the same time. By keeping the slash code separate both parts can be handled without having to look out for the other.
This commit is contained in:
Christoph Oelckers 2017-02-14 20:11:30 +01:00
parent 9e769f29c3
commit b7b0e64471
2 changed files with 107 additions and 24 deletions

View File

@ -1230,6 +1230,7 @@ public:
bool InStateSequence(FState * newstate, FState * basestate);
int GetTics(FState * newstate);
bool SetState (FState *newstate, bool nofunction=false);
virtual void SplashCheck();
virtual bool UpdateWaterLevel (bool splash=true);
bool isFast();
bool isSlow();

View File

@ -4540,23 +4540,22 @@ void AActor::CheckSectorTransition(sector_t *oldsec)
//==========================================================================
//
// AActor::UpdateWaterLevel
// AActor::SplashCheck
//
// Returns true if actor should splash
//
//==========================================================================
bool AActor::UpdateWaterLevel (bool dosplash)
void AActor::SplashCheck()
{
BYTE lastwaterlevel = waterlevel;
double fh = -FLT_MAX;
bool reset=false;
bool reset = false;
waterlevel = 0;
if (Sector == NULL)
{
return false;
return;
}
if (Sector->MoreFlags & SECF_UNDERWATER) // intentionally not SECF_UNDERWATERMASK
@ -4568,7 +4567,7 @@ bool AActor::UpdateWaterLevel (bool dosplash)
const sector_t *hsec = Sector->GetHeightSec();
if (hsec != NULL)
{
fh = hsec->floorplane.ZatPoint (this);
fh = hsec->floorplane.ZatPoint(this);
//if (hsec->MoreFlags & SECF_UNDERWATERMASK) // also check Boom-style non-swimmable sectors
{
if (Z() < fh)
@ -4584,7 +4583,7 @@ bool AActor::UpdateWaterLevel (bool dosplash)
}
}
}
else if (!(hsec->MoreFlags & SECF_FAKEFLOORONLY) && (Top() > hsec->ceilingplane.ZatPoint (this)))
else if (!(hsec->MoreFlags & SECF_FAKEFLOORONLY) && (Top() > hsec->ceilingplane.ZatPoint(this)))
{
waterlevel = 3;
}
@ -4593,29 +4592,23 @@ bool AActor::UpdateWaterLevel (bool dosplash)
waterlevel = 0;
}
}
// even non-swimmable deep water must be checked here to do the splashes correctly
// But the water level must be reset when this function returns
if (!(hsec->MoreFlags&SECF_UNDERWATERMASK))
{
reset = true;
}
}
else
{
// Check 3D floors as well!
for(auto rover : Sector->e->XFloor.ffloors)
for (auto rover : Sector->e->XFloor.ffloors)
{
if (!(rover->flags & FF_EXISTS)) continue;
if (rover->flags & FF_SOLID) continue;
reset = !(rover->flags & FF_SWIMMABLE);
bool reset = !(rover->flags & FF_SWIMMABLE);
if (reset && rover->alpha == 0) continue;
double ff_bottom=rover->bottom.plane->ZatPoint(this);
double ff_top=rover->top.plane->ZatPoint(this);
double ff_bottom = rover->bottom.plane->ZatPoint(this);
double ff_top = rover->top.plane->ZatPoint(this);
if(ff_top <= Z() || ff_bottom > (Center())) continue;
if (ff_top <= Z() || ff_bottom > (Center())) continue;
fh=ff_top;
fh = ff_top;
if (Z() < fh)
{
waterlevel = 1;
@ -4637,14 +4630,103 @@ bool AActor::UpdateWaterLevel (bool dosplash)
// some additional checks to make deep sectors like Boom's splash without setting
// the water flags.
if (boomwaterlevel == 0 && waterlevel != 0 && dosplash)
if (boomwaterlevel == 0 && waterlevel != 0)
{
P_HitWater(this, Sector, PosAtZ(fh), true);
}
boomwaterlevel = waterlevel;
if (reset)
return;
}
//==========================================================================
//
// AActor::UpdateWaterLevel
//
// Returns true if actor should splash
//
//==========================================================================
bool AActor::UpdateWaterLevel(bool dosplash)
{
if (dosplash) SplashCheck();
double fh = -FLT_MAX;
bool reset = false;
waterlevel = 0;
if (Sector == NULL)
{
waterlevel = lastwaterlevel;
return false;
}
if (Sector->MoreFlags & SECF_UNDERWATER) // intentionally not SECF_UNDERWATERMASK
{
waterlevel = 3;
}
else
{
const sector_t *hsec = Sector->GetHeightSec();
if (hsec != NULL)
{
fh = hsec->floorplane.ZatPoint(this);
if (hsec->MoreFlags & SECF_UNDERWATERMASK) // also check Boom-style non-swimmable sectors
{
if (Z() < fh)
{
waterlevel = 1;
if (Center() < fh)
{
waterlevel = 2;
if ((player && Z() + player->viewheight <= fh) ||
(Top() <= fh))
{
waterlevel = 3;
}
}
}
else if (!(hsec->MoreFlags & SECF_FAKEFLOORONLY) && (Top() > hsec->ceilingplane.ZatPoint(this)))
{
waterlevel = 3;
}
else
{
waterlevel = 0;
}
}
}
else
{
// Check 3D floors as well!
for (auto rover : Sector->e->XFloor.ffloors)
{
if (!(rover->flags & FF_EXISTS)) continue;
if (rover->flags & FF_SOLID) continue;
if (!(rover->flags & FF_SWIMMABLE)) continue;
double ff_bottom = rover->bottom.plane->ZatPoint(this);
double ff_top = rover->top.plane->ZatPoint(this);
if (ff_top <= Z() || ff_bottom > (Center())) continue;
fh = ff_top;
if (Z() < fh)
{
waterlevel = 1;
if (Center() < fh)
{
waterlevel = 2;
if ((player && Z() + player->viewheight <= fh) ||
(Top() <= fh))
{
waterlevel = 3;
}
}
}
break;
}
}
}
return false; // we did the splash ourselves
}