summaryrefslogtreecommitdiffstats
path: root/src/Blocks
diff options
context:
space:
mode:
authordaniel0916 <theschokolps@gmail.com>2014-04-07 20:12:17 +0200
committerdaniel0916 <theschokolps@gmail.com>2014-04-07 20:12:17 +0200
commit2e9754ac1cf0537c12ab7974cf55c451c0724540 (patch)
tree713c5b8c8f22f77893b30b9c8cefca4a7c491483 /src/Blocks
parentFixed merge conflict (diff)
parentFixed some more minor issues with the redstone simulator. (diff)
downloadcuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar
cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar.gz
cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar.bz2
cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar.lz
cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar.xz
cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar.zst
cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.zip
Diffstat (limited to 'src/Blocks')
-rw-r--r--src/Blocks/BlockAnvil.h61
-rw-r--r--src/Blocks/BlockBed.cpp118
-rw-r--r--src/Blocks/BlockBed.h14
-rw-r--r--src/Blocks/BlockBigFlower.h131
-rw-r--r--src/Blocks/BlockButton.h29
-rw-r--r--src/Blocks/BlockCactus.h6
-rw-r--r--src/Blocks/BlockCake.h55
-rw-r--r--src/Blocks/BlockCarpet.h6
-rw-r--r--src/Blocks/BlockCauldron.h24
-rw-r--r--src/Blocks/BlockChest.h49
-rw-r--r--src/Blocks/BlockComparator.h24
-rw-r--r--src/Blocks/BlockCrops.h19
-rw-r--r--src/Blocks/BlockDeadBush.h3
-rw-r--r--src/Blocks/BlockDirt.h22
-rw-r--r--src/Blocks/BlockDoor.cpp142
-rw-r--r--src/Blocks/BlockDoor.h54
-rw-r--r--src/Blocks/BlockDropSpenser.h23
-rw-r--r--src/Blocks/BlockEnderchest.h10
-rw-r--r--src/Blocks/BlockEntity.h4
-rw-r--r--src/Blocks/BlockFarmland.h4
-rw-r--r--src/Blocks/BlockFenceGate.h24
-rw-r--r--src/Blocks/BlockFire.h80
-rw-r--r--src/Blocks/BlockFlower.h2
-rw-r--r--src/Blocks/BlockFlowerPot.h83
-rw-r--r--src/Blocks/BlockFluid.h8
-rw-r--r--src/Blocks/BlockFurnace.h12
-rw-r--r--src/Blocks/BlockHandler.cpp141
-rw-r--r--src/Blocks/BlockHandler.h63
-rw-r--r--src/Blocks/BlockHopper.h25
-rw-r--r--src/Blocks/BlockIce.h4
-rw-r--r--src/Blocks/BlockLadder.h51
-rw-r--r--src/Blocks/BlockLeaves.h42
-rw-r--r--src/Blocks/BlockLever.h57
-rw-r--r--src/Blocks/BlockLilypad.h28
-rw-r--r--src/Blocks/BlockMobHead.h186
-rw-r--r--src/Blocks/BlockMushroom.h6
-rw-r--r--src/Blocks/BlockMycelium.h2
-rw-r--r--src/Blocks/BlockNetherWart.h21
-rw-r--r--src/Blocks/BlockNewLeaves.h42
-rw-r--r--src/Blocks/BlockPiston.cpp22
-rw-r--r--src/Blocks/BlockPiston.h8
-rw-r--r--src/Blocks/BlockPlanks.h4
-rw-r--r--src/Blocks/BlockPluginInterface.h14
-rw-r--r--src/Blocks/BlockPortal.h6
-rw-r--r--src/Blocks/BlockPumpkin.h56
-rw-r--r--src/Blocks/BlockQuartz.h67
-rw-r--r--src/Blocks/BlockRail.h307
-rw-r--r--src/Blocks/BlockRedstone.h4
-rw-r--r--src/Blocks/BlockRedstoneRepeater.h26
-rw-r--r--src/Blocks/BlockSapling.h4
-rw-r--r--src/Blocks/BlockSideways.h (renamed from src/Blocks/BlockWood.h)18
-rw-r--r--src/Blocks/BlockSign.h41
-rw-r--r--src/Blocks/BlockSlab.h90
-rw-r--r--src/Blocks/BlockSnow.h10
-rw-r--r--src/Blocks/BlockStairs.h80
-rw-r--r--src/Blocks/BlockStems.h7
-rw-r--r--src/Blocks/BlockSugarcane.h4
-rw-r--r--src/Blocks/BlockTNT.h32
-rw-r--r--src/Blocks/BlockTallGrass.h26
-rw-r--r--src/Blocks/BlockTorch.h115
-rw-r--r--src/Blocks/BlockTrapdoor.h34
-rw-r--r--src/Blocks/BlockVine.h47
-rw-r--r--src/Blocks/BlockWorkbench.h2
-rw-r--r--src/Blocks/BroadcastInterface.h12
-rw-r--r--src/Blocks/ChunkInterface.cpp12
-rw-r--r--src/Blocks/ChunkInterface.h92
-rw-r--r--src/Blocks/MetaRotator.h120
-rw-r--r--src/Blocks/WorldInterface.h40
68 files changed, 2086 insertions, 889 deletions
diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h
new file mode 100644
index 000000000..93a796ef7
--- /dev/null
+++ b/src/Blocks/BlockAnvil.h
@@ -0,0 +1,61 @@
+
+#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;
+ NIBBLETYPE HighBits = a_BlockMeta & 0x0c; // Only highest two bits are preserved
+ int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 1.5) & 0x3;
+ switch (Direction)
+ {
+ case 0: a_BlockMeta = 0x2 | HighBits; break;
+ case 1: a_BlockMeta = 0x3 | HighBits; break;
+ case 2: a_BlockMeta = 0x0 | HighBits; break;
+ case 3: a_BlockMeta = 0x1 | HighBits; 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 66eb9130c..6a3c6a55b 100644
--- a/src/Blocks/BlockBed.cpp
+++ b/src/Blocks/BlockBed.cpp
@@ -6,8 +6,8 @@
void cBlockBedHandler::OnPlacedByPlayer(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
)
@@ -15,7 +15,7 @@ void cBlockBedHandler::OnPlacedByPlayer(
if (a_BlockMeta < 8)
{
Vector3i Direction = MetaDataToDirection(a_BlockMeta);
- a_World->SetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z, E_BLOCK_BED, a_BlockMeta | 0x8);
+ a_ChunkInterface.SetBlock(a_WorldInterface,a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z, E_BLOCK_BED, a_BlockMeta | 0x8);
}
}
@@ -23,26 +23,26 @@ void cBlockBedHandler::OnPlacedByPlayer(
-void cBlockBedHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+void cBlockBedHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
- NIBBLETYPE OldMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
Vector3i ThisPos( a_BlockX, a_BlockY, a_BlockZ );
Vector3i Direction = MetaDataToDirection( OldMeta & 0x7 );
if (OldMeta & 0x8)
{
// Was pillow
- if (a_World->GetBlock(ThisPos - Direction) == E_BLOCK_BED)
+ if (a_ChunkInterface.GetBlock(ThisPos - Direction) == E_BLOCK_BED)
{
- a_World->FastSetBlock(ThisPos - Direction, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(ThisPos - Direction, E_BLOCK_AIR, 0);
}
}
else
{
// Was foot end
- if (a_World->GetBlock(ThisPos + Direction) == E_BLOCK_BED)
+ if (a_ChunkInterface.GetBlock(ThisPos + Direction) == E_BLOCK_BED)
{
- a_World->FastSetBlock(ThisPos + Direction, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(ThisPos + Direction, E_BLOCK_AIR, 0);
}
}
}
@@ -51,34 +51,102 @@ void cBlockBedHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY,
-void cBlockBedHandler::OnUse(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)
+class cTimeFastForwardTester :
+ public cPlayerListCallback
{
- if (a_World->GetDimension() != dimOverworld)
+ 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)
{
Vector3i Coords(a_BlockX, a_BlockY, a_BlockZ);
- a_World->DoExplosionAt(5, a_BlockX, a_BlockY, a_BlockZ, true, esBed, &Coords);
+ a_WorldInterface.DoExplosionAt(5, a_BlockX, a_BlockY, a_BlockZ, true, esBed, &Coords);
}
else
{
- if (a_World->GetTimeOfDay() > 13000)
+ if (a_WorldInterface.GetTimeOfDay() > 13000)
{
- NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
- if (Meta & 0x8)
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ if (Meta & 0x4)
{
- // Is pillow
- a_World->BroadcastUseBed(*a_Player, a_BlockX, a_BlockY, a_BlockZ);
+ a_Player->SendMessageFailure("This bed is occupied.");
}
else
{
- // Is foot end
- Vector3i Direction = MetaDataToDirection( Meta & 0x7 );
- if (a_World->GetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z) == E_BLOCK_BED) // Must always use pillow location for sleeping
+ Vector3i PillowDirection(0, 0, 0);
+
+ if (Meta & 0x8)
{
- a_World->BroadcastUseBed(*a_Player, a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z);
+ // Is pillow
+ a_WorldInterface.GetBroadcastManager().BroadcastUseBed(*a_Player, a_BlockX, a_BlockY, a_BlockZ);
}
- }
- } else {
- a_Player->SendMessage("You can only sleep at night");
+ else
+ {
+ // Is foot end
+ 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 + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z);
+ }
+ }
+
+ 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");
}
}
}
@@ -86,3 +154,5 @@ void cBlockBedHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, i
+
+
diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h
index 8a289b22c..92804aaac 100644
--- a/src/Blocks/BlockBed.h
+++ b/src/Blocks/BlockBed.h
@@ -2,7 +2,9 @@
#pragma once
#include "BlockHandler.h"
-#include "../World.h"
+#include "ChunkInterface.h"
+#include "WorldInterface.h"
+#include "MetaRotator.h"
#include "../Entities/Player.h"
@@ -10,18 +12,18 @@
class cBlockBedHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01, true>
{
public:
cBlockBedHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01,true>(a_BlockType)
{
}
- virtual void OnPlacedByPlayer(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;
- virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override;
- virtual void OnUse(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) override;
+ virtual void OnPlacedByPlayer(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, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
+ virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override;
+ 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;
virtual bool IsUseable(void) override
diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h
new file mode 100644
index 000000000..39fd3cac8
--- /dev/null
+++ b/src/Blocks/BlockBigFlower.h
@@ -0,0 +1,131 @@
+
+#pragma once
+
+#include "BlockHandler.h"
+
+
+
+
+
+class cBlockBigFlowerHandler :
+ public cBlockHandler
+{
+public:
+ typedef cBlockHandler super;
+
+ cBlockBigFlowerHandler(BLOCKTYPE a_BlockType)
+ : cBlockHandler(a_BlockType)
+ {
+ }
+
+
+ virtual void DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ {
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ if (Meta & 0x8)
+ {
+ super::DropBlock(a_ChunkInterface, a_WorldInterface, a_BlockPluginInterface, a_Digger, a_BlockX, a_BlockY - 1, a_BlockZ);
+ }
+ else
+ {
+ super::DropBlock(a_ChunkInterface, a_WorldInterface, a_BlockPluginInterface, a_Digger, a_BlockX, a_BlockY, a_BlockZ);
+ }
+ }
+
+
+ virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
+ {
+ NIBBLETYPE Meta = a_BlockMeta & 0x7;
+
+ if ((Meta == 2) || (Meta == 3))
+ {
+ return;
+ }
+
+ a_Pickups.push_back(cItem(E_BLOCK_BIG_FLOWER, 1, Meta));
+ }
+
+
+ virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ {
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ if (Meta & 0x8)
+ {
+ Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ);
+ }
+
+ NIBBLETYPE FlowerMeta = Meta & 0x7;
+ if (!a_Player->IsGameModeCreative())
+ {
+ if (((FlowerMeta == 2) || (FlowerMeta == 3)) && (a_Player->GetEquippedItem().m_ItemType == E_ITEM_SHEARS))
+ {
+ MTRand r1;
+ if (r1.randInt(10) == 5)
+ {
+ cItems Pickups;
+ if (FlowerMeta == 2)
+ {
+ Pickups.Add(E_BLOCK_TALL_GRASS, 2, 1);
+ }
+ else if (FlowerMeta == 3)
+ {
+ Pickups.Add(E_BLOCK_TALL_GRASS, 2, 2);
+ }
+ a_WorldInterface.SpawnItemPickups(Pickups, a_BlockX, a_BlockY, a_BlockZ);
+ }
+ a_Player->UseEquippedItem();
+ }
+ }
+ }
+
+
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ {
+ return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR) && (a_RelY < cChunkDef::Height) && ((a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ) == E_BLOCK_AIR) || (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ) == E_BLOCK_BIG_FLOWER)));
+ }
+
+
+ virtual void OnPlacedByPlayer(
+ 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,
+ BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
+ ) override
+ {
+ int Meta = (((int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 0.5) & 0x3) + 2) % 4;
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, 0x8 | Meta);
+ }
+
+
+ virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ {
+ NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+
+ if (OldMeta & 0x8)
+ {
+ // Was upper part of flower
+ if (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) == m_BlockType)
+ {
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
+ }
+ }
+ else
+ {
+ // Was lower part
+ if (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ) == m_BlockType)
+ {
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, E_BLOCK_AIR, 0);
+ }
+ }
+ }
+
+
+ virtual const char * GetStepSound(void) override
+ {
+ return "step.grass";
+ }
+} ;
+
+
+
+
diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h
index c898a0466..4b2f6f618 100644
--- a/src/Blocks/BlockButton.h
+++ b/src/Blocks/BlockButton.h
@@ -1,31 +1,32 @@
#pragma once
#include "BlockHandler.h"
-
+#include "Chunk.h"
+#include "MetaRotator.h"
class cBlockButtonHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true>
{
public:
cBlockButtonHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true>(a_BlockType)
{
}
- virtual void OnUse(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) override
+ 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
{
// Set p the ON bit to on
- NIBBLETYPE Meta = (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) | 0x08);
+ NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) | 0x08);
- a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
- a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
+ a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
// Queue a button reset (unpress)
- a_World->QueueSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x07), m_BlockType == E_BLOCK_STONE_BUTTON ? 20 : 30, m_BlockType);
+ a_ChunkInterface.QueueSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x07), m_BlockType == E_BLOCK_STONE_BUTTON ? 20 : 30, m_BlockType, a_WorldInterface);
}
@@ -43,8 +44,8 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
@@ -61,7 +62,7 @@ public:
}
- inline static NIBBLETYPE BlockFaceToMetaData(char a_BlockFace)
+ inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_BlockFace)
{
switch (a_BlockFace)
{
@@ -77,7 +78,7 @@ public:
}
}
- inline static NIBBLETYPE BlockMetaDataToBlockFace(NIBBLETYPE a_Meta)
+ inline static eBlockFace BlockMetaDataToBlockFace(NIBBLETYPE a_Meta)
{
switch (a_Meta & 0x7)
{
@@ -93,7 +94,7 @@ public:
}
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
NIBBLETYPE Meta;
a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta);
@@ -101,7 +102,7 @@ public:
AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true);
BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
- return (a_RelY > 0) && (g_BlockIsSolid[BlockIsOn]);
+ return (a_RelY > 0) && (cBlockInfo::IsSolid(BlockIsOn));
}
} ;
diff --git a/src/Blocks/BlockCactus.h b/src/Blocks/BlockCactus.h
index 88be25dc0..ed441517d 100644
--- a/src/Blocks/BlockCactus.h
+++ b/src/Blocks/BlockCactus.h
@@ -24,7 +24,7 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
if (a_RelY <= 0)
{
@@ -54,7 +54,7 @@ public:
NIBBLETYPE BlockMeta;
if (
a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta) &&
- (g_BlockIsSolid[BlockType])
+ cBlockInfo::IsSolid(BlockType)
)
{
return false;
@@ -65,7 +65,7 @@ public:
}
- void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
+ virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
a_Chunk.GetWorld()->GrowCactus(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, 1);
}
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/BlockCarpet.h b/src/Blocks/BlockCarpet.h
index 5eafd8c21..33dc1da6c 100644
--- a/src/Blocks/BlockCarpet.h
+++ b/src/Blocks/BlockCarpet.h
@@ -31,8 +31,8 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
@@ -49,7 +49,7 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
return (a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR);
}
diff --git a/src/Blocks/BlockCauldron.h b/src/Blocks/BlockCauldron.h
index b0e00f869..41b79b6c3 100644
--- a/src/Blocks/BlockCauldron.h
+++ b/src/Blocks/BlockCauldron.h
@@ -21,24 +21,30 @@ public:
a_Pickups.push_back(cItem(E_ITEM_CAULDRON, 1, 0));
}
- void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
+ 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
{
- char Meta = a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ );
- switch( a_Player->GetEquippedItem().m_ItemType )
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ switch (a_Player->GetEquippedItem().m_ItemType)
{
case E_ITEM_WATER_BUCKET:
{
- a_World->SetBlockMeta( a_BlockX, a_BlockY, a_BlockZ, 3 );
- a_Player->GetInventory().RemoveOneEquippedItem();
- cItem NewItem(E_ITEM_BUCKET, 1);
- a_Player->GetInventory().AddItem(NewItem);
+ if (Meta < 3)
+ {
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 3);
+ if (!a_Player->IsGameModeCreative())
+ {
+ a_Player->GetInventory().RemoveOneEquippedItem();
+ cItem NewItem(E_ITEM_BUCKET, 1);
+ a_Player->GetInventory().AddItem(NewItem);
+ }
+ }
break;
}
case E_ITEM_GLASS_BOTTLE:
{
- if( Meta > 0 )
+ if (Meta > 0)
{
- a_World->SetBlockMeta( a_BlockX, a_BlockY, a_BlockZ, --Meta);
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, --Meta);
a_Player->GetInventory().RemoveOneEquippedItem();
cItem NewItem(E_ITEM_POTIONS, 1, 0);
a_Player->GetInventory().AddItem(NewItem);
diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h
index 88f7c4b32..a1ded4c26 100644
--- a/src/Blocks/BlockChest.h
+++ b/src/Blocks/BlockChest.h
@@ -2,27 +2,27 @@
#pragma once
#include "BlockEntity.h"
-#include "../World.h"
#include "../BlockArea.h"
#include "../Entities/Player.h"
+#include "MetaRotator.h"
class cBlockChestHandler :
- public cBlockEntityHandler
+ public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
{
public:
cBlockChestHandler(BLOCKTYPE a_BlockType)
- : cBlockEntityHandler(a_BlockType)
+ : cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
{
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
@@ -30,7 +30,7 @@ public:
a_BlockType = m_BlockType;
// Is there a doublechest already next to this block?
- if (!CanBeAt(a_World, a_BlockX, a_BlockY, a_BlockZ))
+ if (!CanBeAt(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ))
{
// Yup, cannot form a triple-chest, refuse:
return false;
@@ -38,7 +38,7 @@ public:
// Check if this forms a doublechest, if so, need to adjust the meta:
cBlockArea Area;
- if (!Area.Read(a_World, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1))
+ if (!Area.Read(&a_ChunkInterface, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1))
{
return false;
}
@@ -67,15 +67,15 @@ public:
virtual void OnPlacedByPlayer(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
) override
{
// Check if this forms a doublechest, if so, need to adjust the meta:
cBlockArea Area;
- if (!Area.Read(a_World, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1))
+ if (!Area.Read(&a_ChunkInterface, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1))
{
return;
}
@@ -84,8 +84,8 @@ public:
// Choose meta from player rotation, choose only between 2 or 3
NIBBLETYPE NewMeta = ((rot >= -90) && (rot < 90)) ? 2 : 3;
if (
- CheckAndAdjustNeighbor(a_World, Area, 0, 1, NewMeta) ||
- CheckAndAdjustNeighbor(a_World, Area, 2, 1, NewMeta)
+ CheckAndAdjustNeighbor(a_ChunkInterface, Area, 0, 1, NewMeta) ||
+ CheckAndAdjustNeighbor(a_ChunkInterface, Area, 2, 1, NewMeta)
)
{
// Forming a double chest in the X direction
@@ -94,8 +94,8 @@ public:
// Choose meta from player rotation, choose only between 4 or 5
NewMeta = (rot < 0) ? 4 : 5;
if (
- CheckAndAdjustNeighbor(a_World, Area, 1, 0, NewMeta) ||
- CheckAndAdjustNeighbor(a_World, Area, 2, 2, NewMeta)
+ CheckAndAdjustNeighbor(a_ChunkInterface, Area, 1, 0, NewMeta) ||
+ CheckAndAdjustNeighbor(a_ChunkInterface, Area, 2, 2, NewMeta)
)
{
// Forming a double chest in the Z direction
@@ -111,11 +111,18 @@ public:
return "step.wood";
}
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ {
+ int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
+ int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
+ return CanBeAt(a_ChunkInterface, BlockX, a_RelY, BlockZ);
+ }
+
- virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
cBlockArea Area;
- if (!Area.Read(a_World, a_BlockX - 2, a_BlockX + 2, a_BlockY, a_BlockY, a_BlockZ - 2, a_BlockZ + 2))
+ if (!Area.Read(&a_ChunkInterface, a_BlockX - 2, a_BlockX + 2, a_BlockY, a_BlockY, a_BlockZ - 2, a_BlockZ + 2))
{
// Cannot read the surroundings, probably at the edge of loaded chunks. Disallow.
return false;
@@ -207,15 +214,21 @@ public:
/// If there's a chest in the a_Area in the specified coords, modifies its meta to a_NewMeta and returns true.
- bool CheckAndAdjustNeighbor(cWorld * a_World, const cBlockArea & a_Area, int a_RelX, int a_RelZ, NIBBLETYPE a_NewMeta)
+ bool CheckAndAdjustNeighbor(cChunkInterface & a_ChunkInterface, const cBlockArea & a_Area, int a_RelX, int a_RelZ, NIBBLETYPE a_NewMeta)
{
if (a_Area.GetRelBlockType(a_RelX, 0, a_RelZ) != E_BLOCK_CHEST)
{
return false;
}
- a_World->SetBlockMeta(a_Area.GetOriginX() + a_RelX, a_Area.GetOriginY(), a_Area.GetOriginZ() + a_RelZ, a_NewMeta);
+ a_ChunkInterface.SetBlockMeta(a_Area.GetOriginX() + a_RelX, a_Area.GetOriginY(), a_Area.GetOriginZ() + a_RelZ, a_NewMeta);
return true;
}
+
+
+ virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
+ {
+ a_Pickups.push_back(cItem(E_BLOCK_CHEST, 1, 0));
+ }
} ;
diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h
index 5a8e54eda..4dd05366d 100644
--- a/src/Blocks/BlockComparator.h
+++ b/src/Blocks/BlockComparator.h
@@ -3,26 +3,34 @@
#include "BlockHandler.h"
#include "BlockRedstoneRepeater.h"
+#include "MetaRotator.h"
class cBlockComparatorHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>
{
public:
cBlockComparatorHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>(a_BlockType)
{
}
- virtual void OnUse(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) override
+ 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_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
Meta ^= 0x04; // Toggle 3rd (addition/subtraction) bit with XOR
- a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
+ }
+
+
+ virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
+ {
+ UNUSED(a_ChunkInterface);
+ a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
}
@@ -39,15 +47,15 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR));
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
diff --git a/src/Blocks/BlockCrops.h b/src/Blocks/BlockCrops.h
index 9c4964e02..8606cf3f3 100644
--- a/src/Blocks/BlockCrops.h
+++ b/src/Blocks/BlockCrops.h
@@ -2,8 +2,7 @@
#pragma once
#include "BlockHandler.h"
-#include "../MersenneTwister.h"
-#include "../World.h"
+#include "../FastRandom.h"
@@ -22,7 +21,7 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_Meta) override
{
- MTRand rand;
+ cFastRandom rand;
if (a_Meta == 0x7)
{
@@ -32,18 +31,18 @@ public:
case E_BLOCK_CROPS:
{
a_Pickups.push_back(cItem(E_ITEM_WHEAT, 1, 0));
- a_Pickups.push_back(cItem(E_ITEM_SEEDS, 1 + (int)(rand.randInt(2) + rand.randInt(2)) / 2, 0)); // [1 .. 3] with high preference of 2
+ a_Pickups.push_back(cItem(E_ITEM_SEEDS, (char)(1 + (rand.NextInt(3) + rand.NextInt(3)) / 2), 0)); // [1 .. 3] with high preference of 2
break;
}
case E_BLOCK_CARROTS:
{
- a_Pickups.push_back(cItem(E_ITEM_CARROT, 1 + (int)(rand.randInt(2) + rand.randInt(2)) / 2, 0)); // [1 .. 3] with high preference of 2
+ a_Pickups.push_back(cItem(E_ITEM_CARROT, (char)(1 + (rand.NextInt(3) + rand.NextInt(3)) / 2), 0)); // [1 .. 3] with high preference of 2
break;
}
case E_BLOCK_POTATOES:
{
- a_Pickups.push_back(cItem(E_ITEM_POTATO, 1 + (int)(rand.randInt(2) + rand.randInt(2)) / 2, 0)); // [1 .. 3] with high preference of 2
- if (rand.randInt(20) == 0)
+ a_Pickups.push_back(cItem(E_ITEM_POTATO, (char)(1 + (rand.NextInt(3) + rand.NextInt(3)) / 2), 0)); // [1 .. 3] with high preference of 2
+ if (rand.NextInt(21) == 0)
{
// With a 5% chance, drop a poisonous potato as well
a_Pickups.push_back(cItem(E_ITEM_POISONOUS_POTATO, 1, 0));
@@ -75,7 +74,7 @@ public:
}
- void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
+ virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
NIBBLETYPE Meta = a_Chunk.GetMeta (a_RelX, a_RelY, a_RelZ);
NIBBLETYPE Light = a_Chunk.GetBlockLight(a_RelX, a_RelY, a_RelZ);
@@ -88,7 +87,7 @@ public:
if ((Meta < 7) && (Light > 8))
{
- a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_CROPS, ++Meta);
+ a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, ++Meta);
}
else if (Light < 9)
{
@@ -97,7 +96,7 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_FARMLAND));
}
diff --git a/src/Blocks/BlockDeadBush.h b/src/Blocks/BlockDeadBush.h
index 14617d006..5b687c710 100644
--- a/src/Blocks/BlockDeadBush.h
+++ b/src/Blocks/BlockDeadBush.h
@@ -2,7 +2,6 @@
#pragma once
#include "BlockHandler.h"
-#include "../World.h"
@@ -24,7 +23,7 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
return (a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_SAND);
}
diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h
index 46210e406..aa24b8668 100644
--- a/src/Blocks/BlockDirt.h
+++ b/src/Blocks/BlockDirt.h
@@ -2,8 +2,7 @@
#pragma once
#include "BlockHandler.h"
-#include "../MersenneTwister.h"
-#include "../World.h"
+#include "../FastRandom.h"
@@ -26,7 +25,7 @@ public:
}
- void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
+ virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
if (m_BlockType != E_BLOCK_GRASS)
{
@@ -37,7 +36,7 @@ public:
if (a_RelY < cChunkDef::Height - 1)
{
BLOCKTYPE Above = a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ);
- if ((!g_BlockTransparent[Above] && !g_BlockOneHitDig[Above]) || IsBlockWater(Above))
+ if ((!cBlockInfo::IsTransparent(Above) && !cBlockInfo::IsOneHitDig(Above)) || IsBlockWater(Above))
{
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, E_META_DIRT_NORMAL);
return;
@@ -45,12 +44,12 @@ public:
}
// Grass spreads to adjacent dirt blocks:
- MTRand rand; // TODO: Replace with cFastRandom
+ cFastRandom rand;
for (int i = 0; i < 2; i++) // Pick two blocks to grow to
{
- int OfsX = rand.randInt(2) - 1; // [-1 .. 1]
- int OfsY = rand.randInt(4) - 3; // [-3 .. 1]
- int OfsZ = rand.randInt(2) - 1; // [-1 .. 1]
+ int OfsX = rand.NextInt(3, a_RelX) - 1; // [-1 .. 1]
+ int OfsY = rand.NextInt(5, a_RelY) - 3; // [-3 .. 1]
+ int OfsZ = rand.NextInt(3, a_RelZ) - 1; // [-1 .. 1]
BLOCKTYPE DestBlock;
NIBBLETYPE DestMeta;
@@ -78,9 +77,12 @@ public:
BLOCKTYPE AboveDest;
NIBBLETYPE AboveMeta;
Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta);
- if ((g_BlockOneHitDig[AboveDest] || g_BlockTransparent[AboveDest]) && !IsBlockWater(AboveDest))
+ 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/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp
index e91211559..479c68153 100644
--- a/src/Blocks/BlockDoor.cpp
+++ b/src/Blocks/BlockDoor.cpp
@@ -2,7 +2,6 @@
#include "Globals.h"
#include "BlockDoor.h"
#include "../Item.h"
-#include "../World.h"
#include "../Entities/Player.h"
@@ -10,7 +9,7 @@
cBlockDoorHandler::cBlockDoorHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ : super(a_BlockType)
{
}
@@ -18,24 +17,24 @@ cBlockDoorHandler::cBlockDoorHandler(BLOCKTYPE a_BlockType)
-void cBlockDoorHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+void cBlockDoorHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
- NIBBLETYPE OldMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
if (OldMeta & 8)
{
// Was upper part of door
- if (IsDoor(a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)))
+ if (IsDoor(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)))
{
- a_World->FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
}
}
else
{
// Was lower part
- if (IsDoor(a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)))
+ if (IsDoor(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)))
{
- a_World->FastSetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, E_BLOCK_AIR, 0);
}
}
}
@@ -44,11 +43,34 @@ void cBlockDoorHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY
-void cBlockDoorHandler::OnUse(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)
+void cBlockDoorHandler::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_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_DOOR)
+ if (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_DOOR)
{
- ChangeDoor(a_World, a_BlockX, a_BlockY, a_BlockZ);
+ ChangeDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
+ }
+}
+
+
+
+
+
+void cBlockDoorHandler::OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace)
+{
+ UNUSED(a_ChunkInterface);
+
+ a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+
+ if (Meta & 8)
+ {
+ // Current block is top of the door
+ a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY - 1, a_BlockZ, a_Player);
+ }
+ else
+ {
+ // Current block is bottom of the door
+ a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, a_Player);
}
}
@@ -57,23 +79,23 @@ void cBlockDoorHandler::OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX
void cBlockDoorHandler::OnPlacedByPlayer(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
)
{
NIBBLETYPE a_TopBlockMeta = 8;
if (
- ((a_BlockMeta == 0) && (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) == m_BlockType)) ||
- ((a_BlockMeta == 1) && (a_World->GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) == m_BlockType)) ||
- ((a_BlockMeta == 2) && (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) == m_BlockType)) ||
- ((a_BlockMeta == 3) && (a_World->GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) == m_BlockType))
+ ((a_BlockMeta == 0) && (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) == m_BlockType)) ||
+ ((a_BlockMeta == 1) && (a_ChunkInterface.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) == m_BlockType)) ||
+ ((a_BlockMeta == 2) && (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) == m_BlockType)) ||
+ ((a_BlockMeta == 3) && (a_ChunkInterface.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) == m_BlockType))
)
{
a_TopBlockMeta = 9;
}
- a_World->SetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta);
+ a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta);
}
@@ -88,3 +110,87 @@ const char * cBlockDoorHandler::GetStepSound(void)
+
+NIBBLETYPE cBlockDoorHandler::MetaRotateCCW(NIBBLETYPE a_Meta)
+{
+ if (a_Meta & 0x08)
+ {
+ return a_Meta;
+ }
+ else
+ {
+ return super::MetaRotateCCW(a_Meta);
+ }
+}
+
+
+
+NIBBLETYPE cBlockDoorHandler::MetaRotateCW(NIBBLETYPE a_Meta)
+{
+ if (a_Meta & 0x08)
+ {
+ return a_Meta;
+ }
+ else
+ {
+ return super::MetaRotateCW(a_Meta);
+ }
+}
+
+
+
+NIBBLETYPE cBlockDoorHandler::MetaMirrorXY(NIBBLETYPE a_Meta)
+{
+ // Top bit (0x08) contains door panel type (Top/Bottom panel) Only Bottom panels contain position data
+ // Return a_Meta if panel is a top panel (0x08 bit is set to 1)
+
+ // Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored
+ // in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time,
+ // so the function can only see either the hinge position or orientation, but not both, at any given time. The class itself
+ // needs extra datamembers.
+ if (a_Meta & 0x08) return a_Meta;
+
+ // Holds open/closed meta data. 0x0C == 1100.
+ NIBBLETYPE OtherMeta = a_Meta & 0x0C;
+
+ // Mirrors according to a table. 0x03 == 0011.
+ switch (a_Meta & 0x03)
+ {
+ case 0x03: return 0x01 + OtherMeta; // South -> North
+ case 0x01: return 0x03 + OtherMeta; // North -> South
+ }
+
+ // Not Facing North or South; No change.
+ return a_Meta;
+}
+
+
+
+NIBBLETYPE cBlockDoorHandler::MetaMirrorYZ(NIBBLETYPE a_Meta)
+{
+ // Top bit (0x08) contains door panel type (Top/Bottom panel) Only Bottom panels contain position data
+ // Return a_Meta if panel is a top panel (0x08 bit is set to 1)
+
+ // Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored
+ // in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time,
+ // so the function can only see either the hinge position or orientation, but not both, at any given time.The class itself
+ // needs extra datamembers.
+
+ if (a_Meta & 0x08) return a_Meta;
+
+ // Holds open/closed meta data. 0x0C == 1100.
+ NIBBLETYPE OtherMeta = a_Meta & 0x0C;
+
+ // Mirrors according to a table. 0x03 == 0011.
+ switch (a_Meta & 0x03)
+ {
+ case 0x00: return 0x02 + OtherMeta; // West -> East
+ case 0x02: return 0x00 + OtherMeta; // East -> West
+ }
+
+ // Not Facing North or South; No change.
+ return a_Meta;
+}
+
+
+
diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h
index 1e86446dd..797fe484c 100644
--- a/src/Blocks/BlockDoor.h
+++ b/src/Blocks/BlockDoor.h
@@ -2,27 +2,33 @@
#pragma once
#include "BlockHandler.h"
-#include "../World.h"
#include "../Entities/Player.h"
-
+#include "Chunk.h"
+#include "MetaRotator.h"
class cBlockDoorHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true>
{
+ typedef cMetaRotator<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true> super;
public:
cBlockDoorHandler(BLOCKTYPE a_BlockType);
- virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override;
- virtual void OnUse(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) override;
+ virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override;
+ 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;
+ virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override;
virtual const char * GetStepSound(void) override;
+ virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override;
+ virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override;
+ virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override;
+ virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override;
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
@@ -34,8 +40,8 @@ public:
}
if (
- !CanReplaceBlock(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ)) ||
- !CanReplaceBlock(a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))
+ !CanReplaceBlock(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ)) ||
+ !CanReplaceBlock(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))
)
{
return false;
@@ -54,8 +60,8 @@ public:
virtual void OnPlacedByPlayer(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
) override;
@@ -67,7 +73,7 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR));
}
@@ -137,37 +143,35 @@ public:
/// Changes the door at the specified coords from open to close or vice versa
- static void ChangeDoor(cWorld * a_World, int a_X, int a_Y, int a_Z)
+ static void ChangeDoor(cChunkInterface & a_ChunkInterface, int a_X, int a_Y, int a_Z)
{
- NIBBLETYPE OldMetaData = a_World->GetBlockMeta(a_X, a_Y, a_Z);
-
- a_World->SetBlockMeta(a_X, a_Y, a_Z, ChangeStateMetaData(OldMetaData));
-
+ NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_X, a_Y, a_Z);
+
+ a_ChunkInterface.SetBlockMeta(a_X, a_Y, a_Z, ChangeStateMetaData(OldMetaData));
+
if (OldMetaData & 8)
{
// Current block is top of the door
- BLOCKTYPE BottomBlock = a_World->GetBlock(a_X, a_Y - 1, a_Z);
- NIBBLETYPE BottomMeta = a_World->GetBlockMeta(a_X, a_Y - 1, a_Z);
+ BLOCKTYPE BottomBlock = a_ChunkInterface.GetBlock(a_X, a_Y - 1, a_Z);
+ NIBBLETYPE BottomMeta = a_ChunkInterface.GetBlockMeta(a_X, a_Y - 1, a_Z);
if (IsDoor(BottomBlock) && !(BottomMeta & 8))
{
- a_World->SetBlockMeta(a_X, a_Y - 1, a_Z, ChangeStateMetaData(BottomMeta));
+ a_ChunkInterface.SetBlockMeta(a_X, a_Y - 1, a_Z, ChangeStateMetaData(BottomMeta));
}
}
else
{
// Current block is bottom of the door
- BLOCKTYPE TopBlock = a_World->GetBlock(a_X, a_Y + 1, a_Z);
- NIBBLETYPE TopMeta = a_World->GetBlockMeta(a_X, a_Y + 1, a_Z);
+ BLOCKTYPE TopBlock = a_ChunkInterface.GetBlock(a_X, a_Y + 1, a_Z);
+ NIBBLETYPE TopMeta = a_ChunkInterface.GetBlockMeta(a_X, a_Y + 1, a_Z);
if (IsDoor(TopBlock) && (TopMeta & 8))
{
- a_World->SetBlockMeta(a_X, a_Y + 1, a_Z, ChangeStateMetaData(TopMeta));
+ a_ChunkInterface.SetBlockMeta(a_X, a_Y + 1, a_Z, ChangeStateMetaData(TopMeta));
}
}
}
-
-
} ;
diff --git a/src/Blocks/BlockDropSpenser.h b/src/Blocks/BlockDropSpenser.h
index ce9cc0c5d..88b61a418 100644
--- a/src/Blocks/BlockDropSpenser.h
+++ b/src/Blocks/BlockDropSpenser.h
@@ -6,24 +6,25 @@
#pragma once
#include "../Piston.h"
+#include "MetaRotator.h"
class cBlockDropSpenserHandler :
- public cBlockEntityHandler
+ public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
{
public:
cBlockDropSpenserHandler(BLOCKTYPE a_BlockType) :
- cBlockEntityHandler(a_BlockType)
+ cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
{
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
@@ -34,6 +35,20 @@ public:
a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetYaw(), a_Player->GetPitch());
return true;
}
+
+ virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
+ {
+ // Bit 0x08 is a flag. Lowest three bits are position. 0x08 == 1000
+ NIBBLETYPE OtherMeta = a_Meta & 0x08;
+ // Mirrors defined by by a table. (Source, mincraft.gamepedia.com) 0x07 == 0111
+ switch (a_Meta & 0x07)
+ {
+ case 0x00: return 0x01 + OtherMeta; // Down -> Up
+ case 0x01: return 0x00 + OtherMeta; // Up -> Down
+ }
+ // Not Facing Up or Down; No change.
+ return a_Meta;
+ }
} ;
diff --git a/src/Blocks/BlockEnderchest.h b/src/Blocks/BlockEnderchest.h
index b648248d0..67955f8ce 100644
--- a/src/Blocks/BlockEnderchest.h
+++ b/src/Blocks/BlockEnderchest.h
@@ -2,17 +2,17 @@
#pragma once
#include "BlockEntity.h"
-
+#include "MetaRotator.h"
class cBlockEnderchestHandler :
- public cBlockEntityHandler
+ public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
{
public:
cBlockEnderchestHandler(BLOCKTYPE a_BlockType)
- : cBlockEntityHandler(a_BlockType)
+ : cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
{
}
@@ -23,8 +23,8 @@ public:
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
diff --git a/src/Blocks/BlockEntity.h b/src/Blocks/BlockEntity.h
index 9c6b23665..7f86a22b2 100644
--- a/src/Blocks/BlockEntity.h
+++ b/src/Blocks/BlockEntity.h
@@ -15,9 +15,9 @@ public:
{
}
- virtual void OnUse(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) override
+ 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
{
- a_World->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ);
+ a_ChunkInterface.UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ);
}
virtual bool IsUseable() override
diff --git a/src/Blocks/BlockFarmland.h b/src/Blocks/BlockFarmland.h
index a69d9b775..b720ccd14 100644
--- a/src/Blocks/BlockFarmland.h
+++ b/src/Blocks/BlockFarmland.h
@@ -28,7 +28,7 @@ public:
}
- void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
+ virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
bool Found = false;
@@ -90,6 +90,8 @@ public:
switch (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ))
{
case E_BLOCK_CROPS:
+ case E_BLOCK_POTATOES:
+ case E_BLOCK_CARROTS:
case E_BLOCK_MELON_STEM:
case E_BLOCK_PUMPKIN_STEM:
{
diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h
index 779f12ee1..e202c6610 100644
--- a/src/Blocks/BlockFenceGate.h
+++ b/src/Blocks/BlockFenceGate.h
@@ -2,24 +2,24 @@
#pragma once
#include "BlockHandler.h"
-
+#include "MetaRotator.h"
class cBlockFenceGateHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01, true>
{
public:
cBlockFenceGateHandler(BLOCKTYPE a_BlockType) :
- cBlockHandler(a_BlockType)
+ cMetaRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01, true>(a_BlockType)
{
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
@@ -30,24 +30,30 @@ public:
}
- virtual void OnUse(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) override
+ 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 OldMetaData = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
NIBBLETYPE NewMetaData = PlayerYawToMetaData(a_Player->GetYaw());
OldMetaData ^= 4; // Toggle the gate
if ((OldMetaData & 1) == (NewMetaData & 1))
{
// Standing in front of the gate - apply new direction
- a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, (OldMetaData & 4) | (NewMetaData & 3));
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, (OldMetaData & 4) | (NewMetaData & 3));
}
else
{
// Standing aside - use last direction
- a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, OldMetaData);
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, OldMetaData);
}
}
+ virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
+ {
+ a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
+ }
+
+
virtual bool IsUseable(void) override
{
return true;
diff --git a/src/Blocks/BlockFire.h b/src/Blocks/BlockFire.h
index a69fe2131..c8f158e7e 100644
--- a/src/Blocks/BlockFire.h
+++ b/src/Blocks/BlockFire.h
@@ -17,30 +17,32 @@ public:
}
/// Portal boundary and direction variables
- int XZP, XZM, Dir; // For wont of a better name...
+ // 2014_03_30 _X: What are these used for? Why do we need extra variables?
+ int XZP, XZM;
+ NIBBLETYPE Dir;
- virtual void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override
+ virtual void OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override
{
/*
PORTAL FINDING ALGORITH
=======================
- -Get clicked base block
- -Trace upwards to find first obsidian block; aborts if anything other than obsidian or air is encountered.
- Uses this value as a reference (the 'ceiling')
- -For both directions (if one fails, try the other), BASE (clicked) block:
- -Go in one direction, only stop if a non obsidian block is encountered (abort) OR a portal border is encountered (FindObsidianCeiling returns -1)
- -If a border was encountered, go the other direction and repeat above
- -Write borders to XZP and XZM, write direction portal faces to Dir
- -Loop through boundary variables, and fill with portal blocks based on Dir with meta from Dir
+ - Get clicked base block
+ - Trace upwards to find first obsidian block; aborts if anything other than obsidian or air is encountered.
+ Uses this value as a reference (the 'ceiling')
+ - For both directions (if one fails, try the other), BASE (clicked) block:
+ - Go in one direction, only stop if a non obsidian block is encountered (abort) OR a portal border is encountered (FindObsidianCeiling returns -1)
+ - If a border was encountered, go the other direction and repeat above
+ - Write borders to XZP and XZM, write direction portal faces to Dir
+ - Loop through boundary variables, and fill with portal blocks based on Dir with meta from Dir
*/
a_BlockY--; // Because we want the block below the fire
- FindAndSetPortalFrame(a_BlockX, a_BlockY, a_BlockZ, a_World); // Brought to you by Aperture Science
+ FindAndSetPortalFrame(a_BlockX, a_BlockY, a_BlockZ, a_ChunkInterface, a_WorldInterface);
}
- virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ virtual void OnDigging(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
{
- a_World->DigBlock(a_BlockX, a_BlockY, a_BlockZ);
+ a_ChunkInterface.DigBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ);
}
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
@@ -60,9 +62,9 @@ public:
/// Traces along YP until it finds an obsidian block, returns Y difference or 0 if no portal, and -1 for border
/// Takes the X, Y, and Z of the base block; with an optional MaxY for portal border finding
- int FindObsidianCeiling(int X, int Y, int Z, cWorld * a_World, int MaxY = 0)
+ int FindObsidianCeiling(int X, int Y, int Z, cChunkInterface & a_ChunkInterface, int MaxY = 0)
{
- if (a_World->GetBlock(X, Y, Z) != E_BLOCK_OBSIDIAN)
+ if (a_ChunkInterface.GetBlock(X, Y, Z) != E_BLOCK_OBSIDIAN)
{
return 0;
}
@@ -70,7 +72,7 @@ public:
for (int newY = Y + 1; newY < cChunkDef::Height; newY++)
{
- BLOCKTYPE Block = a_World->GetBlock(X, newY, Z);
+ BLOCKTYPE Block = a_ChunkInterface.GetBlock(X, newY, Z);
if ((Block == E_BLOCK_AIR) || (Block == E_BLOCK_FIRE))
{
continue;
@@ -82,7 +84,7 @@ public:
// This is because the frame is a solid obsidian pillar
if ((MaxY != 0) && (newY == Y + 1))
{
- return EvaluatePortalBorder(X, newY, Z, MaxY, a_World);
+ return EvaluatePortalBorder(X, newY, Z, MaxY, a_ChunkInterface);
}
else
{
@@ -97,11 +99,11 @@ public:
}
/// Evaluates if coords have a valid border on top, based on MaxY
- int EvaluatePortalBorder(int X, int FoundObsidianY, int Z, int MaxY, cWorld * a_World)
+ int EvaluatePortalBorder(int X, int FoundObsidianY, int Z, int MaxY, cChunkInterface & a_ChunkInterface)
{
for (int checkBorder = FoundObsidianY + 1; checkBorder <= MaxY - 1; checkBorder++) // FoundObsidianY + 1: FoundObsidianY has already been checked in FindObsidianCeiling; MaxY - 1: portal doesn't need corners
{
- if (a_World->GetBlock(X, checkBorder, Z) != E_BLOCK_OBSIDIAN)
+ if (a_ChunkInterface.GetBlock(X, checkBorder, Z) != E_BLOCK_OBSIDIAN)
{
// Base obsidian, base + 1 obsidian, base + x NOT obsidian -> not complete portal
return 0;
@@ -112,9 +114,9 @@ public:
}
/// Finds entire frame in any direction with the coordinates of a base block and fills hole with nether portal (START HERE)
- void FindAndSetPortalFrame(int X, int Y, int Z, cWorld * a_World)
+ void FindAndSetPortalFrame(int X, int Y, int Z, cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface)
{
- int MaxY = FindObsidianCeiling(X, Y, Z, a_World); // Get topmost obsidian block as reference for all other checks
+ int MaxY = FindObsidianCeiling(X, Y, Z, a_ChunkInterface); // Get topmost obsidian block as reference for all other checks
int X1 = X + 1, Z1 = Z + 1, X2 = X - 1, Z2 = Z - 1; // Duplicate XZ values, add/subtract one as we've checked the original already the line above
if (MaxY == 0) // Oh noes! Not a portal coordinate :(
@@ -122,9 +124,9 @@ public:
return;
}
- if (!FindPortalSliceX(X1, X2, Y, Z, MaxY, a_World))
+ if (!FindPortalSliceX(X1, X2, Y, Z, MaxY, a_ChunkInterface))
{
- if (!FindPortalSliceZ(X, Y, Z1, Z2, MaxY, a_World))
+ if (!FindPortalSliceZ(X, Y, Z1, Z2, MaxY, a_ChunkInterface))
{
return; // No eligible portal construct, abort abort abort!!
}
@@ -136,11 +138,11 @@ public:
{
if (Dir == 1)
{
- a_World->SetBlock(Width, Height, Z, E_BLOCK_NETHER_PORTAL, Dir);
+ a_ChunkInterface.SetBlock(a_WorldInterface, Width, Height, Z, E_BLOCK_NETHER_PORTAL, Dir);
}
else
{
- a_World->SetBlock(X, Height, Width, E_BLOCK_NETHER_PORTAL, Dir);
+ a_ChunkInterface.SetBlock(a_WorldInterface, X, Height, Width, E_BLOCK_NETHER_PORTAL, Dir);
}
}
}
@@ -150,14 +152,14 @@ public:
/// Evaluates if coordinates are a portal going XP/XM; returns true if so, and writes boundaries to variable
/// Takes coordinates of base block and Y coord of target obsidian ceiling
- bool FindPortalSliceX(int X1, int X2, int Y, int Z, int MaxY, cWorld * a_World)
+ bool FindPortalSliceX(int X1, int X2, int Y, int Z, int MaxY, cChunkInterface & a_ChunkInterface)
{
Dir = 1; // Set assumed direction (will change if portal turns out to be facing the other direction)
bool FoundFrameXP = false, FoundFrameXM = false;
- for (; ((a_World->GetBlock(X1, Y, Z) == E_BLOCK_OBSIDIAN) || (a_World->GetBlock(X1, Y + 1, Z) == E_BLOCK_OBSIDIAN)); X1++) // Check XP for obsidian blocks, exempting corners
+ for (; ((a_ChunkInterface.GetBlock(X1, Y, Z) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock(X1, Y + 1, Z) == E_BLOCK_OBSIDIAN)); X1++) // Check XP for obsidian blocks, exempting corners
{
- int Value = FindObsidianCeiling(X1, Y, Z, a_World, MaxY);
- int ValueTwo = FindObsidianCeiling(X1, Y + 1, Z, a_World, MaxY); // For corners without obsidian
+ int Value = FindObsidianCeiling(X1, Y, Z, a_ChunkInterface, MaxY);
+ int ValueTwo = FindObsidianCeiling(X1, Y + 1, Z, a_ChunkInterface, MaxY); // For corners without obsidian
if ((Value == -1) || (ValueTwo == -1)) // FindObsidianCeiling returns -1 upon frame-find
{
FoundFrameXP = true; // Found a frame border in this direction, proceed in other direction (don't go further)
@@ -168,10 +170,10 @@ public:
return false; // Not valid slice, no portal can be formed
}
} XZP = X1 - 1; // Set boundary of frame interior, note that for some reason, the loop of X and the loop of Z go to different numbers, hence -1 here and -2 there
- for (; ((a_World->GetBlock(X2, Y, Z) == E_BLOCK_OBSIDIAN) || (a_World->GetBlock(X2, Y + 1, Z) == E_BLOCK_OBSIDIAN)); X2--) // Go the other direction (XM)
+ for (; ((a_ChunkInterface.GetBlock(X2, Y, Z) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock(X2, Y + 1, Z) == E_BLOCK_OBSIDIAN)); X2--) // Go the other direction (XM)
{
- int Value = FindObsidianCeiling(X2, Y, Z, a_World, MaxY);
- int ValueTwo = FindObsidianCeiling(X2, Y + 1, Z, a_World, MaxY);
+ int Value = FindObsidianCeiling(X2, Y, Z, a_ChunkInterface, MaxY);
+ int ValueTwo = FindObsidianCeiling(X2, Y + 1, Z, a_ChunkInterface, MaxY);
if ((Value == -1) || (ValueTwo == -1))
{
FoundFrameXM = true;
@@ -186,14 +188,14 @@ public:
}
/// Evaluates if coords are a portal going ZP/ZM; returns true if so, and writes boundaries to variable
- bool FindPortalSliceZ(int X, int Y, int Z1, int Z2, int MaxY, cWorld * a_World)
+ bool FindPortalSliceZ(int X, int Y, int Z1, int Z2, int MaxY, cChunkInterface & a_ChunkInterface)
{
Dir = 2;
bool FoundFrameZP = false, FoundFrameZM = false;
- for (; ((a_World->GetBlock(X, Y, Z1) == E_BLOCK_OBSIDIAN) || (a_World->GetBlock(X, Y + 1, Z1) == E_BLOCK_OBSIDIAN)); Z1++)
+ for (; ((a_ChunkInterface.GetBlock(X, Y, Z1) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock(X, Y + 1, Z1) == E_BLOCK_OBSIDIAN)); Z1++)
{
- int Value = FindObsidianCeiling(X, Y, Z1, a_World, MaxY);
- int ValueTwo = FindObsidianCeiling(X, Y + 1, Z1, a_World, MaxY);
+ int Value = FindObsidianCeiling(X, Y, Z1, a_ChunkInterface, MaxY);
+ int ValueTwo = FindObsidianCeiling(X, Y + 1, Z1, a_ChunkInterface, MaxY);
if ((Value == -1) || (ValueTwo == -1))
{
FoundFrameZP = true;
@@ -204,10 +206,10 @@ public:
return false;
}
} XZP = Z1 - 2;
- for (; ((a_World->GetBlock(X, Y, Z2) == E_BLOCK_OBSIDIAN) || (a_World->GetBlock(X, Y + 1, Z2) == E_BLOCK_OBSIDIAN)); Z2--)
+ for (; ((a_ChunkInterface.GetBlock(X, Y, Z2) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock(X, Y + 1, Z2) == E_BLOCK_OBSIDIAN)); Z2--)
{
- int Value = FindObsidianCeiling(X, Y, Z2, a_World, MaxY);
- int ValueTwo = FindObsidianCeiling(X, Y + 1, Z2, a_World, MaxY);
+ int Value = FindObsidianCeiling(X, Y, Z2, a_ChunkInterface, MaxY);
+ int ValueTwo = FindObsidianCeiling(X, Y + 1, Z2, a_ChunkInterface, MaxY);
if ((Value == -1) || (ValueTwo == -1))
{
FoundFrameZM = true;
diff --git a/src/Blocks/BlockFlower.h b/src/Blocks/BlockFlower.h
index 421e2d5d8..e8fd4c7f6 100644
--- a/src/Blocks/BlockFlower.h
+++ b/src/Blocks/BlockFlower.h
@@ -24,7 +24,7 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
return (a_RelY > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ));
}
diff --git a/src/Blocks/BlockFlowerPot.h b/src/Blocks/BlockFlowerPot.h
index b0faf5218..fc75ef638 100644
--- a/src/Blocks/BlockFlowerPot.h
+++ b/src/Blocks/BlockFlowerPot.h
@@ -2,101 +2,24 @@
#pragma once
#include "BlockHandler.h"
+#include "BlockEntity.h"
class cBlockFlowerPotHandler :
- public cBlockHandler
+ public cBlockEntityHandler
{
public:
cBlockFlowerPotHandler(BLOCKTYPE a_BlockType) :
- cBlockHandler(a_BlockType)
+ cBlockEntityHandler(a_BlockType)
{
}
-
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
a_Pickups.push_back(cItem(E_ITEM_FLOWER_POT, 1, 0));
- if (a_BlockMeta == 0)
- {
- return;
- }
- cItem Plant;
- switch (a_BlockMeta)
- {
- case 1: Plant = cItem(E_BLOCK_RED_ROSE, 1, 0); break;
- case 2: Plant = cItem(E_BLOCK_YELLOW_FLOWER, 1, 0); break;
- case 3: Plant = cItem(E_BLOCK_SAPLING, 1, E_META_SAPLING_APPLE); break;
- case 4: Plant = cItem(E_BLOCK_SAPLING, 1, E_META_SAPLING_CONIFER); break;
- case 5: Plant = cItem(E_BLOCK_SAPLING, 1, E_META_SAPLING_BIRCH); break;
- case 6: Plant = cItem(E_BLOCK_SAPLING, 1, E_META_SAPLING_JUNGLE); break;
- case 7: Plant = cItem(E_BLOCK_RED_MUSHROOM, 1, 0); break;
- case 8: Plant = cItem(E_BLOCK_BROWN_MUSHROOM, 1, 0); break;
- case 9: Plant = cItem(E_BLOCK_CACTUS, 1, 0); break;
- case 10: Plant = cItem(E_BLOCK_DEAD_BUSH, 1, 0); break;
- case 11: Plant = cItem(E_BLOCK_TALL_GRASS, 1, E_META_TALL_GRASS_FERN); break;
- default: return;
- }
- a_Pickups.push_back(Plant);
- }
-
-
- void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
- {
- NIBBLETYPE Meta = a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ );
- if (Meta != 0)
- {
- // Already filled
- return;
- }
-
- switch (a_Player->GetEquippedItem().m_ItemType)
- {
- case E_BLOCK_RED_ROSE: Meta = 1; break;
- case E_BLOCK_YELLOW_FLOWER: Meta = 2; break;
- case E_BLOCK_SAPLING:
- {
- switch (a_Player->GetEquippedItem().m_ItemDamage)
- {
- case E_META_SAPLING_APPLE: Meta = 3; break;
- case E_META_SAPLING_CONIFER: Meta = 4; break;
- case E_META_SAPLING_BIRCH: Meta = 5; break;
- case E_META_SAPLING_JUNGLE: Meta = 6; break;
- }
- break;
- }
- case E_BLOCK_RED_MUSHROOM: Meta = 7; break;
- case E_BLOCK_BROWN_MUSHROOM: Meta = 8; break;
- case E_BLOCK_CACTUS: Meta = 9; break;
- case E_BLOCK_DEAD_BUSH: Meta = 10; break;
- case E_BLOCK_TALL_GRASS:
- {
- if (a_Player->GetEquippedItem().m_ItemDamage == E_META_TALL_GRASS_FERN)
- {
- Meta = 11;
- }
- else
- {
- return;
- }
- break;
- }
- }
-
- if (a_Player->GetGameMode() != gmCreative)
- {
- a_Player->GetInventory().RemoveOneEquippedItem();
- }
- a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
- }
-
-
- virtual bool IsUseable(void) override
- {
- return true;
}
} ;
diff --git a/src/Blocks/BlockFluid.h b/src/Blocks/BlockFluid.h
index bce5064bc..d486d642d 100644
--- a/src/Blocks/BlockFluid.h
+++ b/src/Blocks/BlockFluid.h
@@ -32,7 +32,7 @@ public:
}
- virtual void Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) override
+ virtual void Check(cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface, int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) override
{
switch (m_BlockType)
{
@@ -47,7 +47,7 @@ public:
break;
}
}
- super::Check(a_RelX, a_RelY, a_RelZ, a_Chunk);
+ super::Check(a_ChunkInterface, a_PluginInterface, a_RelX, a_RelY, a_RelZ, a_Chunk);
}
} ;
@@ -68,7 +68,7 @@ public:
/// Called to tick the block
- virtual void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
+ virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
if (a_Chunk.GetWorld()->ShouldLavaSpawnFire())
{
@@ -93,6 +93,7 @@ public:
// Check if it's fuel:
BLOCKTYPE BlockType;
if (
+ ((a_RelY + y < 0) || (a_RelY + y > cChunkDef::Height)) ||
!a_Chunk.UnboundedRelGetBlockType(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType) ||
!cFireSimulator::IsFuel(BlockType)
)
@@ -119,6 +120,7 @@ public:
for (size_t i = 0; i < ARRAYCOUNT(CrossCoords); i++)
{
if (
+ ((RelY + CrossCoords[i].y >= 0) && (RelY + CrossCoords[i].y <= cChunkDef::Height)) &&
a_Chunk.UnboundedRelGetBlockType(RelX + CrossCoords[i].x, RelY + CrossCoords[i].y, RelZ + CrossCoords[i].z, BlockType) &&
(BlockType == E_BLOCK_AIR)
)
diff --git a/src/Blocks/BlockFurnace.h b/src/Blocks/BlockFurnace.h
index 693eac331..a7a807957 100644
--- a/src/Blocks/BlockFurnace.h
+++ b/src/Blocks/BlockFurnace.h
@@ -4,17 +4,17 @@
#include "BlockEntity.h"
#include "../World.h"
#include "../Piston.h"
-
+#include "MetaRotator.h"
class cBlockFurnaceHandler :
- public cBlockEntityHandler
+ public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
{
public:
- cBlockFurnaceHandler(BLOCKTYPE a_BlockType) :
- cBlockEntityHandler(a_BlockType)
+ cBlockFurnaceHandler(BLOCKTYPE a_BlockType)
+ : cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
{
}
@@ -26,8 +26,8 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index 8d09b5559..a764c6f44 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -5,10 +5,14 @@
#include "../World.h"
#include "../Root.h"
#include "../Bindings/PluginManager.h"
+#include "../Chunk.h"
+#include "BlockAnvil.h"
#include "BlockBed.h"
+#include "BlockBigFlower.h"
#include "BlockBrewingStand.h"
#include "BlockButton.h"
#include "BlockCactus.h"
+#include "BlockCake.h"
#include "BlockCarpet.h"
#include "BlockCauldron.h"
#include "BlockChest.h"
@@ -34,10 +38,13 @@
#include "BlockGlass.h"
#include "BlockGlowstone.h"
#include "BlockGravel.h"
+#include "BlockMobHead.h"
#include "BlockHopper.h"
#include "BlockIce.h"
#include "BlockLadder.h"
#include "BlockLeaves.h"
+#include "BlockLilypad.h"
+#include "BlockNewLeaves.h"
#include "BlockLever.h"
#include "BlockMelon.h"
#include "BlockMushroom.h"
@@ -49,13 +56,16 @@
#include "BlockPlanks.h"
#include "BlockPortal.h"
#include "BlockPumpkin.h"
+#include "BlockQuartz.h"
#include "BlockRail.h"
#include "BlockRedstone.h"
#include "BlockRedstoneLamp.h"
#include "BlockRedstoneRepeater.h"
#include "BlockRedstoneTorch.h"
+#include "BlockTNT.h"
#include "BlockSand.h"
#include "BlockSapling.h"
+#include "BlockSideways.h"
#include "BlockSign.h"
#include "BlockSlab.h"
#include "BlockSnow.h"
@@ -67,52 +77,28 @@
#include "BlockTorch.h"
#include "BlockTrapdoor.h"
#include "BlockVine.h"
-#include "BlockWood.h"
#include "BlockWorkbench.h"
-bool cBlockHandler::m_HandlerInitialized = false;
-cBlockHandler * cBlockHandler::m_BlockHandler[256];
-
-
-
-
-
-cBlockHandler * cBlockHandler::GetBlockHandler(BLOCKTYPE a_BlockType)
-{
- if (!m_HandlerInitialized)
- {
- // We have to initialize
- memset(m_BlockHandler, 0, sizeof(m_BlockHandler));
- m_HandlerInitialized = true;
- }
- if (m_BlockHandler[a_BlockType] != NULL)
- {
- return m_BlockHandler[a_BlockType];
- }
-
- return m_BlockHandler[a_BlockType] = CreateBlockHandler(a_BlockType);
-}
-
-
-
-
-
cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
{
switch(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_BIG_FLOWER: return new cBlockBigFlowerHandler (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);
@@ -124,6 +110,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_COBBLESTONE_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_COBWEB: return new cBlockCobWebHandler (a_BlockType);
case E_BLOCK_CROPS: return new cBlockCropsHandler (a_BlockType);
+ case E_BLOCK_DARK_OAK_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_DEAD_BUSH: return new cBlockDeadBushHandler (a_BlockType);
case E_BLOCK_DETECTOR_RAIL: return new cBlockRailHandler (a_BlockType);
case E_BLOCK_DIAMOND_ORE: return new cBlockOreHandler (a_BlockType);
@@ -145,6 +132,8 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_GLASS: return new cBlockGlassHandler (a_BlockType);
case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType);
case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType);
+ case E_BLOCK_HAY_BALE: return new cBlockSidewaysHandler (a_BlockType);
+ case E_BLOCK_HEAD: return new cBlockMobHeadHandler (a_BlockType);
case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType);
case E_BLOCK_ICE: return new cBlockIceHandler (a_BlockType);
case E_BLOCK_INACTIVE_COMPARATOR: return new cBlockComparatorHandler (a_BlockType);
@@ -158,14 +147,18 @@ 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 cBlockWoodHandler (a_BlockType);
+ case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType);
case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType);
case E_BLOCK_MELON_STEM: return new cBlockStemsHandler (a_BlockType);
case E_BLOCK_MYCELIUM: return new cBlockMyceliumHandler (a_BlockType);
case E_BLOCK_NETHER_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_NETHER_PORTAL: return new cBlockPortalHandler (a_BlockType);
case E_BLOCK_NETHER_WART: return new cBlockNetherWartHandler (a_BlockType);
+ case E_BLOCK_NETHER_QUARTZ_ORE: return new cBlockOreHandler (a_BlockType);
+ case E_BLOCK_NEW_LEAVES: return new cBlockNewLeavesHandler (a_BlockType);
+ case E_BLOCK_NEW_LOG: return new cBlockSidewaysHandler (a_BlockType);
case E_BLOCK_NOTE_BLOCK: return new cBlockNoteHandler (a_BlockType);
case E_BLOCK_PISTON: return new cBlockPistonHandler (a_BlockType);
case E_BLOCK_PISTON_EXTENSION: return new cBlockPistonHeadHandler ( );
@@ -174,6 +167,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_POWERED_RAIL: return new cBlockRailHandler (a_BlockType);
case E_BLOCK_PUMPKIN: return new cBlockPumpkinHandler (a_BlockType);
case E_BLOCK_PUMPKIN_STEM: return new cBlockStemsHandler (a_BlockType);
+ case E_BLOCK_QUARTZ_BLOCK: return new cBlockQuartzHandler (a_BlockType);
case E_BLOCK_QUARTZ_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_RAIL: return new cBlockRailHandler (a_BlockType);
case E_BLOCK_REDSTONE_LAMP_ON: return new cBlockRedstoneLampHandler (a_BlockType); // We need this to change pickups to an off lamp; else 1.7+ clients crash
@@ -183,7 +177,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_REDSTONE_REPEATER_ON: return new cBlockRedstoneRepeaterHandler(a_BlockType);
case E_BLOCK_REDSTONE_TORCH_OFF: return new cBlockRedstoneTorchHandler (a_BlockType);
case E_BLOCK_REDSTONE_TORCH_ON: return new cBlockRedstoneTorchHandler (a_BlockType);
- case E_BLOCK_REDSTONE_WIRE: return new cBlockRedstoneHandler (a_BlockType);
+ case E_BLOCK_REDSTONE_WIRE: return new cBlockRedstoneHandler (a_BlockType);
case E_BLOCK_RED_MUSHROOM: return new cBlockMushroomHandler (a_BlockType);
case E_BLOCK_RED_ROSE: return new cBlockFlowerHandler (a_BlockType);
case E_BLOCK_SAND: return new cBlockSandHandler (a_BlockType);
@@ -203,6 +197,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_TALL_GRASS: return new cBlockTallGrassHandler (a_BlockType);
case E_BLOCK_TORCH: return new cBlockTorchHandler (a_BlockType);
case E_BLOCK_TRAPDOOR: return new cBlockTrapdoorHandler (a_BlockType);
+ case E_BLOCK_TNT: return new cBlockTNTHandler (a_BlockType);
case E_BLOCK_VINES: return new cBlockVineHandler (a_BlockType);
case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType);
case E_BLOCK_WATER: return new cBlockFluidHandler (a_BlockType);
@@ -222,20 +217,6 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
-void cBlockHandler::Deinit()
-{
- for (int i = 0; i < 256; i++)
- {
- delete m_BlockHandler[i];
- }
- memset(m_BlockHandler, 0, sizeof(m_BlockHandler)); // Don't leave any dangling pointers around, just in case
- m_HandlerInitialized = false;
-}
-
-
-
-
-
cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockType)
{
m_BlockType = a_BlockType;
@@ -246,8 +227,8 @@ cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockType)
bool cBlockHandler::GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
)
@@ -262,7 +243,7 @@ bool cBlockHandler::GetPlacementBlockTypeMeta(
-void cBlockHandler::OnUpdate(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ)
+void cBlockHandler::OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ)
{
}
@@ -270,7 +251,7 @@ void cBlockHandler::OnUpdate(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a
-void cBlockHandler::OnPlacedByPlayer(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)
+void cBlockHandler::OnPlacedByPlayer(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, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
}
@@ -278,7 +259,7 @@ void cBlockHandler::OnPlacedByPlayer(cWorld * a_World, cPlayer * a_Player, int a
-void cBlockHandler::OnDestroyedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
+void cBlockHandler::OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
{
}
@@ -286,41 +267,41 @@ void cBlockHandler::OnDestroyedByPlayer(cWorld *a_World, cPlayer * a_Player, int
-void cBlockHandler::OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+void cBlockHandler::OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
// Notify the neighbors
- NeighborChanged(a_World, a_BlockX - 1, a_BlockY, a_BlockZ);
- NeighborChanged(a_World, a_BlockX + 1, a_BlockY, a_BlockZ);
- NeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ);
- NeighborChanged(a_World, a_BlockX, a_BlockY + 1, a_BlockZ);
- NeighborChanged(a_World, a_BlockX, a_BlockY, a_BlockZ - 1);
- NeighborChanged(a_World, a_BlockX, a_BlockY, a_BlockZ + 1);
+ NeighborChanged(a_ChunkInterface, a_BlockX - 1, a_BlockY, a_BlockZ);
+ NeighborChanged(a_ChunkInterface, a_BlockX + 1, a_BlockY, a_BlockZ);
+ NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ);
+ NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ);
+ NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ - 1);
+ NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ + 1);
}
-void cBlockHandler::OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+void cBlockHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Notify the neighbors
- NeighborChanged(a_World, a_BlockX - 1, a_BlockY, a_BlockZ);
- NeighborChanged(a_World, a_BlockX + 1, a_BlockY, a_BlockZ);
- NeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ);
- NeighborChanged(a_World, a_BlockX, a_BlockY + 1, a_BlockZ);
- NeighborChanged(a_World, a_BlockX, a_BlockY, a_BlockZ - 1);
- NeighborChanged(a_World, a_BlockX, a_BlockY, a_BlockZ + 1);
+ NeighborChanged(a_ChunkInterface, a_BlockX - 1, a_BlockY, a_BlockZ);
+ NeighborChanged(a_ChunkInterface, a_BlockX + 1, a_BlockY, a_BlockZ);
+ NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ);
+ NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ);
+ NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ - 1);
+ NeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ + 1);
}
-void cBlockHandler::NeighborChanged(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+void cBlockHandler::NeighborChanged(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
if ((a_BlockY >= 0) && (a_BlockY < cChunkDef::Height))
{
- GetBlockHandler(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnNeighborChanged(a_World, a_BlockX, a_BlockY, a_BlockZ);
+ cBlockInfo::GetHandler(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnNeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
}
}
@@ -328,7 +309,15 @@ void cBlockHandler::NeighborChanged(cWorld *a_World, int a_BlockX, int a_BlockY,
-void cBlockHandler::OnNeighborChanged(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+void cBlockHandler::OnNeighborChanged(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
+{
+}
+
+
+
+
+
+void cBlockHandler::OnDigging(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
{
}
@@ -336,7 +325,7 @@ void cBlockHandler::OnNeighborChanged(cWorld *a_World, int a_BlockX, int a_Block
-void cBlockHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
+void cBlockHandler::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)
{
}
@@ -344,7 +333,7 @@ void cBlockHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_BlockX,
-void cBlockHandler::OnUse(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)
+void cBlockHandler::OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace)
{
}
@@ -362,14 +351,14 @@ void cBlockHandler::ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta)
-void cBlockHandler::DropBlock(cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ)
+void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ)
{
cItems Pickups;
- NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
ConvertToPickups(Pickups, Meta);
// Allow plugins to modify the pickups:
- cRoot::Get()->GetPluginManager()->CallHookBlockToPickups(a_World, a_Digger, a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta, Pickups);
+ a_BlockPluginInterface.CallHookBlockToPickups(a_Digger, a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta, Pickups);
if (!Pickups.empty())
{
@@ -385,7 +374,7 @@ void cBlockHandler::DropBlock(cWorld * a_World, cEntity * a_Digger, int a_BlockX
MicroX += r1.rand(1) - 0.5;
MicroZ += r1.rand(1) - 0.5;
- a_World->SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ);
+ a_WorldInterface.SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ);
}
}
@@ -402,7 +391,7 @@ const char * cBlockHandler::GetStepSound()
-bool cBlockHandler::CanBeAt(int a_BlockX, int a_BlockY, int a_BlockZ, const cChunk & a_Chunk)
+bool cBlockHandler::CanBeAt(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, const cChunk & a_Chunk)
{
return true;
}
@@ -447,15 +436,15 @@ bool cBlockHandler::DoesDropOnUnsuitable(void)
-void cBlockHandler::Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk)
+void cBlockHandler::Check(cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface, int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk)
{
- if (!CanBeAt(a_RelX, a_RelY, a_RelZ, a_Chunk))
+ if (!CanBeAt(a_ChunkInterface, a_RelX, a_RelY, a_RelZ, a_Chunk))
{
if (DoesDropOnUnsuitable())
{
int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
- DropBlock(a_Chunk.GetWorld(), NULL, BlockX, a_RelY, BlockZ);
+ DropBlock(a_ChunkInterface, *a_Chunk.GetWorld(), a_PluginInterface, NULL, BlockX, a_RelY, BlockZ);
}
a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0);
diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h
index a732aa797..3a3efb3cc 100644
--- a/src/Blocks/BlockHandler.h
+++ b/src/Blocks/BlockHandler.h
@@ -3,15 +3,17 @@
#include "../Defines.h"
#include "../Item.h"
-#include "../Chunk.h"
+#include "WorldInterface.h"
+#include "ChunkInterface.h"
+#include "BlockPluginInterface.h"
// fwd:
-class cWorld;
class cPlayer;
+class cChunk;
@@ -21,10 +23,12 @@ class cBlockHandler
{
public:
cBlockHandler(BLOCKTYPE a_BlockType);
+
+ virtual ~cBlockHandler() {}
/// Called when the block gets ticked either by a random tick or by a queued tick.
/// Note that the coords are chunk-relative!
- virtual void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ);
+ virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ);
/** Called before a block is placed into a world.
The handler should return true to allow placement, false to refuse.
@@ -32,52 +36,55 @@ public:
Called by cItemHandler::GetPlacementBlockTypeMeta() if the item is a block
*/
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
);
/// Called by cWorld::SetBlock() after the block has been set
- virtual void OnPlaced(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
+ virtual void OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
/// Called by cClientHandle::HandlePlaceBlock() after the player has placed a new block. Called after OnPlaced().
virtual void OnPlacedByPlayer(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
);
/// Called before the player has destroyed a block
- virtual void OnDestroyedByPlayer(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ);
+ virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ);
/// Called before a block gets destroyed / replaced with air
- virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ);
+ virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ);
/// Called when a direct neighbor of this block has been changed (The position is the own position, not the neighbor position)
- virtual void OnNeighborChanged(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ);
+ virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ);
/// Notifies all neighbors of the given block about a change
- static void NeighborChanged(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ);
+ static void NeighborChanged(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ);
/// Called while the player diggs the block.
- virtual void OnDigging(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ);
+ virtual void OnDigging(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ);
/// Called if the user right clicks the block and the block is useable
- virtual void OnUse(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);
+ 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);
+
+ /** Called when a Right Click to this Block is cancelled */
+ virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace);
/// <summary>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</summary>
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta);
/// Handles the dropping of a block based on what ConvertToDrops() returns. This will not destroy the block. a_Digger is the entity causing the drop; it may be NULL
- virtual void DropBlock(cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ);
+ virtual void DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ);
/// Returns step sound name of block
virtual const char * GetStepSound(void);
/// Checks if the block can stay at the specified relative coords in the chunk
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk);
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk);
/** Checks if the block can be placed at this point.
Default: CanBeAt(...)
@@ -112,7 +119,7 @@ public:
By default drops if position no more suitable (CanBeAt(), DoesDropOnUnsuitable(), Drop()),
and wakes up all simulators on the block.
*/
- virtual void Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk);
+ virtual void Check(cChunkInterface & ChunkInterface, cBlockPluginInterface & a_PluginInterface, int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk);
/// <summary>Rotates a given block meta counter-clockwise. Default: no change</summary>
/// <returns>Block meta following rotation</returns>
@@ -134,30 +141,14 @@ public:
/// <returns>Block meta following mirroring</returns>
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) { return a_Meta; }
- /// <summary>Get the blockhandler for a specific block id</summary>
- static cBlockHandler * GetBlockHandler(BLOCKTYPE a_BlockType);
-
- /// <summary>Deletes all initialised block handlers</summary>
- static void Deinit();
-
protected:
BLOCKTYPE m_BlockType;
// Creates a new blockhandler for the given block type. For internal use only, use ::GetBlockHandler() instead.
- static cBlockHandler *CreateBlockHandler(BLOCKTYPE a_BlockType);
- static cBlockHandler *m_BlockHandler[256];
- static bool m_HandlerInitialized; //used to detect if the blockhandlers are initialized
-};
-
+ static cBlockHandler * CreateBlockHandler(BLOCKTYPE a_BlockType);
-
-
-
-// Shortcut to get the blockhandler for a specific block
-inline cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType)
-{
- return cBlockHandler::GetBlockHandler(a_BlockType);
-}
+ friend class cBlockInfo;
+};
diff --git a/src/Blocks/BlockHopper.h b/src/Blocks/BlockHopper.h
index 3998276d7..a882bb077 100644
--- a/src/Blocks/BlockHopper.h
+++ b/src/Blocks/BlockHopper.h
@@ -3,23 +3,23 @@
// Declares the cBlockHopperHandler class representing the handler for the Hopper block
-
+#include "MetaRotator.h"
class cBlockHopperHandler :
- public cBlockEntityHandler
+ public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
{
public:
cBlockHopperHandler(BLOCKTYPE a_BlockType)
- : cBlockEntityHandler(a_BlockType)
+ : cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
{
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
@@ -39,6 +39,21 @@ public:
}
return true;
}
+
+
+ virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
+ {
+ // Bit 0x08 is a flag. Lowest three bits are position. 0x08 == 1000
+ NIBBLETYPE OtherMeta = a_Meta & 0x08;
+ // Mirrors defined by by a table. (Source, mincraft.gamepedia.com) 0x07 == 0111
+ switch (a_Meta & 0x07)
+ {
+ case 0x00: return 0x01 + OtherMeta; // Down -> Up
+ case 0x01: return 0x00 + OtherMeta; // Up -> Down
+ }
+ // Not Facing Up or Down; No change.
+ return a_Meta;
+ }
} ;
diff --git a/src/Blocks/BlockIce.h b/src/Blocks/BlockIce.h
index af4961114..8dfe7ddac 100644
--- a/src/Blocks/BlockIce.h
+++ b/src/Blocks/BlockIce.h
@@ -24,10 +24,10 @@ public:
}
- virtual void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override
{
// TODO: Ice destroyed with air below it should turn into air instead of water
- a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_WATER, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_WATER, 0);
// This is called later than the real destroying of this ice block
}
} ;
diff --git a/src/Blocks/BlockLadder.h b/src/Blocks/BlockLadder.h
index c0aa25f60..a605edf3f 100644
--- a/src/Blocks/BlockLadder.h
+++ b/src/Blocks/BlockLadder.h
@@ -9,25 +9,25 @@
class cBlockLadderHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
{
public:
cBlockLadderHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
{
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
{
- if (!LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace))
+ if (!LadderCanBePlacedAt(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace))
{
- a_BlockFace = FindSuitableBlockFace(a_World, a_BlockX, a_BlockY, a_BlockZ);
+ a_BlockFace = FindSuitableBlockFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
if (a_BlockFace == BLOCK_FACE_BOTTOM)
{
@@ -41,38 +41,39 @@ public:
}
- static NIBBLETYPE DirectionToMetaData(char a_Direction) // tolua_export
+ static NIBBLETYPE DirectionToMetaData(eBlockFace a_Direction) // tolua_export
{ // tolua_export
switch (a_Direction)
{
- case 0x2: return 0x2;
- case 0x3: return 0x3;
- case 0x4: return 0x4;
- case 0x5: return 0x5;
+ case BLOCK_FACE_ZM: return 0x2;
+ case BLOCK_FACE_ZP: return 0x3;
+ case BLOCK_FACE_XM: return 0x4;
+ case BLOCK_FACE_XP: return 0x5;
default: return 0x2;
}
} // tolua_export
- static char MetaDataToDirection(NIBBLETYPE a_MetaData) // tolua_export
+ static eBlockFace MetaDataToDirection(NIBBLETYPE a_MetaData) // tolua_export
{ // tolua_export
switch (a_MetaData)
{
- case 0x2: return 0x2;
- case 0x3: return 0x3;
- case 0x4: return 0x4;
- case 0x5: return 0x5;
- default: return 0x2;
+ case 0x2: return BLOCK_FACE_ZM;
+ case 0x3: return BLOCK_FACE_ZP;
+ case 0x4: return BLOCK_FACE_XM;
+ case 0x5: return BLOCK_FACE_XP;
+ default: return BLOCK_FACE_ZM;
}
} // tolua_export
/// Finds a suitable Direction for the Ladder. Returns BLOCK_FACE_BOTTOM on failure
- static char FindSuitableBlockFace(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+ static eBlockFace FindSuitableBlockFace(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
- for (int Face = 2; Face <= 5; Face++)
+ for (int FaceInt = BLOCK_FACE_ZM; FaceInt <= BLOCK_FACE_XP; FaceInt++)
{
- if (LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Face))
+ eBlockFace Face = static_cast<eBlockFace>(FaceInt);
+ if (LadderCanBePlacedAt(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, Face))
{
return Face;
}
@@ -81,7 +82,7 @@ public:
}
- static bool LadderCanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace)
+ static bool LadderCanBePlacedAt(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace)
{
if ((a_BlockFace == BLOCK_FACE_BOTTOM) || (a_BlockFace == BLOCK_FACE_TOP))
{
@@ -90,17 +91,17 @@ public:
AddFaceDirection( a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true);
- return g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ)];
+ return cBlockInfo::IsSolid(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ));
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface,int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
// TODO: Use AdjustCoordsByMeta(), then cChunk::UnboundedRelGetBlock() and finally some comparison
- char BlockFace = MetaDataToDirection(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
+ eBlockFace BlockFace = MetaDataToDirection(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
- return LadderCanBePlacedAt(a_Chunk.GetWorld(), BlockX, a_RelY, BlockZ, BlockFace);
+ return LadderCanBePlacedAt(a_ChunkInterface, BlockX, a_RelY, BlockZ, BlockFace);
}
diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h
index 539d12a49..8af14686e 100644
--- a/src/Blocks/BlockLeaves.h
+++ b/src/Blocks/BlockLeaves.h
@@ -1,6 +1,6 @@
#pragma once
#include "BlockHandler.h"
-#include "../MersenneTwister.h"
+#include "../FastRandom.h"
#include "../World.h"
#include "../BlockArea.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);
@@ -36,16 +37,18 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
- MTRand rand;
+ cFastRandom rand;
// Only the first 2 bits contain the display information, the others are for growing
- if (rand.randInt(5) == 0)
+ if (rand.NextInt(6) == 0)
{
a_Pickups.push_back(cItem(E_BLOCK_SAPLING, 1, a_BlockMeta & 3));
}
- if ((a_BlockMeta & 3) == E_META_SAPLING_APPLE)
+
+ // 1 % chance of dropping an apple, if the leaves' type is Apple Leaves
+ if ((a_BlockMeta & 3) == E_META_LEAVES_APPLE)
{
- if (rand.rand(100) == 0)
+ if (rand.NextInt(101) == 0)
{
a_Pickups.push_back(cItem(E_ITEM_RED_APPLE, 1, 0));
}
@@ -53,31 +56,30 @@ public:
}
- void OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override
{
- cBlockHandler::OnDestroyed(a_World, a_BlockX, a_BlockY, a_BlockZ);
+ cBlockHandler::OnDestroyed(a_ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ);
- //0.5% chance of dropping an apple
- NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
- //check if Oak (0x1 and 0x2 bit not set)
- MTRand rand;
- if(!(Meta & 3) && rand.randInt(200) == 100)
+ // 0.5% chance of dropping an apple, if the leaves' type is Apple Leaves:
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ cFastRandom rand;
+ if (((Meta & 3) == E_META_LEAVES_APPLE) && (rand.NextInt(201) == 100))
{
cItems Drops;
Drops.push_back(cItem(E_ITEM_RED_APPLE, 1, 0));
- a_World->SpawnItemPickups(Drops, a_BlockX, a_BlockY, a_BlockZ);
+ a_WorldInterface.SpawnItemPickups(Drops, a_BlockX, a_BlockY, a_BlockZ);
}
}
- virtual void OnNeighborChanged(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override
{
- NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
- a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0x7); // Unset 0x8 bit so it gets checked for decay
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0x7); // Unset 0x8 bit so it gets checked for decay
}
- void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
+ virtual void OnUpdate(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
if ((Meta & 0x04) != 0)
@@ -116,8 +118,8 @@ public:
}
// Decay the leaves:
- DropBlock(a_Chunk.GetWorld(), NULL, BlockX, a_RelY, BlockZ);
- a_Chunk.GetWorld()->DigBlock(BlockX, a_RelY, BlockZ);
+ DropBlock(a_ChunkInterface, a_WorldInterface, a_PluginInterface, NULL, BlockX, a_RelY, BlockZ);
+ a_ChunkInterface.DigBlock(a_WorldInterface, BlockX, a_RelY, BlockZ);
}
@@ -139,6 +141,8 @@ bool HasNearLog(cBlockArea & a_Area, int a_BlockX, int a_BlockY, int a_BlockZ)
{
switch (Types[i])
{
+ case E_BLOCK_NEW_LEAVES:
+ case E_BLOCK_NEW_LOG:
case E_BLOCK_LEAVES:
case E_BLOCK_LOG:
{
diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h
index 5b0c89127..ad2ae29e5 100644
--- a/src/Blocks/BlockLever.h
+++ b/src/Blocks/BlockLever.h
@@ -1,27 +1,28 @@
#pragma once
#include "BlockHandler.h"
-
+#include "MetaRotator.h"
class cBlockLeverHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false>
{
+ typedef cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false> super;
public:
cBlockLeverHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false>(a_BlockType)
{
}
- virtual void OnUse(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) override
+ 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
{
// Flip the ON bit on/off using the XOR bitwise operation
- NIBBLETYPE Meta = (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08);
+ NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08);
- a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LEVER, Meta); // SetMeta doesn't work for unpowering levers, so setblock
- a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
+ a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LEVER, Meta); // SetMeta doesn't work for unpowering levers, so setblock
+ a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
}
@@ -39,8 +40,8 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
@@ -51,7 +52,7 @@ public:
}
- inline static NIBBLETYPE LeverDirectionToMetaData(char a_Dir)
+ inline static NIBBLETYPE LeverDirectionToMetaData(eBlockFace a_Dir)
{
// Determine lever direction:
switch (a_Dir)
@@ -73,7 +74,7 @@ public:
}
- inline static NIBBLETYPE BlockMetaDataToBlockFace(NIBBLETYPE a_Meta)
+ inline static eBlockFace BlockMetaDataToBlockFace(NIBBLETYPE a_Meta)
{
switch (a_Meta & 0x7)
{
@@ -94,7 +95,7 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
NIBBLETYPE Meta;
a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta);
@@ -102,7 +103,37 @@ public:
AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true);
BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
- return (a_RelY > 0) && (g_BlockIsSolid[BlockIsOn]);
+ return (a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn);
+ }
+
+
+ virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
+ {
+ switch (a_Meta)
+ {
+ case 0x00: return 0x07; // Ceiling rotation
+ case 0x07: return 0x00;
+
+ case 0x05: return 0x06; // Ground rotation
+ case 0x06: return 0x05;
+
+ default: return super::MetaRotateCCW(a_Meta); // Wall Rotation
+ }
+ }
+
+
+ virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
+ {
+ switch (a_Meta)
+ {
+ case 0x00: return 0x07; // Ceiling rotation
+ case 0x07: return 0x00;
+
+ case 0x05: return 0x06; // Ground rotation
+ case 0x06: return 0x05;
+
+ default: return super::MetaRotateCCW(a_Meta); // Wall Rotation
+ }
}
} ;
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
new file mode 100644
index 000000000..acd1c88fb
--- /dev/null
+++ b/src/Blocks/BlockMobHead.h
@@ -0,0 +1,186 @@
+
+#pragma once
+
+#include "BlockEntity.h"
+#include "../BlockEntities/MobHeadEntity.h"
+
+
+
+
+
+class cBlockMobHeadHandler :
+ public cBlockEntityHandler
+{
+public:
+ cBlockMobHeadHandler(BLOCKTYPE a_BlockType)
+ : cBlockEntityHandler(a_BlockType)
+ {
+ }
+
+ virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
+ {
+ a_Pickups.push_back(cItem(E_ITEM_HEAD, 1, 0));
+ }
+
+ bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+ {
+ if (a_BlockY < 2)
+ {
+ return false;
+ }
+
+ class cCallback : public cMobHeadCallback
+ {
+ bool m_IsWither;
+
+ virtual bool Item (cMobHeadEntity * a_MobHeadEntity)
+ {
+ m_IsWither = (a_MobHeadEntity->GetType() == SKULL_TYPE_WITHER);
+
+ return false;
+ }
+
+ public:
+ cCallback () : m_IsWither(false) {}
+
+ bool IsWither(void) const { return m_IsWither; }
+
+ void Reset(void) { m_IsWither = false; }
+ } CallbackA, CallbackB;
+
+ a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA);
+
+ if (!CallbackA.IsWither())
+ {
+ return false;
+ }
+
+ CallbackA.Reset();
+
+ BLOCKTYPE BlockY1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ);
+ BLOCKTYPE BlockY2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 2, a_BlockZ);
+
+ if ((BlockY1 != E_BLOCK_SOULSAND) || (BlockY2 != E_BLOCK_SOULSAND))
+ {
+ return false;
+ }
+
+ a_World->DoWithMobHeadAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA);
+ a_World->DoWithMobHeadAt(a_BlockX + 1, a_BlockY, a_BlockZ, CallbackB);
+
+ BLOCKTYPE Block1 = a_ChunkInterface.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ);
+ BLOCKTYPE Block2 = a_ChunkInterface.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ);
+
+ if ((Block1 == E_BLOCK_SOULSAND) && (Block2 == E_BLOCK_SOULSAND) && CallbackA.IsWither() && CallbackB.IsWither())
+ {
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
+
+ // Block entities
+ a_World->SetBlock(a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ a_World->SetBlock(a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+
+ // Spawn the wither:
+ a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
+
+ return true;
+ }
+
+ CallbackA.Reset();
+ CallbackB.Reset();
+
+ a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA);
+ a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB);
+
+ Block1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1);
+ Block2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1);
+
+ if ((Block1 == E_BLOCK_SOULSAND) && (Block2 == E_BLOCK_SOULSAND) && CallbackA.IsWither() && CallbackB.IsWither())
+ {
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
+
+ // Block entities
+ a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0);
+ a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
+
+ // Spawn the wither:
+ a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ virtual void OnPlacedByPlayer(
+ 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,
+ BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
+ ) override
+ {
+ class cCallback : public cMobHeadCallback
+ {
+ cPlayer * m_Player;
+ NIBBLETYPE m_OldBlockMeta;
+ NIBBLETYPE m_NewBlockMeta;
+
+ virtual bool Item (cMobHeadEntity * a_MobHeadEntity)
+ {
+ int Rotation = 0;
+ if (m_NewBlockMeta == 1)
+ {
+ Rotation = (int) floor(m_Player->GetYaw() * 16.0F / 360.0F + 0.5) & 0xF;
+ }
+
+ a_MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta));
+ a_MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation));
+ a_MobHeadEntity->GetWorld()->BroadcastBlockEntity(a_MobHeadEntity->GetPosX(), a_MobHeadEntity->GetPosY(), a_MobHeadEntity->GetPosZ(), m_Player->GetClientHandle());
+ return false;
+ }
+
+ public:
+ cCallback (cPlayer * a_CBPlayer, NIBBLETYPE a_OldBlockMeta, NIBBLETYPE a_NewBlockMeta) :
+ m_Player(a_CBPlayer),
+ m_OldBlockMeta(a_OldBlockMeta),
+ m_NewBlockMeta(a_NewBlockMeta)
+ {}
+ };
+ cCallback Callback(a_Player, a_BlockMeta, static_cast<NIBBLETYPE>(a_BlockFace));
+
+ a_BlockMeta = (NIBBLETYPE)a_BlockFace;
+ 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);
+
+ if (a_BlockMeta == SKULL_TYPE_WITHER)
+ {
+ static const Vector3i Coords[] =
+ {
+ Vector3i( 0, 0, 0),
+ Vector3i( 1, 0, 0),
+ Vector3i(-1, 0, 0),
+ Vector3i( 0, 0, 1),
+ Vector3i( 0, 0, -1),
+ };
+ for (size_t i = 0; i < ARRAYCOUNT(Coords); ++i)
+ {
+ if (TrySpawnWither(a_ChunkInterface, World, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z))
+ {
+ break;
+ }
+ } // for i - Coords[]
+ }
+ }
+} ;
+
+
+
+
diff --git a/src/Blocks/BlockMushroom.h b/src/Blocks/BlockMushroom.h
index 2846a6317..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
@@ -24,7 +27,7 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
if (a_RelY <= 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/BlockNetherWart.h b/src/Blocks/BlockNetherWart.h
index 4cc3d989a..812cf906f 100644
--- a/src/Blocks/BlockNetherWart.h
+++ b/src/Blocks/BlockNetherWart.h
@@ -2,14 +2,13 @@
#pragma once
#include "BlockHandler.h"
-#include "../MersenneTwister.h"
+#include "../FastRandom.h"
#include "../World.h"
-/// Common class that takes care of carrots, potatoes and wheat
class cBlockNetherWartHandler :
public cBlockHandler
{
@@ -22,12 +21,12 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_Meta) override
{
- MTRand rand;
+ cFastRandom rand;
if (a_Meta == 0x7)
{
- // Is fully grown, drop the entire produce:
- a_Pickups.push_back(cItem(E_ITEM_NETHER_WART, 1 + (int)(rand.randInt(2) + rand.randInt(2)) / 2, 0));
+ // Fully grown, drop the entire produce:
+ a_Pickups.push_back(cItem(E_ITEM_NETHER_WART, (char)(1 + (rand.NextInt(3) + rand.NextInt(3))) / 2, 0));
}
else
{
@@ -35,18 +34,20 @@ public:
}
}
- void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
- {
- NIBBLETYPE Meta = a_Chunk.GetMeta (a_RelX, a_RelY, a_RelZ);
+ virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
+ {
+ NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
if (Meta < 7)
{
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_NETHER_WART, ++Meta);
}
}
+
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
+ // Needs to be placed on top of a Soulsand block:
return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_SOULSAND));
}
-} ; \ No newline at end of file
+} ;
diff --git a/src/Blocks/BlockNewLeaves.h b/src/Blocks/BlockNewLeaves.h
new file mode 100644
index 000000000..5a267e8c6
--- /dev/null
+++ b/src/Blocks/BlockNewLeaves.h
@@ -0,0 +1,42 @@
+#pragma once
+#include "BlockHandler.h"
+#include "BlockLeaves.h"
+#include "../World.h"
+
+
+
+
+
+
+class cBlockNewLeavesHandler :
+ public cBlockLeavesHandler
+{
+public:
+ cBlockNewLeavesHandler(BLOCKTYPE a_BlockType)
+ : cBlockLeavesHandler(a_BlockType)
+ {
+ }
+
+
+ virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
+ {
+ MTRand rand;
+
+ // Only the first 2 bits contain the display information, the others are for growing
+ if (rand.randInt(5) == 0)
+ {
+ a_Pickups.push_back(cItem(E_BLOCK_SAPLING, 1, (a_BlockMeta & 3) + 4));
+ }
+ }
+
+
+ void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ {
+ cBlockHandler::OnDestroyed(a_ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ);
+ }
+} ;
+
+
+
+
+
diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp
index 88259d96e..542eb33b5 100644
--- a/src/Blocks/BlockPiston.cpp
+++ b/src/Blocks/BlockPiston.cpp
@@ -33,18 +33,18 @@ cBlockPistonHandler::cBlockPistonHandler(BLOCKTYPE a_BlockType)
-void cBlockPistonHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+void cBlockPistonHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
- NIBBLETYPE OldMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
int newX = a_BlockX;
int newY = a_BlockY;
int newZ = a_BlockZ;
AddPistonDir(newX, newY, newZ, OldMeta & ~(8), 1);
- if (a_World->GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION)
+ if (a_ChunkInterface.GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION)
{
- a_World->SetBlock(newX, newY, newZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.SetBlock(a_WorldInterface, newX, newY, newZ, E_BLOCK_AIR, 0);
}
}
@@ -53,8 +53,8 @@ void cBlockPistonHandler::OnDestroyed(cWorld * a_World, int a_BlockX, int a_Bloc
bool cBlockPistonHandler::GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
)
@@ -80,19 +80,19 @@ cBlockPistonHeadHandler::cBlockPistonHeadHandler(void) :
-void cBlockPistonHeadHandler::OnDestroyedByPlayer(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
+void cBlockPistonHeadHandler::OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
{
- NIBBLETYPE OldMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
int newX = a_BlockX;
int newY = a_BlockY;
int newZ = a_BlockZ;
AddPistonDir(newX, newY, newZ, OldMeta & ~(8), -1);
- BLOCKTYPE Block = a_World->GetBlock(newX, newY, newZ);
+ BLOCKTYPE Block = a_ChunkInterface.GetBlock(newX, newY, newZ);
if ((Block == E_BLOCK_STICKY_PISTON) || (Block == E_BLOCK_PISTON))
{
- a_World->DigBlock(newX, newY, newZ);
+ a_ChunkInterface.DigBlock(a_WorldInterface, newX, newY, newZ);
if (a_Player->IsGameModeCreative())
{
return; // No pickups if creative
@@ -100,7 +100,7 @@ void cBlockPistonHeadHandler::OnDestroyedByPlayer(cWorld * a_World, cPlayer * a_
cItems Pickups;
Pickups.push_back(cItem(Block, 1));
- a_World->SpawnItemPickups(Pickups, a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5);
+ a_WorldInterface.SpawnItemPickups(Pickups, a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5);
}
}
diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h
index 36fa6a572..7632b5e5a 100644
--- a/src/Blocks/BlockPiston.h
+++ b/src/Blocks/BlockPiston.h
@@ -13,11 +13,11 @@ class cBlockPistonHandler :
public:
cBlockPistonHandler(BLOCKTYPE a_BlockType);
- virtual void OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override;
+ virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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;
@@ -35,7 +35,7 @@ class cBlockPistonHeadHandler :
public:
cBlockPistonHeadHandler(void);
- virtual void OnDestroyedByPlayer(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override;
+ virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
diff --git a/src/Blocks/BlockPlanks.h b/src/Blocks/BlockPlanks.h
index f3b8dbfb6..2a99a455e 100644
--- a/src/Blocks/BlockPlanks.h
+++ b/src/Blocks/BlockPlanks.h
@@ -17,8 +17,8 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
diff --git a/src/Blocks/BlockPluginInterface.h b/src/Blocks/BlockPluginInterface.h
new file mode 100644
index 000000000..3a36c40b1
--- /dev/null
+++ b/src/Blocks/BlockPluginInterface.h
@@ -0,0 +1,14 @@
+
+#pragma once
+
+/** This interface is used to decouple block handlers from the cPluginManager dependancy through cWorld.
+The block handlers call this interface, which is then implemented by the specific classes that
+the caller provides.
+*/
+class cBlockPluginInterface
+{
+public:
+ virtual ~cBlockPluginInterface() {}
+
+ virtual bool CallHookBlockToPickups(cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0;
+};
diff --git a/src/Blocks/BlockPortal.h b/src/Blocks/BlockPortal.h
index d88d14fc9..21bcbdeea 100644
--- a/src/Blocks/BlockPortal.h
+++ b/src/Blocks/BlockPortal.h
@@ -17,8 +17,8 @@ public:
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
@@ -39,7 +39,7 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
if ((a_RelY - 1 < 0) || (a_RelY + 1 > cChunkDef::Height))
{
diff --git a/src/Blocks/BlockPumpkin.h b/src/Blocks/BlockPumpkin.h
index 5187f24eb..ac2b9817a 100644
--- a/src/Blocks/BlockPumpkin.h
+++ b/src/Blocks/BlockPumpkin.h
@@ -1,20 +1,20 @@
#pragma once
#include "BlockHandler.h"
-
+#include "MetaRotator.h"
class cBlockPumpkinHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x07, 0x02, 0x03, 0x00, 0x01, false>
{
public:
cBlockPumpkinHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x07, 0x02, 0x03, 0x00, 0x01, false>(a_BlockType)
{
}
- virtual void OnPlacedByPlayer(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
+ virtual void OnPlacedByPlayer(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, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override
{
// Check whether the pumpkin is a part of a golem or a snowman
@@ -24,16 +24,16 @@ public:
return;
}
- BLOCKTYPE BlockY1 = a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ);
- BLOCKTYPE BlockY2 = a_World->GetBlock(a_BlockX, a_BlockY - 2, a_BlockZ);
+ BLOCKTYPE BlockY1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ);
+ BLOCKTYPE BlockY2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 2, a_BlockZ);
// Check for a snow golem:
if ((BlockY1 == E_BLOCK_SNOW_BLOCK) && (BlockY2 == E_BLOCK_SNOW_BLOCK))
{
- a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
- a_World->FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
- a_World->FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
- a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtSnowGolem);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
+ a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtSnowGolem);
return;
}
@@ -46,41 +46,41 @@ public:
// Now check both orientations for hands:
if (
- (a_World->GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ) == E_BLOCK_IRON_BLOCK) &&
- (a_World->GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ) == E_BLOCK_IRON_BLOCK)
+ (a_ChunkInterface.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ) == E_BLOCK_IRON_BLOCK) &&
+ (a_ChunkInterface.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ) == E_BLOCK_IRON_BLOCK)
)
{
// Remove the iron blocks:
- a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
- a_World->FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
- a_World->FastSetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
- a_World->FastSetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
- a_World->FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
// Spawn the golem:
- a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtIronGolem);
+ a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtIronGolem);
}
else if (
- (a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1) == E_BLOCK_IRON_BLOCK) &&
- (a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1) == E_BLOCK_IRON_BLOCK)
+ (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1) == E_BLOCK_IRON_BLOCK) &&
+ (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1) == E_BLOCK_IRON_BLOCK)
)
{
// Remove the iron blocks:
- a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
- a_World->FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
- a_World->FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1, E_BLOCK_AIR, 0);
- a_World->FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1, E_BLOCK_AIR, 0);
- a_World->FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1, E_BLOCK_AIR, 0);
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
// Spawn the golem:
- a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtIronGolem);
+ a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtIronGolem);
}
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
diff --git a/src/Blocks/BlockQuartz.h b/src/Blocks/BlockQuartz.h
new file mode 100644
index 000000000..9cc51490f
--- /dev/null
+++ b/src/Blocks/BlockQuartz.h
@@ -0,0 +1,67 @@
+
+#pragma once
+
+#include "BlockHandler.h"
+
+
+
+
+
+class cBlockQuartzHandler : public cBlockHandler
+{
+public:
+ cBlockQuartzHandler(BLOCKTYPE a_BlockType)
+ : cBlockHandler(a_BlockType)
+ {
+ }
+
+
+ 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;
+ NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage);
+ if (Meta != E_META_QUARTZ_PILLAR) // Check if the block is a pillar block.
+ {
+ a_BlockMeta = Meta;
+ return true;
+ }
+
+ a_BlockMeta = BlockFaceToMetaData(a_BlockFace, Meta);
+ return true;
+ }
+
+ inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_BlockFace, NIBBLETYPE a_QuartzMeta)
+ {
+ switch (a_BlockFace)
+ {
+ case BLOCK_FACE_YM:
+ case BLOCK_FACE_YP:
+ {
+ return a_QuartzMeta; // Top or bottom, just return original
+ }
+
+ case BLOCK_FACE_ZP:
+ case BLOCK_FACE_ZM:
+ {
+ return 0x4; // North or south
+ }
+
+ case BLOCK_FACE_XP:
+ case BLOCK_FACE_XM:
+ {
+ return 0x3; // East or west
+ }
+
+ default:
+ {
+ ASSERT(!"Unhandled block face!");
+ return a_QuartzMeta; // No idea, give a special meta (all sides the same)
+ }
+ }
+ }
+} ;
diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h
index 55cadfa48..ad78d290a 100644
--- a/src/Blocks/BlockRail.h
+++ b/src/Blocks/BlockRail.h
@@ -2,7 +2,6 @@
#pragma once
#include "BlockEntity.h"
-#include "../World.h"
@@ -31,58 +30,58 @@ public:
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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;
- a_BlockMeta = FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ);
+ a_BlockMeta = FindMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
return true;
}
- virtual void OnPlaced(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override
+ virtual void OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override
{
- super::OnPlaced(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
+ super::OnPlaced(a_ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
// Alert diagonal rails
- OnNeighborChanged(a_World, a_BlockX + 1, a_BlockY + 1, a_BlockZ);
- OnNeighborChanged(a_World, a_BlockX - 1, a_BlockY + 1, a_BlockZ);
- OnNeighborChanged(a_World, a_BlockX, a_BlockY + 1, a_BlockZ + 1);
- OnNeighborChanged(a_World, a_BlockX, a_BlockY + 1, a_BlockZ - 1);
-
- OnNeighborChanged(a_World, a_BlockX + 1, a_BlockY - 1, a_BlockZ);
- OnNeighborChanged(a_World, a_BlockX - 1, a_BlockY - 1, a_BlockZ);
- OnNeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ + 1);
- OnNeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ - 1);
+ OnNeighborChanged(a_ChunkInterface, a_BlockX + 1, a_BlockY + 1, a_BlockZ);
+ OnNeighborChanged(a_ChunkInterface, a_BlockX - 1, a_BlockY + 1, a_BlockZ);
+ OnNeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ + 1);
+ OnNeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ - 1);
+
+ OnNeighborChanged(a_ChunkInterface, a_BlockX + 1, a_BlockY - 1, a_BlockZ);
+ OnNeighborChanged(a_ChunkInterface, a_BlockX - 1, a_BlockY - 1, a_BlockZ);
+ OnNeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ + 1);
+ OnNeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ - 1);
}
- virtual void OnDestroyed(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override
{
- super::OnDestroyed(a_World, a_BlockX, a_BlockY, a_BlockZ);
+ super::OnDestroyed(a_ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ);
// Alert diagonal rails
- OnNeighborChanged(a_World, a_BlockX + 1, a_BlockY + 1, a_BlockZ);
- OnNeighborChanged(a_World, a_BlockX - 1, a_BlockY + 1, a_BlockZ);
- OnNeighborChanged(a_World, a_BlockX, a_BlockY + 1, a_BlockZ + 1);
- OnNeighborChanged(a_World, a_BlockX, a_BlockY + 1, a_BlockZ - 1);
-
- OnNeighborChanged(a_World, a_BlockX + 1, a_BlockY - 1, a_BlockZ);
- OnNeighborChanged(a_World, a_BlockX - 1, a_BlockY - 1, a_BlockZ);
- OnNeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ + 1);
- OnNeighborChanged(a_World, a_BlockX, a_BlockY - 1, a_BlockZ - 1);
+ OnNeighborChanged(a_ChunkInterface, a_BlockX + 1, a_BlockY + 1, a_BlockZ);
+ OnNeighborChanged(a_ChunkInterface, a_BlockX - 1, a_BlockY + 1, a_BlockZ);
+ OnNeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ + 1);
+ OnNeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ - 1);
+
+ OnNeighborChanged(a_ChunkInterface, a_BlockX + 1, a_BlockY - 1, a_BlockZ);
+ OnNeighborChanged(a_ChunkInterface, a_BlockX - 1, a_BlockY - 1, a_BlockZ);
+ OnNeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ + 1);
+ OnNeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ - 1);
}
- virtual void OnNeighborChanged(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override
{
- NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
- if (IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ) && (Meta != FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ)))
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ if (IsUnstable(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ) && (Meta != FindMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ)))
{
- a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ));
+ a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, FindMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ));
}
}
@@ -93,13 +92,13 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
if (a_RelY <= 0)
{
return false;
}
- if (!g_BlockIsSolid[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)])
+ if (!cBlockInfo::IsSolid(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)))
{
return false;
}
@@ -131,33 +130,33 @@ public:
// Too close to the edge, cannot simulate
return true;
}
- return g_BlockIsSolid[BlockType];
+ return cBlockInfo::IsSolid(BlockType);
}
}
return true;
}
- NIBBLETYPE FindMeta(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+ NIBBLETYPE FindMeta(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
NIBBLETYPE Meta = 0;
char RailsCnt = 0;
bool Neighbors[8]; // 0 - EAST, 1 - WEST, 2 - NORTH, 3 - SOUTH, 4 - EAST UP, 5 - WEST UP, 6 - NORTH UP, 7 - SOUTH UP
memset(Neighbors, false, sizeof(Neighbors));
- Neighbors[0] = (IsUnstable(a_World, a_BlockX + 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST, E_PURE_DOWN));
- Neighbors[1] = (IsUnstable(a_World, a_BlockX - 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST, E_PURE_DOWN));
- Neighbors[2] = (IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_DOWN));
- Neighbors[3] = (IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_DOWN));
- Neighbors[4] = (IsUnstable(a_World, a_BlockX + 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_EAST, E_PURE_NONE));
- Neighbors[5] = (IsUnstable(a_World, a_BlockX - 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_WEST, E_PURE_NONE));
- Neighbors[6] = (IsUnstable(a_World, a_BlockX, a_BlockY + 1, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_NONE));
- Neighbors[7] = (IsUnstable(a_World, a_BlockX, a_BlockY + 1, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_NONE));
- if (IsUnstable(a_World, a_BlockX + 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_EAST))
+ Neighbors[0] = (IsUnstable(a_ChunkInterface, a_BlockX + 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST, E_PURE_DOWN));
+ Neighbors[1] = (IsUnstable(a_ChunkInterface, a_BlockX - 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST, E_PURE_DOWN));
+ Neighbors[2] = (IsUnstable(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ - 1) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_DOWN));
+ Neighbors[3] = (IsUnstable(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ + 1) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_DOWN));
+ Neighbors[4] = (IsUnstable(a_ChunkInterface, a_BlockX + 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_EAST, E_PURE_NONE));
+ Neighbors[5] = (IsUnstable(a_ChunkInterface, a_BlockX - 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_WEST, E_PURE_NONE));
+ Neighbors[6] = (IsUnstable(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ - 1) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_NONE));
+ Neighbors[7] = (IsUnstable(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ + 1) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_NONE));
+ if (IsUnstable(a_ChunkInterface, a_BlockX + 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_EAST))
Neighbors[0] = true;
- if (IsUnstable(a_World, a_BlockX - 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_WEST))
+ if (IsUnstable(a_ChunkInterface, a_BlockX - 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_WEST))
Neighbors[1] = true;
- if (IsUnstable(a_World, a_BlockX, a_BlockY - 1, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_NORTH))
+ if (IsUnstable(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ - 1) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_NORTH))
Neighbors[2] = true;
- if (IsUnstable(a_World, a_BlockX, a_BlockY - 1, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_SOUTH))
+ if (IsUnstable(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ + 1) || !IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_SOUTH))
Neighbors[3] = true;
for (int i = 0; i < 8; i++)
{
@@ -186,36 +185,46 @@ public:
}
if (RailsCnt > 1)
{
- if (Neighbors[3] && Neighbors[0]) return E_META_RAIL_CURVED_ZP_XP;
- else if (Neighbors[3] && Neighbors[1]) return E_META_RAIL_CURVED_ZP_XM;
- else if (Neighbors[2] && Neighbors[0]) return E_META_RAIL_CURVED_ZM_XP;
- else if (Neighbors[2] && Neighbors[1]) return E_META_RAIL_CURVED_ZM_XM;
+ if (Neighbors[3] && Neighbors[0] && CanThisRailCurve()) return E_META_RAIL_CURVED_ZP_XP;
+ else if (Neighbors[3] && Neighbors[1] && CanThisRailCurve()) return E_META_RAIL_CURVED_ZP_XM;
+ else if (Neighbors[2] && Neighbors[0] && CanThisRailCurve()) return E_META_RAIL_CURVED_ZM_XP;
+ else if (Neighbors[2] && Neighbors[1] && CanThisRailCurve()) return E_META_RAIL_CURVED_ZM_XM;
else if (Neighbors[7] && Neighbors[2]) return E_META_RAIL_ASCEND_ZP;
else if (Neighbors[3] && Neighbors[6]) return E_META_RAIL_ASCEND_ZM;
else if (Neighbors[5] && Neighbors[0]) return E_META_RAIL_ASCEND_XM;
else if (Neighbors[4] && Neighbors[1]) return E_META_RAIL_ASCEND_XP;
else if (Neighbors[0] && Neighbors[1]) return E_META_RAIL_XM_XP;
else if (Neighbors[2] && Neighbors[3]) return E_META_RAIL_ZM_ZP;
- ASSERT(!"Weird neighbor count");
+
+ if (CanThisRailCurve())
+ {
+ ASSERT(!"Weird neighbor count");
+ }
}
return Meta;
}
- bool IsUnstable(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+ inline bool CanThisRailCurve(void)
+ {
+ return m_BlockType == E_BLOCK_RAIL;
+ }
+
+
+ bool IsUnstable(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
- if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL)
+ if (!IsBlockRail(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ)))
{
return false;
}
- NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
switch (Meta)
{
case E_META_RAIL_ZM_ZP:
{
if (
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_DOWN) ||
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_DOWN)
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_DOWN) ||
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_DOWN)
)
{
return true;
@@ -226,8 +235,8 @@ public:
case E_META_RAIL_XM_XP:
{
if (
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST, E_PURE_DOWN) ||
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST, E_PURE_DOWN)
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST, E_PURE_DOWN) ||
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST, E_PURE_DOWN)
)
{
return true;
@@ -238,8 +247,8 @@ public:
case E_META_RAIL_ASCEND_XP:
{
if (
- IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_EAST) ||
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST)
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_EAST) ||
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST)
)
{
return true;
@@ -250,8 +259,8 @@ public:
case E_META_RAIL_ASCEND_XM:
{
if (
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST) ||
- IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_WEST)
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST) ||
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_WEST)
)
{
return true;
@@ -262,8 +271,8 @@ public:
case E_META_RAIL_ASCEND_ZM:
{
if (
- IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_NORTH) ||
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH)
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_NORTH) ||
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH)
)
{
return true;
@@ -274,8 +283,8 @@ public:
case E_META_RAIL_ASCEND_ZP:
{
if (
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH) ||
- IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_SOUTH)
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH) ||
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_SOUTH)
)
{
return true;
@@ -286,8 +295,8 @@ public:
case E_META_RAIL_CURVED_ZP_XP:
{
if (
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH) ||
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST)
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH) ||
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST)
)
{
return true;
@@ -298,8 +307,8 @@ public:
case E_META_RAIL_CURVED_ZP_XM:
{
if (
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH) ||
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST)
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH) ||
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST)
)
{
return true;
@@ -310,8 +319,8 @@ public:
case E_META_RAIL_CURVED_ZM_XM:
{
if (
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH) ||
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST)
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH) ||
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST)
)
{
return true;
@@ -322,8 +331,8 @@ public:
case E_META_RAIL_CURVED_ZM_XP:
{
if (
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH) ||
- IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST)
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH) ||
+ IsNotConnected(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST)
)
{
return true;
@@ -335,31 +344,31 @@ public:
}
- bool IsNotConnected(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Pure = 0)
+ bool IsNotConnected(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, char a_Pure = 0)
{
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false);
NIBBLETYPE Meta;
- if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL)
+ if (!IsBlockRail(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ)))
{
- if ((a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure != E_PURE_UPDOWN))
+ if (!IsBlockRail(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)) || (a_Pure != E_PURE_UPDOWN))
{
- if ((a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure == E_PURE_NONE))
+ if (!IsBlockRail(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)) || (a_Pure == E_PURE_NONE))
{
return true;
}
else
{
- Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ);
+ Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ);
}
}
else
{
- Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ);
+ Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ);
}
}
else
{
- Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
}
switch (a_BlockFace)
@@ -422,9 +431,145 @@ public:
}
break;
}
+ default: break;
}
return true;
}
+
+
+ virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
+ {
+ // Bit 0x08 is a flag when a_Meta is in the range 0x00--0x05 and 0x0A--0x0F.
+ // Bit 0x08 specifies direction when a_Meta is in the range 0x06-0x09.
+ if ((a_Meta < 0x06) || (a_Meta > 0x09))
+ {
+ // Save powered rail flag.
+ NIBBLETYPE OtherMeta = a_Meta & 0x08;
+ // Rotates according to table; 0x07 == 0111.
+ // Rails can either be flat (North/South) or Ascending (Asc. East)
+ switch (a_Meta & 0x07)
+ {
+ case 0x00: return 0x01 + OtherMeta; // North/South -> East/West
+ case 0x01: return 0x00 + OtherMeta; // East/West -> North/South
+
+ case 0x02: return 0x04 + OtherMeta; // Asc. East -> Asc. North
+ case 0x04: return 0x03 + OtherMeta; // Asc. North -> Asc. West
+ case 0x03: return 0x05 + OtherMeta; // Asc. West -> Asc. South
+ case 0x05: return 0x02 + OtherMeta; // Asc. South -> Asc. East
+ }
+ }
+ else
+ {
+ switch (a_Meta)
+ {
+ // Corner Directions
+ case 0x06: return 0x09; // Northwest Cnr. -> Southwest Cnr.
+ case 0x07: return 0x06; // Northeast Cnr. -> Northwest Cnr.
+ case 0x08: return 0x07; // Southeast Cnr. -> Northeast Cnr.
+ case 0x09: return 0x08; // Southwest Cnr. -> Southeast Cnr.
+ }
+ }
+ // To avoid a compiler warning;
+ return a_Meta;
+ }
+
+
+ virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
+ {
+ // Bit 0x08 is a flag for value in the range 0x00--0x05 and specifies direction for values withint 0x006--0x09.
+ if ((a_Meta < 0x06) || (a_Meta > 0x09))
+ {
+ // Save powered rail flag.
+ NIBBLETYPE OtherMeta = a_Meta & 0x08;
+ // Rotates according to table; 0x07 == 0111.
+ // Rails can either be flat (North/South) or Ascending (Asc. East)
+ switch (a_Meta & 0x07)
+ {
+ case 0x00: return 0x01 + OtherMeta; // North/South -> East/West
+ case 0x01: return 0x00 + OtherMeta; // East/West -> North/South
+
+ case 0x02: return 0x05 + OtherMeta; // Asc. East -> Asc. South
+ case 0x05: return 0x03 + OtherMeta; // Asc. South -> Asc. West
+ case 0x03: return 0x04 + OtherMeta; // Asc. West -> Asc. North
+ case 0x04: return 0x02 + OtherMeta; // Asc. North -> Asc. East
+ }
+ }
+ else
+ {
+ switch (a_Meta)
+ {
+ // Corner Directions
+ case 0x06: return 0x07; // Northwest Cnr. -> Northeast Cnr.
+ case 0x07: return 0x08; // Northeast Cnr. -> Southeast Cnr.
+ case 0x08: return 0x09; // Southeast Cnr. -> Southwest Cnr.
+ case 0x09: return 0x06; // Southwest Cnr. -> Northwest Cnr.
+ }
+ }
+ // To avoid a compiler warning;
+ return a_Meta;
+ }
+
+
+ virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
+ {
+ // Bit 0x08 is a flag for value in the range 0x00--0x05 and specifies direction for values withint 0x006--0x09.
+ if ((a_Meta < 0x06) || (a_Meta > 0x09))
+ {
+ // Save powered rail flag.
+ NIBBLETYPE OtherMeta = a_Meta & 0x08;
+ // Mirrors according to table; 0x07 == 0111.
+ // Rails can either be flat (North/South) or Ascending (Asc. East)
+ switch (a_Meta & 0x07)
+ {
+ case 0x05: return 0x04 + OtherMeta; // Asc. South -> Asc. North
+ case 0x04: return 0x05 + OtherMeta; // Asc. North -> Asc. South
+ }
+ }
+ else
+ {
+ switch (a_Meta)
+ {
+ // Corner Directions
+ case 0x06: return 0x09; // Northwest Cnr. -> Southwest Cnr.
+ case 0x07: return 0x08; // Northeast Cnr. -> Southeast Cnr.
+ case 0x08: return 0x07; // Southeast Cnr. -> Northeast Cnr.
+ case 0x09: return 0x06; // Southwest Cnr. -> Northwest Cnr.
+ }
+ }
+ // To avoid a compiler warning;
+ return a_Meta;
+ }
+
+
+ virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
+ {
+ // Bit 0x08 is a flag for value in the range 0x00--0x05 and specifies direction for values withint 0x006--0x09.
+ if ((a_Meta < 0x06) || (a_Meta > 0x09))
+ {
+ // Save powered rail flag.
+ NIBBLETYPE OtherMeta = a_Meta & 0x08;
+ // Mirrors according to table; 0x07 == 0111.
+ // Rails can either be flat (North/South) or Ascending (Asc. East)
+ switch (a_Meta & 0x07)
+ {
+ case 0x02: return 0x03 + OtherMeta; // Asc. East -> Asc. West
+ case 0x03: return 0x02 + OtherMeta; // Asc. West -> Asc. East
+ }
+ }
+ else
+ {
+ switch (a_Meta)
+ {
+ // Corner Directions
+ case 0x06: return 0x07; // Northwest Cnr. -> Northeast Cnr.
+ case 0x07: return 0x06; // Northeast Cnr. -> Northwest Cnr.
+ case 0x08: return 0x09; // Southeast Cnr. -> Southwest Cnr.
+ case 0x09: return 0x08; // Southwest Cnr. -> Southeast Cnr.
+ }
+ }
+ // To avoid a compiler warning;
+ return a_Meta;
+ }
} ;
diff --git a/src/Blocks/BlockRedstone.h b/src/Blocks/BlockRedstone.h
index 5ffb77fb6..a898c9acb 100644
--- a/src/Blocks/BlockRedstone.h
+++ b/src/Blocks/BlockRedstone.h
@@ -18,9 +18,9 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
- return ((a_RelY > 0) && g_BlockFullyOccupiesVoxel[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]);
+ return ((a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)));
}
diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h
index 713664659..fe6cd21b9 100644
--- a/src/Blocks/BlockRedstoneRepeater.h
+++ b/src/Blocks/BlockRedstoneRepeater.h
@@ -2,24 +2,25 @@
#pragma once
#include "BlockHandler.h"
-
+#include "Chunk.h"
+#include "MetaRotator.h"
class cBlockRedstoneRepeaterHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>
{
public:
cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>(a_BlockType)
{
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
@@ -28,11 +29,18 @@ public:
a_BlockMeta = RepeaterRotationToMetaData(a_Player->GetYaw());
return true;
}
-
- virtual void OnUse(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) override
+
+ 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
+ {
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, ((a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) + 0x04) & 0x0f));
+ }
+
+
+ virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
{
- a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) + 0x04) & 0x0f));
+ UNUSED(a_ChunkInterface);
+ a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
}
@@ -49,7 +57,7 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR));
}
diff --git a/src/Blocks/BlockSapling.h b/src/Blocks/BlockSapling.h
index 0dcae1f93..3d925029a 100644
--- a/src/Blocks/BlockSapling.h
+++ b/src/Blocks/BlockSapling.h
@@ -25,13 +25,13 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
return (a_RelY > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ));
}
- void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
+ virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
diff --git a/src/Blocks/BlockWood.h b/src/Blocks/BlockSideways.h
index cb5ee995a..d67c3aa24 100644
--- a/src/Blocks/BlockWood.h
+++ b/src/Blocks/BlockSideways.h
@@ -7,18 +7,18 @@
-class cBlockWoodHandler : public cBlockHandler
+class cBlockSidewaysHandler : public cBlockHandler
{
public:
- cBlockWoodHandler(BLOCKTYPE a_BlockType)
+ cBlockSidewaysHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType)
{
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
@@ -29,8 +29,14 @@ public:
return true;
}
-
- inline static NIBBLETYPE BlockFaceToMetaData(char a_BlockFace, NIBBLETYPE a_WoodMeta)
+
+ 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/BlockSign.h b/src/Blocks/BlockSign.h
index 7fbe61893..9d6fede21 100644
--- a/src/Blocks/BlockSign.h
+++ b/src/Blocks/BlockSign.h
@@ -2,8 +2,8 @@
#pragma once
#include "BlockHandler.h"
-#include "../World.h"
#include "../Entities/Player.h"
+#include "Chunk.h"
@@ -31,7 +31,7 @@ public:
}
- static char RotationToMetaData(double a_Rotation)
+ static NIBBLETYPE RotationToMetaData(double a_Rotation)
{
a_Rotation += 180 + (180 / 16); // So it's not aligned with axis
if (a_Rotation > 360)
@@ -45,7 +45,7 @@ public:
}
- static char DirectionToMetaData(char a_Direction)
+ static NIBBLETYPE DirectionToMetaData(eBlockFace a_Direction)
{
switch (a_Direction)
{
@@ -63,14 +63,45 @@ public:
virtual void OnPlacedByPlayer(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
) override
{
a_Player->GetClientHandle()->SendEditSign(a_BlockX, a_BlockY, a_BlockZ);
}
+
+
+ virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
+ {
+ return (++a_Meta) & 0x0F;
+ }
+
+
+ virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
+ {
+ return (--a_Meta) & 0x0F;
+ }
+
+ virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
+ {
+ // Mirrors signs over the XY plane (North-South Mirroring)
+
+ // There are 16 meta values which correspond to different directions.
+ // These values are equated to angles on a circle; 0x08 = 180 degrees.
+ return (a_Meta < 0x08) ? 0x08 + a_Meta : 0x08 - a_Meta;
+ }
+
+
+ virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
+ {
+ // Mirrors signs over the YZ plane (East-West Mirroring)
+
+ // There are 16 meta values which correspond to different directions.
+ // These values are equated to angles on a circle; 0x10 = 360 degrees.
+ return 0x10 - a_Meta;
+ }
} ;
diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h
index 7c1251b28..76f5ed0e7 100644
--- a/src/Blocks/BlockSlab.h
+++ b/src/Blocks/BlockSlab.h
@@ -11,8 +11,7 @@
#include "BlockHandler.h"
#include "../Items/ItemHandler.h"
-
-
+#include "Root.h"
@@ -28,53 +27,21 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
- a_Pickups.push_back(cItem(m_BlockType, 1, a_BlockMeta));
+ a_Pickups.push_back(cItem(m_BlockType, 1, a_BlockMeta & 0x7));
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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;
- BLOCKTYPE Type = (BLOCKTYPE) (a_Player->GetEquippedItem().m_ItemType);
- NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage & 0x07);
+ NIBBLETYPE Meta = (NIBBLETYPE) a_Player->GetEquippedItem().m_ItemDamage;
- // HandlePlaceBlock wants a cItemHandler pointer thing, so let's give it one
- cItemHandler * ItemHandler = cItemHandler::GetItemHandler(GetDoubleSlabType(Type));
-
- // Check if the block at the coordinates is a slab. Eligibility for combining has already been processed in ClientHandle
- if (IsAnySlabType(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ)))
- {
- // Call the function in ClientHandle that places a block when the client sends the packet,
- // so that plugins may interfere with the placement.
-
- if ((a_BlockFace == BLOCK_FACE_TOP) || (a_BlockFace == BLOCK_FACE_BOTTOM))
- {
- // Top and bottom faces need no parameter modification
- a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler);
- }
- else
- {
- // The other faces need to distinguish between top and bottom cursor positions
- if (a_CursorY > 7)
- {
- // Edit the call to use BLOCK_FACE_BOTTOM, otherwise it places incorrectly
- a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_TOP, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler);
- }
- else
- {
- // Edit the call to use BLOCK_FACE_TOP, otherwise it places incorrectly
- a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_BOTTOM, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler);
- }
- }
- return false; // Cancel the event, because dblslabs were already placed, nothing else needed
- }
-
- // Place the single-slab with correct metas:
+ // Set the correct metadata based on player equipped item (i.e. a_BlockMeta not initialised yet)
switch (a_BlockFace)
{
case BLOCK_FACE_TOP:
@@ -105,7 +72,16 @@ public:
a_BlockMeta = Meta & 0x7; break;
}
}
+ case BLOCK_FACE_NONE: return false;
} // switch (a_BlockFace)
+
+ // Check if the block at the coordinates is a single slab. Eligibility for combining has already been processed in ClientHandle
+ // Changed to-be-placed to a double slab if we are clicking on a single slab, as opposed to placing one for the first time
+ if (IsAnySlabType(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ)))
+ {
+ a_BlockType = GetDoubleSlabType(m_BlockType);
+ }
+
return true;
}
@@ -159,21 +135,39 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
- if (m_BlockType == E_BLOCK_DOUBLE_STONE_SLAB)
+ BLOCKTYPE Block = GetSingleSlabType(m_BlockType);
+ a_Pickups.push_back(cItem(Block, 2, a_BlockMeta & 0x7));
+ }
+
+ inline static BLOCKTYPE GetSingleSlabType(BLOCKTYPE a_BlockType)
+ {
+ switch (a_BlockType)
{
- m_BlockType = E_BLOCK_STONE_SLAB;
+ case E_BLOCK_DOUBLE_STONE_SLAB: return E_BLOCK_STONE_SLAB;
+ case E_BLOCK_DOUBLE_WOODEN_SLAB: return E_BLOCK_WOODEN_SLAB;
}
- else
+ ASSERT(!"Unhandled double slab type!");
+ return a_BlockType;
+ }
+
+ virtual const char * GetStepSound(void) override
+ {
+ switch (m_BlockType)
{
- m_BlockType = E_BLOCK_WOODEN_SLAB;
+ case E_BLOCK_DOUBLE_STONE_SLAB: return "step.stone";
+ case E_BLOCK_DOUBLE_WOODEN_SLAB: return "step.wood";
}
- a_Pickups.push_back(cItem(m_BlockType, 2, a_BlockMeta));
+ ASSERT(!"Unhandled double slab type!");
+ return "";
}
-
- virtual const char * GetStepSound(void) override
- {
- return ((m_BlockType == E_BLOCK_DOUBLE_WOODEN_SLAB) || (m_BlockType == E_BLOCK_DOUBLE_WOODEN_SLAB)) ? "step.wood" : "step.stone";
+
+ virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
+ {
+ NIBBLETYPE OtherMeta = a_Meta & 0x07; // Contains unrelated meta data.
+
+ // 8th bit is up/down. 1 right-side-up, 0 is up-side-down.
+ return (a_Meta & 0x08) ? 0x00 + OtherMeta : 0x01 + OtherMeta;
}
} ;
diff --git a/src/Blocks/BlockSnow.h b/src/Blocks/BlockSnow.h
index d7fd1e19e..b21995d3c 100644
--- a/src/Blocks/BlockSnow.h
+++ b/src/Blocks/BlockSnow.h
@@ -18,8 +18,8 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
@@ -28,7 +28,7 @@ public:
BLOCKTYPE BlockBeforePlacement;
NIBBLETYPE MetaBeforePlacement;
- a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockBeforePlacement, MetaBeforePlacement);
+ a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockBeforePlacement, MetaBeforePlacement);
if ((BlockBeforePlacement == E_BLOCK_SNOW) && (MetaBeforePlacement < 7))
{
@@ -65,14 +65,14 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
if (a_RelY > 0)
{
BLOCKTYPE BlockBelow = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ);
NIBBLETYPE MetaBelow = a_Chunk.GetMeta(a_RelX, a_RelY - 1, a_RelZ);
- if (g_BlockIsSnowable[BlockBelow] || ((BlockBelow == E_BLOCK_SNOW) && (MetaBelow == 7)))
+ if (cBlockInfo::IsSnowable(BlockBelow) || ((BlockBelow == E_BLOCK_SNOW) && (MetaBelow == 7)))
{
// If block below is snowable, or it is a thin slow block and has a meta of 7 (full thin snow block), say yay
return true;
diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h
index e463612f5..09ff254a6 100644
--- a/src/Blocks/BlockStairs.h
+++ b/src/Blocks/BlockStairs.h
@@ -2,29 +2,35 @@
#pragma once
#include "BlockHandler.h"
-
+#include "MetaRotator.h"
class cBlockStairsHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x03, 0x03, 0x00, 0x02, 0x01, true>
{
public:
cBlockStairsHandler(BLOCKTYPE a_BlockType) :
- cBlockHandler(a_BlockType)
+ cMetaRotator<cBlockHandler, 0x03, 0x03, 0x00, 0x02, 0x01, true>(a_BlockType)
{
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
{
+ UNUSED(a_ChunkInterface);
+ UNUSED(a_BlockX);
+ UNUSED(a_BlockY);
+ UNUSED(a_BlockZ);
+ UNUSED(a_CursorX);
+ UNUSED(a_CursorZ);
a_BlockType = m_BlockType;
a_BlockMeta = RotationToMetaData(a_Player->GetYaw());
switch (a_BlockFace)
@@ -43,10 +49,12 @@ public:
}
break;
}
+ case BLOCK_FACE_NONE: return false;
}
return true;
}
+
virtual const char * GetStepSound(void) override
{
if (
@@ -96,54 +104,6 @@ public:
}
- virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
- {
- // Bits 3 and 4 stay, the rest is swapped around according to a table:
- NIBBLETYPE TopBits = (a_Meta & 0x0c);
- switch (a_Meta & 0x03)
- {
- case 0x00: return TopBits | 0x03; // East -> North
- case 0x01: return TopBits | 0x02; // West -> South
- case 0x02: return TopBits | 0x00; // South -> East
- case 0x03: return TopBits | 0x01; // North -> West
- }
- // Not reachable, but to avoid a compiler warning:
- return 0;
- }
-
-
- virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
- {
- // Bits 3 and 4 stay, the rest is swapped around according to a table:
- NIBBLETYPE TopBits = (a_Meta & 0x0c);
- switch (a_Meta & 0x03)
- {
- case 0x00: return TopBits | 0x02; // East -> South
- case 0x01: return TopBits | 0x03; // West -> North
- case 0x02: return TopBits | 0x01; // South -> West
- case 0x03: return TopBits | 0x00; // North -> East
- }
- // Not reachable, but to avoid a compiler warning:
- return 0;
- }
-
-
- virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
- {
- // Bits 3 and 4 stay, the rest is swapped around according to a table:
- NIBBLETYPE TopBits = (a_Meta & 0x0c);
- switch (a_Meta & 0x03)
- {
- case 0x00: return TopBits | 0x00; // East -> East
- case 0x01: return TopBits | 0x01; // West -> West
- case 0x02: return TopBits | 0x03; // South -> North
- case 0x03: return TopBits | 0x02; // North -> South
- }
- // Not reachable, but to avoid a compiler warning:
- return 0;
- }
-
-
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
{
// Toggle bit 3:
@@ -151,20 +111,6 @@ public:
}
- virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
- {
- // Bits 3 and 4 stay, the rest is swapped around according to a table:
- NIBBLETYPE TopBits = (a_Meta & 0x0c);
- switch (a_Meta & 0x03)
- {
- case 0x00: return TopBits | 0x01; // East -> West
- case 0x01: return TopBits | 0x00; // West -> East
- case 0x02: return TopBits | 0x02; // South -> South
- case 0x03: return TopBits | 0x03; // North -> North
- }
- // Not reachable, but to avoid a compiler warning:
- return 0;
- }
} ;
diff --git a/src/Blocks/BlockStems.h b/src/Blocks/BlockStems.h
index d860639a5..b726a0901 100644
--- a/src/Blocks/BlockStems.h
+++ b/src/Blocks/BlockStems.h
@@ -17,14 +17,15 @@ public:
{
}
+
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
- int ItemType = (m_BlockType == E_BLOCK_MELON_STEM) ? E_ITEM_MELON_SEEDS : E_ITEM_PUMPKIN_SEEDS;
+ short ItemType = (m_BlockType == E_BLOCK_MELON_STEM) ? E_ITEM_MELON_SEEDS : E_ITEM_PUMPKIN_SEEDS;
a_Pickups.push_back(cItem(ItemType, 1, 0));
}
- void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
+ virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
if (Meta >= 7)
@@ -42,7 +43,7 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_FARMLAND));
}
diff --git a/src/Blocks/BlockSugarcane.h b/src/Blocks/BlockSugarcane.h
index 9cff94800..84d3b2e7d 100644
--- a/src/Blocks/BlockSugarcane.h
+++ b/src/Blocks/BlockSugarcane.h
@@ -23,7 +23,7 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
if (a_RelY <= 0)
{
@@ -73,7 +73,7 @@ public:
}
- void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
+ virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
a_Chunk.GetWorld()->GrowSugarcane(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, 1);
}
diff --git a/src/Blocks/BlockTNT.h b/src/Blocks/BlockTNT.h
new file mode 100644
index 000000000..283a03730
--- /dev/null
+++ b/src/Blocks/BlockTNT.h
@@ -0,0 +1,32 @@
+
+#pragma once
+
+#include "BlockHandler.h"
+
+
+
+
+
+class cBlockTNTHandler :
+ public cBlockHandler
+{
+public:
+ cBlockTNTHandler(BLOCKTYPE a_BlockType)
+ : cBlockHandler(a_BlockType)
+ {
+ }
+
+ virtual const char * GetStepSound(void) override
+ {
+ return "step.grass";
+ }
+
+ virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
+ {
+ a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
+ }
+};
+
+
+
+
diff --git a/src/Blocks/BlockTallGrass.h b/src/Blocks/BlockTallGrass.h
index cd27ab7e6..ba1f2e0f6 100644
--- a/src/Blocks/BlockTallGrass.h
+++ b/src/Blocks/BlockTallGrass.h
@@ -15,14 +15,14 @@ public:
: cBlockHandler(a_BlockType)
{
}
-
-
+
+
virtual bool DoesIgnoreBuildCollision(void) override
{
return true;
}
-
-
+
+
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
// Drop seeds, sometimes
@@ -34,11 +34,25 @@ public:
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ {
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+
+ if ((!a_Player->IsGameModeCreative()) && (a_Player->GetEquippedItem().m_ItemType == E_ITEM_SHEARS))
+ {
+ cItems Pickups;
+ Pickups.Add(E_BLOCK_TALL_GRASS, 1, Meta);
+ a_WorldInterface.SpawnItemPickups(Pickups, a_BlockX, a_BlockY, a_BlockZ);
+ }
+ a_Player->UseEquippedItem();
+ }
+
+
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR));
}
-
+
virtual const char * GetStepSound(void) override
{
diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h
index faba9c4f5..8ddec8de1 100644
--- a/src/Blocks/BlockTorch.h
+++ b/src/Blocks/BlockTorch.h
@@ -1,25 +1,25 @@
#pragma once
#include "BlockHandler.h"
-#include "../World.h"
-
+#include "../Chunk.h"
+#include "MetaRotator.h"
class cBlockTorchHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2>
{
public:
cBlockTorchHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2>(a_BlockType)
{
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
@@ -28,7 +28,7 @@ public:
if ((a_BlockFace == BLOCK_FACE_TOP) || (a_BlockFace == BLOCK_FACE_BOTTOM))
{
- a_BlockFace = FindSuitableFace(a_World, a_BlockX, a_BlockY, a_BlockZ); // Top or bottom faces clicked, find a suitable face
+ a_BlockFace = FindSuitableFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); // Top or bottom faces clicked, find a suitable face
if (a_BlockFace == BLOCK_FACE_NONE)
{
// Client wouldn't have sent anything anyway, but whatever
@@ -38,11 +38,12 @@ public:
else
{
// Not top or bottom faces, try to preserve whatever face was clicked
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true);
- if (!CanBePlacedOn(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ), a_BlockFace))
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); // Set to clicked block
+ if (!CanBePlacedOn(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ), a_BlockFace))
{
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false); // Reset to torch block
// Torch couldn't be placed on whatever face was clicked, last ditch resort - find another face
- a_BlockFace = FindSuitableFace(a_World, a_BlockX, a_BlockY, a_BlockZ);
+ a_BlockFace = FindSuitableFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
if (a_BlockFace == BLOCK_FACE_NONE)
{
return false;
@@ -56,7 +57,7 @@ public:
}
- inline static NIBBLETYPE DirectionToMetaData(char a_Direction)
+ inline static NIBBLETYPE DirectionToMetaData(eBlockFace a_Direction)
{
switch (a_Direction)
{
@@ -76,7 +77,7 @@ public:
}
- inline static char MetaDataToDirection(NIBBLETYPE a_MetaData)
+ inline static eBlockFace MetaDataToDirection(NIBBLETYPE a_MetaData)
{
switch (a_MetaData)
{
@@ -92,13 +93,13 @@ public:
break;
}
}
- return 0;
+ return BLOCK_FACE_TOP;
}
- static bool CanBePlacedOn(BLOCKTYPE a_BlockType, char a_BlockFace)
+ static bool CanBePlacedOn(BLOCKTYPE a_BlockType, eBlockFace a_BlockFace)
{
- if ( !g_BlockFullyOccupiesVoxel[a_BlockType] )
+ if ( !cBlockInfo::FullyOccupiesVoxel(a_BlockType) )
{
return (a_BlockFace == BLOCK_FACE_TOP); // Allow placement only when torch upright (for glass, etc.); exceptions won't even be sent by client, no need to handle
}
@@ -110,41 +111,42 @@ public:
/// Finds a suitable face to place the torch, returning BLOCK_FACE_NONE on failure
- static char FindSuitableFace(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+ static eBlockFace FindSuitableFace(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
for (int i = BLOCK_FACE_YM; i <= BLOCK_FACE_XP; i++) // Loop through all directions
{
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, i, true);
- BLOCKTYPE BlockInQuestion = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
+ eBlockFace Face = static_cast<eBlockFace>(i);
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, Face, true);
+ BLOCKTYPE BlockInQuestion = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ);
if ( // If on a block that can only hold a torch if torch is standing on it, return that face
((BlockInQuestion == E_BLOCK_GLASS) ||
(BlockInQuestion == E_BLOCK_FENCE) ||
(BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) ||
(BlockInQuestion == E_BLOCK_COBBLESTONE_WALL)) &&
- (i == BLOCK_FACE_TOP)
+ (Face == BLOCK_FACE_TOP)
)
{
- return i;
+ return Face;
}
- else if ((g_BlockFullyOccupiesVoxel[BlockInQuestion]) && (i != BLOCK_FACE_BOTTOM))
+ else if (cBlockInfo::FullyOccupiesVoxel(BlockInQuestion) && (i != BLOCK_FACE_BOTTOM))
{
// Otherwise, if block in that direction is torch placeable and we haven't gotten to it via the bottom face, return that face
- return i;
+ return Face;
}
else
{
// Reset coords in preparation for next iteration
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, i, false);
+ AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, Face, false);
}
}
return BLOCK_FACE_NONE;
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
- char Face = MetaDataToDirection(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
+ eBlockFace Face = MetaDataToDirection(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
AddFaceDirection(a_RelX, a_RelY, a_RelZ, Face, true);
BLOCKTYPE BlockInQuestion;
@@ -161,7 +163,7 @@ public:
// No need to check for upright orientation, it was done when the torch was placed
return true;
}
- else if ( !g_BlockFullyOccupiesVoxel[BlockInQuestion] )
+ else if ( !cBlockInfo::FullyOccupiesVoxel(BlockInQuestion) )
{
return false;
}
@@ -183,67 +185,6 @@ public:
{
return "step.wood";
}
-
-
- virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
- {
- // Bit 4 stays, the rest is swapped around according to a table:
- NIBBLETYPE TopBits = (a_Meta & 0x08);
- switch (a_Meta & 0x07)
- {
- case 0x01: return TopBits | 0x04; // East -> North
- case 0x02: return TopBits | 0x03; // West -> South
- case 0x03: return TopBits | 0x01; // South -> East
- case 0x04: return TopBits | 0x02; // North -> West
- default: return a_Meta; // Floor -> Floor
- }
- }
-
-
- virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
- {
- // Bit 4 stays, the rest is swapped around according to a table:
- NIBBLETYPE TopBits = (a_Meta & 0x08);
- switch (a_Meta & 0x07)
- {
- case 0x01: return TopBits | 0x03; // East -> South
- case 0x02: return TopBits | 0x04; // West -> North
- case 0x03: return TopBits | 0x02; // South -> West
- case 0x04: return TopBits | 0x01; // North -> East
- default: return a_Meta; // Floor -> Floor
- }
- }
-
-
- virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
- {
- // Bit 4 stays, the rest is swapped around according to a table:
- NIBBLETYPE TopBits = (a_Meta & 0x08);
- switch (a_Meta & 0x07)
- {
- case 0x03: return TopBits | 0x04; // South -> North
- case 0x04: return TopBits | 0x03; // North -> South
- default: return a_Meta; // Keep the rest
- }
- }
-
-
- // Mirroring around the XZ plane doesn't make sense for floor torches,
- // the others stay the same, so let's keep all the metas the same.
- // The base class does tht for us, no need to override MetaMirrorXZ()
-
-
- virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
- {
- // Bit 4 stays, the rest is swapped around according to a table:
- NIBBLETYPE TopBits = (a_Meta & 0x08);
- switch (a_Meta & 0x07)
- {
- case 0x01: return TopBits | 0x02; // East -> West
- case 0x02: return TopBits | 0x01; // West -> East
- default: return a_Meta; // Keep the rest
- }
- }
} ;
diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h
index 57718b45f..6a36ab874 100644
--- a/src/Blocks/BlockTrapdoor.h
+++ b/src/Blocks/BlockTrapdoor.h
@@ -2,17 +2,17 @@
#pragma once
#include "BlockHandler.h"
-
+#include "MetaRotator.h"
class cBlockTrapdoorHandler :
- public cBlockHandler
+ public cMetaRotator<cBlockHandler, 0x03, 0x01, 0x02, 0x00, 0x03, false>
{
public:
cBlockTrapdoorHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x03, 0x01, 0x02, 0x00, 0x03, false>(a_BlockType)
{
}
@@ -32,17 +32,25 @@ public:
return true;
}
- virtual void OnUse(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) override
+ 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
{
// Flip the ON bit on/off using the XOR bitwise operation
- NIBBLETYPE Meta = (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x04);
+ NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x04);
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
+
+ cWorld * World = (cWorld *) &a_WorldInterface;
+ World->BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player->GetClientHandle());
+ }
- a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
+ virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
+ {
+ UNUSED(a_ChunkInterface);
+ a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
}
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
@@ -57,7 +65,7 @@ public:
return true;
}
- inline static NIBBLETYPE BlockFaceToMetaData(char a_BlockFace)
+ inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_BlockFace)
{
switch (a_BlockFace)
{
@@ -68,12 +76,12 @@ public:
default:
{
ASSERT(!"Unhandled block face!");
- return 0x0;
+ return 0;
}
}
}
- inline static NIBBLETYPE BlockMetaDataToBlockFace(NIBBLETYPE a_Meta)
+ inline static eBlockFace BlockMetaDataToBlockFace(NIBBLETYPE a_Meta)
{
switch (a_Meta & 0x3)
{
@@ -89,7 +97,7 @@ public:
}
}
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
NIBBLETYPE Meta;
a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta);
@@ -97,7 +105,7 @@ public:
AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true);
BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
- return (a_RelY > 0) && (g_BlockIsSolid[BlockIsOn]);
+ return (a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn);
}
};
diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h
index 60aaa9e4b..7bb9dc484 100644
--- a/src/Blocks/BlockVine.h
+++ b/src/Blocks/BlockVine.h
@@ -1,8 +1,7 @@
-
#pragma once
#include "BlockHandler.h"
-
+#include "MetaRotator.h"
@@ -18,16 +17,20 @@ public:
virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, cPlayer * a_Player,
- int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
+ 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
{
+ UNUSED(a_Player);
+ UNUSED(a_CursorX);
+ UNUSED(a_CursorY);
+ UNUSED(a_CursorZ);
// TODO: Disallow placement where the vine doesn't attach to something properly
BLOCKTYPE BlockType = 0;
NIBBLETYPE BlockMeta;
- a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta);
+ a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta);
if (BlockType == m_BlockType)
{
a_BlockMeta = BlockMeta | DirectionToMetaData(a_BlockFace);
@@ -70,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) || g_BlockIsSolid[a_BlockType];
+ return (a_BlockType == E_BLOCK_LEAVES) || (a_BlockType == E_BLOCK_NEW_LEAVES) || cBlockInfo::IsSolid(a_BlockType);
}
@@ -80,7 +83,7 @@ public:
static const struct
{
int x, z;
- int Bit;
+ NIBBLETYPE Bit;
} Coords[] =
{
{ 0, 1, 1}, // south, ZP
@@ -88,7 +91,7 @@ public:
{ 0, -1, 4}, // north, ZM
{ 1, 0, 8}, // east, XP
} ;
- int res = 0;
+ NIBBLETYPE res = 0;
for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
{
BLOCKTYPE BlockType;
@@ -105,7 +108,7 @@ public:
}
- void Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) override
+ void Check(cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface, int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) override
{
NIBBLETYPE CurMeta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
NIBBLETYPE MaxMeta = GetMaxMeta(a_Chunk, a_RelX, a_RelY, a_RelZ);
@@ -128,7 +131,7 @@ public:
{
int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
- DropBlock(a_Chunk.GetWorld(), NULL, BlockX, a_RelY, BlockZ);
+ DropBlock(a_ChunkInterface, *a_Chunk.GetWorld(), a_PluginInterface, NULL, BlockX, a_RelY, BlockZ);
}
a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0);
return;
@@ -162,11 +165,20 @@ public:
return false;
}
- virtual void OnUpdate(cWorld * a_World, int X, int Y, int Z)
+ virtual void OnUpdate(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
{
- if (a_World->GetBlock(X, Y - 1, Z) == E_BLOCK_AIR)
+ UNUSED(a_ChunkInterface);
+ UNUSED(a_WorldInterface);
+ UNUSED(a_BlockPluginInterface);
+
+ BLOCKTYPE Block;
+ a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block);
+ if (Block == E_BLOCK_AIR)
{
- a_World->SetBlock(X, Y - 1, Z, E_BLOCK_VINES, a_World->GetBlockMeta(X, Y, Z));
+ 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));
+ }
}
}
@@ -180,20 +192,21 @@ public:
{
return ((a_Meta << 1) | (a_Meta >> 3)) & 0x0f; // Rotate bits to the left
}
-
-
+
+
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
{
// Bits 2 and 4 stay, bits 1 and 3 swap
- return ((a_Meta & 0x0a) | ((a_Meta & 0x01) << 2) | ((a_Meta & 0x04) >> 2));
+ return (NIBBLETYPE)((a_Meta & 0x0a) | ((a_Meta & 0x01) << 2) | ((a_Meta & 0x04) >> 2));
}
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
{
// Bits 1 and 3 stay, bits 2 and 4 swap
- return ((a_Meta & 0x05) | ((a_Meta & 0x02) << 2) | ((a_Meta & 0x08) >> 2));
+ return (NIBBLETYPE)((a_Meta & 0x05) | ((a_Meta & 0x02) << 2) | ((a_Meta & 0x08) >> 2));
}
+
} ;
diff --git a/src/Blocks/BlockWorkbench.h b/src/Blocks/BlockWorkbench.h
index a2cc6119c..70468369c 100644
--- a/src/Blocks/BlockWorkbench.h
+++ b/src/Blocks/BlockWorkbench.h
@@ -19,7 +19,7 @@ public:
}
- virtual void OnUse(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) override
+ 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
{
cWindow * Window = new cCraftingWindow(a_BlockX, a_BlockY, a_BlockZ);
a_Player->OpenWindow(Window);
diff --git a/src/Blocks/BroadcastInterface.h b/src/Blocks/BroadcastInterface.h
new file mode 100644
index 000000000..b1b450690
--- /dev/null
+++ b/src/Blocks/BroadcastInterface.h
@@ -0,0 +1,12 @@
+
+#pragma once
+
+class cBroadcastInterface
+{
+public:
+ 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/ChunkInterface.cpp b/src/Blocks/ChunkInterface.cpp
new file mode 100644
index 000000000..540581ae7
--- /dev/null
+++ b/src/Blocks/ChunkInterface.cpp
@@ -0,0 +1,12 @@
+
+#include "Globals.h"
+
+#include "ChunkInterface.h"
+#include "BlockHandler.h"
+
+bool cChunkInterface::DigBlock(cWorldInterface & a_WorldInterface, int a_X, int a_Y, int a_Z)
+{
+ cBlockHandler * Handler = cBlockInfo::GetHandler(GetBlock(a_X, a_Y, a_Z));
+ Handler->OnDestroyed(*this, a_WorldInterface, a_X, a_Y, a_Z);
+ return m_ChunkMap->DigBlock(a_X, a_Y, a_Z);
+}
diff --git a/src/Blocks/ChunkInterface.h b/src/Blocks/ChunkInterface.h
new file mode 100644
index 000000000..be7c2e0e5
--- /dev/null
+++ b/src/Blocks/ChunkInterface.h
@@ -0,0 +1,92 @@
+
+#pragma once
+
+#include "../ChunkMap.h"
+#include "../ForEachChunkProvider.h"
+#include "WorldInterface.h"
+
+
+
+
+
+class cChunkInterface:
+ public cForEachChunkProvider
+{
+public:
+
+ cChunkInterface(cChunkMap * a_ChunkMap) : m_ChunkMap(a_ChunkMap) {}
+
+ BLOCKTYPE GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
+ {
+ return m_ChunkMap->GetBlock(a_BlockX,a_BlockY,a_BlockZ);
+ }
+ BLOCKTYPE GetBlock(const Vector3i & a_Pos)
+ {
+ return GetBlock(a_Pos.x, a_Pos.y, a_Pos.z);
+ }
+ NIBBLETYPE GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ)
+ {
+ return m_ChunkMap->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ }
+
+ bool GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta)
+ {
+ return m_ChunkMap->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
+ }
+
+ /** Sets the block at the specified coords to the specified value.
+ Full processing, incl. updating neighbors, is performed.
+ */
+ void SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+ {
+ m_ChunkMap->SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
+ }
+
+ void SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData)
+ {
+ m_ChunkMap->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_MetaData);
+ }
+
+ void QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_TickDelay, BLOCKTYPE a_PreviousBlockType, cWorldInterface & a_WorldInterface)
+ {
+ m_ChunkMap->QueueSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_WorldInterface.GetWorldAge() + a_TickDelay, a_PreviousBlockType);
+ }
+
+ /** Sets the block at the specified coords to the specified value.
+ The replacement doesn't trigger block updates.
+ The replaced blocks aren't checked for block entities (block entity is leaked if it exists at this block)
+ */
+ void FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+ {
+ m_ChunkMap->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
+ }
+
+ void FastSetBlock(const Vector3i & a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta )
+ {
+ FastSetBlock( a_Pos.x, a_Pos.y, a_Pos.z, a_BlockType, a_BlockMeta );
+ }
+
+ void UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
+ {
+ m_ChunkMap->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ);
+ }
+
+ virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) override
+ {
+ return m_ChunkMap->ForEachChunkInRect(a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ, a_Callback);
+ }
+
+ virtual bool WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes) override
+ {
+ return m_ChunkMap->WriteBlockArea(a_Area, a_MinBlockX, a_MinBlockY, a_MinBlockZ, a_DataTypes);
+ }
+
+ bool DigBlock(cWorldInterface & a_WorldInterface, int a_X, int a_Y, int a_Z);
+
+private:
+ cChunkMap * m_ChunkMap;
+};
+
+
+
+
diff --git a/src/Blocks/MetaRotator.h b/src/Blocks/MetaRotator.h
new file mode 100644
index 000000000..899c583e1
--- /dev/null
+++ b/src/Blocks/MetaRotator.h
@@ -0,0 +1,120 @@
+// MetaRotator.h
+
+// Provides a mixin for rotations and reflections
+
+#pragma once
+
+// MSVC generates warnings for the templated AssertIfNotMatched parameter conditions, so disable it:
+#ifdef _MSC_VER
+ #pragma warning(disable: 4127) // Conditional expression is constant
+#endif
+
+
+
+
+
+/*
+Provides a mixin for rotations and reflections following the standard pattern of apply mask then use case.
+
+Usage:
+Inherit from this class providing your base class as Base, the BitMask for the direction bits in bitmask and the masked value for the directions in North, East, South, West. There is also an aptional parameter AssertIfNotMatched. Set this if it is invalid for a block to exist in any other state.
+*/
+
+template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched = false>
+class cMetaRotator : public Base
+{
+public:
+
+ cMetaRotator(BLOCKTYPE a_BlockType) :
+ Base(a_BlockType)
+ {}
+
+ virtual ~cMetaRotator() {}
+
+ virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override;
+ virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override;
+ virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override;
+ virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override;
+};
+
+
+
+
+
+template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
+NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaRotateCW(NIBBLETYPE a_Meta)
+{
+ NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
+ switch (a_Meta & BitMask)
+ {
+ case South: return West | OtherMeta;
+ case West: return North | OtherMeta;
+ case North: return East | OtherMeta;
+ case East: return South | OtherMeta;
+ }
+ if (AssertIfNotMatched)
+ {
+ ASSERT(!"Invalid Meta value");
+ }
+ return a_Meta;
+}
+
+
+
+
+
+template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
+NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaRotateCCW(NIBBLETYPE a_Meta)
+{
+ NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
+ switch (a_Meta & BitMask)
+ {
+ case South: return East | OtherMeta;
+ case East: return North | OtherMeta;
+ case North: return West | OtherMeta;
+ case West: return South | OtherMeta;
+ }
+ if (AssertIfNotMatched)
+ {
+ ASSERT(!"Invalid Meta value");
+ }
+ return a_Meta;
+}
+
+
+
+
+
+template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
+NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaMirrorXY(NIBBLETYPE a_Meta)
+{
+ NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
+ switch (a_Meta & BitMask)
+ {
+ case South: return North | OtherMeta;
+ case North: return South | OtherMeta;
+ }
+ // Not Facing North or South; No change.
+ return a_Meta;
+}
+
+
+
+
+
+template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
+NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaMirrorYZ(NIBBLETYPE a_Meta)
+{
+ NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
+ switch (a_Meta & BitMask)
+ {
+ case West: return East | OtherMeta;
+ case East: return West | OtherMeta;
+ }
+ // Not Facing East or West; No change.
+ return a_Meta;
+}
+
+
+
+
diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h
new file mode 100644
index 000000000..bfbb053d9
--- /dev/null
+++ b/src/Blocks/WorldInterface.h
@@ -0,0 +1,40 @@
+
+#pragma once
+
+#include "BroadcastInterface.h"
+#include "../Mobs/Monster.h"
+
+class cItems;
+
+class cWorldInterface
+{
+public:
+ virtual ~cWorldInterface() {}
+
+ virtual Int64 GetTimeOfDay(void) const = 0;
+ virtual Int64 GetWorldAge(void) const = 0;
+
+ virtual eDimension GetDimension(void) const = 0;
+
+ virtual cBroadcastInterface & GetBroadcastManager() = 0;
+
+ virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData) = 0;
+
+ /** Spawns item pickups for each item in the list. May compress pickups if too many entities: */
+ virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed = 1.0, bool IsPlayerCreated = false) = 0;
+
+ /** Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified: */
+ virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ, bool IsPlayerCreated = false) = 0;
+
+ /** 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;
+
+};