summaryrefslogtreecommitdiffstats
path: root/src/Items
diff options
context:
space:
mode:
Diffstat (limited to 'src/Items')
-rw-r--r--src/Items/ItemBoat.h26
-rw-r--r--src/Items/ItemBucket.h8
-rw-r--r--src/Items/ItemEmptyMap.h2
-rw-r--r--src/Items/ItemFishingRod.h4
-rw-r--r--src/Items/ItemHandler.cpp8
-rw-r--r--src/Items/ItemLilypad.h110
-rw-r--r--src/Items/ItemMap.h2
-rw-r--r--src/Items/ItemMinecart.h6
8 files changed, 145 insertions, 21 deletions
diff --git a/src/Items/ItemBoat.h b/src/Items/ItemBoat.h
index a28ec8e22..42f4ffc8f 100644
--- a/src/Items/ItemBoat.h
+++ b/src/Items/ItemBoat.h
@@ -39,12 +39,20 @@ public:
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
+ Vector3d m_Pos;
+ bool m_HasFound;
+
+ cCallbacks(void) :
+ m_HasFound(false)
{
- if (a_BlockType != E_BLOCK_AIR)
+ }
+
+ virtual bool OnNextBlock(int a_CBBlockX, int a_CBBlockY, int a_CBBlockZ, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, char a_CBEntryFace) override
+ {
+ if (a_CBBlockType != E_BLOCK_AIR)
{
- Pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ);
+ m_Pos.Set(a_CBBlockX, a_CBBlockY, a_CBBlockZ);
+ m_HasFound = true;
return true;
}
return false;
@@ -57,15 +65,15 @@ public:
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))
+ if (!Callbacks.m_HasFound)
{
return false;
}
+ double x = Callbacks.m_Pos.x;
+ double y = Callbacks.m_Pos.y;
+ double z = Callbacks.m_Pos.z;
+
cBoat * Boat = new cBoat(x + 0.5, y + 1, z + 0.5);
Boat->Initialize(a_World);
diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h
index 72cb8fa0a..68c89dd85 100644
--- a/src/Items/ItemBucket.h
+++ b/src/Items/ItemBucket.h
@@ -172,12 +172,12 @@ public:
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))
{
+ if (a_BlockMeta != 0) // GetBlockFromTrace is called for scooping up fluids; the hit block should be a source
+ {
+ return false;
+ }
m_HasHitFluid = true;
m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ);
return true;
diff --git a/src/Items/ItemEmptyMap.h b/src/Items/ItemEmptyMap.h
index f0b1e1424..953673382 100644
--- a/src/Items/ItemEmptyMap.h
+++ b/src/Items/ItemEmptyMap.h
@@ -55,7 +55,7 @@ public:
return true;
}
- a_Player->GetInventory().AddItem(cItem(E_ITEM_MAP, 1, NewMap->GetID()), true, true);
+ a_Player->GetInventory().AddItem(cItem(E_ITEM_MAP, 1, (short)(NewMap->GetID() & 0x7fff)), true, true);
return true;
}
diff --git a/src/Items/ItemFishingRod.h b/src/Items/ItemFishingRod.h
index 15acbd9fe..0431b88b7 100644
--- a/src/Items/ItemFishingRod.h
+++ b/src/Items/ItemFishingRod.h
@@ -123,7 +123,7 @@ public:
}
case 2:
{
- Drops.Add(cItem(E_ITEM_FISHING_ROD, 1, a_World->GetTickRandomNumber(50))); // Fishing rod with durability. TODO: Enchantments on it
+ Drops.Add(cItem(E_ITEM_FISHING_ROD, 1, (short)a_World->GetTickRandomNumber(50))); // Fishing rod with durability. TODO: Enchantments on it
break;
}
case 3:
@@ -152,7 +152,7 @@ public:
}
else if (Junk <= 4)
{
- Drops.Add(cItem(E_ITEM_BOW, 1, a_World->GetTickRandomNumber(64)));
+ Drops.Add(cItem(E_ITEM_BOW, 1, (short)a_World->GetTickRandomNumber(64)));
}
else if (Junk <= 9)
{
diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp
index 454fabdd7..1e77717e3 100644
--- a/src/Items/ItemHandler.cpp
+++ b/src/Items/ItemHandler.cpp
@@ -27,6 +27,7 @@
#include "ItemHoe.h"
#include "ItemLeaves.h"
#include "ItemLighter.h"
+#include "ItemLilypad.h"
#include "ItemMap.h"
#include "ItemMinecart.h"
#include "ItemNetherWart.h"
@@ -115,6 +116,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
case E_ITEM_FISHING_ROD: return new cItemFishingRodHandler(a_ItemType);
case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType);
case E_ITEM_FLOWER_POT: return new cItemFlowerPotHandler(a_ItemType);
+ case E_BLOCK_LILY_PAD: return new cItemLilypadHandler(a_ItemType);
case E_ITEM_MAP: return new cItemMapHandler();
case E_ITEM_ITEM_FRAME: return new cItemItemFrameHandler(a_ItemType);
case E_ITEM_NETHER_WART: return new cItemNetherWartHandler(a_ItemType);
@@ -504,13 +506,13 @@ bool cItemHandler::GetPlacementBlockTypeMeta(
{
ASSERT(m_ItemType < 256); // Items with IDs above 255 should all be handled by specific handlers
- if (m_ItemType > 256)
+ if (m_ItemType >= 256)
{
- LOGERROR("%s: Item %d has no valid block!", __FUNCTION__, m_ItemType);
+ LOGERROR("%s: Item %d is not eligible for direct block placement!", __FUNCTION__, m_ItemType);
return false;
}
- cBlockHandler * BlockH = BlockHandler(m_ItemType);
+ cBlockHandler * BlockH = BlockHandler((BLOCKTYPE)m_ItemType);
cChunkInterface ChunkInterface(a_World->GetChunkMap());
return BlockH->GetPlacementBlockTypeMeta(
ChunkInterface, a_Player,
diff --git a/src/Items/ItemLilypad.h b/src/Items/ItemLilypad.h
new file mode 100644
index 000000000..8fc1d8543
--- /dev/null
+++ b/src/Items/ItemLilypad.h
@@ -0,0 +1,110 @@
+#pragma once
+
+#include "ItemHandler.h"
+#include "../Entities/Player.h"
+#include "Vector3.h"
+#include "../LineBlockTracer.h"
+#include "BlockInfo.h"
+
+
+
+
+
+class cItemLilypadHandler :
+ public cItemHandler
+{
+ typedef cItemHandler super;
+
+public:
+ cItemLilypadHandler(int a_ItemType):
+ super(a_ItemType)
+ {
+
+ }
+
+
+ virtual bool IsPlaceable(void) override
+ {
+ return false; // Set as not placeable so OnItemUse is called
+ }
+
+
+ virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
+ {
+ if (a_BlockFace > BLOCK_FACE_NONE)
+ {
+ // Clicked on the side of a submerged block; vanilla allows placement, so should we
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
+ a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LILY_PAD, 0);
+ if (!a_Player->IsGameModeCreative())
+ {
+ a_Player->GetInventory().RemoveOneEquippedItem();
+ }
+ return true;
+ }
+
+ class cCallbacks :
+ public cBlockTracer::cCallbacks
+ {
+ public:
+ cCallbacks(cWorld * a_CBWorld) :
+ m_HasHitFluid(false),
+ m_World(a_CBWorld)
+ {
+ }
+
+ virtual bool OnNextBlock(int a_CBBlockX, int a_CBBlockY, int a_CBBlockZ, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, char a_CBEntryFace) override
+ {
+ if (IsBlockWater(a_CBBlockType))
+ {
+ if ((a_CBBlockMeta != 0) || (a_CBEntryFace == BLOCK_FACE_NONE)) // The hit block should be a source. The FACE_NONE check is clicking whilst submerged
+ {
+ return false;
+ }
+ AddFaceDirection(a_CBBlockX, a_CBBlockY, a_CBBlockZ, BLOCK_FACE_YP); // Always place pad at top of water block
+ BLOCKTYPE Block = m_World->GetBlock(a_CBBlockX, a_CBBlockY, a_CBBlockZ);
+ if (
+ !IsBlockWater(Block) &&
+ cBlockInfo::FullyOccupiesVoxel(Block)
+ )
+ {
+ // Can't place lilypad on air/in another block!
+ return true;
+ }
+ m_HasHitFluid = true;
+ m_Pos.Set(a_CBBlockX, a_CBBlockY, a_CBBlockZ);
+ return true;
+ }
+ return false;
+ }
+
+ Vector3i m_Pos;
+ bool m_HasHitFluid;
+ cWorld * m_World;
+
+ };
+
+ cCallbacks Callbacks(a_World);
+ cLineBlockTracer Tracer(*a_Player->GetWorld(), 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)
+ {
+ a_World->SetBlock(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z, E_BLOCK_LILY_PAD, 0);
+ if (!a_Player->IsGameModeCreative())
+ {
+ a_Player->GetInventory().RemoveOneEquippedItem();
+ }
+ return true;
+ }
+
+ return false;
+ }
+};
+
+
+
+
diff --git a/src/Items/ItemMap.h b/src/Items/ItemMap.h
index e8ff9da88..056fe0fe7 100644
--- a/src/Items/ItemMap.h
+++ b/src/Items/ItemMap.h
@@ -29,7 +29,7 @@ public:
virtual void OnUpdate(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item)
{
- cMap * Map = a_World->GetMapManager().GetMapData(a_Item.m_ItemDamage);
+ cMap * Map = a_World->GetMapManager().GetMapData((unsigned)a_Item.m_ItemDamage);
if (Map == NULL)
{
diff --git a/src/Items/ItemMinecart.h b/src/Items/ItemMinecart.h
index bcaa5635a..25500aeb9 100644
--- a/src/Items/ItemMinecart.h
+++ b/src/Items/ItemMinecart.h
@@ -1,4 +1,3 @@
-
// ItemMinecart.h
// Declares the various minecart ItemHandlers
@@ -72,6 +71,11 @@ public:
}
} // switch (m_ItemType)
Minecart->Initialize(a_World);
+
+ if (!a_Player->IsGameModeCreative())
+ {
+ a_Player->GetInventory().RemoveOneEquippedItem();
+ }
return true;
}