1
0

Added IsSwimming and IsSubmerged flags and access methods

This commit is contained in:
James Ravenscroft 2013-08-09 08:37:39 +01:00
parent 2b9fdc3e36
commit dace1f7bd2
3 changed files with 44 additions and 15 deletions

View File

@ -32,7 +32,6 @@
#include "Protocol/ProtocolRecognizer.h" #include "Protocol/ProtocolRecognizer.h"
#define float2int(x) ((x)<0 ? ((int)(x))-1 : (int)(x))
#define AddPistonDir(x, y, z, dir, amount) switch (dir) { case 0: (y)-=(amount); break; case 1: (y)+=(amount); break;\ #define AddPistonDir(x, y, z, dir, amount) switch (dir) { case 0: (y)-=(amount); break; case 1: (y)+=(amount); break;\
@ -505,9 +504,8 @@ void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ,
if ((a_PosY > m_Player->GetPosY()) && !a_IsOnGround && m_Player->IsOnGround()) if ((a_PosY > m_Player->GetPosY()) && !a_IsOnGround && m_Player->IsOnGround())
{ {
// we only add this exhaustion if the player is not swimming - otherwise we end up with both jump + swim exhaustion // we only add this exhaustion if the player is not swimming - otherwise we end up with both jump + swim exhaustion
cWorld * World = m_Player->GetWorld();
BLOCKTYPE BlockType = World->GetBlock( float2int(m_Player->GetPosX()), float2int(m_Player->GetPosY()), float2int(m_Player->GetPosZ()) ); if(! m_Player->IsSwimming() )
if(! IsBlockWater(BlockType) )
{ {
m_Player->AddFoodExhaustion(m_Player->IsSprinting() ? 0.8 : 0.2); m_Player->AddFoodExhaustion(m_Player->IsSprinting() ? 0.8 : 0.2);
} }

View File

@ -61,6 +61,8 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
, m_SprintingMaxSpeed(0.13) , m_SprintingMaxSpeed(0.13)
, m_IsCrouched(false) , m_IsCrouched(false)
, m_IsSprinting(false) , m_IsSprinting(false)
, m_IsSwimming(false)
, m_IsSubmerged(false)
, m_EatingFinishTick(-1) , m_EatingFinishTick(-1)
{ {
LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d", LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d",
@ -181,8 +183,11 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
super::Tick(a_Dt, a_Chunk); super::Tick(a_Dt, a_Chunk);
//handle air drowning stuff // set player swimming state
HandleAir(a_Chunk); SetSwimState( a_Chunk);
// handle air drowning stuff
HandleAir();
if (m_bDirtyPosition) if (m_bDirtyPosition)
{ {
@ -1326,20 +1331,34 @@ void cPlayer::UseEquippedItem()
GetInventory().DamageEquippedItem(); GetInventory().DamageEquippedItem();
} }
void cPlayer::SetSwimState(cChunk & a_Chunk)
{
void cPlayer::HandleAir(cChunk & a_Chunk) 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;
// 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));
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 // 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)
// Get the type of block the player's standing in: // 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)) if (IsSubmerged())
{ {
// either reduce air level or damage player // either reduce air level or damage player
if(m_AirLevel < 1) if(m_AirLevel < 1)

View File

@ -260,6 +260,12 @@ public:
virtual bool IsSprinting(void) const { return m_IsSprinting; } virtual bool IsSprinting(void) const { return m_IsSprinting; }
virtual bool IsRclking (void) const { return IsEating(); } virtual bool IsRclking (void) const { return IsEating(); }
/// Returns whether the player is swimming or not
virtual bool IsSwimming(void) const{ return m_IsSwimming; }
/// Return whether the player is under water or not
virtual bool IsSubmerged(void) const{ return m_IsSubmerged; }
protected: protected:
typedef std::map< std::string, bool > PermissionMap; typedef std::map< std::string, bool > PermissionMap;
PermissionMap m_ResolvedPermissions; PermissionMap m_ResolvedPermissions;
@ -335,6 +341,9 @@ protected:
bool m_IsCrouched; bool m_IsCrouched;
bool m_IsSprinting; bool m_IsSprinting;
bool m_IsSwimming;
bool m_IsSubmerged;
/// The world tick in which eating will be finished. -1 if not eating /// The world tick in which eating will be finished. -1 if not eating
Int64 m_EatingFinishTick; Int64 m_EatingFinishTick;
@ -347,7 +356,10 @@ protected:
void HandleFood(void); void HandleFood(void);
/// Called in each tick to handle air-related processing i.e. drowning /// Called in each tick to handle air-related processing i.e. drowning
void HandleAir(cChunk & a_Chunk); void HandleAir();
/// Called once per tick to set IsSwimming and IsSubmerged
void SetSwimState(cChunk & a_Chunk);
/// Adds food exhaustion based on the difference between Pos and LastPos, sprinting status and swimming (in water block) /// Adds food exhaustion based on the difference between Pos and LastPos, sprinting status and swimming (in water block)
void ApplyFoodExhaustionFromMovement(cChunk & a_Chunk); void ApplyFoodExhaustionFromMovement(cChunk & a_Chunk);