summaryrefslogtreecommitdiffstats
path: root/src/Blocks
diff options
context:
space:
mode:
Diffstat (limited to 'src/Blocks')
-rw-r--r--src/Blocks/BlockAnvil.h63
-rw-r--r--src/Blocks/BlockBed.cpp73
-rw-r--r--src/Blocks/BlockCake.h55
-rw-r--r--src/Blocks/BlockDirt.h5
-rw-r--r--src/Blocks/BlockHandler.cpp6
-rw-r--r--src/Blocks/BlockLeaves.h1
-rw-r--r--src/Blocks/BlockLilypad.h28
-rw-r--r--src/Blocks/BlockMobHead.h14
-rw-r--r--src/Blocks/BlockMushroom.h4
-rw-r--r--src/Blocks/BlockMycelium.h2
-rw-r--r--src/Blocks/BlockSideways.h8
-rw-r--r--src/Blocks/BlockVine.h7
-rw-r--r--src/Blocks/BroadcastInterface.h8
-rw-r--r--src/Blocks/WorldInterface.h11
14 files changed, 269 insertions, 16 deletions
diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h
new file mode 100644
index 000000000..9f5f84be0
--- /dev/null
+++ b/src/Blocks/BlockAnvil.h
@@ -0,0 +1,63 @@
+
+#pragma once
+
+#include "BlockHandler.h"
+#include "../World.h"
+#include "../Entities/Player.h"
+
+
+
+
+
+class cBlockAnvilHandler :
+ public cBlockHandler
+{
+public:
+ cBlockAnvilHandler(BLOCKTYPE a_BlockType)
+ : cBlockHandler(a_BlockType)
+ {
+ }
+
+ virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
+ {
+ a_Pickups.push_back(cItem(E_BLOCK_ANVIL, 1, a_BlockMeta >> 2));
+ }
+
+ virtual bool GetPlacementBlockTypeMeta(
+ cChunkInterface & a_ChunkInterface, cPlayer * a_Player,
+ int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
+ int a_CursorX, int a_CursorY, int a_CursorZ,
+ BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
+ ) override
+ {
+ a_BlockType = m_BlockType;
+
+ int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 0.5) & 0x3;
+ int RawMeta = a_BlockMeta >> 2;
+
+ Direction++;
+ Direction %= 4;
+ switch (Direction)
+ {
+ case 0: a_BlockMeta = 0x2 | RawMeta << 2; break;
+ case 1: a_BlockMeta = 0x3 | RawMeta << 2; break;
+ case 2: a_BlockMeta = 0x0 | RawMeta << 2; break;
+ case 3: a_BlockMeta = 0x1 | RawMeta << 2; break;
+ default:
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ virtual bool IsUseable() override
+ {
+ return true;
+ }
+} ;
+
+
+
+
diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp
index 3dad4feba..6a3c6a55b 100644
--- a/src/Blocks/BlockBed.cpp
+++ b/src/Blocks/BlockBed.cpp
@@ -51,6 +51,49 @@ void cBlockBedHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInt
+class cTimeFastForwardTester :
+ public cPlayerListCallback
+{
+ virtual bool Item(cPlayer * a_Player) override
+ {
+ if (!a_Player->IsInBed())
+ {
+ return true;
+ }
+
+ return false;
+ }
+};
+
+
+
+
+
+class cPlayerBedStateUnsetter :
+ public cPlayerListCallback
+{
+public:
+ cPlayerBedStateUnsetter(Vector3i a_Position, cWorldInterface & a_WorldInterface) :
+ m_Position(a_Position), m_WorldInterface(a_WorldInterface)
+ {
+ }
+
+ virtual bool Item(cPlayer * a_Player) override
+ {
+ a_Player->SetIsInBed(false);
+ m_WorldInterface.GetBroadcastManager().BroadcastEntityAnimation(*a_Player, 2);
+ return false;
+ }
+
+private:
+ Vector3i m_Position;
+ cWorldInterface & m_WorldInterface;
+};
+
+
+
+
+
void cBlockBedHandler::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)
{
if (a_WorldInterface.GetDimension() != dimOverworld)
@@ -69,6 +112,8 @@ void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface
}
else
{
+ Vector3i PillowDirection(0, 0, 0);
+
if (Meta & 0x8)
{
// Is pillow
@@ -77,16 +122,30 @@ void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface
else
{
// Is foot end
- Vector3i Direction = MetaDataToDirection( Meta & 0x7 );
- if (a_ChunkInterface.GetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z) == E_BLOCK_BED) // Must always use pillow location for sleeping
+ VERIFY((Meta & 0x4) != 0x4); // Occupied flag should never be set, else our compilator (intended) is broken
+
+ PillowDirection = MetaDataToDirection(Meta & 0x7);
+ if (a_ChunkInterface.GetBlock(a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z) == E_BLOCK_BED) // Must always use pillow location for sleeping
{
- a_WorldInterface.GetBroadcastManager().BroadcastUseBed(*a_Player, a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z);
+ a_WorldInterface.GetBroadcastManager().BroadcastUseBed(*a_Player, a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z);
}
}
- a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, (Meta | (1 << 2)));
- }
-
- } else {
+
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x4); // Where 0x4 = occupied bit
+ a_Player->SetIsInBed(true);
+
+ cTimeFastForwardTester Tester;
+ if (a_WorldInterface.ForEachPlayer(Tester))
+ {
+ cPlayerBedStateUnsetter Unsetter(Vector3i(a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z), a_WorldInterface);
+ a_WorldInterface.ForEachPlayer(Unsetter);
+ a_WorldInterface.SetTimeOfDay(0);
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0xB); // Where 0xB = 1011, and zero is to make sure 'occupied' bit is always unset
+ }
+ }
+ }
+ else
+ {
a_Player->SendMessageFailure("You can only sleep at night");
}
}
diff --git a/src/Blocks/BlockCake.h b/src/Blocks/BlockCake.h
new file mode 100644
index 000000000..36e133388
--- /dev/null
+++ b/src/Blocks/BlockCake.h
@@ -0,0 +1,55 @@
+#pragma once
+
+#include "BlockHandler.h"
+
+
+
+
+
+class cBlockCakeHandler :
+ public cBlockHandler
+{
+public:
+ cBlockCakeHandler(BLOCKTYPE a_BlockType)
+ : cBlockHandler(a_BlockType)
+ {
+ }
+
+ virtual void 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
+ {
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+
+ if (!a_Player->Feed(2, 0.1))
+ {
+ return;
+ }
+
+ if (Meta >= 5)
+ {
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ }
+ else
+ {
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta + 1);
+ }
+ }
+
+ virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
+ {
+ // Give nothing
+ }
+
+ virtual bool IsUseable(void) override
+ {
+ return true;
+ }
+
+ virtual const char * GetStepSound(void) override
+ {
+ return "step.cloth";
+ }
+} ;
+
+
+
+
diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h
index 544424a04..a1ab74257 100644
--- a/src/Blocks/BlockDirt.h
+++ b/src/Blocks/BlockDirt.h
@@ -79,7 +79,10 @@ public:
Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta);
if ((cBlockInfo::IsOneHitDig(AboveDest) || cBlockInfo::IsTransparent(AboveDest)) && !IsBlockWater(AboveDest))
{
- Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0);
+ if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, BlockX * cChunkDef::Width, BlockY, BlockZ * cChunkDef::Width, ssGrassSpread))
+ {
+ Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0);
+ }
}
} // for i - repeat twice
}
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index aa97b2ca9..7fd8c183c 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -6,10 +6,12 @@
#include "../Root.h"
#include "../Bindings/PluginManager.h"
#include "../Chunk.h"
+#include "BlockAnvil.h"
#include "BlockBed.h"
#include "BlockBrewingStand.h"
#include "BlockButton.h"
#include "BlockCactus.h"
+#include "BlockCake.h"
#include "BlockCarpet.h"
#include "BlockCauldron.h"
#include "BlockChest.h"
@@ -39,6 +41,7 @@
#include "BlockIce.h"
#include "BlockLadder.h"
#include "BlockLeaves.h"
+#include "BlockLilypad.h"
#include "BlockNewLeaves.h"
#include "BlockLever.h"
#include "BlockMelon.h"
@@ -85,12 +88,14 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
// Block handlers, alphabetically sorted:
case E_BLOCK_ACACIA_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_ACTIVATOR_RAIL: return new cBlockRailHandler (a_BlockType);
+ case E_BLOCK_ANVIL: return new cBlockAnvilHandler (a_BlockType);
case E_BLOCK_BED: return new cBlockBedHandler (a_BlockType);
case E_BLOCK_BIRCH_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_BREWING_STAND: return new cBlockBrewingStandHandler (a_BlockType);
case E_BLOCK_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_BROWN_MUSHROOM: return new cBlockMushroomHandler (a_BlockType);
case E_BLOCK_CACTUS: return new cBlockCactusHandler (a_BlockType);
+ case E_BLOCK_CAKE: return new cBlockCakeHandler (a_BlockType);
case E_BLOCK_CARROTS: return new cBlockCropsHandler (a_BlockType);
case E_BLOCK_CARPET: return new cBlockCarpetHandler (a_BlockType);
case E_BLOCK_CAULDRON: return new cBlockCauldronHandler (a_BlockType);
@@ -138,6 +143,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_LAPIS_ORE: return new cBlockOreHandler (a_BlockType);
case E_BLOCK_LAVA: return new cBlockLavaHandler (a_BlockType);
case E_BLOCK_LEAVES: return new cBlockLeavesHandler (a_BlockType);
+ case E_BLOCK_LILY_PAD: return new cBlockLilypadHandler (a_BlockType);
case E_BLOCK_LIT_FURNACE: return new cBlockFurnaceHandler (a_BlockType);
case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType);
case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType);
diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h
index 7b8f0b378..a6d3373c1 100644
--- a/src/Blocks/BlockLeaves.h
+++ b/src/Blocks/BlockLeaves.h
@@ -16,6 +16,7 @@
{ \
case E_BLOCK_LEAVES: a_Area.SetBlockType(x, y, z, (BLOCKTYPE)(E_BLOCK_SPONGE + i + 1)); break; \
case E_BLOCK_LOG: return true; \
+ case E_BLOCK_NEW_LOG: return true; \
}
bool HasNearLog(cBlockArea &a_Area, int a_BlockX, int a_BlockY, int a_BlockZ);
diff --git a/src/Blocks/BlockLilypad.h b/src/Blocks/BlockLilypad.h
new file mode 100644
index 000000000..2dd4ec768
--- /dev/null
+++ b/src/Blocks/BlockLilypad.h
@@ -0,0 +1,28 @@
+
+#pragma once
+
+#include "BlockHandler.h"
+#include "Entities/Pickup.h"
+
+
+
+
+class cBlockLilypadHandler :
+ public cBlockHandler
+{
+public:
+ cBlockLilypadHandler(BLOCKTYPE a_BlockType)
+ : cBlockHandler(a_BlockType)
+ {
+ }
+
+ virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
+ {
+ // Reset meta to zero
+ a_Pickups.push_back(cItem(E_BLOCK_LILY_PAD, 1, 0));
+ }
+};
+
+
+
+
diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h
index 2b128f13b..6aa01f986 100644
--- a/src/Blocks/BlockMobHead.h
+++ b/src/Blocks/BlockMobHead.h
@@ -21,6 +21,18 @@ public:
{
a_Pickups.push_back(cItem(E_ITEM_HEAD, 1, 0));
}
+
+ bool TrySpawnWither(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
+ {
+ if (a_BlockY < 2)
+ {
+ return false;
+ }
+
+ // TODO 2014-03-24 xdot
+
+ return false;
+ }
virtual void OnPlacedByPlayer(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player,
@@ -62,6 +74,8 @@ public:
cWorld * World = (cWorld *) &a_WorldInterface;
World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta);
+
+ TrySpawnWither(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
}
} ;
diff --git a/src/Blocks/BlockMushroom.h b/src/Blocks/BlockMushroom.h
index 623cfda64..135d418d7 100644
--- a/src/Blocks/BlockMushroom.h
+++ b/src/Blocks/BlockMushroom.h
@@ -17,6 +17,9 @@ public:
}
+ // TODO: Add Mushroom Spread
+
+
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
// Reset meta to 0
@@ -39,6 +42,7 @@ public:
case E_BLOCK_CACTUS:
case E_BLOCK_ICE:
case E_BLOCK_LEAVES:
+ case E_BLOCK_NEW_LEAVES:
case E_BLOCK_AIR:
{
return false;
diff --git a/src/Blocks/BlockMycelium.h b/src/Blocks/BlockMycelium.h
index 7f897c72a..2a8ef5fca 100644
--- a/src/Blocks/BlockMycelium.h
+++ b/src/Blocks/BlockMycelium.h
@@ -16,6 +16,8 @@ public:
{
}
+ // TODO: Add Mycel Spread
+
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
a_Pickups.push_back(cItem(E_BLOCK_DIRT, 1, 0));
diff --git a/src/Blocks/BlockSideways.h b/src/Blocks/BlockSideways.h
index 69c0a7230..d67c3aa24 100644
--- a/src/Blocks/BlockSideways.h
+++ b/src/Blocks/BlockSideways.h
@@ -29,7 +29,13 @@ public:
return true;
}
-
+
+ virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
+ {
+ a_Pickups.Add(m_BlockType, 1, a_BlockMeta & 0x3);
+ }
+
+
inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_BlockFace, NIBBLETYPE a_WoodMeta)
{
switch (a_BlockFace)
diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h
index 0b57acc7b..e14218633 100644
--- a/src/Blocks/BlockVine.h
+++ b/src/Blocks/BlockVine.h
@@ -73,7 +73,7 @@ public:
/// Returns true if the specified block type is good for vines to attach to
static bool IsBlockAttachable(BLOCKTYPE a_BlockType)
{
- return (a_BlockType == E_BLOCK_LEAVES) || cBlockInfo::IsSolid(a_BlockType);
+ return (a_BlockType == E_BLOCK_LEAVES) || (a_BlockType == E_BLOCK_NEW_LEAVES) || cBlockInfo::IsSolid(a_BlockType);
}
@@ -175,7 +175,10 @@ public:
a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block);
if (Block == E_BLOCK_AIR)
{
- a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
+ if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX * cChunkDef::Width, a_RelY - 1, a_RelZ * cChunkDef::Width, ssVineSpread))
+ {
+ a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
+ }
}
}
diff --git a/src/Blocks/BroadcastInterface.h b/src/Blocks/BroadcastInterface.h
index f6ccd580b..b1b450690 100644
--- a/src/Blocks/BroadcastInterface.h
+++ b/src/Blocks/BroadcastInterface.h
@@ -4,7 +4,9 @@
class cBroadcastInterface
{
public:
-
- virtual void BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) = 0;
- virtual void BroadcastSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL) = 0;
+ virtual ~cBroadcastInterface() {}
+
+ virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) = 0;
+ virtual void BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL) = 0;
+ virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) = 0;
};
diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h
index e59b00eff..bfbb053d9 100644
--- a/src/Blocks/WorldInterface.h
+++ b/src/Blocks/WorldInterface.h
@@ -9,7 +9,8 @@ class cItems;
class cWorldInterface
{
public:
-
+ virtual ~cWorldInterface() {}
+
virtual Int64 GetTimeOfDay(void) const = 0;
virtual Int64 GetWorldAge(void) const = 0;
@@ -27,7 +28,13 @@ public:
/** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */
virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0;
-
+
/** Sends the block on those coords to the player */
virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player) = 0;
+
+ /** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */
+ virtual bool ForEachPlayer(cItemCallback<cPlayer> & a_Callback) = 0;
+
+ virtual void SetTimeOfDay(Int64 a_TimeOfDay) = 0;
+
};