diff options
Diffstat (limited to 'source/Player.cpp')
-rw-r--r-- | source/Player.cpp | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/source/Player.cpp b/source/Player.cpp index bbf39f789..fb752ed87 100644 --- a/source/Player.cpp +++ b/source/Player.cpp @@ -40,6 +40,8 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) , m_IP("") , m_LastBlockActionTime( 0 ) , m_LastBlockActionCnt( 0 ) + , m_AirLevel( MAX_AIR_LEVEL ) + , m_AirTickTimer( DROWNING_TICKS ) , m_bVisible( true ) , m_LastGroundHeight( 0 ) , m_bTouchGround( false ) @@ -121,10 +123,14 @@ cPlayer::~cPlayer(void) -void cPlayer::Initialize(cWorld * a_World) +bool cPlayer::Initialize(cWorld * a_World) { - super::Initialize(a_World); - GetWorld()->AddPlayer(this); + if (super::Initialize(a_World)) + { + GetWorld()->AddPlayer(this); + return true; + } + return false; } @@ -174,6 +180,10 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk) } super::Tick(a_Dt, a_Chunk); + + //handle air drowning stuff + HandleAir(a_Chunk); + if (m_bDirtyPosition) { // Apply food exhaustion from movement: @@ -1196,7 +1206,7 @@ bool cPlayer::LoadFromDisk() } m_Health = root.get("health", 0).asInt(); - + m_AirLevel = root.get("air", MAX_AIR_LEVEL).asInt(); m_FoodLevel = root.get("food", MAX_FOOD_LEVEL).asInt(); m_FoodSaturationLevel = root.get("foodSaturation", MAX_FOOD_LEVEL).asDouble(); m_FoodTickTimer = root.get("foodTickTimer", 0).asInt(); @@ -1242,6 +1252,7 @@ bool cPlayer::SaveToDisk() root["rotation"] = JSON_PlayerRotation; root["inventory"] = JSON_Inventory; root["health"] = m_Health; + root["air"] = m_AirLevel; root["food"] = m_FoodLevel; root["foodSaturation"] = m_FoodSaturationLevel; root["foodTickTimer"] = m_FoodTickTimer; @@ -1309,7 +1320,42 @@ void cPlayer::UseEquippedItem() } +void cPlayer::HandleAir(cChunk & a_Chunk) +{ + // Ref.: http://www.minecraftwiki.net/wiki/Chunk_format + // see if the player is /submerged/ water (block above is water) + // Get the type of block the player's standing in: + BLOCKTYPE BlockIn; + int RelX = (int)floor(m_LastPosX) - a_Chunk.GetPosX() * cChunkDef::Width; + int RelY = (int)floor(m_LastPosY + 1.1); + int RelZ = (int)floor(m_LastPosZ) - a_Chunk.GetPosZ() * cChunkDef::Width; + // 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)); + if (IsBlockWater(BlockIn)) + { + // either reduce air level or damage player + if(m_AirLevel < 1) + { + if(m_AirTickTimer < 1) + { + // damage player + TakeDamage(dtDrowning, NULL, 1, 1, 0); + // reset timer + m_AirTickTimer = DROWNING_TICKS; + }else{ + m_AirTickTimer -= 1; + } + }else{ + // reduce air supply + m_AirLevel -= 1; + } + }else{ + // set the air back to maximum + m_AirLevel = MAX_AIR_LEVEL; + m_AirTickTimer = DROWNING_TICKS; + } +} void cPlayer::HandleFood(void) |