summaryrefslogtreecommitdiffstats
path: root/src/Items
diff options
context:
space:
mode:
authorTycho Bickerstaff <work.tycho@gmail.com>2013-12-18 20:06:11 +0100
committerTycho Bickerstaff <work.tycho@gmail.com>2013-12-18 20:06:11 +0100
commite627f2f98cb9a2ec7cddcaac779350abcbae414a (patch)
tree6101aa8aa5a0152c278e129a26ba7ca26172597c /src/Items
parentadded zlib (diff)
parentMerge pull request #440 from mc-server/repeaterfixes (diff)
downloadcuberite-e627f2f98cb9a2ec7cddcaac779350abcbae414a.tar
cuberite-e627f2f98cb9a2ec7cddcaac779350abcbae414a.tar.gz
cuberite-e627f2f98cb9a2ec7cddcaac779350abcbae414a.tar.bz2
cuberite-e627f2f98cb9a2ec7cddcaac779350abcbae414a.tar.lz
cuberite-e627f2f98cb9a2ec7cddcaac779350abcbae414a.tar.xz
cuberite-e627f2f98cb9a2ec7cddcaac779350abcbae414a.tar.zst
cuberite-e627f2f98cb9a2ec7cddcaac779350abcbae414a.zip
Diffstat (limited to 'src/Items')
-rw-r--r--src/Items/ItemBoat.h39
-rw-r--r--src/Items/ItemBucket.h120
-rw-r--r--src/Items/ItemHandler.cpp2
-rw-r--r--src/Items/ItemNetherWart.h54
4 files changed, 169 insertions, 46 deletions
diff --git a/src/Items/ItemBoat.h b/src/Items/ItemBoat.h
index 6e3395f1d..79c8e9589 100644
--- a/src/Items/ItemBoat.h
+++ b/src/Items/ItemBoat.h
@@ -10,6 +10,7 @@
#pragma once
#include "../Entities/Boat.h"
+#include "../LineBlockTracer.h"
@@ -30,23 +31,47 @@ public:
virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override
{
- if (a_Dir < 0)
+ if (a_Dir > 0)
{
return false;
}
+
+ class cCallbacks :
+ public cBlockTracer::cCallbacks
+ {
+ public:
+ Vector3d Pos;
+ virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override
+ {
+ if (a_BlockType != E_BLOCK_AIR)
+ {
+ Pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ);
+ return true;
+ }
+ return false;
+ }
+ } Callbacks;
- double x = (double)a_BlockX + 0.5;
- double y = (double)a_BlockY + 0.5;
- double z = (double)a_BlockZ + 0.5;
+ cLineBlockTracer Tracer(*a_World, Callbacks);
+ Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector());
+ Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5);
- cBoat * Boat = NULL;
+ Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z);
+
+ double x = Callbacks.Pos.x;
+ double y = Callbacks.Pos.y;
+ double z = Callbacks.Pos.z;
+
+ if ((x == 0) && (y == 0) && (z == 0))
+ {
+ return false;
+ }
- Boat = new cBoat (x, y, z);
+ cBoat * Boat = new cBoat(x + 0.5, y + 1, z + 0.5);
Boat->Initialize(a_World);
return true;
}
-
} ;
diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h
index fa3d48da1..c9a632580 100644
--- a/src/Items/ItemBucket.h
+++ b/src/Items/ItemBucket.h
@@ -5,6 +5,7 @@
#include "../World.h"
#include "../Simulator/FluidSimulator.h"
#include "../Blocks/BlockHandler.h"
+#include "../LineBlockTracer.h"
@@ -39,61 +40,54 @@ public:
bool ScoopUpFluid(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace)
{
- if (a_BlockFace < 0)
+ if (a_BlockFace > 0)
{
return false;
}
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
- 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)
+
+ Vector3i BlockPos;
+ if (!GetBlockFromTrace(a_World, a_Player, BlockPos))
+ {
+ return false; // Nothing in range.
+ }
+
+ if (a_World->GetBlockMeta(BlockPos.x, BlockPos.y, BlockPos.z) != 0)
{
// Not a source block
return false;
}
-
- if (a_Player->GetGameMode() == gmCreative)
+
+ BLOCKTYPE Block = a_World->GetBlock(BlockPos.x, BlockPos.y, BlockPos.z);
+ ENUM_ITEM_ID NewItem;
+
+ if (IsBlockWater(Block))
{
- // 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;
+ NewItem = E_ITEM_WATER_BUCKET;
}
-
- ENUM_ITEM_ID NewItem = E_ITEM_EMPTY;
- switch (ClickedBlock)
+ else if (IsBlockLava(Block))
{
- 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;
- }
-
- default: return false;
+ NewItem = E_ITEM_LAVA_BUCKET;
}
-
- // Remove the bucket from the inventory
- if (!a_Player->GetInventory().RemoveOneEquippedItem())
+ else
{
- LOG("Clicked with an empty bucket, but cannot remove one from the inventory? WTF?");
- ASSERT(!"Inventory bucket mismatch");
- return true;
+ return false;
}
- // Give new bucket, filled with fluid:
- cItem Item(NewItem, 1);
- a_Player->GetInventory().AddItem(Item, true, true);
+ // Give new bucket, filled with fluid when the gamemode is not creative:
+ if (!a_Player->IsGameModeCreative())
+ {
+ // Remove the bucket from the inventory
+ if (!a_Player->GetInventory().RemoveOneEquippedItem())
+ {
+ LOG("Clicked with an empty bucket, but cannot remove one from the inventory? WTF?");
+ ASSERT(!"Inventory bucket mismatch");
+ return true;
+ }
+ a_Player->GetInventory().AddItem(cItem(NewItem), true, true);
+ }
// Remove water / lava block
- a_Player->GetWorld()->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ a_Player->GetWorld()->SetBlock(BlockPos.x, BlockPos.y, BlockPos.z, E_BLOCK_AIR, 0);
return true;
}
@@ -157,4 +151,52 @@ public:
return true;
}
+
+ bool GetBlockFromTrace(cWorld * a_World, cPlayer * a_Player, Vector3i & BlockPos)
+ {
+ class cCallbacks :
+ public cBlockTracer::cCallbacks
+ {
+ public:
+ Vector3i m_Pos;
+ bool m_HasHitFluid;
+
+
+ cCallbacks(void) :
+ m_HasHitFluid(false)
+ {
+ }
+
+ virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override
+ {
+ if (a_BlockMeta != 0) // Even if it was a water block it would not be a source.
+ {
+ return false;
+ }
+ if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType))
+ {
+ m_HasHitFluid = true;
+ m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ);
+ return true;
+ }
+ return false;
+ }
+ } Callbacks;
+
+ cLineBlockTracer Tracer(*a_World, Callbacks);
+ Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector());
+ Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5);
+
+ Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z);
+
+ if (!Callbacks.m_HasHitFluid)
+ {
+ return false;
+ }
+
+
+ BlockPos.Set(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z);
+ return true;
+ }
+
};
diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp
index 92ba94999..23b9a86d4 100644
--- a/src/Items/ItemHandler.cpp
+++ b/src/Items/ItemHandler.cpp
@@ -23,6 +23,7 @@
#include "ItemLeaves.h"
#include "ItemLighter.h"
#include "ItemMinecart.h"
+#include "ItemNetherWart.h"
#include "ItemPickaxe.h"
#include "ItemThrowable.h"
#include "ItemRedstoneDust.h"
@@ -101,6 +102,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
case E_ITEM_FIREWORK_ROCKET: return new cItemFireworkHandler();
case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType);
case E_ITEM_FLOWER_POT: return new cItemFlowerPotHandler(a_ItemType);
+ case E_ITEM_NETHER_WART: return new cItemNetherWartHandler(a_ItemType);
case E_ITEM_REDSTONE_DUST: return new cItemRedstoneDustHandler(a_ItemType);
case E_ITEM_REDSTONE_REPEATER: return new cItemRedstoneRepeaterHandler(a_ItemType);
case E_ITEM_SHEARS: return new cItemShearsHandler(a_ItemType);
diff --git a/src/Items/ItemNetherWart.h b/src/Items/ItemNetherWart.h
new file mode 100644
index 000000000..aa4a44340
--- /dev/null
+++ b/src/Items/ItemNetherWart.h
@@ -0,0 +1,54 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+#include "../World.h"
+
+
+
+
+
+class cItemNetherWartHandler :
+ public cItemHandler
+{
+public:
+ cItemNetherWartHandler(int a_ItemType) :
+ cItemHandler(a_ItemType)
+ {
+
+ }
+
+ virtual bool IsPlaceable(void) override
+ {
+ return true;
+ }
+
+ virtual bool GetPlacementBlockTypeMeta(
+ cWorld * a_World, cPlayer * a_Player,
+ int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ int a_CursorX, int a_CursorY, int a_CursorZ,
+ BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
+ ) override
+ {
+ if (a_BlockFace != BLOCK_FACE_TOP)
+ {
+ // Only allow planting nether wart from the top side of the block
+ return false;
+ }
+
+ // Only allow placement on farmland
+ int X = a_BlockX;
+ int Y = a_BlockY;
+ int Z = a_BlockZ;
+ AddFaceDirection(X, Y, Z, a_BlockFace, true);
+ if (a_World->GetBlock(X, Y, Z) != E_BLOCK_SOULSAND)
+ {
+ return false;
+ }
+
+ a_BlockMeta = 0;
+ a_BlockType = E_BLOCK_NETHER_WART;
+
+ return true;
+ }
+} ; \ No newline at end of file