summaryrefslogtreecommitdiffstats
path: root/source/Player.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Player.cpp')
-rw-r--r--source/Player.cpp44
1 files changed, 43 insertions, 1 deletions
diff --git a/source/Player.cpp b/source/Player.cpp
index ae119a1fb..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 )
@@ -178,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:
@@ -1200,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();
@@ -1246,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;
@@ -1313,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)