diff options
Diffstat (limited to 'source/Player.cpp')
-rw-r--r-- | source/Player.cpp | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/source/Player.cpp b/source/Player.cpp index b7f53daeb..b2643f2c8 100644 --- a/source/Player.cpp +++ b/source/Player.cpp @@ -61,6 +61,8 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) , m_SprintingMaxSpeed(0.13) , m_IsCrouched(false) , m_IsSprinting(false) + , m_IsSwimming(false) + , m_IsSubmerged(false) , m_EatingFinishTick(-1) { LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d", @@ -180,14 +182,17 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk) } super::Tick(a_Dt, a_Chunk); + + // set player swimming state + SetSwimState( a_Chunk); - //handle air drowning stuff - HandleAir(a_Chunk); + // handle air drowning stuff + HandleAir(); if (m_bDirtyPosition) { // Apply food exhaustion from movement: - ApplyFoodExhaustionFromMovement(a_Chunk); + ApplyFoodExhaustionFromMovement(); cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*this); BroadcastMovementUpdate(m_ClientHandle); @@ -400,7 +405,14 @@ void cPlayer::FinishEating(void) return; } ItemHandler->OnFoodEaten(m_World, this, &Item); + GetInventory().RemoveOneEquippedItem(); + + //if the food is mushroom soup, return a bowl to the inventory + if( Item.m_ItemType == E_ITEM_MUSHROOM_SOUP ) { + cItem emptyBowl(E_ITEM_BOWL, 1, 0, ""); + GetInventory().AddItem(emptyBowl, true, true); + } } @@ -1320,20 +1332,35 @@ void cPlayer::UseEquippedItem() GetInventory().DamageEquippedItem(); } - -void cPlayer::HandleAir(cChunk & a_Chunk) +void cPlayer::SetSwimState(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 RelY = (int)floor(m_LastPosY + 0.1); int RelZ = (int)floor(m_LastPosZ) - a_Chunk.GetPosZ() * cChunkDef::Width; + + // first we check if the player is swimming + // 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)) + m_IsSwimming = IsBlockWater(BlockIn); + + // now we check if the player is submerged + + VERIFY(a_Chunk.UnboundedRelGetBlockType(RelX, RelY+1, RelZ, BlockIn)); + + m_IsSubmerged = IsBlockWater(BlockIn); +} + +void cPlayer::HandleAir() +{ + // 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: + + if (IsSubmerged()) { // either reduce air level or damage player if(m_AirLevel < 1) @@ -1420,7 +1447,7 @@ void cPlayer::HandleFood(void) -void cPlayer::ApplyFoodExhaustionFromMovement(cChunk & a_Chunk) +void cPlayer::ApplyFoodExhaustionFromMovement() { if (IsGameModeCreative()) { @@ -1438,14 +1465,6 @@ void cPlayer::ApplyFoodExhaustionFromMovement(cChunk & a_Chunk) return; } - // 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 + 0.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)); - // Apply the exhaustion based on distance travelled: double BaseExhaustion = Movement.Length(); if (IsSprinting()) @@ -1453,7 +1472,7 @@ void cPlayer::ApplyFoodExhaustionFromMovement(cChunk & a_Chunk) // 0.1 pt per meter sprinted BaseExhaustion = BaseExhaustion * 0.1; } - else if (IsBlockWater(BlockIn)) + else if (IsSwimming()) { // 0.015 pt per meter swum BaseExhaustion = BaseExhaustion * 0.015; |