diff options
Diffstat (limited to 'src/Blocks')
42 files changed, 802 insertions, 185 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 3dad4feba..6a3c6a55b 100644 --- a/src/Blocks/BlockBed.cpp +++ b/src/Blocks/BlockBed.cpp @@ -51,6 +51,49 @@ void cBlockBedHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInt +class cTimeFastForwardTester : + public cPlayerListCallback +{ + virtual bool Item(cPlayer * a_Player) override + { + if (!a_Player->IsInBed()) + { + return true; + } + + return false; + } +}; + + + + + +class cPlayerBedStateUnsetter : + public cPlayerListCallback +{ +public: + cPlayerBedStateUnsetter(Vector3i a_Position, cWorldInterface & a_WorldInterface) : + m_Position(a_Position), m_WorldInterface(a_WorldInterface) + { + } + + virtual bool Item(cPlayer * a_Player) override + { + a_Player->SetIsInBed(false); + m_WorldInterface.GetBroadcastManager().BroadcastEntityAnimation(*a_Player, 2); + return false; + } + +private: + Vector3i m_Position; + cWorldInterface & m_WorldInterface; +}; + + + + + void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) { if (a_WorldInterface.GetDimension() != dimOverworld) @@ -69,6 +112,8 @@ void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface } else { + Vector3i PillowDirection(0, 0, 0); + if (Meta & 0x8) { // Is pillow @@ -77,16 +122,30 @@ void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface else { // Is foot end - Vector3i Direction = MetaDataToDirection( Meta & 0x7 ); - if (a_ChunkInterface.GetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z) == E_BLOCK_BED) // Must always use pillow location for sleeping + VERIFY((Meta & 0x4) != 0x4); // Occupied flag should never be set, else our compilator (intended) is broken + + PillowDirection = MetaDataToDirection(Meta & 0x7); + if (a_ChunkInterface.GetBlock(a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z) == E_BLOCK_BED) // Must always use pillow location for sleeping { - a_WorldInterface.GetBroadcastManager().BroadcastUseBed(*a_Player, a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z); + a_WorldInterface.GetBroadcastManager().BroadcastUseBed(*a_Player, a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z); } } - a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, (Meta | (1 << 2))); - } - - } else { + + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x4); // Where 0x4 = occupied bit + a_Player->SetIsInBed(true); + + cTimeFastForwardTester Tester; + if (a_WorldInterface.ForEachPlayer(Tester)) + { + cPlayerBedStateUnsetter Unsetter(Vector3i(a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z), a_WorldInterface); + a_WorldInterface.ForEachPlayer(Unsetter); + a_WorldInterface.SetTimeOfDay(0); + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0xB); // Where 0xB = 1011, and zero is to make sure 'occupied' bit is always unset + } + } + } + else + { a_Player->SendMessageFailure("You can only sleep at night"); } } diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h index 6daa94730..92804aaac 100644 --- a/src/Blocks/BlockBed.h +++ b/src/Blocks/BlockBed.h @@ -4,7 +4,7 @@ #include "BlockHandler.h" #include "ChunkInterface.h" #include "WorldInterface.h" -#include "MetaRotater.h" +#include "MetaRotator.h" #include "../Entities/Player.h" @@ -12,11 +12,11 @@ class cBlockBedHandler : - public cMetaRotater<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01, true> + public cMetaRotator<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01, true> { public: cBlockBedHandler(BLOCKTYPE a_BlockType) - : cMetaRotater<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01,true>(a_BlockType) + : cMetaRotator<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01,true>(a_BlockType) { } diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index 740cbe3c4..4b2f6f618 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -2,17 +2,17 @@ #include "BlockHandler.h" #include "Chunk.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockButtonHandler : - public cMetaRotater<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true> + public cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true> { public: cBlockButtonHandler(BLOCKTYPE a_BlockType) - : cMetaRotater<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true>(a_BlockType) + : cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true>(a_BlockType) { } 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/BlockCauldron.h b/src/Blocks/BlockCauldron.h index 2e1032d2b..41b79b6c3 100644 --- a/src/Blocks/BlockCauldron.h +++ b/src/Blocks/BlockCauldron.h @@ -23,7 +23,7 @@ public: 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_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); switch (a_Player->GetEquippedItem().m_ItemType) { case E_ITEM_WATER_BUCKET: diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h index 30588d8fc..a1ded4c26 100644 --- a/src/Blocks/BlockChest.h +++ b/src/Blocks/BlockChest.h @@ -4,18 +4,18 @@ #include "BlockEntity.h" #include "../BlockArea.h" #include "../Entities/Player.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockChestHandler : - public cMetaRotater<cBlockEntityHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true> + public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04> { public: cBlockChestHandler(BLOCKTYPE a_BlockType) - : cMetaRotater<cBlockEntityHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true>(a_BlockType) + : cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType) { } diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h index e570ff302..4dd05366d 100644 --- a/src/Blocks/BlockComparator.h +++ b/src/Blocks/BlockComparator.h @@ -3,18 +3,18 @@ #include "BlockHandler.h" #include "BlockRedstoneRepeater.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockComparatorHandler : - public cMetaRotater<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true> + public cMetaRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true> { public: cBlockComparatorHandler(BLOCKTYPE a_BlockType) - : cMetaRotater<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>(a_BlockType) + : cMetaRotator<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>(a_BlockType) { } diff --git a/src/Blocks/BlockCrops.h b/src/Blocks/BlockCrops.h index ffc2b3f8b..8606cf3f3 100644 --- a/src/Blocks/BlockCrops.h +++ b/src/Blocks/BlockCrops.h @@ -2,7 +2,7 @@ #pragma once #include "BlockHandler.h" -#include "../MersenneTwister.h" +#include "../FastRandom.h" @@ -21,7 +21,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_Meta) override { - MTRand rand; + cFastRandom rand; if (a_Meta == 0x7) { @@ -31,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)); diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index 544424a04..aa24b8668 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -2,7 +2,7 @@ #pragma once #include "BlockHandler.h" -#include "../MersenneTwister.h" +#include "../FastRandom.h" @@ -44,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; @@ -79,7 +79,10 @@ public: Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta); if ((cBlockInfo::IsOneHitDig(AboveDest) || cBlockInfo::IsTransparent(AboveDest)) && !IsBlockWater(AboveDest)) { - Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0); + if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, BlockX * cChunkDef::Width, BlockY, BlockZ * cChunkDef::Width, ssGrassSpread)) + { + Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0); + } } } // for i - repeat twice } diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index 4e38ef334..479c68153 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -110,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 981774c17..797fe484c 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -4,15 +4,15 @@ #include "BlockHandler.h" #include "../Entities/Player.h" #include "Chunk.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockDoorHandler : - public cMetaRotater<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true> + public cMetaRotator<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true> { - typedef cMetaRotater<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true> super; + typedef cMetaRotator<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true> super; public: cBlockDoorHandler(BLOCKTYPE a_BlockType); @@ -21,6 +21,10 @@ public: 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( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, @@ -142,14 +146,14 @@ public: static void ChangeDoor(cChunkInterface & a_ChunkInterface, int a_X, int a_Y, int a_Z) { 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_ChunkInterface.GetBlock(a_X, a_Y - 1, a_Z); - NIBBLETYPE BottomMeta = a_ChunkInterface.GetBlockMeta(a_X, a_Y - 1, a_Z); + NIBBLETYPE BottomMeta = a_ChunkInterface.GetBlockMeta(a_X, a_Y - 1, a_Z); if (IsDoor(BottomBlock) && !(BottomMeta & 8)) { @@ -168,62 +172,6 @@ public: } } } - - - virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override - { - if (a_Meta & 0x08) - { - return a_Meta; - } - else - { - return super::MetaRotateCCW(a_Meta); - } - } - - - - virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override - { - if (a_Meta & 0x08) - { - return a_Meta; - } - else - { - return super::MetaRotateCW(a_Meta); - } - } - - - - virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override - { - if (a_Meta & 0x08) - { - return a_Meta; - } - else - { - return super::MetaMirrorXY(a_Meta); - } - } - - - - virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override - { - if (a_Meta & 0x08) - { - return a_Meta; - } - else - { - return super::MetaMirrorYZ(a_Meta); - } - } - } ; diff --git a/src/Blocks/BlockDropSpenser.h b/src/Blocks/BlockDropSpenser.h index 7e0ad0e55..88b61a418 100644 --- a/src/Blocks/BlockDropSpenser.h +++ b/src/Blocks/BlockDropSpenser.h @@ -6,18 +6,18 @@ #pragma once #include "../Piston.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockDropSpenserHandler : - public cMetaRotater<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04> + public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04> { public: cBlockDropSpenserHandler(BLOCKTYPE a_BlockType) : - cMetaRotater<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType) + cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType) { } diff --git a/src/Blocks/BlockEnderchest.h b/src/Blocks/BlockEnderchest.h index 97cf484fb..67955f8ce 100644 --- a/src/Blocks/BlockEnderchest.h +++ b/src/Blocks/BlockEnderchest.h @@ -2,17 +2,17 @@ #pragma once #include "BlockEntity.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockEnderchestHandler : - public cMetaRotater<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04> + public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04> { public: cBlockEnderchestHandler(BLOCKTYPE a_BlockType) - : cMetaRotater<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType) + : cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType) { } diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h index e3162bbd6..e202c6610 100644 --- a/src/Blocks/BlockFenceGate.h +++ b/src/Blocks/BlockFenceGate.h @@ -2,17 +2,17 @@ #pragma once #include "BlockHandler.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockFenceGateHandler : - public cMetaRotater<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01, true> + public cMetaRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01, true> { public: cBlockFenceGateHandler(BLOCKTYPE a_BlockType) : - cMetaRotater<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01, true>(a_BlockType) + cMetaRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01, true>(a_BlockType) { } diff --git a/src/Blocks/BlockFire.h b/src/Blocks/BlockFire.h index a25b87858..c8f158e7e 100644 --- a/src/Blocks/BlockFire.h +++ b/src/Blocks/BlockFire.h @@ -17,25 +17,27 @@ 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(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_ChunkInterface, a_WorldInterface); // Brought to you by Aperture Science + FindAndSetPortalFrame(a_BlockX, a_BlockY, a_BlockZ, a_ChunkInterface, a_WorldInterface); } virtual void OnDigging(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override diff --git a/src/Blocks/BlockFurnace.h b/src/Blocks/BlockFurnace.h index 27ef2689f..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) { } diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index aa97b2ca9..7fd8c183c 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -6,10 +6,12 @@ #include "../Root.h" #include "../Bindings/PluginManager.h" #include "../Chunk.h" +#include "BlockAnvil.h" #include "BlockBed.h" #include "BlockBrewingStand.h" #include "BlockButton.h" #include "BlockCactus.h" +#include "BlockCake.h" #include "BlockCarpet.h" #include "BlockCauldron.h" #include "BlockChest.h" @@ -39,6 +41,7 @@ #include "BlockIce.h" #include "BlockLadder.h" #include "BlockLeaves.h" +#include "BlockLilypad.h" #include "BlockNewLeaves.h" #include "BlockLever.h" #include "BlockMelon.h" @@ -85,12 +88,14 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) // Block handlers, alphabetically sorted: case E_BLOCK_ACACIA_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_ACTIVATOR_RAIL: return new cBlockRailHandler (a_BlockType); + case E_BLOCK_ANVIL: return new cBlockAnvilHandler (a_BlockType); case E_BLOCK_BED: return new cBlockBedHandler (a_BlockType); case E_BLOCK_BIRCH_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_BREWING_STAND: return new cBlockBrewingStandHandler (a_BlockType); case E_BLOCK_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_BROWN_MUSHROOM: return new cBlockMushroomHandler (a_BlockType); case E_BLOCK_CACTUS: return new cBlockCactusHandler (a_BlockType); + case E_BLOCK_CAKE: return new cBlockCakeHandler (a_BlockType); case E_BLOCK_CARROTS: return new cBlockCropsHandler (a_BlockType); case E_BLOCK_CARPET: return new cBlockCarpetHandler (a_BlockType); case E_BLOCK_CAULDRON: return new cBlockCauldronHandler (a_BlockType); @@ -138,6 +143,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_LAPIS_ORE: return new cBlockOreHandler (a_BlockType); case E_BLOCK_LAVA: return new cBlockLavaHandler (a_BlockType); case E_BLOCK_LEAVES: return new cBlockLeavesHandler (a_BlockType); + case E_BLOCK_LILY_PAD: return new cBlockLilypadHandler (a_BlockType); case E_BLOCK_LIT_FURNACE: return new cBlockFurnaceHandler (a_BlockType); case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType); case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType); diff --git a/src/Blocks/BlockHopper.h b/src/Blocks/BlockHopper.h index 59b84aa0e..a882bb077 100644 --- a/src/Blocks/BlockHopper.h +++ b/src/Blocks/BlockHopper.h @@ -3,16 +3,16 @@ // 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) { } @@ -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/BlockLadder.h b/src/Blocks/BlockLadder.h index a3e9edc6b..a605edf3f 100644 --- a/src/Blocks/BlockLadder.h +++ b/src/Blocks/BlockLadder.h @@ -9,11 +9,11 @@ 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) { } diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index 7b8f0b378..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)); } @@ -57,11 +60,10 @@ public: { cBlockHandler::OnDestroyed(a_ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ); - //0.5% chance of dropping an apple + // 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); - //check if Oak (0x1 and 0x2 bit not set) - MTRand rand; - if(!(Meta & 3) && rand.randInt(200) == 100) + 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)); diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h index ef6e102cd..ad2ae29e5 100644 --- a/src/Blocks/BlockLever.h +++ b/src/Blocks/BlockLever.h @@ -1,17 +1,18 @@ #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) { } @@ -104,6 +105,36 @@ public: 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 index 2b128f13b..acd1c88fb 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -21,6 +21,103 @@ public: { 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, @@ -50,18 +147,37 @@ public: } public: - cCallback (cPlayer * a_Player, NIBBLETYPE a_OldBlockMeta, NIBBLETYPE a_NewBlockMeta) : - m_Player(a_Player), + 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 = 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 623cfda64..135d418d7 100644 --- a/src/Blocks/BlockMushroom.h +++ b/src/Blocks/BlockMushroom.h @@ -17,6 +17,9 @@ public: } + // TODO: Add Mushroom Spread + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // Reset meta to 0 @@ -39,6 +42,7 @@ public: case E_BLOCK_CACTUS: case E_BLOCK_ICE: case E_BLOCK_LEAVES: + case E_BLOCK_NEW_LEAVES: case E_BLOCK_AIR: { return false; diff --git a/src/Blocks/BlockMycelium.h b/src/Blocks/BlockMycelium.h index 7f897c72a..2a8ef5fca 100644 --- a/src/Blocks/BlockMycelium.h +++ b/src/Blocks/BlockMycelium.h @@ -16,6 +16,8 @@ public: { } + // TODO: Add Mycel Spread + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { a_Pickups.push_back(cItem(E_BLOCK_DIRT, 1, 0)); diff --git a/src/Blocks/BlockNetherWart.h b/src/Blocks/BlockNetherWart.h index 923180e19..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: } } + 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 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(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)); } } ; diff --git a/src/Blocks/BlockPluginInterface.h b/src/Blocks/BlockPluginInterface.h index 7428c9a7a..3a36c40b1 100644 --- a/src/Blocks/BlockPluginInterface.h +++ b/src/Blocks/BlockPluginInterface.h @@ -1,8 +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/BlockPumpkin.h b/src/Blocks/BlockPumpkin.h index 349f52605..ac2b9817a 100644 --- a/src/Blocks/BlockPumpkin.h +++ b/src/Blocks/BlockPumpkin.h @@ -1,16 +1,16 @@ #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) { } diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h index 07e9814cd..ad78d290a 100644 --- a/src/Blocks/BlockRail.h +++ b/src/Blocks/BlockRail.h @@ -431,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/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h index 1e2a86949..fe6cd21b9 100644 --- a/src/Blocks/BlockRedstoneRepeater.h +++ b/src/Blocks/BlockRedstoneRepeater.h @@ -3,17 +3,17 @@ #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) { } diff --git a/src/Blocks/BlockSideways.h b/src/Blocks/BlockSideways.h index 69c0a7230..d67c3aa24 100644 --- a/src/Blocks/BlockSideways.h +++ b/src/Blocks/BlockSideways.h @@ -29,7 +29,13 @@ public: return true; } - + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.Add(m_BlockType, 1, a_BlockMeta & 0x3); + } + + inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_BlockFace, NIBBLETYPE a_WoodMeta) { switch (a_BlockFace) diff --git a/src/Blocks/BlockSign.h b/src/Blocks/BlockSign.h index cd0c02a40..6c0becfd6 100644 --- a/src/Blocks/BlockSign.h +++ b/src/Blocks/BlockSign.h @@ -71,6 +71,37 @@ public: { 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 7cd2c97b2..4f94d45f6 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -14,8 +14,6 @@ - - class cBlockSlabHandler : public cBlockHandler { @@ -105,6 +103,7 @@ public: a_BlockMeta = Meta & 0x7; break; } } + case BLOCK_FACE_NONE: return false; } // switch (a_BlockFace) return true; } @@ -184,6 +183,15 @@ public: ASSERT(!"Unhandled double slab type!"); return ""; } + + + 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/BlockStairs.h b/src/Blocks/BlockStairs.h index ea8405597..09ff254a6 100644 --- a/src/Blocks/BlockStairs.h +++ b/src/Blocks/BlockStairs.h @@ -2,17 +2,17 @@ #pragma once #include "BlockHandler.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockStairsHandler : - public cMetaRotater<cBlockHandler, 0x03, 0x03, 0x00, 0x02, 0x01, true> + public cMetaRotator<cBlockHandler, 0x03, 0x03, 0x00, 0x02, 0x01, true> { public: cBlockStairsHandler(BLOCKTYPE a_BlockType) : - cMetaRotater<cBlockHandler, 0x03, 0x03, 0x00, 0x02, 0x01, true>(a_BlockType) + cMetaRotator<cBlockHandler, 0x03, 0x03, 0x00, 0x02, 0x01, true>(a_BlockType) { } @@ -30,9 +30,7 @@ public: UNUSED(a_BlockY); UNUSED(a_BlockZ); UNUSED(a_CursorX); - UNUSED(a_CursorY); UNUSED(a_CursorZ); - UNUSED(a_BlockMeta); a_BlockType = m_BlockType; a_BlockMeta = RotationToMetaData(a_Player->GetYaw()); switch (a_BlockFace) @@ -51,10 +49,12 @@ public: } break; } + case BLOCK_FACE_NONE: return false; } return true; } + virtual const char * GetStepSound(void) override { if ( diff --git a/src/Blocks/BlockStems.h b/src/Blocks/BlockStems.h index 705436345..b726a0901 100644 --- a/src/Blocks/BlockStems.h +++ b/src/Blocks/BlockStems.h @@ -17,9 +17,10 @@ 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)); } diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index d32c77629..8ddec8de1 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -2,17 +2,17 @@ #include "BlockHandler.h" #include "../Chunk.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockTorchHandler : - public cMetaRotater<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2> + public cMetaRotator<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2> { public: cBlockTorchHandler(BLOCKTYPE a_BlockType) - : cMetaRotater<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2>(a_BlockType) + : cMetaRotator<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2>(a_BlockType) { } diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index 9bae92c4d..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) { } diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 708583e70..7bb9dc484 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -1,7 +1,7 @@ #pragma once #include "BlockHandler.h" -#include "MetaRotater.h" +#include "MetaRotator.h" @@ -73,7 +73,7 @@ public: /// Returns true if the specified block type is good for vines to attach to static bool IsBlockAttachable(BLOCKTYPE a_BlockType) { - return (a_BlockType == E_BLOCK_LEAVES) || cBlockInfo::IsSolid(a_BlockType); + return (a_BlockType == E_BLOCK_LEAVES) || (a_BlockType == E_BLOCK_NEW_LEAVES) || cBlockInfo::IsSolid(a_BlockType); } @@ -83,7 +83,7 @@ public: static const struct { int x, z; - int Bit; + NIBBLETYPE Bit; } Coords[] = { { 0, 1, 1}, // south, ZP @@ -91,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; @@ -175,7 +175,10 @@ public: a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block); if (Block == E_BLOCK_AIR) { - a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); + if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX * cChunkDef::Width, a_RelY - 1, a_RelZ * cChunkDef::Width, ssVineSpread)) + { + a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); + } } } @@ -194,14 +197,14 @@ public: 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/BroadcastInterface.h b/src/Blocks/BroadcastInterface.h index f6ccd580b..b1b450690 100644 --- a/src/Blocks/BroadcastInterface.h +++ b/src/Blocks/BroadcastInterface.h @@ -4,7 +4,9 @@ class cBroadcastInterface { public: - - virtual void BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) = 0; - virtual void BroadcastSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL) = 0; + virtual ~cBroadcastInterface() {} + + virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) = 0; + virtual void BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL) = 0; + virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) = 0; }; diff --git a/src/Blocks/MetaRotater.h b/src/Blocks/MetaRotator.h index dde88e6db..899c583e1 100644 --- a/src/Blocks/MetaRotater.h +++ b/src/Blocks/MetaRotator.h @@ -1,4 +1,4 @@ -// MetaRotater.h +// MetaRotator.h // Provides a mixin for rotations and reflections @@ -21,15 +21,15 @@ Inherit from this class providing your base class as Base, the BitMask for the d */ template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched = false> -class cMetaRotater : public Base +class cMetaRotator : public Base { public: - cMetaRotater(BLOCKTYPE a_BlockType) : + cMetaRotator(BLOCKTYPE a_BlockType) : Base(a_BlockType) {} - virtual ~cMetaRotater() {} + virtual ~cMetaRotator() {} virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override; virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override; @@ -42,7 +42,7 @@ public: template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched> -NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaRotateCW(NIBBLETYPE a_Meta) +NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaRotateCW(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); switch (a_Meta & BitMask) @@ -64,7 +64,7 @@ NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatc template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched> -NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaRotateCCW(NIBBLETYPE a_Meta) +NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaRotateCCW(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); switch (a_Meta & BitMask) @@ -86,7 +86,7 @@ NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatc template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched> -NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaMirrorXY(NIBBLETYPE a_Meta) +NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaMirrorXY(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); switch (a_Meta & BitMask) @@ -103,7 +103,7 @@ NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatc template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched> -NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaMirrorYZ(NIBBLETYPE a_Meta) +NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaMirrorYZ(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); switch (a_Meta & BitMask) diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index e59b00eff..bfbb053d9 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -9,7 +9,8 @@ class cItems; class cWorldInterface { public: - + virtual ~cWorldInterface() {} + virtual Int64 GetTimeOfDay(void) const = 0; virtual Int64 GetWorldAge(void) const = 0; @@ -27,7 +28,13 @@ public: /** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */ virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0; - + /** Sends the block on those coords to the player */ virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player) = 0; + + /** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */ + virtual bool ForEachPlayer(cItemCallback<cPlayer> & a_Callback) = 0; + + virtual void SetTimeOfDay(Int64 a_TimeOfDay) = 0; + }; |