summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/ClientHandle.cpp97
-rw-r--r--src/ClientHandle.h3
-rw-r--r--src/Defines.h10
-rw-r--r--src/Inventory.cpp10
-rw-r--r--src/Inventory.h41
5 files changed, 125 insertions, 36 deletions
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index caff15cd0..1009cdbd6 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -815,6 +815,16 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB
return;
}
+ if (
+ (Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) ||
+ (Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) ||
+ (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6)
+ )
+ {
+ m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
+ return;
+ }
+
cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
if (PlgMgr->CallHookPlayerLeftClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status))
{
@@ -878,6 +888,7 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB
case DIG_STATUS_CANCELLED:
{
// Block breaking cancelled by player
+ FinishDigAnimation();
return;
}
@@ -916,7 +927,7 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
// It is a duplicate packet, drop it right away
return;
}
-
+
if (
m_Player->IsGameModeCreative() &&
ItemCategory::IsSword(m_Player->GetInventory().GetEquippedItem().m_ItemType)
@@ -925,14 +936,17 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
// Players can't destroy blocks with a Sword in the hand.
return;
}
-
- if (cRoot::Get()->GetPluginManager()->CallHookPlayerBreakingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta))
+
+ if (
+ (Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) ||
+ (Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) ||
+ (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6)
+ )
{
- // A plugin doesn't agree with the breaking. Bail out. Send the block back to the client, so that it knows:
m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
return;
}
-
+
// Set the last digging coords to the block being dug, so that they can be checked in DIG_FINISHED to avoid dig/aim bug in the client:
m_HasStartedDigging = true;
m_LastDigBlockX = a_BlockX;
@@ -1004,24 +1018,24 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo
return;
}
- m_HasStartedDigging = false;
- if (m_BlockDigAnimStage != -1)
+ FinishDigAnimation();
+
+ cWorld * World = m_Player->GetWorld();
+ cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
+
+ if (cRoot::Get()->GetPluginManager()->CallHookPlayerBreakingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta))
{
- // End dig animation
- m_BlockDigAnimStage = -1;
- // It seems that 10 ends block animation
- m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_BlockDigAnimX, m_BlockDigAnimY, m_BlockDigAnimZ, 10, this);
+ // A plugin doesn't agree with the breaking. Bail out. Send the block back to the client, so that it knows:
+ m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
+ return;
}
- cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
-
if (a_OldBlock == E_BLOCK_AIR)
{
LOGD("Dug air - what the function?");
return;
}
-
- cWorld * World = m_Player->GetWorld();
+
ItemHandler->OnBlockDestroyed(World, m_Player, m_Player->GetEquippedItem(), a_BlockX, a_BlockY, a_BlockZ);
// The ItemHandler is also responsible for spawning the pickups
cChunkInterface ChunkInterface(World->GetChunkMap());
@@ -1036,6 +1050,36 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo
+void cClientHandle::FinishDigAnimation()
+{
+ if (
+ !m_HasStartedDigging || // Hasn't received the DIG_STARTED packet
+ (m_LastDigBlockX == -1) ||
+ (m_LastDigBlockY == -1) ||
+ (m_LastDigBlockZ == -1)
+ )
+ {
+ return;
+ }
+
+ m_HasStartedDigging = false;
+ if (m_BlockDigAnimStage != -1)
+ {
+ // End dig animation
+ m_BlockDigAnimStage = -1;
+ // It seems that 10 ends block animation
+ m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_LastDigBlockX, m_LastDigBlockY, m_LastDigBlockZ, 10, this);
+ }
+
+ m_BlockDigAnimX = -1;
+ m_BlockDigAnimY = -1;
+ m_BlockDigAnimZ = -1;
+}
+
+
+
+
+
void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, const cItem & a_HeldItem)
{
LOGD("HandleRightClick: {%d, %d, %d}, face %d, HeldItem: %s",
@@ -1043,7 +1087,23 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
);
cWorld * World = m_Player->GetWorld();
-
+
+ if (
+ (Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) ||
+ (Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) ||
+ (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6)
+ )
+ {
+ if (a_BlockFace != BLOCK_FACE_NONE)
+ {
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
+ World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
+ World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); // 2 block high things
+ m_Player->GetInventory().SendEquippedSlot();
+ }
+ return;
+ }
+
cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
if (PlgMgr->CallHookPlayerRightClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))
{
@@ -1057,7 +1117,8 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
{
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
- World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); //2 block high things
+ World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); // 2 block high things
+ m_Player->GetInventory().SendEquippedSlot();
}
return;
}
@@ -1246,6 +1307,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e
{
// Handler refused the placement, send that information back to the client:
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockY, m_Player);
+ m_Player->GetInventory().SendEquippedSlot();
return;
}
@@ -1255,6 +1317,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e
{
// A plugin doesn't agree with placing the block, revert the block on the client:
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
+ m_Player->GetInventory().SendEquippedSlot();
return;
}
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index b6bba4eae..f3dea7a4a 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -374,6 +374,9 @@ private:
/** Handles the DIG_FINISHED dig packet: */
void HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta);
+ /** The clients will receive a finished dig animation */
+ void FinishDigAnimation();
+
/** Converts the protocol-formatted channel list (NUL-separated) into a proper string vector. */
AStringVector BreakApartPluginChannels(const AString & a_PluginChannels);
diff --git a/src/Defines.h b/src/Defines.h
index 9fa3b3a8e..b0b209934 100644
--- a/src/Defines.h
+++ b/src/Defines.h
@@ -3,6 +3,7 @@
#include "ChatColor.h"
#include <limits>
+#include <cmath>
@@ -528,6 +529,15 @@ inline float GetSpecialSignf( float a_Val )
+template<class T> inline int Diff(T a_Val1, T a_Val2)
+{
+ return std::abs(a_Val1 - a_Val2);
+}
+
+
+
+
+
// tolua_begin
enum eMessageType
diff --git a/src/Inventory.cpp b/src/Inventory.cpp
index a365e4ed4..bce882c88 100644
--- a/src/Inventory.cpp
+++ b/src/Inventory.cpp
@@ -243,6 +243,16 @@ void cInventory::SetHotbarSlot(int a_HotBarSlotNum, const cItem & a_Item)
+void cInventory::SendEquippedSlot()
+{
+ int EquippedSlotNum = cInventory::invArmorCount + cInventory::invInventoryCount + GetEquippedSlotNum();
+ SendSlot(EquippedSlotNum);
+}
+
+
+
+
+
const cItem & cInventory::GetSlot(int a_SlotNum) const
{
if ((a_SlotNum < 0) || (a_SlotNum >= invNumSlots))
diff --git a/src/Inventory.h b/src/Inventory.h
index 1ad7c4776..39aef1538 100644
--- a/src/Inventory.h
+++ b/src/Inventory.h
@@ -56,13 +56,13 @@ public:
// tolua_begin
- /// Removes all items from the entire inventory
+ /** Removes all items from the entire inventory */
void Clear(void);
- /// Returns number of items out of a_ItemStack that can fit in the storage
+ /** Returns number of items out of a_ItemStack that can fit in the storage */
int HowManyCanFit(const cItem & a_ItemStack, bool a_ConsiderEmptySlots);
- /// Returns how many items of the specified type would fit into the slot range specified
+ /** Returns how many items of the specified type would fit into the slot range specified */
int HowManyCanFit(const cItem & a_ItemStack, int a_BeginSlotNum, int a_EndSlotNum, bool a_ConsiderEmptySlots);
/** Adds as many items out of a_ItemStack as can fit.
@@ -86,33 +86,36 @@ public:
*/
int AddItems(cItems & a_ItemStackList, bool a_AllowNewStacks, bool a_tryToFillEquippedFirst);
- /// Removes one item out of the currently equipped item stack, returns true if successful, false if empty-handed
+ /** Removes one item out of the currently equipped item stack, returns true if successful, false if empty-handed */
bool RemoveOneEquippedItem(void);
- /// Returns the number of items of type a_Item that are stored
+ /** Returns the number of items of type a_Item that are stored */
int HowManyItems(const cItem & a_Item);
- /// Returns true if there are at least as many items of type a_ItemStack as in a_ItemStack
+ /** Returns true if there are at least as many items of type a_ItemStack as in a_ItemStack */
bool HasItems(const cItem & a_ItemStack);
+
+ /** Sends the equipped item slot to the client */
+ void SendEquippedSlot();
- /// Returns the cItemGrid object representing the armor slots
+ /** Returns the cItemGrid object representing the armor slots */
cItemGrid & GetArmorGrid(void) { return m_ArmorSlots; }
- /// Returns the cItemGrid object representing the main inventory slots
+ /** Returns the cItemGrid object representing the main inventory slots */
cItemGrid & GetInventoryGrid(void) { return m_InventorySlots; }
- /// Returns the cItemGrid object representing the hotbar slots
+ /** Returns the cItemGrid object representing the hotbar slots */
cItemGrid & GetHotbarGrid(void) { return m_HotbarSlots; }
- /// Returns the player associated with this inventory
+ /** Returns the player associated with this inventory */
cPlayer & GetOwner(void) { return m_Owner; }
- /// Copies the non-empty slots into a_ItemStacks; preserves the original a_Items contents
+ /** Copies the non-empty slots into a_ItemStacks; preserves the original a_Items contents */
void CopyToItems(cItems & a_Items);
// tolua_end
- /// Returns the player associated with this inventory (const version)
+ /** Returns the player associated with this inventory (const version) */
const cPlayer & GetOwner(void) const { return m_Owner; }
// tolua_begin
@@ -136,10 +139,10 @@ public:
*/
int ChangeSlotCount(int a_SlotNum, int a_AddToCount);
- /// Adds the specified damage to the specified item; deletes the item and returns true if the item broke.
+ /** Adds the specified damage to the specified item; deletes the item and returns true if the item broke. */
bool DamageItem(int a_SlotNum, short a_Amount);
- /// Adds the specified damage to the currently held item; deletes the item and returns true if the item broke.
+ /** Adds the specified damage to the currently held item; deletes the item and returns true if the item broke. */
bool DamageEquippedItem(short a_Amount = 1);
const cItem & GetEquippedHelmet (void) const { return m_ArmorSlots.GetSlot(0); }
@@ -149,13 +152,13 @@ public:
// tolua_end
- /// Sends the slot contents to the owner
+ /** Sends the slot contents to the owner */
void SendSlot(int a_SlotNum);
- /// Update items (e.g. Maps)
+ /** Update items (e.g. Maps) */
void UpdateItems(void);
- /// Converts an armor slot number into the ID for the EntityEquipment packet
+ /** Converts an armor slot number into the ID for the EntityEquipment packet */
static int ArmorSlotNumToEntityEquipmentID(short a_ArmorSlotNum);
void SaveToJson(Json::Value & a_Value);
@@ -172,10 +175,10 @@ protected:
cPlayer & m_Owner;
- /// Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return NULL for invalid SlotNum
+ /** Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return NULL for invalid SlotNum */
const cItemGrid * GetGridForSlotNum(int a_SlotNum, int & a_GridSlotNum) const;
- /// Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return NULL for invalid SlotNum
+ /** Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return NULL for invalid SlotNum */
cItemGrid * GetGridForSlotNum(int a_SlotNum, int & a_GridSlotNum);
// cItemGrid::cListener override: