1
0

Fixed player swimstate crash.

The check for swimming / submersion checks the Y coord first. Fixes #63.
This commit is contained in:
madmaxoft 2013-08-14 10:33:26 +02:00
parent fcb558a427
commit c0629a9a6e

View File

@ -1322,7 +1322,7 @@ cPlayer::StringList cPlayer::GetResolvedPermissions()
void cPlayer::UseEquippedItem() void cPlayer::UseEquippedItem(void)
{ {
if (GetGameMode() == gmCreative) // No damage in creative if (GetGameMode() == gmCreative) // No damage in creative
{ {
@ -1332,29 +1332,39 @@ void cPlayer::UseEquippedItem()
GetInventory().DamageEquippedItem(); GetInventory().DamageEquippedItem();
} }
void cPlayer::SetSwimState(cChunk & a_Chunk) void cPlayer::SetSwimState(cChunk & a_Chunk)
{ {
int RelY = (int)floor(m_LastPosY + 0.1);
if ((RelY < 0) || (RelY >= cChunkDef::Height))
{
m_IsSwimming = false;
m_IsSubmerged = false;
return;
}
BLOCKTYPE BlockIn; BLOCKTYPE BlockIn;
int RelX = (int)floor(m_LastPosX) - a_Chunk.GetPosX() * cChunkDef::Width; int RelX = (int)floor(m_LastPosX) - a_Chunk.GetPosX() * cChunkDef::Width;
int RelY = (int)floor(m_LastPosY + 0.1);
int RelZ = (int)floor(m_LastPosZ) - a_Chunk.GetPosZ() * cChunkDef::Width; int RelZ = (int)floor(m_LastPosZ) - a_Chunk.GetPosZ() * cChunkDef::Width;
// first we check if the player is swimming // Check if the player is swimming:
// Use Unbounded, because we're being called *after* processing super::Tick(), which could have changed our chunk // Use Unbounded, because we're being called *after* processing super::Tick(), which could have changed our chunk
VERIFY(a_Chunk.UnboundedRelGetBlockType(RelX, RelY, RelZ, BlockIn)); VERIFY(a_Chunk.UnboundedRelGetBlockType(RelX, RelY, RelZ, BlockIn));
m_IsSwimming = IsBlockWater(BlockIn); m_IsSwimming = IsBlockWater(BlockIn);
// now we check if the player is submerged // Check if the player is submerged:
VERIFY(a_Chunk.UnboundedRelGetBlockType(RelX, RelY + 1, RelZ, BlockIn));
VERIFY(a_Chunk.UnboundedRelGetBlockType(RelX, RelY+1, RelZ, BlockIn));
m_IsSubmerged = IsBlockWater(BlockIn); m_IsSubmerged = IsBlockWater(BlockIn);
} }
void cPlayer::HandleAir()
void cPlayer::HandleAir(void)
{ {
// Ref.: http://www.minecraftwiki.net/wiki/Chunk_format // Ref.: http://www.minecraftwiki.net/wiki/Chunk_format
// see if the player is /submerged/ water (block above is water) // see if the player is /submerged/ water (block above is water)
@ -1363,22 +1373,28 @@ void cPlayer::HandleAir()
if (IsSubmerged()) if (IsSubmerged())
{ {
// either reduce air level or damage player // either reduce air level or damage player
if(m_AirLevel < 1) if (m_AirLevel < 1)
{ {
if(m_AirTickTimer < 1) if (m_AirTickTimer < 1)
{ {
// damage player // damage player
TakeDamage(dtDrowning, NULL, 1, 1, 0); TakeDamage(dtDrowning, NULL, 1, 1, 0);
// reset timer // reset timer
m_AirTickTimer = DROWNING_TICKS; m_AirTickTimer = DROWNING_TICKS;
}else{ }
else
{
m_AirTickTimer -= 1; m_AirTickTimer -= 1;
} }
}else{ }
else
{
// reduce air supply // reduce air supply
m_AirLevel -= 1; m_AirLevel -= 1;
} }
}else{ }
else
{
// set the air back to maximum // set the air back to maximum
m_AirLevel = MAX_AIR_LEVEL; m_AirLevel = MAX_AIR_LEVEL;
m_AirTickTimer = DROWNING_TICKS; m_AirTickTimer = DROWNING_TICKS;
@ -1386,6 +1402,9 @@ void cPlayer::HandleAir()
} }
void cPlayer::HandleFood(void) void cPlayer::HandleFood(void)
{ {
// Ref.: http://www.minecraftwiki.net/wiki/Hunger // Ref.: http://www.minecraftwiki.net/wiki/Hunger