summaryrefslogtreecommitdiffstats
path: root/src/Blocks
diff options
context:
space:
mode:
Diffstat (limited to 'src/Blocks')
-rw-r--r--src/Blocks/BlockBed.cpp62
-rw-r--r--src/Blocks/BlockBed.h21
-rw-r--r--src/Blocks/BlockEntity.h2
-rw-r--r--src/Blocks/BlockHandler.cpp11
-rw-r--r--src/Blocks/BlockHandler.h4
5 files changed, 88 insertions, 12 deletions
diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp
index adc01c158..d6112f853 100644
--- a/src/Blocks/BlockBed.cpp
+++ b/src/Blocks/BlockBed.cpp
@@ -1,3 +1,6 @@
+
+// BlockBed.cpp
+
#include "Globals.h"
#include "BlockBed.h"
@@ -7,6 +10,7 @@
#include "../BoundingBox.h"
#include "../Mobs/Monster.h"
#include "../Entities/Entity.h"
+#include "../BlockEntities/BedEntity.h"
@@ -16,14 +20,19 @@ void cBlockBedHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInt
{
NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
- Vector3i ThisPos( a_BlockX, a_BlockY, a_BlockZ);
- Vector3i Direction = MetaDataToDirection( OldMeta & 0x3);
+ Vector3i ThisPos(a_BlockX, a_BlockY, a_BlockZ);
+ Vector3i Direction = MetaDataToDirection(OldMeta & 0x3);
if (OldMeta & 0x8)
{
// Was pillow
if (a_ChunkInterface.GetBlock(ThisPos - Direction) == E_BLOCK_BED)
{
+ // First replace the bed with air
a_ChunkInterface.FastSetBlock(ThisPos - Direction, E_BLOCK_AIR, 0);
+
+ // Then destroy the bed entity
+ Vector3i PillowPos(ThisPos - Direction);
+ a_ChunkInterface.SetBlock(PillowPos.x, PillowPos.y, PillowPos.z, E_BLOCK_AIR, 0);
}
}
else
@@ -31,7 +40,12 @@ void cBlockBedHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInt
// Was foot end
if (a_ChunkInterface.GetBlock(ThisPos + Direction) == E_BLOCK_BED)
{
+ // First replace the bed with air
a_ChunkInterface.FastSetBlock(ThisPos + Direction, E_BLOCK_AIR, 0);
+
+ // Then destroy the bed entity
+ Vector3i FootPos(ThisPos + Direction);
+ a_ChunkInterface.SetBlock(FootPos.x, FootPos.y, FootPos.z, E_BLOCK_AIR, 0);
}
}
}
@@ -169,4 +183,48 @@ bool cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface
+void cBlockBedHandler::OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, const sSetBlock & a_BlockChange)
+{
+ class cBedColor :
+ public cBedCallback
+ {
+ public:
+ short m_Color;
+ cBedColor(short a_Color) :
+ m_Color(a_Color)
+ {
+ }
+
+ virtual bool Item(cBedEntity * a_Bed) override
+ {
+ a_Bed->SetColor(m_Color);
+ return true;
+ }
+ };
+ cBedColor BedCallback(a_Player->GetEquippedItem().m_ItemDamage);
+ a_Player->GetWorld()->DoWithBedAt(a_BlockChange.GetX(), a_BlockChange.GetY(), a_BlockChange.GetZ(), BedCallback);
+}
+
+
+
+
+
+void cBlockBedHandler::ConvertToPickups(cEntity * a_Digger, cItems & a_Pickups, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
+{
+ class cBedColor :
+ public cBedCallback
+ {
+ public:
+ short m_Color = E_META_WOOL_RED;
+
+ virtual bool Item(cBedEntity * a_Bed) override
+ {
+ m_Color = a_Bed->GetColor();
+ return true;
+ }
+ };
+ cBedColor BedCallback;
+ a_Digger->GetWorld()->DoWithBedAt(a_BlockX, a_BlockY, a_BlockZ, BedCallback);
+ a_Pickups.Add(cItem(E_ITEM_BED, 1, BedCallback.m_Color));
+}
diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h
index cfb02ceeb..a9a3d0e20 100644
--- a/src/Blocks/BlockBed.h
+++ b/src/Blocks/BlockBed.h
@@ -1,10 +1,14 @@
+// BlockBed.h
+
#pragma once
+#include "BlockEntity.h"
#include "BlockHandler.h"
#include "MetaRotator.h"
-#include "Item.h"
#include "ChunkInterface.h"
+#include "../World.h"
+#include "../Entities/Entity.h"
class cPlayer;
@@ -14,15 +18,16 @@ class cWorldInterface;
class cBlockBedHandler :
- public cMetaRotator<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01, true>
+ public cMetaRotator<cBlockEntityHandler, 0x3, 0x02, 0x03, 0x00, 0x01, true>
{
public:
cBlockBedHandler(BLOCKTYPE a_BlockType)
- : cMetaRotator<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01, true>(a_BlockType)
+ : cMetaRotator<cBlockEntityHandler, 0x3, 0x02, 0x03, 0x00, 0x01, true>(a_BlockType)
{
}
virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override;
+
virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override;
virtual bool IsUseable(void) override
@@ -30,11 +35,9 @@ public:
return true;
}
- virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
- {
- // Reset meta to zero
- a_Pickups.push_back(cItem(E_ITEM_BED, 1, 0));
- }
+ virtual void ConvertToPickups(cItems & Pickups, NIBBLETYPE Meta) override {}
+
+ virtual void ConvertToPickups(cEntity * a_Digger, cItems & a_Pickups, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ) override;
// Bed specific helper functions
static NIBBLETYPE RotationToMetaData(double a_Rotation)
@@ -77,6 +80,8 @@ public:
a_ChunkInterface.SetBlockMeta(a_BedPosition.x, a_BedPosition.y, a_BedPosition.z, Meta);
}
+ virtual void OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, const sSetBlock & a_BlockChange) override;
+
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
{
UNUSED(a_Meta);
diff --git a/src/Blocks/BlockEntity.h b/src/Blocks/BlockEntity.h
index 06cd860c5..5b1267ec9 100644
--- a/src/Blocks/BlockEntity.h
+++ b/src/Blocks/BlockEntity.h
@@ -2,7 +2,7 @@
#pragma once
#include "BlockHandler.h"
-
+#include "ChunkInterface.h"
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index 36b20088c..41e3561d1 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -463,7 +463,6 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac
{
case E_BLOCK_ACACIA_DOOR:
case E_BLOCK_ACTIVE_COMPARATOR:
- case E_BLOCK_BED:
case E_BLOCK_BEETROOTS:
case E_BLOCK_BIRCH_DOOR:
case E_BLOCK_BREWING_STAND:
@@ -512,9 +511,19 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac
ConvertToPickups(Pickups, Meta);
break;
}
+ case E_BLOCK_BED:
+ {
+ // Need to access the bed entity to get the color for the item damage
+ ConvertToPickups(a_Digger, Pickups, Meta, a_BlockX, a_BlockY, a_BlockZ);
+ }
default: Pickups.Add(m_BlockType, 1, Meta); break;
}
}
+ else if (m_BlockType == E_BLOCK_BED)
+ {
+ // Need to access the bed entity to get the color for the item damage
+ ConvertToPickups(a_Digger, Pickups, Meta, a_BlockX, a_BlockY, a_BlockZ);
+ }
else
{
ConvertToPickups(Pickups, Meta);
diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h
index 24552fb46..625def7d8 100644
--- a/src/Blocks/BlockHandler.h
+++ b/src/Blocks/BlockHandler.h
@@ -80,6 +80,10 @@ public:
/** Called when the item is mined to convert it into pickups. Pickups may specify multiple items. Appends items to a_Pickups, preserves its original contents */
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta);
+ /** Called when the item is mined to convert it into pickups. Pickups may specify multiple items. Appends items to a_Pickups, preserves its original contents.
+ Overloaded method with coords and digger, for blocks that needs to access the block entity, e.g. a bed */
+ virtual void ConvertToPickups(cEntity * a_Digger, cItems & a_Pickups, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ) {}
+
/** Handles the dropping, but not destruction, of a block based on what ConvertTo(Verbatim)Pickups() returns, including the spawning of pickups and alertion of plugins
@param a_Digger The entity causing the drop; it may be nullptr
@param a_CanDrop Informs the handler whether the block should be dropped at all. One example when this is false is when stone is destroyed by hand