summaryrefslogtreecommitdiffstats
path: root/source/Items/ItemBucket.h
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-10-18 21:41:29 +0200
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-10-18 21:41:29 +0200
commitc68aa68c699a618d0172bceacf553ab96fc32cdd (patch)
treea2eb1d2e76ea183f2c0aee66accd98beeba48e0d /source/Items/ItemBucket.h
parentFixed item damage value not being read from the 1.3.2 protocol (wtf, why was it disabled?) (diff)
downloadcuberite-c68aa68c699a618d0172bceacf553ab96fc32cdd.tar
cuberite-c68aa68c699a618d0172bceacf553ab96fc32cdd.tar.gz
cuberite-c68aa68c699a618d0172bceacf553ab96fc32cdd.tar.bz2
cuberite-c68aa68c699a618d0172bceacf553ab96fc32cdd.tar.lz
cuberite-c68aa68c699a618d0172bceacf553ab96fc32cdd.tar.xz
cuberite-c68aa68c699a618d0172bceacf553ab96fc32cdd.tar.zst
cuberite-c68aa68c699a618d0172bceacf553ab96fc32cdd.zip
Diffstat (limited to '')
-rw-r--r--source/Items/ItemBucket.h208
1 files changed, 139 insertions, 69 deletions
diff --git a/source/Items/ItemBucket.h b/source/Items/ItemBucket.h
index 21c9da2a9..3490300ae 100644
--- a/source/Items/ItemBucket.h
+++ b/source/Items/ItemBucket.h
@@ -3,92 +3,162 @@
#include "ItemHandler.h"
#include "../World.h"
+#include "../Simulator/FluidSimulator.h"
+#include "../Blocks/BlockHandler.h"
-class cItemBucketHandler : public cItemHandler
+
+
+
+
+class cItemBucketHandler :
+ public cItemHandler
{
public:
- cItemBucketHandler(int a_ItemID)
- : cItemHandler(a_ItemID)
+ cItemBucketHandler(int a_ItemType) :
+ cItemHandler(a_ItemType)
{
}
- virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir) override
+ virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override
+ {
+ switch (m_ItemType)
+ {
+ case E_ITEM_BUCKET: return ScoopUpFluid(a_World, a_Player, a_Item, a_BlockX, a_BlockY, a_BlockZ, a_Dir);
+ case E_ITEM_LAVA_BUCKET: return PlaceFluid (a_World, a_Player, a_Item, a_BlockX, a_BlockY, a_BlockZ, a_Dir, E_BLOCK_LAVA);
+ case E_ITEM_WATER_BUCKET: return PlaceFluid (a_World, a_Player, a_Item, a_BlockX, a_BlockY, a_BlockZ, a_Dir, E_BLOCK_WATER);
+ default:
+ {
+ ASSERT(!"Unhandled ItemType");
+ return false;
+ }
+ }
+ }
+
+
+
+ bool ScoopUpFluid(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir)
{
- switch(m_ItemID)
+ if (a_Dir < 0)
{
- case E_ITEM_BUCKET:
+ return false;
+ }
+ AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_Dir);
+ BLOCKTYPE ClickedBlock;
+ NIBBLETYPE ClickedMeta;
+ a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedMeta);
+ LOGD("Bucket Clicked BlockType %d, meta %d", ClickedBlock, ClickedMeta);
+ if (ClickedMeta != 0)
+ {
+ // Not a source block
+ return false;
+ }
+
+ if (a_Player->GetGameMode() == eGameMode_Creative)
+ {
+ // In creative mode don't modify the inventory, just remove the fluid:
+ a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ return true;
+ }
+
+ ENUM_ITEM_ID NewItem = E_ITEM_EMPTY;
+ switch (ClickedBlock)
+ {
+ case E_BLOCK_WATER:
+ case E_BLOCK_STATIONARY_WATER:
{
- if (a_Dir >= 0)
- {
- AddDirection(a_X, a_Y, a_Z, a_Dir);
- }
- BLOCKTYPE ClickedBlock = a_World->GetBlock(a_X, a_Y, a_Z);
- LOG("Bucket Clicked BlockID: %d", ClickedBlock);
- ENUM_ITEM_ID NewItem = E_ITEM_EMPTY;
- switch (ClickedBlock)
- {
- case E_BLOCK_WATER:
- case E_BLOCK_STATIONARY_WATER:
- {
- NewItem = E_ITEM_WATER_BUCKET;
- break;
- }
- case E_BLOCK_LAVA:
- case E_BLOCK_STATIONARY_LAVA:
- {
- NewItem = E_ITEM_LAVA_BUCKET;
- break;
- }
- }
- cItem Item(a_Item->m_ItemID, 1);
- if (
- (NewItem != E_ITEM_EMPTY) &&
- (
- ((a_Player->GetGameMode() == 1) ||
- a_Player->GetInventory().RemoveItem(Item))
- )
- )
- {
- // Give New Bucket
- cItem Item(NewItem, 1);
- a_Player->GetInventory().AddItem(Item);
- // Remove water / lava block
- a_Player->GetWorld()->SetBlock(a_X, a_Y, a_Z, E_BLOCK_AIR, 0);
- return true;
- }
+ NewItem = E_ITEM_WATER_BUCKET;
break;
}
-
- case E_ITEM_WATER_BUCKET:
- case E_ITEM_LAVA_BUCKET:
+ case E_BLOCK_LAVA:
+ case E_BLOCK_STATIONARY_LAVA:
{
- BLOCKTYPE NewBlock = (m_ItemID == E_ITEM_LAVA_BUCKET) ? E_BLOCK_LAVA : E_BLOCK_WATER;
- if (a_Dir >= 0)
- {
- AddDirection(a_X, a_Y, a_Z, a_Dir);
- if (a_World->GetBlock(a_X, a_Y, a_Z) == E_BLOCK_AIR)
- {
- cItem Item(a_Item->m_ItemID, 1);
- if ((a_Player->GetGameMode() == 1) || (a_Player->GetInventory().RemoveItem(Item)))
- {
- a_World->SetBlock(a_X, a_Y, a_Z, NewBlock, 0);
+ NewItem = E_ITEM_LAVA_BUCKET;
+ break;
+ }
+
+ default: return false;
+ }
+
+ // Remove the bucket from the inventory
+ cItem Item(a_Item->m_ItemType, 1);
+ if (!a_Player->GetInventory().RemoveItem(Item))
+ {
+ LOG("Clicked with an empty bucket, but cannot remove one from the inventory? WTF?");
+ ASSERT(!"Inventory bucket mismatch");
+ return true;
+ }
+
+ // Give new bucket, filled with fluid:
+ Item.m_ItemType = NewItem;
+ Item.m_ItemCount = 1;
+ a_Player->GetInventory().AddItem(Item);
+
+ // Remove water / lava block
+ a_Player->GetWorld()->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ return true;
+ }
- if (a_Player->GetGameMode() == 1)
- {
- break; //No new Bucket for creative players
- }
- cItem Item(E_ITEM_BUCKET, 1);
- a_Player->GetInventory().AddItem(Item);
- return true;
- }
- }
- }
+
+ bool PlaceFluid(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir, BLOCKTYPE a_FluidBlock)
+ {
+ if (a_Dir < 0)
+ {
+ return false;
+ }
+
+ BLOCKTYPE CurrentBlock = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
+ bool CanWashAway = cFluidSimulator::CanWashAway(CurrentBlock);
+ if (!CanWashAway)
+ {
+ // The block pointed at cannot be washed away, so put fluid on top of it / on its sides
+ AddDirection(a_BlockX, a_BlockY, a_BlockZ, a_Dir);
+ CurrentBlock = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
+ }
+ if (
+ !CanWashAway &&
+ (CurrentBlock != E_BLOCK_AIR) &&
+ (CurrentBlock != E_BLOCK_WATER) &&
+ (CurrentBlock != E_BLOCK_STATIONARY_WATER) &&
+ (CurrentBlock != E_BLOCK_LAVA) &&
+ (CurrentBlock != E_BLOCK_STATIONARY_LAVA)
+ )
+ {
+ // Cannot place water here
+ return false;
+ }
+
+ if (a_Player->GetGameMode() != eGameMode_Creative)
+ {
+ // Remove fluid bucket, add empty bucket:
+ cItem Item(a_Item->m_ItemType, 1);
+ if (!a_Player->GetInventory().RemoveItem(Item))
+ {
+ LOG("Clicked with a full bucket, but cannot remove one from the inventory? WTF?");
+ ASSERT(!"Inventory bucket mismatch");
+ return false;
+ }
+ Item.m_ItemType = E_ITEM_BUCKET;
+ Item.m_ItemCount = 1;
+ if (!a_Player->GetInventory().AddItem(Item))
+ {
+ return false;
+ }
+ }
+
+ // Wash away anything that was there prior to placing:
+ if (CanWashAway)
+ {
+ cBlockHandler * Handler = BlockHandler(CurrentBlock);
+ if (Handler->DoesDropOnUnsuitable())
+ {
+ Handler->DropBlock(a_World, a_BlockX, a_BlockY, a_BlockZ);
}
- break;
}
- return false;
+ a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_FluidBlock, 0);
+
+ return true;
}
}; \ No newline at end of file